enemy shoots + scrolable background

This commit is contained in:
Sylvain PILLOT 2023-02-05 10:05:05 +01:00
parent 7df7b70f5d
commit b4203610a0
21 changed files with 309 additions and 164 deletions

View File

@ -30,6 +30,7 @@ add_custom_command(
set(SOURCES
src/main.cpp
src/fast_trig.cpp
src/extrakeyboard.cpp
src/collections.cpp
@ -57,10 +58,12 @@ set(ASSETS_cg
assets-cg/Sprites/Bullets/bullet_normal.png
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/Players/mainship1.png
assets-cg/Sprites/Players/Satellite_Lvl1.png
assets-cg/Sprites/Enemies/Lifebar.png
assets-cg/Sprites/Enemies/mainship2.png
assets-cg/Sprites/Enemies/Enemy_Blue_Lvl1.png
assets-cg/Sprites/Enemies/Enemy_Red_Lvl1.png

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,14 +0,0 @@
{ "columns":32,
"image":"tileset.png",
"imageheight":1024,
"imagewidth":512,
"margin":0,
"name":"Tileset_Space",
"spacing":0,
"tilecount":2048,
"tiledversion":"1.8.0",
"tileheight":16,
"tilewidth":16,
"type":"tileset",
"version":"1.8"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -12,32 +12,36 @@
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;
Bullet::Bullet( uint16_t lx, uint16_t ly, uint8_t id )
Bullet::Bullet( uint16_t lx, uint16_t ly, int16_t dx, int16_t dy, uint8_t id )
{
x = libnum::num( lx );
y = libnum::num( ly );
sx = libnum::num( dx );
sy = libnum::num( dy );
ID=id;
if (ID==0)
if (ID==BULLET_NORMAL)
{
sx = libnum::num( 6 );
sy = 0;
strength = 5;
}
else if (ID==1)
else if (ID==BULLET_BLUE)
{
sx = libnum::num( 3 );
sy = 0;
strength = 2;
}
else if (ID==2)
else if (ID==BULLET_LASER)
{
sx = libnum::num( 3 );
sy = 0;
strength = 1;
}
else if (ID==BULLET_ENEMY_BLUE)
{
strength = 2;
}
toberemoved = false;
}
@ -58,23 +62,28 @@ void Bullet::Update( float dt )
void Bullet::Render( )
{
uint16_t px = (int) x;
uint16_t py = (int) y;
int16_t px = (int) x;
int16_t py = (int) y;
if (ID==0)
if (ID==BULLET_NORMAL)
{
azrp_image_p8( px-img_bullet_normal.width/2, py-img_bullet_normal.height/2, &img_bullet_normal, DIMAGE_NONE );
return;
}
else if (ID==1)
else if (ID==BULLET_BLUE)
{
azrp_image_p8( px-img_bullet_blue.width/2, py-img_bullet_blue.height/2, &img_bullet_blue, DIMAGE_NONE );
return;
}
else if (ID==2)
else if (ID==BULLET_LASER)
{
azrp_image_p8( px-img_bullet_laser.width/2, py-img_bullet_laser.height/2, &img_bullet_laser, DIMAGE_NONE );
return;
}
else if (ID==BULLET_ENEMY_BLUE)
{
azrp_image_p8( px-img_bullet_enemy_blue.width/2, py-img_bullet_enemy_blue.height/2, &img_bullet_enemy_blue, DIMAGE_NONE );
return;
}
}

View File

@ -4,10 +4,20 @@
#include <cstdint>
#include <num/num.h>
enum
{
BULLET_NORMAL,
BULLET_BLUE,
BULLET_LASER,
BULLET_ENEMY_BLUE,
};
class Bullet
{
public:
Bullet( uint16_t lx, uint16_t ly, uint8_t id );
Bullet( uint16_t lx, uint16_t ly, int16_t dx, int16_t dy, uint8_t id );
~Bullet();
void Update( float dt );
void Render();

View File

@ -5,9 +5,13 @@
extern std::vector<Particle*> MyParticles;
extern std::vector<Bullet*> MyPlayerBullets;
extern std::vector<Bullet*> MyEnemiesBullets;
extern std::vector<Enemy*> MyEnemies;
extern std::vector<Impact*> MyImpacts;
extern Player *MyPlayer;
@ -15,33 +19,34 @@ extern Player *MyPlayer;
void Create_Player_Shoot( uint8_t id )
{
if (id==0)
if (id==BULLET_NORMAL)
{
Bullet *b = new Bullet( (int) MyPlayer->x+21, (int) MyPlayer->y, id );
Bullet *b = new Bullet( (int) MyPlayer->x+21, (int) MyPlayer->y, 6, 0, id );
MyPlayerBullets.push_back( b );
}
else if (id==1)
else if (id==BULLET_BLUE)
{
Bullet *b1 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y-17, id );
Bullet *b1 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y-17, 5, 0, id );
MyPlayerBullets.push_back( b1 );
Bullet *b2 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y+17, id );
Bullet *b2 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y+17, 5, 0, id );
MyPlayerBullets.push_back( b2 );
}
else if (id==2)
else if (id==BULLET_LASER)
{
Bullet *b1 = new Bullet( (int) MyPlayer->x+21, (int) MyPlayer->y, id );
Bullet *b1 = new Bullet( (int) MyPlayer->x+21, (int) MyPlayer->y, 3, 0, id );
MyPlayerBullets.push_back( b1 );
Bullet *b2 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y-17, id );
Bullet *b2 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y-17, 3, 0, id );
MyPlayerBullets.push_back( b2 );
Bullet *b3 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y+17, id );
Bullet *b3 = new Bullet( (int) MyPlayer->x, (int) MyPlayer->y+17, 3, 0, id );
MyPlayerBullets.push_back( b3 );
}
}
void Create_Ennemies( void )
void Create_Enemies( void )
{
Enemy* e1 = new Enemy( 348, 112, 0);
e1->Set_Speed_Vector( 1, 1, -6 );
@ -129,6 +134,21 @@ void Clean_Everything( void )
MyPlayerBullets.erase( MyPlayerBullets.begin() + i );
}
MyPlayerBullets.clear();
for(unsigned int i=0; i<MyEnemiesBullets.size(); i++)
{
delete( MyEnemiesBullets[i] );
MyEnemiesBullets.erase( MyEnemiesBullets.begin() + i );
}
MyEnemiesBullets.clear();
for(unsigned int i=0; i<MyImpacts.size(); i++)
{
delete( MyImpacts[i] );
MyImpacts.erase( MyImpacts.begin() + i );
}
MyImpacts.clear();
}

