Major Bugfix in Vector Lib, also Fixed collision mechanics!
This commit is contained in:
parent
a9119f4856
commit
ede7e06230
68
breakout.c
68
breakout.c
@ -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));
|
||||
}
|
||||
}
|
||||
|
30
vector.c
30
vector.c
@ -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);
|
||||
}
|
||||
|
22
vector.h
22
vector.h
@ -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__
|
||||
|
Loading…
Reference in New Issue
Block a user