Pong ~Part 1~ Setting up the Project

In 1972 Atari pioneered the video game industry with the release of Pong. If you think of classic games, Pong is almost always near the top of the list. So it is fitting that Pong should be at least one of your first flash games you make. In this tutorial, we are going to create a complete Pong game from start to finish.

 

This is what we are going to create over the next 6 tutorials:

Step One: Set up the Flash project, and create the game pieces.

The first thing to do is to create a new Flash project (make sure your select the actionscript 3 version) and name it something like “Pong Tutorial”. I recommend creating a central “Flash” folder, and then creating a new folder inside that for each of your projects. This will keep things neat and organized.

Now what you want to do is to go into the properties panel of your new project, and next to where it says “Size” hit the edit button.

In here are 3 important things that we might want to change: The dimensions of your game, the FPS (frames-per-second), and the background color. Make sure that your project size is 550px wide by 400px tall – this should already be the default. Then change your background color to black. We’ll use white game pieces on a black background, just like the original. Finally, set your FPS to 60. This is the number of times the game will update its display every second that you play. So the higher your FPS, the smoother the visuals will be. 30 is a pretty standard FPS, but 60 gives even smoother gameplay. The only downside is that if your FPS is too high your game might lag and be worse off than using a lower FPS.

 

Now that our project is set up, the first thing we are going to do is create the main game pieces for our Pong game. These will include 2 paddles and the ball. So first, let’s make the ball. Using the circle tool, create a white, 10 x 10 pixel circle. Tip: Hold down shift while using the Oval Tool to draw circles. Edit the size to be exactly what you want by using the “Position and Size” section of the properties panel.

And now use Modify –> Convert to Symbol and turn it into a new Movie Clip object. You can name it “Ball”, or anything else that takes your fancy. One thing to be careful about is the Registration section. Click on the center block of the grid. This will make the center of the ball become the center of the object instead of one of the corners.

Next up is are the two paddles. Since they are the same we can just make one paddle Movie Clip, and create two instances of it.

Use the rectangle tool to draw a paddle 10 pixels wide by 50 pixels tall.

Then convert it to a symbol, name it Paddle, and set its registration to the center.

 

Alright, that was easy. Now all we have to do is set up the stage with the game pieces. Go to your Library panel and drag two paddles onto the main stage, and 1 ball (if the library isn’t open go to Window –> Library or hit Command+L).

Set the position of one paddle to (20, 200), the other to (530, 200), and the ball to (275, 200). You want your screen to look like this:

 

Step One — COMPLETE!

