How to Make a Rhythm Game in AS2 – Part 4
Part 4: More Programming of the Arrows
Ok, now that we’ve gotten the arrows onto the stage, we can actually make them move up the stage and hitTest them with the receptors. We’re going to do all of this without putting even a line of code in the arrow MovieClips. Let’s take a look back at the code which placed the arrows onto the stage.
function makeLvl():Void{
//code here will create the level
if(sTime < sTempo){
//if the required time hasn't reached the limit
//then update the time
sTime ++;
} else {
//if the time has reached the limit
//then reset the time
sTime = 0;
//and create an corresponding arrow with the
//number within the level array
//if an actual arrow can be made
if(lvlArrayAll[lvlCurrent][sArrow] != 0){
if(lvlArrayAll[lvlCurrent][sArrow] == 1){
//place a left arrow onto the stage
attachMovie('arrowLeft', 'arrow'+sArrow, getNextHighestDepth());
//set the _x value of the arrow so that it is in the
//right place to touch the receptor
_root['arrow'+sArrow]._x = 135;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 2){
//place an up arrow onto the stage
attachMovie('arrowUp', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 205;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 3){
//place a down arrow onto the stage
attachMovie('arrowDown', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 275;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 4){
//place a right arrow onto the stage
attachMovie('arrowRight', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 345;
}
//set the arrow's y coordinate off of the stage
//so that the user can't see it when it appears
_root['arrow'+sArrow]._y = 500;
}
//get the next arrow if it the song isn't finished
if(sArrow < lvlArrayAll[lvlCurrent].length){
sArrow ++;
} else {
//if the song is finished, then reset the game
//of course, we don't have the code for that yet
//so we're just going to go back to the first frame
gotoAndPlay(1);
gameIsOver = true;
//and then delete all of the arrows
for(var i:Number = 0;i
What we're going to do is add enterFrame function to the arrow. If you have no idea how to do this, then I'm happy to tell you that it is actually very simple. Insert this code into the makeLvl() function after we defined the _y value of the MovieClip.
//adding enterFrame events to the arrow
_root['arrow'+sArrow].onEnterFrame = function(){
//making the arrow move up
this._y -= arrowSpeed;
}
Next, we have to give the receptors an instance name. We're going to name it mcReceptor. That's easy to remember, right? Also, we forgot to place some code when creating the arrow. We have to set the arrow's id, which is the actually arrow key that needs to be pressed. Change the following code to the makeLvl function.
if(lvlArrayAll[lvlCurrent][sArrow] == 1){
//place a left arrow onto the stage
attachMovie('arrowLeft', 'arrow'+sArrow, getNextHighestDepth());
//set the _x value of the arrow so that it is in the
//right place to touch the receptor
_root['arrow'+sArrow]._x = 135;
//setting the arrowCode of the arrow
_root['arrow'+sArrow].arrowCode = Key.LEFT;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 2){
//place an up arrow onto the stage
attachMovie('arrowUp', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 205;
_root['arrow'+sArrow].arrowCode = Key.UP;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 3){
//place a down arrow onto the stage
attachMovie('arrowDown', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 275;
_root['arrow'+sArrow].arrowCode = Key.DOWN;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 4){
//place a right arrow onto the stage
attachMovie('arrowRight', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 345;
_root['arrow'+sArrow].arrowCode = Key.RIGHT;
}
Anyway, after doing this, we're going to place the following code into the arrow's onEnterFrame function.
//hitTesting with the receptor
if(this.hitTest(_root.mcReceptor)){
if(Key.isDown(this.arrowCode)){
//checking if the correct key is down
this.removeMovieClip();
}
}
Now, if you test the game now, there's going to be a problem. The game will reset before all of the arrows even reach the receptor. There are two ways that I can think of to fix this. The first option is to count all of the arrow instances on stage and when it's 0, then end the game. The second, which I prefer, is to just add a certain amount of "0"'s to the end of the array each time the game begins. The second option is what I'm going to do. In the beginCode() function, add the following code.
//make the level array longer
lvlArrayAll[lvlCurrent].push(0,0,0,0,0);
Now, the game should be working out pretty well. I'm pretty proud of our progress this lesson, so I'm going to end it now. We've finished the basic gameplay of the game. Next lesson, we will make a menu system where the player can choose which games to play. It'll be great.
Final Code for the Game Frame
stop();
//VARIABLES
//sTime is the current frame that is being played
//Once it reaches sTempo, then it will be reset
//and a note will be created
var sTime:Number = 0;
//sTempo is how many frames it takes before
//a note is created. Because it's 12, and
//the frame rate is 24, it will take a half of a second
//for a note to be made
var sTempo:Number = 12;
//sNote is the current arrow of the level that is created
//0 makes no arrow
//1 makes a left arrow
//2 makes an up arrow
//3 makes a down arrow
//4 makes a right arrow
var sArrow:Number = 0;
//arrowSpeed is how fast the arrow moves up the screen
var arrowSpeed:Number = 10;
//gameIsOver is whether the game's over
var gameIsOver:Boolean = false;
function beginCode():Void{
//Code here will only be run once at the beginning
//of the game
//every frame, run makeLvl()
onEnterFrame = function(){
makeLvl();
}
//make the level array longer
lvlArrayAll[lvlCurrent].push(0,0,0,0,0);
}
function makeLvl():Void{
//code here will create the level
if(sTime < sTempo){
//if the required time hasn't reached the limit
//then update the time
sTime ++;
} else {
//if the time has reached the limit
//then reset the time
sTime = 0;
//and create an corresponding arrow with the
//number within the level array
//if an actual arrow can be made
if(lvlArrayAll[lvlCurrent][sArrow] != 0){
if(lvlArrayAll[lvlCurrent][sArrow] == 1){
//place a left arrow onto the stage
attachMovie('arrowLeft', 'arrow'+sArrow, getNextHighestDepth());
//set the _x value of the arrow so that it is in the
//right place to touch the receptor
_root['arrow'+sArrow]._x = 135;
//setting the arrowCode of the arrow
_root['arrow'+sArrow].arrowCode = Key.LEFT;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 2){
//place an up arrow onto the stage
attachMovie('arrowUp', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 205;
_root['arrow'+sArrow].arrowCode = Key.UP;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 3){
//place a down arrow onto the stage
attachMovie('arrowDown', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 275;
_root['arrow'+sArrow].arrowCode = Key.DOWN;
} else if(lvlArrayAll[lvlCurrent][sArrow] == 4){
//place a right arrow onto the stage
attachMovie('arrowRight', 'arrow'+sArrow, getNextHighestDepth());
_root['arrow'+sArrow]._x = 345;
_root['arrow'+sArrow].arrowCode = Key.RIGHT;
}
//set the arrow's y coordinate off of the stage
//so that the user can't see it when it appears
_root['arrow'+sArrow]._y = 500;
//adding enterFrame events to the arrow
_root['arrow'+sArrow].onEnterFrame = function(){
//making the arrow move up
this._y -= arrowSpeed;
//hitTesting with the receptor
if(this.hitTest(_root.mcReceptor)){
if(Key.isDown(this.arrowCode)){
//checking if the correct key is down
this.removeMovieClip();
}
}
}
}
//get the next arrow if it the song isn't finished
if(sArrow < lvlArrayAll[lvlCurrent].length){
sArrow ++;
} else {
//if the song is finished, then reset the game
//of course, we don't have the code for that yet
//so we're just going to go back to the first frame
gotoAndPlay(1);
gameIsOver = true;
//and then delete all of the arrows
for(var i:Number = 0;i