How to Make Pong with Javascript

Hershy Bateea
9 min readAug 7, 2016

--

Pong is an awesome game to play, but it’s even more fun if you’ve made it yourself! Making pong with javascript is a great way to get started on your web dev journey (though it may not seem like it yet), learn javascript, or just have fun making a cool game. So let’s get started!

You can also take a look at this and more stories at: https://hershalb.com/how-to-make-pong-with-javascript/

First, we start building the necessary moving parts — the two paddles on either side of the screen and the ball in the middle. Create a new file “pong.html” in the directory of your choice, and add the following code:

<!doctype html>
<html>
<body>
<div id=”paddle1" style=”position:absolute;left:0px;top:460px;width:10px;height:150px;background-color:black;”>
</div>
<div id=”ball” style=”position:absolute;left:820px;top:510px;width:25px;height:25px;background-color:red;border-radius:50%;”>
</div>
<div id=”paddle2" style=”position:absolute;right:0px;top:460px;width:10px;height:150px;background-color:black;”>
</div>
</body>

This code creates two paddle divs, with the ids of “paddle1” and “paddle2”. We style the paddles so that they are 150px in height and 10px wide. You can edit this to your preference. The “position: absolute” style attribute on the paddles allow us to place them anywhere on the screen without worrying about the position of other divs. Next, the “left: 0px” and “right: 0px” on each respective paddle ensures that the paddles are at the very edge of the screen. Finally, the “top: …” property puts the top of each paddle 460px from the top of the screen.

The ball div is essentially the same as the paddles, except the left value is changed (because we want the ball in the middle of the screen) and there is a “border-radius: 50%” property which essentially makes the div into a circle.

The top and left values may need to be changed depending on the size of your screen, but drag and drop this file into your favorite browser and it should look like:

First pong.html edit, left space on top for title and scores.

Next below the closing body tag, we need to add script tags to add javascript into the file. Since the amount of code we will write is going to be short, I decided to add it into the same html file, but keep in mind it is smart to import javascript from another file.

...
</body>
<script type="text/javascript">
</script>

What do we need javascript for? We need to add something that will move the objects once we press a key. So how can we do that? First we need to decide what variables will be changed. The position of the paddles will change, they will be moving up and down which can be manipulated by the top style property that was mentioned earlier. Next, the ball left and top position needs to be changed. We will keep a list of variables to keep track of all the important information.

var paddleHeight = 150;
var ballRadius = 25;
var halfPaddleHeight = paddleHeight / 2;
var speedOfPaddle1 = 0;
var positionOfPaddle1 = 460;
var speedOfPaddle2 = 0;
var positionOfPaddle2 = 460;
var topPositionOfBall = 510;
var leftPositionOfBall = 820;
var topSpeedOfBall = 0;
var leftSpeedOfBall = 0;
var score1;
var score2;

The variables should be self explanatory, but each keeps track of the corresponding top and left values, so that when the variables change, so do the style values. Now, let’s add code that moves the paddles up and down. The way to do this is to detect whether a user has pressed the up, down, W, or S keys. We can do that in Javascript by adding an eventListener. Based on that, we will change the top style value of the paddle using javascript’s “document.getElementById” function.

document.addEventListener('keydown', function (e) {
if (e.keyCode == 87 || e.which == 87) { // W key
positionOfPaddle1 -= 10;
document.getElementById("paddle1").style.top =
(positionOfPaddle1) + "px"
}
if (e.keyCode == 83 || e.which == 83) { // S Key
positionOfPaddle1 += 10;
document.getElementById("paddle1").style.top =
(positionOfPaddle1) + "px";
}
if (e.keyCode == 38 || e.which == 38) { // up arrow
positionOfPaddle2 -= 10;
document.getElementById("paddle2").style.top =
(positionOfPaddle2) + "px";
}
if (e.keyCode == 40 || e.which == 40) { // down arrow
positionOfPaddle2 += 10;
document.getElementById("paddle2").style.top =
(positionOfPaddle2) + "px";
}
}, false);

