Sidescrolling Platformer — Part 12 — Basic Enemies

Welcome back to the side scrolling tutorial series. In this session, we will be adding (very) basic enemies to the game, which you can shoot and destroy with the bullets we created previously. This will create a lot of possibilities for what you can do with your game. In later tutorials we will add a scoring system and more advanced A.I. (artificial intelligence) to the enemies, but for now let’s focus on: creating the Enemy class, adding a few enemies to the game map, and destroying them when they are hit by a bullet.

Creating the Enemy Class

Creating the Enemy class is very similar to creating the Bullet class. If you just read Part 10 and Part 11, most of this step will look the same as when we made the Bullet class and symbol.

First, we need art. We need to create a Movie Clip object to represent the enemy on the stage. Feel free to decorate your enemy however you choose — it could be a random, inanimate object, a crazy monster, or anywhere in between.

…In my case, it falls into the “anywhere in between” category… an ugly cross between a target and an evil villain :P

AS3 Game Tutorial Sidescrolling Platformer Game Enemy and Player

Who wouldn’t want to shoot that thing?

Now select your enemy, and convert it to a Movie Clip symbol. Use the Advanced section to link this object to the “Enemy” class. If you need a refresher on what all the settings are for, refer to how we did it in Part 10. Press the “OK” button twice to create the symbol. You can remove the instance of your enemy from the stage after you finish creating the symbol.

Convert Enemy to symbol

Now we need to create the “Enemy” class for the object. In the File menu, select New… to create a new file. Make sure to select “Actionscript 3.0 Class”, and name it Enemy. Press “OK”. This will generate a basic actionscript file.

Create new actionscript file for Enemy classI’m going to cut right to the chase on this one, because we’ve already seen what went into the Bullet class.

Edit your Enemy.as file until it looks like this:

package
{
	import flash.display.MovieClip;
	import flash.events.Event;

	public class Enemy extends MovieClip
	{
		public function Enemy(xLocation:int, yLocation:int)
		{
			// constructor code
			x = xLocation;
			y = yLocation;

			addEventListener(Event.ENTER_FRAME, loop);
		}

		public function loop(e:Event):void
		{
			//the looping code goes here
		}

		public function removeSelf():void
		{
			trace("remove self");
			removeEventListener(Event.ENTER_FRAME, loop); //stop the loop
			this.parent.removeChild(this); //tell this object's "parent object" to remove this object
		}

	}

}

This gives us a good starting point to work from. When we create the enemy, we will pass in its x and y position so that it spawns in the correct spot. It will constantly have a loop of code running for any specialized behavior, although at the moment it is empty. When we want it to be destroyed, we can call the removeSelf function.

What more is there to do? Actually, nothing else yet. We will add to this later, when we want the enemy to do additional things, but for now this is all we need to get started.

Adding Enemies to the Map

By adding enemies directly to the “map” (the main background object), they will scroll with the rest of the background when the player runs around. Again, this is somewhat similar to adding the bullets, but it varies on two key issues. First off, we aren’t creating a new one each time a button is pressed — instead, we are adding a bunch of them when the game first starts. Second, the enemies aren’t being added next to the player — they are located at different, specific locations throughout the map.

Go back to the code for Frame 1 on the main timeline. Remember how we made a container array for all the bullets? Let’s do the same for the enemies. Somewhere at the top of your program, add:


var enemyList:Array = new Array();

Next, create a new function that will add a bullet to the stage. Notice how closely this mirrors the code for adding a bullet:

function addEnemy(xLocation:int, yLocation:int):void
{
	var enemy:Enemy = new Enemy(xLocation, yLocation);
	back.addChild(enemy);

	enemy.addEventListener(Event.REMOVED, enemyRemoved);
	enemyList.push(enemy);
}

As you can see, this function requires two parameters: an xLocation and a yLocation. For example, we might write “addEnemy(200, 100);”  and the program would create a new instance of the Enemy class, tell it to start at (200, 100), add it to the background, add it to the enemyList array, and start listening for an event that will activate when the enemy is eventually removed. Pretty good for ~8 lines of code!

In order to make that event activate when the enemy is removed, add another function “enemyRemoved” which mirrors the “bulletRemoved” function from last time:

function enemyRemoved(e:Event):void
{
	e.currentTarget.removeEventListener(Event.REMOVED, enemyRemoved); //this just removes the eventListener so we don't get an error
	enemyList.splice(enemyList.indexOf(e.currentTarget), 1); //this removes 1 object from the enemyList, at the index of whatever object caused this function to activate
}

Alright, now we can actually add the enemies using these functions we created. But first, to be organized, lets make a function that gets called when the game is first loaded that will setup the enemies. Right underneath the variables and the eventListeners at the top of your program, add the following:


addEnemiesToLevel1();

