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){
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
vector.c
30
vector.c
@ -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);
|
||||||
}
|
}
|
||||||
|
22
vector.h
22
vector.h
@ -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__
|
||||||
|
Loading…
Reference in New Issue
Block a user