How to make a simple AS 3.0 Pong Game (Tutorial)

First of all, I’m so so sorry for my long delay, I had a tough period, with lots of hard exams and stuff like that, but now I’m coming with a new tutorial, that I hope will be helpful for many of you . In the beginning I’ll show you how the final result should look.

Final Result Preview


Flash Pong Game

Create the objects

Paddle.as

So, in Flash Builder or in other IDE create a new AS 3.0 Project and name it PongGame.
In this first step we will create our objects, and because this is a simple game, we have only two objects: a paddle and a ball. First let’s see how the Paddle class looks like.

package hc
{
	import flash.display.Sprite;

	public class Paddle extends Sprite
	{
		private var _width:uint;
		private var _height:uint;
		private var _color:uint;
		private var _alpha:Number;
		
		public function Paddle(width:uint, height:uint, color:uint, alpha:Number)
		{
			this._width = width;
			this._height = height;
			this._color = color;
			this._alpha = alpha;

		}
		
		public function Draw():void
		{
			with(this.graphics)
			{
				beginFill(_color,_alpha);
				drawRect(0,0,_width,_height);
				endFill();
			}
		}
		
	}
}

As you can see, this is a very simple class, that has only a constructor and a method Draw();, which creates our object.

Ball.as

Now that our paddle is created, we only need a ball. Let’s take a look at this Ball class:

package hc
{
	import flash.display.Sprite;

	public class Ball extends Sprite
	{
		private var _radius:uint;
		private var _alpha:Number;
		private var _color:uint;
		
		private var Speed:Number = 4;
		private var VX:Number = 0;
		private var VY:Number = 0;
		
		private var enemyPoints:int = 0;
		private var heroPoints:int = 0;
		
		public function Ball(radius:uint, alpha:Number, color:uint)
		{
			this._alpha = alpha;
			this._radius = radius;
			this._color = color;
		}
		
		public function Draw():void
		{
			with(this.graphics)
			{
				beginFill(_color, _alpha);
				drawCircle(0,0,_radius);
				endFill();
			}
		}
		
		public function SetBallStartPosition():void
		{
			with(this.graphics)
			{
				this.x = stage.stageWidth * 0.5;
				this.y = stage.stageHeight * 0.5;
			}
		}
		
		private function getRandom(low:Number=0, high:Number=1):Number
		{
			return Math.floor(Math.random() * (1+high-low)) + low;
		}
		
		public function MoveBall():void
		{
			var rand:Number = getRandom(-10,10);
			
			if(rand >= 0)
			{
				VY -= Speed;
			}
			else
			{
				VY += Speed;
			}
			
			if(rand % 2 == 0)
			{
				VX += Speed;
			}
			else
			{
				VX -= Speed;
			}
			
		}
		
		public function Update():void
		{
			this.x += VX;
			this.y += VY;
		}
		
		public function setWallColision():void
		{
			if (this.x < 0)
			{
				this.x = 0;
				VX *= -1;
				enemyPoints++;
			}
			
			
				
			else if (this.x > stage.stageWidth)
			{
				this.x = stage.stageWidth - this.width;
				VX *= -1;
				heroPoints++;
			}
			if (this.y < 0)
			{
				this.y = 0;
				VY *= -1;
			}
				
			else if(this.y > stage.stageHeight - this.height)
			{
				this.y = stage.stageHeight - this.height;
				VY *= -1;
			}
			
		}
		
		public function setPaddleCollision(paddle:Paddle):void
		{
			if(paddle.hitTestObject(this))
			{
				VX *= -1;
			}
		}
		
		public function setEnemyPoints():int
		{
			return enemyPoints;
		}
		
		public function setHeropoints():int
		{
			return heroPoints;
		}
	}
}

I know it is much information at once, but I don’t think it is so hard to understand because this class holds the graphic representation of our ball, and all the logical stuff that our object needs to know. Don’t get freaked out, all the methods that are unclear for you right now, you will understand them when we reach the main class.
Let’s talk about this class and all the methods that are inside it:

First we have 6 variables, that are only about our ball, like: radius, alpha, color , speed, VX, VY. Then we have 2 variables that are not about our ball, but are related to ball position : enemyPoints, heroPoints.

Next it is a simple constructor, and of course a Draw(); method again, because we need to give shape to our object. SetBallStartPosition(); takes the object and places it at the center of the screen.

