The Spawn Engine

an educational open source Flash game engine

How to add more class files

With this tutorial I’m going to show how to add more class files to the Spawn Engine. I’m using version 0.1.2 and CS5. We will add this to later versions of TSE but for now it’ll just be a tutorial showing you how to add it yourself and explaining why this is good practice.

Action Script 3 is an object oriented language (OOP). I’m not going into detail on what OOP is since there are plenty of articles out there doing a better job than I’d do. Check out these two!

First the steps, then we’ll discuss what we’ve won.

1) Right click in your library on the enemy movie clip and choose Properties. There is already a Class linked to this movie clip: Enemy. But that class don’t have any file, so we are going to make one now.

2) Click on the pen button “Edit class definition” and CS5 opens a new tab with an as-file for the class Enemy. The class is empty except for the basic structure (package, import, class and constructor). So we are going to move a few things from the engine to this class.

3) Save the file as Enemy.as in the same folder as your other files for this project.

4) Inside the Enemy class add the line

private var speed:int;

private const MIN_SPEED:int = 7;
private const MAX_DIFF_SPEED:int = 6;

This will be the move speed of the enemy movie clip which earlier was found in the engine. We need to remove it from the engine and only have this data inside the Enemy class.

5) Inside the public function Enemy (the constructor) we add the line

speed = MIN_SPEED + Math.random() * MAX_DIFF_SPEED;

We want each new enemy that is spawned to have its own unique speed. In version 0.1.2 all enemies have the same speed 9 set by a constant. What will the speed of these new enemies be?

6) Under the constructor we add a new function getSpeed that should look like

public function getSpeed():int
{
return speed;
}

Why did we do this?

7) There are a few changes that we need to do in SpawnEngine.as now. Find this lines of code and comment it so it looks like this

//private const ENEMY_SPEED:int = 9;

We no longer need this constant since that data is now stored inside each Enemy object.

8) Find this line

enemies[i].y += ENEMY_SPEED;

and rewrite it to

enemies[i].y += enemies[i].getSpeed();

We want to use the new function that returns the variable speed which now is a unique value for each Enemy object.

8) Test your changes! You should be able to see some enemies moving faster than others. If you want to change the minimum and maximum speed of the enemies you’ll need to go the the Enemy class file and change the constants we added in step 4.

What your Enemy.as should look like now

package {
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
private var speed:int;
private const MIN_SPEED:int = 7;
private const MAX_DIFF_SPEED:int = 6;
public function Enemy()
{
// constructor code
speed = MIN_SPEED + Math.random()*MAX_DIFF_SPEED;
}
public function getSpeed():int
{
return speed;
}
}
}

Why did we do this?

This was just one small step in the right direction. We moved one piece of data, speed, from the engine into a separate class file. The engine don’t need to know everything and do everything. With more class files the engine will be shorter and more manageable. We put the functions and the variables where they belong, inside the class of the object. This also allows us to do things that were difficult to do before, like adding a unique speed to each enemy. Or maybe we want to add health to each enemy or some other value inside each enemy. This is much easier to do when the enemy has its own class. To improve the enemy class we could move more functionality to it from the engine. Each enemy can move itself instead of the engine doing the work for example.

Could we have done this differently?

Now we wrote the Enemy class to fit into the engine. I wanted to show this while making very small changes to the engine. We wrote a function getSpeed and we could of course have done that differently. We could have written a function inside the Enemy class where the enemy moves itself instead of a function that sends the speed to the engine so the engine can move the enemy. Had we written this class file at the same time we wrote the engine things would be different from now when we write the class file after the engine. Future versions of the engine will show this.

What’s next?

Now that we have done this small change on enemies you can do this for the pickups and more.

2012/03/07 Posted by | Tutorials | , , , | Leave a comment

Add enemies to the stage in Flash instead of using code