View File

@ -13,7 +13,7 @@
void Create_Player_Shoot( uint8_t id );
void Create_Ennemies( void );
void Create_Enemies( void );
void Create_Explosion( uint16_t xexplosion, uint16_t yexplosion );
void Create_Impact( uint16_t ximpact, uint16_t yimpact );

View File

@ -1,12 +1,18 @@
#include "enemy.h"
#include "bullet.h"
#include <num/num.h>
#include <gint/rtc.h>
extern bopti_image_t img_Lifebar;
extern bopti_image_t img_mainship2;
extern bopti_image_t img_Enemy_Blue_Lvl1;
extern bopti_image_t img_Enemy_Red_Lvl1;
extern std::vector<Bullet*> MyEnemiesBullets;
Enemy::Enemy( int16_t _x, int16_t _y, uint8_t _id )
{
x = libnum::num( _x );
@ -22,18 +28,21 @@ Enemy::Enemy( int16_t _x, int16_t _y, uint8_t _id )
width = img_mainship2.width/2;
height = img_mainship2.height/2;
speed = 1;
life = 400;
}
else if (ID==1)
{
width = img_Enemy_Blue_Lvl1.width/2;
height = img_Enemy_Blue_Lvl1.height/2;
speed = 2;
life = 200;
}
else if (ID==2)
{
width = img_Enemy_Red_Lvl1.width/2;
height = img_Enemy_Red_Lvl1.height/2;
speed = 2;
life = 100;
}
xmin = (int) x - width;
@ -43,9 +52,7 @@ Enemy::Enemy( int16_t _x, int16_t _y, uint8_t _id )
toberemoved = false;
if (ID==0) life = 400;
else if (ID==1) life = 200;
else if (ID==2) life = 100;
lastshottime = 0;
}
Enemy::~Enemy()
@ -75,14 +82,62 @@ void Enemy::Update( float dt )
ymin = (int) y - height;
ymax = (int) y + height;
uint32_t tempshoot = rtc_ticks();
if (Shoot_OK( tempshoot ))
{
if ( ID==0 )
{
Bullet *b = new Bullet( xmin, (int) y, -3, 0, BULLET_ENEMY_BLUE );
MyEnemiesBullets.push_back( b );
}
else if ( ID==1 )
{
Bullet *b1 = new Bullet( xmin, (int) y, -5, 0, BULLET_ENEMY_BLUE );
MyEnemiesBullets.push_back( b1 );
Bullet *b2 = new Bullet( xmin, (int) y, -5, 0, BULLET_ENEMY_BLUE );
MyEnemiesBullets.push_back( b2 );
}
else if ( ID==2 )
{
Bullet *b = new Bullet( xmin, (int) y, -1, 0, BULLET_ENEMY_BLUE );
MyEnemiesBullets.push_back( b );
}
}
if (life<=0) toberemoved=true;
}
void Enemy::Render( void )
{
if (ID==0) azrp_image_p8_effect(xmin, ymin, &img_mainship2, DIMAGE_NONE);
if (ID==1) azrp_image_p8_effect(xmin, ymin, &img_Enemy_Blue_Lvl1, DIMAGE_NONE);
if (ID==2) azrp_image_p8_effect(xmin, ymin, &img_Enemy_Red_Lvl1, DIMAGE_NONE);
azrp_subimage_p8_effect( (int) x - img_Lifebar.width/2, ymin - 10, &img_Lifebar, 0, 0, img_Lifebar.width, 7, DIMAGE_NONE );
int life0=100;
if (ID==0)
{
azrp_image_p8_effect(xmin, ymin, &img_mainship2, DIMAGE_NONE);
life0 = 400;
}
else if (ID==1)
{
azrp_image_p8_effect(xmin, ymin, &img_Enemy_Blue_Lvl1, DIMAGE_NONE);
life0 = 200;
}
else if (ID==2)
{
azrp_image_p8_effect(xmin, ymin, &img_Enemy_Red_Lvl1, DIMAGE_NONE);
life0 = 100;
}
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 );
}
@ -102,4 +157,15 @@ void Enemy::Set_Speed_Vector( uint8_t _sp, uint8_t _xd, uint8_t _yd)
speed = _sp;
dirx = _xd;
diry = _yd;
}
bool Enemy::Shoot_OK( uint32_t tempshoot )
{
if(tempshoot-lastshottime>15)
{
lastshottime=tempshoot;
return true;
}
else return false;
}

