2DGD

Here are some walkthroughs for the more complicated practicals in the 2D Game Design module (Singapore Polytechnic)

Practical 9 - SpaceInvaders Walkthrough
Picking up from where we left off last time - SpaceInvaders game! For those of you still stuck for whatever reason, here is a full textual summary of what you should have in your file. I am not providing the full code here, but this detailed description should help you along in fixing any errors in your file. In this I have described EVERY single step you will need to complete the basic practical.

NOTE: You should be able to understand everything in Practical 9, or else Practical 10 will be tortuous and painful for you to complete. Practical 10 or the Platform Game builds heavily on the things you have done in Practical 9 so make sure you can get your SpaceInvaders Game to work.

SpaceInvaders.as
In your SpaceInvaders.as file, you should have created the following functions inside public class SpaceInvaders extends MovieClip


 * startGame
 * keyDownHandler
 * keyUpHandler
 * update
 * gotHit
 * resetGame
 * gameOver

Also make sure that at the start of the SpaceInvaders class, you have declared all the variables. if you do not declare all the variables and their type, this simple failure to declare the variable in advance will break the code. yes, i'm afraid that's just how it just works. things you would potentially declare (which also give a clue on what values you are going to be creating to score the game's variables later on) would be as follows:


 * number: score, life, lastBulletTime
 * boolean: firing, left, right
 * array: aliensArray, aliensBulletsArray, bulletsArray

public function startGame

 * Use this to define the starting variables of the game (ie: score, life, firing, left, right, lastBulletTime and declaring the new Arrays (aliensArray, aliensBulletArray, and bulletsArray (the player's own bullet).
 * You should also add stage listeners here (namely, to call update, keyDownHandler and keyUpHandler.

private function keyDownHandler
You should know how to add the conditionals here for whichever keyCode is pressed. ''
 * if spacebar is pressed, firing should be set to true
 * if the left key is pressed, left should equal true
 * if the right key is pressed, right should equal ''true

private function keyUpHandler
If the key is up, then the values in keyDownHandler don't apply anymore, so...
 * if spacebar is pressed, firing should be set to false
 * if the left key is pressed, left should equal false
 * if the right key is pressed, right should equal false

private function update

 * LEFT/RIGHT HANDLER - create a conditional to check if right or left is true. check if the x position of mcPlayer exceeds 550 (the size of the stage) while its going right, and check if x position of mcPlayer is going lower than 0 (the starting point of the stage) while its going left.
 * FIRING HANDLER - create a conditional to check if firing is true. create a timer and have it fire once every one second by checking it against lastBulletTime. create new Laser. place your new Laser with a starting point of where mcPlayer's x position is at. push the new Laser into the bulletsArray and addChild it. after this code executes, set firing to false because it should not be fired continously and it should stop firing after the laser is indeed fired.
 * ALIEN HANDLER - create a conditional with a random number generator. if the random number is small enough (randomly so!), then have it create a new Alien. have the new Alien start somewhere on the top left hand side of the stage. push this into aliensArray, and addChild it.
 * ALIEN MOVEMENT HANDLER - create a for loop in which you remove the aliens as they go off screen (when the x position exceeds 550 or the stagewidth). make sure you removeChild it, and also splice the array.
 * ALIEN BULLET HANDLER - create a for loop in which you move ALL the alien bullets on the stage downwards (increase the y position). Why do it all together? Because ANY and All the bullets on the stage have to move downwards all the time anyway.
 * ALIEN BULLET AND MCPLAYER COLLISON HANDLER - create a for loop within another for loop. you will want to loop through ALL the items in bulletsArray, and then check with hitTestObject with ALL the items in aliensArray. if there is a hit, then increase the variable named score by 10 points, removeChild that bullet from bulletArray, and removeChild that alien from aliensArray. Finally, splice both arrays. at the end of this, put a "break", because 1 laser can only hit 1 alien, so you want it to exit the loop once its been hit.
 * PLAYER'S BULLET AND ALIEN COLLISION HANDLER - create a for loop in which you check all the alienBullets in aliensBulletsArray for a hitTestObject with mcPlayer. if there is a hit, call the gotHit function. Remember to put a break in this loop as well.
 * CHECK IF GAME IS OVER - check the value of the variable life. if life is equal to, or less than 0, then run the function gameOver.
 * PRINT SCORE AND LIFE - create two dynamic textfields and assign them a name in flash under properties. print the score or number of lives left into the corresponding text boxes.

private function gotHit

 * when this function is run, subtract 1 from life.
 * if life is less than or equal to 0, run the function gameOver, or else (if there are still remaining lives) then run the function resetGame so that the game can still continue

private function resetGame

 * change both the x and y position of mcPlayer back to the starting position. that's because when you reset the game you want the player to start at its original position once again.
 * for all of the items in the aliensBulletsArray, bulletsArray, and aliensArray, removeChild every single one of them. you can use a for loop to do this.
 * create a brand new empty array for each of the above arrays.

private function gameOver

 * if the game is over, you dont want the game to continue running, and you don't want mcPlayer to still move around when people press the keys. so remove all the eventlisteners you created in the function startGame. this means you should remove the listener that would call update, keyDownHandler, and keyUpHandler.

Practical 10 - Platform Game Walkthrough
Open the flash file and examine the linkages in the library, and refer to your tutorial worksheet which also has more information in it.



PlatformGame.as
In your PlatformGame.as file, you should have created the following functions inside public class PlatformGame extends MovieClip


 * startGame
 * setupGame
 * keyDownHandler
 * keyUpHandler
 * update
 * gotHit
 * resetGame
 * gameOver

at the start of this class, also make sure you declare all the variables and their types. this also gives you a clue on what values you are going to be creating to make the game and store the game's variables later on. the variables would be as such:


 * number: score, life, speedX, speedY
 * boolean: jumping, left, right
 * array: platformsArray, aliensArray

Note that some of these are very similar to Practical 9. Except that instead of having a boolean for firing, you have a boolean for jumping!

public function startGame
this is the "initialising function", similar to the startGame in Practical 9. I might also call this "init". many other programmers might call a starting function by the names "startGame" or init. if you are working on a development project collaboratively, or trying to read someone else's code you can look out for this term when you are trying to understand what is happening in someone else's code.


 * Use this to define the starting variables of the game (ie: score, life, speedX, speedY, jumping, left, right) and declaring the new Arrays (platformsArray and aliensArray).
 * Since this runs when the game starts, you will want to call the function setupGame, which you will create as the function that will check for all the things on the stage, adding them to an array so you can control them with code, and then animating them in code.
 * You should also add your stage listeners here (namely, to call update, keyDownHandler and keyUpHandler)

private function setupGame
here, you should check for the items that are on the stage and then put them into the appropriate arrays. This practical shows you how you can create the items in flash on the stage and then dynamically move them around. This is great for when everything is pretty fixed and if your enemies or aliens are predictable. You can probably mock something up very fast. Try multiplying more aliens

if (object is SomeClass){ trace("This code executes if the object is a SomeClass object")} }
 * create a for loop to check for ALL the children items on the stage. you can return how many items are on the stage with MovieClip(root).numChildren - if the object is Platform, then push this object into platformsArray. if the object is Alien, then push this object into aliensArray. because it is not a variable but an object with a class. you use the operator "is" to check if it is the right class of object.

therefore similarly, you can probably guess what this other snippet might mean: if (object1 is getClass(object2)) { trace("By golly, these two objects are of the same class! And I didn't even have to actually know what object2's actual class was!"); }

private function keyDownHandler
similar to the keyDownHandler in Practical 9 except that you have jumping instead of firing.

private function keyUpHandler
similar to the keyUpHandler in Practical 9 except that you do not change jumping to false when key is up (because you want maximum bounce out of each jump!)

private function update

 * LEFT/RIGHT HANDLER: if right is true, run moveRight on mcPlayer (moveRight is defined in Player.as). if left is true, run moveLeft on mcPlayer (moveLeft is also defined in Player.as)
 * ...otherwise, run stopMoving on mcPlayer (this is defined in Player.as)
 * MCPLAYER JUMPING HANDLER: if jumping and mcPlayer function isInAir is not running, run the function jump in mcPlayer.
 * ALIEN POSITION HANDLER: move all the aliens by running update on all the items in aliensArray
 * PLAYER AND PLATFORM COLLISION HANDLER: check for collision between player and platform when player is falling down. if mcPlayer isFallingDown, run a for loop in which you do a hitTestObject between all the items in platformsArray and mcPlayer.hitBox (hitBox is a thing inside mcPlayer and we are using it as the "hitzone" for mcPlayer). if there is a hit, then run hitFloor on mcPlayer. remember to put a break at the end of this loop because after it hits you want the loop to stop running.
 * PLAYER AND ALIEN COLLISION HANDLER: check for collision between player and aliens. for all of the aliens in the aliensArray, check hitTestObject with mcPlayer.hitBox, and if mcPlayer is falling down still, then consider it as that the player has "jumped" on the alien correctly, so remove that alien and splice that item from the aliensArray, otherwise the player has been hit, and we should run gotHit function instead.

 BONUS: Since many have difficulty with the hitTest, here is sample code for the collision hitTest....:  //Check for collision between player and platforms if (mcPlayer.isFallingDown) {				for (var k = platformsArray.length - 1; k >= 0; k--) {					if (platformsArray[k].hitTestObject(mcPlayer.hitBox)) {						mcPlayer.y = platformsArray[k].y;						mcPlayer.hitFloor(platformsArray[k]); //Exit the loops break; }				}			}			//Check for collision between player and aliens for (var j = aliensArray.length - 1; j >= 0; j--) {				if (aliensArray[j].hitTestObject(mcPlayer.hitBox)) {					if (mcPlayer.isFallingDown) {						//player jumped on it						removeChild(aliensArray[j]); aliensArray.splice(j,1); }					else {						//player is hit gotHit; }				}			} 


 * LIFE CHECKER AND HANDLER: if life is less than 0, run gameOver.
 * PRINT SCORE AND LIFE: create the dynamic textfield to hold the number of lives and score. print the life value in that textfield.

Player.as
In your Player.as file, you should have created the following functions inside public class Player extends MovieClip


 * Player
 * moveRight
 * moveLeft
 * stopMoving
 * jump
 * isInAir
 * isFallingDown
 * hitFloor(platform)
 * update

At the start of the Player class, you should also declare these variables and their type:


 * number: facing, speedX, speedY
 * boolean: playerInAir
 * standingonFloor

public function Player

 * let player drop in by setting the player's speedX and speedY position to 0 initially, and playerInAir to true. this will make it appear to "drop" right into place when the game starts.

public function moveRight

 * increase speedX to a positive value

public function moveLeft

 * decrease speedX to a negative value

public function stopMoving

 * set speedX to zero

public function jump

 * set speedY to negative
 * set playerInAir to true

public function isInAir

 * return this.playerInAir

public function isFallingDown

 * return this.speedY more than 0

public function hitFloor(platform)

 * set playerInAir to false
 * set speedY to 0
 * and set this.standingOnFloor to platform

public function update
 if (this.currentLabel != "right"){ this.gotoAndPlay("right"); } 
 * if speedX is more than 0, and if the x position of the player is less than than 780, then change the facing of the player to face right, increase the x position by the value of speedX. the larger speedX is, the more rapidly the x position will change.
 * else, if speedX is less than 0, and if the x position of the player is more than 20, set the facing of the player to face left, and increase the x position by the value of speedX.
 * else, facing can be set to zero because the player is not moving and it should be facing straight ahead.
 * if playerInAir, add gravity by increasing speedY and then setting mcPlayer to increase at the rate of speedY.
 * check if the player should fall off and at the same time, if standingOnFloor is also not null, check if player has moved off the floor it is standing on.
 * inside your mcPlayer there are a few frameLabels. if facing is right, then go to and play at the label marked "right", if its left, then go to and play at the label marked "left", and then if its idling then go to and play at the label marked "idle". when doing this, you should also make a check to see where the label is at currently before playing it.

BONUS: Since many have difficulty with the hitTest, here is sample code for the collision hitTest....:  //Check for collision between player and platforms if (mcPlayer.isFallingDown) {				for (var k = platformsArray.length - 1; k >= 0; k--) {					if (platformsArray[k].hitTestObject(mcPlayer.hitBox)) {						mcPlayer.y = platformsArray[k].y;						mcPlayer.hitFloor(platformsArray[k]); //Exit the loops break; }				}			}			//Check for collision between player and aliens for (var j = aliensArray.length - 1; j >= 0; j--) {				if (aliensArray[j].hitTestObject(mcPlayer.hitBox)) {					if (mcPlayer.isFallingDown) {						//player jumped on it						removeChild(aliensArray[j]); aliensArray.splice(j,1); }					else {						//player is hit gotHit; }				}			} 

Alien.as
In your Alien.as file, you should have created the following functions inside public class Alien extends MovieClip


 * Alien
 * update

At the start of the Alien class, you should also declare these variables and their type:


 * number: dirX, startingX

use Alien function to set the starting positions, and use update function to make alien shuffle to the left, and then shuffle to the right after it shuffles to the right up to a fixed distance. when you get more comfortable with playing around with it, you can also try different motions for your aliens. or add in random factors to the alien's motion!

this should form a good start for your platform game! now you can try coding up the POWERUP! feature and other extra features that i haven't discussed in this walkthrough.

Practical 11 - Coming Soon
Next.... we make the platform game SCROLL along with the user. LIKE A BOSS.

First, copy over the code you need from your first PlatformGame into this PlatformGame2.

Timeline - Create new and seperate sections for each stage

 * your file will have two sections in it already on the timeline. go and create an additional one called "win"
 * assign unique names to aliens in both stage1 and stage2 (do not just copy over to new stage verbatim)
 * make sure that you use Platform_S2 from library for floating platforms, and Platform2_S2 from library for ground platform
 * name the ground platform instance as "mcPlatform2"
 * drag a new portal over from library and name it "mcPortal2"
 * note that in frame 1 of stage1, it calls the function startGame - in your file you will see there is an additional function called startGame2. when you get to stage2, it should call the startGame2 function.

edit the alien function

 * instead of having the aliens move according to a startingX attribute, make a new attribute called patrolX which is 0 at first.
 * the new logic of the alien is to have it increase and when it exceeds 20 then dirX should be -1 (or vice versa)

edit the update function

 * let's update the scrolling function here as well. the player does not really move, it is the platform that does most of the moving. we are going to create something interconnected with a new function called "shouldMovePlayer"

shouldMovePlayer function
did you notice how in startGame we had these lines? currPortal = mcPortal1; currPlatform = mcPlatform1;

you may be able to guess that its related to the code you need to have in the function shouldMovePlayer. for startGame2 you will need to assign the right values for currPortal and currPlatform.

//Scroll everything if ((currPlatform.x - currPlatform.width/2 -speedX < 0) &&					(currPlatform.x + currPlatform.width/2 -speedX > 800)) {					for (var i = aliensArray.length - 1; i >= 0; i--) {						aliensArray[i].x += -speedX; }					for (var i = platformsArray.length - 1; i >= 0; i--) {							platformsArray[i].x += -speedX; }					currPortal.x += -speedX; return false; }				else return true;

create a new startGame2 function

 * this is for setting up the starting game variables for stage2. remember to change the value for currPortal to the new name for the portal in stage2, which is probably mcPortal2.

update function
In the update function, one of the things you will need to have is the hitTest for the portal and player. You should have named the portals correctly in the different parts of the stage first. Note that we don't use hitTestObject since we want to test for the hitTest between the portal and the player's x and y coordinate. You can do this in different ways but this is one example of how to do it:

//Check for collision between portals and player if (currPortal.hitTestPoint(mcPlayer.x, mcPlayer.y)) {				if (currentLabel == "stage1") gotoAndStop("stage2"); else if (currentLabel == "stage2") {					removeEventListener(Event.ENTER_FRAME, update); gotoAndStop("win"); }			}