From 36bce711cc88a7055fd4c50b17dd788db169ecae Mon Sep 17 00:00:00 2001 From: SlyVTT Date: Sun, 13 Aug 2023 17:33:25 +0200 Subject: [PATCH] Working on implementation of Boss with multiple parts to be exploded [WIP] --- CMakeLists.txt | 4 +- TODO.txt | 2 +- assets-cg/Sprites/Boss/Boss1.png | Bin 0 -> 2457 bytes assets-cg/Sprites/Boss/fxconv-metadata.txt | 5 + src/boss.cpp | 264 +++++++++++++++++++++ src/boss.h | 55 +++++ src/main.cpp | 56 ++++- 7 files changed, 379 insertions(+), 7 deletions(-) create mode 100644 assets-cg/Sprites/Boss/Boss1.png create mode 100644 assets-cg/Sprites/Boss/fxconv-metadata.txt create mode 100644 src/boss.cpp create mode 100644 src/boss.h diff --git a/CMakeLists.txt b/CMakeLists.txt index acba949..d1ee0de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,7 @@ set(SOURCES src/starfieldshader.cpp src/background.cpp src/bonus.cpp - + src/boss.cpp src/point2D.cpp src/trajectory.cpp @@ -71,6 +71,8 @@ set(ASSETS_cg assets-cg/Sprites/Enemies/mainship2.png assets-cg/Sprites/Enemies/Enemy_Blue_Lvl1.png assets-cg/Sprites/Enemies/Enemy_Red_Lvl1.png + + assets-cg/Sprites/Boss/Boss1.png assets-cg/Levels/tileset.png assets-cg/Levels/Level2.json diff --git a/TODO.txt b/TODO.txt index 5b92fea..e6d7af8 100644 --- a/TODO.txt +++ b/TODO.txt @@ -27,7 +27,7 @@ The SHMUP Todo list : # Bosses - Créer des bosses avec différentes zones, mobiles les unes par rapport aux autres - Créer des hitboxes pour chacune des zones du boss avec différentes sensibilités (par exemple le coeur/générateur = zone critique, mais mieux défendues) -- Créer des protections des certaines zones qui peuvent "sauter" (boucliers qui s'usent) +- Créer des protections pour certaines zones qui peuvent "sauter" (boucliers qui s'usent) # Autres : - plein de trucs dont boss "multi-morceaux et multi-hitboxes" diff --git a/assets-cg/Sprites/Boss/Boss1.png b/assets-cg/Sprites/Boss/Boss1.png new file mode 100644 index 0000000000000000000000000000000000000000..9d341ff61de87f33e34160bfce7ed6261902c45f GIT binary patch literal 2457 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 +#include +#include +#include +#include "fast_trig.h" + +#include +#include "collections.h" + + +extern bopti_image_t img_Lifebar; +extern bopti_image_t img_Boss1; + + +#define NB_PIECES_BOSS 12 +libnum::num XdataBossInternal[NB_PIECES_BOSS]; +libnum::num YdataBossInternal[NB_PIECES_BOSS]; +libnum::num XdataBossExternal[NB_PIECES_BOSS]; +libnum::num YdataBossExternal[NB_PIECES_BOSS]; + +BossPart Pieces[NB_PIECES_BOSS*2]; + + + +#include + +void savedata( void ) +{ + FILE* exportfp = fopen("databosPtxt", "w" ); + if(exportfp) + { + fprintf(exportfp, "Points : \n" ); + + for( int i=0; i 0; + + if ((P3x - P1x) * as_y - (P3y - P1y) * as_x > 0 == s_ab) + return false; + if ((P3x - P2x) * (Py - P2y) - (P3y - P2y)*(Px - P2x) > 0 != s_ab) + return false; + return true; +} + + + +Boss::Boss( int16_t _x, int16_t _y, uint8_t _id ) +{ + x = libnum::num(_x); + y = libnum::num(_y); + + ID = _id; + + speed = 10; + + toberemoved = false; + + width = img_Boss1.width/2; + height = img_Boss1.height/2; + + xmin = (int) x - width; + xmax = (int) x + width; + ymin = (int) y - height; + ymax = (int) y + height; + + if (ID==0) + { + life = 1000; + life0 = 1000; + } + + lastshoot0 = rtc_ticks(); + lastshoot1 = rtc_ticks(); + lastshoot2 = rtc_ticks(); + + radiusInt = libnum::num( 75 ); + radiusExt = libnum::num( 100 ); + + rotAngle = 0.0f; + rotSpeed = 2; + + this->Update(0.0f); + + for( int i=0; i360.0f) rotAngle-=360.0f; + + + uint16_t angleint = (uint16_t) rotAngle; + uint16_t angledelta = (uint16_t) (360/NB_PIECES_BOSS); + + for( int i=0; ix + this->radiusInt * FastCosInt( angleint ); + YdataBossInternal[ i ] = this->y + this->radiusInt * FastSinInt( angleint ); + angleint += angledelta; + if (angleint>=360) angleint -= 360; + } + + // Pour le cercle Exterieur on se décale d'un demi-incrément d'angle pour le sommet du triangle + angleint = (uint16_t) rotAngle + angledelta/2; + if (angleint>=360) angleint -= 360; + + for( int i=0; ix + this->radiusExt * FastCosInt( angleint ); + YdataBossExternal[ i ] = this->y + this->radiusExt * FastSinInt( angleint ); + angleint += angledelta; + if (angleint>=360) angleint -= 360; + } + + +} + + +void Boss::Render( void ) +{ + + if (ID==0 && toberemoved==false) + { + for( int i=0; ilife0*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 ); + else azrp_subimage_p8_effect((int) x - img_Lifebar.width/2, ymin - 9, &img_Lifebar, 0, 17, (img_Lifebar.width*life)/life0, 5, DIMAGE_NONE ); + }; +} + + +bool Boss::Test_Impact( Bullet *projectile ) +{ + for( int i=0; i< NB_PIECES_BOSS; i++ ) + { + if (Pieces[i*2].toberemoved == false) + { + if (Is_Point_Inside_Triangle( (int) projectile->x, (int) projectile->y, + (int) XdataBossExternal[ Pieces[i*2].P1 ], (int) YdataBossExternal[ Pieces[i*2].P1 ], + (int) XdataBossExternal[ Pieces[i*2].P2 ], (int) YdataBossExternal[ Pieces[i*2].P2 ], + (int) XdataBossInternal[ Pieces[i*2].P3 ], (int) YdataBossInternal[ Pieces[i*2].P3 ] )) + { + Pieces[i*2].life -= projectile->strength; + if (Pieces[i*2].life<=0) + { + Pieces[i*2].toberemoved = true; + Create_Explosion( (int) projectile->x, (int) projectile->y ); + } + projectile->toberemoved = true; + return true; + } + } + if (Pieces[i*2+1].toberemoved == false) + { + if (Is_Point_Inside_Triangle( (int) projectile->x, (int) projectile->y, + (int) XdataBossInternal[ Pieces[i*2+1].P1 ], (int) YdataBossInternal[ Pieces[i*2+1].P1 ], + (int) XdataBossInternal[ Pieces[i*2+1].P2 ], (int) YdataBossInternal[ Pieces[i*2+1].P2 ], + (int) XdataBossExternal[ Pieces[i*2+1].P3 ], (int) YdataBossExternal[ Pieces[i*2+1].P3 ] )) + { + Pieces[i*2+1].life -= projectile->strength; + if (Pieces[i*2+1].life<=0) + { + Pieces[i*2+1].toberemoved = true; + Create_Explosion( (int) projectile->x, (int) projectile->y ); + } + projectile->toberemoved = true; + return true; + } + } + } + + if (projectile->x >= xmin && projectile->x <= xmax && projectile->y >= ymin && projectile->y <= ymax ) + { + life -= projectile->strength; + if (life<0) toberemoved = true; + projectile->toberemoved = true; + return true; + } + else return false; +} + diff --git a/src/boss.h b/src/boss.h new file mode 100644 index 0000000..19b851a --- /dev/null +++ b/src/boss.h @@ -0,0 +1,55 @@ +#ifndef BOSS_H +#define BOSS_H + +#include +#include + +#include +#include + +#include +#include +#include "bullet.h" + + + +typedef struct +{ + uint8_t P1, P2, P3; + uint16_t life; + bool toberemoved; + int color; +} BossPart; + + + +class Boss +{ + public: + Boss( int16_t _x, int16_t _y, uint8_t _id ); + ~Boss(); + + void Update( float dt ); + void Render( void ); + + bool Test_Impact( Bullet *projectile ); + + libnum::num x, y; // center position of the boss + uint8_t width, height; // width and height -for the hitbox + int16_t xmin, xmax, ymin, ymax; // square hitbox (to speed up the bullet impact calculations) + uint8_t ID; + int16_t life, life0; + uint8_t speed; // speed of the boss + uint32_t lastshoot0 = 0; + uint32_t lastshoot1 = 0; + uint32_t lastshoot2 = 0; + uint8_t rotSpeed; + bool toberemoved; + + private: + float rotAngle; + libnum::num radiusInt, radiusExt; +}; + + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2c0e082..f583df6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #define DEBUG_MODE 0 #define USB 1 #define MORE_RAM 1 +#define CALCEMU 0 #include #include @@ -43,7 +44,7 @@ #include "bonus.h" #include "impact.h" #include "background.h" - +#include "boss.h" #include "trajectory.h" #include @@ -89,6 +90,7 @@ std::vector MyBonuses; Background MyBackground; Player *MyPlayer; +Boss *MyBoss; KeyboardExtra MyKeyboard; @@ -164,6 +166,24 @@ static void update( float dt ) delete( MyEnemies[i] ); MyEnemies.erase( MyEnemies.begin() + i ); } + + if (MyBoss) + { + if (MyBoss->toberemoved == true) + { + Bonus *b = new Bonus( (int) MyBoss->x, (int) MyBoss->y, rand() % 2 ); + MyBonuses.push_back( b ); + + Create_Explosion( (int) MyBoss->x, (int) MyBoss->y ); + delete( MyBoss ); + MyBoss=nullptr; + } + } + } + + if (MyBoss) + { + MyBoss->Update( dt ); } for(unsigned int i=0; iTest_Impact(MyPlayerBullets[i])==true) + { + //TODO : we can create a list of impacts here, to be rendered later on + Create_Impact( (int) MyPlayerBullets[i]->x, (int) MyPlayerBullets[i]->y ); + } + + // Check if the property toberemoved has been set to "true" for particle deletion if (MyPlayerBullets[i]->toberemoved == true) { @@ -292,7 +320,6 @@ static void render( void ) static void get_inputs( float dt ) { - uint8_t speed = 4; uint32_t tempshoot = rtc_ticks(); if(MyKeyboard.IsKeyPressed(MYKEY_F1)) @@ -340,7 +367,7 @@ static void get_inputs( float dt ) bool AddMoreRAM( void ) { - #if(MORE_RAM) + #if(MORE_RAM && !CALCEMU) /* allow more RAM */ char const *osv = (char*) 0x80020020; @@ -386,11 +413,24 @@ bool AddMoreRAM( void ) kmalloc_add_arena(&extended_ram ); return true; } + #elif (MORE_RAM && CALCEMU) + + extended_ram.name = "extram"; + extended_ram.is_default = true; + extended_ram.start = (void *)0x8c200000; + extended_ram.end = (void *)0x8c4e0000 ; + + kmalloc_init_arena(&extended_ram, true); + kmalloc_add_arena(&extended_ram ); + return true; + #else return false; #endif + + return false; } void FreeMoreRAM( void ) @@ -429,7 +469,7 @@ int main(void) _uram = kmalloc_get_arena("_uram"); #endif - bool canWeAllocate3Mb = AddMoreRAM(); + bool canWeAllocateMoreRam = AddMoreRAM(); __printf_enable_fp(); __printf_enable_fixed(); @@ -447,6 +487,8 @@ int main(void) MyPlayer = new Player( azrp_width/4, azrp_height/2, 0); + MyBoss = new Boss( 3*azrp_width/4, azrp_height/2, 0); + /* #if(DBGCRSH) debug_crash( 1 ); @@ -475,6 +517,8 @@ int main(void) // update as per the time spend to do the loop update( elapsedTime ); + MyBoss->Update(elapsedTime); + // update the RAM consumption status #if(MORE_RAM) _uram_stats = kmalloc_get_gint_stats(_uram); @@ -494,6 +538,8 @@ int main(void) render(); + MyBoss->Render(); + azrp_update(); } @@ -533,7 +579,7 @@ int main(void) usb_close(); #endif - FreeMoreRAM( ); + if (canWeAllocateMoreRam) FreeMoreRAM( ); return 1; }