Skip to content


[AS 3] AS Physics Engine (APE) – Car Demo

Playing around a little more I was able (as much as I think) to make a more rigid, possibly more real, way of creating a car. I decided to combine this new class with the Bridge class file I created earlier in the week.

Here is the Main.as Document Class:

package {
	import org.cove.ape.*;

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;

	public class Main extends Sprite {

		private static var colA:uint = 0x333333;
		private static var colB:uint = 0x336699;
		private static var colC:uint = 0x000000;
		private static var boundaryColor:uint = 0x6699aa;
		private static var carColor:uint = 0x336699;
		private static var carOutlineColor:uint = 0x000000;

		private var car:Car;

		public function Main() {

			stage.frameRate = 55;

			// Initialize the engine. The argument here is the time step value.
			// Higher values scale the forces in the sim, making it appear to run
			// faster or slower. Lower values result in more accurate simulations.
			APEngine.init(1/4);

			// set up the default diplay container
			APEngine.container = this;

			// gravity -- particles of varying masses are affected the same
			APEngine.addMasslessForce(new Vector(0, 3));

			// bx:Number, by:Number, yslope:Number; bsize:Number; particleSize:Number, colB:uint, colC:uint, colD:uint
			var bridge:Bridge = new Bridge(-4, 200, 11.9, 55, 5, colA, colB, colC);
			APEngine.addGroup(bridge);

			var bridge2:Bridge = new Bridge(270, 260, .4, 55, 5, colA, colB, colC);
			APEngine.addGroup(bridge2);

			var bridge3:Bridge = new Bridge(545, 262, -80.4, 55, 5, colA, colB, colC);
			APEngine.addGroup(bridge3);

			// the border
			var boundary:Boundary = new Boundary(boundaryColor);
			APEngine.addGroup(boundary);

			car = new Car(carOutlineColor, carColor);

			APEngine.addGroup(car);

			// determine what collides with what.
			car.addCollidableList(new Array(boundary, bridge, bridge2, bridge3));

			stage.addEventListener(KeyboardEvent.KEY_DOWN, key_pressed);
			stage.addEventListener(KeyboardEvent.KEY_UP, key_released);
			addEventListener(Event.ENTER_FRAME, run);
		}

		function key_pressed(event:KeyboardEvent):void {
			var keySpeed:Number = 0.8;

			if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.RIGHT)
			{
				car.speed = keySpeed;
			}

			if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.LEFT)
			{
				car.speed = -keySpeed;
			}
		}

		function key_released(event:KeyboardEvent):void
		{
			car.speed = 0;
		}

		private function run(evt:Event):void {
			APEngine.step();
			APEngine.paint();
		}
	}
}

Here is my Car.as Class:

package {

	import org.cove.ape.*;

	public class Car extends Group {

		private var wheelParticleA:WheelParticle;
		private var wheelParticleB:WheelParticle;

		public function Car(colorOne:uint, colorTwo:uint) {

			wheelParticleA = new WheelParticle(140,30,14,false,2);
			wheelParticleA.setStyle(0, colorOne, 1, colorTwo);
			addParticle(wheelParticleA);
			wheelParticleA.sprite.cacheAsBitmap = true;

			var suspA:CircleParticle = new CircleParticle(140,0,7,false,10);
			suspA.mass = 0.001;
			suspA.setStyle(1, colorOne, 1, colorOne);
			addParticle(suspA);

			wheelParticleB = new WheelParticle(200,30,14,false,2);
			wheelParticleB.setStyle(0, colorOne, 1, colorTwo);
			addParticle(wheelParticleB);
			wheelParticleB.sprite.cacheAsBitmap = true;

			var suspB:CircleParticle = new CircleParticle(200,0,7,false,10);
			suspB.mass = 0.001;
			suspB.setStyle(1, colorOne, 1, colorOne);
			addParticle(suspB);

			var wheelAConnector:SpringConstraint = new SpringConstraint(wheelParticleA, suspB, .7, false, 8);
			wheelAConnector.setStyle(0, colorOne, 1, colorTwo);
			addConstraint(wheelAConnector);

			var shockAConnector:SpringConstraint = new SpringConstraint(wheelParticleA, suspA, .6, false, 8);
			shockAConnector.setStyle(0, colorOne, 1, colorTwo);
			addConstraint(shockAConnector);

			var wheelBConnector:SpringConstraint = new SpringConstraint(wheelParticleB, suspA, 0.5, false, 8);
			wheelBConnector.setStyle(0, colorOne, 1, colorTwo);
			addConstraint(wheelBConnector);

			var bodyConnector:SpringConstraint = new SpringConstraint(suspA, suspB, 0.2, true, 8);
			bodyConnector.setStyle(0, colorOne, 1, colorTwo);
			addConstraint(bodyConnector);

			var shockBConnector:SpringConstraint = new SpringConstraint(wheelParticleB, suspB, .6, false, 8);
			shockBConnector.setStyle(0, colorOne, 1, colorTwo);
			addConstraint(shockBConnector);

			var axelConnector:SpringConstraint = new SpringConstraint(wheelParticleA, wheelParticleB, .7, false, 8);
			axelConnector.setStyle(0, colorOne, 1, colorTwo);
			addConstraint(axelConnector);
		}

		public function set speed(s:Number):void {
			wheelParticleA.angularVelocity = s;
			wheelParticleB.angularVelocity = s;
		}
	}
}

