Tutorial: Make a Rhythm Game in AS2 – Part 4


Written By MrSun at 7:34 am - Monday, August 04th, 2008
Categories: All Tutorials, AS2, Flash, Game Development, Intermediate Tutorials

Table of Contents

Step 4: Programming the Arrows: Part 2

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<sArrow;i++){
				_root['arrow'+i].removeMovieClip();
			}
		}
	}
}

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<sArrow;i++){
				_root['arrow'+i].removeMovieClip();
			}
		}
	}
}
 
beginCode();

The Final Product

Source .fla File

«
»