Papervision3D Game-like Sample
game-like sample using Papervision 3d and Tweener
//game-like sample using Papervision 3d and Tweener
package {
import flash.display.*;
import flash.events.*;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.getTimer;
import caurina.transitions.Tweener;
import org.papervision3d.core.clipping.FrustumClipping;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.*;
import org.papervision3d.materials.special.CompositeMaterial;
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
[SWF(backgroundColor=0x6666FF)]
public class Pv3DSam1 extends Sprite
{
//private var container : Sprite;
private var viewport : Viewport3D;
private var scene : Scene3D;
private var camera : Camera3D;
private var rootNode : DisplayObject3D;
private var renderer : BasicRenderEngine;
private var light : PointLight3D;
//for debug
private var frameCount : Number;
private var prevTimer : Number;
private var debugText : Array;
private var numDebugItems : int = 12;
//camera information
private var exCamera : Array;
private var cameraStatus : int = 0; // 0: ground, 1:during change, 2:bird-eyes, 3:Look-at-paperPlane
//coneObject
private var coneObj : DisplayObject3D;
private var coneMat : CompositeMaterial; //FlatShadeMaterial;
//cubeObject
private var cubeObj : DisplayObject3D;
private var cubeSize : int = 50;//cubeオブジェクト1辺の長さ
private var cubeSegment : int = 1; //面の分割数
private var cubeMatList : MaterialsList;
private var cubeMat : CompositeMaterial; //FlatShadeMaterial;
private var cubeRotTheta : Number = 0;
//paperPlaneObject
private var paperPlaneObj : DisplayObject3D;
private var paperPlaneSize : int = 20;
private var paperPlaneMat : CompositeMaterial; //FlatShadeMaterial;
private var paperPlaneRotTheta : Number = 0;
//ground field
private var fieldObj : DisplayObject3D;
private var fieldSize : int = 2000;
private var fieldSegment : int = 1;
private var fieldMat : CompositeMaterial;
private var fieldLimit : int = fieldSize / 2 - 20;
private var rightKey :Boolean = false;
private var leftKey :Boolean = false;
private var upKey :Boolean = false;
private var downKey :Boolean = false;
private var shiftKey :Boolean = false;
private var spaceKey :Boolean = false;
private var charaHeight : int = 50;
private var onJump : Boolean = false;
private var deltaJump : int = 0;
private var powerJump : int = 40;
private var deltaRot : int = 2;
private var deltaMove : int = 7;
public function Pv3DSam1():void
{
stage.frameRate = 30;
stage.quality = "LOW";
stage.scaleMode = "noScale";
stage.align = StageAlign.TOP_LEFT;
viewport = new Viewport3D( 0, 0, true );
renderer = new BasicRenderEngine( );
scene = new Scene3D( );
rootNode = new DisplayObject3D( );
light = new PointLight3D( );
addChild( viewport );
scene.addChild( rootNode );
renderer.clipping = new FrustumClipping(FrustumClipping.BOTTOM);
light.y = 2000;
//create ground field
fieldMat = new CompositeMaterial();
fieldMat.addMaterial( new ColorMaterial( 0x888800, 1 ) );
fieldMat.addMaterial( new WireframeMaterial( 0x000000, 0.3 ) );
fieldMat.lineAlpha = 0.1;
fieldMat.fillAlpha = 1;
fieldObj = new Plane( fieldMat, fieldSize, fieldSize, fieldSegment, fieldSegment );
fieldObj.rotationX = 90;
rootNode.addChild( fieldObj );
//create cone
coneMat = new CompositeMaterial();
coneMat.addMaterial( new FlatShadeMaterial( light, 0xDDDDDD, 0xFF6666 ) );
coneMat.addMaterial( new WireframeMaterial( 0x000000, 0.3 ) );
coneObj = new Cone( coneMat, 50, 200, 16, 1 );
coneObj.y = 101;
rootNode.addChild( coneObj );
//create cube
cubeMat = new CompositeMaterial();
cubeMat.addMaterial( new FlatShadeMaterial(light, 0xFFFF00, 0xAAAA00) );
cubeMat.addMaterial( new WireframeMaterial( 0x000000, 0.3 ) );
cubeMatList = new MaterialsList( );
cubeMatList.addMaterial( cubeMat, "all" );
cubeObj = new Cube( cubeMatList, cubeSize, cubeSize, cubeSize, cubeSegment, cubeSegment, cubeSegment );
cubeObj.y = cubeSize;
rootNode.addChild( cubeObj );
//create paperPlane
paperPlaneMat = new CompositeMaterial();
paperPlaneMat.addMaterial( new FlatShadeMaterial( light, 0x88CCAA, 0x448866 ) );
paperPlaneMat.addMaterial( new WireframeMaterial( 0x000000, 0.3 ) );
paperPlaneMat.oneSide = false;
paperPlaneObj = new PaperPlane( paperPlaneMat, 0.7 );
paperPlaneObj.y = 30;
paperPlaneObj.rotationY = 180;
rootNode.addChild ( paperPlaneObj );
//camera setting
camera = new Camera3D(90, 10, 2000, true);
camera.z = -cubeSize;
camera.y = charaHeight;
camera.x = 124;
camera.z = -340;
camera.focus = 10;
camera.zoom = 50;
camera.rotationY = 300 ;
exCamera = new Array();
//fps computing
frameCount = 0;
prevTimer = getTimer();
stage.addEventListener( Event.ENTER_FRAME, loop );
stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler );
stage.addEventListener( KeyboardEvent.KEY_UP, keyUPHandler );
initializeDebugger();
}
private function initializeDebugger():void
{
debugText = new Array();
var debugTextFormat:TextFormat = new TextFormat();
debugTextFormat.size = 11;
debugTextFormat.color = 0xFFFFFF;
debugTextFormat.font = "Courier New";
for( var i:int = 0; i < numDebugItems; i++ )
{
debugText[ i ] = new TextField();
debugText[ i ].type = "dynamic";
debugText[ i ].width = 150;
debugText[ i ].height = 20;
debugText[ i ].x = 12;
debugText[ i ].y = 8 + 15 * i;
debugText[ i ].defaultTextFormat = debugTextFormat;
debugText[ i ].text = " --------";
addChild( debugText[i] );
}
}
private function keyDownHandler( event:KeyboardEvent ):void
{
switch ( event.keyCode )
{
case Keyboard.RIGHT:
rightKey = true;
break;
case Keyboard.LEFT:
leftKey = true;
break;
case Keyboard.UP:
upKey = true;
break;
case Keyboard.DOWN:
downKey = true;
break;
case Keyboard.SHIFT:
shiftKey = true;
break;
case Keyboard.SPACE:
spaceKey = true;
break;
default:
break;
}
}
private function keyUPHandler( event:KeyboardEvent ):void
{
switch ( event.keyCode )
{
case Keyboard.RIGHT:
rightKey = false;
break;
case Keyboard.LEFT:
leftKey = false;
break;
case Keyboard.UP:
upKey = false;
break;
case Keyboard.DOWN:
downKey = false;
break;
case Keyboard.SHIFT:
shiftKey=false;
break;
case Keyboard.SPACE:
spaceKey = false;
break;
default:
break;
}
}
private function loop( event:Event ):void
{
controlCamera();
moveObjects();
displayDebug();
renderer.renderScene( scene, camera, viewport );
}
private function displayDebug():void
{
frameCount ++;
if ( (getTimer() - prevTimer ) / 1000 >= 0.25 )
{
var fps:Number = frameCount * 1000 / ( getTimer() - prevTimer );
fps = Math.floor( fps * 10 ) / 10;
prevTimer = getTimer();
frameCount = 0;
debugText[ 0 ].text = "FPS : " + fps;
}
debugText[ 1 ].text = "CAMERA_X : " + int( camera.x );
debugText[ 2 ].text = "CAMERA_Y : " + int( camera.y );
debugText[ 3 ].text = "CAMERA_Z : " + int( camera.z );
debugText[ 4 ].text = "ROT_X : " + int( camera.rotationX );
debugText[ 5 ].text = "ROT_Y : " + int( camera.rotationY );
debugText[ 6 ].text = "ROT_Z : " + int( camera.rotationZ );
debugText[ 8 ].text = "Move : ↑↓";
debugText[ 9 ].text = "Turn : →←";
debugText[ 10 ].text = "Observe : Shift";
debugText[ 11 ].text = "Bird-eyes: Space"
}
private function moveObjects():void
{
cubeObj.rotationZ += 10;
cubeRotTheta += Math.PI * 2 / 100;
cubeObj.x = Math.cos( cubeRotTheta ) * 150 - 250;
cubeObj.z = Math.sin( cubeRotTheta ) * 150 - 250;
paperPlaneObj.rotationY -= 360 / 100;
paperPlaneObj.x = - Math.cos( cubeRotTheta ) * 300 + 150;
paperPlaneObj.z = - Math.sin( cubeRotTheta ) * 300 + 150;
paperPlaneObj.y = ( Math.cos( cubeRotTheta ) ) * 100 + 110;
}
private function controlCamera():void
{
if( spaceKey == true )
{
if( cameraStatus == 0 )
{
renderer.clipping = new FrustumClipping(FrustumClipping.NEAR);
cameraStatus = 1;
exCamera[0] = camera.x;
exCamera[1] = camera.y;
exCamera[2] = camera.z;
exCamera[3] = camera.rotationX;
exCamera[4] = camera.rotationY;
exCamera[5] = camera.rotationZ;
Tweener.addTween( camera, {x: 0, y:2000, z:0, time:2} );
Tweener.addTween( camera, {rotationX: 90, time:3, onComplete: function():void{cameraStatus = 2} } );
}
else if( cameraStatus == 2 )
{
cameraStatus = 1;
Tweener.addTween( camera, {x: exCamera[0], y:exCamera[1], z:exCamera[2], time:3} );
Tweener.addTween( camera, {rotationX: exCamera[3], time:2, onComplete: function():void
{
cameraStatus = 0;
renderer.clipping = new FrustumClipping(FrustumClipping.BOTTOM);
}} );
exCamera.length = 0;
}
}
if( rightKey == true )
{
camera.rotationY += deltaRot;
}
else if( leftKey == true )
{
camera.rotationY -= deltaRot;
}
if( shiftKey == true )
{
if( cameraStatus == 0 )
{
exCamera[0] = camera.rotationX;
exCamera[1] = camera.rotationY;
exCamera[2] = camera.rotationZ;
cameraStatus = 3;
}
if( cameraStatus == 3 )
{
camera.lookAt( paperPlaneObj );
}
}
else
{
if( cameraStatus == 3 )
{
cameraStatus = 0;
camera.rotationX = exCamera[0];
camera.rotationY = exCamera[1];
camera.rotationZ = exCamera[2];
exCamera.length = 0;
}
}
if( cameraStatus == 0 )
{
if( camera.x > - fieldLimit && camera.x < fieldLimit && camera.z > - fieldLimit && camera.z < fieldLimit )
{
if( upKey == true )
{
camera.moveForward( deltaMove );
}
else if ( downKey == true )
{
camera.moveBackward( deltaMove );
}
}
/*
if( shiftKey == true && onJump == false)
{
onJump = true;
deltaJump = powerJump;
}
if( onJump == true )
{
camera.y += deltaJump;
if( deltaJump == -powerJump )
{
onJump = false;
deltaJump = 0;
}
else
{
deltaJump -= 2;
}
}
*/
//avoid camera going out of the field
if( camera.x > fieldLimit - 10 )
{
camera.x = fieldLimit - 10;
}
else if( camera.x < - fieldLimit + 10)
{
camera.x = - fieldLimit + 10;
}
else if( camera.z > fieldLimit - 10 )
{
camera.z = fieldLimit - 10;
}
else if( camera.z < - fieldLimit + 10 )
{
camera.z = - fieldLimit + 10;
}
}
}
}
}