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: More Advanced Character Movement



It’s easy to setup simple character movement based on keypresses, we’re going to take it a step farther. Don’t worry this is still easy but this time around we are going to add velocities in x and y directions that will be affected by “friction” and your keypresses… The end result will be a much smoother movement for our spaceship.

This is a continuation of the previous article in the series, Character Movement / Multiple Key Presses, so if you need to review what we have already done click the link. Otherwise, you can download the final source code of the tutorial here.

Step 1: Movement Speed Based on a Variable

In our Ship class, let’s add a new class variable called speed. It’s type will be Number and we’ll set it equal to 5. Now let’s replace our x -=2, x += 2, y -= 2, and y += 2 (in the loop function) with x -= speed, x += speed, y -= speed, and y += speed.  It’s a very simple change, that will make it easy in the future to update speed. Here’s the new Ship class and the swf.

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 = 5;
 
		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
		{
			if (key.isDown(Keyboard.LEFT))
				x -= speed;
			else if (key.isDown(Keyboard.RIGHT))
				x += speed;
 
			if (key.isDown(Keyboard.UP))
				y -= speed;
			else if (key.isDown(Keyboard.DOWN))
				y += speed;
		}
 
	}
 
}

And the compiled game:

how to Flash spaceship game with dynamic speed for beginners.

Step 2: Creating Velocity in X and Y for our Game

So before we can have velocity in x and y we need to variables to track it.  Create two more private variables named vx and vy. Both of which should be Numbers and set their values to zero.  Change the default value of speed from 5 to 0.5. That may seem slow for now, but you’ll see why in a second.  Now we are going to change vx and vy instead of x and y when a key is pressed. So simply change your x and y variables in our loop function to vx and vy. Last let’s update our x and y with vx and vy.  So at the end of our loop just add x += vx; and y += vy;  Your code should now look as follows:

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;
 
		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
		{
			if (key.isDown(Keyboard.LEFT))
				vx -= speed;
			else if (key.isDown(Keyboard.RIGHT))
				vx += speed;
 
			if (key.isDown(Keyboard.UP))
				vy -= speed;
			else if (key.isDown(Keyboard.DOWN))
				vy += speed;
 
			x += vx;
			y += vy;
		}
 
	}
 
}

And the game should look like this:

Flash Game for Beginners, movement with velocity on frictionless surface.

Don’t hold down a key too long! Your ship builds speed the longer you hold in one direction and when you let go of the key it keeps going.

Step 3: Creating Friction to Slow our Ships Movement

So we need some friction to slow down our speed over time.  Simple, let’s create a new class private variable and call it friction. It’s a Number and it’s value is 0.93.  Now this is not going to be the accurate physics coefficient of friction, not even close, but it works great for a project like this.  Just add else statements onto the end of our horizontal and vertical key press conditionals.  In the else condition add vx *= friction for the horizontal and vy*= friction for the vertical.

Your class should now look like this:

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;
 
		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
		{
			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;
 
			x += vx;
			y += vy;
 
			rotation = vx;
 
		}
 
	}
 
}

Alright compile yours. It should look something like this:

Movement with some friction, rotation and speed. Flash Game Development Step 6

Break Down Time:

  • First we added a new variable friction. It’s the same as the ones before… so nothing special.  The closer our friction variable is to one the slicker our surface is… If the friction is above one our ship will gain speed, below one it will lose speed.  Between .9 and 1 are usually the most effective friction values if you are using friction like this tutorial.
  • Only applying the friction when keys aren’t being pressed allows us to gain as much speed as we want and only lose it when the keys are released. That’s the purpose of putting vx*=friction and vy*=friction in the else condition.
  • Last I added rotation = vx. Rotation is in degrees, so we have 360 degrees to play with. Like x and y variables, rotation is defaulted to zero.  So when our vx is negative our ship rotates left, when it’s positive it rotates right… giving us a more realistic effect.

Step 4: Setting a Max Speed and Creating a 3D Appearance for our Spaceship

