big boost on laser collision test with addition AABB pre-chech

This commit is contained in:
Sylvain PILLOT 2023-09-09 09:02:01 +02:00
parent 1fa16bf5f8
commit ed95b0c307
9 changed files with 143 additions and 66 deletions

View File

@ -44,7 +44,7 @@ set(SOURCES
src/shaders/filledpoly.cpp
src/shaders/line.cpp
src/shaders/starfieldshader.cpp
src/shmup/entity.cpp
src/shmup/collections.cpp
src/shmup/impact.cpp
@ -108,7 +108,7 @@ set(ASSETS_cg
fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)
add_executable(shmup ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
target_compile_options(shmup PRIVATE -Wall -Wextra -Os -std=c++20)
target_compile_options(shmup PRIVATE -Wall -Wextra -O3 -std=c++20)
target_link_options(shmup PRIVATE -Wl,-Map=Build_Addin.map -Wl,--print-memory-usage -fno-use-cxa-atexit -fpermissive)
target_link_libraries(shmup Azur::Azur -lnum LibProf::LibProf Gint::Gint -lstdc++)

View File

@ -5,7 +5,7 @@
#define DEBUG_MODE 0
#define USB 0
#define MORE_RAM 1
#define MORE_RAM 0
#define CALCEMU 1

View File

@ -509,6 +509,22 @@ void debug_crash_msg( char *chain )
}
*/
int EntryClockLevel;
void InitOverClock( void )
{
EntryClockLevel = clock_get_speed();
clock_set_speed( CLOCK_SPEED_F4 );
}
void RestoreOVerClock( void )
{
clock_set_speed( EntryClockLevel );
}
int main(void)
{
exitToOS = false;
@ -530,6 +546,8 @@ int main(void)
azrp_starfield_init( 250 );
InitOverClock();
//Create_Enemies( );
MyPlayer = new Player( azrp_width/4, azrp_height/2, 0);
@ -570,6 +588,8 @@ int main(void)
usb_open(interfaces, GINT_CALL_NULL);
#endif
prof_init();
do
@ -652,5 +672,7 @@ int main(void)
if (canWeAllocateMoreRam) FreeMoreRAM( );
RestoreOVerClock();
return 1;
}

View File

@ -12,7 +12,6 @@ void azrp_starfield_init( uint8_t nbstars );
void azrp_starfield_close( void );
void azrp_shader_line_configure(void);
void azrp_shader_circle_configure(void);
void azrp_shader_filledcircle_configure(void);

View File

@ -1,19 +1,21 @@
#include "../config.h"
#include "boss.h"
#include "bullet.h"
#include <cstdint>
#include <num/num.h>
#include <gint/rtc.h>
#include <sys/types.h>
#include "../utilities/fast_trig.h"
#include <gint/gint.h>
#include "collections.h"
#include "player.h"
#include "boss.h"
#include "bullet.h"
#include "../utilities/fast_trig.h"
#include "../shaders/MyAzurShaders.h"
#include "../utilities/vector2D.h"
extern bopti_image_t img_Lifebar;
extern bopti_image_t img_Boss1;
extern bopti_image_t img_BossGun;
@ -25,7 +27,7 @@ extern std::vector<Bullet*> MyEnemiesBullets;
extern Player *MyPlayer;
#define NB_PIECES_BOSS 12
#define NB_GUNS 12
#define NB_GUNS 6
libnum::num XdataBossInternal[NB_PIECES_BOSS];
libnum::num YdataBossInternal[NB_PIECES_BOSS];
@ -36,6 +38,7 @@ BossPart Pieces[NB_PIECES_BOSS*2];
libnum::num xGuns[NB_GUNS];
libnum::num yGuns[NB_GUNS];
uint8_t NbActiveGun = 0;
BossGun Guns[NB_GUNS];
@ -215,6 +218,11 @@ void Boss::Update( float dt )
uint32_t tempshoot = rtc_ticks();
bool hasExternalGun = false;
NbActiveGun = 0;
for( int i=0; i<NB_GUNS; i++ )
if (Guns[i].toberemoved==false)
NbActiveGun++;
if (Shoot_OK( tempshoot, BULLET_ENEMY_RED ))
{
@ -234,7 +242,8 @@ void Boss::Update( float dt )
}
}
if (hasExternalGun==false)
//if (hasExternalGun==false)
if (NbActiveGun==0)
if(Shoot_OK( tempshoot, BULLET_ENEMY_GREEN ))
{
/* central shoot from the main ship only if no more other gun shooting */
@ -502,25 +511,26 @@ bool Boss::Test_Impact( Laser *projectile )
bool Boss::Shoot_OK( uint32_t tempshoot, uint8_t shootID )
{
return false;
if (shootID==BULLET_ENEMY_RED)
{
if(tempshoot-lastshoot0>1)
if(tempshoot-lastshoot0>30)
{
lastshoot0=tempshoot;
return true;
}
else return false;
}
else if (shootID==BULLET_ENEMY_GREEN)
if (shootID==BULLET_ENEMY_GREEN)
{
if(tempshoot-lastshoot1>1)
if(tempshoot-lastshoot1>75)
{
lastshoot1=tempshoot;
return true;
}
else return false;
}
else return false;
return false;
}

View File

@ -33,8 +33,8 @@ void Laser::Render( void )
{
// TODO this is juste for quick implementation : a thick Line Shader will be needed to be able to plot lasers in every directions
azrp_line((int) sx , (int) sy , (int) (sx+dx*1000) , (int) (sy+dy*1000) , C_WHITE );
azrp_line((int) sx-1, (int) sy-1, (int) (sx+dx*1000)-1, (int) (sy+dy*1000)-1, RGB565_OCEANBLUE );
azrp_line((int) sx-2, (int) sy-2, (int) (sx+dx*1000)-2, (int) (sy+dy*1000)-2, RGB565_AZURBLUE );
azrp_line((int) sx+1, (int) sy+1, (int) (sx+dx*1000)+1, (int) (sy+dy*1000)+1, RGB565_OCEANBLUE );
azrp_line((int) sx+2, (int) sy+2, (int) (sx+dx*1000)+2, (int) (sy+dy*1000)+2, RGB565_AZURBLUE );
//azrp_line((int) sx-1, (int) sy-1, (int) (sx+dx*1000)-1, (int) (sy+dy*1000)-1, RGB565_OCEANBLUE );
//azrp_line((int) sx-2, (int) sy-2, (int) (sx+dx*1000)-2, (int) (sy+dy*1000)-2, RGB565_AZURBLUE );
//azrp_line((int) sx+1, (int) sy+1, (int) (sx+dx*1000)+1, (int) (sy+dy*1000)+1, RGB565_OCEANBLUE );
//azrp_line((int) sx+2, (int) sy+2, (int) (sx+dx*1000)+2, (int) (sy+dy*1000)+2, RGB565_AZURBLUE );
}

View File

@ -6,6 +6,7 @@
#include <num/num.h>
#include <gint/rtc.h>
#include "../utilities/fast_trig.h"
#include "../utilities/utilities.h"
#include "background.h"
#include "laser.h"
@ -45,7 +46,9 @@ Player::Player( int16_t _x, int16_t _y, uint8_t _id )
ymin = (int) y - height;
ymax = (int) y + height;
if (ID==0) life = 1000;
life0=10000;
if (ID==0) life = 10000;
lastshoot0 = rtc_ticks();
lastshoot1 = rtc_ticks();
@ -113,7 +116,6 @@ void Player::Render( void )
}
}
int16_t life0=1000;
if (life>life0*2/3) azrp_subimage_p8_effect((int) x - img_Lifebar.width/2, ymin - 9, &img_Lifebar, 0, 7, (img_Lifebar.width*life)/life0, 5, DIMAGE_NONE );
else if (life>life0/3) azrp_subimage_p8_effect((int) x - img_Lifebar.width/2, ymin - 9, &img_Lifebar, 0, 12, (img_Lifebar.width*life)/life0, 5, DIMAGE_NONE );
@ -140,12 +142,36 @@ bool Player::Test_Impact( Bullet *projectile )
else return false;
}
bool Player::Test_Impact( Laser *projectile )
{
Vector2D Start( projectile->sx, projectile->sy );
Vector2D Direction( projectile->dx, projectile->dy );
Vector2D BoxMin( xmin, ymin );
Vector2D BoxMax( xmax, ymax );
if (LineRectangle_Collision( Start, Direction, BoxMin, BoxMax))
{
life -= projectile->strength;
projectile->toberemoved = true;
return true;
}
else return false;
}
bool Player::Test_Impact( Bonus *bonus )
{
if (bonus->x >= xmin && bonus->x <= xmax && bonus->y >= ymin && bonus->y <= ymax )
{
if (bonus->ID==0) life = 1000;
else if (bonus->ID==1) satNumber++;
if (bonus->ID==0)
{
life += 1000;
if (life>life0) life=life0;
}
else if (bonus->ID==1)
satNumber++;
bonus->toberemoved = true;
return true;
@ -268,16 +294,9 @@ void Player::Activate_Laser( void )
if(isLaser==false)
{
isLaser = true;
Laser *mylaser1 = new Laser( (int) xmax, (int) y, 1, 0, LASER );
Lasers.push_back( mylaser1 );
/*
Laser *mylaser2 = new Laser( (int) xmax, (int) y, 0, -1, LASER );
Lasers.push_back( mylaser2 );
Laser *mylaser3 = new Laser( (int) xmax, (int) y, 0, 1, LASER );
Lasers.push_back( mylaser3 );
*/
Laser *mylaser1 = new Laser( (int) xmax, (int) y, 1, 0, LASER );
Lasers.push_back( mylaser1 );
}
}

View File

@ -23,6 +23,7 @@ class Player
void Render( void );
bool Test_Impact( Bullet *projectile );
bool Test_Impact( Laser *projectile );
bool Test_Impact( Bonus *bonus );
bool Test_Collision( Enemy *adverseship );
void Set_Speed( uint8_t _sp );
@ -43,6 +44,7 @@ class Player
int16_t xmin, xmax, ymin, ymax; // square hitbox (to speed up the bullet impact calculations)
uint8_t ID;
int16_t life;
uint16_t life0;
uint8_t speed; // speed of the player
uint32_t lastshoot0 = 0;
uint32_t lastshoot1 = 0;

View File

@ -13,6 +13,7 @@
#include "vector2D.h"
#include <num/num.h>
#include <algorithm>
extern font_t milifont_prop;
extern font_t font_shmup;
@ -46,12 +47,19 @@ void Azur_draw_text_shmup(int x, int y, char const *fmt, ...)
bool AABB_Collision( SpriteLocator image1, SpriteLocator image2 )
{
if( (image2.x >= image1.x + image1.image->width)
|| (image2.x + image2.image->width <= image1.x)
|| (image2.y >= image1.y + image1.image->height)
|| (image2.y + image2.image->height <= image1.y) )
return false;
if( (image2.x >= image1.x + image1.image->width) ) return false;
if( (image2.x + image2.image->width <= image1.x) ) return false;
if( (image2.y >= image1.y + image1.image->height) ) return false;
if( (image2.y + image2.image->height <= image1.y) ) return false;
// if( (image2.x >= image1.x + image1.image->width)
// || (image2.x + image2.image->width <= image1.x)
// || (image2.y >= image1.y + image1.image->height)
// || (image2.y + image2.image->height <= image1.y) )
// return false;
// no need to do pixel perfect detection
return true;
}
@ -227,32 +235,32 @@ bool Pixel_Perfect_Collision( SpriteLocator image1, SpriteLocator image2 )
#include <num/vec.h>
bool get_line_intersection( Vector2D p0_n, Vector2D p1_n, Vector2D p2_n, Vector2D p3_n, Vector2D *pr)
{
using namespace libnum;
vec<float,2> p0((float)p0_n.x, (float)p0_n.y);
vec<float,2> p1((float)p1_n.x, (float)p1_n.y);
vec<float,2> p2((float)p2_n.x, (float)p2_n.y);
vec<float,2> p3((float)p3_n.x, (float)p3_n.y);
libnum::vec<float,2> p0((float)p0_n.x, (float)p0_n.y);
libnum::vec<float,2> p1((float)p1_n.x, (float)p1_n.y);
libnum::vec<float,2> p2((float)p2_n.x, (float)p2_n.y);
libnum::vec<float,2> p3((float)p3_n.x, (float)p3_n.y);
vec<float,2> s1, s2;
s1 = p1 - p0; s1 = p1 - p0;
s2 = p3 - p2; s2 = p3 - p2;
libnum::vec<float,2> s1, s2;
s1 = p1 - p0;
s2 = p3 - p2;
float s, t;
s = (-s1.y * (p0.x - p2.x) + s1.x * (p0.y - p2.y)) / (-s2.x * s1.y + s1.x * s2.y);
t = ( s2.x * (p0.y - p2.y) - s2.y * (p0.x - p2.x)) / (-s2.x * s1.y + s1.x * s2.y);
float s, t, u;
u = 1 / (-s2.x * s1.y + s1.x * s2.y);
s = (-s1.y * (p0.x - p2.x) + s1.x * (p0.y - p2.y)) * u;
if (s<0) return false;
if (s>1) return false;
if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
t = ( s2.x * (p0.y - p2.y) - s2.y * (p0.x - p2.x)) * u;
if (t<0) return false;
if (t>1) return false;
// Collision detected
if (pr != NULL)
{
// Collision detected
if (pr != NULL)
{
(*pr).x = p0.x + (t * s1.x);
(*pr).y = p0.y + (t * s1.y);
}
return true;
(*pr).x = p0.x + (t * s1.x);
(*pr).y = p0.y + (t * s1.y);
}
return false; // No collision
return true;
}
/* FIRST IMPLEMENTATION USING THE VECTOR2D.H CLASS */
@ -288,19 +296,26 @@ bool LineSegment_Collision( Vector2D O, Vector2D dir, Vector2D A, Vector2D B )
bool LineRectangle_Collision( Vector2D Start, Vector2D Direction, Vector2D Min, Vector2D Max )
{
{
Vector2D End = Start.Clone();
End.Add( Direction, libnum::num(1000));
/* kind of quick AABB to quickly limit case where accurate check is done */
if(Start.x < Min.x && End.x < Min.x ) return false;
if(Start.x > Max.x && End.x > Max.x ) return false;
if(Start.y < Min.y && End.y < Min.y ) return false;
if(Start.y > Max.y && End.y > Max.y ) return false;
Vector2D P1(Min.x, Min.y);
Vector2D P2(Max.x, Min.y);
Vector2D P3(Max.x, Max.y);
Vector2D P4(Min.x, Max.y);
return( get_line_intersection(Start, End, P1, P2, NULL)
|| get_line_intersection(Start, End, P2, P3, NULL)
|| get_line_intersection(Start, End, P3, P4, NULL)
|| get_line_intersection(Start, End, P4, P1, NULL));
if (get_line_intersection(Start, End, P1, P2, NULL) ) return true;
if (get_line_intersection(Start, End, P2, P3, NULL) ) return true;
if (get_line_intersection(Start, End, P3, P4, NULL) ) return true;
if (get_line_intersection(Start, End, P4, P1, NULL) ) return true;
return false;
}
@ -310,7 +325,17 @@ bool LineTriangle_Collision( Vector2D Start, Vector2D Direction, Vector2D A, Vec
Vector2D End = Start.Clone();
End.Add( Direction, libnum::num(1000));
return( get_line_intersection(Start, End, A, B, NULL)
|| get_line_intersection(Start, End, B, C, NULL)
|| get_line_intersection(Start, End, C, A, NULL));
/* kind of quick AABB to quickly limit case where accurate check is done */
Vector2D Min( std::min(A.x, std::min(B.x, C.x)), std::min(A.y, std::min(B.y, C.y)) );
Vector2D Max( std::max(A.x, std::max(B.x, C.x)), std::max(A.y, std::max(B.y, C.y)) );
if(Start.x < Min.x && End.x < Min.x ) return false;
if(Start.x > Max.x && End.x > Max.x ) return false;
if(Start.y < Min.y && End.y < Min.y ) return false;
if(Start.y > Max.y && End.y > Max.y ) return false;
if (get_line_intersection(Start, End, A, B, NULL) ) return true;
if (get_line_intersection(Start, End, B, C, NULL) ) return true;
if (get_line_intersection(Start, End, C, A, NULL) ) return true;
return false;
}