Major Bugfix in Vector Lib, also Fixed collision mechanics!

This commit is contained in:
Michael Chen 2018-01-20 10:56:52 +01:00
parent a9119f4856
commit ede7e06230
3 changed files with 53 additions and 67 deletions

View File

@ -150,54 +150,40 @@ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){
} }
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){
SDL_Point ballCenter = BALL_GetCenter(obj); if (!RECT_Collide(&(obj->TargetRect), rect)) return false;
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;
// Already returned with false if square ball hitbox didnt collide with rect // 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 center = (Vector) {.x = ballCenter.x, .y = ballCenter.y };
Vector corner; 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; bool left, right, top, bottom, yMid = false, xMid = false;
left = (ballCenter.x) < (rect->x); left = (ballCenter.x) < (rect->x);
right = (ballCenter.x) > (rect->x) + (rect->w); right = (ballCenter.x) > (rect->x) + (rect->w);
top = (ballCenter.y) < (rect->y); top = (ballCenter.y) < (rect->y);
bottom = (ballCenter.y) > (rect->y) + (rect->h); 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); yMid = !(top || bottom);
xMid = !(left || right); xMid = !(left || right);
if (yMid) if (yMid) // Hit left or right
(obj->Momentum).x = -(obj->Momentum).x; (obj->Momentum).x = -(obj->Momentum).x;
if (xMid) if (xMid) // Hit bottom or top
(obj->Momentum).y = -(obj->Momentum).y; (obj->Momentum).y = -(obj->Momentum).y;
// if (yMid && xMid) printf("WARNING: Ball is completely inside block!\n"); if (xMid || yMid) return true;
// if (yMid || xMid) { // Ball collides with Edge // double oldAngle = fmod((double)(VECTOR_GetRotation(obj->Momentum)), 360.0f);
// } else { // Ball collides with corner
// /* if (left) {
// * perpendicular = vectorRotation(vectorSub(center, corner)); corner.x = (rect->x);
// * angle = fabs(perpendicular - oldMomentum); } else if (right) {
// * if (oldMomentum < perpendicular) corner.x = ((rect->x) + (rect->w));
// * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum + (2 * angle)), (obj->Speed)); } // Other case will not appear since returned above
// * else if (top) {
// * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum - (2 * angle)), (obj->Speed)); 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; return true;
} /* BALL_CollideWithRect */ } /* BALL_CollideWithRect */
@ -224,7 +210,7 @@ void BALL_SteerMomentum(Ball * obj, Paddle * paddle){
offset /= paddleHalfLen; offset /= paddleHalfLen;
offset *= (paddle->SteeringAngle); offset *= (paddle->SteeringAngle);
DOUBLE_Constrain(&offset, -(paddle->SteeringAngle), (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){ 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); SDL_Point ballCenter = BALL_GetCenter(obj);
(obj->Rotation) += (obj->RotationValue); // No effect on physics (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))) { if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) {
(obj->Location) = oldLocation; // Maybe remove this (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 // 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! // 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 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)); 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++) { for (size_t i = 0; i < BlockCount; i++) {
if (blocks[i].HP <= 0) continue; if (blocks[i].HP <= 0) continue;
@ -261,7 +247,7 @@ void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){
oldLocation = obj->Location; oldLocation = obj->Location;
if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) { if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
BLOCK_DealDamage(blocks + i, 1); BLOCK_DealDamage(blocks + i, 1);
(obj->Location) = vectorAdd(oldLocation, (obj->Momentum)); (obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum));
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
} }
} }

View File

@ -6,7 +6,7 @@
const double degreeToRadians = M_PI / 180.0f; const double degreeToRadians = M_PI / 180.0f;
// End Properties // End Properties
Vector vectorScale(Vector v, double factor){ Vector VECTOR_ScaleBy(Vector v, double factor){
return (Vector) return (Vector)
{ {
.x = v.x * factor, .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)); 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; double da = atan2(v.x, -v.y) / degreeToRadians;
if (da < 0.0f) return (da + 360.0f); if (da < 0.0f) return (da + 360.0f);
else return da; else return da;
} }
Vector vectorScaleTo(Vector v, double magnitude){ Vector VECTOR_ChangeScaleTo(Vector v, double magnitude){
return vectorScale(v, magnitude / vectorMagnitude(v)); 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); return (v1.x * v2.x ) + (v1.y * v2.y);
} }
double vectorDist(Vector v1, Vector v2){ double VECTOR_Distance(Vector v1, Vector v2){
return sqrt(dotProduct(v1, v2)); return sqrt(VECTOR_DotProduct(v1, v2));
} }
Vector vectorAdd(Vector v1, Vector v2){ Vector VECTOR_Add(Vector v1, Vector v2){
return (Vector) return (Vector)
{ {
.x = v1.x + v2.x, .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) return (Vector)
{ {
.x = v1.x - v2.x, .x = v1.x - v2.x,
@ -61,7 +61,7 @@ double degreeCos(double x){
return cos(x * degreeToRadians); return cos(x * degreeToRadians);
} }
Vector getDirectionalUnitVector(double rotation){ Vector VECTOR_GetDirectionalUnitVector(double rotation){
return (Vector) return (Vector)
{ {
.x = degreeSin(rotation), .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) Vector v = (Vector)
{ {
.x = degreeSin(rotation), .x = degreeSin(rotation),
.y = -degreeCos(rotation) .y = -degreeCos(rotation)
}; };
return vectorScale(v, Magnitude); return VECTOR_ScaleBy(v, Magnitude);
} }
Vector getScaledVectorFromTo(Vector from, Vector to, double Magnitude){ Vector VECTOR_GetScaledVectorFromTo(Vector from, Vector to, double Magnitude){
return vectorScale(vectorSub(to, from), Magnitude); return VECTOR_ChangeScaleTo(VECTOR_Subtract(to, from), Magnitude);
} }

View File

@ -8,19 +8,19 @@ typedef struct vectorStruct {
// End Structs // End Structs
// Prototypes // Prototypes
Vector vectorScale(Vector v, double factor); Vector VECTOR_ScaleBy(Vector v, double factor);
double vectorMagnitude(Vector v); double VECTOR_GetMagnitude(Vector v);
double vectorRotation(Vector v); double VECTOR_GetRotation(Vector v);
Vector vectorScaleTo(Vector v, double magnitude); Vector VECTOR_ChangeScaleTo(Vector v, double magnitude);
double dotProduct(Vector v1, Vector v2); double VECTOR_DotProduct(Vector v1, Vector v2);
double vectorDist(Vector v1, Vector v2); double VECTOR_Distance(Vector v1, Vector v2);
Vector vectorAdd(Vector v1, Vector v2); Vector VECTOR_Add(Vector v1, Vector v2);
Vector vectorSub(Vector v1, Vector v2); Vector VECTOR_Subtract(Vector v1, Vector v2);
double degreeSin(double x); double degreeSin(double x);
double degreeCos(double x); double degreeCos(double x);
Vector getDirectionalUnitVector(double rotation); Vector VECTOR_GetDirectionalUnitVector(double rotation);
Vector getScaledDirectionalUnitVector(double rotation, double Magnitude); Vector VECTOR_GetScaledDirectionalUnitVector(double rotation, double Magnitude);
Vector getScaledVectorFromTo(Vector from, Vector to, double Magnitude); Vector VECTOR_GetScaledVectorFromTo(Vector from, Vector to, double Magnitude);
// End Prototypes // End Prototypes
#endif // __vector_h__ #endif // __vector_h__