From ede7e06230be2e35a2199855b952b690c3caa714 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Sat, 20 Jan 2018 10:56:52 +0100 Subject: [PATCH] Major Bugfix in Vector Lib, also Fixed collision mechanics! --- breakout.c | 68 ++++++++++++++++++++++-------------------------------- vector.c | 30 ++++++++++++------------ vector.h | 22 +++++++++--------- 3 files changed, 53 insertions(+), 67 deletions(-) diff --git a/breakout.c b/breakout.c index bb43112..9efac19 100644 --- a/breakout.c +++ b/breakout.c @@ -150,54 +150,40 @@ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){ } bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ - SDL_Point ballCenter = BALL_GetCenter(obj); - - if (((obj->TargetRect).x) + ((obj->TargetRect).w) < (rect->x)) return false; - if (((obj->TargetRect).x) > (rect->x) + (rect->w)) return false; - if (((obj->TargetRect).y) + ((obj->TargetRect).w) < (rect->y)) return false; - if (((obj->TargetRect).y) > (rect->y) + (rect->h)) return false; + if (!RECT_Collide(&(obj->TargetRect), rect)) return false; // Already returned with false if square ball hitbox didnt collide with rect + SDL_Point ballCenter = BALL_GetCenter(obj); Vector center = (Vector) {.x = ballCenter.x, .y = ballCenter.y }; Vector corner; -// Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt im rechteck liegt! -// double perpendicular, oldMomentum, angle; -// oldMomentum = fmod((double)(vectorRotation(obj->Momentum) + 180), 360.0f); - bool left, right, top, bottom, yMid = false, xMid = false; left = (ballCenter.x) < (rect->x); right = (ballCenter.x) > (rect->x) + (rect->w); top = (ballCenter.y) < (rect->y); bottom = (ballCenter.y) > (rect->y) + (rect->h); - // if (top) - // corner.y = rect->y; - // else if (bottom) - // corner.y = (rect->y) + (rect->w); - // else - // yMid = true; - // if (left) - // corner.x = rect->x; - // else if (right) - // corner.x = (rect->x) + (rect->w); - // else - // xMid = true; yMid = !(top || bottom); xMid = !(left || right); - if (yMid) + if (yMid) // Hit left or right (obj->Momentum).x = -(obj->Momentum).x; - if (xMid) + if (xMid) // Hit bottom or top (obj->Momentum).y = -(obj->Momentum).y; - // if (yMid && xMid) printf("WARNING: Ball is completely inside block!\n"); - // if (yMid || xMid) { // Ball collides with Edge - // } else { // Ball collides with corner - // /* - // * perpendicular = vectorRotation(vectorSub(center, corner)); - // * angle = fabs(perpendicular - oldMomentum); - // * if (oldMomentum < perpendicular) - // * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum + (2 * angle)), (obj->Speed)); - // * else - // * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum - (2 * angle)), (obj->Speed)); - // */ - // } + if (xMid || yMid) return true; + // double oldAngle = fmod((double)(VECTOR_GetRotation(obj->Momentum)), 360.0f); + + if (left) { + corner.x = (rect->x); + } else if (right) { + corner.x = ((rect->x) + (rect->w)); + } // Other case will not appear since returned above + if (top) { + corner.y = (rect->y); + } else if (bottom) { + corner.y = ((rect->y) + (rect->h)); + } + // printf("Hit corner at %.0f|%.0f!\n", corner.x, corner.y); + // printf("Ball center at %.0f|%.0f!\n", center.x, center.y); +// TODO: Reflection at lot + (obj->Momentum) = VECTOR_GetScaledVectorFromTo(corner, center, (obj->Speed)); + // printf("New Magnitude = %.2f\n", VECTOR_GetMagnitude((obj->Momentum))); return true; } /* BALL_CollideWithRect */ @@ -224,7 +210,7 @@ void BALL_SteerMomentum(Ball * obj, Paddle * paddle){ offset /= paddleHalfLen; offset *= (paddle->SteeringAngle); DOUBLE_Constrain(&offset, -(paddle->SteeringAngle), (paddle->SteeringAngle)); - (obj->Momentum) = getDirectionalUnitVector(offset); + (obj->Momentum) = VECTOR_GetDirectionalUnitVector(offset); } void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location){ @@ -242,7 +228,7 @@ void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){ SDL_Point ballCenter = BALL_GetCenter(obj); (obj->Rotation) += (obj->RotationValue); // No effect on physics - (obj->Location) = vectorAdd((obj->Location), oldMomentum); + (obj->Location) = VECTOR_Add((obj->Location), oldMomentum); if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { (obj->Location) = oldLocation; // Maybe remove this @@ -250,10 +236,10 @@ void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){ // Following assumes that the paddle position was udated before the ball was updated // BUG/GLITCH: Make sure that the postition of the ball is not shifted into the borders of the game! while (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { // Move away from rect in small steps - (obj->Location) = vectorAdd((obj->Location), (obj->Momentum)); + (obj->Location) = VECTOR_Add((obj->Location), (obj->Momentum)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); } - (obj->Momentum) = vectorScaleTo((obj->Momentum), (obj->Speed)); + (obj->Momentum) = VECTOR_ChangeScaleTo((obj->Momentum), (obj->Speed)); } for (size_t i = 0; i < BlockCount; i++) { if (blocks[i].HP <= 0) continue; @@ -261,7 +247,7 @@ void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){ oldLocation = obj->Location; if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) { BLOCK_DealDamage(blocks + i, 1); - (obj->Location) = vectorAdd(oldLocation, (obj->Momentum)); + (obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); } } diff --git a/vector.c b/vector.c index b4ec420..eb553df 100644 --- a/vector.c +++ b/vector.c @@ -6,7 +6,7 @@ const double degreeToRadians = M_PI / 180.0f; // End Properties -Vector vectorScale(Vector v, double factor){ +Vector VECTOR_ScaleBy(Vector v, double factor){ return (Vector) { .x = v.x * factor, @@ -14,30 +14,30 @@ Vector vectorScale(Vector v, double factor){ }; } -double vectorMagnitude(Vector v){ +double VECTOR_GetMagnitude(Vector v){ return sqrt((v.x * v.x) + (v.y * v.y)); } -double vectorRotation(Vector v){ +double VECTOR_GetRotation(Vector v){ double da = atan2(v.x, -v.y) / degreeToRadians; if (da < 0.0f) return (da + 360.0f); else return da; } -Vector vectorScaleTo(Vector v, double magnitude){ - return vectorScale(v, magnitude / vectorMagnitude(v)); +Vector VECTOR_ChangeScaleTo(Vector v, double magnitude){ + return VECTOR_ScaleBy(v, magnitude / VECTOR_GetMagnitude(v)); } -double dotProduct(Vector v1, Vector v2){ +double VECTOR_DotProduct(Vector v1, Vector v2){ return (v1.x * v2.x ) + (v1.y * v2.y); } -double vectorDist(Vector v1, Vector v2){ - return sqrt(dotProduct(v1, v2)); +double VECTOR_Distance(Vector v1, Vector v2){ + return sqrt(VECTOR_DotProduct(v1, v2)); } -Vector vectorAdd(Vector v1, Vector v2){ +Vector VECTOR_Add(Vector v1, Vector v2){ return (Vector) { .x = v1.x + v2.x, @@ -45,7 +45,7 @@ Vector vectorAdd(Vector v1, Vector v2){ }; } -Vector vectorSub(Vector v1, Vector v2){ +Vector VECTOR_Subtract(Vector v1, Vector v2){ return (Vector) { .x = v1.x - v2.x, @@ -61,7 +61,7 @@ double degreeCos(double x){ return cos(x * degreeToRadians); } -Vector getDirectionalUnitVector(double rotation){ +Vector VECTOR_GetDirectionalUnitVector(double rotation){ return (Vector) { .x = degreeSin(rotation), @@ -69,16 +69,16 @@ Vector getDirectionalUnitVector(double rotation){ }; } -Vector getScaledDirectionalUnitVector(double rotation, double Magnitude){ +Vector VECTOR_GetScaledDirectionalUnitVector(double rotation, double Magnitude){ Vector v = (Vector) { .x = degreeSin(rotation), .y = -degreeCos(rotation) }; - return vectorScale(v, Magnitude); + return VECTOR_ScaleBy(v, Magnitude); } -Vector getScaledVectorFromTo(Vector from, Vector to, double Magnitude){ - return vectorScale(vectorSub(to, from), Magnitude); +Vector VECTOR_GetScaledVectorFromTo(Vector from, Vector to, double Magnitude){ + return VECTOR_ChangeScaleTo(VECTOR_Subtract(to, from), Magnitude); } diff --git a/vector.h b/vector.h index 2bbaf4d..39130ae 100644 --- a/vector.h +++ b/vector.h @@ -8,19 +8,19 @@ typedef struct vectorStruct { // End Structs // Prototypes -Vector vectorScale(Vector v, double factor); -double vectorMagnitude(Vector v); -double vectorRotation(Vector v); -Vector vectorScaleTo(Vector v, double magnitude); -double dotProduct(Vector v1, Vector v2); -double vectorDist(Vector v1, Vector v2); -Vector vectorAdd(Vector v1, Vector v2); -Vector vectorSub(Vector v1, Vector v2); +Vector VECTOR_ScaleBy(Vector v, double factor); +double VECTOR_GetMagnitude(Vector v); +double VECTOR_GetRotation(Vector v); +Vector VECTOR_ChangeScaleTo(Vector v, double magnitude); +double VECTOR_DotProduct(Vector v1, Vector v2); +double VECTOR_Distance(Vector v1, Vector v2); +Vector VECTOR_Add(Vector v1, Vector v2); +Vector VECTOR_Subtract(Vector v1, Vector v2); double degreeSin(double x); double degreeCos(double x); -Vector getDirectionalUnitVector(double rotation); -Vector getScaledDirectionalUnitVector(double rotation, double Magnitude); -Vector getScaledVectorFromTo(Vector from, Vector to, double Magnitude); +Vector VECTOR_GetDirectionalUnitVector(double rotation); +Vector VECTOR_GetScaledDirectionalUnitVector(double rotation, double Magnitude); +Vector VECTOR_GetScaledVectorFromTo(Vector from, Vector to, double Magnitude); // End Prototypes #endif // __vector_h__