APE – Actionscript Physics Engine tutorial – Part 2

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:

Flex to Flash

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();

// wheels graphic
var tireA:tire=new tire();
var tireB:tire=new tire();

// ape init
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);
var cp2:CircleParticle = new CircleParticle(240,183,3,true);
var rp:RectangleParticle = new RectangleParticle(350,300,100,10,0,true);
rp.sprite.name = "floor";
var rp2:RectangleParticle = new RectangleParticle(150,200,200,10,-0.1,true);
var rp3:RectangleParticle = new RectangleParticle(300,50,300,10,0,true);
var rp4:RectangleParticle = new RectangleParticle(120,55,30,30,0,true);
var wa: WheelParticle = new WheelParticle(160,20,10,false,2);
var wb: WheelParticle = new WheelParticle(200,20,10,false,2);
var wc:SpringConstraint = new SpringConstraint(wa, wb, 0.5, true, 1);

// 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);

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") {
			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 {

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:


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…

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers