WOW-Engine is an ActionScript 3.0 open source library which allows you to simulate real world physics (like in racing games for example) in your applications. The WOW engine calculates only the interactions within physic objects and you need an 3D engine to visualize the results. In this tutorial I use the Sandy 3D engine because WOW is based on Sandy. You can use any other 3D library, its simple, all you have to do its to link the objects from WOW-Engine to 3D visualizer objects.

ActionScript is giving us a huge field for researches and programmers exploit this field with diligence. Few years ago I made an 3D engine in ActionScript 2.0. At that point in time the 3D engines like Papervision wasnt existing yet or they was only coming to existence. Now we have more engines like Papervision, Sandy, Away3D and many others. Whats the next step? WOW-Engine is simulating real 3D world physics and it can be used with any of 3D visualizing engines.

In this article I will describe making of a simple game using WOW-Engine. I will cover rather matters that you cant find in any other tutorials but I will provide links to all necessary tutorials you need to get complete cover of the theme.

Sandy is a Flash 3D engine we will use in this game. Here is the tutorial about installing and setting the Sandy: http://www.flashsandy.org/tutorials/3.0/install_sandy_flash_cs3
You can find tens of tutorials about Sandy here: http://www.flashsandy.org/tutorials/3.0

WOW-Engine is a free AS3 open source physics engine written by Seraf ( Jérôme Birembaut ) capable to handle positions in a 3D environment. Here is the oficial home page of the WOW: http://seraf.mediabox.fr/wow-engine
And here is the tutorial how to install and set it: http://www.flashsandy.org/tutorials/3.0/sandy_cs3_tut30

Installing this engines is really simple, you can do it in few minutes and lets start making the game. I am sure all of you have seen games with physics simulation, like racing cars, or arcades, almost all games use the physics. The point of our game is pulling the red rubber balls out of the green boundary by hitting them with the yellow ball and manipulating the hits strength and direction. The blue balls must stay within the green boundary.

Here is the game we are going to create:

So lets import the necessary classes:

