This time we add some live to our scene. Not much at the beginning but enough to grasp what's going on in 3D animation.
2. Goals
In this part you learn:
- how to do basic animated 3D scene
- how to add free-walk ability
3. Implementation
This tutorial will be divided into two part. At the first part we introduce basic way of implement simple animation. At the second we employ some mathematics to receive quite interesting effect of keeping two objects face to face.
To receive animation effect we must get familiar we concept of "events". Events are thrown when specific event occurs - for instance mouse button is pressed. But besides user interface events there are also internal events such as ENTER_FRAME event. This event occurs each time new flash animation frame is going to be drawn to the screen. To perform some custom action before recent frame will be actually drown we can add event listener. Event listener is a special function which will be performed each time specific event occurs. In case of ENTER_FRAME event, whilst we register custom action it will be preformed each new frame going be displayed. In the listener function we can to any changes to the scene, such as moving objects, changing camera position, adding new objects. The following listing presents most basic example.
package {
import flash.events.Event;
import alternativa.engine3d.materials.FillMaterial;
import alternativa.engine3d.primitives.Box;
import alternativa.engine3d.core.Object3DContainer;
import alternativa.engine3d.core.View;
import alternativa.engine3d.core.Camera3D;
import flash.display.Sprite;
[SWF(backgroundColor=0xEEEADB,frameRate="100")]
public class First3DAnimation extends Sprite {
private var camera:Camera3D;
private var box:Box;
public function First3DAnimation() {
camera = new Camera3D(); //camera is now class attribute!!
camera.view = new View(640, 480);
addChild(camera.view);
addChild(camera.diagram);
camera.y = -500;
camera.z = 400;
camera.rotationX = -135 * Math.PI / 180;
var container : Object3DContainer = new Object3DContainer();
container.addChild(camera);
box = new Box(); // box is now class attribute
box.scaleX = 2;
box.x = -200;
var material : FillMaterial = new FillMaterial(0xdea200, 1, 1, 0x0);
box.setMaterialToAllFaces(material);
box.rotationZ = Math.PI / 6; // eq. 30 * Math.PI / 180
container.addChild(box);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void{
if (box.x < 200) {
box.x += 2;
}
camera.render();
}
}
}
There are two things you must pay attention here:
- Camera is now class attribute. That means can be can be reached in all methods of the class (in particular ENTER_FRAME listener function)
- onEnterFrame method has one argument of Event type. It is not used here, but required to be.
- on each frame render method is performed
Now it is time to add some extra 3D capabilities - free walk through. This feature let us to move in space in all direction (In fact it basically changes the camera location and rotation).
package {
import alternativa.engine3d.primitives.Plane;
import alternativa.engine3d.controllers.SimpleObjectController;
import flash.events.Event;
import alternativa.engine3d.materials.FillMaterial;
import alternativa.engine3d.primitives.Box;
import alternativa.engine3d.core.Object3DContainer;
import alternativa.engine3d.core.View;
import alternativa.engine3d.core.Camera3D;
import flash.display.Sprite;
[SWF(backgroundColor=0xEEEADB,frameRate="20")]
public class First3DAnimation extends Sprite {
private var camera:Camera3D;
private var box:Box;
private var controller:SimpleObjectController;
private var step:Number = 2;
public function First3DAnimation() {
camera = new Camera3D();
camera.view = new View(640, 480);
addChild(camera.view);
addChild(camera.diagram);
camera.y = -500;
camera.z = 400;
camera.rotationX = -135 * Math.PI / 180;
controller = new SimpleObjectController(stage, camera, 250);
var container : Object3DContainer = new Object3DContainer();
container.addChild(camera);
var plane:Plane = new Plane(800, 400);
plane.setMaterialToAllFaces(new FillMaterial(0xa1a1a1, 1, 1, 0));
container.addChild(plane);
box = new Box();
box.scaleX = 2;
box.x = -200;
var material : FillMaterial = new FillMaterial(0xdea200, 1, 1, 0x0);
box.setMaterialToAllFaces(material);
box.rotationZ = Math.PI / 6; // eq. 30 * Math.PI / 180
container.addChild(box);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void{
if (Math.abs(box.x) > 200) {
step = -step;
}
box.x += step;
controller.update();
camera.render();
}
}
}
Here we have added controller to the scene, or more precisely to the camera. Now we can move the camera in all direction. Additionally extra primitive has been introduced - Plane - which is basically one-faced flat 3D object.
Camera controls:
awsd, arrows - moving left/right/forward/backward
dragging with mouse - looking around
e,c - moving up and down
That is all for now. In the next part we learn how to focus camera attention whilst particular object is moving.
