Working Catmull-Rom Splines for loopping trajectories of enemies
This commit is contained in:
parent
47fb74d32c
commit
4e66ba1b80
|
@ -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 |
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "enemy.h"
|
||||
#include "MyAzurShaders.h"
|
||||
#include "impact.h"
|
||||
#include "trajectory.h"
|
||||
|
||||
|
||||
void Create_Player_Shoot( uint8_t id );
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue