Major glitchfix and minor bugfix in collision system.

This commit is contained in:
Michael Chen 2018-01-21 14:27:53 +01:00
parent 39e5b1bff9
commit 3fc18843b3
2 changed files with 50 additions and 26 deletions

View File

@ -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) }; 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){ void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){
Vector oldMomentum = obj->Momentum; Vector oldMomentum = obj->Momentum;
Vector oldLocation = obj->Location; Vector oldLocation = obj->Location;
SDL_Point ballCenter = BALL_GetCenter(obj);
(obj->Rotation) += (obj->RotationValue); // No effect on physics (obj->Rotation) += (obj->RotationValue); // No effect on physics
(obj->Location) = VECTOR_Add((obj->Location), oldMomentum); (obj->Location) = VECTOR_Add((obj->Location), oldMomentum);
if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { if (!BALL_CollideWithPaddle(obj, paddle)) // Collide with Paddle
(obj->Location) = oldLocation; // Maybe remove this for (size_t i = 0; i < BlockCount; i++) { // Check Collide with each block
BALL_SteerMomentum(obj, paddle); // Sets it to unit vector! if (blocks[i].HP <= 0) continue;
// Following assumes that the paddle position was udated before the ball was updated oldMomentum = obj->Momentum;
// BUG/GLITCH: Make sure that the postition of the ball is not shifted into the borders of the game! oldLocation = obj->Location;
while (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { // Move away from rect in small steps if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
(obj->Location) = VECTOR_Add((obj->Location), (obj->Momentum)); BLOCK_DealDamage(blocks + i, 1);
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); (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 if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries
(obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead (obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead
else if ((obj->Location).y < 0.0f) else BALL_CollideWithBorders(obj);
(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;
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
} /* BALL_Update */ } /* BALL_Update */

View File

@ -59,6 +59,9 @@ bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2);
void BALL_SteerMomentum(Ball * obj, Paddle * paddle); void BALL_SteerMomentum(Ball * obj, Paddle * paddle);
void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location); void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location);
SDL_Point BALL_GetCenter(Ball * obj); 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_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount);
void BALL_DestroyObject(Ball * obj); void BALL_DestroyObject(Ball * obj);
void BALL_Deinitialize(); void BALL_Deinitialize();