View File

@ -37,6 +37,10 @@ class Enemy
private:
int8_t dirx, diry; // vector of the current direction of the ennemy (TODO : to implement more complex displacement pattern)
uint32_t lastshottime;
bool Shoot_OK( uint32_t tempshoot );
};

61
src/fast_trig.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "fast_trig.h"
#include "num/num.h"
static libnum::num cosTable[360];
static libnum::num sinTable[360];
void Fast_Trig_Init( void )
{
for(int u=0; u<360; u++)
{
cosTable[u] = libnum::num( cos( u * PI / 180 ) );
sinTable[u] = libnum::num( sin( u * PI / 180 ) );
}
}
libnum::num FastCos( int16_t angle )
{
if (angle>=0 and angle<360) return cosTable[ angle ];
else
{
int16_t input = angle;
if (input<0)
{
while (input<0) input+=360;
return cosTable[ angle ];
}
else
{
while (input>=360) input-=360;
return cosTable[ angle ];
}
}
}
libnum::num FastSin( int16_t angle )
{
if (angle>=0 and angle<360) return sinTable[ angle ];
else
{
int16_t input = angle;
if (input<0)
{
while (input<0) input+=360;
return sinTable[ angle ];
}
else
{
while (input>=360) input-=360;
return sinTable[ angle ];
}
}
}
libnum::num FastTan( int16_t angle )
{
//TODO : work on representation of infinite number for angle = 90 degrees or angle = 270 degrees
return libnum::num(0);
}

19
src/fast_trig.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef FAST_TRIG_H
#define FAST_TRIG_H
#include <cmath>
#include <num/num.h>
#define PI 3.141592
void Fast_Trig_Init( void );
libnum::num FastCos( int16_t angle );
libnum::num FastSin( int16_t angle );
libnum::num FastTan( int16_t angle );
#endif

View File

