AS Gamer Limelight Tutorial

spotlight
An Even Better AS3 OOP Flash Custom Cursor In the last tutorial we created a custom cursor, in this tutorial we'll address some issue...

AS Gamer Spotlight Tutorials

AS3 Flash Games for Beginners: Level Mechanics and Animated Backgrounds



Okay, so your character is designed, moving correctly, and all around pretty fun to control… but when you move off the screen, he just disappears.  So you want to make him always stay on the screen… Maybe an invisible wall that bounces him back… maybe he flips to the other side of the screen.  And your background, it’s cool and simple but you want something that has some movement. This tutorial is about making your character interact with the level correctly and look good doing it.

Like the other articles in this series, if you haven’t been keeping up here’s the previous article: More Advanced Character Movement.

And here’s the source code from the previous article: More Advanced Character Movement Source Code

Okay, let’s get started.

Step 1: Making your Character “Jump” to the Other Side of the Game Screen.

Okay so really this is simple, if you think about it, you probably know how to do this yourself and my help is entirely useless. So I’ll make it quick and the explanation simple.  We want our character, when at an x position less the the left side of the screen (0) to move to the right side of the screen (stageRef.stageWidth) and visa versa.  The same applies for y.  So, I’ve taken the liberties of slightly rearranging the Ship class (for clarity’s sake) and adding some new code to make this work.  Feel free to just copy and paste this code over your current Ship class.

package com.asgamer.basics1
{
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import com.senocular.utils.KeyObject;
	import flash.ui.Keyboard;
	import flash.events.Event;
 
	public class Ship extends MovieClip
	{
 
		private var stageRef:Stage;
		private var key:KeyObject;
		private var speed:Number = 0.5;
		private var vx:Number = 0;
		private var vy:Number = 0;
		private var friction:Number = 0.93;
		private var maxspeed:Number = 8;
 
		public function Ship(stageRef:Stage)
		{
			this.stageRef = stageRef;
			key = new KeyObject(stageRef);
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
		}
 
		public function loop(e:Event) : void
		{
			//keypresses
			if (key.isDown(Keyboard.LEFT))
				vx -= speed;
			else if (key.isDown(Keyboard.RIGHT))
				vx += speed;
			else
				vx *= friction;
 
			if (key.isDown(Keyboard.UP))
				vy -= speed;
			else if (key.isDown(Keyboard.DOWN))
				vy += speed;
			else
				vy *= friction;
 
			//update position
			x += vx;
			y += vy;
 
			//speed adjustment
			if (vx > maxspeed)
				vx = maxspeed;
			else if (vx < -maxspeed)
				vx = -maxspeed;
 
			if (vy > maxspeed)
				vy = maxspeed;
			else if (vy < -maxspeed)
				vy = -maxspeed;
 
			//ship appearance
			rotation = vx;
			scaleX = (maxspeed - Math.abs(vx))/(maxspeed*4) + 0.75;
 
			//stay inside screen
			if (x > stageRef.stageWidth)
				x = 0;
			else if (x < 0)
				x = stageRef.stageWidth;
 
			if (y > stageRef.stageHeight)
				y = 0;
			else if (y < 0)
				y = stageRef.stageHeight;
 
		}
 
	}
 
}

So the new code is everything after the stay inside screen comment. Simple code, huh? Awesome. Here’s the breakdown.

  • if (x > stageRef.stageWidth). Well simple if x is greater than stageRef.stageWidth then… do something. In our case just make x = 0.  The rest of the conditionals are the same idea. So if you understand this.  You should understand the whole thing.

Here’s the running swf.

Flash Basics, Making our Ship Reposition when it extends outside the Game border. Even more advanced Character movement.

Step 1 Revisited: Doing this Backwards…. Cool Free Bouncy Effect Included!

Alright so the above works great, but let’s do it again this time making our ship bounce back when it hits the wall.  The idea is simple, if x is greater than the stage’s width then let’s make our ship stop and bounce back from the way it came.  Can you figure it out? Well we just need to change the code after our stay inside screen comment. Here’s the difference:

			//stay inside screen
			if (x > stageRef.stageWidth)
			{
				x = stageRef.stageWidth;
				vx = -vx;
			}
			else if (x < 0)
			{
				x = 0;
				vx = -vx;
			}
 
			if (y > stageRef.stageHeight)
			{
				y = stageRef.stageHeight;
				vy = -vy;
			}
			else if (y < 0)
			{
				y = 0;
				vy = -vy;
			}

