rendering + flippers' motion working

This commit is contained in:
Sylvain PILLOT 2023-05-27 23:25:48 +02:00
parent 4a94bceb8f
commit 3bfd6eac80
3 changed files with 145 additions and 21 deletions

View File

@ -6,3 +6,8 @@ Add background pictures
Add targets and enable bonus
Add multiple flippers all around the tables/boards
Add the possibilty to have connected tables using a king on tunnel
Add ball launcher with user controle initial velocity

View File

@ -75,6 +75,9 @@ void SetupScene(void) {
simHeight = libnum::num32(azrp_height) / cScale;
MyPinball.score = 0;
MyPinball.gravity.Set( Vector2D( libnum::num32(0.0), libnum::num32(-3.0) ) );
MyPinball.pause = true;
MyPinball.borders.clear();
MyPinball.borders.push_back( Vector2D( libnum::num32(0.74) , libnum::num32(0.25)));
@ -144,7 +147,7 @@ void HandleBallBallCollision( Ball ball1, Ball ball2 )
ball2.vel.Add(dir, newV2-v2 );
}
void HandleBallOsbtacleCollision( Ball ball, Obstacle obstacle )
void HandleBallObstacleCollision( Ball ball, Obstacle obstacle )
{
Vector2D dir = ball.pos - obstacle.pos;
libnum::num32 d = dir.Length();
@ -161,6 +164,94 @@ void HandleBallOsbtacleCollision( Ball ball, Obstacle obstacle )
MyPinball.score++;
}
void HandleBallFlipperCollision( Ball ball, Flipper flipper )
{
Vector2D closest = ClosestPointOnSegment( ball.pos, flipper.pos, flipper.getTip() );
Vector2D dir;
dir.SubtractVectors( ball.pos, closest );
libnum::num32 d = dir.Length();
if ( d==libnum::num32(0) || d > (ball.radius + flipper.radius) ) return;
dir.Normalise();
libnum::num32 corr = ball.radius + flipper.radius-d;
ball.pos.Add(dir, corr);
/* Update velocity */
Vector2D radius = closest.Clone();
radius.Add( dir, flipper.radius );
radius.Subtract( flipper.pos, libnum::num32(1) );
Vector2D surfaceVel = radius.PerpCW();
surfaceVel.Scale( flipper.currentAngularVelocity );
libnum::num32 v = ball.vel.Dot( dir );
libnum::num32 newV = surfaceVel.Dot( dir );
ball.vel.Add( dir, newV - v );
}
void HandleBallBorderCollision( Ball ball, std::vector<Vector2D> border )
{
int mod = border.size();
if (mod<3) return;
/* Find closest segment */
Vector2D d, closest, ab, normal;
libnum::num32 minDist = libnum::num32(0);
for( int i=0; i<mod; i++)
{
Vector2D a = border[i];
Vector2D b = border[(i+1) % mod];
Vector2D c = ClosestPointOnSegment( ball.pos, a, b );
d.SubtractVectors(ball.pos, c);
libnum::num32 dist = d.Length();
if (i==0 || dist <minDist)
{
minDist = dist;
closest.Set( c );
ab.SubtractVectors(b, a);
normal = ab.PerpCW();
}
}
/* Push out */
d.SubtractVectors( ball.pos, closest );
libnum::num32 dist = d.Length();
if (dist == libnum::num32(0))
{
d.Set( normal );
dist = normal.Length();
}
d.Normalise();
if( d.Dot( normal ) >= libnum::num32(0) )
{
if ( dist > ball.radius ) return;
ball.pos.Add( d, ball.radius - dist );
}
else ball.pos.Add( d, -(ball.radius + dist) );
/* Update velocity */
libnum::num32 v = ball.vel.Dot( d );
libnum::num32 newV = ABS(v) * ball.restitution;
ball.vel.Add( d, newV - v );
}
static void hook_prefrag(int id, void *fragment, int size) {
if (!screenshot && !record)
@ -193,7 +284,26 @@ static void hook_prefrag(int id, void *fragment, int size) {
}
}
static void update(float dt) {}
static void update(float dt)
{
MyPinball.dt = libnum::num32( dt );
for( int i=0; i<MyPinball.flippers.size(); i++ ) MyPinball.flippers[i].Simulate( MyPinball.dt );
for( int i=0; i<MyPinball.balls.size(); i++ )
{
MyPinball.balls[i].Simulate( MyPinball.dt, MyPinball.gravity );
for( int j=0; j<MyPinball.balls.size(); j++ ) HandleBallBallCollision( MyPinball.balls[i], MyPinball.balls[j] );
for( int j=0; j<MyPinball.obstacles.size(); j++ ) HandleBallObstacleCollision( MyPinball.balls[i], MyPinball.obstacles[j] );
for( int j=0; j<MyPinball.flippers.size(); j++ ) HandleBallFlipperCollision( MyPinball.balls[i], MyPinball.flippers[j] );
HandleBallBorderCollision( MyPinball.balls[i], MyPinball.borders );
}
}
static void render(void) {
@ -210,16 +320,17 @@ static void render(void) {
{
libnum::num32 angleflip = MyPinball.flippers[i].restAngle + MyPinball.flippers[i].sign * MyPinball.flippers[i].rotation;
azrp_filledcircle( CX(MyPinball.flippers[i].pos), CY(MyPinball.flippers[i].pos), (int) (MyPinball.flippers[i].radius*cScale), C_GREEN );
Vector2D extremity = MyPinball.flippers[i].pos.Clone();
extremity.x += COS(angleflip)*MyPinball.flippers[i].length;
extremity.y += SIN(angleflip)*MyPinball.flippers[i].length;
azrp_filledcircle( CX(extremity), CY(extremity), (int) (MyPinball.flippers[i].radius*cScale), C_GREEN );
azrp_line( CX(MyPinball.flippers[i].pos), CY(MyPinball.flippers[i].pos), CX(extremity), CY(extremity), C_GREEN );
azrp_filledcircle( CX(MyPinball.flippers[i].getTip()), CY(MyPinball.flippers[i].getTip()), (int) (MyPinball.flippers[i].radius*cScale), C_GREEN );
azrp_line( CX(MyPinball.flippers[i].pos), CY(MyPinball.flippers[i].pos), CX(MyPinball.flippers[i].getTip()), CY(MyPinball.flippers[i].getTip()), C_GREEN );
}
azrp_draw_text(150, 01, "FPS = %.0f - Mem Free = %d", (float)(1000.0f / elapsedTime), _uram_stats->free_memory + extram_stats->free_memory);
azrp_draw_text(150, 0, "FPS = %.0f - Mem Free = %d", (float)(1000.0f / elapsedTime), _uram_stats->free_memory + extram_stats->free_memory);
azrp_draw_text(150, 20, "Score : %d", MyPinball.score );
}
static void get_inputs(float dt) {
@ -228,6 +339,23 @@ static void get_inputs(float dt) {
exitToOS = true;
};
if (MyKeyboard.IsKeyPressed(MYKEY_F1)) {
MyPinball.flippers[0].touchIdentifier = libnum::num32(0);
}
else {
MyPinball.flippers[0].touchIdentifier = libnum::num32(-1);
}
if (MyKeyboard.IsKeyPressed(MYKEY_F6)) {
MyPinball.flippers[1].touchIdentifier = libnum::num32(0);
}
else {
MyPinball.flippers[1].touchIdentifier = libnum::num32(-1);
}
#if (DEBUG_MODE)
if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) &&
MyKeyboard.IsKeyPressedEvent(MYKEY_7) && usb_is_open()) {
@ -242,18 +370,7 @@ static void get_inputs(float dt) {
record = false;
};
if (MyKeyboard.IsKeyPressedEvent(MYKEY_F1)) {
}
if (MyKeyboard.IsKeyPressedEvent(MYKEY_F2)) {
}
if (MyKeyboard.IsKeyPressedEvent(MYKEY_F3)) {
}
if (MyKeyboard.IsKeyPressedEvent(MYKEY_F4)) {
}
if (MyKeyboard.IsKeyPressedEvent(MYKEY_F5)) {
}
if (MyKeyboard.IsKeyPressedEvent(MYKEY_F6)) {
}
#endif
/* we can have either LEFT or RIGHT or NONE OF THEM pressed for the direction

View File

@ -69,10 +69,11 @@ public:
if (pressed)
this->rotation = MIN(this->rotation + dt * this->angularVelocity, this->maxRotation);
else
this->rotation = MAX(this->rotation - dt * this->angularVelocity, 0.0);
this->rotation = MAX(this->rotation - dt * this->angularVelocity, libnum::num(0.0) );
this->currentAngularVelocity = this->sign * (this->rotation - prevRotation) / dt;
}
/*
bool Select(Vector2D pos)
{
Vector2D D;;
@ -80,6 +81,7 @@ public:
bool test = (D.Length() < this->length);
return test;
}
*/
Vector2D getTip()
{