How to Create Pong in Your HTML5 Game

No HTML5 game development discussion would be complete without a mention of the famous Pong game. While this wasn't technically the first video game, it was the first to attract popular attention, and it's by far one of the more influential games ever made.


Build the game paddle

The paddle object is quite straightforward, but there are actually two paddles with different behaviors. In this version of the game, the left paddle is controlled by the player, and the right paddle is controlled by a computer AI. A single paddle object can serve as either a player or an AI paddle. The player paddle just follows the mouse:

  tPaddle.followMouse = function(){
   //follows mouse for player control
   this.setPosition(this.x, scene.getMouseY());
  } // end followMouse method

Add artificial stupidity to your game

It's actually very easy to build an Artificial Intelligence (AI) for the opponent. Simply set the paddle's Y value equal to the ball's Y value. However, this will be boring, because the opponent will never miss, and will always hit the ball squarely in the middle of the paddle, making it easy to return. This is no fun at all. Give the AI paddle some kind of attention issues.

The AI shouldn't directly follow the ball. Instead, it should check to see whether the ball is above or below it, and respond accordingly.

Two variables were added to control the AI paddle's motion. The BRAINS constant is a percentage. If BRAINS is set to .5, the paddle will check for ball location only half the time. For an easier game, set the BRAINS value low.

The other primary value is V_SPEED, or the vertical speed of the paddle. This indicates how quickly the paddle will move toward the ball. A higher value will create a more powerful AI player. Find the right combination of these two values to get the AI behavior you want. Here's the code for the autoMove() method:

  tPaddle.autoMove = function(){
   //automatically moves
   //don't move on every turn
   if (Math.random() < BRAINS){
    if (this.y > ball.y){
    } else {
    } // end if
   } // end if
  } // end autoMove

Build a ball to bounce off boundaries

While the ball is a seemingly simplistic sprite, it does have some interesting behavior. The ball has a unique boundary-checking scheme. It bounces off the top and bottom of the screen, but if it leaves the sides, it wraps.

If you don't have a boundary scheme that fits one of the standard patterns, you can simply overwrite the checkBounds() method to do whatever you want. (Note that you don't need to explicitly call checkBounds(). It is automatically called by the sprite's update() method. Your custom version of checkBounds simply replaces the built-in version. Here's a variant:

  tBall.checkBounds = function(){
   //overwrite checkbounds function to give
   //custom behavior
   //bounce off of top and bottom
   if (this.y < 0){
    this.setDY(this.dy * -1);
   if (this.y > scene.height){
    this.setDY(this.dy * -1);
   //wrap off of sides
   if(this.x < 0){
    this.setPosition(scene.width - 150, this.y);
    //computer scores
   } // end if
   if (this.x > scene.width){
    this.setPosition(150, this.y);
    //player scores
   } // end if
  } // end checkBounds

If the ball hits the top or bottom of the screen, invert dy to make it bounce. If it hits the left or right of the screen, move it to the other side.

Put some spin on the game ball

In traditional versions of Pong, the ball can be controlled by choosing where on the paddle to hit the ball. If you hit the ball near the top of the paddle, the ball will move upward. If you hit the ball near the center of the paddle, it will fly across the screen horizontally, and if you hit near the bottom, the ball will move downward.

  tBall.checkBounce = function(paddle){
   //responds to a collision with the given paddle
   //Max and min dy
   MAX = 10
   if (this.collidesWith(paddle)){
    this.setDX(this.dx * -1);  
    dy = this.y - paddle.y;
    dy = ((dy / paddle.height) * 2);
    dy *= MAX;
   } // end if
  } // end checkBounce

The dx value is easy to calculate because you simply invert dx to move in the other direction. The dy value is calculated by determining the difference between the ball's y position and that of the paddle:

  1. Determine a maximum dy.

    This value determines the highest level of deflection you'll allow. If the MAX value is set to 10, the ball's dy value will be -10 at the top of the paddle, 0 at the middle, and 10 at the bottom of the paddle.

  2. Invert dx.

    If the ball is moving left, multiply the dx value by -1 to make it go right. If it's going right, the same operation (multiplying by -1) will make it go left. Any paddle collision inverts the ball's dx.

  3. Find the raw difference in y values.

    Calculate how far apart the y value of the paddle and the ball are.

  4. Normalize this value.

    If you divide the raw dy value by the height of the paddle, you'll get a range between -.5 and .5. Multiply that value by 2 to get a -1 to 1 range.

  5. Multiply the normalized dy by MAX.

    Multiplying the normalized dy value by the MAX value will give a dy value between -MAX and MAX.

How to improve the Pong game

While this Pong game has the basic behavior down, it's far from ready for actual play. Here are a few things to consider adding:

  • Add aesthetic appeal. You can do a lot to make it look better, from customizing the paddles to adding ball animations and sound effects.

  • Add scorekeeping. Add the ability to track user and computer scores. Also add some way to determine the end of the game.

  • Add powerups. Change the size of each paddle, invert the control of the player paddle, change the ball speed, make the ball occasionally invisible, or invert the ball-paddle collision algorithm for starters.

  • Tune up the AI. It gets pretty jittery when the ball is traveling in a flat trajectory. See if you can figure out a way to smooth out this behavior.

  • Add a Comment
  • Print
  • Share
blog comments powered by Disqus

Inside Sweepstakes

Win $500. Easy.