And the SWF:

Spaceship bouncing off of invisible wall. Flash Game Design for Beginners.

And the breakdown:

  • So first we added {} around our conditionals. This is because now we need more than one statement to be excuted if the condition is met. So we have to wrap them in curly brackets to make the code work. I left this out on a big project a day ago and about pulled my hair out trying to find the error, so be careful.
  • The main difference though is instead of setting our x and y to the opposite side the screen we just force it back to the end of the screen our character is trying to leave.
  • And to make our character bounce, simple, we just negate the velocity.  Simple idea, the speed at which we hit our invisible wall is forced back in the opposite direction, it’s perfect… I mean it’s Newtonian. Which is perfect enough for me.

Step 2: Creating a Starscape/Spacedust Moving Background.

Alright, you’ll love this, at least I do. It’s great when you can do something super simple and create an awesome effect with it. This, in my opinion, is an excellent effect and requires very little programming or art to acheive it. We’re going to create a starscape, spacedust, or whatever you want to call it.  So in terms of art all we need to do is create a new movieclip, named Star, of a small white dot.  This should be easy to make, just grab the Oval Tool (O) and draw a circle. Hold shift and drag to constrain your drawing to a circle instead of oval.  Then once finished in your properties window (CTRL+F3) set the circles height and width to 6 and it’s x and y to -3.   This will make the circle directly in the center of the registration point (Your registration point is always at 0,0 from inside the MovieClip). Great, now if you want you can add a radial gradient of a 100% alpha white to 0% alpha white with the Paint Bucket Tool (K) for a different effect.

Alright take our Star movieclip and right click it and select Linkage… Export it for actionscript let’s make it’s class be com.asgamer.basics1.Star. Click OK. Below’s a shot of the Linkage setup:

Linkage setup for our Star MovieClip

Linkage setup for our Star MovieClip

If it says it doesn’t exist, it’s because it doesn’t, don’t worry click OK. Now let’s create that class so it does exist.  Just make a new Star.as class in the com/asgamer/basics1 folder.  And copy and paste this bunch of code into it.

package com.asgamer.basics1
{
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
 
	public class Star extends MovieClip
	{
 
		private var stageRef:Stage;
		private var speed:Number;
 
		public function Star(stageRef:Stage)
		{
			this.stageRef = stageRef;
			setupStar(true);
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
		}
 
		public function setupStar(randomizeY:Boolean = false) : void
		{
			//inline conditional, looks complicated but it's not.
			y = randomizeY ? Math.random()*stageRef.stageHeight : 0;
			x = Math.random()*stageRef.stageWidth;
			alpha = Math.random();
			rotation = Math.random()*360;
			scaleX = Math.random();
			scaleY = Math.random();
 
			speed = 2 + Math.random()*2;
		}
 
		public function loop(e:Event) : void
		{
			y += speed;
 
			if (y > stageRef.stageHeight)
				setupStar();
 
		}
 
	}
}

Wow. There’s quite a bit of code there. Don’t be overwhelmed, if you’ve followed through this series from the beginning you’ll understand the most of it.

Let’s break it down:

  • We’ve got a list of imports, our Star class extends MovieClip and two class variables… stageRef which will hold our stage (we’ve used it like this before) and a speed variable.
  • setupStar(true); Here we are just calling the function setupStar and sending the Boolean true into it. Booleans are variables that store one of two things, true or false.  But why are we sending true? We will get to that.
  • public function setupStar(randomizeY:Boolean = false). So our function setupStar catches one variable randomizeY ,it’s  a boolean, that equals false? Well if inside a functions parameters we set it equal to a value then if nothing is passed into the function parameter, it will take the value it is set equal to.  In our constructor function where we passed true as randomizeY, randomizeY will take a value of true. But if we had just called setupStar() then randomizeY would be false.
  • y = randomizeY ? Math.random()*stageRef.stageHeight : 0; What is this gibberish? Well it’s a inline conditional. Much like our if else conditionals we’ve done in the past except this one runs on one line.  In english this reads:  y if randomizeY is true equals Math.random() times the stage height otherwise y equals 0.
  • Math.random(). This is a Flash function that return a random number between 0 and 1.  We can use it to make things seem uncontrolled, spontaneous, or more appropriately random.
  • Since alpha, scaleX, scaleY all are 100% of their original values at 1. We can set them to Math.random() and get a nice set of different stars.
  • speed = 2 + Math.random()*2. Creates some variety in the speed of the stars.  Then can be moving between between 2 and 4 pixels per frame.
  • if (y > stageRef.stageHeight) setupStar(); Simple… if our star moves off the stage, we setup the Star again and make it start all over.  The difference this time is we don’t pass anything into randomizeY so it defaults to false. Which means y will be set to 0.

