Tutorial: Create a Brick Breaker Game in AS3 – Part 4
Table of Contents
Step 4: Hit Testing the Bricks
Now that we’ve actually made the bricks, we can now break them with our ball… Anyway, this will be pretty easy to accomplish. But, if you are new to ActionScript 3.0 classes, it’ll be a pretty cool learning experience.
First of all, we’re going to have to create a class file for the bricks. This is easy, just go to File->New and select “ActionScript File”.
Once you’ve created the file, immediately save it as “Brick.as” in the same folder as your .fla file. Then, type the following code in:
//Classes must always be wrapped in a package
package {
//importing display elements that we can use in this class
import flash.display.*;
//importing flash events that we can use (like ENTER_FRAME)
import flash.events.*;
//defining the class name and saying that it
//extends the MovieClip class, meaning that it has the same
//properties as a movieclip
public class Brick extends MovieClip {
//all classes must have a function that runs every time
//an instance of the class is put on stage
public function Brick(){
}
}
}
This is a skeleton of what most ActionScript classes will look like. Although making a class is not necessary for this small game, it will definitely help if you want to expand your game. In order the use the class file in your game, you must import it first, so add this code to the first line of the first frame of your main flash file.
//IMPORTS
import Brick;
We also have to change our previous brick MovieClip, mcBrick, to the class, Brick. This way, all of the code we place into Brick.as will be used in the Brick MovieClip.
So, right click the mcBrick MovieClip in your library and click on linkage. This window will pop up.
Now, find where it says “Class” (it’s going to be highlighted), and set it from “mcBrick” to “Brick”. Now, we have a class. Of course, now we’re going to have to change the makeLvl() function slightly. Now we don’t add “mcBrick” to the stage, but just “Brick”. Just change the following:
var brick:MovieClip = new mcBrick();
to:
var brick:Brick = new Brick();
If you test it out, it will work out exactly the same as before. Now, we add code to “Brick.as”. Let’s go.
We can’t access the root level of the document through the Brick() function, so we’re going to add two listeners to it.
public function Brick(){
//Code that will be run when the brick is added to the stage
addEventListener(Event.ADDED, beginClass);
//Enter frame code
addEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
Next, we define those two functions.
//private function are just functions that you can't access
//from the main timeline, but only within the class itself
private function beginClass(event:Event):void{
}
private function enterFrameEvents(event:Event):void{
}
In order to access the main timeline, we have to type in MovieClip(root). But, this is quite a bit of typing, so we can shorten it by putting it into a variable. Because I’m guessing that most of you have used ActionScript 2.0 before, I’m going to call this variable _root. Because this variable is non-existent in AS3, we can define it as anything. In this case, it actually will be the root of the document. Place this code after the class definition:
public class Brick extends MovieClip {
//The main timeline!
private var _root:MovieClip;
//etc etc etc
Then, we can define the variable within the beginClass() function:
//defining _root as the document root
_root = MovieClip(root);
Now, we can easily access the main timeline within the class. Go on, test it out. Make a trace statement or two.
Now, let’s make some hit testing, eh?
private function enterFrameEvents(event:Event):void{
//hit testing with the ball
if(this.hitTestObject(_root.mcBall)){
//making the ball bounce off vertically
_root.ballYSpeed *= -1;
//destroying this brick
this.parent.removeChild(this);
//stop running this code
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
}
This will make the ball bounce off and destroy the brick every time it touches it. Pretty cool, right? Well, that’s all for this part of the tutorial. Next, we’re going to make more levels and add a win/lose system!
Final Code for Main Flash File Frame 1:
//IMPORTS
import Brick;
//Current level player is on
var currentLvl:int = 1;
//The array code for lvl 1
var lvl1Code:Array = new Array(1,1,1,1,1,1,1);
//The array that contains all of the level codes
var lvlArray:Array = new Array(lvl1Code);
Final Code for Main Flash File Frame 2:
stop();
//VARIABLES
//These variables are needed for moving the ball
var ballXSpeed:Number = 8; //X Speed of the Ball
var ballYSpeed:Number = 8; //Y Speed of the Ball
//First I defined a function where all of
//the code needed to start the game is placed
//This includes listeners, variable definitions, and other stuff
function beginCode():void{
//Adds a listener to the paddle which
//runs a function every time a frame passes
mcPaddle.addEventListener(Event.ENTER_FRAME, movePaddle);
//Adds a listener to the ball which
//runs a function every time a frame passes
mcBall.addEventListener(Event.ENTER_FRAME, moveBall);
//making the level
makeLvl();
}
function movePaddle(event:Event):void{
//The paddle follows the mouse
mcPaddle.x = mouseX - mcPaddle.width / 2;
//Keeping the paddle in the stage
//If the mouse goes off too far to the left
if(mouseX < mcPaddle.width / 2){
//Keep the paddle on stage
mcPaddle.x = 0;
}
//If the mouse goes off too far to the right
if(mouseX > stage.stageWidth - mcPaddle.width / 2){
//Keep the paddle on stage
mcPaddle.x = stage.stageWidth - mcPaddle.width;
}
}
function moveBall(event:Event):void{
//Code for moving ball goes here
mcBall.x += ballXSpeed; //Move the ball horizontally
mcBall.y += ballYSpeed; //Move the ball vertically
//Bouncing the ball off of the walls
if(mcBall.x >= stage.stageWidth-mcBall.width){
//if the ball hits the right side
//of the screen, then bounce off
ballXSpeed *= -1;
}
if(mcBall.x <= 0){
//if the ball hits the left side
//of the screen, then bounce off
ballXSpeed *= -1;
}
if(mcBall.y >= stage.stageHeight-mcBall.height){
//if the ball hits the bottom
//then bounce up
ballYSpeed *= -1;
}
if(mcBall.y <= 0){
//if the ball hits the top
//then bounce down
ballYSpeed *= -1;
}
//Hitting the paddle
if(mcBall.hitTestObject(mcPaddle)){
calcBallAngle();
}
}
function calcBallAngle():void{
//ballPosition is the position of the ball is on the paddle
var ballPosition:Number = mcBall.x - mcPaddle.x;
//hitPercent converts ballPosition into a percent
//All the way to the left is -.5
//All the way to the right is .5
//The center is 0
var hitPercent:Number = (ballPosition / (mcPaddle.width - mcBall.width)) - .5;
//Gets the hitPercent and makes it a larger number so the
//ball actually bounces
ballXSpeed = hitPercent * 10;
//Making the ball bounce back up
ballYSpeed *= -1;
}
function makeLvl():void{ //Places bricks onto Level
//finding the array length of the lvl code
//The index has to be currentLvl-1 because:
//array indexes start on 0 and our lvl starts at 1
//our level will always be 1 higher than the actual index of the array
var arrayLength:int = lvlArray[currentLvl-1].length;
//the current row of bricks we are creating
var brickRow:int = 0;
//Now, creating a loop which places the bricks onto the stage
for(var i:int = 0;i
Final Code for Brick.as
//Classes must always be wrapped in a package
package {
//importing display elements that we can use in this class
import flash.display.*;
import flash.events.*;
//defining the class name and saying that it
//extends the MovieClip class, meaning that it has the same
//properties as a movieclip
public class Brick extends MovieClip {
//The main timeline!
private var _root:MovieClip;
//all classes must have a function that runs every time
//an instance of the class is put on stage
public function Brick(){
//Code that will be run when the brick is added to the stage
addEventListener(Event.ADDED, beginClass);
//Enter frame code
addEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
//private function are just functions that you can't access
//from the main timeline, but only within the class itself
private function beginClass(event:Event):void{
//defining _root as the document root
_root = MovieClip(root);
}
private function enterFrameEvents(event:Event):void{
//hit testing with the ball
if(this.hitTestObject(_root.mcBall)){
//making the ball bounce off vertically
_root.ballYSpeed *= -1;
//destroying this brick
this.parent.removeChild(this);
//stop running this code
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
}
}
}
The Final Product: