We are going to recreate a version of the pong game.
You will be learning how to:
Create paddles that move
Create a ball that bounces
Add scores for players 1 and 2
Reset the ball between rounds using broadcasts
Winning the game
Add some basic physics to the ball (Extension)
We will be doing this in Scratch
Create a new Scratch project. Right click on the cat sprite and choose 'delete'
Add a sprite for player 1's paddle using the instructions below
Repeat for player 2's paddle (with appropriate name change)
Now it's time to make the paddles move with some code. We are going to make it so that player 1 is controlled with the left and right arrows and player 2 is controlled with the 'a' and 'd' keys. We do this by continuously checking if the button is pressed. If it is we make it move. Here's the pieces:
Now let's look at how we put them all together. First we have to understand how the scratch screen is laid out. Scratch uses a 2-dimensional grid like this:
The X-axis goes from a minimum of -240 to a maximum of 240
The Y-axis goes from a minimum of -180 to a maximum of 180
To move left and right we will be moving along the X-axis. To go right we increase x by 10 and to go left we decrease x by 10.
Putting all the pieces together we get:
We are going to start off by adding in a ball sprite. For this we are going to choose the basic ball, but any round sprite of a similar size should work.
Next we are going to add code to its script to make it move continuously and bounce if it hits the edge.
When you run the script the ball should bounce around the screen, including through the paddles. Obviously this isn't how it should work. We want the ball to bounce off the paddles. We also want the ball to start back in the centre each time and fall toward one of the paddles. Let's have a look at how to do all of that.
We'll start with the positioning and moving toward the paddle.
When we put it altogether we get:
For bouncing off the paddles we'll keep it basic to begin with. When it hits the paddle it'll turn around and go back the other way. The following code is for one paddle. You'll need to do the same for paddle 2. When we add physics later we will make this a bit more interesting.
Put the code above between the move 10 steps and the if on edge, bounce
In a game of pong if the ball hits the top or the bottom that should be a goal for player on the other side. To code that in we are going to need to get a bit creative and really understand the grid on which scratch is based.
First we need to add variables for the scores. Go into data and choose 'Make a variable'
First one will be 'Player 1 Score', do it again and make 'Player 2 Score'
You should now have some new blocks under the data tab. We need to set the initial score to 0 so games start with new scores. Take the new 'Set Player 1 Score to 0' block and drag it under the start block. Do the same again and use the dropdown box to change the variable to 'Player 2 Score'. If you've done everything correctly your code should look like this:
Now it's time to do something with the score. Drag the 'if on edge, bounce' block out of the code, but don't throw it away. We're going to build exactly what should happen if it hits the edge. The first part is going to be a new 'if' block with the condition 'touching edge?'
Inside this we are going to put some 'if-then-else' blocks. We will need two of them, one inside the other. This is called 'nesting' as in Russian Nesting Dolls. When we put them together it should look like this:
The are three possible things we want to check for. If it touches the top, if it touches the bottom and if it touches any other side. This brings us back to the grid:
Touching the top means the ball is at or nearly at the maximum on the Y-axis. We'll give it some leeway and call it Y: 155
Touching the bottom means the ball is at or nearly at the minimum on the Y-axis. We'll give it some leeway and call it Y: -155
Anything else means we are touching the sides.
To program this we will use the comparison operators less than (<) and greater than (>). First let's do the bottom:
Slot this into the first 'if-then-else' and then build the check for the top using the > and slot it into the second 'if'-then-else'. Finally add the 'if on edge, bounce' back in to the final 'else'.
Now we're ready to add the score changing in. We'll say player 1 is the bottom, and player 2 is the top.
When the ball hits the bottom (y position < -155) player 2 gets a point and the ball should head towards player 2 (up).
When the ball hits the top (y position > 155) player 1 gets a point and the ball should head towards player 1 (up).
Finally drag this entire block into the main code for the ball under 'if touching paddle 2?'. This should be the same place you took the 'if on edge, bounce' back in step 5.
4. Resetting the Ball
The second to last step is to reset the game state after each goal. We will be accomplishing this using broadcasts.
Sprites have their own way of talking to each other to know when something has happened. These are called broadcasts. They are messages passed between sprites that do not appear on screen.
We will be broadcasting a message called 'score' that will be picked up by different parts of the game and each will respond to it in their own way.
We will also alter the code to create a 'Game Start' message so we can pause the ball after each score.
Under the 'Event's tab there are 3 broadcast related blocks found at the bottom.
'When I receive...' allows us to do something when the sprite receives the message
'broadcast ...' allows us to send out a message to all sprites (including ourselves)
'broadcast ... and wait' does the same as a regular broadcast but pauses the script until all 'When I receive' scripts from this broadcast are finished
Click the dropdown box that says 'message1' and choose 'new message...' Name the new message 'goal'
Inside the ball script, go to where we change Player 1 Score by 1 and add a broadcast goal in underneath:
Go to the bottom paddle and add this code then do the same but change the y value to positive for the top paddle.
Next go to the backdrop. In here we are going to work out who, if anyone has won, and then what to do. We have 3 different options. Either:
Player 1 has won
Player 2 has won
No one has won.
To figure this out we are going to have two nested 'if-then-else' here. The first just checks if either player won, the second determines who won. The reason we do it like this is that we have some code that is universal to either player winning - stopping the ball and paddles from moving. Here's our structure:
We could choose a larger score than 10 (remember > will trigger only if it's over the number so we want to be one less than the goal) and if we choose to be really fancy we could make a variable called 'Max Score' so that we can choose what score to go up to.
We will fill in the gaps with more broadcasts:
Game Over will contain our universal rules for game over
Player 1 wins and Player 2 wins will make the appropriate message show up
Game Start will reset the ball for another round if there isn't a winner yet.
Then we need to change our ball from starting on the green flag to sending a 'game start' on the green flag. Do this by detaching the code below 'point in direction 180' and reattach it to a 'When I receive game start'
5. Winning the Game
The final step is to set up a 'Player X wins' message.
We will create a new sprite for the message and use the text tool to write out what we want:
Inside this sprite we are going to add the script for receiving the broadcast that player 1 has won:
Repeat steps 2 and 3 for the 'Player 2 Wins' broadcast
Back in the two paddles and the ball we need to add code for receiving the Game Over broadcast:
If we run the game now though, our paddles will hide when the game is over and won't appear again. To fix this we need to make sure when the game starts that they reappear again. Create this code in each of the paddles to make them appear.
Congratulations the game is complete
If we want to go beyond the basics we can add some more realistic physics into the game. At the moment the ball just bounces back in the same direction.
This is a fairly complicated script . It's not long but it isn't easy to understand.
When the ball touches the paddle we want it to do one of three things
If it hits on the left we want it to bounce back on the left (the arc: -80 to -1 degrees)
If it hits on the right we want it to bounce back on the right (the arc 1 to 80 degrees)
If it hits in the centre we want it to bounce straight (0 degrees or 180 degrees)
Inside the ball sprite's code we are going to revist the 'if touching paddle? then' section for the bottom paddle. Inside it we are going to create two nested if-then-else blocks.
The condition uses the pieces below to determine if the ball is hitting the paddle from the left.
Putting them together we get our if-then-else structure:
Inside we want to point the ball in the direction it came from, but with a bit of random spin to it. We are going to use the point in direction block and the pick random block. For pick random we want the ball to bounce off in the arc of -80 degrees to -1 degree.
Putting it altogether we get:
For the top paddle the code is almost identical. However the directions need to be inverted as the ball is coming from the other way. If we don't the ball will bounce right through the paddle! We do this by taking the result away from 180.