Adding this within the script tags will allow us to change the position of the left and right paddle every time W, S, up, or down is pressed. Now open reload the pong.html file in your browser and test the keys out and… the paddles move! However, the movement is very choppy right now, but we want a smoother action. The way we can do this is continuously update the position of the paddles with a function that gets called multiple times per second. This function would update the top style position, and the event listener we just made would update the speed of the paddles.

document.addEventListener(‘keydown’, function (e) {
if (e.keyCode == 87 || e.which == 87) { // W key
speedOfPaddle1 = -10;
}
if (e.keyCode == 83 || e.which == 83) { // S Key
speedOfPaddle1 = 10;
}
if (e.keyCode == 38 || e.which == 38) { // up arrow
speedOfPaddle2 = -10;
}
if (e.keyCode == 40 || e.which == 40) { // down arrow
speedOfPaddle2 = 10;
}
}, false);
// This function gets called 60 times per second window.setInterval(function show() {
positionOfPaddle1 += speedOfPaddle1;
positionOfPaddle2 += speedOfPaddle2;
document.getElementById(“paddle1”).style.top =
(positionOfPaddle1) + “px”;
document.getElementById(“paddle2”).style.top =
(positionOfPaddle2) + “px”;
}, 1000/60);

Now reloading the doc, we see that pressing the up and down arrow keys moves the paddle with a much smoother motion, but the paddles don’t stop! How can we stop the paddles as soon as we let go of the key we are pressing? All we have to do is add another event listener for the ‘keyup’ action. Same as last time, but it will set the speed to 0 for any keyup action. Try writing this yourself first, and then take a look at the code below.

document.addEventListener(‘keyup’, function (e) {
if (e.keyCode == 87 || e.which == 87) {
speedOfPaddle1 = 0;
}
if (e.keyCode == 83 || e.which == 83) {
speedOfPaddle1 = 0;
}
if (e.keyCode == 38 || e.which == 38) {
speedOfPaddle2 = 0;
}
if (e.keyCode == 40 || e.which == 40) {
speedOfPaddle2 = 0;
}
}, false);

The keyup action is triggered when the arrow key is let go of, and the keydown action is triggered when the key is pressed. So when you stop pressing the key, the paddle will stop moving. Reload the doc and we now have smooth paddle movement that stops as soon as you let go of the key. Now all we have to do is add if statements within the window.setInterval function to ensure that the paddles stop at a certain point (if you keep holding the down arrow, the paddle will continuously move downwards).

positionOfPaddle1 += speedOfPaddle1;
positionOfPaddle2 += speedOfPaddle2;
if (positionOfPaddle1 <= 150) {
positionOfPaddle1 = 150;
}
if (positionOfPaddle2 <= 150) {
positionOfPaddle2 = 150;
}
if (positionOfPaddle1 >= window.innerHeight — paddleHeight) {
positionOfPaddle1 = window.innerHeight — paddleHeight;
}
if (positionOfPaddle2 > window.innerHeight — paddleHeight) {
positionOfPaddle2 = window.innerHeight — paddleHeight;
}
...

This function says that if the paddle position is 150 (this number was chosen to keep space for the title and scores) from the top of the screen, don’t change the position of the paddle. If the paddle position is a paddle length away from the bottom of the screen, then stop the paddle. Trying the game out again, we can see that the paddles will not go beyond a certain point. Now we must handle the ball movement.

Right away, we know that the ball position must be updated by the ball speed, so add the proper code in the setInterval function.

topPositionOfBall += topSpeedOfBall;
leftPositionOfBall += leftSpeedOfBall;
...document.getElementById("ball").style.top =
(topPositionOfBall) + "px";
document.getElementById("ball").style.left =
(leftPositionOfBall) + "px";

The speed of the ball is not affected by any keypress, so we must create a function that gives a set speed to the ball as soon as the document is loaded. The way to do this is in the first body tag. And in the script tags, we will add a function startBall() that gives a random left and top speed to the ball.

<html>
<body onload="startBall()"
...
...
<script>
function startBall() {
topPositionOfBall = 510;
leftPositionOfBall = 820;
if (Math.random() < 0.5) {
var side = 1
} else {
var side = -1
}
topSpeedOfBall = Math.random() * -2 - 3;
leftSpeedOfBall = side * (Math.random() * 2 + 3);
};
</script>

