# Game Time! ## Bounce Game

Let’s combine all our knowledge, with some new actions to make a game! Let’s make a game like Pong or Breakout. We’ll have a paddle on the bottom of the stage that we have to move back and forth to catch a bouncing ball.

## Draw Loop

To control the graphics for our game, we’ll use something called a “draw loop”. A draw loop is a simple concept. We make an action to draw our game elements on the stage, and we call it over and over in a loop until the game is over.

After each call we should sleep for a few milliseconds to avoid too much flicker on the screen.

To start we’ll make a new action called `draw_stage`, and we’ll start our draw loop.

``````gníomh draw_stage() {
>-- We'll fill in our drawing logic in here later
}

>-- Loop forever
nuair-a fíor {
>-- Call the draw_stage action
draw_stage()

>-- Sleep for a few milliseconds
}``````

Let’s get started with our paddle. We want a paddle that we can move around on the bottom of the stage. We’ll set up some variables and then use some stage actions in the `draw_stage` action to draw the paddle.

Let’s make variables called `paddle_height` and `paddle_width`. For the height we can use something like 20, as a small but visible value. For the paddle width we can divide the stage width so the paddle is always 20% of the stage wide. We can use our integer division operator (`//`) to make sure we round down to a whole number.

Let’s add the following code to the top of the program.

``````paddle_height := 20

Now we can make 2 more variables, `paddle_x` and `paddle_y`, these are the x and y coordinates of the paddle. Specifically the top right corner. We want to start with the paddle in the bottom left of the stage, so let’s set `paddle_x` to be `0`. To get the paddle on the bottom you might be tempted to set `paddle_y` to be `fad_y@stáitse` (the height of the stage), but this won’t work, we need to subtract the paddle height to account for how tall the paddle is.

Now our variables at the top of the program look like this:

``````paddle_height := 20

### Draw the Paddle

Now that we know where our paddle is, and how big it is, let’s add the logic on how to draw it to the `draw_stage` action.

Before we draw our paddle, we should clear the stage of any old things we drew before. We use the `glan@stáitse` action to do this. “Glan” translates as “clean” or “clear”, and it clears the stage.

After we clear the stage we can change the colour, I’d like to draw a red paddle, so I’ll type `dath@stáitse("dearg")` to change the colour to “dearg” (red).

Now we can draw our paddle! We can use the `dron_lán@stáitse` action (short for “dronuilleog lán” meaning “full rectangle”) to draw a rectangle. We need to give it 4 arguments, the x coordinate, the y coordinate, the width and the height.

Now our `draw_stage` action looks like this:

``````gníomh draw_stage() {
>-- Clear the stage
glan@stáitse()

dath@stáitse("dearg") >-- Red pen

}``````

Let’s try out our program now:

Don’t forget to press to stop the program otherwise it will go forever!

You should see a small red paddle being drawn at the bottom of the stage.

### Move the Paddle

Now that we can draw the paddle, how do we move it? We can use the “méarchlár” (meaning “keyboard”) action to get keyboard presses from the user!

First let’s make a new action called `key_control`. This is the action that will be called when the user presses a key. It takes one argument, the key that was pressed.

``````gníomh key_control(key) {
}``````

Let’s fill in `scríobh(key)` for now.

``````gníomh key_control(key) {
scríobh(key)
}``````

Now we can tell Setanta to use this action with the keyboard by passing it to the `méarchlár@stáitse` action by calling `méarchlár@stáitse(key_control)`. Let’s add that to our program.

Run this program, press the arrow keys on your keyboard and then check the console.

You should see that “ArrowRight”, “ArrowLeft”, “ArrowDown” or “ArrowUp” have been printed in your console. Each key you press has a name that describes it, we can check the name of the key that was pressed in the `key_control` action to behave differently depending on what key was pressed.

Note that the name of the keys are in English, this is because these names don’t come from Setanta, they come from the browser.

Let’s add a new variable called `paddle_speed` to control the speed of the paddle (how far to move the paddle when the user presses an arrow key). I’ll start with a value of 50 as I think it works well.

Then we can change the code in the `key_control` action to change the `paddle_x` variable to move the paddle left and right depending on the key that was pressed:

``````paddle_speed := 50

gníomh key_control(key) {
má key == "ArrowLeft" {
} nó má key == "ArrowRight" {
}
}``````

As you can see if the left arrow is pressed we decrease the x coordinate, and if the right arrow is pressed we increase the x coordinate.

Try out the code now: The paddle should move when you press the arrow keys!

## The Ball

Next let’s add a ball to bounce around the stage. Just like with the paddle we’ll add 2 new variables for the x and y coordinates of the ball, `ball_x` and `ball_y`, let’s start the ball in the top left corner (0, 0).

Let’s add another variable for the radius of the ball, `ball_rad`, and start it with a value of 30.

