diff --git a/breakout.c b/breakout.c index 9efac19..416dcda 100644 --- a/breakout.c +++ b/breakout.c @@ -222,42 +222,63 @@ SDL_Point BALL_GetCenter(Ball * obj){ return (SDL_Point) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) }; } +void BALL_CollideWithBorders(Ball * obj){ + if ((obj->Location).y < 0.0f) + (obj->Momentum).y = -(obj->Momentum).y; + if ((obj->Location).x < 0.0f || (obj->Location).x > BREAKOUT_BoxWidth - (2 * (obj->Size))) + (obj->Momentum).x = -(obj->Momentum).x; +} + +void BALL_MoveAwayFromBoundaries(Ball * obj){ + while (((obj->Location).y) < 0) + ((obj->Location).y)++; + while (((obj->Location).x) < 0) + ((obj->Location).x)++; + while ((((obj->Location).x) + ((obj->Size) * 2)) > BREAKOUT_BoxWidth) + ((obj->Location).x)--; +} + +bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle){ + if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { + SDL_Point 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 + BALL_SteerMomentum(obj, paddle); // Sets it to unit vector! + // Following assumes that the paddle position was udated before the ball was updated + while (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { // Move away from rect in small steps + (obj->Location) = VECTOR_Add((obj->Location), (obj->Momentum)); + BALL_MoveAwayFromBoundaries(obj); + RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); + } + (obj->Momentum) = VECTOR_ChangeScaleTo((obj->Momentum), (obj->Speed)); + return true; + } + return false; +} /* BALL_CollideWithPaddle */ + void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){ Vector oldMomentum = obj->Momentum; Vector oldLocation = obj->Location; - SDL_Point ballCenter = BALL_GetCenter(obj); (obj->Rotation) += (obj->RotationValue); // No effect on physics (obj->Location) = VECTOR_Add((obj->Location), oldMomentum); - if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { - (obj->Location) = oldLocation; // Maybe remove this - BALL_SteerMomentum(obj, paddle); // Sets it to unit vector! - // 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) = VECTOR_Add((obj->Location), (obj->Momentum)); - RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); + if (!BALL_CollideWithPaddle(obj, paddle)) // Collide with Paddle + for (size_t i = 0; i < BlockCount; i++) { // Check Collide with each block + if (blocks[i].HP <= 0) continue; + oldMomentum = obj->Momentum; + oldLocation = obj->Location; + if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) { + BLOCK_DealDamage(blocks + i, 1); + (obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum)); + BALL_MoveAwayFromBoundaries(obj); + RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); + } } - (obj->Momentum) = VECTOR_ChangeScaleTo((obj->Momentum), (obj->Speed)); - } - for (size_t i = 0; i < BlockCount; i++) { - if (blocks[i].HP <= 0) continue; - oldMomentum = obj->Momentum; - oldLocation = obj->Location; - if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) { - BLOCK_DealDamage(blocks + i, 1); - (obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum)); - RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); - } - } - if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries (obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead - else if ((obj->Location).y < 0.0f) - (obj->Momentum).y = -(obj->Momentum).y; - if ((obj->Location).x < 0.0f || (obj->Location).x > BREAKOUT_BoxWidth - (2 * (obj->Size))) - (obj->Momentum).x = -(obj->Momentum).x; + else BALL_CollideWithBorders(obj); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); } /* BALL_Update */ diff --git a/breakout.h b/breakout.h index 8a638d9..70e3efc 100644 --- a/breakout.h +++ b/breakout.h @@ -59,6 +59,9 @@ 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); +void BALL_CollideWithBorders(Ball * obj); +void BALL_MoveAwayFromBoundaries(Ball * obj); +bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle); void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount); void BALL_DestroyObject(Ball * obj); void BALL_Deinitialize();