Alright so we broke it down… One more thing to do. We have to add some Stars to the background.  So let’s open our Engine class and in the constructor function after we position ourShip let’s add this code:

			for (var i:int = 0; i < numStars; i++)
			{
				stage.addChildAt(new Star(stage), 1);
			}

First of all you’ll notice numStars in the first line of the new code.  You’ll need to add a new class variable named numStars… make it be an int of value 80.

		private var numStars:int = 80;

Let’s break down the for loop:

  • for (var i:int = 0; i < numStars; i++). Alright so a for loops through the code inside it until the conditional inside the for statement is met.  There are 3 parts to a basic for loop, initializing the variable being used. We create an int variable named i and set it to 0 (An int is a integer and is best to use when your number variable is always going to be a whole number.) Then we check if i is greater than numStars… which we set to 80… so yeah it’s not greater than numStars.  Last we tell Flash what to do at the end of each loop until our condition is met.  So this fo rloop is ran 80 times.  We could write this same code if we wrote the stage.addChildAt line 80 times but the for loop makes it a lot simplier.
  • stage.addChildAt(new Star(stage), 1); addChildAt is the same as addChild except it let’s us set where is the displayList we want to drop our DisplayObject in the second parameter. When our game is ran, our background is automatically dropped in spot 0 then ourShip is placed at spot 1.  So if we add our stars at spot 1 our ship will be used up 1 each time. We could use stage.getChildIndex(ourShip) to get the position of our ship and drop the star there.
  • new Star(stage). before when we created our ship we wrote var ourShip:Ship = new Ship(stage) and passed ourShip into addChild.  The only difference here is that we have no variable holding each of our new stars. They are simply created and dropped onto the stage.

Alright! your engine class should look like this now:

//our package... simply put, the directory structure to this file
package com.asgamer.basics1
{
	//list of our imports these are classes we need in order to
	//run our application.
	import flash.display.MovieClip;
	import flash.display.Stage;
 
	//our Engine class it extends MovieClip
	public class Engine extends MovieClip
	{
 
		private var numStars:int = 80;
		//our constructor function. This runs when an object of
		//the class is created
		public function Engine()
		{
			//create an object of our ship from the Ship class
			var ourShip:Ship = new Ship(stage);
			//add it to the display list
			stage.addChild(ourShip);
 
			ourShip.x = stage.stageWidth / 2;
			ourShip.y = stage.stageHeight / 2;
 
			for (var i:int = 0; i < numStars; i++)
			{
				stage.addChildAt(new Star(stage), 1); //OR stage.addChildAt(new Star(stage), stage.getChildIndex(ourShip));
			}
 
		}
 
	}
 
}

And your SWF:

Scrolling Background Flash as3 with spacedust and stars.

Pretty awesome huh? We have a plenty of tertiary animation with our moving background.  Alright that’s all for this part… join the rss and get updates when the next tutorial is released because next time we are learning to shoot bullets with timeouts using AS3 Timers.
Subscribe to the RSS Feed

here’s the source code:
Level Mechanics and Animated Backgrounds Source Code Zip Archive

Continue on to the next tutorial in the series:
Firing Weapons with Delay

Tags: , , , ,


Where to Go Next?


February 8th, 2009 | Tutorials |

