Compare commits

...

6 Commits

19 changed files with 706 additions and 43 deletions

3
.gitignore vendored
View File

@ -12,3 +12,6 @@
*.sublime-project
*.sublime-workspace
.vscode
*.json

View File

@ -64,6 +64,8 @@ set(ASSETS_cg
assets-cg/Sprites/Bullets/bullet_blue.png
assets-cg/Sprites/Bullets/bullet_laser.png
assets-cg/Sprites/Bullets/bullet_enemy_blue.png
assets-cg/Sprites/Bullets/bullet_enemy_red.png
assets-cg/Sprites/Bullets/bullet_enemy_green.png
assets-cg/Sprites/Players/mainship1.png
assets-cg/Sprites/Players/Satellite_Lvl1.png
@ -74,7 +76,8 @@ set(ASSETS_cg
assets-cg/Sprites/Enemies/Enemy_Red_Lvl1.png
assets-cg/Sprites/Boss/Boss1.png
assets-cg/Sprites/Boss/BossGun.png
assets-cg/Levels/tileset.png
assets-cg/Levels/Level2.json
# assets-cg/Levels/Tileset_Space.json
@ -90,5 +93,5 @@ target_link_libraries(shmup Azur::Azur -lnum LibProf::LibProf Gint::Gint -lstdc+
if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
generate_g3a(TARGET shmup OUTPUT "MyShmup.g3a"
NAME "MyShmup" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
NAME "Shmup v0.4" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
endif()

View File

@ -3,4 +3,87 @@
First attempt to use Lephe's Azur.
Yet it only consists in a Particle Engine able to reproduce some kind of explosions and a starfield moving in the background of the screen.
The particle engine is based on fixed-point maths for update and on Azur shaders for rendering.
The particle engine is based on fixed-point maths for update and on Azur shaders for rendering.
Some pictures of current revision
![Boss with Bullet Hell effect (test)](https://www.planet-casio.com/storage/staff/BulletHell1.png)
![Simple enemy on a Spline Trajectory](https://imgur.com/VdBngl3.png)
[Current video of "gameplay"](https://youtu.be/vJsYjfI_HT4)
Still a lot of missing features.
Please see below what I would like to implement on the long run (sorry in French right now).
# SHMUP Todo list :
## Moteur de jeu
- [DONE] better keyboard management engine for keypressed() and keyreleased() events
- Mettre une système d'ajustement de FPS mini avec switch des niveaux d'overclock à la volée de manière dynamique
## Partie décors :
- [WIP] - animer le décors avec le parallaxe (glissement de la droite vers la gauche pour donner l'avancement du vaisseau).
- animer des éléments du décors (clignotements, sprites animés, ...)
- interaction avec le décors (collisions possibles avec certaines tiles) qui imposent donc de suivre un "chemin" dans le niveau
- [DONE] multiple layers de tiles pour avoir des niveaux plus beaux
## Partie mouvement :
- améliorer le système de trajectoires sur base de Splines pour rendre la vitesse des ennemis plus constante.
- rendre les satellites sur une trajectoire (possibilité d'avoir des patterns plus complexes)
- possibilité de transformer les trajectoires (grossissement/rétrécissement, translation et rotation)
## Partie interaction / gameplay :
- implémenter les tirs ennemis (avec une IA minimale)
- [DONE] implémenter les hits des tirs ennemis sur le joueur
- implémenter les collisions avec les ennemies
- implémenter les collisions de bullets avec les satellites pour que ceux-ci perdent de la vie aussi
- implémenter le tir des satellites
- [DONE] implémenter un système de bonus (points, upgrade tir/satellites/... )
- implémenter un système d'amélioration de compétence de tirs (bullet -> mega bullet -> laser -> )
- implémenter un système d'animation du vaisseau (réacteurs par exemple)
## Bosses
- [DONE] Créer des bosses avec différentes zones, mobiles les unes par rapport aux autres
- [DONE] 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)
- [DONE] Créer des protections pour certaines zones qui peuvent "sauter" (boucliers qui s'usent)
## Autres :
- [DONE] plein de trucs dont boss "multi-morceaux et multi-hitboxes"
- création de différents levels
- créations de différents ennemis
- créations de différents boss
o boss 1 : "rotating shield" avec multiples cannons
o boss 2 : "threwing saws"
o boss 3 : "Gun Crab"
o boss 4 : "Demoniac Snake"
o boss 5 : "Space Octopus"
- création de séquences avec les boss (différentes phases)
- créations de différentes armes
- [DONE - CAN BE IMPROVED] créations de différents bonus
- création de shields pour se protéger
## Modes spéciaux
- mode menu avec différentes planètes à selectionner pour les différents niveaux
- mode hyperspace travel pour les transitions :
- sous mode : à la "Tie fighter" ?
- sous mode : éviter les astéroïdes
- sous mode classique shmup horizontal
- sous mode classique shmup vertical
- sous mode Danmaku / Bullet Hell (par exemple contre les boss)
## Interface :
- Page d'accueil
- Choix du niveau
- Ecran de titre

View File

@ -1,48 +1,92 @@
The SHMUP Todo list :
# The SHMUP Todo list :
# Engine
## Engine
- [DONE] better keyboard management engine for keypressed() and keyreleased() events
- Mettre une système d'ajustement de FPS mini avec switch des niveaux d'overclock à la volée de manière dynamique
# Partie décors :
## Partie décors :
- [WIP] - animer le décors avec le parallaxe (glissement de la droite vers la gauche pour donner l'avancement du vaisseau).
- animer des éléments du décors (clignotements, sprites animés, ...)
- interaction avec le décors (collisions possibles avec certaines tiles) qui imposent donc de suivre un "chemin" dans le niveau
- multiple layers de tiles pour avoir des niveaux plus beaux
- [DONE] multiple layers de tiles pour avoir des niveaux plus beaux
# Partie mouvement :
## Partie mouvement :
- améliorer le système de trajectoires sur base de Splines pour rendre la vitesse des ennemis plus constante.
- rendre les satellites sur une trajectoire (possibilité d'avoir des patterns plus complexes)
- possibilité de transformer les trajectoires (grossissement/rétrécissement, translation et rotation)
# Partie interaction / gameplay :
## Partie interaction / gameplay :
- implémenter les tirs ennemis (avec une IA minimale)
- implémenter les hits des tirs ennemis sur le joueur
- [DONE] implémenter les hits des tirs ennemis sur le joueur
- implémenter les collisions avec les ennemies
- implémenter les collisions de bullets avec les satellites pour que ceux-ci perdent de la vie aussi
- implémenter le tir des satellites
- implémenter un système de bonus (points, upgrade tir/satellites/... )
- [DONE] implémenter un système de bonus (points, upgrade tir/satellites/... )
- implémenter un système d'amélioration de compétence de tirs (bullet -> mega bullet -> laser -> )
- implémenter un système d'animation du vaisseau (réacteurs par exemple)
# 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 pour certaines zones qui peuvent "sauter" (boucliers qui s'usent)
# Autres :
- plein de trucs dont boss "multi-morceaux et multi-hitboxes"
## Scenario
- implémenter un système de séquences avec des vagues de monstres qui arrivent les unes après les autres
- possibilité d'avoir dans les séquences:
o fond étoilé ou non
o niveau tiled ou non
o eventuellement choix d'un mode alternatif, du genre éviter les rochers
o sequence de monstres avec trajectoires
o boss de fin
o eventuelles récompenses/upgrades de vaisseau
## Bosses
- [DONE] Créer des bosses avec différentes zones, mobiles les unes par rapport aux autres
- [DONE] 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)
- [DONE] Créer des protections pour certaines zones qui peuvent "sauter" (boucliers qui s'usent)
## Autres :
- [DONE] plein de trucs dont boss "multi-morceaux et multi-hitboxes"
- création de différents levels
- créations de différents ennemis
- créations de différents boss
o boss 1 : "rotating shield" avec multiples cannons
o boss 2 : "threwing saws"
o boss 3 : "Gun Crab"
o boss 4 : "Demoniac Snake"
o boss 5 : "Space Octopus"
- création de séquences avec les boss (différentes phases)
- créations de différentes armes
- créations de différents bonus
- [DONE - CAN BE IMPROVED] créations de différents bonus
- création de shields pour se protéger
# Modes spéciaux
## Modes spéciaux
- mode menu avec différentes planètes à selectionner pour les différents niveaux
- mode hyperspace travel pour les transitions :
- sous mode : à la "tie fighter" ?
- sous mode : à la "Tie fighter" ?
- sous mode : éviter les astéroïdes
- sous mode classique shmup horizontal
- sous mode classiqie shmup vertical
- sous mode classique shmup vertical
- sous mode Danmaku / Bullet Hell (par exemple contre les boss)
## Interface :
- Page d'accueil
- Choix du niveau/séquence (un écran avec choix de planètes par exemple ou de galaxies)
- Ecran de titre
- transitions style "hyper space" serait vraiment cool
## Histoire (à peaufiner)
En tant de Space Marshall, votre rôle est de faire respecter
la loi intergalactique et de punir les contrevenants.
Votre périmètre se situe dans le Grand Amas de RUZA-25f/s
et armé de votre vaisseau, vous devez aider les civilisations
locales en pourchassant et anéantissant les hordes de Zgrog.
Cette race alien robotique a pour but de coloniser les planètes
et les stations orbitales géantes pour faire disparaître tout
vie organique.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -10,15 +10,23 @@
#include <gint/gint.h>
#include "collections.h"
#include "player.h"
#include "vector2D.h"
extern bopti_image_t img_Lifebar;
extern bopti_image_t img_Boss1;
extern bopti_image_t img_BossGun;
extern font_t milifont_prop;
extern std::vector<Bullet*> MyEnemiesBullets;
extern Player *MyPlayer;
#define NB_PIECES_BOSS 12
#define NB_GUNS 12
libnum::num XdataBossInternal[NB_PIECES_BOSS];
libnum::num YdataBossInternal[NB_PIECES_BOSS];
libnum::num XdataBossExternal[NB_PIECES_BOSS];
@ -26,6 +34,10 @@ libnum::num YdataBossExternal[NB_PIECES_BOSS];
BossPart Pieces[NB_PIECES_BOSS*2];
libnum::num xGuns[NB_GUNS];
libnum::num yGuns[NB_GUNS];
BossGun Guns[NB_GUNS];
#include <stdio.h>
@ -88,7 +100,7 @@ Boss::Boss( int16_t _x, int16_t _y, uint8_t _id )
ID = _id;
speed = 10;
speed = 1;
toberemoved = false;
@ -106,12 +118,13 @@ Boss::Boss( int16_t _x, int16_t _y, uint8_t _id )
life0 = 1000;
}
hasTrajectory=false;
lastshoot0 = rtc_ticks();
lastshoot1 = rtc_ticks();
lastshoot2 = rtc_ticks();
radiusInt = libnum::num( 75 );
radiusExt = libnum::num( 100 );
radiusInt = libnum::num( 80 );
radiusExt = libnum::num( 90 );
rotAngle = 0.0f;
rotSpeed = 2;
@ -135,6 +148,11 @@ Boss::Boss( int16_t _x, int16_t _y, uint8_t _id )
Pieces[i*2+1].color = 0x528a; //darker gray
}
for( int i=0; i<NB_GUNS; i++ )
{
Guns[i].life = 100;
Guns[i].toberemoved = false;
}
/* FOR DEBUGGING */
// gint_world_switch( GINT_CALL( savedata ) );
@ -143,13 +161,19 @@ Boss::Boss( int16_t _x, int16_t _y, uint8_t _id )
Boss::~Boss()
{
if (hasTrajectory)
delete(pathToFollow);
}
void Boss::Update( float dt )
{
if (hasTrajectory)
{
pathToFollow->CalculatePosition( dt, speed, true, &x, &y );
}
xmin = (int) x - width;
xmax = (int) x + width;
ymin = (int) y - height;
@ -159,6 +183,7 @@ void Boss::Update( float dt )
if (rotAngle>360.0f) rotAngle-=360.0f;
/* Management of the shield part of the boss (rotating circles made of triangles)*/
uint16_t angleint = (uint16_t) rotAngle;
uint16_t angledelta = (uint16_t) (360/NB_PIECES_BOSS);
@ -182,6 +207,63 @@ void Boss::Update( float dt )
if (angleint>=360) angleint -= 360;
}
/* Management of the Guns part of the boss (rotating cannons made of sprites)*/
angledelta = (uint16_t) (360/NB_GUNS);
angleint = (uint16_t) rotAngle + angledelta/2;
if (angleint>=360) angleint -= 360;
for( int i=0; i<NB_GUNS; i++ )
{
xGuns[i] = this->x + (this->radiusInt + this->radiusExt) / 2 * FastCosInt( angleint );
yGuns[i] = this->y + (this->radiusInt + this->radiusExt) / 2 * FastSinInt( angleint );
angleint += angledelta;
if (angleint>=360) angleint -= 360;
}
uint32_t tempshoot = rtc_ticks();
bool hasExternalGun = false;
if (Shoot_OK( tempshoot, BULLET_ENEMY_RED ))
{
/* shoot from the rotating cannons (aiming directly the position of the player )*/
for( int i=0; i<NB_GUNS; i++ )
{
if (Guns[i].toberemoved==false)
{
Vector2D shootDirection( MyPlayer->x - xGuns[i], MyPlayer->y - yGuns[i] );
shootDirection.Normalise();
Bullet *b = new Bullet( xGuns[i] , yGuns[i], shootDirection.x, shootDirection.y, BULLET_ENEMY_RED );
MyEnemiesBullets.push_back( b );
hasExternalGun = true;
}
}
}
if (hasExternalGun==false)
if(Shoot_OK( tempshoot, BULLET_ENEMY_GREEN ))
{
/* central shoot from the main ship only if no more other gun shooting */
Bullet *b0 = new Bullet( xmin, (int) y, -3, 0, BULLET_ENEMY_GREEN );
MyEnemiesBullets.push_back( b0 );
Bullet *b1 = new Bullet( xmin, (int) y, -2, -2, BULLET_ENEMY_BLUE );
MyEnemiesBullets.push_back( b1 );
Bullet *b2 = new Bullet( xmin, (int) y, -2, 2, BULLET_ENEMY_BLUE );
MyEnemiesBullets.push_back( b2 );
Bullet *b3 = new Bullet( xmin, (int) y, -3, -1, BULLET_ENEMY_GREEN );
MyEnemiesBullets.push_back( b3 );
Bullet *b4 = new Bullet( xmin, (int) y, -3, 1, BULLET_ENEMY_GREEN );
MyEnemiesBullets.push_back( b4 );
}
}
@ -189,7 +271,7 @@ void Boss::Update( float dt )
void Boss::Render( void )
{
if (ID==0 && toberemoved==false)
if (toberemoved==false)
{
for( int i=0; i<NB_PIECES_BOSS; i++ )
{
@ -224,17 +306,38 @@ void Boss::Render( void )
}
}
for( int i=0; i<NB_GUNS; i++ )
{
if (Guns[i].toberemoved==false)
{
azrp_image_p8_effect( (int) xGuns[i] - img_BossGun.width/2,
(int) yGuns[i] - img_BossGun.height/2,
&img_BossGun, DIMAGE_NONE);
#if(DEBUG_MODE)
dfont( &milifont_prop );;
int X = (int) xGuns[i] - img_BossGun.width/2 + 15 ;
int Y = (int) yGuns[i] - img_BossGun.height/2 +15;
azrp_print( X, Y, C_WHITE, "%d", Guns[i].life );
#endif
}
}
azrp_image_p8_effect(xmin, ymin, &img_Boss1, DIMAGE_NONE);
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 );
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 )
{
/* We check if the bullet collides with teh shield of the boss */
for( int i=0; i< NB_PIECES_BOSS; i++ )
{
if (Pieces[i*2].toberemoved == false)
@ -273,13 +376,65 @@ bool Boss::Test_Impact( Bullet *projectile )
}
}
/* We check if the bullet collides with the cannons of the boss */
for( int i=0; i<NB_GUNS; i++ )
{
if (Guns[i].toberemoved==false)
{
if (projectile->x >= (int) xGuns[i] - img_BossGun.width/2 &&
projectile->x <= (int) xGuns[i] + img_BossGun.width/2 &&
projectile->y >= (int) yGuns[i] - img_BossGun.height/2 &&
projectile->y <= (int) yGuns[i] + img_BossGun.height/2 )
{
Guns[i].life -= projectile->strength;
if (Guns[i].life<0)
{
Guns[i].toberemoved = true;
Create_Explosion( (int) projectile->x, (int) projectile->y );
}
projectile->toberemoved = true;
return true;
}
}
}
/* We check if the bullet collides with the main ship part of the boss */
if (projectile->x >= xmin && projectile->x <= xmax && projectile->y >= ymin && projectile->y <= ymax )
{
life -= projectile->strength;
if (life<0) this->toberemoved = true;
if (life<0)
{
this->toberemoved = true;
Create_Explosion( (int) projectile->x, (int) projectile->y );
}
projectile->toberemoved = true;
return true;
}
else return false;
}
bool Boss::Shoot_OK( uint32_t tempshoot, uint8_t shootID )
{
if (shootID==BULLET_ENEMY_RED)
{
if(tempshoot-lastshoot0>1)
{
lastshoot0=tempshoot;
return true;
}
else return false;
}
else if (shootID==BULLET_ENEMY_GREEN)
{
if(tempshoot-lastshoot1>1)
{
lastshoot1=tempshoot;
return true;
}
else return false;
}
else return false;
}

View File

@ -10,7 +10,7 @@
#include <num/num.h>
#include <sys/types.h>
#include "bullet.h"
#include "trajectory.h"
typedef struct
@ -22,6 +22,12 @@ typedef struct
} BossPart;
typedef struct
{
int16_t life;
bool toberemoved;
} BossGun;
class Boss
{
@ -40,15 +46,21 @@ class Boss
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;
uint32_t lastshoot = 0;
uint8_t rotSpeed;
bool toberemoved;
bool hasTrajectory = false;
Trajectory *pathToFollow;
private:
float rotAngle;
libnum::num radiusInt, radiusExt;
libnum::num radiusInt, radiusExt;
uint32_t lastshoot0 = 0;
uint32_t lastshoot1 = 0;
bool Shoot_OK( uint32_t tempshoot, uint8_t shootID );
};

View File

@ -15,7 +15,8 @@ extern bopti_image_t img_bullet_normal;
extern bopti_image_t img_bullet_blue;
extern bopti_image_t img_bullet_laser;
extern bopti_image_t img_bullet_enemy_blue;
extern bopti_image_t img_bullet_enemy_red;
extern bopti_image_t img_bullet_enemy_green;
Bullet::Bullet( uint16_t lx, uint16_t ly, int16_t dx, int16_t dy, uint8_t id )
@ -44,6 +45,51 @@ Bullet::Bullet( uint16_t lx, uint16_t ly, int16_t dx, int16_t dy, uint8_t id )
{
strength = 2;
}
else if (ID==BULLET_ENEMY_RED)
{
strength = 3;
}
else if (ID==BULLET_ENEMY_GREEN)
{
strength = 5;
}
toberemoved = false;
}
Bullet::Bullet( libnum::num lx, libnum::num ly, libnum::num dx, libnum::num dy, uint8_t id )
{
x = lx;
y = ly;
sx = dx;
sy = dy;
ID=id;
if (ID==BULLET_NORMAL)
{
strength = 5;
}
else if (ID==BULLET_BLUE)
{
strength = 2;
}
else if (ID==BULLET_LASER)
{
strength = 1;
}
else if (ID==BULLET_ENEMY_BLUE)
{
strength = 2;
}
else if (ID==BULLET_ENEMY_RED)
{
strength = 3;
}
else if (ID==BULLET_ENEMY_GREEN)
{
strength = 5;
}
toberemoved = false;
}
@ -87,5 +133,15 @@ void Bullet::Render( )
azrp_image_p8( px-img_bullet_enemy_blue.width/2, py-img_bullet_enemy_blue.height/2, &img_bullet_enemy_blue, DIMAGE_NONE );
return;
}
else if (ID==BULLET_ENEMY_RED)
{
azrp_image_p8( px-img_bullet_enemy_red.width/2, py-img_bullet_enemy_red.height/2, &img_bullet_enemy_red, DIMAGE_NONE );
return;
}
else if (ID==BULLET_ENEMY_GREEN)
{
azrp_image_p8( px-img_bullet_enemy_green.width/2, py-img_bullet_enemy_green.height/2, &img_bullet_enemy_green, DIMAGE_NONE );
return;
}
}

View File

@ -11,6 +11,8 @@ enum
BULLET_BLUE,
BULLET_LASER,
BULLET_ENEMY_BLUE,
BULLET_ENEMY_RED,
BULLET_ENEMY_GREEN,
};
@ -18,6 +20,7 @@ class Bullet
{
public:
Bullet( uint16_t lx, uint16_t ly, int16_t dx, int16_t dy, uint8_t id );
Bullet( libnum::num lx, libnum::num ly, libnum::num dx, libnum::num dy, uint8_t id );
~Bullet();
void Update( float dt );
void Render();

View File

@ -3,10 +3,10 @@
#define DEBUG_MODE 0
#define USB 1
#define MORE_RAM 0
#define CALCEMU 0
#define DEBUG_MODE 0
#define USB 0
#define MORE_RAM 1
#define CALCEMU 1
#endif

View File

@ -107,7 +107,6 @@ void Enemy::Update( float dt )
Bullet *b = new Bullet( xmin, (int) y, -1, 0, BULLET_ENEMY_BLUE );
MyEnemiesBullets.push_back( b );
}
}

