Photo by Steven Skerritt on Unsplash
Pong is a two-player table tennis theme game. It includes a moving ball and two paddles. The paddles are moved up and down by the players to make sure the ball hits it and sends it back in the direction of the other player. If one misses the ball, the other player gets the point. The first one who reaches the point needed to win will win the game. We are using HTML5 canvas and JavaScript to implement this game. Let’s look at how the game logic works.
- We’ll deploy a ball with an initial velocity and a direction at the center.
- We move the paddles up and down using the keys on the keyboard. W & S for the left player to move up and down respectively. UP & DOWN arrow keys for the right player to move up and down respectively.
- The direction of the ball is changed and speed is increased a little when the ball touches a paddle.
- The up and down boundaries of the canvas will reflect the ball when the ball hits.
- Once a player misses the ball, the other player’s score is incremented by one. It is checked whether the player has reached the score that is needed to win and if it is reached, then the player wins and the game ends.
- The game is continued until a player wins.
Technologies used
- HTML
- CSS
- JavaScript
Explanation of Source code
Let’s go through the code to understand the logic better and see how we can build ping pong.
- First, we need to create an HTML page with a canvas to run the game. Here we have a canvas to render the game and two paragraph tags to display the scores. The block with class small-device is to disable the game and display the message on small screens because there won’t be keyboard controls. The CSS file style.css and JavaScript file script.js are linked to this HTML file. 2. Now we have to add some styles to our page to make it look nice. The look and feel of a page are also an important part. The styles are straightforward, we set the canvas to the center, and scores are shown on both sides of the board. Now we also have a neon effect to our game using the box shadows. 3. Now it’s time to build the game logic using JavaScript. We have to initialize the canvas, ball, and two players. We have created the canvas and we are storing the winner in session storage, and as of now, the winner is set to none. The ball, the left player ( left paddle), and the right player ( right paddle ) are initialized with necessary properties like height, width, x & y positions, color, player name, speed, etc. The ball will have x and y velocities. 4. Now we have to create a game state and also handle key presses and key states. We’ll track each player’s score in the game object. It also contains the score needed to win, the hit count to trigger an increase in the speed of the ball, etc. We have a state for keys to record which keys are being pressed at a time. Event listeners are set up to update the states of keys on key down and key up. 5. Now we have to write functions to draw the ball and players to the canvas*.* The players and ball is drawn based on the properties of the object. A function is defined to clear the canvas and draw all of the objects to the screen. 6. We have to handle resizing the window and updating the values on resizing. When we resize a screen canvas needs to be resized and the objects in the canvas have to be repositioned to match the new canvas size. The function resize handler is called each time we resize the screen and also at the start of the program to organize the canvas and object positions. It also disables the game with an overlay when the screen size is below 560px. 7. Now we have to update the positions of the paddles when the respective keys are pressed. Here we are updating the positions of the players based on the keypress and boundaries of the canvas. 8. Time for some utility functions to reset the ball positions after each player gets a score, one to set the score of the players and display them on the page, and one to reset the game once it is over. While resetting the ball I’m changing directions of the ball because the one who got a point gets the next hit. The function which sets the score checks if all the conditions are met to update the score. It resets the ball to the center and updates the score displayed on the page. The reset game function will reset all the scores and update all states of objects to the default position, essentially resetting the game. 9. Time to write the game over function which checks if anyone wins The game-over function checks if anyone wins and saves the winner in the session storage. The page is redirected to winner.html which fetches the winner from session storage and displays it. 10. Now we have to implement collision of the ball, direction change, increase in speed, etc. The function to update states will change the Y velocity of the ball to its opposite when it touches the roof and floor of the canvas. If it touches the paddle the X velocity is changed and a function named collisionTimeLag() is called. The collision time deactivates the collision of the object for 1 second to prevent any types of bugs on collision ( like updating the state so many times on colliding ). During the deactivation, no collision will be detected ( There’s no chance for collisions during this time too ) The functions for setting the score and checking whether the game is over are invoked to ensure game updates correctly. The speed is increased when we cross the number of hits we specified in the object to increase the speed. Most importantly the position of the ball is changed by adding the velocity to the position. 11. Now let’s implement the main game loop which runs the game. This game loop will update the key presses, update the states, and draws everything constantly at around 60 times per second based on our computer resources. requestAnimationFrame is an efficient way to make animations in JavaScript. As our game loop runs and states are updated, our game will run smoothly. Voila! We made a ping pong game 🥳 You can find the whole code of the game in my Github repository. Feel free to fork it and have fun, tweak things and add new functionalities.
Want to connect?
Follow me on Twitter.