Box2Dをちょっと勉強してみて、
このライブラリでは、
「物理演算させた結果を数値パラメータとして取り出して使う」、
ということがわかってきた。
Box2Dで遊んでいる人の多くがそうであるように、
このパラメータを何で使ったらおもしろいかというひとつの行き先として、3D表示がある。
Flashには3D表現のライブラリとしては、PaperVision3Dが有名です。
というわけで、3D表現とか未経験なので、勉強もかねて、
技術評論社の簡単なBox2Dサンプルの動作を、
Papervision3Dライブラリを使って3D表示させてみた。
↑ 画面クリックで、箱が落ちます。
Box2D部分はほぼ技術評論社のものと変更ありません。
Box2Dは、2次元の物理演算ライブラリなので、
PaperVision3Dを用いても、表示されている領域内では、2Dの動作しかしません。
Box2Dで、毎フレームごとのX座標、Y座標、傾きなどの値を取り出して、
PaperVision3Dの世界に落とし込んでいます。
というわけで、とりあえずPaperVision3Dの初体験ができましたw
がんばればもうちょっと面白いことできそうだなー。
↓ソース全部。
使用したPaperVision3Dライブラリのバージョンは
「Public Alpha 2.0 - Great White (24.03.08)」です。
メインのPaperVisionTestクラス
- package src {
- import Box2D.Collision.b2AABB;
- import Box2D.Collision.Shapes.b2PolygonDef;
- import Box2D.Common.Math.b2Vec2;
- import Box2D.Dynamics.b2Body;
- import Box2D.Dynamics.b2BodyDef;
- import Box2D.Dynamics.b2DebugDraw;
- import Box2D.Dynamics.b2World;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.events.MouseEvent;
- /**
- * ...
- * @author Default
- */
- public class PaperVisionTest extends Sprite {
- private var world:b2World;
- private var boxBody:b2Body;
- private var pvView:PVView;
- public function PaperVisionTest() {
- // イベントハンドラを登録する
- stage.addEventListener(MouseEvent.CLICK, clickHandler);
- addEventListener(Event.ENTER_FRAME, enterFrameHandler);
- pvView = new PVView;
- pvView.x = -100;
- pvView.y = -100;
- addChild(pvView);
- }
- private function clickHandler(event:MouseEvent):void {
- ////////////////////////////////////////
- // 物理エンジンのセットアップ
- // 外枠を定義する
- var worldAABB:b2AABB = new b2AABB();
- worldAABB.lowerBound.Set(-100, -100);
- worldAABB.upperBound.Set(100, 100);
- // 重力を下方向に10m/s^2とする
- var gravity:b2Vec2 = new b2Vec2(0, 10);
- // 外枠と重力を指定して、物理エンジン全体をセットアップする
- world = new b2World(worldAABB, gravity, true);
- ////////////////////////////////////////
- // 床の設置
- // 床は画面の下のほうに設置します
- // 床の位置を左から2.1m、上から3mとする
- var floorBodyDef:b2BodyDef = new b2BodyDef();
- floorBodyDef.position.Set(2.15, 3);
- // 床の形を、幅4m、厚さ20cmとする
- // 指定するのはその半分の値
- var floorShapeDef:b2PolygonDef = new b2PolygonDef();
- floorShapeDef.SetAsBox(2, 0.1);
- // 床を動かない物体として作る
- var floor:b2Body = world.CreateBody(floorBodyDef);
- floor.CreateShape(floorShapeDef);
- ////////////////////////////////////////
- // 箱の設置
- // 箱は床の上から落として、少しはねるようにします
- // 箱の位置を左から2.5m、上から1mとする
- var boxBodyDef:b2BodyDef = new b2BodyDef();
- boxBodyDef.position.Set(2.5, 1);
- // 箱の形を、幅60cm、高さ40cmとして45度ぐらい右に回す
- var boxShapeDef:b2PolygonDef= new b2PolygonDef();
- boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0.9);
- boxShapeDef.density = 1; // 密度 [kg/m^2]
- boxShapeDef.restitution = 0.75; // 反発係数、通常は0~1
- // 箱を動く物体として作る
- boxBody = world.CreateBody(boxBodyDef);
- boxBody.CreateShape(boxShapeDef);
- boxBody.SetMassFromShapes();
- ////////////////////////////////////////
- // 描画設定
- var debugDraw:b2DebugDraw = new b2DebugDraw();
- debugDraw.m_sprite = this;
- debugDraw.m_drawScale = 100; // 1mを100ピクセルにする
- debugDraw.m_fillAlpha = 0.6; // 不透明度
- debugDraw.m_lineThickness = 1; // 線の太さ
- debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
- world.SetDebugDraw(debugDraw);
- }
- private function enterFrameHandler(event:Event):void {
- if (world == null) {
- return;
- }
- // Flashはデフォルトで秒間24フレームなので、
- // 物理シミュレーションを1/24秒進める
- world.Step(1 / 24, 10);
- // 箱の座標、傾きを3D世界に適用する。
- var b2vec:b2Vec2 = boxBody.GetPosition();
- pvView.setCubePosition(b2vec.x * 100, b2vec.y * 100, boxBody.GetAngle());
- }
- }
- }
3D表示用PVViewクラス
- package src {
- import Box2D.Dynamics.b2Body;
- import org.papervision3d.lights.PointLight3D;
- import org.papervision3d.materials.ColorMaterial;
- import org.papervision3d.materials.shadematerials.PhongMaterial;
- import org.papervision3d.materials.special.CompositeMaterial;
- import org.papervision3d.materials.utils.MaterialsList;
- import org.papervision3d.materials.WireframeMaterial;
- import org.papervision3d.objects.primitives.Cube;
- import org.papervision3d.view.BasicView;
- /**
- * ...
- * @author Default
- */
- public class PVView extends BasicView{
- private var b2BodyList:Array;
- private var _light:PointLight3D;
- private var cube:Cube;
- public function PVView(){
- b2BodyList = new Array();
- camera.z = -50;
- camera.x = -40;
- camera.y = -40;
- _light = new PointLight3D;
- _light.x = 0;
- _light.y = 0;
- _light.z = 40;
- var colorMaterial:ColorMaterial = new ColorMaterial(0x77FF77, 1);
- var wireMaterial:WireframeMaterial = new WireframeMaterial(0x66FF66, 1);
- var phongMaterial:PhongMaterial = new PhongMaterial( _light, 0xCCDDCC, 0xDDEEDD, 1 );
- var compositeMaterial:CompositeMaterial = new CompositeMaterial();
- compositeMaterial.addMaterial(colorMaterial);
- compositeMaterial.addMaterial(phongMaterial);
- compositeMaterial.addMaterial(wireMaterial);
- var materialsList:MaterialsList = new MaterialsList;
- materialsList.addMaterial(compositeMaterial, "all");
- cube = new Cube(materialsList, 60, 40, 40);
- cube.x = 2.5 * 100;
- cube.y = 1 * 100;
- scene.addChild(cube);
- startRendering();
- }
- public function setCubePosition(x:Number, y:Number, rotationY) {
- cube.x = x;
- cube.z = y;
- rotationY = rotationY * 180;
- cube.rotationY = rotationY;
- }
- }
- }
- Newer: ベジェ曲線、オートトレス等使って、イベント告知ページ作ってみた
- Older: Box2Dでバスケのフリースローゲーム(2)
Comments:2
- とおりすがり 09-02-03 (火) 10:22
-
うまく回転ができてないみたいですね。
boxBodyDef.position.Set(2.5, 1);
の次の行に
boxBodyDef.angle = 0.9;
を追加boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0.9);
を
boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0);rotationY = rotationY * 180;
を
rotationY = rotationY * (180/Math.PI)でなおると思います。
- admin 09-02-19 (木) 11:59
-
お、どうもありがとうございます。
直してテストしてみます
Trackbacks:1
- Trackback URL for this entry
- http://parpue.net/web/138/trackback
- Listed below are links to weblogs that reference
- Box2D と PaperVision3D を連携させてみる from parpue.net
- pingback from parpue.net - Box2D,Papervision3Dでフリースローゲームを3D表示 08-08-01 (金) 1:35
-
[...] 前々回のエントリでBox2DとPapervision3dを連携させてみて、 前のフリースローも似たようなことできるんじゃないかと思ってやってみた。 [...]


