[JigLibFlash] Terrain Physics
クリックでリセットするよ!
/**
* Copyright clockmaker ( http://wonderfl.net/user/clockmaker )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xWPW
*/
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.utils.*;
import jiglib.physics.*;
import jiglib.plugin.papervision3d.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.special.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.view.*;
[SWF(width="465",height="465",frameRate="60")]
public class Main extends BasicView {
public static const MAX_ITEMS:int = 10;
public static const GROUND_SIZE:int = 1500;
public static const GROUND_HEIGHT:int = 600;
private var spehres:Vector.<RigidBody>;
private var physics:Papervision3DPhysics;
public function Main(){
// 初期設定
stage.quality = StageQuality.LOW;
opaqueBackground = 0x0;
// カメラの位置
camera.y = 700;
// 3Dの物理エンジン
physics = new Papervision3DPhysics(scene, 10);
// 地面を作成
var groundMat:WireframeMaterial = new WireframeMaterial(0x999999);
// パーリンノイズででこぼこ作成
var bmd:BitmapData = new BitmapData(100, 100, false, 0x0);
bmd.perlinNoise(40, 40, 1, 1, true, false, 7, true);
// でこぼこ
var ground:RigidBody = physics.createTerrain(bmd, groundMat, GROUND_SIZE, GROUND_SIZE, GROUND_HEIGHT, 15, 15);
ground.friction = 0.1;
ground.restitution = 0.8;
ground.y = -GROUND_HEIGHT;
// 球体のテクスチャ
var wireFrameMat:WireframeMaterial = new WireframeMaterial(0xFF0000);
var colorMat:ColorMaterial = new ColorMaterial(0x0, 0.76);
var compMat:CompositeMaterial = new CompositeMaterial();
compMat.addMaterial(colorMat);
compMat.addMaterial(wireFrameMat);
spehres = new Vector.<RigidBody>();
for (var i:int = 0; i < 10; i++){
var rigidBody:RigidBody = physics.createSphere(compMat, 100 * Math.random() + 20, 8, 6);
rigidBody.restitution = 0.8;
rigidBody.friction = 1;
spehres[i] = rigidBody;
}
resetAll();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.CLICK, resetAll);
startRendering();
}
private function enterFrameHandler(e:Event = null):void {
// 角度に応じてカメラの位置を設定
var msec:Number = getTimer();
camera.x = 1000 * Math.sin(msec / 2000);
camera.z = 1000 * Math.cos(msec / 2000);
camera.y = 500 * Math.sin(msec / 2500) + 900;
// 範囲からでた球体を初期位置に戻す
resetBody();
// 物理演算
physics.engine.integrate(0.4);
}
private function resetBody():void {
for (var i:int = 0; i < spehres.length; i++){
var rigidBody:RigidBody = spehres[i];
var pos:Vector3D = rigidBody.currentState.position;
if (pos.x < -GROUND_SIZE/2 || pos.x > GROUND_SIZE/2 || pos.z < -GROUND_SIZE/2 || pos.z > GROUND_SIZE/2){
var force:Number = (Math.random() - 0.5) * 500;
rigidBody.moveTo(new Vector3D(0, 1000, 0));
rigidBody.addBodyForce(new Vector3D(force, 0, force), new Vector3D(force, 0, force));
}
}
}
private function resetAll(e:Event = null):void {
for (var i:int = 0; i < spehres.length; i++){
var rigidBody:RigidBody = spehres[i];
var force:Number = (Math.random() - 0.5) * 500;
rigidBody.moveTo(new Vector3D(0, 1000, 0));
rigidBody.addBodyForce(new Vector3D(force, 0, force), new Vector3D(force, 0, force));
}
}
}
}