The start ball function creates a new variable side based on Math.random. Math.random() returns a random number between 0 and 1. If side is negative, the ball will move to the left. If side is positive ball will move to the right. Next, the speed of the ball is set by random values. The (Math.random() * 2 + 3) may seem arbitrary, but these are values you can play around with to see how fast you want the ball to move. The reason we set the leftPos and topPos for the ball is to ensure that when we start a new game, the ball is centered first.

Finally, we need to add if statements again to stop the ball at certain points, but instead of making the ball stop moving, we want to make the ball reflect off the surface. If it bounces off the top of the screen, the top speed will become negative and it will go in the other direction. The same idea applies to the bottom of the screen. We will add this code in the setInterval function below the other if statements.

if (topPositionOfBall <= 150 || 
topPositionOfBall >= window.innerHeight — ballRadius) {
topSpeedOfBall = -topSpeedOfBall
}

Now, we must add the same code to the left and right side of the screen, but only if the paddle is next to it. Otherwise, we want to start a new round by calling startBall(). To do this, we need to add more if statements in the setInterval function, and check the position of the ball according to the position of the paddles.

if (leftPositionOfBall <= paddleWidth) {
if (topPositionOfBall > positionOfPaddle1 &&
topPositionOfBall < positionOfPaddle1 + paddleHeight) {
leftSpeedOfBall = -leftSpeedOfBall;
} else {
startBall();
}
}
if (leftPositionOfBall >= window.innerWidth — ballRadius - paddleWidth) {
if (topPositionOfBall > positionOfPaddle2 &&
topPositionOfBall < positionOfPaddle2 + paddleHeight) {
leftSpeedOfBall = -leftSpeedOfBall
} else {
startBall();
}
}

If the position of the ball is left of the first paddle, and the ball is in between the two ends of the paddle, the speed of the ball gets negated. The same applies for the right side. Now we have a fully functioning game of Pong, the only thing we need now is a title and Scores to make the game look nicer. The way to do this is to add headlines for the scores and title in the html.

<body onload=”startBall()”>
<h1 style=”position:absolute;left:45%;top:10px;font-size:70px;”>Pong</h1>
<h1 style=”position:absolute;left:30px;top:80px;”>Score 1: <span id=”score1">0</span></h1>
<h1 style=”position:absolute;right:30px;top:80px;”>Score 2: <span id=”score2">0</span></h1>
<hr style=”margin-top:150px;”>

The screen should now look like:

Pong with a Scoreboard

Now, we need to edit the scores. When we call startBall(), we know the score will change, so if we call startBall() after the ball has gone past the left paddle score2 will increase by 1 and the same applies for the ride side. Using the same code from above:

if (leftPositionOfBall <= paddleWidth) {
if (topPositionOfBall > positionOfPaddle1 &&
topPositionOfBall < positionOfPaddle1 + paddleHeight) {
leftSpeedOfBall = -leftSpeedOfBall;
} else {
score2++;
startBall();
}
}
if (leftPositionOfBall >= window.innerWidth — ballRadius - paddleWidth) {
if (topPositionOfBall > positionOfPaddle2 &&
topPositionOfBall < positionOfPaddle2 + paddleHeight) {
leftSpeedOfBall = -leftSpeedOfBall
} else {
score1++;
startBall();
}
}
...document.getElementById('score1').innerHTML = score1.toString();
document.getElementById('score2').innerHTML = score2.toString();

Now reload the page, and you have a fully functioning game of Pong! It’s even more fun now that you’ve made it yourself! Check out the full source code here. Next, you can try adding your own fun changes to the game: have sounds when the ball hits the paddle, make the ball a picture, have a background picture, or add buttons to the game. Enjoy!

--

--

Hershy Bateea
Hershy Bateea

Written by Hershy Bateea

Hello, I’m Hershal Bhatia, currently a Software Engineer at Amazon – AWS where I am building out a new service. Check out more at www.hershalb.com

Responses (2)