Getting started with Actionscript 3 Page 2/4 Previous page Next page
[ July 06, 2006 ] Milan Toth (MilGra)
A 4 chapter long, in-depth introduction to the new characteristics of Actionscript 3 and the Flash player 9 framework.
The author will guide you through all the new features by constructing a real application step by step. A must read for all Flash enthusiasts.

Getting started with AS3, Second Part - Making the ball move

Getting started with AS3, Second Part - Making the ball move

We have a rather ugly bouncing ball. It could be more spectacular, if the stage would be in no scale mode, framerate would be higher, and there would be something behind it. Our solution is the Stage class. Let's import Stage class, and its constants.

import flash.display.Stage;
import flash.display.StageScaleMode;
import flash.display.StageAlign;

Then we need a private variable:

private var myStage:Stage;
//
..
//
myStage = new Stage( );
myStage.frameRate = 25;
myStage.scaleMode = StageScaleMode.NO_SCALE;
myStage.align = StageAlign.TOP;
//

As you can see, we set framerate, saclemode and align, so it is better now. Let's draw a background:

private var myBack:MovieClip;
//
..
//
myBack = new MovieClip( );
myBack.graphics.beginFill( 0x900000 , 1 );
myBack.graphics.lineStyle( 2 , 0xffffff , 1 );
myBack.graphics.moveTo( 0 , 0 );
myBack.graphics.lineTo( 400 , 0 );
myBack.graphics.lineTo( 400 , 200 );
myBack.graphics.lineTo( 0 , 200 );
myBack.graphics.lineTo( 0 , 0 );
addChild( myBack );

Modifiy some coordinates in myBall's step function, so the ball can't go out of the background.

graphics.drawCircle( 0 , 0 , 20 );
..
if ( x + xspeed > 390 ) xspeed *= -1;
if ( x + xspeed < 10 ) xspeed *= -1;
if ( y + yspeed > 190 ) yspeed *= -1;
if ( y + yspeed < 10 ) yspeed *= -1;

It's quite good now. And now for something completely different: we make some interaction ! :) Let's say we would like to grab the ball, and throw it. BallClip class will watch for mouse Press/Release events, and will call the controller's "move me" function. So we need two new functions, which will be invoked by mouse events.

//
//
//
public function mouseDownHandler ( eventOBJ:MouseEvent ):void
{
	//
	father.dragBall( );
	//
}

//
//
//
public function mouseUpHandler ( eventOBJ:MouseEvent ):void
{
	//
	father.releaseBall( );
	//
}

We assign the events in the constructor.

//
addEventListener( MouseEvent.MOUSE_DOWN , mouseDownHandler );
addEventListener( MouseEvent.MOUSE_UP , mouseUpHandler );
//

Don't forget to import flash.events.MouseEvent class!

Now BallClip will know if we clicked it. Let's continue with TestBall's functions. But there is an important thing first: if we create an arbitraty object somewhere, we have to tell him immediately that we are its parents, in its constructor if its possible. If we do this, the object can refer us directly, and this is extremely useful. So in TestBall do this:

myBall = new BallClip( this );

