forked from: flash on 2010-12-30
♥1 |
Line 221 |
Modified 2010-12-31 01:36:54 |
MIT License
archived:2017-03-20 20:14:48
ActionScript3 source code
/**
* Copyright takashi08 ( http://wonderfl.net/user/takashi08 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uowx
*/
// forked from takashi08's flash on 2010-12-30
package
{
import Box2D.Collision.Shapes.b2PolygonDef;
import Box2D.Collision.b2AABB;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.Joints.b2MouseJoint;
import Box2D.Dynamics.Joints.b2MouseJointDef;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2World;
import com.adobe.viewsource.ViewSource;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Point;
import org.papervision3d.core.effects.BitmapLayerEffect;
import org.papervision3d.core.effects.utils.BitmapClearMode;
import org.papervision3d.core.effects.utils.BitmapDrawCommand;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.view.BasicView;
import org.papervision3d.view.layer.BitmapEffectLayer;
[SWF(backgroundColor="0x000000")]
public class Box2D_PV3D3 extends BasicView
{
// Box2D用の変数
private var worldWidth:Number;
private var worldHeight:Number;
private var m_iterations:int;
private var m_wallWidth:Number;
private var m_wallHeight:Number;
private var m_timeStep:Number;
private var m_physScale:Number;
private var m_world:b2World;
private var m_mouseJoint:b2MouseJoint;
private var m_draggedBody:b2Body;
private var mouseXWorldPhys:Number;
private var mouseYWorldPhys:Number;
private var Box2DShapeArray:Array;
private var IsMouseDown:Boolean;
private var arrayPosition:int;
// PV3D用の変数
private var rootNode:DisplayObject3D;
private var cubeSize:int;
private var pv3d_height:Number;
public function Box2D_PV3D3()
{
// ソースビューの設定とステージの設定
ViewSource.addMenuItem(this, "srcview/index.html");
stage.quality=StageQuality.HIGH;
stage.align=StageAlign.TOP_LEFT;
stage.scaleMode=StageScaleMode.NO_SCALE;
stage.frameRate = 40;
// PV3Dの基本設定
super(0, 0, true, true);
cubeSize = 100;
pv3d_height = 80;
rootNode=scene.addChild(new DisplayObject3D("rootNode"));
camera.zoom=1000/camera.focus+1;
camera.target=DisplayObject3D.ZERO;
camera.x=400;
// ライトの設定
var light:PointLight3D=new PointLight3D(true);
light.z=-100;
// Box2Dの基本設定
worldWidth=stage.stageWidth;
worldHeight=stage.stageHeight;
m_iterations=30;
m_timeStep=1/40;
m_physScale=30;
var worldAABB:b2AABB = new b2AABB;
worldAABB.lowerBound.Set(-1000.0,-1000.0);
worldAABB.upperBound.Set(1000.0,1000.0);
var gravity:b2Vec2=new b2Vec2(0.0,30.0);
var doSleep:Boolean=true;
m_world=new b2World(worldAABB,gravity,doSleep);
// Box2Dの世界の壁を作成(今回はサイズ固定)
var wallShapeDef:b2PolygonDef=new b2PolygonDef();
var wallBodyDef:b2BodyDef=new b2BodyDef();
var wall:b2Body;
m_wallWidth = 1400;
m_wallHeight = 300;
// 左の壁
wallShapeDef.SetAsBox(10/m_physScale, m_wallHeight/2/m_physScale);
wallBodyDef.position.Set(0, m_wallHeight/2/m_physScale);
wall=m_world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
// 右の壁
wallBodyDef.position.Set(m_wallWidth/m_physScale, m_wallHeight/2/m_physScale);
wall=m_world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
// 上の壁
wallShapeDef.SetAsBox(m_wallWidth/2/m_physScale, 10/m_physScale);
wallBodyDef.position.Set(m_wallWidth/2/m_physScale, 0);
wall=m_world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
// 下の壁
wallBodyDef.position.Set(m_wallWidth/2/m_physScale, m_wallHeight/m_physScale);
wall=m_world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
wall.SetMassFromShapes();
// PV3DとBox2DでBoxを作成する
Box2DShapeArray=new Array();
var colorArray:Array = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xffffff];
for(var i:int=0; i < 5; i++)
{
// Cubeの作成して、rootNodeに追加
var mat:FlatShadeMaterial=new FlatShadeMaterial(light, colorArray[i] as uint);
mat.interactive=true;
var matList:MaterialsList=new MaterialsList({all:mat});
var cube:Cube=new Cube(matList, cubeSize,cubeSize, cubeSize);
cube.extra={width:cubeSize/2, height:cubeSize/2, arrayPos:i};
cube.x=(i * 150) - 300;
cube.y=10;
cube.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, onGetArrayPosition);
rootNode.addChild(cube);
// Box2Dの世界に箱を作りだし、PV3DのCubeを持たせる
var boxShape:b2PolygonDef=new b2PolygonDef();
boxShape.SetAsBox(cubeSize/2/m_physScale, cubeSize/2/m_physScale);
boxShape.density=8;
boxShape.friction=8;
boxShape.restitution=0.5;
var bodyDef:b2BodyDef=new b2BodyDef();
bodyDef.position.Set((cube.x + worldWidth/2)/m_physScale, (cube.y + worldHeight/2)/m_physScale);
var body:b2Body=m_world.CreateBody(bodyDef);
body.CreateShape(boxShape);
body.SetUserData(cube);
body.SetMassFromShapes();
// 作成した箱はArrayに格納する
Box2DShapeArray[i]=body;
}
// ドラッグに利用する変数の初期化
arrayPosition = -1;
IsMouseDown = false;
// 各イベントの追加
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(Event.RESIZE, onResize);
// Box2Dのデバッグ
// setDebug();
}
// リサイズ用関数。リサイズ後のサイズを獲得する。
private function onResize(e:Event):void
{
worldWidth=stage.stageWidth;
worldHeight=stage.stageHeight;
}
// Box2Dのデバッグ用の関数
public function setDebug():void
{
var dbgDraw:b2DebugDraw=new b2DebugDraw;
var dbgSprite:Sprite=new Sprite;
addChild(dbgSprite);
dbgDraw.m_sprite=dbgSprite;
dbgDraw.m_drawScale=30;
dbgDraw.m_fillAlpha=0.5;
dbgDraw.m_lineThickness=0;
dbgDraw.m_drawFlags=0xFFFFFFFF;
m_world.SetDebugDraw(dbgDraw);
}
// マウスの座標を獲得し、Box2D用に変換する関数
private function updateMouseWorld():void
{
mouseXWorldPhys = mouseX/m_physScale;
mouseYWorldPhys = (mouseY+pv3d_height)/m_physScale;
}
// フレームイベント用関数
private function onEnterFrame(event:Event):void
{
// Box2Dのステップの更新
updateMouseWorld();
mouseDrag();
m_world.Step(m_timeStep, m_iterations);
// Box2Dのオブジェクトの座標をPV3Dのオブジェクトに反映
for(var bb:b2Body=m_world.GetBodyList(); bb; bb=bb.GetNext())
{
if (bb.GetUserData()is DisplayObject3D)
{
bb.GetUserData().x=bb.GetPosition().x * m_physScale - worldWidth / 2;
bb.GetUserData().y=-bb.GetPosition().y * m_physScale + worldHeight / 2 + pv3d_height;
bb.GetUserData().rotationZ=-bb.GetAngle() * (180 / Math.PI);
}
}
// カメラを動かし、PV3Dのレンダリング
camera.x+=(viewport.containerSprite.mouseX - camera.x) * 0.05;
singleRender();
}
// クリックされたPV3Dオブジェクトの配列番号を獲得する関数
private function onGetArrayPosition(event:InteractiveScene3DEvent):void
{
arrayPosition = (event.target as DisplayObject3D).extra.arrayPos;
}
// ドラッグアンドドロップ用の関数
private function mouseDrag():void
{
if (IsMouseDown && ! m_mouseJoint)
{
m_draggedBody=null;
if (arrayPosition > -1)
m_draggedBody=Box2DShapeArray[arrayPosition];
if (m_draggedBody)
{
var md:b2MouseJointDef=new b2MouseJointDef();
md.body1=m_world.GetGroundBody();
md.body2=m_draggedBody;
md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
md.maxForce=300.0 * m_draggedBody.GetMass();
md.timeStep=m_timeStep;
m_mouseJoint=m_world.CreateJoint(md)as b2MouseJoint;
m_draggedBody.WakeUp();
}
}
if (!IsMouseDown)
{
if ( m_mouseJoint)
{
m_world.DestroyJoint( m_mouseJoint);
m_mouseJoint=null;
}
}
if ( m_mouseJoint)
{
var p2:b2Vec2=new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
m_mouseJoint.SetTarget(p2);
}
}
// マウスダウン用の関数
private function onMouseDown(event:MouseEvent):void
{
IsMouseDown=true;
}
// マウスアップ用の関数
private function onMouseUp(event:MouseEvent):void
{
IsMouseDown=false;
arrayPosition=-1;
}
}
}