From: Matthew Owens Date: Fri, 2 Oct 2020 14:26:37 +0000 (+0100) Subject: moved collisions to their own file & added ball/paddle collision response X-Git-Url: https://git.owens.tech///git?a=commitdiff_plain;h=ffc97facfdcc5fecac3418fcdd869b9d61f7999b;p=pong.git moved collisions to their own file & added ball/paddle collision response --- diff --git a/src/collision.c b/src/collision.c new file mode 100644 index 0000000..4682ece --- /dev/null +++ b/src/collision.c @@ -0,0 +1,32 @@ +#include "collision.h" + +bool ll_collision(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, Vec2df *intersect) +{ + float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / + ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); + float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / + ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); + + if(intersect) { + intersect->x = x1 + (uA * (x2-x1)); + intersect->y = y1 + (uB * (y2-y1)); + } + + return (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1); +} + +/* + * (v)box / line collision + * returns 0 on no collision, 1/2/3/4 on left/right/top/bottom + */ +int lr_collision(Vec2df start, Vec2df end, SDL_Rect r, Vec2df *i) { + if(ll_collision(start.x, start.y, end.x, end.y, r.x, r.y, r.x, r.y + r.h, i)) + return 1; //left + if(ll_collision(start.x, start.y, end.x, end.y, r.x + r.w, r.y, r.x + r.w, r.y + r.h, i)) + return 2; //right + if(ll_collision(start.x, start.y, end.x, end.y, r.x, r.y, r.x + r.w, r.y , i)) + return 3; //top + if(ll_collision(start.x, start.y, end.x, end.y, r.x, r.y + r.h, r.x + r.w, r.y + r.h, i)) + return 4; //bottom +} diff --git a/src/collision.h b/src/collision.h new file mode 100644 index 0000000..38111a8 --- /dev/null +++ b/src/collision.h @@ -0,0 +1,8 @@ +#pragma once +#include +#include +#include "vec2d.h" + +bool ll_collision(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, Vec2df *intersect); +int lr_collision(Vec2df start, Vec2df end, SDL_Rect r, Vec2df *i); diff --git a/src/main.c b/src/main.c index e200376..8eb04c4 100644 --- a/src/main.c +++ b/src/main.c @@ -4,16 +4,8 @@ #include #include #include "timestep.h" - -typedef struct Vec2di { - int x; - int y; -} Vec2di; - -typedef struct Vec2df { - float x; - float y; -} Vec2df; +#include "collision.h" +#include "vec2d.h" typedef struct Colour { Uint8 r; @@ -90,36 +82,6 @@ static void vbox_render(const Vbox *b) SDL_RenderFillRect(renderer, &b->r); } -static bool ll_collision(float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4, Vec2df *intersect) -{ - float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / - ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); - float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / - ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); - - if(intersect) { - intersect->x = x1 + (uA * (x2-x1)); - intersect->y = y1 + (uB * (y2-y1)); - } - - return (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1); -} - -/* - * (v)box / line collision - * returns 0 on no collision, 1/2/3/4 on left/right/top/bottom - */ -static int lr_collision(Vec2df start, Vec2df end, SDL_Rect r, Vec2df *i) { - if(ll_collision(start.x, start.y, end.x, end.y, r.x, r.y, r.x, r.y + r.h, i)) - return 1; //left - if(ll_collision(start.x, start.y, end.x, end.y, r.x + r.w, r.y, r.x + r.w, r.y + r.h, i)) - return 2; //right - if(ll_collision(start.x, start.y, end.x, end.y, r.x, r.y, r.x + r.w, r.y , i)) - return 3; //top - if(ll_collision(start.x, start.y, end.x, end.y, r.x, r.y + r.h, r.x + r.w, r.y + r.h, i)) - return 4; //bottom -} static void paddle_update(const Uint8* keyStates, float dt) { @@ -146,10 +108,6 @@ static void ball_update(float dt) float halfw = ball.r.w / 2; float halfh = ball.r.h / 2; - // applying velocity - ball.r.x += ball.v.x * dt; - ball.r.y += ball.v.y * dt; - // velocity projection start to center of ball vline[0].x = ball.r.x + halfw; vline[0].y = ball.r.y + halfh; @@ -165,17 +123,41 @@ static void ball_update(float dt) // are we going to collide with the paddle? { int willCollide = lr_collision(vline[0], vline[1], pad.r, NULL); + // left/right/top/bottom switch(willCollide) { //TODO: set ball loc to colliding wall, invert vel & skip vel add + case 1: + ball.r.x = pad.r.x - ball.r.w; + ball.v.x *= -1; + break; + case 2: + ball.r.x = pad.r.x + pad.r.w; + ball.v.x *= -1; + break; + case 3: + ball.r.y = pad.r.y - ball.r.h; + ball.v.y *= -1; + break; + case 4: + ball.r.y = pad.r.y + pad.r.h; + ball.v.y *= -1; + break; } + if(willCollide != 0) { collisionResponded = true; } + } + + // applying velocity if needed + if(!collisionResponded) { + ball.r.x += ball.v.x * dt; + ball.r.y += ball.v.y * dt; } // screen bounds checks & responses - if(ball.r.x + ball.r.w > windowSize.x && !collisionResponded){ + if(ball.r.x + ball.r.w > windowSize.x){ ball.r.x = windowSize.x - ball.r.w; ball.v.x *= -1; } - if(ball.r.y + ball.r.h > windowSize.y && !collisionResponded){ + if(ball.r.y + ball.r.h > windowSize.y){ ball.r.y = windowSize.y - ball.r.h; ball.v.y *= -1; } diff --git a/src/vec2d.h b/src/vec2d.h new file mode 100644 index 0000000..664718b --- /dev/null +++ b/src/vec2d.h @@ -0,0 +1,12 @@ +#pragma once + +typedef struct Vec2di { + int x; + int y; +} Vec2di; + +typedef struct Vec2df { + float x; + float y; +} Vec2df; +