@ -1,4 +1,4 @@
#define DEBUG_MODE 0
#define DEBUG_MODE 1
#include <azur/azur.h>
#include <azur/gint/render.h>
@ -20,6 +20,7 @@
#include <num/num.h>
#include "fast_trig.h"
#include "extrakeyboard.h"
#include "collections.h"
@ -72,6 +73,7 @@ kmalloc_gint_stats_t *extram_stats;
std::vector<Particle*> MyParticles;
std::vector<Bullet*> MyPlayerBullets;
std::vector<Bullet*> MyEnemiesBullets;
std::vector<Enemy*> MyEnemies;
std::vector<Impact*> MyImpacts;
@ -138,6 +140,9 @@ static void update( float dt )
{
MyEnemies[i]->Update( dt );
// Check if there is a collision with the current enemy
//MyPlayer->Test_Collision( MyEnemies[i] );
// Check if the property toberemoved has been set to "true" for particle deletion
if (MyEnemies[i]->toberemoved == true)
{
@ -181,6 +186,26 @@ static void update( float dt )
}
}
for(unsigned int i=0; i<MyEnemiesBullets.size(); i++)
{
MyEnemiesBullets[i]->Update( dt );
if(MyPlayer->Test_Impact(MyEnemiesBullets[i])==true)
{
//TODO : we can create a list of impacts here, to be rendered later on
Create_Impact( (int) MyEnemiesBullets[i]->x, (int) MyEnemiesBullets[i]->y );
}
// Check if the property toberemoved has been set to "true" for particle deletion
if (MyEnemiesBullets[i]->toberemoved == true)
{
delete( MyEnemiesBullets[i] );
MyEnemiesBullets.erase( MyEnemiesBullets.begin() + i );
}
}
MyBackground.Update( dt );
}
@ -199,6 +224,9 @@ static void render( void )
for(auto& b : MyPlayerBullets)
b->Render();
for(auto& b : MyEnemiesBullets)
b->Render();
for(auto& e : MyEnemies)
e->Render();
@ -235,17 +263,17 @@ static void get_inputs( float dt )
if(MyKeyboard.IsKeyPressed(MYKEY_F1))
{
if (MyPlayer->Shoot_OK(tempshoot, 0)) Create_Player_Shoot(0);
if (MyPlayer->Shoot_OK(tempshoot, BULLET_NORMAL)) Create_Player_Shoot(0);
}
if(MyKeyboard.IsKeyPressed(MYKEY_F2))
{
if (MyPlayer->Shoot_OK(tempshoot, 1)) Create_Player_Shoot(1);
if (MyPlayer->Shoot_OK(tempshoot, BULLET_BLUE)) Create_Player_Shoot(1);
}
if(MyKeyboard.IsKeyPressedEvent(MYKEY_F3))
{
if (MyPlayer->Shoot_OK(tempshoot, 2)) Create_Player_Shoot(2);
if (MyPlayer->Shoot_OK(tempshoot, BULLET_LASER)) Create_Player_Shoot(2);
}
if (MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyHoldPressed(MYKEY_EXIT)) {exitToOS = true; };
@ -286,7 +314,7 @@ bool AddMoreRAM( void )
extended_ram.name = "extram";
extended_ram.is_default = true;
extended_ram.start = (void *)0x8c200000;
extended_ram.end = (void *)0x8c500000 ;
extended_ram.end = (void *)0x8c4e0000 ;
kmalloc_init_arena(&extended_ram, true);
kmalloc_add_arena(&extended_ram );
@ -316,7 +344,7 @@ bool AddMoreRAM( void )
extended_ram.name = "extram";
extended_ram.is_default = true;
extended_ram.start = (void *)0x88200000;
extended_ram.end = (void *)0x88500000 ;
extended_ram.end = (void *)0x884e0000 ;
kmalloc_init_arena(&extended_ram, true);
kmalloc_add_arena(&extended_ram );
@ -329,15 +357,35 @@ void FreeMoreRAM( void )
memset(extended_ram.start, 0, (char *)extended_ram.end - (char *)extended_ram.start);
}
/*
#define DBGCRSH 1
#include <gint/keyboard.h>
int a=0;
void debug_crash( int value )
{
dprint( 1, 1+a*10, C_BLACK, "point = %d : REACHED", value );
a++;
dupdate();
getkey();
}
extern bopti_image_t img_Enemy_Red_Lvl1;
void debug_crash_msg( char *chain )
{
dprint( 1, 1+a*10, C_BLACK, "point = %s : REACHED", chain );
a++;
dupdate();
getkey();
}
*/
int main(void)
{
exitToOS = false;
Fast_Trig_Init();
_uram = kmalloc_get_arena("_uram");
bool canWeAllocate3Mb = AddMoreRAM();
@ -354,11 +402,15 @@ int main(void)
azrp_starfield_init( 250 );
Create_Ennemies( );
Create_Enemies( );
MyPlayer = new Player( azrp_width/4, azrp_height/2, 0);
/*
#if(DBGCRSH)
debug_crash( 1 );
#endif
*/
usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL };
usb_open(interfaces, GINT_CALL_NULL);
@ -398,6 +450,7 @@ int main(void)
render();
azrp_update();
}
prof_leave(perf_render);