function addEnemiesToLevel1():void
{
	addEnemy(player.x - scrollX, player.y - scrollY); //adds an enemy at the player's initial x and y
}

Test out your code, and an enemy should spawn right behind you when you start the game!

Add the enemy to the stage

Hey there, Mr. Enemy! How’s it going?

Awesome… but we don’t want the enemy to spawn right there. Now you just need to pick some combinations of x and y coordinates inside the background object, and create enemies at those points.

An easy way to place the enemies exactly where you want is to double click on the background object to edit it, and then drag instances of the enemy inside the background at your desired locations. Write down the x and y position of each of the enemies you added (you can find it in the Properties panel), and then remember to delete the instances of the Enemy from the background, or you will get an error. Now you can just add a line of code for each enemy in the addEnemiesToLevel1() function, and specify the x and y coordinates you recorded.

Find the x and y location coordinates for each enemy in the background map

For example, I dragged this to into the background, and rounded off its coordinates to (1225, -875)

My final addEnemiesToLevel1 function looks like this:


addEnemiesToLevel1();

function addEnemiesToLevel1():void
{
	addEnemy(620, -115);
	addEnemy(900, -490);
	addEnemy(2005, -115);
	addEnemy(1225, -875);
}

And the resulting project looks like this:

Destroying the Enemies with the Bullets

Time to add some interactivity!  Here’s the logic behind what I’m going to do to destroy the enemy.

  • We have a list of all of the bullets
  • We have a list of all of the enemies
  • If we compare each and every combination of bullets and enemies for a hit-test, we can tell if any enemies have been hit by any bullets
  • We can accomplish this using a for loop
I’m going to jump right into this and show you the code. Yes, it is pretty confusing. But it makes sense if you take it piece by piece.
Add this big conditional to the end of the main game loop. Don’t worry if you don’t know what those strange “for” lines mean:

if (enemyList.length > 0) // if there are any enemies left in the enemyList
{
	for (var i:int = 0; i < enemyList.length; i++) // for each enemy in the enemyList
	{
		if (bulletList.length > 0) // if there are any bullets alive
		{
			for (var j:int = 0; j < bulletList.length; j++) // for each bullet in the bulletList
			{
				if ( enemyList[i].hitTestObject(bulletList[j]) )
				{
					trace("Bullet and Enemy are colliding");
					enemyList[i].removeSelf();
					bulletList[j].removeSelf();
				}

				// enemyList[i] will give you the current enemy
				// bulletList[j] will give you the current bullet
				// this will check all combinations of bullets and enemies
				// and see if any are colliding
			}
		}
	}
}

I tried to explain everything in the comments, but I’ll go over everything again. First off, we check if there are even any enemies left (by checking if there are any objects in the enemyList array), because we don’t want to waste memory checking for collisions, if there aren’t even any enemies around.

Next, we have this possibly-foreign line of code:

for (var i:int = 0; i < enemyList.length; i++)

This is a basic example of the “for” loop, which is a standard part of any programming language, including actionscript. Essentially, “for” allows you to perform some code multiple times. For is especially used with arrays, because it easily lets you do the same section of code 1 time for each object in an array. You can see that there are 3 “sections” in the parentheses part of the for loop, separated by semicolons:

  • The first section, “var i:int = 0″, tells the program where to start counting from. In most cases, you want to start with zero. We create a variable, i, to keep track of this.
  • The second section, “i < enemyList.length”, tells the program when to stop repeating the code. In our case, we start at zero, and continue repeating the code until our variable is not less than the length of our array.
  • The third section, “i++”, tells the program what to do in between each repetition of the code. In our case, we increase i by 1.
The net result of this for loop is that we have a variable i which starts with the value of 0. If the value is less than how many objects are in our array, the code will execute once. Then i will increase by one. If i is still less than the length of the array, the code will execute again. The process keeps repeating until the condition in the second section is not satisfied. There is a ton more information about for loops all over the internet, so if you are interested you should definitely just Google it, and you’ll find a much more in-depth explanation.
Finally in this code chunk, we have the hitTestObject check. We use enemyList[i] to get each enemy from the enemyList array, and we use bulletList[j] to do the same with the bullets. This lets us check each and every combination of bullets and enemies for a match, at which point we call removeSelf() on both of them to destroy them.

Try it out!

Get you source files here.

Comments, questions, and suggestions are appreciated.

Stay tuned for more awesome features! I’ve gotten into a pretty consistent bi-weekly schedule, so definitely check out the site in a couple weeks if you are looking for more interactivity from your enemies.

Advertisements

