From: Matthew Owens Date: Fri, 2 Oct 2020 13:00:06 +0000 (+0100) Subject: added collision detection functions X-Git-Url: https://git.owens.tech///git?a=commitdiff_plain;h=b037fd12068b677aa91af119a068a1f72315ec67;p=pong.git added collision detection functions --- diff --git a/src/main.c b/src/main.c index e686468..e200376 100644 --- a/src/main.c +++ b/src/main.c @@ -90,6 +90,37 @@ 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) { pad.v.x = 0; @@ -112,18 +143,32 @@ static void paddle_update(const Uint8* keyStates, float dt) static void ball_update(float dt) { bool collisionResponded = false; + 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; - vline[0].x = ball.r.x + ball.r.w / 2; - vline[0].y = ball.r.y + ball.r.h / 2; - - // todo: fix - // terniary should be replaced with the size of the ball * normalised vel - vline[1].x = vline[0].x + ball.v.x + ( ball.v.x > 0 ? ball.r.w / 2 : 0); - vline[1].y = vline[0].y + ball.v.y + ( ball.v.y > 0 ? ball.r.h / 2 : 0); - + // velocity projection start to center of ball + vline[0].x = ball.r.x + halfw; + vline[0].y = ball.r.y + halfh; + + // setting velocity projection end + vline[1].x = vline[0].x + ball.v.x; + if(ball.v.x > 0) { vline[1].x += halfw; } + else if (ball.v.x < 0) {vline[1].x -= halfw; } + vline[1].y = vline[0].y + ball.v.y; + if(ball.v.y > 0) { vline[1].y += halfh; } + else if (ball.v.y < 0) {vline[1].y -= halfh; } + + // are we going to collide with the paddle? + { + int willCollide = lr_collision(vline[0], vline[1], pad.r, NULL); + switch(willCollide) { + //TODO: set ball loc to colliding wall, invert vel & skip vel add + } + } // screen bounds checks & responses if(ball.r.x + ball.r.w > windowSize.x && !collisionResponded){ @@ -223,7 +268,6 @@ static void cleanup() int main() { - //TODO: run on primary display if(!init()) { return 1; } while(!quit) {