Beat-em up fighting tutorial (updated) Page 5/5 Previous page 
[ January 21, 2007 ] Kris Foxton
A tutorial that shows how organize graphics and sprites in a fighting game, how to implement the controls and manage the various moves.

Making a Beat-Em-Up Fighting Game in Flash: Part FIVE

In this chapter we will with the implementation of enemies and code how to spawn, initialise, and kill them.

Firsly, let's get one of those nasty melting zombies from the game in there. Here's the png file you'll need.

zombie-gif

Now you have two options.

1) Copy the steps you used to make Rick, except this time replace the images of him with their appropriate zombie match. By right-clicking on the rick_mc file in the libary and choosing Duplicate, you can create an identical mc set-up as Rick's. Be sure to name the mc "zombie", and also set up the linkage name as the same -"zombie". Inside that main mc, you need two place your two new animation instances on two frames with stop() commands in them. Name the first frame (of the zombie walking) "walk" and the second frame (zombie getting splatted) as "dead".

2) Take the "Here's one we made earlier" approach and download my FLA at the bottom. I'll forgive you for taking the easy route now that you've already spent the time creating Rick in the earlier articles.

Finished result should look something like this.

zombie1

What we're going to work on next, is having the zombie walk towards you and become a punching bag for Rick to splat.

Double click into the zombie mc and then also double click into the hit animation (the mc of the zombie dying). At the end of the frames, click F5 to make yourself an empty frame. Next open up the AS script for that frame and type:

removeMovieClip(_parent);

Don't worry, I'll be explaining what it does later. By the way though, we use 'parent' here because the clip is within another mc, and what we want to do is not to remove not just the current mc (_root.zombie.hit), but the mc structure contained in the above level (_root.zombie). The one it is nested within.

Well dudes, this is where games begin to get trickier and trickier. In order to have real control over our movieclips, we can't go around putting objects on the actual Stage all the time, or how else are you going to make baddies reappear after you've destroyed them?We need to develop routines for calling the movie clips dynamically using ActionScript, and doing all the handling for them within tidy little functions. This is done by using attachmovie. As you might or might not know, all Flash is, is movies. Even the stage is an mc in itself, titled level0. Put this code at the very top of your AS script.

_root.attachMovie("zombie", "brownzombie", 9, {_x:100, _y:100});

If you run it, and your linkage is correct (zombie), you should see a little zombie appear on top of Rick. What you actually did with that line of code is you called an mc called zombie onto the stage timeline (level0 or _root), and you named it brownzombie. You gave it a depth of 9 and the x, and y co-ordinates of 100, 100. Now, if you wanted to alter it in any way, you would need to reference the new instance name (in this case 'brownzombie'). Try typing these lines under for example:

brownzombie._x=200;
brownzombie._y=200;
brownzombie._rotation=45;
brownzombie._alpha=50;

Try another experiment. Add this line:

brownzombie.gotoAndStop("dead"); 

If everything ran smoothly you should have seen the zombie splatter and then disappear. He disappeared because of the removeMovieClip line, which detached the movie from the Stage. In other words, Hasta la vista 'brownzombie'.

With me still? If not, go have a beer, come back and reread.

Okay, go ahead and delete all of that stuff, we don't need it. So lets create a function that will attach a zombie to the stage, give it some initial variables like co-ordinates and the direction it's facing, and then point it to a function that takes care of it's AI. One last necessary step is to have somewhere to store that zombie. An array. The array will act as a container for all the movieclips of the monsters in our world.

MonstersInScene = new Array();
tag=0;

This next function you can place anywhere on the script. Keep related functions together though, if you can.

SpawnEnemy = function () 
{
	//INITIALISE VARS
	
	//attachedObj = _root.attachMovie("zombie", "brownzombie"+tag, 9, {_x:600, _y:205});
	
	attachedObj.health = 100;
	attachedObj.speed=5;
	attachedObj.hit=false;
	attachedObj.alive = true;
	attachedObj.gotoFunction = AIZombie;
		   
	MonstersInScene.push(attachedObj);
	
	// MonstersInScene
	tag++; 	
}