View File

@ -3,17 +3,16 @@
#include "enemy.h"
#include <num/num.h>
#include <gint/rtc.h>
#include <math.h>
#include "fast_trig.h"
#include "background.h"
extern bopti_image_t img_Lifebar;
extern bopti_image_t img_mainship1;
extern bopti_image_t img_Satellite_Lvl1;
extern Background MyBackground;
static int16_t cosTable[360], sinTable[360];
#define PI 3.141592
Player::Player( int16_t _x, int16_t _y, uint8_t _id )
{
x = libnum::num(_x);
@ -42,12 +41,6 @@ Player::Player( int16_t _x, int16_t _y, uint8_t _id )
satAngle = 0;
satRadius = 50;
satSpeed = 2;
for(int u=0; u<360; u++)
{
cosTable[u] = (int16_t) (satRadius*cos( u * PI / 180 ));
sinTable[u] = (int16_t) (satRadius*sin( u * PI / 180 ));
}
}
Player::~Player()
@ -72,6 +65,8 @@ void Player::Update( float dt )
void Player::Render( void )
{
azrp_subimage_p8_effect( (int) x - img_Lifebar.width/2, ymin - 10, &img_Lifebar, 0, 0, img_Lifebar.width, 7, DIMAGE_NONE );
if (ID==0) azrp_image_p8_effect(xmin, ymin, &img_mainship1, DIMAGE_NONE);
int w = img_Satellite_Lvl1.width/2;
@ -85,11 +80,18 @@ void Player::Render( void )
{
int angle = (int) satAngle + u*incangle;
angle = angle % 360;
int xsat = (int) x + cosTable[angle];
int ysat = (int) y + sinTable[angle];
int xsat = (int) (x + FastCos( angle ) * libnum::num( satRadius) );
int ysat = (int) (y + FastSin( angle ) * libnum::num( satRadius) );
azrp_image_p8_effect(xsat-w, ysat-h, &img_Satellite_Lvl1, DIMAGE_NONE);
}
}
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 );
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 );
}
@ -104,7 +106,7 @@ bool Player::Test_Impact( Bullet *projectile )
else return false;
}
bool Player::Test_Impact( Enemy *adverseship )
bool Player::Test_Collision( Enemy *adverseship )
{
if (adverseship->xmax >= xmin && adverseship->xmin <= xmax && adverseship->ymax >= ymin && adverseship->ymin <= ymax )
{
@ -122,7 +124,7 @@ void Player::Set_Speed( uint8_t _sp )
bool Player::Shoot_OK( uint32_t tempshoot, uint8_t shootID )
{
if (shootID==0)
if (shootID==BULLET_NORMAL)
{
if(tempshoot-lastshoot0>8)
{
@ -131,7 +133,7 @@ bool Player::Shoot_OK( uint32_t tempshoot, uint8_t shootID )
}
else return false;
}
else if (shootID==1)
else if (shootID==BULLET_BLUE)
{
if(tempshoot-lastshoot1>15)
{
@ -140,7 +142,7 @@ bool Player::Shoot_OK( uint32_t tempshoot, uint8_t shootID )
}
else return false;
}
else if (shootID==2)
else if (shootID==BULLET_LASER)
{
if(tempshoot-lastshoot2>2)
{

View File

@ -22,7 +22,7 @@ class Player
void Render( void );
bool Test_Impact( Bullet *projectile );
bool Test_Impact( Enemy *adverseship );
bool Test_Collision( Enemy *adverseship );
void Set_Speed( uint8_t _sp );
bool Shoot_OK( uint32_t tempshoot, uint8_t shootID );

View File

@ -279,7 +279,7 @@ void azrp_starfield( void )
cmd.nbpixel = pixels.size();
cmd.data = pixels.data();
for(int i=0; i<pixels.size(); i++)
for(unsigned int i=0; i<pixels.size(); i++)
{
pixels[i]->x = (pixels[i]->x - pixels[i]->s) % 396;
pixels[i]->frag = pixels[i]->y / 16;