Working Catmull-Rom Splines for loopping trajectories of enemies

This commit is contained in:
Sylvain PILLOT 2023-01-23 22:03:09 +01:00
parent 47fb74d32c
commit 4e66ba1b80
11 changed files with 116 additions and 13 deletions

View File

@ -43,7 +43,7 @@ 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
# ...
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -59,6 +59,32 @@ void Create_Ennemies( void )
Enemy* e4 = new Enemy( 348, 112, 1);
e4->Set_Speed_Vector( 1, 3, 3 );
MyEnemies.push_back( e4 );
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 );
Enemy* e5 = new Enemy( 348, 112, 2);
e5->hasTrajectory = true;
e5->pathToFollow = MyTrajectory;
MyEnemies.push_back( e5 );
}

View File

@ -9,6 +9,7 @@
#include "enemy.h"
#include "MyAzurShaders.h"
#include "impact.h"
#include "trajectory.h"
void Create_Player_Shoot( uint8_t id );

View File

@ -5,6 +5,7 @@
extern bopti_image_t img_mainship2;
extern bopti_image_t img_Enemy_Blue_Lvl1;
extern bopti_image_t img_Enemy_Red_Lvl1;
Enemy::Enemy( int16_t _x, int16_t _y, uint8_t _id )
{
@ -28,6 +29,12 @@ Enemy::Enemy( int16_t _x, int16_t _y, uint8_t _id )
height = img_Enemy_Blue_Lvl1.height/2;
speed = 2;
}
else if (ID==2)
{
width = img_Enemy_Red_Lvl1.width/2;
height = img_Enemy_Red_Lvl1.height/2;
speed = 2;
}
xmin = (int) x - width;
xmax = (int) x + width;
@ -38,22 +45,33 @@ Enemy::Enemy( int16_t _x, int16_t _y, uint8_t _id )
if (ID==0) life = 400;
else if (ID==1) life = 200;
else if (ID==2) life = 100;
}
Enemy::~Enemy()
{
if (hasTrajectory)
delete(pathToFollow);
}
void Enemy::Update( float dt )
{
libnum::num a = libnum::num( dt / 60000.0f );
x += a * libnum::num( dirx * speed );
y += a * libnum::num( diry * speed );
if (!hasTrajectory)
{
libnum::num a = libnum::num( dt / 60000.0f );
x += a * libnum::num( dirx * speed );
y += a * libnum::num( diry * speed );
if (x<width || x>azrp_width-width) dirx=-1*dirx;
if (y<height || y>azrp_height-height) diry=-1*diry;
if (x<width || x>azrp_width-width) dirx=-1*dirx;
if (y<height || y>azrp_height-height) diry=-1*diry;
}
else
{
int tempX, tempY;
pathToFollow->CalculatePosition( dt, speed, true, &tempX, &tempY );
x = libnum::num( tempX );
y = libnum::num( tempY );
}
xmin = (int) x - width;
xmax = (int) x + width;
@ -65,8 +83,9 @@ void Enemy::Update( float dt )
void Enemy::Render( void )
{
if (ID==0) azrp_image_p8_effect(xmin, ymin, &img_mainship2, IMAGE_VFLIP);
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);
}

View File

@ -9,6 +9,7 @@
#include <num/num.h>
#include "bullet.h"
#include "trajectory.h"
class Enemy
@ -31,6 +32,8 @@ class Enemy
uint8_t speed; // speed of this ennemy
bool toberemoved;
bool hasTrajectory = false;
Trajectory *pathToFollow;
private:
int8_t dirx, diry; // vector of the current direction of the ennemy (TODO : to implement more complex displacement pattern)

View File

@ -1,4 +1,4 @@
#define DEBUG_MODE 1
#define DEBUG_MODE 0
#include <azur/azur.h>
#include <azur/gint/render.h>
@ -253,12 +253,13 @@ static void get_inputs( float dt )
if(keydown(KEY_8) && usb_is_open()) {record = true; };
if(keydown(KEY_9) && usb_is_open()) {record = false; };
if(keydown(KEY_DEL) && usb_is_open()) {textoutput = true;};
#endif
if(keydown(KEY_SHIFT) && keydown(KEY_F1)) {texttodraw=0;}
if(keydown(KEY_SHIFT) && keydown(KEY_F2)) {texttodraw=1;}
if(keydown(KEY_SHIFT) && keydown(KEY_F3)) {texttodraw=2;}
if(keydown(KEY_SHIFT) && keydown(KEY_F4)) {texttodraw=3;}
#endif
if(keydown(KEY_LEFT))
@ -344,6 +345,8 @@ void FreeMoreRAM( void )
}
extern bopti_image_t img_Enemy_Red_Lvl1;
int main(void)
{

View File

@ -2,12 +2,60 @@
Trajectory::Trajectory( )
{
accumulatedTime = 0.0f;
}
Trajectory::~Trajectory( )
{
for( auto& p : ControlPoints )
delete( p );
ControlPoints.clear();
}
void Trajectory::AddPoint( Point2D *p )
{
ControlPoints.push_back( p );
}
void Trajectory::CalculatePosition( float time, uint16_t speed, bool looped, int *xreturn, int *yreturn )
{
accumulatedTime += speed * time / 2000000.0f;
if (accumulatedTime>ControlPoints.size()) accumulatedTime-=ControlPoints.size();
libnum::num t = libnum::num( accumulatedTime - (int) accumulatedTime );
int p0, p1, p2, p3;
if (!looped)
{
p1 = (int) accumulatedTime + 1;
p2 = p1 + 1;
p3 = p2 + 1;
p0 = p1 - 1;
}
else
{
p1 = (int) accumulatedTime;
p2 = (p1 + 1) % ControlPoints.size();
p3 = (p2 + 1) % ControlPoints.size();
p0 = p1 >= 1 ? p1 - 1 : ControlPoints.size() - 1;
}
libnum::num tt = t * t;
libnum::num ttt = tt * t;
libnum::num q1 = -ttt + 2*tt - t;
libnum::num q2 = 3*ttt - 5*tt + libnum::num( 2 );
libnum::num q3 = -3*ttt + 4*tt + t;
libnum::num q4 = ttt - tt;
libnum::num tx = libnum::num( 0.5f ) * (ControlPoints[p0]->x * q1 + ControlPoints[p1]->x * q2 + ControlPoints[p2]->x * q3 + ControlPoints[p3]->x * q4);
libnum::num ty = libnum::num( 0.5f ) * (ControlPoints[p0]->y * q1 + ControlPoints[p1]->y * q2 + ControlPoints[p2]->y * q3 + ControlPoints[p3]->y * q4);
*xreturn = (int) tx;
*yreturn = (int) ty;
}

View File

@ -15,9 +15,12 @@ class Trajectory
Trajectory( );
~Trajectory( );
void AddPoint( Point2D *p );
void CalculatePosition( float time, uint16_t speed, bool looped, int *xreturn, int *yreturn );
std::vector<Point2D*> ControlPoints;
bool isLoop;
float accumulatedTime;
};