/**
* Copyright tepe ( http://wonderfl.net/user/tepe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/mK7U
*/
package {
import Box2D.Collision.b2AABB;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.Joints.*;
import flash.display.*;
import flash.events.*;
import flash.text.*;
public class CarFinal extends Sprite {
// 物理エンジン内の1mを表すためのピクセル数
private static const DRAW_SCALE:Number = 100;
// 物理エンジンの管理クラス
private var world:b2World;
// 車体
private var body:b2Body;
// 前輪
private var frontWheel:b2Body;
// 後輪
private var rearWheel:b2Body;
// マウスジョイントの定義
private var mouseJointDef:b2MouseJointDef;
// マウスジョイント
private var mouseJoint:b2MouseJoint;
private var txt1:TextField = new TextField();
private function debugDraw():void {
var debugDraw:b2DebugDraw = new b2DebugDraw();
debugDraw.m_sprite = this;
debugDraw.m_drawScale = DRAW_SCALE;
debugDraw.m_fillAlpha = 0.3;
debugDraw.m_lineThickness = 1;
debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
world.SetDebugDraw(debugDraw);
}
public function CarFinal() {
////////////////////////////////////////
// 物理エンジンのセットアップ
// 外枠を定義する
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100, -100);
worldAABB.upperBound.Set(100, 100);
txt1.text = "aaa";
addChild(txt1);
var gravity:b2Vec2 = new b2Vec2(0, 9.8);//重力方向
// 外枠と重力を指定して、物理エンジン全体をセットアップする
world = new b2World(worldAABB, gravity, true);
debugDraw();
////////////////////////////////////////
// 床の設置
// 床は画面の下のほうに設置します
// 床の位置を左から2.5m、上から3mとする
var floorBodyDef:b2BodyDef = new b2BodyDef();
floorBodyDef.position.Set(2.5, 3);
// 床の形を、幅4m、厚さ20cmとする
// 指定するのはその半分の値
var floorShapeDef:b2PolygonDef = new b2PolygonDef();
floorShapeDef.SetAsBox(2, 0.1);
// 床を動かない物体として作る
var floor:b2Body = world.CreateBody(floorBodyDef);
floor.CreateShape(floorShapeDef);
// 床の画像を作る
var floorImage:Sprite = new Sprite();
floorImage.graphics.lineStyle(1,0x000000);
floorImage.graphics.beginFill(0xff0000,0.2);
floorImage.graphics.drawRect(0,0,100,100);
floorImage.graphics.endFill();
//======================
//▼床(静体)の生成
//BodyDefの設定
var bdFloor:b2BodyDef = new b2BodyDef();
bdFloor.position.Set(2, 2);//初期位置
//ShapeDefの設定
var pdFloor:b2PolygonDef = new b2PolygonDef();
pdFloor.SetAsBox(1.5, 0.15);
//ボディの生成
var bFloor:b2Body = world.CreateBody(bdFloor);
bFloor.CreateShape(pdFloor);
addBox();
addBall(2);
// 画像のサイズを合わせる
floorImage.width = 4 * DRAW_SCALE;
floorImage.height = 0.2 * DRAW_SCALE;
// 床の中心が(0, 0)に来るように,左上にずらす
floorImage.x = -floorImage.width / 2;
floorImage.y = -floorImage.height / 2;
// b2BodyのユーザデータとしてSpriteを作る
floor.m_userData = new Sprite();
// Spriteの場所を物理エンジン内の場所と一致させる
floor.GetUserData().x = floor.GetWorldCenter().x * DRAW_SCALE;
floor.GetUserData().y = floor.GetWorldCenter().y * DRAW_SCALE;
floor.GetUserData().addChild(floorImage);
addChild(floor.GetUserData());
////////////////////////////////////////
// 車体(body)を作る
// 幅が80cm、高さが20cmで、場所は床の中心から少し上のところ
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.position.Set(2.5, 2);
var bodyShape:b2PolygonDef = new b2PolygonDef();
bodyShape.SetAsBox(0.4, 0.1);
bodyShape.density = 1;
body = world.CreateBody(bodyDef);
body.CreateShape(bodyShape);
body.SetMassFromShapes();
// 車体の画像を読み込んで表示する
var bodyImage:Sprite = new Sprite();
bodyImage.graphics.lineStyle(1,0x000000);
bodyImage.graphics.beginFill(0x00ff00,0.2);
bodyImage.graphics.drawRect(0,0,100,100);
bodyImage.graphics.endFill();
bodyImage.width = 0.8 * DRAW_SCALE;
bodyImage.height = 0.2 * DRAW_SCALE;
bodyImage.x = -bodyImage.width / 2;
bodyImage.y = -bodyImage.height / 2;
body.m_userData = new Sprite();
body.GetUserData().x = body.GetWorldCenter().x * DRAW_SCALE;
body.GetUserData().y = body.GetWorldCenter().y * DRAW_SCALE;
body.GetUserData().addChild(bodyImage);
addChild(body.GetUserData());
////////////////////////////////////////
// 前輪(frontWheel)を作る
// bodyDefは再利用できる
bodyDef.position.Set(2.8, 2);
var wheelShape:b2CircleDef = new b2CircleDef();
wheelShape.radius = 0.15;
wheelShape.density = 1;
frontWheel = world.CreateBody(bodyDef);
frontWheel.CreateShape(wheelShape);
frontWheel.SetMassFromShapes();
//world.DestroyBody(floor);
//removeChild(floor.m_userData);
// 前輪の画像を読み込んで表示する
var frontWheelImage:Sprite = new Sprite();
frontWheelImage.graphics.lineStyle(1,0x000000);
frontWheelImage.graphics.beginFill(0x00ffff);
//frontWheelImage.graphics.drawRect(0,0,20,20);
frontWheelImage.graphics.drawCircle(20,20,20);
frontWheelImage.graphics.moveTo(20,20);
frontWheelImage.graphics.lineTo(10,0);
frontWheelImage.graphics.endFill();
frontWheelImage.width = 0.3 * DRAW_SCALE;
frontWheelImage.height = 0.3 * DRAW_SCALE;
frontWheelImage.x = -frontWheelImage.width / 2;
frontWheelImage.y = -frontWheelImage.height / 2;
frontWheel.m_userData = new Sprite();
frontWheel.GetUserData().x = frontWheel.GetWorldCenter().x * DRAW_SCALE;
frontWheel.GetUserData().y = frontWheel.GetWorldCenter().y * DRAW_SCALE;
frontWheel.GetUserData().addChild(frontWheelImage);
addChild(frontWheel.GetUserData());
////////////////////////////////////////
// 後輪(rearWheel)を作る
bodyDef.position.Set(2.2, 2);
// wheelShapeも再利用できる
rearWheel = world.CreateBody(bodyDef);
rearWheel.CreateShape(wheelShape);
rearWheel.SetMassFromShapes();
// 後輪の画像を読み込んで表示する
var rearWheelImage:Sprite = new Sprite();
rearWheelImage.graphics.lineStyle(1,0x000000);
rearWheelImage.graphics.beginFill(0xffff00);
rearWheelImage.graphics.drawCircle(20,20,20);
rearWheelImage.graphics.endFill();
//線
rearWheelImage.graphics.moveTo(20,20);
rearWheelImage.graphics.lineTo(10,0);
rearWheelImage.width = 0.3 * DRAW_SCALE;
rearWheelImage.height = 0.3 * DRAW_SCALE;
rearWheelImage.x = -rearWheelImage.width / 2;
rearWheelImage.y = -rearWheelImage.height / 2;
rearWheel.m_userData = new Sprite();
rearWheel.GetUserData().x = rearWheel.GetWorldCenter().x * DRAW_SCALE;
rearWheel.GetUserData().y = rearWheel.GetWorldCenter().y * DRAW_SCALE;
rearWheel.GetUserData().addChild(rearWheelImage);//
addChild(rearWheel.GetUserData());
////////////////////////////////////////
// 車体と前輪をつなぐ
// ジョイントを定義するjointDef変数
var jointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
// つながれる2つの物体と、つなぐ位置(前輪の中央)を使って、定義を初期化する
jointDef.Initialize(body, frontWheel, frontWheel.GetWorldCenter());
// 回転速度の設定(6で1秒に1回転ぐらい)
jointDef.motorSpeed = 3;
// トルクの設定(大きいほど坂道に強くなる)
jointDef.maxMotorTorque = 1;
// 車輪を回すようにする
//jointDef.enableMotor = true;
// 回転ジョイントを作る
var frontJoint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));
////////////////////////////////////////
// 車体と後輪をつなぐ
// つながれる2つの物体と、つなぐ位置(後輪の中央)を使って、定義を初期化する
jointDef.Initialize(body, rearWheel, rearWheel.GetWorldCenter());
// 回転ジョイントを作る
var rearJoint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));
////////////////////////////////////////
setMouseJoint();
// イベントハンドラを登録する
addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
private function setMouseJoint():void{
// マウスジョイントの定義を作る
mouseJointDef = new b2MouseJointDef();
mouseJointDef.body1 = world.GetGroundBody();
mouseJointDef.body2 = body;
mouseJointDef.target = body.GetWorldCenter();
mouseJointDef.maxForce = 105;
mouseJointDef.timeStep = 1 / 24;
}
private function addBall(x:Number=0,y:Number=0):void{
//▼ボール(動体)の生成------------------
var _bBall:b2Body;
var bdBall:b2BodyDef = new b2BodyDef();
bdBall.position.Set(x,y);
//ShapeDefの設定
var pdBall:b2CircleDef = new b2CircleDef();
pdBall.radius = 0.25;
pdBall.density = 1;//密度(1平方メートルあたりの重量(kg))
pdBall.restitution = 0.9;//反発係数(通常0~1)
//ボディの生成
_bBall = world.CreateBody(bdBall);
_bBall.CreateShape(pdBall);
//質量の設定
_bBall.SetMassFromShapes();
}
private function addBox():void{
//~~~~~~~~~~~~~~~~▼箱(動体)の生成
var _bBox:b2Body;
var bdBox:b2BodyDef = new b2BodyDef();
bdBox.position.Set(5.5 / 2, 1);
//ShapeDefの設定
var pdBox:b2PolygonDef = new b2PolygonDef();
pdBox.SetAsBox(0.2, 0.2);//形状
pdBox.density = 10000;//密度(1平方メートルあたりの重量(kg))
//ボディの生成
_bBox = world.CreateBody(bdBox);
_bBox.CreateShape(pdBox);
//質量の設定
_bBox.SetMassFromShapes();
}
private function mouseMove(e:MouseEvent):void {
if (mouseJoint) {
// マウスが押された場所を物理エンジン内の座標系に変換する
var x:Number = e.stageX / DRAW_SCALE;
var y:Number = e.stageY / DRAW_SCALE;
// マウスジョイントのカーソル位置を更新
mouseJoint.SetTarget(new b2Vec2(x, y));
}
}
private function mouseDown(e:MouseEvent):void {
mouseJoint = b2MouseJoint(world.CreateJoint(mouseJointDef));
}
private function mouseUp(event:MouseEvent):void {
world.DestroyJoint(mouseJoint);
mouseJoint = null;
}
//フレーム
private function onFrame(e:Event):void {
// ワールド内の全てのb2Bodyに対する処理
for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) {
if (b.GetUserData() is Sprite) {
// 物理エンジン内での位置と回転角度を反映させる
b.GetUserData().x = b.GetWorldCenter().x * DRAW_SCALE;
b.GetUserData().y = b.GetWorldCenter().y * DRAW_SCALE;
b.GetUserData().rotation = b.GetAngle() * 180 / Math.PI;
if(b.IsFrozen()){
world.DestroyBody(body);
removeChild(body.m_userData);
txt1.text = "Lost";
}
}
}
// Flashはデフォルトで秒間24フレームなので、
// 物理シミュレーションを1/24秒進める
world.Step(1 / 24, 10);
}
}
}