If you run your game (Command+Return), you will see these graphics show up. But… they don’t do anything yet :(

Download the source code pong1

Pong ~Part 2~ Programming the Ball

Step Two: Program the basic game loop and the ball

First things first, we need to name each instance of our game pieces — this is what we’ll use to refer to each object in the code. Name the paddle on the left “playerPaddle” (no quotes), the paddle on the right “cpuPaddle”, and the ball can just be named “ball”.

OK, now open up the actionscript panel (Window -> Actions), and click anywhere on the background so that nothing on the stage is selected. Flash is now set up so that the code that you type into the panel will run when we compile the game.

So, we’re ready to add code… where’s the best place to start?

I strongly recommend planning out in your head what the game needs to do before you start programming. I boiled our game down to 3 main mechanics, and we can add any extra features afterwards:

One thing in common between all of these actions is that they need to be happening every single frame, not just a one-shot deal. So let’s begin with the main game loop.
init(); //call this function once, at the very beginning, to initialize everything  function init():void { 	stage.addEventListener(Event.ENTER_FRAME, loop); //every time our game enters a new frame (60 times per second), this event listener will fire and our game will loop }  function loop(e:Event):void {  } 

Very basic, but everything that we code inside the loop function will happen over and over again.

Let’s start with our first game mechanic: the ball. This code will make it move.

var ballSpeedX:int = -3; //how fast the ball is moving left and right var ballSpeedY:int = -2; //how fast the ball is moving up and down (negative = up)  init();  function init():void { 	stage.addEventListener(Event.ENTER_FRAME, loop); }  function loop(e:Event):void { 	ball.x += ballSpeedX; //each frame, we add the ballSpeedX to the ball's x position 	ball.y += ballSpeedY; //we do the same with the ballSpeedY and the ball's y position } 

If you compile the game now (Control -> Test Movie) you should see the ball zoom off of the upper-right corner of the screen.

That’s an improvement, but we want our ball to bounce off of every wall so that it stays on the screen. Try this:

var ballSpeedX:int = -3; var ballSpeedY:int = -2;  init();  function init():void { 	stage.addEventListener(Event.ENTER_FRAME, loop); }  function loop(e:Event):void { 	ball.x += ballSpeedX; 	ball.y += ballSpeedY;  	//because the ball's position is measured by where its CENTER is... 	//...we need add or subtract half of its width or height to see if that SIDE is hitting a wall  	//first check the left and right boundaries 	if(ball.x <= ball.width/2){ //check if the x position of the left side of the ball is less than or equal to the left side of the screen, which would be 0 		ball.x = ball.width/2; //then set the ball's x position to that point, in case it already moved off the screen 		ballSpeedX *= -1; //and multiply the ball's x speed by -1, which will make it move right instead of left  	} else if(ball.x >= stage.stageWidth-ball.width/2){ //check to see the right side of the ball is touching the right boundary, which would be 550 		ball.x = stage.stageWidth-ball.width/2; //reposition it, just in case 		ballSpeedX *= -1; //multiply the x speed by -1 (now moving left, not right)  	}  	//now we do the same with the top and bottom of the screen 	if(ball.y <= ball.height/2){ //if the y position of the top of the ball is less than or equal to the top of the screen 		ball.y = ball.height/2; //like we did before, set it to that y position... 		ballSpeedY *= -1; //...and reverse its y speed so that it is now going down instead of up  	} else if(ball.y >= stage.stageHeight-ball.height/2){ //if the bottom of the ball is lower than the bottom of the screen 		ball.y = stage.stageHeight-ball.height/2; //reposition it 		ballSpeedY *= -1; //and reverse its y speed so that it is moving up now  	} } 

It really isn’t too complicated, but I’ve added a ton of comments so you know exactly what is happening. In order to find the x value of the right side of the screen we used the stageWidth property of the stage, and likewise we used the stageHeight property to find the y value of the bottom of the screen. If the ball’s position is ever greater or less than a specific side of the screen, the speed will reverse and it will bounce off the wall.

Compile it… and… it’s like you have magic invisible borders on your screen!

Download the source code here!pong2

Sweet game! It still needs a lot of work, but this is a good foundation to work off of.

Pong ~Part 3~ The Player’s Paddle

Step Three: Program the Player-controlled Paddle

We got the ball to move and bounce off of the walls in our last tutorial. Now it’s time to program the player-controlled paddle. What does the playerPaddle need to do?

  • Set it’s y-position to the y-position of the mouse
  • Stay within the boundaries of the screen
  • Block the ball from passing through it

This will be a pretty simple tutorial section.

Add this one little line of code to your loop function (it doesn’t matter where; I just put it at the top).

1
playerPaddle.y = mouseY;

Literally, this just sets the y position of the paddle to the y position of the mouse every frame. It’s that simple. Compile your code and you can see the paddle move with your mouse.

But if you move your mouse above or below the game window, the paddle will keep moving out of the game screen. In order to fix that, we add some code similar to what we did with the ball. Add this all inside the loop function, right below the last line we added. See if you can understand what I’m doing:

1
2
3
4
5
6
7
8
//check if top of paddle is above top of screen
if(playerPaddle.y - playerPaddle.height/2 < 0){
     playerPaddle.y = playerPaddle.height/2;
 
//check if bottom of paddle is below bottom of screen
} else if(playerPaddle.y + playerPaddle.height/2 > stage.stageHeight){
     playerPaddle.y = stage.stageHeight - playerPaddle.height/2;
}

Now no matter what you do, the paddle cannot go beyond the boundaries of the screen!

Download the source code here

I know this tutorial was really short and simple, but are going to wait to program the collisions between the ball and the playerPaddle until after we code the cpuPaddle.

 

Pong ~Part 4~ The CPU’s Paddle

Step Four: Program the Computer-controlled Paddle

OK, so the last tutorial was pretty short and sweet. So lets waste no time getting into the next step. This step is pretty important because we begin to look at a very important step in game programming: AI (which stands for Artificial Intelligence).

Artificial Intelligence

Any time when the computer itself needs to control something (like an enemy in a game) and perform certain actions depending on certain conditions, we call this AI. Now, our AI is fairly basic. We need the computer’s paddle to move up and down to try to block the ball from getting past. It would be easy to make the cpuPaddle ALWAYS block the ball — all we would do is constantly set the cpuPaddle.y to the ball.y position. But how do we give the computer the intelligence to act like a normal player, sometimes succeeding and other times failing?

The best way to figure this out is to simply look at how a normal player would react in a situation, and try to replicate that with code.

This is actually pretty easy in our case — just think of how you play pong. You constantly watch the ball. If it is too far below your paddle, you move your paddle down. If it is too far above, you move it up. However, to stop the computer from being an invincible pong player, we will give the cpuPaddle a max movement speed, so that it can’t always catch the ball in time. That will be the basis for our AI. It’s really simple, but that’s all we need right now.

At the top of your file create a new variable which will control how fast the cpuPaddle can move up and down:

1
var cpuPaddleSpeed:int = 3;

And then in your game loop function, add this code (anywhere is fine, I just put it at the top).

1
2
3
4
5
if(cpuPaddle.y < ball.y - 10){
    cpuPaddle.y += cpuPaddleSpeed;
} else if(cpuPaddle.y > ball.y + 10){
    cpuPaddle.y -= cpuPaddleSpeed;
}

This code moves the cpuPaddle. If the y position of the paddle is more than 10 pixels above or below the ball, it will move in whatever direction it needs to, with a speed equal to the cpuPaddleSpeed.

Wait a minute… now that we spent all this time giving the cpuPaddle some basic AI to make it imperfect, it still never misses the ball! Don’t worry, this is only for the moment. Right now, the ball is traveling at a constant y-speed: 2 (or -2). But once we program the collisions between the paddles and the ball we are going to add a few lines of code that will change the ball’s y speed (and therefore, its direction) so that it is possible for the ball to move faster than the cpuPaddle can keep up with.

Get the source code while supplies last! Click here to download.

Again, this was only a short-and-sweet tutorial designed to get the cpuPaddle moving with some AI. Next tutorial we are going to get into the juicy part you’ve all been waiting for: programming the collisions between the paddles and the ball — at which point you will actually be able to play the game!

 

Pong ~Part 5~ Collisions!

Let’s get started.

So far, we’ve got the ball to move and bounce off walls. We’ve made the playerPaddle be controllable by the mouse. And we’ve told the cpuPaddle to move up or down depending upon the position of the ball. It’s time to turn this into a “real” game by letting the ball be blocked by the paddles.

Hit Testing

The way Flash handles collisions between two objects on the stage is called hit testing. The way it works is that Flash keeps track of invisible bounding boxes around every object on the screen. These bounding boxes are the smallest possible rectangle that your object can fit inside. So for our paddles, the bounding box is exactly the same shape. But for the ball, instead of using the circular 30px by 30px shape we drew, Flash uses a 30px by 30px square.

(This doesn’t really matter too much in our game because it is so simple but in more complex games where you have objects of complex shapes it can be a problem. There are a couple more complex ways to do perfect collision detection, but we aren’t going to worry about that yet!)

In order to check for collisions, we need to specify two objects in our game. First off let’s check between the ball and the playerPaddle.

Here is the code which will handle the collisions between the ball and the playerPaddle:

(add this into the top of the main game loop)

	if( playerPaddle.hitTestObject(ball) == true ){ 		if(ballSpeedX < 0){ 			ballSpeedX *= -1; 		} 	} 

What this code does is it accesses the playerPaddle’s hitTestObject method inside of an “if” statement. We passed in whatever object we wanted it to check for — the ball. HitTestObject is a built-in method in Flash which will check whether 2 objects’ bounding boxes are overlapping at all. If they are, it will return “true”, and your following code will execute. If they aren’t colliding, the conditional will return “false” and nothing will happen.

Notice we added in the extra line so that it only bounces the ball back if the ballSpeedX is a negative number. This is because the playerPaddle is on the left, so we only need to bounce the ball back if it is moving in the negative direction. This little extra bit of actionscript will prevent any potential bugs in the game where the ball might get stuck repeatedly bouncing behind the far side of the paddle.

If you compile your code… voila! The ball bounces off your paddle! Congratulations, your project is gradually starting to resemble a real game.

If we duplicate that code, but substitute in the cpuPaddle for the playerPaddle, and a ballSpeedX of greater than 0 instead of less than 0, we can get the cpuPaddle to handle its own collisions too.

Add to the first set of code, so that it includes the following “else” statement:

	if( playerPaddle.hitTestObject(ball) == true ){ 		if(ballSpeedX < 0){ 			ballSpeedX *= -1; 		}  	} else if(cpuPaddle.hitTestObject(ball) == true ){ //add this 		if(ballSpeedX > 0){ 			ballSpeedX *= -1; 		}  	}  

Let’s test this out.

Awesome!

Alright, so that’s all fine and dandy, but let’s take this to the next level. In order to add some level of skill to this game — and make it possible for the cpuPaddle to lose, we are going to program a set of instructions so that the angle of the ball will change depending on what spot it collides with the paddle. If the ball hits the top of the paddle it will angle upwards; if it hits the bottom it will angle downwards; if it hits the middle it will go somewhere in between.

How do we accomplish this? By adding this code… I’ll explain afterwards.

First create a new function called “calculateBallAngle”. You can place it anywhere in the code window as long as it isn’t inside any other function. I put mine right above the loop function.

function calculateBallAngle(paddleY:Number, ballY:Number):Number { 	var ySpeed:Number = 5 * ( (ballY-paddleY) / 25 ); 	// (ballY-paddleY) / 25 will be between -1 and 1 depending on where the ball hits  	return ySpeed; } 

Note: This function doesn’t return “void” like all of those we have worked with in the past. When this function runs it calculates a Number value, which it sends back to wherever the function was called from. This Number is going to be the y speed of the ball, which we are setting to a value between -5 and 5.

In our case this will be the hitTestObject code we added earlier, so let’s go back to the main game loop and add a couple new lines to that section.

	if( playerPaddle.hitTestObject(ball) == true ){ 		if(ballSpeedX < 0){ 			ballSpeedX *= -1; 			ballSpeedY = calculateBallAngle(playerPaddle.y, ball.y); //add this 		}  	} else if(cpuPaddle.hitTestObject(ball) == true ){ 		if(ballSpeedX > 0){ 			ballSpeedX *= -1; 			ballSpeedY = calculateBallAngle(cpuPaddle.y, ball.y); //add this 		}  	} 

If this looks unfamiliar to you, don’t worry. What we’re doing is every time the ball collides with one of the paddles, in addition to changing the x velocity of the ball, we are setting the y velocity of the ball to the results of our calculateBallAngle function that we just added. When we are checking for collisions between the playerPaddle and the ball, we pass in the y values of the playerPaddle and the ball to the calculations. When we are checking with the cpuPaddle, we use that y value instead.

Run your code one last time.

Beautiful.

Well, there you have your basic Pong game. We accomplished our 3 main goals we set in Part 2: programming the mouse-controlled playerPaddle, the AI-controlled cpuPaddle, and programming the ball and its collisions.

Grab your copy of the source code HERE.

But don’t stop now, there is still so much we can do to make this game better! Next we are going to at least look at adding a scoring system, a main menu, and a win/lose capability.

Pong ~Part 6~ Scoring Points

Keeping track of score

Pong traditionally has 2 score values: the player’s score and the computer’s score. This is actually super-simple for us to create! Basically a score value is just a variable that holds a number. At the start of the game we set the variable to 0, and every time the ball hits the left or right walls we add 1 to the score of whoever scored the point.

First off, let’s create the playerScore and cpuScore variables, which will be integers. Add this right below the other variable declarations.

1
2
var playerScore:int = 0;
var cpuScore:int = 0;

That was easy enough. Now let’s revisit some old code from Part 2 of this series (when we programmed the ball bouncing off the walls). Logically, whenever the ball hits the right edge of the screen the player will score 1 point. And whenever the ball hits the left edge of the screen the computer scores a point.

Modify this code from the main game loop…

1
2
3
4
if(ball.x = stage.stageWidth-ball.width/2){
    ball.x = stage.stageWidth-ball.width/2;
    ballSpeedX *= -1;
}

…so that it looks like this:

1
2
3
4
5
if(ball.x = stage.stageWidth-ball.width/2){
    ball.x = stage.stageWidth-ball.width/2;
    ballSpeedX *= -1;
    playerScore++; //increase playerScore by 1
}

Also, modify your other code by adding cpuScore++, in the same way you added playerScore++.

1
2
3
4
5
if(ball.x &lt;= ball.width/2){
     ball.x = ball.width/2;
     ballSpeedX *= -1;
     cpuScore++; //increase cpuScore by 1
}

As you can see, in order for the player to score a point we type in “playerScore ++”, and we type in “cpuScore ++” when the computer scores a point. Pretty self explanatory.

Creating the text fields

So if you test the game now you’ll notice that although we did add the code for the scoring system, nothing has visually changed. We still need to add a display for the scores, so the you can visibly see how many points each side has. In order to do this we need to first move back over to the stage of Flash and build a text game object for each score.

 

Use the Text Tool (T) to create a text field on the screen. In it, type: Player Score: 0 (as shown above). Select it, and in the top of the properties panel switch the text field from Static Text to Dynamic Text. This changes it from just ordinary text into a game object which we can modify using code. It also lets us give the text an instance name, so name yours “playerScoreText”.

The rest of the formatting doesn’t really matter, except to make it look differently. Feel free to either use the formatting shown in the image above, or to format the text field on your own. Personally I set the color to white, used a size 18 Courier font, set the position to (0,0) and set the width to 200 so that the text field has extra space in case the score takes up multiple digits.

Now we must do the same for the cpuScore.

 

Basically just repeat what we did for the playerScoreText: Create a text field, type in: CPU Score: 0, set it to Dynamic Text, give it the instance name cpuScoreText, and format it like you did the last one. I positioned my cpuScoreText at (400,0) and gave it a width of 150.

Putting it all together

So now that the text fields are all set up we can return to the code and put everything together.

Create a new function in your code window called updateTextFields:

1
2
3
4
5
function updateTextFields():void
{
    playerScoreText.text = ("Player Score: " + playerScore);
    cpuScoreText.text = ("CPU Score: " + cpuScore);
}

Every time this function is called the we modify the text property of the playerScoreText and cpuScoreText. We set the text equal to the score name (in quotes) plus the score variable (no quotes). This function is complete.

All we have to do to make this work is to call updateTextFields() anytime someone scores a point. So go back to the code in the game loop, and add those lines:

1
2
3
4
5
6
if(ball.x = stage.stageWidth-ball.width/2){
    ball.x = stage.stageWidth-ball.width/2;
    ballSpeedX *= -1;
    playerScore++; //increase playerScore by 1
    updateTextFields();
}

And now, ladies and gentlemen, the scoring system is done!

 

Get your sourcecode hot off the press,.here