diff --git a/breakout.c b/breakout.c index b9c3d5b..61d9acb 100644 --- a/breakout.c +++ b/breakout.c @@ -219,7 +219,7 @@ void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){ GAME_ChangeState(GameOver); else { // Reduce score when there is a life left - scenery->Score = (int)roundf((float)(scenery->Score) * BREAKOUT_LifePenalty); + // scenery->Score = (int)roundf((float)(scenery->Score) * BREAKOUT_LifePenalty); printf("Oh oh, only %d lives left!\n", scenery->Lives); } return; @@ -355,16 +355,27 @@ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ 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 unitMomentum = VECTOR_ChangeScaleTo((obj->Momentum), 1.0f); + Vector center = BALL_GetCenter(obj); Vector corner; 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); + left = (center.x) < (rect->x); + right = (center.x) > (rect->x) + (rect->w); + top = (center.y) < (rect->y); + bottom = (center.y) > (rect->y) + (rect->h); yMid = !(top || bottom); xMid = !(left || right); + // Move away from hitbox from where you came from when stuck in the middle of the block at high speeds + while (yMid && xMid) { + (obj->Location) = VECTOR_Subtract((obj->Location), unitMomentum); + center = BALL_GetCenter(obj); + left = (center.x) < (rect->x); + right = (center.x) > (rect->x) + (rect->w); + top = (center.y) < (rect->y); + bottom = (center.y) > (rect->y) + (rect->h); + yMid = !(top || bottom); + xMid = !(left || right); + } if (yMid) // Hit left or right (obj->Momentum).x = -(obj->Momentum).x; if (xMid) // Hit bottom or top @@ -382,9 +393,6 @@ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ } 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 Vector cornerToMid = VECTOR_GetVectorFromTo(corner, center); if (VECTOR_GetMagnitude(cornerToMid) > (obj->Size)) return false; double lot = VECTOR_GetRotation(cornerToMid); @@ -392,7 +400,6 @@ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ double outAngle = fmod(lot + (0.5 * (lot - inRotation)), 360.0f); printf("In: %.2f | Lot: %.2f | Out: %.2f\n", inRotation, lot, outAngle); (obj->Momentum) = VECTOR_GetScaledDirectionalUnitVector(outAngle, (obj->Speed)); - // printf("New Magnitude = %.2f\n", VECTOR_GetMagnitude((obj->Momentum))); return true; } /* BALL_CollideWithRect */ @@ -427,8 +434,8 @@ void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location){ rect->y = (int)round(Location->y); } -SDL_Point BALL_GetCenter(Ball * obj){ - return (SDL_Point) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) }; +Vector BALL_GetCenter(Ball * obj){ + return (Vector) {.x = ((obj->Location).x) + (obj->Size), .y = ((obj->Location).y) + (obj->Size) }; } void BALL_CollideWithBorders(Ball * obj){ @@ -449,7 +456,7 @@ void BALL_MoveAwayFromBoundaries(Ball * obj){ bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle){ if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { - SDL_Point ballCenter = BALL_GetCenter(obj); + Vector ballCenter = BALL_GetCenter(obj); if (ballCenter.y > (paddle->TargetRect).y) // if the ball hits the paddle from the sides (or the bottom (?)) BALL_CollideWithRect(obj, &(paddle->TargetRect)); else diff --git a/breakout.h b/breakout.h index c4efca2..bcbf566 100644 --- a/breakout.h +++ b/breakout.h @@ -71,7 +71,7 @@ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect); bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2); void BALL_SteerMomentum(Ball * obj, Paddle * paddle); void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location); -SDL_Point BALL_GetCenter(Ball * obj); +Vector BALL_GetCenter(Ball * obj); void BALL_CollideWithBorders(Ball * obj); void BALL_MoveAwayFromBoundaries(Ball * obj); bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle);