In the previous part of the tutorial we added some movement to our game that allowed us to move our player paddle up and down and bounce the ball around the constraints of the stage. In this part of the tutorial we are going to add movement to the computer paddle, add logic that will rebound the ball if it hits a paddle and also add some logic that stops the game and resets everything if the ball makes it past either paddle.
By the end of this tutorial you should have something that is similar to this – http://jsbin.com/ulowiy/9/
Note: You can move the player paddle on the left by using the up and down arrows on your keyboard. (Remember you must be using a browser that supports HTML5).
The JavaScript
OK – Let’s start off this tutorial by making the ball rebound off either paddle if it hits it or stop and reset the game if the ball manages to get past either paddle. To do this we need to expand on some of the logic that we wrote in the last part of the tutorial however before we get to that let’s declare a new global variable.
//timeout variable var wait;
We will use this new variable to set a timeout that waits three seconds before starting a new game (if the ball manages to make it past one of the paddles). Let’s add the logic that will tell us when this happens. Within the drawGame() function locate the if statement that checks if the x position of the ball added onto the amount we want to move the ball on the x axis is greater than or equal to the width of the canvas.
For the comp paddle we are going to change the if statement to the following:
//if the x position of the ball added onto the amount we want to move //the ball on the x axis is greater than or equal to the width of the //canvas if (x + directionX >= WIDTH) { //if the ball hits the compPaddle if (y > compPaddle && y < compPaddle + paddleHeight) { //depending on where the ball hits the compPaddle, rebound at an angle directionY = 10 * ((y - (compPaddle + paddleHeight / 2)) / paddleHeight); //rebound the ball directionX = -directionX; } else { //stop the current game from redrawing clearInterval(refreshStage); //wait three seconds then call the init //function to start a new game wait = setTimeout(init, 3000); } }
For the player paddle we are going to change the succeeding else if statement to the following:
//if the x position of the ball added onto the amount we want to move //the ball on the x axis is less than or equal to 0 else if (x + directionX <= 0) { //if the ball hits the playerPaddle if (y > playerPaddle && y < playerPaddle + paddleHeight) { //depending on where the ball hits the paddle, rebound at an angle directionY = 10 * ((y - (playerPaddle + paddleHeight / 2)) / paddleHeight); //rebound the ball directionX = -directionX; } else { //stop the current game from redrawing clearInterval(refreshStage); //wait three seconds then call the init //function to start a new game wait = setTimeout(init, 3000); } }
In the above two functions we are firstly checking if the ball hits the respective paddle and if it does then we will rebound the ball at a slight angle depending on where the ball impacts the paddle. If the ball doesn’t hit the paddle (but gets to the edge of the stage) then we stop the game by clearing our interval and then wait three seconds before calling the init() function using a setTimeout call.
If you run your game now then the ball should bounce past the comp paddle, wait for three seconds, reset everything and then do the whole thing all over again. So we need to add some logic to get the comp paddle to move and try to bounce the ball back in our direction. To simulate some basic AI we are going to use some maths and probability; we will keep all of the logic together in one function and will call this new function from within the drawGame() function. Place the call just after we have moved the player paddle and just before we draw the two paddles on the canvas.
//call the compMoves function to move the compPaddle compMoves();
We can place the function itself toward the bottom of our JavaScript after the clearStage() function we created in the last tutorial.
//this function calculates the movement of the compPaddle function compMoves() { //randomly pick a number beteween 0 and 1 var delayReaction = Math.random(); //chance of delayed reaction if (delayReaction >= 0.15) { if (y > compPaddle + paddleHeight) { if (compPaddle + paddleHeight + 20 <= HEIGHT) { compPaddle += 5; } } else if (y < compPaddle) { if (compPaddle - 20 >= 0) { compPaddle -= 5; } } else { var centerPaddle = Math.random(); //chance of ball hitting center of the paddle if (centerPaddle > 0.4) { //if ball closer to left side of computer paddle if (Math.abs(y - compPaddle) < Math.abs(y - compPaddle - paddleHeight)) { if (compPaddle - 20 >= 0) { compPaddle -= 5; } } else { if (compPaddle + paddleHeight + 20 <= HEIGHT) { compPaddle += 5; } } } } } }
What we are doing in this function is simulating a delayed reaction by creating a number between 0 and 1 and if that number is greater than 0.15 we move the paddle, if it isn’t we do nothing. If we do move the paddle then we can re-use the logic that we used for the player paddle to ensure that there is room for the paddle to move further up, or further down on the canvas. The last part of the function simulates logic around centring the paddle so that the ball would hit it in the middle. Again we use a random number to bring an element of chance into our game. If we didn’t do this then the computer paddle would always hit the ball back to us, which wouldn’t be a fun game at all.
If you run your code now you will notice that the ball is repeatedly moving at the same angle and is too fast for the comp paddle. To mix things up a bit lets change the direction and speed that the ball sets off at. If you remember from the last tutorial, the variables that depict which angle the ball sets off at are directionX and directionY. Let’s swap the following two lines:
directionX = 4; directionY = 6;
With the following lines:
directionX=6; //once the game begins, the ball will move a random number of pixels //either up or down every time the game stage is redrawn directionY = Math.floor(Math.random() * 10) -6;
What these lines are doing are ensuring that the ball will always start off moving along the x-axis by 6 pixels every time the stage is redrawn but the movement on the y-axis will be a random number that is either positive or negative. By doing this we randomize the speed and direction that the ball will start off at for each game. Feel free to play around with these numbers until you feel you have the right mix.
If you run your code now you should have yourself the fundamentals of a basic pong game written completely in HTML5, CSS and Javascript!
Code: http://jsbin.com/ulowiy/9/edit
In the final tutorial we will add some finishing touches to our game, such as keeping score and some nice to haves like sound.
Mark
Tagged: Allstate NI, Allstate Northern Ireland, Belfast, Canvas, CSS, Game, HTML5, IT, JavaScript, JQuery, Mark B, Northern Ireland, Pong, Software Developer, Software Development Image may be NSFW.
Clik here to view.
Clik here to view.
