[Flash 10]

MArs 2014

How to build a billiard game with Flash regular display list

A great billiard game that use stage3D (flash 11+) and probably away physics

But what if you cannot target stage3D ?

Here is the “final preview”

[swfobj src=”https://yopsolo.fr/ressources/pool-game-step-preview.swf” alt=”Animation Flash” width=”721″ height=”486″ class=”flashObject” AllowScriptAccess=”always” allowfullscreen=”false” bgcolor=”#ffffff” required_player_version=”10″]

And how to build it in 3 steps:

  • physics
  • rendering using native 3D
  • sync 2D physics and 3D redering.

STEP 1 – Physics
We will use box2d, in order to to speed up the set up there is a great tool known as quick Box2D

simBalls = new Vector.<quickobject>;</quickobject>

// create the simulation view
simView = new MovieClip();
sim = new QuickBox2D(simView);

// adding it to the stage
addChild( simView );
// a quick command to create 4 walls based on Stage size
sim.createStageWalls();
// we are in 2D with a top down view so gravity is null
sim.gravity = new b2Vec2();
sim.grid(25, 0xCCCCCC, .5);

// creating 16 balls
var bb:QuickObject;
for (var j:int = 0; j &lt; NB_BALLS ; ++j ) 
{
	bb = sim.addCircle( { x:Math.random() * 640/30, y: Math.random() * 480/30, radius:.5,  isBullet:true } ); // choose a random position on the board
	bb.body.ApplyImpulse( new b2Vec2( (Math.random() * 30) - 15, (Math.random() * 30) - 15), bb.body.GetPosition() ); // apply an impulse on each body
	simBalls.push( bb ); // keep a reference to that body
}

// start the simulation
sim.start();
// all balls are draggable
sim.mouseDrag();	

[swfobj src=”https://yopsolo.fr/ressources/pool-game-step-1-physics.swf” alt=”Animation Flash” width=”640″ height=”480″ class=”flashObject” AllowScriptAccess=”always” allowfullscreen=”false” bgcolor=”#ffffff” required_player_version=”10″]

STEP 2 – 3D

You can easily create a Ball3D class based on alumican’s experiments or saharan

package game
{
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;

/**
* ...
* @author YopSolo
*/
public class Ball3D extends Sprite
{
private var _sphere:Sphere;

public function Ball3D(texture:BitmapData, radius:int = 30, x:Number = 0, y:Number = 0)
{

this.x = x;
this.y = y;

this.mouseChildren = false;
this.mouseEnabled = false;

_sphere = addChild(new Sphere(texture, radius, 16, 12)) as Sphere;
_sphere.render();
}

public function rot(rAngleX:Number, rAngleY:Number):void
{
_sphere.rotateByQuaternion(rAngleX, rAngleY, 0, false);
_sphere.render();
}

}

}

[swfobj src=”https://yopsolo.fr/ressources/pool-game-step-2-3D.swf” alt=”Animation Flash” width=”640″ height=”480″ class=”flashObject” AllowScriptAccess=”always” allowfullscreen=”false” bgcolor=”#ffffff” required_player_version=”10″]

STEP 3 – SYNC 3D dispaly and 2D physics

Finally, in the update loop it’s time to sync the display to the physic engine.

private function _oef(e:Event):void
{
var ball:Ball3D;
for (var i:int = 0; i < NB_BALLS; i++)
{
ball = balls[i] as Ball3D;
ball.x = simBalls[i].x * 30;
ball.y = simBalls[i].y * 30;
ball.rot( -simBalls[i].body.m_linearVelocity.y / 30, simBalls[i].body.m_linearVelocity.x / 30); // the trick :)
}
}

note : 30 is default size of the quick box2d physic world

[swfobj src=”https://yopsolo.fr/ressources/pool-game-step-3-Sync.swf” alt=”Animation Flash” width=”640″ height=”480″ class=”flashObject” AllowScriptAccess=”always” allowfullscreen=”false” bgcolor=”#ffffff” required_player_version=”10″]

Edit :
Have a look to this great experiment build by @makc3d on wonderfl.net