Welcome Guest | Signup | Login


Best Flash Components | Flash Gallery | Flash Audio & Video | Flash Menus | User Interface | Website Templates

Tutorials

 

Tutorials >> Pong
Posted by fflash

A full version of the souce code created in this part in also available. In this part of the project, you will learn:

- Monitoring keyboard events in AS3

- More drawing functions

- Controlled responses to keyboard events.


Here is a live example of what we will create.

Over the course of the series you will make the game below:

obrazek

Okay, let's get started. The first thing to do is to create a new project with one .fla and an ActionScirpt File. Save the ActionScript file as Game.as. Then set the document class of the fla to "Game". Then set the Frame Rate of the .fla to about 40. Now, finally, we can crack on with code. First comes the package declaration and then the imports; today we will be using Movie Clips, Events, and a new one, the "Keyboard" class. This Keyboard class allows us to utilise keyboard events, the focus of today's tutorial.

Next come the definition of a Movie Clip, which will hold the player. Then we move onto the constuctor function. This is the first block of our code.
Code: Select allpackage {
import flash.display.MovieClip;
import flash.events.*;
import flash.ui.Keyboard;
public class Game extends MovieClip {
public var playerone:MovieClip = new MovieClip;
public function Game() {
Apologies for ripping through the code like this, but it really is a neccesity, as they is quite a lot of code to get through. The next line, I think, requires a small description of its very own. For keyboard events to work the focus has to be on the stage. This line ensures that this is the case.
Code: Select allstage.focus = this;
After that though, the next few lines we have have seen before, just drawing in the player.
Code: Select allplayerone.graphics.beginFill(0xffffff);
playerone.graphics.drawRect(0,0,20,100);
playerone.x = 10;
playerone.y = 140;
addChild(playerone);
You may question why the rectangle wasn't just drawn straight to (10,140). Well, this is because if we drew it to, say, (100, 100) then that point would become the player's point (0,0). Thus if we had wanted to mov ethe player to (0,0) on the stage, we would have had to set the x and y of the player to (-100, -100). To remove this potential complication we draw it at (0,0) and move it.
Code: Select allstage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyboardDown);
}
public function onKeyboardDown(event:KeyboardEvent):void {
The code above sets the event handler for keys being pressed (you should, perhap, not that line down); and so every time one is pressed a function will run. This function is called onKeyboardDown. The contents of which are such:
Code: Select allif (event.keyCode == Keyboard.UP) {
if (playerone.y > 0) {
playerone.y -= 5;
}
} else if (event.keyCode == Keyboard.DOWN) {
if (playerone.y < 300) {
playerone.y +=5;
}
}
}//End function
}//End class
}//End package
Which means this:

If the key that has just been pressed is the 'up' key
and we are not touching the top or above
move up 5 pixels

Instead if the key that has just been pressed is the 'down' key
and we are not touching the bottom or below
move down 5 pixels


It is, of course, CTRL/Command and ENTER to view our work, once you have saved the .as file

So what exactly have we made?

Well, today, we have made a white rectangle can move up and down, but only to the edge of the screen. Next time we will add in the ball (quite a complex thing). That will soon exist.

PART 2

A full version of the souce code created in this part in also available. In this part of the project, you will learn:

- Apply math(s) (which I'm not going to explain) in AS3

- Bouncing effect at top and bottom of screen

- Applying hitTestObject function.


Here is a live example of what we will create.

Over the course of the series you will make the game below:

obrazek

Okay, let's get started. Today we will be creating the ball. First we need to add a load of variables and a load of objects. The first is the ball Movie Clip (pretty obvious one, that one). The rest concern the angle at which the ball rebounds off of the paddle, and its speed afterwards. The idea is something like this diagram shows, if you can work out what exactly it does show:

obrazek

Okay then. Here are all of those aforementiong variables, which you need to paste underneath the var playerone:MovieClip line:
Code: Select allpublic var ball:MovieClip = new MovieClip;
public var xspeed:Number = -0.5;
public var yspeed:Number = 0;
public var udist:Number = 0;
public var ufraction:Number = 0;
public var edist:Number = 0;
public var efraction:Number = 0;
public var fullspeed:Number = 10;
public var maxspeed:Number = 5;
You don't really need to understand all of those, as this isn't a maths lesson, but the two prefixed with "u" refer to "you" so we will be using them today, and not the ones prefixed with "e" ("enemy"). In terms of achieving our aim of creating the ball, we first need to draw in the ball (the only line there you need to understand), so in the Game() function, under the playerone.y line add:
Code: Select allplayerone.graphics.endFill();//If you haven't already got this line, I forgot it last time
ball.graphics.beginFill(0xffffff);
ball.graphics.drawCircle(270,190,20);
ball.graphics.endFill();
ball.addEventListener(Event.ENTER_FRAME,ballmovement);
addChild(ball);
So, what does that lot do? Well, we draw in the ball (for basic information on that, see a previous tutorial on drawing), and then give it an event Listener for the enter_frame event, like we did in a previous tutorial also. The we add the ball to the Display List (i.e. display it), which we also have an old tutorial about. Now we've got that sorted, we need to write in the function that gets done each frame, called ballmovement:
Code: Select allpublic function ballmovement(e:Event):void {

if (xspeed < maxspeed &amp;&amp; xspeed >= 0) {
xspeed += 0.05;
}
if (xspeed > -maxspeed &amp;&amp; xspeed < 0) {
xspeed -= 0.05;
}

ball.x += xspeed;
ball.y += yspeed;
The first two bits of that accelerate the ball along the x-axis, which has the effect of accelerating it slightly overall so rallies get faster over time, and stopping the ball going at an absurd angle and instead levelling out a bit. The third bit moves the ball accordingly, to the preset xspeed and yspeed variables. The rest of this function, thankfully also the rest of the source code we need to add, is more boring.
Code: Select allif (ball.y>=((stage.stageHeight/2)-10)&amp;&amp;yspeed>0) {
//If hitting bottom
yspeed = -yspeed;//Go other direction
}
if (ball.y<=-((stage.stageHeight/2)-30)&amp;&amp;yspeed<0) {
//If hitting top
yspeed = -yspeed;//Go other direction
}

if (ball.hitTestObject(playerone)) {//if ball hits player paddle
udist=(playerone.y) - (ball.y + 5);
//Calculate the xspeed and yspeed needed for correct angle and set them to that value.
if (udist!=0) {
ufraction=udist/(playerone.height/2);
yspeed=-((1-Math.abs(ufraction))*fullspeed);
var oldxspeed = xspeed;
xspeed=ufraction*fullspeed;
if (xspeed < oldxspeed) {
xspeed = oldxspeed;
yspeed *= (oldxspeed / xspeed);
}
} else if (udist==0) {
xspeed=-fullspeed;
}

//
if (xspeed<0) {
xspeed=-xspeed;//Make sure we are going in the right direction...
}
if (xspeed > maxspeed) {
xspeed = maxspeed;//...but not too fast
}
}//End hittest
}//End function
The comments in that tell you roughly what each bit does. Perhaps if you're decent at maths you will be able to fully understand, I can't say I do enough to be able to explain it in exact terms to you, but it should work. You might be able to pick out in that the line beginning "if (ball.hittTestObject". If you haven't already read it, we have a tutorial about the hitTestObject() function. All that code is long, I accept, but hey, it makes the ball work and that's all I care about.

It is, of course, CTRL/Command and ENTER to view our work, once you have saved the .as file.

So what exactly have we made?

Well, today, we have made a ball, and made it bounce off the top, bottom and our paddle correctly. Next time we will add in the enemy (so we can have a rally).

PART 3

A full version of the souce code created in this part in also available. In this part of the project, you will learn:

- Reversing the math(s) which we did last week for use with the AI as well

- Adding a "brain" for the AI


Here is a live example of what we will create.

Over the course of the series you will make the game below:

obrazek

Okay, let's get started. Today we will be creating the AI - the opposition. First we need to add the Movie Clip object for the AI, next to all the other similar declarations, near the top of the code:
Code: Select allpublic var ai:MovieClip = new MovieClip;
Okay. Now we need to draw in the AI, much as we did with the player Movie Clip. We are also going to add an event listener so the AI is able to respond to events around it. To do this we put these lines in the constructor under the similar lines for the ball and playerone:
Code: Select allai.graphics.beginFill(0xffffff);
ai.graphics.drawRect(520,140,20,100);
ai.graphics.endFill();
ai.addEventListener(Event.ENTER_FRAME,aimovement);
addChild(ai);
The next logical step, therefore, is to add in this Event Listener. What we want to do is this: when the ball is above the opposition, make it move up; when below the opposition, move down. And we can do this, quite simply, like so:
Code: Select allpublic function aimovement(e:Event):void {
if (ball.y>ai.y){
ai.y += 6;
}
if (ball.y<ai.y){
ai.y -= 6;
}
}
Now to move onto what to do if the AI hits the ball. To quote last week's tutorial:

"...the two prefixed with "u" refer to "you" so we will be using them today, and not the ones prefixed with "e" ("enemy")..."

Well today we are going to use these one prefixed with "e". We are, in short, going to do the opposite of what we did last week. To do this, we are going to add in another if statement , this time hittesting the AI MC; like the last, very similar one, anywhere inside the ballmovement function. It looks like this:
Code: Select allif (ball.hitTestObject(ai)) {//if ball hits AI paddle
edist=(ai.y + 5)-(ball.y + 5);
if (edist!=0) {
efraction=edist/(ai.height/2);
yspeed=-((1-Math.abs(efraction))*fullspeed);
xspeed=efraction*fullspeed;

} else {
xspeed=fullspeed;
}
if (xspeed>0) {
xspeed=-xspeed;//Make sure we are going in the right direction...
}
if (xspeed > maxspeed) {
xspeed = maxspeed;//... and not too fast, either
}
}
The comments in that tell you roughly what each bit does. You might want to read the tutorial about the hitTestObject() function if you haven't done so already. All that code is long, I accept, but hey, it makes the ball bounce off the AI and that's all I care about.

It is, of course, CTRL/Command and ENTER to view our work, once you have saved the .as file. You should be able to have a bit of the rally before the ball gets stuck off the screen.

So what exactly have we made?
Well, today, we have made the ball bounce off the AI paddle correctly. Next time we will make the ball return when it goes off the screen and score the game.

PART 4

A full version of the souce code created in this part in also available. In this final part of the project, you will learn:

- How to score a simple game by setting a textbox to a value

- Resetting the game

- Quick function creation


Here is a live example of what we will create.

Over the course of the series you will make the game below:

obrazek

Okay, let's get started. The first thing you need to do is to create a couple of textboxes to hold the scores. You can do this using the "text" tool from the toolbox. Make them dynamic textboxes by using the drop down box in the properties box that will probably say "Static Text" at the moment. You need to set their instance names to scoreText1 (player score) and scoreText2 (enemy score).
For more information about dynamic textboxes and instance names, see a previous tutorial

Good. Once you've done that, you need to add this line of code into the Game() function near the top of our code:
Code: Select allstage.addEventListener(Event.ENTER_FRAME,resetHandler);
This adds a function that checks every frame to see whether either player has scored, and we are calling this function "resetHandler". Do not fear, it's pretty simple to add in a function ( just put this underneath another function/Event Handler:
Code: Select allpublic function resetHandler(e:Event){
if(ball.x < (-270)){
Well, in those two lines we have declared the function and also add in an if statement that ask whether the ball is off the left hand side of the screen which is at 270. You may be wondering why the left hand side of the screen is at -270 and not 0; this is because the ball starts at x=270 which it will call its own (0,0). Thus, x=0 on the stage is at x=-270 for the ball. So, what are we going to do when the ball is off the side of the screen? Give the opposition a point of course:
Code: Select allscoreText2.text = String(Number(scoreText2.text ) + 1)
reset();
}
Here we also call the reset() function as well, and end the if function. The first line of that is slightly more interesting - we set the text of the enemy score textbox we created earlier to what it was before (scoreText2.text) turned into a number (Number()) added one 2 and turned back into a string (String()). We shall be looking in detail at the reset function in a minute. For now, we shall just go on and say what will happen when we score! Oh good:
Code: Select allif(ball.x > (550 - 270)){
scoreText1.text = String(Number(scoreText1.text ) + 1)
reset();
}
}
This is pretty much the same as the last bit, so I won't go through it all again. The extra "}" on the end closes off our resetHandler function, which leaves us with only one thing left to do, and it needs to go directly under the resetHandler function:
Code: Select allfunction reset(){
xspeed = -0.5;
yspeed = 0;
udist = 0;
ufraction = 0;
edist = 0;
efraction = 0;
fullspeed = 10;
maxspeed = 5;
ball.y = 0;
ball.x = 0;
playerone.y = 140;
}
That is, in fact, much easier than it may first appear. All we are doing is resetting all the variable back to the values they were when we started, repositioning the player and moving the ball back to the middle. In record time, we have finished. Yes, give yourself a pat on the back.

It is, of course, CTRL/Command and ENTER to view our work, once you have saved the .as file. Hurrah! It should all work. If it doesn't work for you, a line may have been missed by me (you never know).