I am writing a fairly simple breakout-style game for Android phones. I have successfully detected the collisions between the ball(s) and bricks. The problem that I am having is in calculating the new vector for the ball. Even though the bricks are rectangular, I want to treat them as circles for the purpose of introducing more uniqueness to the ball directions.
I have the center point and vector of the ball and the center point of the brick which it has collided with and need to determine the new vector. The speed of the ball is always constant so the vector will be adjusted to that length but the direction is where I am having issues calculating. I've given it a few shots but they always end up being wildly incorrect.
The following is the code which I wrote but it has unpredictable results. All of the calculations must be done directly or using any of the methods in the Android SDK without a physics library of any sort.
float collisionUnitVectorX = ball.getLocation().x - blockCenterX;
float collisionUnitVectorY = ball.getLocation().y - blockCenterY;
final double collisionVectorLength = Math.sqrt(Math.pow(collisionUnitVectorX, 2) + Math.pow(collisionUnitVectorY, 2));
collisionUnitVectorX /= collisionVectorLength;
collisionUnitVectorY /= collisionVectorLength;
final double ballVectorLength = Math.sqrt(Math.pow(ball.getVectorX(), 2) + Math.pow(ball.getVectorY(), 2));
final float ballUnitVectorX = (float)(ball.getVectorX() / ballVectorLength);
final float ballUnitVectorY = (float)(ball.getVectorY() / ballVectorLength);
ball.setVectorX((float)(collisionUnitVectorX + ballUnitVectorX));
ball.setVectorY((float)(collisionUnitVectorY + ballUnitVectorY));
Here is a list of the information that I have for calculation:
- ball center (x,y)
- ball radius
- ball vector (x,y)
- block center (x,y)
The calculation should result in a new vector x and y values which has a length equal to the constant BALL_SPEED
.
Remember, collision has already been determined, I am only looking for the new vector calculation. Thank you in advance.
(accepted answer author will be attributed in game credits)
Answer
Here is some pseudo code that will accomplish this. I'm assuming ball vector represents the position change (velocity) of the ball.
Vector collisionUnitVector = blockCtr - ball.GetLoc();
float cuvLength = collisionUnitVector.Length();
collisionUnitVector /= cuvLength;
Vector Velocity = ball.GetVector();
float speed = velocity.Length();
Vector velocityNormal = velocity / speed;
float dotProduct = Dot(collisionUnitVector, velocityNormal);
Vector vFactor = 2 * (-collisionUnitVector * dotProduct * speed);
Vector newVelocity = velocity + vFactor;
No comments:
Post a Comment