In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Bringing Physics to Sandy 3D, using JigLibFlash (recurring balls)

The application shows balls rolling on slopes
Extending the BasicView sets up the Sandy scen for us :)
To get a nice bouncing, I mosty play with restitution.
No doubt this could be enhanced in quite a few ways
Go on and fork me :)

@author 	petit@petitpub.com
// forked from petit's Bringing Physics to Sandy 3D, using JigLibFlash
package 
{
	import flash.events.Event;
	import jiglib.math.JNumber3D;
	import jiglib.plugin.sandy3d.Sandy3DPhysics;
	import jiglib.plugin.sandy3d.Sandy3DMesh;

	import sandy.view.BasicView;
	import sandy.materials.attributes.LightAttributes;
	import sandy.materials.attributes.LineAttributes;
	import sandy.materials.attributes.PhongAttributes;
	import sandy.materials.attributes.MaterialAttributes;
	import sandy.materials.attributes.GouraudAttributes;
	import sandy.materials.ColorMaterial;
	import sandy.materials.Appearance;
	
	import jiglib.physics.RigidBody;
	/**
	 * The application shows balls rolling on slopes
	 * Extending the BasicView sets up the Sandy scen for us :)
	 * To get a nice bouncing, I mosty play with restitution.
	 * No doubt this could be enhanced in quite a few ways
	 * Go on and fork me :)
	 * 
	 * @author 	petit@petitpub.com
	 */
	public class BallsOnSlopes extends BasicView 
	{
		private var physics:Sandy3DPhysics; // The physic engine adapter class
		private var ground:RigidBody;
		private var balls:Array; // An array of chained objects
		private const NUM_BALLS:int = 3;
		
		/**
		 * Set up the experiment
		 */
		public function BallsOnSlopes(){
			super.init(600,400);
			balls = new Array();
			scene.light.setDirection(1,-1,2);
			camera.z = -800; camera.y = 200; camera.lookAt(0, 200, 0);
			
			// Create an instance of the physics engine
			physics = new Sandy3DPhysics(scene, 3);

			createObjects();
			render();

			// reset on click
			stage.addEventListener ("click", click);
		}
		
		/**
		 * Create the ground, ramps and balls
		 */
		private function createObjects():void {
			// Create some materials
			var groundAttributes:MaterialAttributes = new MaterialAttributes( new LineAttributes(0.5,0xECECEC,0.6), new LightAttributes(true));			
			var groundMaterial:ColorMaterial =  new ColorMaterial(0x26A6D0, 1, groundAttributes);
			
			var backMaterial:ColorMaterial = new ColorMaterial(0xFF552A, 0.6);

			var slopeAttributes:MaterialAttributes = new MaterialAttributes( new LightAttributes(true));	
			var slopeMaterial:ColorMaterial = new ColorMaterial(0x1B9A1B, 0.8, slopeAttributes);
			slopeMaterial.lightingEnable = true;

			var ballAttributes:MaterialAttributes = new MaterialAttributes( new PhongAttributes(true,0.2,15,2 ));
			var ballMaterial:ColorMaterial = new ColorMaterial(0xFFAA2A, 1, ballAttributes);
			ballMaterial.lightingEnable = true;
			
			// Create the ground
			ground = physics.createGround("ground", new Appearance(groundMaterial), 800, 0, 10);
			physics.getMesh(ground).enableForcedDepth = true;
			physics.getMesh(ground).forcedDepth = 40040;
			ground.restitution = 0.6;

			// Create the back wall
			var backWall:RigidBody = physics.createCube("back", new Appearance( backMaterial ), 600, 2, 400, 2);
			physics.getMesh(backWall).forcedDepth = 40020;
			backWall.z = 200;
			backWall.y = 200;
			backWall.restitution = 1.6;
			backWall.movable = false;
			

			// Create the slopes
			var slope1:RigidBody = physics.createCube("slope1", new Appearance(slopeMaterial), 50, 200, 8, 2);
			physics.getMesh(slope1).useSingleContainer = false;
			slope1.x = -250; slope1.y = 300; slope1.z = 100;
			slope1.rotationX = -25;
			slope1.movable = false;

			var slope2:RigidBody = physics.createCube("slope2", new Appearance(slopeMaterial), 50, 300, 8, 2);
			physics.getMesh(slope2).useSingleContainer = false;
			slope2.x = -250; slope2.y = 200; slope2.z = -100;
			slope2.rotationX = 35;
			slope2.movable = false;

			// Create multiple balls
			for ( var i:int = 0; i < NUM_BALLS; i++) {
				balls[i]=physics.createSphere("ball" + 1, new Appearance(ballMaterial), 20, 8, 8);
				balls[i].x = -250; balls[i].y = 400 + 40 * i; balls[i].z = 160;
				//physics.getMesh(balls[i]).useSingleContainer = false;
				balls[i].restitution = 1.8;
			}
		}

		/**
		 * Overrides the simpleRender method to call the time step method of the rendering engine.
		 * @param	event	The ENTER_FRAME or timer event - the heart beat of Sandy
		 */
		override public function simpleRender( event:Event = null ):void {
			physics.step( );
			super.simpleRender( event );

			for ( var i:int = 0; i < NUM_BALLS; i++) {
				if (balls [i].z < camera.z) {
					balls[i].x = -250; balls[i].y = 400 + 40 * i; balls[i].z = 16;
				}
			}

		}

		public function click( event:Event = null ):void {

			for ( var i:int = 0; i < NUM_BALLS; i++) {
				balls[i].x = -250; balls[i].y = 400 + 40 * i; balls[i].z = 16; balls[i].setActive();
			}

		}
	}
}