One of the reasons that we call the Spawn Engine just that, is because the Engine spawns enemies and pickups for the player to interact with. There are functions for spawning, moving, collision testing and removing these objects. But lets say you want to add enemies to the stage in Flash instead of using code. How and why would we want that?

One reason could be that you don’t want enemies to just randomly rain down. You want them to come in very specific and different formations at different intervals. Lets say a first wave of five enemies in a formation like a circle. Then a second wave of 10 in the shape of a square, and so on. Of course this is possible to do inside the newEnemy function but this can be tedious and difficult. We have an excellent tool in Flash, why not use it?

Well it is possible to add the enemies to the stage in Flash and design our level this way. Its more WYSIWYG and simple. Once you play test the level it’s easy to make small changes to add or remove enemies or space them out more. It could be a very comfortable way of designing levels. Lets take a look at one way of doing this.

First we need to turn off the random spawning. Go to your startGame function and comment out the call to setNextEnemy.

//setNextEnemy();

Next we need to add our enemies on stage. Make sure you use the top layer and the second key frame called “game”. Add as many or few enemies you want. To first try this method I would only add a few enemies first and later add more. Put them high up on the stage or even above the stage. These enemies will fall down like the spawned enemies did before, once we alter the code.

Also make sure you select all your enemies added to the stage and add these to a new movieclip. Give that movieclip an instance name “enemies_mc”.

Now if you run your game you will have the added enemies just haning there. They wont move and you can’t shoot them. They need to be added to your enemies array in order for the functions in the Engine to be able to interact with them. The function moveEnemies uses the enemies array and so does the function checkBulletEnemyCollissions. We don’t want to rewrite these since they work. We only need to make sure that the enemies inside enemies_mc are added to the enemies array.

Lets do this by going to the startGame function and right at the end of the function, before the closing curly brace, add some lines of code.

for (var i=0; i<enemies_mc.numChildren; i++) {
// what happens inside the loop
}

All we have done is added an empty for loop. We will replace that comment and fill this loop out with more code but I first want to explain what the loop will do. The movieclip enemies_mc is a container that has several movieclips inside it. A container is often refered to as parent and the objects inside are called children. The stage is a parent with the child enemies_mc just as enemies_mc is a parent to the children of type enemy inside it.

We don’t want or need to know how many enemies (children) are inside enemies_mc (the parent) since we can use the numChildren property that tells us the number of children inside the parent. And we can refer to these children and loop through them all one by one.

The idea now is that each child inside enemies_mc will be added to the enemies array. To get a specific child inside the parent we use the function getChildAt() which needs a parameter, a index number pointing to the child we want to get. We write inside our for loop

var mc = genemies.getChildAt(i);

and mc is now a variable which is the child inside enemies_mc. The index i is the variable we have in our for loop meaning that i will start at 0 and go to 1, 2, 3 and so on depending on how many enemy objects are inside the enemies_mc.

Next we want an if statement that checks that the child mc is actually an Enemy object. So we write

if (mc is Enemy) {
// more inside the if statement
}

We want to remove that comment inside the if statement and add the code that actually adds an enemy to the array. And we don’t want to add mc to the enemy array. We want to make a new Enemy object. It gets a bit complicated to have a movieclip inside a movieclip and that child is also in an array that we use for moving and collision detection. No, we much rather want a movieclip right on the stage just like we do in the newEnemy function. There are other ways to solving this but I wanted to choose one that looked like code you’ve seen before, like the newEnemy functions.

Go to the newEnemy function and find the one row that creates a new Enemy variable, the two rows that change the x and y values and the two rows that add that Enemy variable to the stage and to the array. Replace the comment in the if statement above with these five rows of code. Remember to set the x and y values of the new Enemy object equal to the x and y values of mc!

Only one thing left. We have now gone through all the Enemy objects inside enemies_mc and used each of these to create new Enemy objects that have been added to the array and stage. We no longer need enemies_mc and after our for loops closing curly brace we write

removeChild(enemies_mc);

to remove that movieclip. Try your code! Don’t read on just yet. See if you can get the code to work first! 🙂