package {
import flash.display.Sprite
import flash.text.*
import flash.events.*
import flash.ui.*
//Sandy classes
import sandy.core.Scene3D
import sandy.core.data.*
import sandy.core.scenegraph.*
import sandy.materials.*;
import sandy.materials.attributes.*;
import sandy.primitive.*
//wow engine classes
import fr.seraf.wow.primitive.*
import fr.seraf.wow.core.WOWEngine
import fr.seraf.wow.core.data.WVecto

After that we start constructing our WowGame class:

public class WowGame extends Sprite  {
var wow:WOWEngine
var wowSphere:WSphere, wowSphere2:WSphere, wowSphere3:WSphere
var wowSphere4:WSphere, wowSphere5:WSphere
var wowBound:WBoundArea
var scene:Scene3D, camera:Camera3D
var cameraAngle:Number=.18, cameraRadius:Number=-700
var objectsTransformGroup:TransformGroup
var mySphere:Sphere, mySphere2:Sphere, mySphere3:Sphere, mySphere4:Sphere, mySphere5:Sphere
var redPhong:Appearance, bluePhong:Appearancevar bottom:Plane3D
var sceneWidth:Number=550, sceneHeight:Number=720
var alteration:String="stage"
var textF:TextField=new TextField
var textF2:TextField=new TextField
var directionArray:Array=new Array()
var rootScene:Group
var hitStrength:uint=200
var gameStopped:Boolean=falsepublic function WowGame()  {
setText("begin")
textF.width=250
textF.x=5; textF.y=5
textF.height=150
textF.width=350
textF.multiline=true
textF.wordWrap=true
addChild(textF)
textF2.width=250
textF2.x=350; textF2.y=5
textF2.height=150
textF2.width=350
textF2.multiline=true
textF2.wordWrap=true
textF2.text="Pull the red speres out of the green line\n"
textF2.appendText("The yellow sphere and the blue ones\n")
textF2.appendText("cant cross the green line\n")
textF2.appendText("Press ENTER to reset")
addChild(textF2)
camera = new Camera3D(sceneWidth, sceneHeight)
// We create the "group" that is the tree of all the visible objects
rootScene = createScene()
scene = new Scene3D( "scene", this, camera, rootScene )
addEventListener( Event.ENTER_FRAME, enterFrameHandler )
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed) }
// Create the scene graph based on the root Group of the scene
function createScene():Group {
    camera.y = 580
    camera.z = cameraRadius
    camera.x=Math.sin(cameraAngle) * cameraRadius
    camera.z=Math.cos(cameraAngle) * cameraRadius
    camera.lookAt(0,-380,0) };

Now we are inside the “createScene” function. Here are created the main elements of the game.
The Wow engine, the Wow spheres and we also put Wow bound area wich presents a cube. You cant see this cube in game but if you will pull a ball too far you will see it will impinge something.
After Wow goes the Sandy main group with all objects. Notice that here is created the ball which will be hitted when you will press the Space key. Its name is “mySphere”. It is included in the TransformGroup which also include the arrow which show the direction and the strength of the hit.

wow=new WOWEngine();
// SELECTIVE is better for dealing with lots of little particles colliding,
wow.collisionResponseMode = wow.SELECTIVE
wow.addMasslessForce(new WVector(0,12,0))
// values of the wowSphere are the x,y,z, radius, fixed, mass, ellasticity, friction
wowSphere = new WSphere(-180, -150, -180, 25, false, 1, 1)
wow.addParticle(wowSphere)
wowSphere2 = new WSphere(-30, 335, 30, 25, false, 1, 1)
wow.addParticle(wowSphere2)
wowSphere3 = new WSphere(-30, 335, -30, 25, false, 1, 1)
wow.addParticle(wowSphere3)
wowSphere4 = new WSphere(30, 335, 30, 25, false, 1, 1)
wow.addParticle(wowSphere4)
wowSphere5 = new WSphere(30, 335, -30, 25, false, 1, 1)
wow.addParticle(wowSphere5)wowBound = new WBoundArea(sceneWidth*2, sceneHeight, sceneWidth*2);
wowBound.elasticity=1
wowBound.friction=0
wow.setBoundArea(wowBound)// Create the root Group
var mainGroup:Group = new Group()
// We need to create a transformGroup
objectsTransformGroup = new TransformGroup('myGroup')var wireMaterial:Material = new WireFrameMaterial(2,0xff0000)
var wireApp:Appearance = new Appearance(wireMaterial)
for(var i:int=-1;i<7;i++){
var tempLine:Line3D=new Line3D(null, new Point3D(i*10, 0, 0),
new Point3D( (i+1)*10, 0, 0) )
tempLine.appearance=wireApp
tempLine.useSingleContainer = false
objectsTransformGroup.addChild(tempLine)
directionArray[i]=tempLine  }
var tempDirLine:Line3D=new Line3D(null, new Point3D(70, 0, 0),
new Point3D( 55, 0, -10) )
tempDirLine.appearance=wireApp
tempDirLine.useSingleContainer = false
objectsTransformGroup.addChild(tempDirLine)
directionArray[7]=tempDirLine
var tempDirLine2:Line3D=new Line3D(null, new Point3D(70, 0, 0),
new Point3D( 55, 0, 10) )
tempDirLine2.appearance=wireApp
tempDirLine.useSingleContainer = false
objectsTransformGroup.addChild(tempDirLine2)
directionArray[8]=tempDirLine2

Here ends the construction of the direction arrow. As you see it consist of multiple element. I do so for better visualising. When rendering the scene the render machine counts the polygons and the lines in base of its points. If I would make a single line intersecting the sphere it would be rendered sometimes fully in front and sometimes behind the sphere. The line consisting of multiple objects is being rendered correctly. The directionArray includes all the elements of the arrow. Later we will use this array to move the arrow depending of the hit strength. Next goes the balls construction.

mySphere = new Sphere( "theObj2", 25, 8, 8 )
mySphere2 = new Sphere( "theObj2", 25, 8, 8 )
mySphere3 = new Sphere( "theObj2", 25, 8, 8 )
mySphere4 = new Sphere( "theObj2", 25, 8, 8 )
mySphere5 = new Sphere( "theObj2", 25, 8, 8 )// we define a new material
var phongAttribute:PhongAttributes = new PhongAttributes (true, 0.2, 2)
var materialAttr:MaterialAttributes = new MaterialAttributes( phongAttribute )
var ballMaterial:Material = new ColorMaterial(0xffff00, 1, materialAttr)
ballMaterial.lightingEnable = true
var ballApp:Appearance = new Appearance(ballMaterial )var blueMaterial:Material = new ColorMaterial(0x0000ff, 1, materialAttr)
blueMaterial.lightingEnable = true
bluePhong = new Appearance( blueMaterial)var redMaterial:Material = new ColorMaterial(0xff0000, 1, materialAttr)
redMaterial.lightingEnable = true
redPhong = new Appearance(redMaterial)mySphere.appearance = ballApp
mySphere.useSingleContainer = falsemySphere2.appearance = bluePhong
mySphere3.appearance = redPhong
mySphere4.appearance = redPhong
mySphere5.appearance = bluePhong
var lightAttr:MaterialAttributes = new MaterialAttributes( new LightAttributes( true, 0.4),
new LineAttributes( 1, 0x888888, 1 ),
new OutlineAttributes(3, 0x00AA00, 1))
var bottomMaterial:Material = new ColorMaterial(0x000000, 1, lightAttr)
var bottomApp:Appearance = new Appearance( bottomMaterial )
bottom = new Plane3D( "thePlane", sceneWidth, sceneWidth, 3, 3, Plane3D.ZX_ALIGNED, "quad" )
bottom.y = -sceneHeight/2
bottom.appearance=bottomApp
bottom.enableForcedDepth = true
bottom.forcedDepth = 9999999999998
// we now add all the object to the root group:
objectsTransformGroup.addChild(mySphere)
mainGroup.addChild(bottom)
mainGroup.addChild(objectsTransformGroup)
mainGroup.addChild(mySphere2)
mainGroup.addChild(mySphere3)
mainGroup.addChild(mySphere4)
mainGroup.addChild(mySphere5)
objectsTransformGroup.rotateY=38
return mainGroup       }

