Sidescrolling Platformer — Part 10 — Shooting

Welcome back to the flash game tutorial: how to make a side scrolling platformer game in actionscript 3. I can’t believe we’re already up to part ten! As you can probably tell from the title, this tutorial part will exclusively feature shooting. Not all platformer games require this feature, but I’ve had a bunch of requests for this tutorial — probably because side scrolling shooters are an amazing game genre (for example, the classic Metroid games). We don’t have anything yet for our bullets to interact with, but don’t worry — next tutorial we will add the enemies. For now, let’s just focus on getting our hero to shoot.

Here is a preliminary demo of what we’ll be creating. Use the space bar to fire.

An External Actionscript File

…I knew this moment would arrive eventually… the moment when — *gasp* — we finally need to use a custom class and an external actionscript file. If you’ve never programmed anything with Object Oriented Programming before, and you’ve never created an external .as file, this might seem intimidating. Or perhaps you have no idea what I’m talking about. No matter where you stand right now, I hope that by the end of this tutorial you will have a solid idea of what external classes are, why we use them, and how to create a Class for the bullets. In future tutorials we will go into more depth on the topic.

Bullets are Different

Think about each of the objects in our game.

  • The player.
  • The background.
  • The Door.
  • The Key.

What do they all have in common? There’s only one of each, which we’ve manually dragged onto the stage every time we’ve wanted to use them.

Now think about how we might create a bullet… hmm… That’s a bit trickier. We can’t really just drag a bunch of bullets onto the stage to use them. We need to frequently add and remove them throughout the game. And on top of that, each bullet needs to act in the same way — we would need to code each individual bullet so that it flies forward in the direction of the player, and so it reacts to interactive objects (like enemies, etc). This is an extremely impractical way to code a shooter game.

What we need, is something more advanced. Something that can add and remove bullets dynamically throughout our game. Something that can preset each bullet with a “template” of code to follow — so that we don’t need to worry about programming the details of every single instance.

What we need, is a Class.

  1. Classes are external actionscript files that we associate with a single symbol from our library. The Bullet symbol that we’ll create will soon be “linked” to the Bullet class. 
  2. A class is a template of code. Whenever we created an instance of an object in the past, it initially did nothing — we needed to add more code on the main timeline to tell it what to do. But when we create an instance of an object which is linked to a class, it will come pre-packaged with a set of instructions.
  3. Classes can be used to give the same behavior to many instances of the same object — for example, we can tell all bullets to travel forward when they are created — or we could tell all “coin” instances to collide with the player, and play a sound when they disappear. We could add hundreds of coins and bullets to the stage, and without writing any extra code, these objects will function perfectly.
  4. We can dynamically add and remove class-based objects from the stage by using the addChild() and removeChild() functions.

Convinced yet?

We don’t need to restructure our entire game — our current objects work fine without any classes. But our bullets are different. Watch and learn — coding with classes is one of the major steps towards becoming an advanced programmer. It is a little more difficult than timeline programming, but it is much more powerful.

Create the Bullet symbol

Before we can code, let’s draw a bullet object that our player can shoot. If I was feeling ambitious, I might redraw the player to be holding some sort of gun, but for now I’m just going to leave my player-graphics as they are, and draw a simple bullet to shoot.

Draw a bullet. I used the Oval Tool, and held down the Shift key to create a circle. Mine is orange with a black outline, just to make it stand out. Feel free to make yours look like anything you want.

Draw the bullet

Next, select the bullet image and convert it into a Movie Clip object, oriented about its center. STOP! Before you hit, OK, like you’re used to doing, we need to do an additional step to set this up for a class.

Convert the Bullet to a Movie Clip symbol

See that little arrow next to Advanced? That’s right, we’re graduating to advanced mode. Congrats. Now click the arrow… and try not to get intimidated by all the options.

Advanced mode control panel for converting the bullet to a movie clip

Before you freak out from an overexposure of advanced-ness, just know that you only need to focus on the middle section.

Annotated advanced options for converting bullet symbol

OK, so now that you know what you need to focus on, you might be wondering what we actually need to do. Basically, all you need to do is check the box next to “Export for ActionScript“, and the rest will automatically fill itself out. This next screenshot should help you out.

Select the Export for Actionscript option on the Bullet symbol advanced options