View File

@ -484,11 +484,33 @@ int main(void)
azrp_starfield_init( 250 );
Create_Enemies( );
//Create_Enemies( );
MyPlayer = new Player( azrp_width/4, azrp_height/2, 0);
MyBoss = new Boss( 3*azrp_width/4, azrp_height/2, 0);
Point2D *A = new Point2D( 348, 112 );
Point2D *B = new Point2D( 371, 199 );
Point2D *C = new Point2D( 198, 149 );
Point2D *D = new Point2D( 25, 199 );
Point2D *E = new Point2D( 25, 25 );
Point2D *F = new Point2D( 198, 75 );
Point2D *G = new Point2D( 371, 25 );
Trajectory *MyTrajectory= new Trajectory();
MyTrajectory->AddPoint( A );
MyTrajectory->AddPoint( B );
MyTrajectory->AddPoint( C );
MyTrajectory->AddPoint( D );
MyTrajectory->AddPoint( E );
MyTrajectory->AddPoint( F );
MyTrajectory->AddPoint( G );
MyBoss->hasTrajectory = true;
MyBoss->pathToFollow = MyTrajectory;
/*
#if(DBGCRSH)
@ -546,7 +568,7 @@ int main(void)
elapsedTime = ((float) (time_update+time_render));
#if(DEBUG_MODE)
#if(DEBUG_MODE && USB)
if (textoutput && usb_is_open())
{
@ -567,6 +589,11 @@ int main(void)
Clean_Everything();
// TODO - make it clean for the future
delete( MyBoss );
delete( MyPlayer );
azrp_starfield_close( );

278
src/vector2D.h Normal file
View File

@ -0,0 +1,278 @@
#ifndef VECTOR2D_H
#define VECTOR2D_H
#include <num/num.h>
#include <stdint.h>
#define numPI 3.14159265
libnum::num32 sqrt_num32(libnum::num32 v) {
uint32_t t, q, b, r;
r = v.v;
b = 0x40000000;
q = 0;
while (b > 0x40) {
t = q + b;
if (r >= t) {
r -= t;
q = t + b;
}
r <<= 1;
b >>= 1;
}
q >>= 8;
libnum::num32 ret;
ret.v = q;
return ret;
}
/* TO DO : rework these functions for sine and cosine calculation */
libnum::num32 cos_num32(libnum::num32 angle) {
// Taylor serie for cos(x) = 1 - x²/2! + x⁴/4! + x⁶/6! + x⁸/8! + ...
// Cosine function is even
if (angle < libnum::num32(0))
return cos_num32(-angle);
// Look for an angle in the range [0, 2*pi [
libnum::num32 anglereduced = angle;
while (anglereduced >= libnum::num32(2 * numPI))
anglereduced -= libnum::num32(2 * numPI);
// Exploit the symetry for angle and angle+Pi to reduce the order of the
// limited developpement
if (anglereduced >= libnum::num(numPI))
return -cos_num32(anglereduced - libnum::num(numPI));
libnum::num32 sum = libnum::num32(1);
libnum::num32 angle2 = anglereduced * anglereduced;
// set first value of the Taylor serie : x⁰/0! = 1/1
libnum::num32 numerator = libnum::num32(1);
libnum::num32 denominator = libnum::num32(1);
for (int i = 2; i <= 8; i += 2) {
numerator *= (-angle2);
denominator *= libnum::num32(i - 1) * libnum::num32(i);
sum += (numerator / denominator);
}
return sum;
}
libnum::num32 sin_num32(libnum::num32 angle) {
// Taylor serie for cos(x) = x/1! - x³/3! + x⁵/5! - x⁷/7! + x⁹/9! + ...
// Sine function is odd
if (angle < libnum::num32(0))
return -sin_num32(-angle);
// Look for an angle in the range [0, 2*pi [
libnum::num32 anglereduced = angle;
while (anglereduced >= libnum::num32(2 * numPI))
anglereduced -= libnum::num32(2 * numPI);
// Exploit the symetry for angle and angle+Pi to reduce the order of the
// limited developpement
if (anglereduced >= libnum::num(numPI))
return -sin_num32(anglereduced - libnum::num(numPI));
libnum::num32 sum = anglereduced;
libnum::num32 angle2 = anglereduced * anglereduced;
// set first value of the Taylor serie : x¹/1! = x/1
libnum::num32 numerator = anglereduced;
libnum::num32 denominator = libnum::num32(1);
for (int i = 2; i <= 8; i += 2) {
numerator *= (-angle2);
denominator *= libnum::num32(i) * libnum::num32(i + 1);
sum += (numerator / denominator);
}
return sum;
}
class Vector2D {
public:
Vector2D() {
this->x = libnum::num32(0);
this->y = libnum::num32(0);
}
Vector2D(float x, float y) {
this->x = libnum::num32(x);
this->y = libnum::num32(y);
}
Vector2D(libnum::num32 x, libnum::num32 y) {
this->x = x;
this->y = y;
}
Vector2D(const Vector2D &v) {
this->x = v.x;
this->y = v.y;
}
~Vector2D() {}
void Set(Vector2D v) {
this->x = v.x;
this->y = v.y;
}
void Normalise(void) {
libnum::num32 len = this->Length();
this->x /= len;
this->y /= len;
}
Vector2D Clone(void) {
Vector2D NewVector(this->x, this->y);
return NewVector;
}
Vector2D MakeVector(Vector2D A, Vector2D B) {
Vector2D NewVector(B.x - A.x, B.y - A.y);
return NewVector;
}
void AddVectors(Vector2D a, Vector2D b) {
this->x = a.x + b.x;
this->y = a.y + b.y;
}
void Add(Vector2D v, libnum::num32 scale) {
this->x += v.x * scale;
this->y += v.y * scale;
}
void SubtractVectors(Vector2D a, Vector2D b) {
this->x = a.x - b.x;
this->y = a.y - b.y;
}
void Subtract(Vector2D v, libnum::num32 scale) {
this->x -= v.x * scale;
this->y -= v.y * scale;
}
libnum::num32 Length(void) {
return sqrt_num32(this->x * this->x + this->y * this->y);
}
void Scale(libnum::num32 scale) {
this->x *= scale;
this->y *= scale;
}
libnum::num32 Dot(Vector2D v) { return (this->x * v.x + this->y * v.y); }
libnum::num32 Det(Vector2D v) { return (this->x * v.y - this->y * v.x); }
Vector2D PerpCW(void) {
Vector2D temp(-this->y, this->x);
return temp;
}
Vector2D PerpCCW(void) {
Vector2D temp(this->y, -this->x);
return temp;
}
/* overloading of most interesting operators */
libnum::num32 operator[](uint8_t pos) { return pos == 0 ? x : y; }
Vector2D &operator=(const Vector2D &v) {
this->x = v.x;
this->y = v.y;
return *this;
}
Vector2D operator+(const Vector2D &v) const {
return Vector2D(x + v.x, y + v.y);
}
Vector2D operator-(const Vector2D &v) const {
return Vector2D(x - v.x, y - v.y);
}
Vector2D &operator+=(Vector2D const &other) {
this->x += other.x;
this->y += other.y;
return *this;
}
Vector2D operator-() const { return (Vector2D(-x, -y)); }
Vector2D operator+() const { return *this; }
Vector2D &operator-=(Vector2D const &other) {
this->x -= other.x;
this->y -= other.y;
return *this;
}
Vector2D &operator*=(libnum::num32 scale) {
this->x *= scale;
this->y *= scale;
return *this;
}
Vector2D &operator/=(libnum::num32 scale) {
this->x /= scale;
this->y /= scale;
return *this;
}
friend Vector2D operator*(libnum::num32 scale, Vector2D const &v) {
Vector2D r;
r.x = v.x * scale;
r.y = v.y * scale;
return r;
}
friend Vector2D operator*(Vector2D const &v, libnum::num32 scale) {
Vector2D r;
r.x = v.x * scale;
r.y = v.y * scale;
return r;
}
friend Vector2D operator/(Vector2D const &v, libnum::num32 scale) {
Vector2D r;
r.x = v.x / scale;
r.y = v.y / scale;
return r;
}
libnum::num32 x;
libnum::num32 y;
};
Vector2D ClosestPointOnSegment(Vector2D P, Vector2D A, Vector2D B) {
Vector2D AB = B - A;
libnum::num32 t = AB.Dot(AB);
if (t == 0)
return A;
libnum::num32 t2 = (P.Dot(AB) - A.Dot(AB)) / t;
if (t2 < libnum::num32(0))
t2 = libnum::num32(0);
if (t2 > libnum::num32(1))
t2 = libnum::num32(1);
Vector2D C = A.Clone();
C.Add(AB, t2);
return C;
}
#endif