25 Responses to “AS3 Flash Games for Beginners: Level Mechanics and Animated Backgrounds”

  1. bresson says:

    great tuts. building my own game based on these tuts. do have a question - how can i make the stars responsive to the speed of the ship? for instance, if the up key is pressed, i want the stars to fly by the ship faster. thanks!!!

  2. Par says:

    You’d need to make the each of the stars get their speed from a variable that is related to the ship. So you could pass the ship variable into each of the stars and then add ship.vy to the speed of each of the stars.

  3. bresson says:

    Thank you for responding. How can I reference the Star instance in Engine.as? My thinking is to pass ship.vy into the Engine class through a getVY function and then reference it with _starInstance.setVY but I’m a bit lost on how to reference the star instances. Thank again -

  4. Par says:

    inside the for loop

    stage.addChildAt(new Star(stage, ourShip), 1);

    Now inside the Star class

    public function Star(stageRef:Stage, ship:Ship)
    {
    this.ship = ship; // make it a class variable
    this.stageRef = stageRef;
    setupStar(true);

    addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
    }

    Then in the loop function

    y += speed + ship.vy;

  5. bresson says:

    thanks - the stars are now responsive to ship speed. i do notice that performance drops significantly - can reach moments when the stars and ship just freeze. otherwise it works great. thanks again.

  6. Par says:

    yeah, it’s definitely not the most optimal way of doing this but it does work.

  7. Jonhatan says:

    I get the following error:

    ArgumentError: Error #1063: Argument count mismatch on com.asgamer.basics1::Star$iinit(). Expected 1, got 0.
    at flash.display::Sprite/flash.display:Sprite::constructChildren()
    at flash.display::Sprite$iinit()
    at flash.display::MovieClip$iinit()
    at com.asgamer.basics1::Engine$iinit()

  8. Adrian says:

    so do i get the #1063 error!

  9. Rish says:

    Im getting 1063 error! Spent hours trying to fix it, but doesnt work! help!

  10. DinoLando says:

    Code works fine for me.. using Flash CS4.

    @Jonhatan,Adrian,Rish:
    Make sure you keep the file structure inside the source code zip intact. So create a new folder and unzip there. Open basics1.fla and run. Hopefully that helps :)

  11. memyselfandmetoo says:

    I am trying to sort of replicate your edge of the stage effect. My movieclip is 6x wider than the stage - I am using

    var scrollSpeed=20;
    stage.addEventListener(Event.ENTER_FRAME, pan);
    function pan(evt:Event):void {
    MovieClip(root).gallery_mc.x -= (stage.mouseX - (stage.stageWidth/2)) / scrollSpeed;
    }

    to scroll my clip - which is working great. I can’t find anything that tells me how to stop the clip when the edges reach the edges of the stage. My clip just scrolls off into infinity (on either side) unless the mouse is used to bring it back by going to the opposite edge of the stage. It is probably something simple and maybe I can no longer see the forest for the trees but I have been searching and experimenting for 3 days and cannot figure it out. Appreciate any guidance/help you might be able to offer! I think you tutorial is very well written!

  12. memyselfandmetoo says:

    Disregard previous - I finally figured it out. Just as I suspected - easy fix after I left it alone for awhile and came back to it.

  13. mike says:

    How do I use the same Math.random output for 2 different variables? Basically I don’t like how X and Y are random independent of each other - some stars are extremely squished. They should both be using the same value so the stars are kept circular. I tried a few different things but all are giving me error (scaleY + scaleX = Math.random, or scaleY, scaleX = ..etc.)

    Thanks for the great tutorial!

  14. David G says:

    I was getting the #1063 errors, too, until I realized I left a copy of the Star movie clip on the stage. Once I deleted the clip (so that the stage is completely empty) the error was fixed. Hope this helps other who have the same problem.

    And thanks for the great tutorials! My Flash Actionscript skills have been very out of date and these are helping me get caught up finally.

  15. aceofspadez619 says:

    I’m loving this tutorial! Of all the Flash Game Tuts out there, I find it to be the right balance of simplicity for beginners, but complex enough to make a nice game and really get a taste of how to code properly in AS3. Other stuff out there is either TOO simple (how to make Flash Pong, yeah!!, poorly designed/coded (put your action script on each frame, yeah!!), or assuming you are coming over from a coding background and know C# already.

    I’m a 1st timer in game dev and coding, but fairly familiar with Flash and found that this taught the concepts very well, showed how to utilize the IDE when appropriate and how to easily link and store code in external files. Great job!

    Okay, to my (really simple) question:
    On the create moving stars step of the tut, you used the addChildAt method and needed to specify a number (1) for the second param when placing the stars. I can look up more about what a display list is and how it works, but what I don’t get is why you continued to add the stars to ’spot 1′ when you explained that the background is at ’spot 0′ and the ship at ’spot 1′. Does everything need to be at 1 for simplicity’s sake (I haven’t gotten to the enemyships yet, so maybe I’ll see there.

    Thanks for ‘breaking it down’.

  16. aceofspadez619 says:

    …adding to my previous post.

    In some ways answered my own question. I forgot that I had added the background to the stage at runtime as you had suggested in Step one, so when I copied your code into my Engine.as file, I lost the background! I had forgot what I had done so at first I tried this (I have a Background.as file with an empty constructor function, which i’m guessing is all that’s needed since the background does nothing):

    //add background to the stage
    stage.addChild(new Background());

    which brought back my background, but (as I’m sure you know) no stars!! I guessed they were covered up, so I used the addChildAt to set the level to 0:

    //add background to the stage
    stage.addChildAt(new Background(), 0);

    and my stars are back! So I’m guessing this displayList number corresponds to the “level” of the object, similar to the layer list on the timeline (objects in layers above cover up objects below)?

  17. emb03 says:

    @memyselfandmetoo

    I am having this issue. You said it was easy, but how did you get the background to stop panning at the edge of the stage?

    Thanks!

  18. johno says:

    Hi, im trying to get the stars to go from right to left iv managed to do this fairly easily but once the first wave appears no more come i have managed to make the stars go left to right fine but cant seem to get them to carry on producing from the right to left any ideas?

  19. MrKrackham says:

    @johno

    I tried doing that too. Just switch all occurrences of WidthHeight, xy and randomizeYrandomizeX. Seemed to work fine :)

    package com.asgamer.basics1
    {
    import flash.display.MovieClip;
    import flash.display.Stage;
    import flash.events.Event;

    public class Star extends MovieClip
    {
    private var stageRef:Stage;
    private var speed:Number;

    public function Star(stageRef:Stage)
    {
    this.stageRef = stageRef;
    setupStar(true);

    addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
    }

    public function setupStar(randomizeX:Boolean = false) : void
    {
    //inline conditional, looks complicated but it’s not.
    x = randomizeX ? Math.random()*stageRef.stageWidth : 0;
    y = Math.random()*stageRef.stageHeight;
    alpha = Math.random();
    rotation = Math.random()*360;
    scaleY = Math.random();
    scaleX = Math.random();

    speed = 2 + Math.random()*2;
    }

    public function loop(e:Event) : void
    {
    x += speed;

    if (x > stageRef.stageWidth)
    setupStar();
    }
    }
    }

  20. Ollie says:

    Yes, I have the same problem as johno. I can’t get the stars to be reproduced when having them scroll horizontally.

  21. mikehart says:

    I’m getting a strange error when I try to compile. its on the line in the for loop

    1136:Incorrect number of arguments. Expected 0.

  22. Unsafe Creations says:

    In case anyone was having touble with johno’s problem…(Just posting this because it took me like 30 minutes to figure out…I might just be dumb, though)

    If you want the Stars to go from left to right, use MrKrackham’s example above. If you want them to go from right to left, and your stars aren’t respawning, and if you’re an AS noob like me, here’s the problems.

    public function setupLine(randomizeX:Boolean = false) : void
    {
    //inline conditional, looks complicated but it’s not.
    x = randomizeX ? Math.random()*stageRef.stageWidth : 750; **has to be 750, this is where they respawn**
    y = Math.random()*stageRef.stageHeight;
    alpha = Math.random();
    scaleX = Math.random();
    scaleY = Math.random();

    speed = 2 + Math.random()*2;
    }

    public function loop(e:Event) : void
    {
    x -= speed; ****has to be a minus sign, so they go left****

    if (x < 0) ****this is where it got. don’t know why. it just did.****
    setupLine();

    }

    }
    }

  23. cnicoletti says:

    First let me start off by saying how cool this is!

    Anyway, I have setup the stars and they are flowing rather well.

    My question is, how do you get them to stop?

    removeChild? If so, How does that work with multiple stars on stage at once?

  24. Daniël says:

    Here, Daniël here.
    I have the same problem as mikehart, getting an 1136 error..
    Even after I compared all the codes written by me with the final .zip of this tut, I cant find it.

    The only thing I have “customized”, is the player code to get a smaller boundary for the ship to fly in.
    Its really weird and frustrating to still get the message
    “1136: Incorrect number of arguments. Expected 0.”

    Can anybody help me?

  25. Gary says:

    Hi,

    This is a great tutorial. I was wondering if the code for the Starfield background can be modified to look like a 1st person point of view? In otherwords, we are traveling towards the stars and the stars are zooming past us?

    This is terrific. Thanks very much.

    Best,
    Gary

Leave a Reply

Sponsors & Links

Build Flash Online advertisement advertisement advertisement