Next goes the enterFrameHandler. The important matter when using a physics engine with a 3D engine is linking the objects from physics engine to 3D objects. This way in every frame the 3D spheres takes the positions of the Wow spheres.
Also the enterFrameHandler verifies if the red spheres are out of the boundary they have to pass. If a red sphere passes the green boundary it becomes blue and if the blue sphere passes the boundary it becomes red. When all spheres are blue the winning function is shooted. If the yellow sphere goes out of boundary the endGame function goes on.

function enterFrameHandler(event:Event):void{
    wow.step()
    objectsTransformGroup.x=wowSphere.px
    objectsTransformGroup.y=-wowSphere.py
    objectsTransformGroup.z=wowSphere.pz
    mySphere2.x=wowSphere2.px
    mySphere2.y=-wowSphere2.py
    mySphere2.z=wowSphere2.pz
    mySphere3.x=wowSphere3.px
    mySphere3.y=-wowSphere3.py
    mySphere3.z=wowSphere3.pz
    mySphere4.x=wowSphere4.px
    mySphere4.y=-wowSphere4.py
    mySphere4.z=wowSphere4.pz
    mySphere5.x=wowSphere5.px
    mySphere5.y=-wowSphere5.py
    mySphere5.z=wowSphere5.pz
    if(!gameStopped){checkGame()}
    scene.render()  };
function checkGame():void{
    if(mySphere2.x>sceneWidth/2||mySphere2.x<-sceneWidth/2||
    mySphere2.z>sceneWidth/2||mySphere2.z<-sceneWidth/2){
    mySphere2.appearance=redPhong}else{mySphere2.appearance=bluePhong}
    if(mySphere3.x>sceneWidth/2||mySphere3.x<-sceneWidth/2||
                    mySphere3.z>sceneWidth/2||mySphere3.z<-sceneWidth/2){
        mySphere3.appearance=bluePhong}else{mySphere3.appearance=redPhong}
    if(mySphere4.x>sceneWidth/2||mySphere4.x<-sceneWidth/2||
                    mySphere4.z>sceneWidth/2||mySphere4.z<-sceneWidth/2){
        mySphere4.appearance=bluePhong}else{mySphere4.appearance=redPhong}
    if(mySphere5.x>sceneWidth/2||mySphere5.x<-sceneWidth/2||
                    mySphere5.z>sceneWidth/2||mySphere5.z<-sceneWidth/2){
        mySphere5.appearance=redPhong}else{mySphere5.appearance=bluePhong}
    if(objectsTransformGroup.x>sceneWidth/2||objectsTransformGroup.x<-sceneWidth/2||
                    objectsTransformGroup.z>sceneWidth/2||
                    objectsTransformGroup.z<-sceneWidth/2){
        endGame() }
if(mySphere2.appearance==bluePhong&&mySphere3.appearance==bluePhong&&
                             mySphere4.appearance==bluePhong&&mySphere5.appearance==bluePhong){
    winning()}  };

In next lines of code we will set the behavior on pressing the keys. We have two modes, in first one pressing the LEFT RIGHT UP DOWN arrows we move the camera and this way we rotate the scene view right and left and zoom it in and out. I done the camera rotation using trigonometry formulas. I described this formulas detailed in my blog http://alexgblog.com
Pressing the CONTROL key we get in the second mode wherein we change the hit parameters, pressing RIGHT and LEFT arrows we change the direction and pressing UP and DOWN keys we change the strength of the hit.
Pressing SPACE we make the hit and the ENTER key resets the game.

