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.
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.
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.
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:
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.
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
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.
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.
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.