Pong | Handling the ball hitting a paddle.
When two collision objects hit each other they send a message. These messages are received by the on_message function as parameters. Every game object has an on_message listener, and therefore we could put our collision response code either behind the paddle or the ball. If we put the code behind the paddle we will need to duplicte it for each paddle and also pass another message to the ball telling it to change direction since the ball's position is an encapsulated attribute. i.e. only the ball can change it's own position. Therefore it feels more logical to put the code behind the ball instead. After all, this is where the other code to change the ball direction is anyway.
When deciding where to put the collision response code, usually you will want to put it behind the object that has to take some action.
- In the assets panel, double click the ball.script file. In the on_message function, add the code to bounce the ball off the paddle.
function on_message(self, message_id, message, sender)
if message_id == hash("contact_point_response") then
-- Move ball out of the paddle
go.set_position(go.get_position() + message.normal * message.distance)
-- Calculate bounce angle
local pos = go.get_position()
local paddle = go.get_position(message.other_id)
local paddle_intersect = paddle.y - pos.y
local bounce_vector = paddle_intersect * 1.3
-- Set new direction
self.direction.y = -math.sin(bounce_vector)
self.direction.x = -self.direction.x
-- Normalise direction to ensure constant speed
self.direction = vmath.normalize(self.direction)
sound.play("#bounce")
end
end
on_message has four parameters:
- self - an array of attributes belonging to the ball object.
- message_id - a hashed string identifying the message broadcast. contact_point_response is a default message.
- message - a table of additional parameters about the object collided with. In this case the paddle.
- sender - the id of the other object collided with.
First we check if we have received a message by listening for it. Remember strings are hashed to speed up the condition checking for the ALU. contact_point_response is a global message that provides contact point data.
Once two objects have collided they will be slightly inside each other. This needs to be resolved by moving the ball outside of the paddle.
To change the direction of the ball we could simply use the line of code self.direction.x = -self.direction.x
However this makes the trajectory of the ball too predictable. To add a little finesse to the game we want to modify the trajectory of the ball depending on where it hits the paddle.
To do this we find out where the ball has hit the paddle by comparing the y position of both objects and multiplying this number by a constant. Through trial and error a constant of 1.3 feels about right. If the ball hits near the middle of the paddle the result will be a smaller number than if it hit towards the edge of the paddle.
We then use a little trigonometry to set the correct vector, reverse the x direction of the ball to send it back to our opponent and normalise the final vector to ensure a constant speed regardless of the trajectory.
- Save the changes by pressing CTRL-S or 'File', 'Save All'.
- Run your program. The ball should bounce off the paddles. There will be an issue if the ball hits the top or bottom of a paddle but we'll ignore that for now!
We can now move on to keeping score. Stage 8a >