Finally then we need two more variables to control the direction the ball is moving in. We call these `ball_dx` and `ball_dy`. `ball_dx` is the change of the ball in the x direction, and `ball_dy` is the change in the y direction. We’ll start with a value of 2 for each, meaning the ball will start off moving diagonally towards the bottom right.

``````ball_x := 0
ball_y := 0

ball_dx := 2
ball_dy := 2``````

### Draw the Ball

Let’s add the logic to draw the ball to our `draw_stage` action. We’ll switch the colour of the pen to blue (“gorm”), and use the `ciorcal_lán` (meaning “full circle”) to draw the ball.

``````gníomh draw_stage() {
>-- Clear the stage
glan@stáitse()

dath@stáitse("dearg") >-- Red pen

dath@stáitse("gorm") >-- Blue pen

>-- Draw ball
}``````

### Ball Movement

We want the ball to move, let’s make a new action called `update_ball` that will be called in our draw loop. We should use this action to move the ball a tiny amount (`ball_dx` and `ball_dy` specifically).

``````gníomh update_ball() {
ball_x += ball_dx
ball_y += ball_dy
}``````

Now we include a call to `update_ball` into our draw loop

``````>-- Loop forever
nuair-a fíor {
>-- Call the draw_stage action
draw_stage()

>-- Update ball
update_ball()

>-- Sleep for a few milliseconds
}``````

Let’s run the code we have so far:

Oh no! The ball just flies off the screen! This is because we haven’t programmed in what the ball should do when it hits the paddle or the walls. Let’s do that now.

### Bounce

To add bouncing logic we should change our `update_ball` action. Let’s start with the walls and we’ll do the paddle logic after.

Before we update the balls position, we can check if it will go past each of the walls, and if it will we should turn it around.

For example, if the x coordinate is going to be less than 0, then it will have gone past the left wall, so we should turn the ball around in the x direction. Similarly if the x coordinate is greater than `fad_x@stáitse` we should turn the ball around in the x direction. If the y coordinate is less than 0, then the ball is going off the top side so we should change it’s y direction.

Let’s put two new variables in our `update_ball` action called `pred_x` and `pred_y`, these will be the predicted position of the ball, then we can use these values to check if it’s going to go over an edge.

``````gníomh update_ball() {
>-- Predicted coordinates
pred_x := ball_x + ball_dx
pred_y := ball_y + ball_dy

>-- We'll do our bounce logic here

>-- After bounce checks, update ball position
ball_x += ball_dx
ball_y += ball_dy
}``````

Now we insert our checks if the predicted positions are over an edge. To change the direction of the ball in the `x` direction we want to make `ball_dx` equal to it’s negative. The same can be done with `ball_dy`.

When the ball goes over the bottom edge, the game is over. We can use the `stop` action to completely stop the program.

``````gníomh update_ball() {
>-- Predicted coordinates
pred_x := ball_x + ball_dx
pred_y := ball_y + ball_dy

má pred_x < 0 {
>-- Gone over the left edge
>-- Change ball_dx direction
ball_dx = -ball_dx
}
má pred_x > fad_x@stáitse {
>-- Gone over the right edge
>-- Change ball_dx direction
ball_dx = -ball_dx
}
má pred_y < 0 {
>-- Gone over the top edge
>-- Change ball_dy direction
ball_dy = -ball_dy
}
má pred_y > fad_y@stáitse {
>-- Gone over the bottom edge
scríobh("GAME OVER")
stop()
}

>-- After bounce checks, update ball position
ball_x += ball_dx
ball_y += ball_dy
}``````

Now that we’ve taken care of the top, left and right edges, we need to take care of the paddle.

When we detect that the ball is going to go past the paddle, we can do an additional check to see if the paddle is under the ball by checking if the `ball_x` is between `paddle_x` and `paddle_x + paddle_width`.

If the ball has touched the paddle we can turn it around as if it hit a wall.

``````gníomh update_ball() {
>-- Predicted coordinates
pred_x := ball_x + ball_dx
pred_y := ball_y + ball_dy

má pred_x < 0 {
>-- Gone over the left edge
>-- Change ball_dx direction
ball_dx = -ball_dx
}
má pred_x > fad_x@stáitse {
>-- Gone over the right edge
>-- Change ball_dx direction
ball_dx = -ball_dx
}
má pred_y < 0 {
>-- Gone over the top edge
>-- Change ball_dy direction
ball_dy = -ball_dy
}
má pred_y > fad_y@stáitse {
>-- Gone over the bottom edge
scríobh("GAME OVER")
stop()
}

má pred_y > paddle_y {
>-- Ball gone past paddle_y
>-- Check if paddle is underneath
má pred_x >= paddle_x & pred_x <= paddle_x + paddle_width {
>-- Turn ball_dy around
ball_dy = -ball_dy
}
}

>-- After bounce checks, update ball position
ball_x += ball_dx
ball_y += ball_dy
}``````

Let’s try it out!

• The collisions are currently calculated with the center of the ball `ball_x, ball_y`. Add or subtract the radius of the ball to make the collisions work with the edge of the ball instead.