The Bridge.as class file

package {

	import org.cove.ape.*;

	public class Bridge extends Group {

		public function Bridge(bx:Number, by:Number, yslope:Number, bsize:Number, particleSize:Number, colB:uint, colC:uint, colD:uint) {	

			var bridgePAA:CircleParticle = new CircleParticle(bx,by,particleSize,true);
			bridgePAA.setStyle(1, colC, 1, colB);
			addParticle(bridgePAA);

			bx += bsize;
			by += yslope;
			var bridgePA:CircleParticle = new CircleParticle(bx,by,particleSize);
			bridgePA.setStyle(1, colC, 1, colB);
			addParticle(bridgePA);

			bx += bsize;
			by += yslope;
			var bridgePB:CircleParticle = new CircleParticle(bx,by,particleSize);
			bridgePB.setStyle(1, colC, 1, colB);
			addParticle(bridgePB);

			bx += bsize;
			by += yslope;
			var bridgePC:CircleParticle = new CircleParticle(bx,by,particleSize);
			bridgePC.setStyle(1, colC, 1, colB);
			addParticle(bridgePC);

			bx += bsize;
			by += yslope;
			var bridgePD:CircleParticle = new CircleParticle(bx,by,particleSize);
			bridgePD.setStyle(1, colC, 1, colB);
			addParticle(bridgePD);

			bx += bsize;
			by += yslope;
			var bridgePDD:CircleParticle = new CircleParticle(bx,by,particleSize,true);
			bridgePDD.setStyle(1, colC, 1, colB);
			addParticle(bridgePDD);

			var bridgeConnA:SpringConstraint = new SpringConstraint(bridgePAA, bridgePA,
					0.9, true, 10, 0.8);

			// collision response on the bridgeConnA will be ignored on
			// on the first 1/4 of the constraint. this avoids blow ups
			// particular to springcontraints that have 1 fixed particle.
			bridgeConnA.fixedEndLimit = 0.25;
			bridgeConnA.setStyle(1, colC, 1, colB);
			addConstraint(bridgeConnA);

			var bridgeConnB:SpringConstraint = new SpringConstraint(bridgePA, bridgePB,
					0.9, true, 10, 0.8);
			bridgeConnB.setStyle(1, colC, 1, colB);
			addConstraint(bridgeConnB);

			var bridgeConnC:SpringConstraint = new SpringConstraint(bridgePB, bridgePC,
					0.9, true, 10, 0.8);
			bridgeConnC.setStyle(1, colC, 1, colB);
			addConstraint(bridgeConnC);

			var bridgeConnD:SpringConstraint = new SpringConstraint(bridgePC, bridgePD,
					0.9, true, 10, 0.8);
			bridgeConnD.setStyle(1, colC, 1, colB);
			addConstraint(bridgeConnD);

			var bridgeConnE:SpringConstraint = new SpringConstraint(bridgePD, bridgePDD,
					0.9, true, 10, 0.8);
			bridgeConnE.fixedEndLimit = 0.25;
			bridgeConnE.setStyle(1, colC, 1, colB);
			addConstraint(bridgeConnE);
		}
	}
}

The Boundary.as class file so the car will not drive off the screen

package {

	import org.cove.ape.*;

	public class Boundary extends Group {

		public function Boundary(boundaryColor:uint) {
			// RectangleParticle - x, y, width, height
			var floor:RectangleParticle = new RectangleParticle(350,299,700,1,0,true);
			floor.setStyle(0, boundaryColor, 1, boundaryColor);
			addParticle(floor);

			var leftWall:RectangleParticle = new RectangleParticle(1,250,1,500,0,true);
			leftWall.setStyle(0, boundaryColor, 1, boundaryColor);
			addParticle(leftWall);

			var rightWall:RectangleParticle = new RectangleParticle(699,250,1,500,0,true);
			rightWall.setStyle(0, boundaryColor, 1, boundaryColor);
			addParticle(rightWall);
		}
	}
}

Posted in APE - Actionscript Physics Engine, Actionscript 3.


3 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Pim says

    Hi Morgan,

    i just started to play around with APE and must say your tutorials are extremely useful!

    Tnx for providing them :)

Continuing the Discussion

  1. APE Project - Step 4 - Adding a Car | actionscript 3 | morgan newcomb, website and flash developer, burlington, vermont linked to this post on August 8, 2008

    [...] I pulled a Car class from an older project of mine and decided to integrate it into my project here…. gotta love the ease of integration of [...]

  2. APE Project - Step 8 - Adding a Fixed Bridge | actionscript 3 | morgan newcomb, website and flash developer, burlington, vermont linked to this post on August 15, 2008

    [...] a few past experiments [1 | 2 ] I wanted to add a bridge to my movie here. For [...]



Some HTML is OK

or, reply to this post via trackback.