function keyPressed(event:KeyboardEvent):void {
if(alteration=="stage"){
    switch(event.keyCode) {
        case Keyboard.UP:
            camera.y-=8
            if(camera.y<100){camera.y=100}
            camera.lookAt(0,-380,0); break
        case Keyboard.DOWN:
            camera.y+=8
            if(camera.y>1000){camera.y=1000}
            camera.lookAt(0,-380,0); break
        case Keyboard.RIGHT:
            cameraAngle-=.02
            camera.x=Math.sin(cameraAngle) * cameraRadius
            camera.z=Math.cos(cameraAngle) * cameraRadius
            camera.lookAt(0,-380,0); break
        case Keyboard.LEFT:
            cameraAngle+=.02
            camera.x=Math.sin(cameraAngle) * cameraRadius
            camera.z=Math.cos(cameraAngle) * cameraRadius
            camera.lookAt(0,-380,0); break
        case Keyboard.ENTER:
            reset(); break
        case Keyboard.CONTROL:
            setText(alteration);break
        case Keyboard.SPACE:
            hitBall();break} }
else{
    switch(event.keyCode) {
        case Keyboard.UP:
            if(hitStrength<500){
                hitStrength+=10
                for(var t:int=-1;t<9;t++){
                    directionArray[t].x++} }; break
        case Keyboard.DOWN:
            if(hitStrength>100){
                hitStrength-=10
                for(var r:int=-1;r<9;r++){
                    directionArray[r].x--} }; break
        case Keyboard.RIGHT:
            objectsTransformGroup.rotateY -=2; break
        case Keyboard.LEFT:
            objectsTransformGroup.rotateY +=2; break
        case Keyboard.ENTER:
            reset(); break
        case Keyboard.CONTROL:
            setText(alteration);break
        case Keyboard.SPACE:
            hitBall(); break} }		};
function setText(altMode:String):void{
    if(altMode=="stage"){alteration="ball"
        textF.text="CHANGE BALL HIT PARAMETERS mode \n"
        textF.appendText("press LEFT RIGHT for rotating the hit vector\n")
        textF.appendText("press UP DOWN for incresing hit power in and out\n")
        textF.appendText("press CONTROL to change the mode\n")
        textF.appendText("press SPACE to hit the ball\n") }
    else{alteration="stage"
        textF.text="CHANGE THE SCENE VIEW mode\n"
        textF.appendText("press LEFT RIGHT for rotate\n")
        textF.appendText("press UP DOWN for zoom\n")
        textF.appendText("press CONTROL to change the mode\n")
        textF.appendText("press SPACE to hit the ball\n")}  };
function hitBall():void{
    var angleInRadians=objectsTransformGroup.rotateY*Math.PI/180
    var zHit:Number=Math.sin(angleInRadians) * hitStrength
    var xHit:Number=Math.cos(angleInRadians) * hitStrength
    wowSphere.addForce( new WVector( xHit, 0, zHit) )};function endGame():void{
    textF2.text="You lost\n"
    textF2.appendText("The yellow sphere and the blue ones\n")
    textF2.appendText("cant cross the green line\n")
    textF2.appendText("Press ENTER to reset")};function winning(){
    gameStopped=true
    textF2.text="YOU WON!!!\n"
    textF2.appendText("Press ENTER to reset")};function reset():void{ trace("RESET")
    wowSphere.px = -180
    wowSphere.py = -150
    wowSphere.pz = -180
    wowSphere2.px = -30
    wowSphere2.py = 335
    wowSphere2.pz = 30
    wowSphere3.px = -30
    wowSphere3.py = 335
    wowSphere3.pz = -30
    wowSphere4.px = 30
    wowSphere4.py = 335
    wowSphere4.pz = 30
    wowSphere5.px = 30
    wowSphere5.py = 335
    wowSphere5.pz = -30};
} }

The game I made is simplier than I wanted initially. Its not about making economy of paper only but also because of the Wow engine is far far from being perfect or even finished. For example the WowPlane can be only infinite, if you want to make a shelve you cant do it. Also the WowBox has very strange rotation properties, you cant really use it. Right now it is being developed the Wow-Engine 2.0, probably in the second version Seraf will fix this issues but he write on his blog that he is sick of physics, probably he needs some rest. I can imagine you are not satisfied with this and I found that what you need. There is an almost perfect physics engine for C# called JigLib and it was recently ported to ActionScript 3.0. In next articles I will talk about JigLibFlash, also I could talk about gameplay creation or games programming depending on your comments. The source for the game is here