Now, we have a getRandom(); method and a MoveBall(); method. As you may assume the first method < getRandom(); > , returns us a random number from an interval. This number will direct, our ball movement, as you can see in the next method < MoveBall(); >. Update(); function moves the ball on the screen.

setWallColision(); and setPaddleCollision();, these two methods, take care that when the ball touches the paddle or the edge of the screen, it goes in the opposite direction.

The last two functions, return the number of hero points, and the number of the enemy points.

Create the hero

Hero.as

package hc
{
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;

	public class Hero extends Paddle
	{
		private var UpKeyDown:Boolean;
		private var DownKeyDown:Boolean;
		
		private var Speed:Number = 0.7;
		private var VY:Number = 0;
		private var Friction:Number = 0.1;
		private var MaxSpeed:Number = 3.5;
		
		public function Hero(width:uint, height:uint, color:uint, alpha:Number)
		{
			super(width, height, color, alpha);
		}
		
		public function SetHeroStartPosition():void
		{
			this.x = 0;
			this.y = stage.stageHeight * .5 - (height * .5);
		}
		
		public function Update():void
		{
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
			movePaddle();
		}
		
		
		private function onKeyDown(e:KeyboardEvent):void 
		{
			if (e.keyCode == Keyboard.UP) 
			{
				UpKeyDown = true;
			}
			else if (e.keyCode == Keyboard.DOWN)
			{
				DownKeyDown = true;
			}
		}
		
		private function onKeyUp(e:KeyboardEvent):void 
		{
			if (e.keyCode == Keyboard.UP) 
			{
				UpKeyDown = false;
			}
			else if (e.keyCode == Keyboard.DOWN)
			{
				DownKeyDown = false;
			}
		}
		
		public function movePaddle():void
		{
			if (UpKeyDown)
			{
				VY -= Speed
			}
			else if (DownKeyDown)
			{
				VY += Speed;
			}
			else
				VY *= Friction;
			
			this.y += VY;
			
			if (VY > MaxSpeed)
			{
				VY = MaxSpeed;
			}
				
			else if (VY < - MaxSpeed)
			{
				VY = - MaxSpeed;
			}
			
		}
		
		public function SetLimits():void
		{
			if(this.y < 0)
			{
				this.y = 0;
			}
			if(this.y > stage.stageHeight - this.height)
			{
				this.y = stage.stageHeight - this.height;
				
			}
		}
	}
}

So, this is the Hero class.
SetHeroStartPosition() – place the object in the area where it should be.
Update() – Calls three methods : onKeyDown, onKeyUp and movePaddle. The first and the second method, check if one of the UP and DOWN buttons are pressed. And the movePaddle() just move our object on the screen.
SetLimits() – don’t allow the object to exceed the screen height.

Create the enemy

Enemy.as

package hc
{
	public class Enemy extends Paddle
	{
		private var Speed:Number = 0.7;
		private var VY:Number = 0;
		private var Friction:Number = 0.1;
		private var MaxSpeed:Number = 3.5;
		
		public function Enemy(width:uint, height:uint, color:uint, alpha:Number)
		{
			super(width, height, color, alpha);
		}
		
		public function SetEnemyStartPosition():void
		{
			this.x = stage.stageWidth - this.width;
			this.y = stage.stageHeight * .5 - (this.height * .5);
		}
		
		public function Update(ball:Ball):void
		{
			if(ball.x > stage.stageWidth * 0.3)
			{
				if(ball.y > this.y)
				{
					VY += Speed;
				}
				if(ball.y < this.y)
				{
					VY -= Speed;
				}
				this.y += VY;
				
				if (VY > MaxSpeed)
				{
					VY = MaxSpeed;
				}
					
				else if (VY < - MaxSpeed)
				{
					VY = - MaxSpeed;
				}
			}
			
			
		}
		
		public function SetLimits():void
		{
			if(this.y > stage.stageHeight - this.height)
			{
				this.y = stage.stageHeight - this.height;
			}
			
			if(this.y < 0)
			{
				this.y = 0;
			}
		}
	}
}

Again the first method that we meet is SetEnemyStartPosition, I think it is clear what this function does. Next we have the Update method; here is where the logical stuff about how our enemy should move on the screen, happen . And of course the final method is SetLimits, as I said before, this function don’t allow the object to exceed the screen height.

Game Screen

GameScreen.as

