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){
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));
}
}

View File

@ -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);
}

View File

@ -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__