You can click “OK” now. A notification window will pop up, but you can just hit OK again. This notification is just letting us know that we linked our symbol to the Bullet class, but we haven’t actually created this class yet.

Error notification about class linked with bullet symbol

Now here’s the new part. Delete the bullet from your stage; we don’t need any instances of it. Don’t worry, it’ll still stay in our project’s symbol library. Go to the Library panel, where you can find all of your symbols you have created. You can see that the Bullet is still there. And you can also see that it is linked to a class.

Bullet in library panel is linked to class

Create the External Class

It’s time to create the class. Click on the File menu, and select New… (you can also use the shortcut Command+N). This will bring you to a menu which you can use to create a new file. Instead of creating an entire new project, select ActionScript 3.0 Class. Your menu might look a little different from mine, because I recently upgraded to Flash Professional CS6, but it should be almost the same. Although it isn’t necessary, you can give your class a class name now by typing in Bullet. This will generate a few lines of default code. Click “OK” now.

Create a new actionscript file for the bullet class

You should be taken to a new tab inside flash, that looks like this:

Bullet class external actionscript tab default

Don’t worry if you don’t understand the default code. I’ll explain it line by line.

Line 1 reads: package {

  • “Package” is just a standard keyword that flash uses to locate an external class. You will see it at the top of every single actionscript class you’ll ever read in you life. Sometimes there will be a few extra keywords up there too, which will tell the flash player which folders to look inside to find the saved file. But we are going to save this file in the same folder as the Flash project, so all we need is package.
  • The open bracket is the way we group together code in actionscript. Just like functions are surrounded by brackets, an actionscript file is packaged inside of a pair of brackets.

Line 3 reads: public class Bullet {

  • This defines the name of the class. Anything inside this pair of brackets will be part of the Bullet class.
  • The keyword public is important, and you will see it a lot in classes. Back on the main timeline, everything was able to be read by the main timeline’s “brain”, because they were all in the same file. But the main timeline doesn’t necessarily know about all of the classes, variables, and functions outside of its own actionscript window on frame 1.
  • So we give each class, variable, and function in an external file one of the following keywords:
    • public – This means anyone is able to access it
    • private – This means no one else can access it (besides code within the same class)
    • (There are a couple more keywords, but you won’t need those unless you’re doing something more complicated)

Line 5 reads: public function Bullet () {

  • This is a function, just like the functions we’ve created before. However, it has the public keyword, which means it’s open to public access.
  • This is actually a special function, called the constructor. Because it is named exactly the same name as the class, the flash player knows that it is the constructor. It will automatically activate the code inside the constructor when we first create a Bullet object. It is the code that sets up (or “constructs”) the class.

The rest of the lines just finish adding brackets to close off all of the sections of code. Remember not to forget any brackets, or you’ll get an error!

Before we start editing this, let’s save it in the same folder that we saved the Flash Project. Here’s how I organize my files on my computer: I have one main “Flash” folder on my desktop. Inside this folder, I creature a new folder for every project I start working on. So I have one folder inside of it called “Platformer”, another called “Pong”, etc, etc. Use File –> Save… to save your new class inside your “Platformer” folder (or wherever your project is saved). Make sure to name it Bullet.as — the flash player is very picky about how classes are named. Classes need to be saved with the same exact file name as their class name, otherwise they won’t work. Also, you are supposed to Capitalize the names of you classes, unlike the names of your functions, variables, etc.

Programming the Bullet

Enough talk about classes, let’s actually program the bullet. The best way to learn classes is to see them in action.

What do we want a bullet to do? It isn’t too complicated. Each time we create a bullet, we want to make it face in the direction of the player, and move forward. After a certain amount of time, it should disappear.

Let’s start out by extending another class. When we created a new class, it started out as a completely blank slate. This means that it doesn’t even have the functionality of a basic Movie Clip symbol. Our Bullet is a Movie Clip symbol, so we need this functionality for the class to work behind-the-scenes. We can accomplish this by making the Bullet class extend the Movie Clip class. It’s simple to do. Just add “extends MovieClip” to line 3, before the bracket.

But what’s that strange import statement on line 2? Well, here’s another inconvenient truth about classes — as a way for the Flash player to run faster and more optimized, the classes start out as such a blank slate, that they don’t even have references to many parts of Flash’s as3 library by default, such as the MovieClip class. You need to import references to them. You can import the MovieClip class by importing flash.display.MovieClip.


package {
    import flash.display.MovieClip;
    public class Bullet extends MovieClip {
        public function Bullet() {
            // constructor code
        }

    }
}

Now let’s give our bullet its very own “loop” function.


package {
    import flash.display.MovieClip;
    import flash.events.Event; //add this
    public class Bullet extends MovieClip{
        public function Bullet() {
            // constructor code
            addEventListener(Event.ENTER_FRAME, loop); //add this
        }
        public function loop(e:Event):void { //add this
            //looping code goes here
        }
    }
}

Notice how you should write the addEventListener inside the constructor. This way it’ll be added once, right when the object is first created.

Also notice how we need to import the ability to listen for events, by importing flash.events.Event.

We want the bullet to move at a constant speed, so lets create a variable to hold that value. Notice how it is a private variable, because no one else needs to know what its value is. Also, in the loop function we just created, add a line of code which will add the speed to the x-position each frame.


package {
    import flash.display.MovieClip;
    import flash.events.Event;
    public class Bullet extends MovieClip{
        private var speed:int = 10; //add this
        public function Bullet() {
            // constructor code
            addEventListener(Event.ENTER_FRAME, loop);
        }
        public function loop(e:Event):void {
            //looping code goes here
            x += speed; //add this
        }
    }
}

OK, now here’s a semi-tricky part. We need information about where the bullet should start at, and what direction it should face. We can get this through the constructor, by setting up some variables that we can pass into the class when we create it. Remember how when we use the function “gotoAndStop”, we include a number for which frame we want to stop at? In a similar manner, we can pass in information to a new object of a custom class.

After all is done, your constructor should look like this:

public function Bullet(playerX:int, playerY:int, playerDirection:String) { //notice the variables we pass in
    // constructor code
    if(playerDirection == "left") {
        speed = -10;
        x = playerX - 25;
    } else if(playerDirection == "right") {
        speed = 10;
        x = playerX + 25
    }
    y = playerY - 75;
    addEventListener(Event.ENTER_FRAME, loop);
}

I’m confident you can understand what’s going on in the body of the constructor, but you might be confused about the syntax we use in the header.

public function Bullet(playerX:int, playerY:int, playerDirection:String) {
Each of the 3 variable names, separated by commas, are properties which we are passing into the bullet when we create it. For example, we could create a new bullet object in the main timeline using: var bullet:Bullet = new Bullet(player.x, player.y, “left”);
This would create a customized bullet that would start out at the x and y position defined in the body of the constructor, and it would travel to the left.
It gets easier to understand the more you practice.
That’s actually all you need to do for this class, for the moment. We can add onto it in the next tutorial, to give it more functionality (for example, disappearing after a set amount of time, or colliding). But for now, let’s return to the main timeline and add some code that will create the bullet when we press a keyboard button.

Shooting!!

Wow, this has been a long tutorial. Let’s end it on a strong note, by shooting some bullets! I am going to use the space bar as my shooting button.

An easy way to activate some code once each time a key is pressed, is to call a function inside the keyUpHandler. Each time the player releases the key, the function will be called once, and we will create a new bullet.

At the end of the keyUpHandler function, add:

if(e.keyCode == Keyboard.SPACE){
    fireBullet();
}

We haven’t defined the fireBullet() function yet, so go ahead and create it. This should be all the rest you need to make the program work as intended.

Create a new function:


function fireBullet():void {
    var playerDirection:String;
    if(player.scaleX < 0){
        playerDirection = "left";
    } else if(player.scaleX > 0){
        playerDirection = "right";
    }
    var bullet:Bullet = new Bullet(player.x, player.y, playerDirection);
    stage.addChild(bullet);
}

The first half of this function just creates a new variable playerDirection and sets it to “left” or “right” depending on how the player’s graphics are scaled. The second half of the function is the good stuff we should pay attention to.

Anytime you want to create a new instance of a class you use the format:

var instanceName:ClassName = new ClassName(parameter1, parameter2, etc);

Because we set up our Bullet class with the parameters…

playerX:int, playerY:int, playerDirection:String

…we needed to pass in information to the new Bullet instance with those specified data types…

player.x, player.y, playerDirection

The final thing we did in the fireBullet function, was to use flash’s addChild function to add the bullet instance to the stage. In theory, you could remove it by using stage.removeChild(bullet), but we won’t get to that until next time (there is a trick to making it work correctly).

Testing it Out

Try testing your game! If everything was coded and linked correctly, you should be able to fire bullets using the space bar!

As you can tell, we are far from finished. But this tutorial is closing in on 3000 words, so I’ve got to save some content for Part 11. Right now, the bullets are never actually removed — they fly off of the stage, but they still exist and take up memory, slowing down our game. Also, the bullet speed should be affected by the scrolling of the background, because right now it doesn’t look realistic. They even travel up and down with the player when he jumps, instead of staying in the same y position that they are created. I’ll try to cover those features in the next tutorial, as well as introducing enemies to the game.

And here are the source files. (That’s right, now we have multiple source files. I also included a PDF version of the code from the main timeline)

As always, questions, comments, and suggestions are appreciated, and I try to respond to them all :-)

Cheers!

Advertisements

50 comments on “Sidescrolling Platformer — Part 10 — Shooting

  1. Bob says:

    Great tutorial as always ben! thanks for this :)

  2. AS3NOOB says:

    Nice tutorial, I think i see where this is going. Hopefully part 11 will come out soon.

  3. Logan says:

    Is it possible to keep the bullets on the same trajectory when they are fired instead of going up when you jump?

    Trying to figure this out and your tutorials are amazing! they really are helping me out with my Introductory classes for Flash

    • Ben Reynolds says:

      Yes, it definitely is possible to make the bullets act as you describe. I was hoping to fit that into the Part 10 tutorial, but I spent so much time explaining how classes work that I ran out of time. I might just release a short Part 11 by the end of the week, which will finish fixing the bullets’ behavior. The secret really lies in using back.addChild(bullet) instead of stage.addChild(bullet), but there are a bunch of extra steps you need to do to make them appear in the right place and move correctly.

  4. Christian Meyer says:

    I keep getting a compiler error saying that I have my loop function is an undefined property. The error points to the line where you reference the loop in the Enemy class, and I didn’t change anything in the original action script. What do you think the problem could be?

    • Ben Reynolds says:

      Hmmmm… that’s strange. Have you tried downloading my source files? If not, look at my working source code in those and make sure yours matches up exactly. If you’re still having trouble, let me know.

      • Christian Meyer says:

        I downloaded the source files, i think the problem was me having the “fireBullet” function in the loop instead of out in the open, plus my Bullet class was a little bit off, but it works now. Thanks!

  5. Bob Johnson says:

    Do you think you could have enemies in the next tutorial? I’ve really been looking forward to them. Also, a mini tutorial for a menu screen or something would be nice too, but I think enemies would be needed sooner in order to make the bullets useful. Thanks for making these though

  6. Matthews says:

    Please keep up the good work. Hopefully I can make a game out of these tutorials to put in my portfolio, thanks to you.

  7. Keith Schmidt says:

    Not to try and rush you, but could you put up the next part as soon as possible? I’m using your tutorial for a class and I need to turn it in in a few days, all I need are some enemies and a title screen.

  8. Jojo White says:

    Ben c’mon dawg help a brother out my name’s Jojo and I need this game to pass my final class! My entire high school career hinges on the creation of this game and I desperately need enemies in my game to get a decent grade!

  9. Eric says:

    Thanks for all your help, this is my second game.
    http://bit.ly/KZOCJg

  10. ss502 says:

    Mate you have really helped me a lot. I have read a few books on AS3 and none of these books seem to explain it as relevant and clearly as you.

    I have a question that i need answering. It is stopping me from achieving what I want.

    I have created separate external classes like Player, Collision, Background.

    My main document class is called Main (these are example classes not the real names for clarity)

    basically i have the player on the stage and given him an instance named ‘Player’ In the Player class i have attached moving methods ‘movePlayer’ ‘keyupHandler’ ‘keyDownHandler’ (made private). I tried to reference him in the Main class using Player.gotoAndPlay(“WalkLeft”) this wouldn’t work?

    how can I control instances on the stage via document class instead of addChild and all that. because I prefer to work that way :)

    Keep Up the good work Ben!

    Shaun

  11. Eric says:

    This is my game, I used your tutorials to make most of the main game, Thanks. http://bit.ly/KZOCJg

  12. bysomy says:

    This is my game, I’ve used your tutorials to make it, so thanks. http://bit.ly/KZOCJg

  13. Michael says:

    I’m pumped to finally learn how to add enemies!! Can’t wait for that part. Thanks for your tutorials again!!

    • Ben Reynolds says:

      No problem! I just released the next tutorial, although it still doesn’t cover enemies. However, it does the “prep work” that needs to be done with the bullets before we can add enemies. Thanks for your support :-)

  14. jay to the jay says:

    my god, dude i could kiss your feet
    for the past week i have been trying to get my sidescroller off the ground
    and my biggest problem has been shooting bullets
    thank you soo so much man =)

    one question my bullet is triangle not a circle so if i shoot it right, it faces the right way but if shoot it left its facing towards me eventhough its travelling away from me how do i flip it so its facing the other way. should i just use the scaleX??

  15. edison says:

    Thanks for take a time for make this tutorial. realmente lo aprecio. thanks.

  16. Emil says:

    But you don’t remove Bullets !!!
    In the big game it can be a real problem …

  17. Colt K says:

    I have done all of this but it tell me “access of undefined property loop” in the line with the addEventListener in the Bullet.as file.

  18. Colt K says:

    Never mind it was because I put “public function lop(e:Event):void {” instead of “loop”

  19. Jonathan Grenier says:

    ty for making this mine work wonderfully, my mysterious character actually fire his secret projectiles very well….by the way is there is a way to set joypad/joystick button in flash that would be awesome…just like the game I’m making..

  20. Mike says:

    Bullet doesn’t spawn in the right place.

  21. andy says:

    Hi, great tutorial, thanks. I have a question: How can you make bullets fire in 8 directions using the arrow keys? For example, if I want to shoot diagonally, I press UP and RIGHT and it fires diagonally at a 45 degree angle. Like the way Bill Rizer fires his gun in Contra for NES.

    any help would be hugely appreciated.
    Thanks.

  22. Tom says:

    Hey where does the “keyUpHandler” go? You don’t quite say. It may have been in another tutorial. But these things are amazing. Great help.

  23. Scene 1 Layer ‘actions’, Frame 1, Line 287 1136: Incorrect number of arguments. Expected 0

    Any suggestions? I copied the code and still no luck

    also when I edit the class for my Bullet it always remakes an actionscript.

    this happened to me with trying wck,

    please help, thankyou

    • Nvm
      Solution:
      In preferences (ctrl+U) > actionscript > AS3 settings > add your folder under Source Path

      this I assume will get it linked to the correct place

      Anyway, amazing tutorials! Ill have a question about wck in the future if I get there :] such as, could you put them together? and how would you do that?

      Thankyou!

  24. Connor says:

    I have a problem…when ever i try to save my class file, it tells me
    “Access to /Bullet.as was denied”

  25. mdn says:

    Keep getting errors. Where do I put the codes in the tutorial?
    The as file is not recognizing playerDirection as a thing

  26. AS says:

    My bullets are firing from a position incrementally further and further away from my player. And if I hit the space bar fast enough, I end up with a line of stationary bullets in front of my character going to the right of the screen(I’ve not seen it develop on the left but possible it’s just off screen).

    • AS says:

      I figured it out.

      I have been using all external class files, and was declaring the bullets in more than one location. Once I got all that cleaned up the bullets are functioning perfectly.

  27. the crest says:

    Peculiar article, exactly what I was looking
    for.

  28. tud07744 says:

    Hey friend, lol just dropping a line to say, I’ve read almost all your tutorials, just the way you explain simply and with effective language and easy to follow steps, I know i could try to learn AS3 classes 10 other places on the web, but this is my favorite… THANK YOU IMMENSELY!

  29. Jessy Barber says:

    Hey Ben,
    I’ve been using this guide for an upcoming school project which has been working wonders until this point. Ever since I added the code for the shooting my player is no longer able to move and I have tried everything to fix this issue including permitting debugging and downloading your source files. Nothing seems to work and when I try to move my player i get a spam of this message in the output log:
    TypeError: Error #1010: A term is undefined and has no properties.
    at Untitled_1_fla::MainTimeline/loop()[Untitled_1_fla.MainTimeline::frame1:162]
    I have looked at line 162 of the code and all my instance names but cannot understand why this is happening!
    Please help!!!!
    Much appreciated.

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