前回に引き続きBox2DFlashAS3で遊んでいます。
四角の一人ボール遊びです。
画面をクリックした後、「←」「→」で左右移動、「s」キーでジャンプです。
「s」キー連打で多段ジャンプ可w
前回より、ちゃんと部屋のサイズとか考えて作りました。天井は吹き抜けですが。
四角を右と左に動かす際、加速の感じを出すために、
イーズアウト・イーズインの公式を使いました。
といっても見つけてきただけです。
■イージングの公式いろいろ
http://www.actionscript.org/forums/showthread.php3?t=42833
■Flash Tweener の イージングパターン
http://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html
easeInOutQuadの式
ACTIONSCRIPT:
- /**
- * t = time
- * b = beginning value
- * c = change in value
- * d = duration
- */
- public function easeInOutQuad(t:Number, b:Number, c:Number, d:Number):Number {
- if ((t/=d/2) <1) return c/2*t*t + b;
- return -c/2 * ((--t)*(t-2) - 1) + b;
- };
この関数を使ってm_linearVelocityで与える力の加減を計算しています。
キーを離したときの減速は、Box2Dの摩擦計算に任せているので何もしないでOK。ラクチン。
昔の人はこういうライブラリなしで、ファミコン容量でゼロからマリオとか作ったわけよね。
スゲー!
↓ ソース全部
ACTIONSCRIPT:
- package src {
- import Box2D.Collision.b2AABB;
- import Box2D.Collision.b2ContactID;
- import Box2D.Collision.Shapes.b2CircleDef;
- 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 Box2D.Dynamics.Contacts.b2ContactEdge;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.events.KeyboardEvent;
- import flash.events.MouseEvent;
- import flash.events.TextEvent;
- import flash.text.TextField;
- import flash.ui.Keyboard;
- /**
- * @author okm
- */
- public class LabyrinsSuite extends Sprite{
- private var world:b2World;
- private var square:b2Body;
- public function LabyrinsSuite() {
- var textField:TextField = new TextField;
- textField.text = "click me ";
- textField.x = 100;
- textField.y = 100;
- textField.selectable = false;
- this.addChild(textField);
- stage.addEventListener(MouseEvent.CLICK, go);
- }
- public function go(event:MouseEvent):void {
- stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
- stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
- ////////////////////////////////////////
- // 物理エンジンのセットアップ
- // 縦横200メートルの世界を作成
- 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);
- /////////////////////////////////////////////
- // 部屋の作成 横幅 12M 高さ 8M の部屋を作成
- /////////////////////////////////////////////
- // 床
- // 天井の高さは 8M 床の 中心X座標は 7.5M(真ん中)
- var floorBodyDef:b2BodyDef = new b2BodyDef();
- floorBodyDef.position.Set(6, 8);
- // 床の形を、幅12m、厚さ20cmとする
- // 指定するのはその半分の値
- var floorShapeDef:b2PolygonDef = new b2PolygonDef();
- floorShapeDef.friction = 0.1;
- floorShapeDef.SetAsBox(6, 0.1);
- // 床を動かない物体として作る
- var floor:b2Body = world.CreateBody(floorBodyDef);
- floor.CreateShape(floorShapeDef);
- // 両端の壁 高さは 8M 幅 10cm
- // 左壁
- var leftWallBodyDef:b2BodyDef = new b2BodyDef();
- leftWallBodyDef.position.Set(0.05, 4);
- var wallShapeDef:b2PolygonDef = new b2PolygonDef();
- wallShapeDef.friction = 0;
- wallShapeDef.SetAsBox(0.05, 4);
- var leftWall:b2Body = world.CreateBody(leftWallBodyDef);
- leftWall.CreateShape(wallShapeDef);
- // 右壁
- var rightWallBodyDef:b2BodyDef = new b2BodyDef();
- rightWallBodyDef.position.Set(11.95, 4);
- var rightWall:b2Body = world.CreateBody(rightWallBodyDef);
- rightWall.CreateShape(wallShapeDef);
- ////////////////////////////////////////
- // 箱生命体
- ////////////////////////////////////////
- // 箱の位置を左から2.5m、上から1mとする
- var boxBodyDef:b2BodyDef = new b2BodyDef();
- boxBodyDef.position.Set(2.5, 1);
- // 箱の幅 60cm 高さ 1M 重さは 30kg とする
- var boxShapeDef:b2PolygonDef= new b2PolygonDef();
- //boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0.8);
- boxShapeDef.SetAsBox(0.6, 1);
- boxShapeDef.density = 50; // 密度 [kg/m^2] 30/0.6*1
- boxShapeDef.friction = 0.2; // 摩擦係数
- boxShapeDef.restitution = 0.3; // 反発係数、通常は0~1
- // 箱を動く物体として作る
- var boxBody:b2Body = world.CreateBody(boxBodyDef);
- boxBody.CreateShape(boxShapeDef);
- // SetMassFromShapes で重力が有効になる
- boxBody.SetMassFromShapes();
- square = boxBody;
- // ボール
- var circleDef:b2CircleDef = new b2CircleDef;
- circleDef.radius = 0.5;
- circleDef.density = 0.5;
- circleDef.friction = 0.5;
- circleDef.restitution = 0.5;
- var circleBD:b2BodyDef = new b2BodyDef();
- circleBD.position.Set(2.7,0.5);
- var circle:b2Body = world.CreateBody(circleBD);
- circle.CreateShape(circleDef);
- circle.SetMassFromShapes();
- ////////////////////////////////////////
- // 描画設定
- var debugDraw:b2DebugDraw = new b2DebugDraw();
- debugDraw.m_sprite = this;
- debugDraw.m_drawScale = 45; // 1mを45ピクセルにする
- debugDraw.m_fillAlpha = 0.3; // 不透明度
- debugDraw.m_lineThickness = 1; // 線の太さ
- debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
- world.SetDebugDraw(debugDraw);
- this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
- }
- private var m_InputL:Number = 0;
- private var m_InputR:Number = 0;
- private var m_InputS:Number = 0;
- private var m_Dir:Number = 0;
- private var moveTime:Number = 0;
- // キーが押されたときの処理
- private function keyDownHandler(event:KeyboardEvent):void {
- square.WakeUp();
- if(event.keyCode == Keyboard.LEFT && m_InputL != 1){
- m_InputL = 1;
- m_InputR = 0;
- m_Dir = -1.0;
- moveTime = 0;
- }
- if(event.keyCode == Keyboard.RIGHT && m_InputR != 1){
- m_InputR = 1;
- m_InputL = 0;
- m_Dir = 1.0;
- moveTime = 0;
- }
- if(event.keyCode == 83){ // s
- m_InputS = 1;
- }
- }
- private function keyUpHandler(event:KeyboardEvent):void {
- if(event.keyCode == Keyboard.LEFT){
- m_InputL = 0;
- }
- if(event.keyCode == Keyboard.RIGHT){
- m_InputR = 0;
- }
- if(event.keyCode == 83){ // s
- m_InputS = 0;
- }
- }
- private function enterFrameHandler(event:Event):void {
- if (m_InputS == 1) {
- square.m_linearVelocity.y = -4;
- }
- if (m_InputL> 0) {
- var leftForce:Number = this.easeInOutQuad(moveTime, 0.5, 6, 30);
- if (moveTime <30) moveTime++;
- square.m_linearVelocity.x = -leftForce;
- }
- if (m_InputR> 0) {
- var rightForce:Number = this.easeInOutQuad(moveTime, 0.5, 6, 30);
- if (moveTime <30) moveTime++;
- square.m_linearVelocity.x = rightForce;
- }
- if (world == null) {
- return;
- }
- // Flashはデフォルトで秒間24フレームなので、
- // 物理シミュレーションを1/24秒進める
- world.Step(1 / 24, 10);
- }
- /**
- * t = time
- * b = beginning value
- * c = change in value
- * d = duration
- */
- public function easeInOutQuad(t:Number, b:Number, c:Number, d:Number):Number {
- if ((t/=d/2) <1) return c/2*t*t + b;
- return -c/2 * ((--t)*(t-2) - 1) + b;
- };
- }
- }
- Newer: Box2d で降りしきる箱と戯れる箱
- Older: 物理エンジン Box2DFlashAS3 を使ってみる
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://parpue.net/web/33/trackback
- Listed below are links to weblogs that reference
- Box2Dで 四角の一人ボール遊び from parpue.net