46 comments on “Sidescrolling Platformer — Part 12 — Basic Enemies

  1. Thanks for this man, your tutorials are the best explained on the net!

  2. Tom says:

    cool will you do patrolling AI and hitTest too?

    • Ben Reynolds says:

      Yeah, I’m going to make the enemy patrol left and right in the next tutorial. I’ll also add the ability for you to get hurt if you bump into the enemy, and maybe even add HP and a health bar (from my Mini Lesson).

  3. Good tut. Will you be doing more on classes? and good structure of games?

  4. Kalejoop says:

    I’ve been following the tutorial up untill i added the following:
    function addEnemiesToLevel1():void{
    addEnemy(-171, 443);
    addEnemy(194, 322);
    }

    And it worked when I tested it. But then suddenly when I tried it again, it had the following errors:

    Scene=Scene 1, layer=background, frame=1, Line 44 ‘{‘ expected

    Scene=Scene 1, layer=background, frame=1, Line 46 Unexpected ‘}’ encountered

    any idea on what went wrong?

    • Ben Reynolds says:

      Did you forget to put a “{” left bracket symbol somewhere? Specifically double check line 44 in your code — that’s what the error message says is causing a problem. Let me know if you’re still having trouble.

      • Kalejoop says:

        function addEnemiesToLevel1():void{

        Is line 44

        • Kalejoop says:

          It’s just so strange, because it worked when I tested it, then I left my computer to do something else and when I came back and tested it again it had the error. I tried changing line 44 and 46 and removed and placed the ‘{‘ multiple times. But nothing seems to work. When I remove the entire function and test it, the error just starts referring to another ‘{‘ in the actionscript.

          • Ben Reynolds says:

            Hmmm, that is strange. Try searching in your code (Edit –> Find) for all the left and right braces. Manually double-check that you aren’t missing any, and there aren’t any extras. It seems like that might be the problem, but it is hard to pinpoint unless you go through all your code.

          • Kalejoop says:

            So I’ve been going through my code and checked it multiple times but it seems to be fine. I tried a few other things and I noticed that whenever I remove all the ‘:void’ the errors go away. But of course, without the ‘:void’, the game still wont work when I test it even though there are no errors occuring.

            Also, I’ve been searching a bit on the internet and noticed a few other guys with the same problem. Their code was fine but they kept getting the ‘{‘ expected error like me.
            I haven’t found anything that resolves the issue. Some people said it had to be something outside of the code, like classes or something else, but I checked the Bullet.as and Enemy.as code and that seemed to be fine as well. Others just said that it might have to do with coding on the timeline in stead of just using classes.

            Any ideas after reading all this?

          • Ben Reynolds says:

            The only thing I can think of would be quit Flash, restart your computer and check it. Then if it still isn’t working, try copy and pasting your code into a blank text document, and then erasing all of the code in your timeline. Try compiling your game to clear everything out, and then copy and paste the code back in. Or try downloading my source files and experiment to see if using my code works, or if your code messes up my project too, etc.

            None of this is really scientific or exact, and I’m not sure any of it will even help. But if nothing in your code is wrong, maybe something strange like this might fix it.

  5. Lil Bro says:

    uh problem i’m a 14 year old male African American so it’s understandable that i’d have small complications my main complication is the aspect of animating the character are there any tutorials you know that can help in my situation? and also i think i’ll wait to continue making my game until you make it to hp and stuff thank you and peace out o( ^v^ )*

  6. Hi again Ben, looking for a bit of help on how to make my enemies colide with my player if i walk into them, was trying to use the hitTestObject method and here is the code i tried with no luck, any ideas where im going wrong?

    if (enemyList.length > 0)
    {
    for (var i:int = 0; i 0)
    {
    for (var j:int = 0; j < bulletList.length; j++)
    {
    if ( enemyList[i].hitTestObject(bulletList[j]) )
    {
    trace("Bullet and Enemy are colliding");
    enemyList[i].removeSelf();
    bulletList[j].removeSelf();
    } else if(enemyList[i].hitTestObject(player)){
    xSpeed *= -0.5;
    }
    }
    }
    }

    }

  7. Alexander Franzén says:

    Hey, could you add a tutorial on how to make the background go back too scrollX = 0 and scrollY = 500 if the player jumps out of the map boundries. Ive tried using this, don’t know how wrong it it:

    if(scrollY == 450){
    scrollX = 0;
    scrollY = 500;
    }

    Help please. (:

  8. Pedro Gomez says:

    Are you going to be able to do the same thing to the player using action script class? Also what if we just want the player to move and not the camera?

    • Ben Reynolds says:

      Yes, you can create a separate Player.as class file if you want, although it would require significant modifications to our existing code in this project. If you want to move the player instead of the camera, then you should update the player.x and player.y positions instead of the scrollX and scrollY variables.

  9. muri says:

    When you remove bullet by bulletList[j].removeSelf(); will not stop eventListener in child, how stop it?
    (if is removed by “distance” from function in Child will stop it).
    I mean that loop in Child.

  10. Jeremie Picaso says:

    hello guys im new here and i have created an as3 game side-scroller but i’m stock w/ just jumping and hopping around my game without an attack.. can you add Mr.Ben Reynolds an sword attack here in your tutorials?

  11. Michael says:

    You didn’t give up on us Ben did you!? Haha.

  12. Cm Guy Ü says:

    Tutorial 13 Please!! :-))

  13. tyler says:

    I have the enemies hurting the player etc. but…

    What is the best way to get the current levels enemies to remove before going to the next ‘level’? (because they will just dupe if you do not kill them).

    Fantastic work by the way this really is some optimal stuff! :)

  14. tyler says:

    I worked it out – thought I’d post my solution here to help others :)

    function nextLevel():void{
    // Remove the enemies from current level
    for (var i:int = 0; i < enemyList.length; i++) { // for each enemy
    enemyList[i].removeSelf(); // remove from current level
    }
    // then just the normal code
    currentLevel++;
    trace("Next Level: " + currentLevel);
    if(currentLevel == 2){
    gotoLevel2();
    addEnemy(620, -115);
    addEnemy(900, -490);
    addEnemy(2005, -115);
    addEnemy(1225, -875);
    }

  15. […] Flash Collision hello can you please help on the tut that im doing… this is the tut site https://as3gametuts.com/2012/06/20/platformer-12/comment-page-1/#comment-800 […]

  16. Dreamonic says:

    You seriously need a new part in this series, it’s the best tutorial on the complete intahnetz!
    You’re insane, man! Massive respect!

  17. Hey these are really great tutorials, one of the best I’ve came across! I was wondering how you would make it so the bullets would be removed if they hit the collision platforms the player aso jumps on. I’ve tried the basic

    if (bulletList.length > 0)
    {

    for (var c:int = 0; c < bulletList.length; c++)
    {

    if ( bulletList[c].hitTestObject(back.collisions) )
    {

    bulletList[c].removeSelf();
    }}}
    but that is removing bullets as soon as they were fired.

    I'm not great with Actionscript and any reply would be greatly appreciated.

  18. this is really good series. I hope you tell something about “moving platform”, “traps” and “spring jumper”.

    anyway, this is for(var i = 0; i < 1000000; i++){trace("really good series");}

  19. MaxC says:

    Very helpful tutorials. I’m made sure that I typed up the code word for word but the error ‘access of undefined property back’ keeps coming up. I’m a beginner at AS3 coding so I’m sure it’s a very simple mistake. Any suggestions would be greatly appreciated. :)

  20. Jonathan Grenier says:

    I made a menu that allow the player to change the controls to any key on the keyboard, if you want I could make a tutorial that shows how to make it, just ask me or contact me at doomer666@hotmail.co.uk

  21. Chris says:

    Hey what’s up? Your tutorial is great btw it helped me a LOT! Now i have a question :) , I have made movieclips INSIDE the Enemy Movieclip so that my enemy moves, looks better. However the collision now between the enemy and the bumps or my player doesn’t work! Can you help me?! I’d really appreciate it! thnx

  22. AKS says:

    Sir Ben I have something bothering my mind.
    Mistake me If I’m wrong,I’m still learning things.
    In http://active.tutsplus.com/tutorials/actionscript/as3-101-loops/ Step 20.
    It says that you need to decrement j in your for loop or it will cause errors.
    For example if the bullet in the 1st index(0) hits the 1st enemy(0) then both of them will be remove.
    And because of that the bullets in the array will shift down by 1.Then the loop will increment j by one missing the 2nd bullet WHICH is in the 1st index(0).

    I’m sorry if the lines above this doesn’t make sesce.The link would explain it better than I did.

  23. JoeFrank says:

    I add moveclips in the enemy moveclip, and now the enemy moves through the bumpers. Also, the player can’t interact with the enemies. Can someone help me figure out how to add animation to the enemies (walking and attacking)?

    • Katie says:

      I have the same Problem here. As soon as I add animation to the enemy it dosn’t react to anything. Don’t really know how to solve that.

      • Katie says:

        Okay, so I’ve found the Solution for Animated Enemies with a little help from my dear programmer colleague. In the addEnemy function replace:

        “enemy.addEventListener(Event.REMOVED,enemyRemoved);”

        with

        “enemy.addEventListener(Event.REMOVED_FROM_STAGE, enemyRemoved);”

        Worked fine for me!

  24. daoinelibra says:

    Hey, this tutorial is awesome. One little snag that’s been stopping me though is this bit:

    var enemy:Enemy = new Enemy(xLocation, yLocation);
    back.addChild(enemy);

    I get a compiler error that tells me that is an incorrect number of arguments, and it expected 0. The game doesn’t run unless I remove the “xLocoation, yLocation” from the parentheses, which kind of defeats the object and no enemies appear.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s