package hc
{
	import flash.display.Sprite;
	import flash.text.TextField;

	public class GameScreen extends Sprite
	{
		
		public function showFillet(fillet:Sprite,_x:int,_y:int,_width:int,_height:int):void
		{
			with(fillet.graphics)
			{
				beginFill(0xffffff, 1);
				drawRect(_x,_y, _width, _height);
				endFill();
			}
		}
		
		public function showScore(fillet:Sprite, heroTextField:TextField, enemyTextField:TextField, 
								  heroPoints:int, enemyPoints:int ):void
		{
			heroTextField.width = 20;
			heroTextField.x = 200;
			heroTextField.y = 10;
			heroTextField.text = heroPoints.toString();
			heroTextField.selectable = false;
			
			enemyTextField.width = 20;
			enemyTextField.x = 290;
			enemyTextField.y = 10;
			enemyTextField.text = enemyPoints.toString();
			enemyTextField.selectable = false;
			
		}
	}
}

In this class, I’ve created only graphical elements that are not moving, like the score and the fillet. I think this is the easiest class to understand, and because of that, I will not stay longer to explain here, because this contains only graphics elements and some attributes.

Main Class

PongGame.as

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.text.TextField;
	
	import hc.Ball;
	import hc.Enemy;
	import hc.GameScreen;
	import hc.Hero;
	import hc.Paddle;
	
	[SWF(width="500", height="350", frameRate="60", backgroundColor="#C0C0C0")]
	
	public class PongGame extends Sprite
	{	
		private var hero:Hero =  new Hero(15,80,0x3090C7,1);
		private var enemy:Enemy = new Enemy(15,80,0x0000CC,1);
		private var ball:Ball = new Ball(5,1,0xffffff);
		
		private var heroPoints:int = 0;
		private var enemyPoints:int = 0;
		
		private var gameScreen:GameScreen = new GameScreen();
		private var fillet:Sprite =  new Sprite();
		private var heroTextField:TextField = new TextField();
		private var enemyTextField:TextField = new TextField();
		
		public function PongGame()
		{
			LoadContent();
			stage.addEventListener(Event.ENTER_FRAME, Update);
		}
		
		private function LoadContent():void
		{
			hero.Draw();
			addChild(hero);
			
			enemy.Draw();
			addChild(enemy);
			
			ball.Draw();
			addChild(ball);
			
			gameScreen.showFillet(fillet, stage.stageWidth * 0.5, 0, 1,stage.stageHeight);
			addChild(fillet);
			
			addChild(heroTextField);
			addChild(enemyTextField);
			
			StartGame();
		}
		
		private function StartGame():void
		{
			hero.SetHeroStartPosition();
			
			enemy.SetEnemyStartPosition();
			
			ball.SetBallStartPosition();
			ball.MoveBall();
		}
		
		private function Update(e:Event):void
		{
			hero.Update();
			hero.SetLimits();
			
			ball.Update();
			ball.setWallColision();
			ball.setPaddleCollision(hero);
			ball.setPaddleCollision(enemy);
			
			enemy.Update(ball);
			enemy.SetLimits();
			
			
			UpdateScore();
			
			gameScreen.showScore(fillet, heroTextField, enemyTextField, heroPoints,enemyPoints);
		}
		
		private function UpdateScore():void
		{
			enemyPoints = ball.setEnemyPoints();
			heroPoints = ball.setHeropoints();
		}
		
	}
}

Here we are at the end of the tutorial, this is the final class and the most important one, because here are put together all the methods and logical stuff that we created so far.

As you can see the first three variables are: hero, enemy and ball; these are our most important objects. Then we have two variables for hero points and for enemy points and of course the last four variables are describing the game graphic that is not moving.

In the constructor we have two methods : LoadContent and an enter frame function called Update.

In the LoadContent (the name says it all) , we loaded all the graphic elements that we have( hero, enemy, ball, aso. ). I do not know if you have noticed, but the LoadContent function calls another function named StartGame. This new method place the objects on the screen.

Now we are at the most important function of the game, I named it Update. Why is it the most important function of the game?. Because it takes care about all the events that are happening. It knows what to do in every situation, of course if the developer takes care to cover all the possibilities.
As you can see, inside of this method are called some other methods that I spoke about earlier.

And the final method is UpdateScore, this method counts the hero points and the enemy points.

So, this was my tutorial about How to make a simple AS 3.0 Pong Game . I hope you have understood all the things that I tried to explain to you. I wish this tutorial will be helpful for many of you out there.
Cya next time.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

WordPress SEO