In BallClip make a private MovieClip type variable called father, it stores our father. ( the id "root" would be better, but it is reserved hence we are a MovieClip, and every DisplayObject has a root, which is the root of the movie. )

	public function BallClip ( myRoot:MovieClip )

	{
		//
		father = myRoot;

Now mouseDownHandler and mouseUpHandler will know what to call.
So we need function(s) in TestBall, which stops our ball's motion, creates a mouse movement listener, and moves the ball. We will need a dragBall function, which stops the timer, and initializes the listener, and a moveBall function, which moves the ball, and sets the previous coordinates of the ball, we need them to set the speed of the ball. Then releaseBall function sets the new speed, and starts the timer.

Two important things:

1. moveTimer object existed only as a local variable, we have to make it global, make it possible for other functions to reach it.

2. We have to set BallClip's xspeed and yspeed variables, make it possible to TestBall to reach it

Timer interval is set down to 20 ms from 50, to make movement smooth.

The final code:

//begin
//
//
package
{
	//
	//
	//
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	import flash.events.MouseEvent;
	import flash.display.Stage;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;
	import flash.display.MovieClip;
	//
	//
	//
	public class TestBall extends MovieClip
	{
		//
		//
		//
		private var myStage:Stage;
		private var myBack:MovieClip;
		private var myBall:BallClip;
		private var moveTimer:Timer;
		//
		private var xspeed:Number = 0;
		private var yspeed:Number = 0;
		//
		private var oldx:Number;
		private var oldy:Number;
		//
		//
		//
		public function TestBall( )

		{
			//
			myStage = new Stage( );
			myStage.frameRate = 25;
			myStage.scaleMode = StageScaleMode.NO_SCALE;
			myStage.align = StageAlign.TOP;
			//
			myBack = new MovieClip( );
			myBack.graphics.beginFill( 0x900000 , 1 );
			myBack.graphics.lineStyle( 2 , 0xffffff , 1 );
			myBack.graphics.moveTo( 0 , 0 );
			myBack.graphics.lineTo( 400 , 0 );
			myBack.graphics.lineTo( 400 , 200 );
			myBack.graphics.lineTo( 0 , 200 );
			myBack.graphics.lineTo( 0 , 0 );
			addChild( myBack );
			//
			myBall = new BallClip( this );
			addChild( myBall );
			//
			moveTimer = new Timer( 20 );
			moveTimer.addEventListener( TimerEvent.TIMER , myBall.step );
			moveTimer.start( );
			//
		}

		//
		//
		//
		public function dragBall ( ):void
		{
			//
			addEventListener( MouseEvent.MOUSE_MOVE , moveBall );
			moveTimer.stop( );
			//
		}

		//
		//
		//
		public function releaseBall ( ):void

		{
			//
			removeEventListener( MouseEvent.MOUSE_MOVE , moveBall );
			myBall.xspeed = xspeed;
			myBall.yspeed = yspeed;
			moveTimer.start( );
			//
		}

		//
		//
		//
		public function moveBall ( eventOBJ:MouseEvent ):void

		{
			//
			myBall.x = mouseX;
			myBall.y = mouseY;
			//
			xspeed = mouseX - oldx;
			yspeed = mouseY - oldy;
			//
			oldx = mouseX;
			oldy = mouseY;
			//
		}

		//
		//
		//
	}
	//
	//
	//
}
//
//
//
import flash.display.MovieClip;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
//
//
//
class BallClip extends MovieClip

{
	//
	//
	//
	private var father:MovieClip;
	public var xspeed:Number;
	public var yspeed:Number;
	//
	//
	//
	public function BallClip ( myRoot:MovieClip )

	{
		//
		father = myRoot;
		//
		graphics.beginFill( 0xff0000 , 1 );
		graphics.drawCircle( 0 , 0 , 20 );
		graphics.endFill( );
		//
		x = 20;
		y = 20;
		//
		xspeed = Math.random( )*5;
		yspeed = Math.random( )*5;
		//
		addEventListener( MouseEvent.MOUSE_DOWN , mouseDownHandler );
		addEventListener( MouseEvent.MOUSE_UP , mouseUpHandler );
		//
	}

	//
	//
	//
	public function step ( timeEvent:TimerEvent ):void
	{
		//
		if ( x + xspeed > 390 ) xspeed *= -1;
		if ( x + xspeed < 10 ) xspeed *= -1;
		if ( y + yspeed > 190 ) yspeed *= -1;
		if ( y + yspeed < 10 ) yspeed *= -1;
		//
		x += xspeed;
		y += yspeed;
		//
	}

	//
	//
	//
	public function mouseDownHandler ( eventOBJ:MouseEvent ):void
	{
		//
		father.dragBall( );
		//
	}

	//
	//
	//
	public function mouseUpHandler ( eventOBJ:MouseEvent ):void

	{
		//
		father.releaseBall( );
		//
	}

	//
	//
	//
}
//
//
//end

Well, this is really fantastic now, but it isn't lifelike, let's use gravity!

private var gravity:Number = 0.5;
//
..
//
//
//
public function step ( timeEvent:TimerEvent ):void

{
	//
	yspeed += gravity;
	//
	if ( x + xspeed > 390 ) xspeed *= -1;
	if ( x + xspeed < 10 ) xspeed *= -1;
	if ( y + yspeed > 190 ) { yspeed -= gravity; yspeed *= -1; }

	if ( y + yspeed < 10 ) yspeed *= -1;
	//
	x += xspeed;
	y += yspeed;
	//
}
//

How does it look like? What?!?! Ugly?!?! Let's put in a Bitmap and a Sound then in part three.


 
 
Name: Milan Toth (MilGra)
Location: Koka, Hungary
Age: 24
Flash experience: 4 years
Job: flash developer/web designer
Website: http://www.tetrapod.ini.hu/
 
 
| Homepage | News | Games | Articles | Multiplayer Central | Reviews | Spotlight | Forums | Info | Links | Contact us | Advertise | Credits |

| www.smartfoxserver.com | www.gotoandplay.biz | www.openspace-engine.com |

gotoAndPlay() v 3.0.0 -- (c)2003-2008 gotoAndPlay() Team -- P.IVA 03121770048