Breakdown: if you assing an attachMovie to a variable (attachedObj or any name you like) that variable then can be used to control the instance you've just spawned. So attachedObj._x is now the same as brownzombie._x. It's a timesaver. We add +tag to the reference name because we need to have unique names for every zombie. So the first zombie is now brownzombie1. The next zombie will be brownzombie2, the third brownzombie3 etc. We also need to set the depth uniquely. Before it was 9, but if we have every zombie at depth 9, then when two are on the same screen at the same time, weird shit happen. So we set the depth at 'tag', which changed for every spawned beast.
Finally, we push the mc into the next available slot in the array. So our array will become something like MonstersInScene[brownzombie1,brownzombie2,etc].

Now we can control brownzombie1, by doing things like

MonstersInScene[0]._alpha=0;
MonstersInScene[1]._rotation=22;

Again, big timesaver.
Now that we've created a function to initialise the zombie, we can call it at any point by calling SpawnEnemy() anywhere. HOWEVER, this will do naught but put a little running freaky dude on your screen at co-ords 600,205 (which are off the screen BTW). Nope, we need to give the dude a brain. We need some artificial intelligence.

Put this function below the last one.

function displayZombie()
{
	if(this.alive)
	{
		this.gotoAndStop("walk");
		
		// YOUR FIRST AI
		
		if(rick_mc._x<=this._x-20)
		{
			this._xscale = 100;
			this._x-=this.speed;
		}
		else if(rick_mc._x>=this._x+20)
		{
			this._x+=this.speed;
			this._xscale = -100;
		}
		
		//We have to add a small offset of + and - 20
		//to stop the zombie from 'flickering' when he's close.
		//Remove the numbers - you'll see what I mean
	}
	else
	{
		this.gotoAndStop("dead");
		//Activates the dying animation, which automatically removes this movie clip/sprite
		//when it reaches the final frame
	}
}

I think that function is preeeetty self-explanatory. If Rick is far from the zombie, the zombie moves closer. If the zombie is close enough, he stops. That's it. He's dumber than Frankenstein at this point, and can't even hurt you.

zombie3

Want to see him in action? Of course you do. Stick this in your main code loop, within the onEnterFrame=function section.

MonstersInScene[tag-1].gotoFunction();

Now the little bastard will chase you all over the place like you've been having it off with his daughter.

Next up is the fun. Let's make it so that Rick can splat not just one, but multiple freaks one-after-the-other using hitTest for collision detection.
All we need is one final function. A function that simultaneously:

a) checks if rick is attacking, if so, then checks for a hit test between the box shape of rick and the zombie, and sets the zombies alive flag to false if so.

AND

b) checks if there are zombies in existence and if not, spawns one.

function RenderEnemy() 
{
	for (counter=0;counter < MonstersInScene.length;counter++)	
	{
		MonstersInScene[counter].gotoFunction();
		
		if(rick_mc.attack)
		{	
			if(rick_mc.hitTest(MonstersInScene[counter]))
				MonstersInScene[counter].alive=false;
		}
		
		if(MonstersInScene[counter]._x==null)
		{
			MonstersInScene.splice(counter,1);
			SpawnEnemy();		
		}		
	}
}

The last piece of coding you need to do now is to swap:

MonstersInScene[tag-1].gotoFunction();

in your main onEnterFrame loop, with this one:

RenderEnemy();

Go ahead and splat those mofo's till you're happier than Frodo after saving Middle-Earth.

If you notice, when Rick is attacking, he can basically destroy the zombie even when his feet or hands are nowhere near the thing. In the future parts of this tutorial we're going to look into ways to make the detection more accurate, add sound, and create enemies that take damage and more than a single hit to kill.

DOWNLOAD THE FLA

Questions/advice/tutorial errors: email to youngdude77@hotmail.com

 
 
Name: Kris Foxton
Location: Fukuoka, Japan
Age: 28
Flash experience: 1 year. A keen-to-learn newb.
Job: Famous nobody
Website: http://ydjapan.blogspot.com/
 
 
| Homepage | News | Games | Articles | Multiplayer Central | Reviews | Spotlight | Forums | Info | Links | Contact us | Advertise | Credits |

| www.smartfoxserver.com | www.gotoandplay.biz | www.openspace-engine.com |

gotoAndPlay() v 3.0.0 -- (c)2003-2008 gotoAndPlay() Team -- P.IVA 03121770048