One problem might be that the new Enemy objects don’t end up exactly where the Enemy objects inside the enemies_mc are placed, even if you wrote e.x = mc.x; This is because mc is inside enemies_mc and it’s x and y values are relative to it’s container and not relative to the stage. For a full explanation of this concept read the excellent article Understanding Flash’s Coordinate Systems by Michael James Williams. The quick and simple answer is that you need to add the x and y values of enemies_mc by writing e.x = mc.x + enemies_mc.x;

My code looks like this. Does yours?

for (var i=0; i<enemies_mc.numChildren; i++) {
var mc = enemies_mc.getChildAt(i);
if (mc is Enemy) {
var e:Enemy = new Enemy;
e.x = mc.x + enemies_mc.x;
e.y = mc.y + enemies_mc.y;
addChild(e);
enemies.push(e);
}
}
removeChild(enemies_mc);

And that is how we can add enemies to the stage in Flash instead of using code. This was just one quick simple way to solve the problem. I’m sure there are several others and if you find one or have any questions or suggestion please comment.

2011/03/15 Posted by | Tutorials | , , , , , , | Leave a comment

Zigzag moving enemies

For this tutorial I’m using version 0.1 and adding zigzag moving enemies. Instead of just having the enemies spawn and move straight down (making them very easy to shoot) we want them to move from side to side. We will not make them move in an actual wave this time, since I don’t want to make this overly complicated math-wise. We will look at that later.

The first thing we will do is add these two variables among our other variables:

private var enemyWaveWidth:int = 30;
private var enemySideSpeed:int = 2;

These two variables tells the engine first how far to the side from the enemies spawn point the enemy will move and then how fast the enemy will move sideways. Experiment with other values.

Next up we need to change the newEnemy function. When we spawn an enemy we need to add a few things. We want a direction on each enemy, either right or left. This should be random so not all enemies move the same. After the lines of code when we create the e and change its x and y we add these lines:

if (Math.random() >= 0.5)
e.sideSpeed = enemySideSpeed;
else
e.sideSpeed = enemySideSpeed * -1;

Now that we have added a direction and speed to the enemy we want to add the boundaries to the left and right so the enemy knows how far to zig and zag. This is why we added the enemyWaveWidth variable. I want the boundaries to vary from enemy to enemy so I’ve added randomness to my code. First the basic version:

e.maxRight = e.x + enemyWaveWidth;
e.maxLeft = e.x – enemyWaveWidth;

This only tells the enemy how far to the left and right to move the enemy. Notice that we use the x- and y-value of the enemy.

If we want some randomness we could instead of writing the two lines of code above use the following:

var randomWaveWidth = (enemyWaveWidth/2) * Math.random() + (enemyWaveWidth/2);
e.maxRight = e.x + randomWaveWidth;
e.maxLeft = e.x – randomWaveWidth;

This will give each enemy a unique wave width. In my code above I use the enemyWaveWidth and my enemies will have a wave width somewhere between half enemyWaveWidth and a full enemyWaveWidth.

Now we are almost done. We only need to fix the moveEnemies function. After we have updated the enemy y-value we need to add a line of code to also change the x-value moving the enemy sideways:

enemies[i].x += enemies[i].sideSpeed;

But this will move the enemy in one direction only. In order to change that we add these lines right after:

if ( enemies[i].x >= enemies[i].maxRight || enemies[i].x <= enemies[i].maxLeft )
enemies[i].sideSpeed *= -1;

If the x-value of the enemy is equal or greater than the enemy max value on either the right or left side we switch the direction of the sideSpeed variable by simply switching sign (negative to positive or the other way around).

And thats it! Now you have zigzag moving enemies. Maybe you didn’t want your enemies to move like this, but instead your pickups. You should be able to fix that using this tutorial.

If you have any suggestions or questions just post a comment!

2011/03/12 Posted by | Tutorials | , | Leave a comment