Вы находитесь на странице: 1из 5

Begin programming:

Build your first mobile game

Detecting a collision
A detailed guide on how to detect collisions in the game.
The game wouldnt be a game if there were no collisions between the objects in it, so you will need to
learn how to detect collisions and react to them appropriately. For this you will be using some maths.
Dont worry we will show you step-by-step how to do it.
Lets observe two balls that have collided (here R1 and R2 are the radius of balls)

Figure 1: Two balls in collision

You see that there should be a collision if c (the distance between the centres of the balls) is smaller than
the combined length of the two radiuses (R1 and R2). That is when c < R1 + R2. Likewise there should not
be a collision if c > R1 + R2.
Equation 1: Collision condition

c = R1 + R2

Figure 2: Two balls not in collision

University of Reading 2014

Thursday 18 September 2014

Page 1

Collision
When the collision happens you can cheat a bit and create this physical rule:

Figure 3: Collision point

The small ball will go in a new direction, in a straight line away from the the object it has collided with, as
if the ball hit the object without an angle. This is easier than real physics, because the directions can be set
by taking the centrum of the ball, and subtracting the centrum of the paddle. After that you should adjust
the speed so that it is the same as the original speed.

This line finds the old velocity of the ball.


float velocityOfBall = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY);

Math.sqrt can be used to find the square root. It has a library of many different and useful mathematical
functions.
(You can explore the different functions it has here:
http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html)
You need to find the new speeds for the X and Y direction to get the new direction of the ball. First you
find the distance between the centrum of the two balls; this will give you the new direction that the ball
needs to go after the impact.

Figure 4: New direction of travel Calculation for X direction


University of Reading 2014

Thursday 18 September 2014

Page 2

mBallSpeedX = mBallX - mPaddleX;

Figure 5: New direction of travel - Y direction


mBallSpeedY = mBallY - mCanvasHeight;

Remember that mCanvasHeight is always the Y position of the paddle. At this stage mBallSpeedX and
mBallSpeedY are not speeds/velocities, but values of the new direction. Now you have the new directions,
you need to adjust them so that they have the same speed as they did before the collision. To do this you
need to find the new velocity that the ball would have if it was using the given mBallSpeedY and
mBallSpeedX:
float newVelocity = (float) Math.sqrt(mBallSpeedX*mBallSpeedX + mBallSpeedY*mBallSpeedY);

Then that can be used to adjust mBallSpeedX and mBallSpeedY so that the speed is exactly the same as
the old velocity before the collision.
mBallSpeedX = mBallSpeedX * velocityOfBall / newVelocity;
mBallSpeedY = mBallSpeedY * velocityOfBall / newVelocity;

Now the speeds are velocities again.


Without any comments the code looks like this:
if(mBallSpeedY > 0) {
distanceBetweenBallAndBall =
(mPaddleX - mBallX) * (mPaddleX - mBallX) +
(mCanvasHeight - mBallY) *(mCanvasHeight - mBallY);
if(mMinDistanceBetweenRedBallAndBigBall >= distanceBetweenBallAndBall) {
float velocityOfBall = (float) Math.sqrt(mBallSpeedX*mBallSpeedX +
mBallSpeedY*mBallSpeedY);
mBallSpeedX = mBallX - mPaddleX;
mBallSpeedY = mBallY - mCanvasHeight;
float newVelocity = (float) Math.sqrt(mBallSpeedX*mBallSpeedX +
mBallSpeedY*mBallSpeedY);
mBallSpeedX = mBallSpeedX * velocityOfBall / newVelocity;
mBallSpeedY = mBallSpeedY * velocityOfBall / newVelocity;
}
}

Now for the maths!


University of Reading 2014

Thursday 18 September 2014

Page 3

Pythagoras Theorem teaches us that:

You can learn more about Pythagoras Theorem here: http://www.mathsisfun.com/pythagoras.html


This theorem is used to calculate the distance, c, between the two centres of balls that are likely to
collide. It was decided in Equation 1 that the collision should happen if:
c <= R1 + R2
Note: c = R1 + R2 is the moment of collision. You need to check for c <= R1 + R2 in the condition because
there are update intervals.
Using basic algebra (squaring both sides of the equation) it can also be said that:
c2 <= (R1 + R2)2
By using this equation you can avoid taking the square root, which is slow can be slow on a computer
compared with performing a multiplication.
In the code:
(R1 + R2)2 is found by the last line inside setupBeginning so that it can be used throughout the code.
Remember to declare mMinDistanceBetweenRedBallAndBigBall where all member variables are
declared. It should look like this:
private float mMinDistanceBetweenRedBallAndBigBall = 0;
mMinDistanceBetweenRedBallAndBigBall =
(mPaddle.getWidth()/2+mBall.getWidth()/2)*(mPaddle.getWidth()/2+mBall.getWidth()/2);

c2 <= (R1 + R2)2 should then be checked in the beginning of updateGame, but only if mBallSpeedY is
positive.
That can be done in this code:
if(mBallSpeedY > 0) {
//TODO find c

if(mMinDistanceBetweenRedBallAndBigBall >= c_squared) {


//TODO change mBallSpeedX and mBallSpeedY
University of Reading 2014

Thursday 18 September 2014

Page 4

}
}

Lets call c2 the distanceBetweenBallAndBall, because it describes what c is better than just c_squared.
It is found using Pythagoras theorem:
a is: mPaddleX mBallX
b is: mCanvasHeight mBallY

distanceBetweenBallAndBall = a2 + b2
so
if(mBallSpeedY > 0) {
distanceBetweenBallAndBall =
(mPaddleX - mBallX) * (mPaddleX - mBallX) +
(mCanvasHeight - mBallY) *(mCanvasHeight - mBallY);
if(mMinDistanceBetweenRedBallAndBigBall >= distanceBetweenBallAndBall) {
//TODO change mBallSpeedX and mBallSpeedY
}
}

University of Reading 2014

Thursday 18 September 2014

Page 5

Вам также может понравиться