APE - Actionscript Physics Engine tutorial - Part 2
Filed Under Flash •
I've been playing a lot with APE in the last days, so I am ready to write another tutorial.
I strongly recommend you to read the first part before continuing.
The first thing I wanted to do is having the APE environment working on Flash CS3 instead of Flex.
It's very easy: when you create a new Flash file (Actionscript 3), just go to "Publish Settings", then "Flash -> Settings" then "Browse to Path" and then select the path to your ape_a045\source directory
Look at the picture and follow the 6 steps:

Now you are redy to execute APE files on Flash CS3, but it's not over. In order to get the funniest features of APE, you have to update the current alpha 0.45 to the one you will find in the "trunk" of the code repository. Simply go to this link, and overwrite your files with the ones you find there.
Now you are really ready to rumble!
In the experiment I made I created 3 Movie Clips in my library: two squares with a gradient fill to use as background (linked as back and back_win), and a circle with another gradient to represent the wheel (linked as tire).
Then, as usual, my actionscript, all in the first frame:
-
import org.cove.ape.*;
-
import flash.events.Event;
-
import flash.events.KeyboardEvent;
-
import flash.display.Sprite;
-
-
// listeners
-
addEventListener(Event.ENTER_FRAME, run);
-
stage.addEventListener(KeyboardEvent.KEY_DOWN, key_pressed);
-
stage.addEventListener(KeyboardEvent.KEY_UP, key_released);
-
-
// importing background
-
var backgr:Sprite = new back();
-
var backgr_win:Sprite = new back_win();
-
this.addChild(backgr);
-
-
// wheels graphic
-
var tireA:tire=new tire();
-
var tireB:tire=new tire();
-
-
// ape init
-
APEngine.init(1/4);
-
APEngine.container = this;
-
APEngine.addForce(new VectorForce(false,0,2));
-
var defaultGroup:Group = new Group();
-
defaultGroup.collideInternal = true;
-
var cp:CircleParticle = new CircleParticle(250,10,5,false,90);
-
defaultGroup.addParticle(cp);
-
var cp2:CircleParticle = new CircleParticle(240,183,3,true);
-
defaultGroup.addParticle(cp2);
-
var rp:RectangleParticle = new RectangleParticle(350,300,100,10,0,true);
-
defaultGroup.addParticle(rp);
-
rp.sprite.name = "floor";
-
var rp2:RectangleParticle = new RectangleParticle(150,200,200,10,-0.1,true);
-
defaultGroup.addParticle(rp2);
-
var rp3:RectangleParticle = new RectangleParticle(300,50,300,10,0,true);
-
defaultGroup.addParticle(rp3);
-
var rp4:RectangleParticle = new RectangleParticle(120,55,30,30,0,true);
-
defaultGroup.addParticle(rp4);
-
var wa: WheelParticle = new WheelParticle(160,20,10,false,2);
-
defaultGroup.addParticle(wa);
-
var wb: WheelParticle = new WheelParticle(200,20,10,false,2);
-
defaultGroup.addParticle(wb);
-
var wc:SpringConstraint = new SpringConstraint(wa, wb, 0.5, true, 1);
-
defaultGroup.addConstraint(wc);
-
-
// styles and displays
-
rp.setStyle(0, 0x000000, 1, 0xff0000,0.5);
-
rp2.setStyle(0, 0x000000, 1, 0x000000,0.5);
-
rp3.setStyle(0, 0x000000, 1, 0x000000,0.5);
-
rp4.setStyle(0, 0x000000, 1, 0x000000,0.5);
-
cp.setStyle(0, 0x000000, 1, 0x000000,0.5);
-
cp2.setStyle(0, 0x000000, 1, 0x000000,0.5);
-
wb.setDisplay(tireB);
-
wa.setDisplay(tireA);
-
-
APEngine.addGroup(defaultGroup);
-
var win = false;
-
-
// ape listeners
-
wa.addEventListener(CollisionEvent.COLLIDE, check_coll);
-
wb.addEventListener(CollisionEvent.COLLIDE, check_coll);
-
-
function check_coll(e:CollisionEvent):void {
-
var collided = e.collidingItem.sprite.name;
-
if (collided=="floor") {
-
if(!win){
-
this.addChild(backgr_win);
-
win = true;
-
}
-
}
-
}
-
-
function key_pressed(event:KeyboardEvent):void {
-
if (event.keyCode == Keyboard.UP) {
-
wa.angularVelocity = 0.1;
-
wb.angularVelocity = 0.1;
-
}
-
if (event.keyCode == Keyboard.DOWN) {
-
wa.angularVelocity =- 0.1;
-
wb.angularVelocity =- 0.1;
-
}
-
}
-
-
function key_released(event:KeyboardEvent):void {
-
wa.angularVelocity = 0;
-
wb.angularVelocity = 0;
-
}
-
-
function run(evt:Event):void {
-
APEngine.step();
-
APEngine.paint();
-
}
Lines 1-4: Importing required libraries (only the one at line 1 is not included in the CS3 package and it's APE itself)
Line 7: Adding the enter frame listener as explained in the first part
Lines 8-9: Adding listeners to keyboard events: I want to determine when a key is down and when a key is up. When it's down, I will call the key_pressed function and if it's up I will call the key_released function.
Line 12: Assigning the back object to a new sprite called backgr
Line 13: Same thing for the back_win object assigned to backr_win sprite
Line 14: Putting the backr sprite on stage
Lines 17-18: Creating to new objects of tire type (a new type invented by me) as instances of the tire MovieClip I created. They will represent tires graphic
Lines 21-22: Initializing APE engine as seen on the first part.
Line 23: This is the same of adding a massless force as explained in first part, but in the "trunk" version of APE addMasslessForce does not work anymore so you have to use VectorForce. The three parameters define if the force is massles (false) or not (true), the horizontal force and the vertical one.
Lines 24-44: Adding particles and constraints as seen in the first part, with the exception of line 32 where I call one rectangle particle as "floor".
Lines 47-52: Setting the styles of display of the particles I created. Let's examine the setStlye parameters:
lineThickness:Number (default = 0)
lineColor:uint (default = 0x000000)
lineAlpha:Number (default = 1)
fillColor:uint (default = 0xffffff)
fillAlpha:Number (default = 1)
Lines 53-54: Attaching tire sprites to wheels. Let's examine the setDisplay parameters:
d:DisplayObject
offsetX:Number (default = 0)
offsetY:Number (default = 0)
rotation:Number (default = 0)
Line 56: Adding the group to the APE engine as seen in first part.
Line 57: Setting a boolean win variable to false. It's a game, so I have to check if the player wins
Lines 60-61: this listener is a brand new feature of the "trunk" version. I am listening if one of the wheels collide to another particle, and if true I call the check_coll function.
Line 63: Beginning of the check_coll function
Line 64: A variable called "collided" is set to the name of the particle the wheel collided with
Line 65: If a wheel collided to the rectangle object called "floor" (line 32)...
Lines 66-69: Set the win variable to true and display the other background, the one I reserved for the victory. Please notice that when you win, you won't see the simulation anymore, but it's still running. I'll explain how to stop and reset the simulation in a future tutorial.
Line 73: Beginning of the function to be executed every time a key is pressed
Lines 74-77: If the player presses the "UP" key, I set the angular velocity of both wheels to 0.1
Lines 78-81: If the player presses the "DOWN" key, I set the angular velocity of both wheels to -0.1
Line 84: Beginning of the function to be called every time a key is released
Lines 85-86: Setting the angular velocity of both wheels to zero
Lines 89-92: Beginning of the simulation itself as explained in first part.
And it's done! In this game you have to drive your "car" with UP and DOWN arrows and touch with a wheel the red platform
If you fall off the screen, you will have to reload the window.
This is the source code of this little game and this is the trunk version of APE in case you're too lazy to download it by yourself. Give me feedback while I prepare the next round...
Tell me what do you think about this post. I'll write better and better entries.
They can be easily customized to meet the unique requirements of your project.
28 Responses to “APE - Actionscript Physics Engine tutorial - Part 2”
Leave a Reply

[...] 23rd update: Part 2 [...]
Wow, u are so amazing cant wait for the next tuts o man u are so cool
does this actionscript work in Actionscript 2.0?
i have Falsh MX (7)
briliant tutorial anyway
It works only with Flash CS3
Anyway, you can download a full 30 days evaluation version at Adobe site.
This is great! I tried it out and it worked perfectly. I even managed to change around the terrain.
is there a way to make this work in flash 6? thanks
look at this site
http://www.cove.org/flade/
i was so cool! but it only works in flash CS3
:( will u stop doing tutorials in AS 2 becoz i have mx 7 and i can’t d’load flash CS3..
I won’t stop writing tuts in AS2 because at the moment most people have an AS2 version.
But I think this is going to change in about a year.
a year… i think all will get flash cS3 till then,right now i can’t d’load the trial too,coz that will be of more than 100mb and can u expect someone to d’load 100mb at a downloading rate on 10kb per second.. :)
Can someone tell me how i can draw something and make it a particle? How do i do that?
Emanuele,
I have run into a strange problem. I have been working with APE on one of my computers in CS# and everything is working perfect. But when I moved my project to another machine, I got this error:
-Infinity
TypeError: Error #1009: Cannot access a property or method of a null object reference.
I have the APE class on the new machine, so I can’t seem to think of what might be causing this. Have you run ino this yet?
ive run into a similar problem:
1046: Type was not found or was not a compile-time constant: CollisionEvent.
adam: you get this error if you use an APE version different than the one in the trunk.
Check the final part of the post to understand what I am talking about
I keep getting:
1046: Type was not found or was not a compile-time constant: CollisionEvent.
no matter how hard I try I cannot get your second experiment to play.. I know you talked about the trunk and all of that but could you elaborate more?
hello ther i do have the same message
1046: Type was not found or was not a compile-time constant: CollisionEvent.
…in french but it is actually the same message.
I just downloaded the ape 0.45 trunk but i don’t understand why this doesn t work..
Maybe some classes were removed… but i still can’t make it work
Very useful tutorial. Thanks! In part 2 you should mention that the docs for the original 0.45 are no longer entirely accurate for the current cvs version. And, since the author doesn’t say so in the docs, that the rotation of a rectangle particle is measured in radians.
Hi. i was gettign the same 1046 error. i put the shape i wanted to test for a collision in a class like this and it worked fine.
package src
{
import org.cove.ape.*;
public class Exit extends Group
{
public function Exit ()
{
var exit:RectangleParticle = new RectangleParticle(650, 444, 50, 100, 0, true);
addParticle (exit);
exit.addEventListener (CollisionEvent.COLLIDE, checkColl);
}
private function checkColl (e:CollisionEvent):void
{
trace (”hit”);
}
}
}
hi,
I get it to run but nothing happens, no balls roll off the screen or anything…
if you get the error:
Scene1,Layer “layer 1″, Frame 1, Line64
the error that you get 1046:Type was not found or was not a compile-time constant:CollisionEvent
you havent set up the paths to APE correctly
to fix this:
publish settings -> actionscript 3.0 settings -> add the destination to the APE classes.
should fix the problem
Clark
clark, maybe you forgot to press (and hold) up or down key? :)
Great tutorial, thanks! Tell me if this make sense: I noticed that a circle and a wheel with the same properties will accelerate differently on the same downward slope and constant gravity force - the circle lags behind. I think this is due to the lack of ‘traction’ for the wheel.
Is there a setting that I am missing somewhere that cause the circle to lag? Do you see any downside of using disconnected wheels instead of circles (for free moving round objects)?
Thanks, Stan
sorry meant to say ‘lack of traction for the circle’ in the comment above…
id like to thank you, this just got me through the first hurdle of AS3
Very Interesting tutorial :-)
Actually im doing my collegeproject on a simulation of traffic flow along a road in flash ..:-(( and was wondering if i could have some guidelines from you concerning that..id be very grateful! Thank you
After a lot of search, i have found your site, and those valuable basic tutorial on “APE”… Thank you very much !
[...] You can also find two tutorials on my blog here and here [...]
You can get this for AS2.