Tutorials

February 7, 2009

AS3 Flash Games for Beginners: More Advanced Character Movement

More articles by »
Written by: Par
basics1_tn

Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg ThisSubmit to reddit

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:

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:

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:

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.

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

Similar Posts:


Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg ThisSubmit to reddit


About the Author

Par
Hey! Don't be surprised, I'm a flash developer. While Flash is definitely one of my favorite languages to develop in, most of all I just like making games. If you want to see the games I've developed so far head over to my website, DigitallyBold, in the link below. If you want to know more about what I'm working on now and in the future be sure to follow me on twitter.




21 Comments


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

    waiting for your next tutorial :)


  2. encoder

    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. 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. Vups.. Wronge place i paste my question.. But any way.. Can you help?


  5. Peter

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

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


  8. mikehart

    @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

    @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 :)


  10. Awesome tutorial! I already knew how to do the regular movement stuff, but the the 3D effects were simple and looked surprisingly cool. Great job thinking of that, I would never have thought of that on my own.


  11. Roshan C

    Very nice!!! excellent job..


  12. and again, very awful…nah, the opposite ^^ no problems with making it clear, understood all and learned very usefull things…so, cya on the next page again…

    peace
    jesta


  13. Dan

    How does the ship get scaled differently if it’s going left, differently if it’s going right?


  14. santosh

    nice!!!!!!!!!!!!!!!!!!


  15. can g.

    hello everybody, don’t know if ppl are still watching this article but I’d like to say it’s an awesome tutorial!! (very informative and perfect for beginners like myself)

    However i came across a little bug: when moving left and/or up (when the x and y values are getting negative values) the clip keeps moving in that direction for a disturbingly long time compared to the time it keeps moving right or down. This also applies to the above compiled versions. (If you look carefully, it keeps moving pixel by pixel towards left even if you press left key for a very short time)

    I think the reason for this is about rounding the negative values down (to -1 I think?). Don’t have a solution for it as I said I’m a beginner to AS3, but it would be nice if somebody solved it and posted it here.

    Have a nice day.


  16. S.L

    it’s nice but, when you go in diagonal the speed becomes 1.4 times faster, is there a way to keep the speed constant no matter which direction?


  17. noobgamer

    Hi its a great tutorial…Can anyone explain how to arrive at the scaleX=(maxspeed-abs(vx)/(maxspeed*4) +0.75..In a mathematical way how to write this so that he number falls between 0 and 0.25. Is this a method of trial and error or any other workaround to it???

    are there any other ways other than this???

    These tutorials are very very cool. Thanks a lot


  18. mark-o

    Nice,tutorial! You can put scaleY = (maxspeed – Math.abs(vy))/(maxspeed*4) + 0.75; just under last line in Ship file for some effect when you press up.


  19. Awesome .. thanks a lot. I really need this XD


  20. Michael

    Thank you again for this great tutorial. I have a few basica questions. Since we changed the x and y variables to vx and vy, we are still updating an x and a y variable. we are also updating a rotation variable as well as scaleX. Where are the variables. what class are they in that we can change them?



Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">


Advertisement