Author: Max Pellizzaro
Date: November 12th 2007
Update: February 09th 2008
version: 3.0
In the previous tutorial we saw how to make a ball bouncing using tweenings. Let’s now make it bouncing using equations.
In order to model a bouncing ball we need to model:
Let’s see how to do all this.
The Document class must be changed to Example012.as The name of the class in the .as file and the name of the constructor now is: Example012. In this tutorial we will use the same asset as the prevoius tutorial to model out tennis court.
Update after rel 3.0.1
package
{
import flash.display.*;
import flash.net.URLRequest;
import flash.events.*;
import flash.ui.*;
import sandy.core.Scene3D;
import sandy.core.data.*;
import sandy.core.scenegraph.*;
import sandy.materials.*;
import sandy.materials.attributes.*;
import sandy.primitive.*;
import sandy.util.*;
import sandy.events.*;
public class Example012 extends Sprite
{
private var scene:Scene3D;
private var camera:Camera3D;
private var sphere:Sphere;
private var bottom:Plane3D;
private var wilson:Plane3D;
private var isBouncing:Boolean = false;
private var bounce:Number = -0.70;
private var friction:Number = 0.98;
private var gravity:Number = -0.50;
private var vx:Number = 0.00;
private var vy:Number = 0.00;
private var vz:Number = 0.00;
private var img:MyBall=new MyBall();
private var bitmap:Bitmap=new Bitmap(img);
private var imgCrt:MyCourt=new MyCourt();
private var bitmapCrt:Bitmap=new Bitmap(imgCrt);
private var imgWils:MyWilson=new MyWilson();
private var bitmapWils:Bitmap=new Bitmap(imgWils);
public function Example012():void
{
// We create the camera
camera = new Camera3D( 600, 300 );
camera.z = -300;
camera.x = 0;
camera.y = 150;
camera.lookAt(0,0,0);
// We create the "group" that is the tree of all the visible objects
var root:Group = createScene();
// We create a Scene and we add the camera and the objects tree
scene = new Scene3D( "scene", this, camera, root );
// Listen to the heart beat and render the scene
addEventListener( Event.ENTER_FRAME, enterFrameHandler );
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
}
// Create the scene graph based on the root Group of the scene
private function createScene():Group
{
// Create the root Group
var g:Group = new Group();
// Create the tennis court
bottom = new Plane3D('bottom', 300, 530, 20, 20,
Plane3D.ZX_ALIGNED,'quad');
// we define the texture for the tennis court
var materialCrt:BitmapMaterial = new BitmapMaterial( bitmapCrt.bitmapData );
materialCrt.lightingEnable = true;
var appCrt:Appearance = new Appearance( materialCrt );
bottom.enableBackFaceCulling = false;
bottom.useSingleContainer = false;
bottom.appearance = appCrt;
// Create the wilson poster
wilson = new Plane3D('wilson', 160, 40, 20, 20,
Plane3D.YZ_ALIGNED ,'quad');
wilson.rotateZ = 195;
wilson.y = 22;
wilson.x = -200;
// we define the texture for the tennis court
var materialWils:BitmapMaterial = new BitmapMaterial( bitmapWils.bitmapData );
materialWils.lightingEnable = true;
var appWils:Appearance = new Appearance( materialWils );
wilson.enableBackFaceCulling = false;
wilson.useSingleContainer = false;
wilson.appearance = appWils;
// we define the tennis ball
sphere = new Sphere("sphere", 20,20,20);
sphere.z = 0;
sphere.x = 0;
sphere.y = 20;
sphere.rotateY = 110;
var materialImg:BitmapMaterial = new BitmapMaterial( bitmap.bitmapData );
materialImg.lightingEnable = true;
var appImg:Appearance = new Appearance( materialImg );
sphere.enableBackFaceCulling = false;
sphere.useSingleContainer = false;
sphere.appearance = appImg;
g.addChild( sphere);
g.addChild( bottom );
g.addChild( wilson );
return g;
}
// The Event.ENTER_FRAME event handler tells the Scene3D to render
private function enterFrameHandler( event : Event ) : void
{
if(isBouncing)
{
if(sphere.y < 20)
{
vy *= bounce;
sphere.y = 20;
}
else
{
vy += gravity;
vy *= friction;
}
sphere.y += vy;
}
if(Math.sqrt(Math.sqrt(vy*vy))< 0.5 && sphere.y < 21)
isBouncing = false;
scene.render();
}
private function keyPressed(event:KeyboardEvent):void {
switch(event.keyCode) {
case Keyboard.PAGE_DOWN:
camera.z -=5;
break;
case Keyboard.PAGE_UP:
camera.z +=5;
break;
case Keyboard.CONTROL:
sphere.y = 150;
vy = -10;
isBouncing = true;
break;
}
}
}
}
The first part of the code is identical of the previous tutorial, so we will not discuss how to build the Tennis court. Let’s focus on the important stuff: the motion.
You will notice that there is not tweenings, so how did we model the motions? First we define some important variables:
private var isBouncing:Boolean = false; private var bounce:Number = -0.70; private var friction:Number = 0.98; private var gravity:Number = -0.50; private var vx:Number = 0.00; private var vy:Number = 0.00; private var vz:Number = 0.00;
I have put here more variables that we need right now, but you will get the idea on what you need to model motion. The three main variables are:
The Boolean variable isBouncing has been introduced to avoid infinite loop calculation from the engine.
The other three important variables are vx, vy and vz that models the velocity of the ball in each direction.
Now that we have declared the right variables, let’s move to the equation, that can be found in the enterFrameHandler(..) function. It has been placed there since this code must run every time the engine fire a new frame.
if(isBouncing) { if(sphere.y < 20) { vy *= bounce; sphere.y = 20; } else { vy += gravity; vy *= friction; } sphere.y += vy; } if(Math.sqrt(Math.sqrt(vy*vy))< 0.5 && sphere.y < 21) isBouncing = false;
Well this is a lot of code, and we might get confused by the “if” condition I have placed to save infinite computation when the ball is almost stopped. So let’s clean the code to just highlight what is really important:
if(sphere.y < 20) vy *= bounce; vy += gravity; vy *= friction; sphere.y += vy;
Now this is much better. These are core line we need to concentrate:
I let you understand all the control I have introduce to mess up this simple code.
So let’s see the result !!
Get the focus of the flash and use the ctrl key (Apple key on Mac) to make the ball bounce and compare the result with the previous tutorial.