So the last we need to do is make sure our ship doesn’t break light speed and we can’t follow it anymore. So let’s create a maxspeed:Number variable and set it to 8.  Then we’ll check if our vx or vy breaks our maxspeed in positive and negative directions.  If it does we’ll reset it to the max speed.  And I’ll throw in a quick scaleX line that will make our ship look like it’s rotating in 3D.  I’ll explain after the fact…. here’s the code.

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
		{
			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;
 
			x += vx;
			y += vy;
 
			rotation = vx;
 
			if (vx > maxspeed)
				vx = maxspeed;
			else if (vx < -maxspeed)
				vx = -maxspeed;
 
			if (vy > maxspeed)
				vy = maxspeed;
			else if (vy < -maxspeed)
				vy = -maxspeed;
 
			scaleX = (maxspeed - Math.abs(vx))/(maxspeed*4) + 0.75;
		}
 
	}
 
}

And our compiled file.

AS3 Flash Game with Spaceship rendered in pseudo 3D with friction and movement.

Awesome huh? Here’s the breakdown:

  • The if else conditions are quite simple. If vx is greater than the maxspeed set it to the maxspeed.  If vx is less than negative maxspeed set it to negative maxspeed. And the same for vy.
  • Now scaleX allows us to scale our DisplayObject in the horizontal direction. scaleY allows us to scale our DisplayObject in a vertical direction.  Setting scaleX to 1 (default) sets our ship to it’s original size.  .5 sets it to half, .25 to a quarter… you get the point. (maxspeed-Math.abs(vx))/(maxspeed*4) will return us a Number between 0 and .25.  If our vx is at 0 it will return .25 and if vx is at the maxspeed it will return 0.  So incase you haven’t figured it out, Math.abs(vx) will return the absolute value of vx.  So in the end, if we are moving at maxspeed our ship is at 75% of full size.  If our ship is at rest, it’s 100% size.  Perfect for making it look like it’s rotating. If the size looks off for your ship, feel free to adjust the calculations to work for you :)

Alright Tutorial 3 Completed! Here’s the final source:
AS Gamer Flash Games for Beginners Advanced Ship Movement Archive

Jump on over to the next tutorial in the series, Level Mechanics and Animated Backgrounds


Where to Go Next?


February 7th, 2009 | Tutorials |

10 Responses to “AS3 Flash Games for Beginners: More Advanced Character Movement”

  1. Nice Tutorial, it was chosen for the homepage of http://www.tutorialsroom.com

    waiting for your next tutorial :)

  2. encoder says:

    i reinvented this wheel last year. my advice:
    change the brightness of the ship according to the direction of the lateral movement. brighter left darker right or reverse.

  3. NicoJunior says:

    Hey - Really great tut.

    I got throug and my game is workign but i keep getting this error:

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

    Any idea why?

  4. NicoJunior says:

    Vups.. Wronge place i paste my question.. But any way.. Can you help?

  5. Peter says:

    First of all: This is a great piece of work! Thank you :-)

    Next… Is the code supplied here supposed to behave the same as your compiled examples? When I compile, the movement is much more stuttered as opposed to your examples on the website which have nice smooth movement. The speed doesnt match either… Am I doing something wrong or IS there a difference?

  6. JimE says:

    Peter you might check the frame rate of your fla to see if it set too low. That could cause it to be jumpy

  7. mikehart says:

    check your fps in you fla file. it will be at the bottom under properties. you may have it set too low.

  8. mikehart says:

    @Peter

    you may want to check your FPS on the .fla file. In CS4 its under the properties tab the properties/library window o the right of the stage.

  9. Yulaw says:

    @Peter

    It might be a bit late, but if you are still struggling on that problem I have found your solution.
    When following the tutorial I came across the same problem.

    Solution is getting rid of the { and } marks on your control section. After that it will move smoothly acros your stage :)

Leave a Reply

Sponsors & Links

Build Flash Online advertisement advertisement advertisement