[JigLibFlash] Accelerometer with Android
Android の加速度センサーで楽しめます!
ぜひ Android 2.2 以上のスマートフォンでお試しください。
(PC でもマウスで代用できるようにしてます)
Accelerometer クラスと JigLib の 3D 物理演算を組み合わせたデモ。3D エンジンには Papervision3D を使用。
こちらの解説記事もどうぞ!
http://clockmaker.jp/blog/2010/12/3d-physics/
/**
* Copyright clockmaker ( http://wonderfl.net/user/clockmaker )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uyMu
*/
package {
import com.bit101.components.*;
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import flash.sensors.*;
import jiglib.physics.*;
import jiglib.plugin.papervision3d.*;
import net.hires.debug.Stats;
import org.papervision3d.cameras.*;
import org.papervision3d.core.math.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.utils.*;
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.view.*;
[SWF(width="465",height="465",frameRate="60",backgroundColor="0x0")]
public class BasicDemo extends BasicView {
public static const GROUND_SIZE:int = 20000;
public static const GROUND_HEIGHT:int = 2000;
public static const GROUND_SEGMENT:int = 20;
private var physics:Papervision3DPhysics;
private var spehres:Vector.<RigidBody>;
private var cameraTarget:DisplayObject3D;
private var accel:Accelerometer;
private var gravityArr:Vector.<Number> = Vector.<Number>([0, 0]);
private var mouseUse:Boolean = false;
public function BasicDemo(){
// 初期設定
stage.quality = StageQuality.LOW;
opaqueBackground = 0x0;
super(465, 465, true, false, CameraType.SPRING);
// 3Dの物理エンジン
physics = new Papervision3DPhysics(scene, 10);
// 地面を作成
// パーリンノイズででこぼこ作成
var bmd:BitmapData = new BitmapData(100, 100, true, 0x0);
bmd.lock();
bmd.perlinNoise(20, 20, 1, 1, true, false, 7, true);
bmd.applyFilter(bmd, bmd.rect, new Point(), new GlowFilter(0xFFFFFF, 1, 16, 16, 5, 3, true));
bmd.unlock();
// でこぼこ
var ground:RigidBody = physics.createTerrain(bmd, new WireframeMaterial(0x666666), GROUND_SIZE, GROUND_SIZE, GROUND_HEIGHT, GROUND_SEGMENT, GROUND_SEGMENT);
ground.friction = 1;
ground.restitution = 1;
ground.y = -GROUND_HEIGHT;
// 球体のテクスチャ
spehres = new Vector.<RigidBody>();
for (var i:int = 0; i < 3; i++){
// 球体を作成
var wire:WireframeMaterial = new WireframeMaterial(i == 0 ? 0xFF0000 : 0x808080);
var rigidBody:RigidBody = physics.createSphere(wire, 300, 6, 4);
rigidBody.restitution = 1;
rigidBody.friction = 1;
rigidBody.moveTo(new Vector3D(0, 1000, 0));
spehres[i] = rigidBody;
}
// 壁
createWall(0, GROUND_SIZE / 2, 0);
createWall(GROUND_SIZE / 2, 0, 90);
createWall(0, -GROUND_SIZE / 2, 180);
createWall( -GROUND_SIZE / 2, 0, 270);
// カメラの視点
cameraTarget = new DisplayObject3D();
scene.addChild(cameraTarget);
// カメラの位置
SpringCamera3D(camera).target = cameraTarget;
SpringCamera3D(camera).mass = 7;
SpringCamera3D(camera).damping = 7;
SpringCamera3D(camera).stiffness = 1;
SpringCamera3D(camera).positionOffset = new Number3D(0, 2000, 2000);
// for android デバイス
if (Accelerometer.isSupported){
accel = new Accelerometer();
accel.setRequestedUpdateInterval(100);
accel.addEventListener(AccelerometerEvent.UPDATE, accelerometer_updateHandler);
}
// PCデバイスの場合は
else {
mouseUse = true;
}
// 部品
addChild(new Stats());
new PushButton(this, 100, 10, "FULL SCREEN", clickHandler);
// レンダリング
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
/** エンターフレームのハンドラー */
private function enterFrameHandler(e:Event = null):void {
cameraTarget.copyPosition(Pv3dMesh(spehres[0].skin).mesh);
// マウス
if (mouseUse){
gravityArr[0] += (-7 * ((mouseX / stage.stageWidth - 0.5)) - gravityArr[0]) * 0.4;
gravityArr[1] += (7 * ((mouseY / stage.stageHeight - 0.5)) - gravityArr[1]) * 0.4;
updateGravity(new Vector3D(gravityArr[0], -10, gravityArr[1]));
}
// 物理演算
physics.engine.integrate(0.75);
// レンダリング
singleRender();
}
/** 加速度計のハンドラー */
private function accelerometer_updateHandler(event:AccelerometerEvent):void {
updateGravity(new Vector3D(event.accelerationX * 20, -10, event.accelerationY * 20));
}
/** 重力方向の更新 */
private function updateGravity(vec:Vector3D):void {
physics.engine.gravity.x = vec.x;
physics.engine.gravity.y = vec.y;
physics.engine.gravity.z = vec.z;
// 重力をオブジェクトに反映
for (var i:int = 0; i < spehres.length; i++){
spehres[i].updateGravity(physics.engine.gravity, physics.engine.gravityAxis);
}
}
/** クリックのハンドラー */
private function clickHandler(e:Event):void {
stage.displayState = (stage.displayState == StageDisplayState.FULL_SCREEN) ? StageDisplayState.NORMAL : StageDisplayState.FULL_SCREEN;
}
/** 壁を作る */
private function createWall(tx:Number, tz:Number, rot:Number):void {
var ml:MaterialsList = new MaterialsList({all: new ColorMaterial(0x0, 0)});
var wall:RigidBody = physics.createCube(ml, GROUND_SIZE, 100, 10000);
wall.x = tx;
wall.y = 5000;
wall.z = tz;
wall.rotationY = rot;
wall.movable = false;
}
}
}