Home > Flash | WEB > Box2d で風雨に揺れる葉っぱのようなもの

Box2d で風雨に揺れる葉っぱのようなもの

なんか夏休みろくにとれなかったので、
最近インドネシアはバリ島に遊びに行ってました。

バリ島は雨季が近いということでスコールも1度味わってきました。

というわけで、雨と風にたなびく葉っぱのようなものを強引にBox2Dで作ってみました。
雨粒のあたり判定が甘いのは仕様です。
ちょっとこれを使ってまた別のものを作ろうと考えています。

↓ 以下、種明かしのようなもの

これをみると、いかに強引かがわかりますね。
ただBox2Dを使うことで、強引でも簡単にそれっぽいものができると思います。

 

今回は回転ジョイントを用意し、常に葉っぱの先端部分の棒が右回転する力を加えました。
その棒に対して、重りを加え、ときどき重りに下向きの力を加えることによって、
風を受けている感じを表現している・・・つもりです。

以下ソースコード・・・強引です。

FlowLeafを呼び出す Box2DWorldTestクラス

ACTIONSCRIPT:
  1. package {
  2.     import Box2D.Collision.Shapes.b2CircleDef;
  3.     import Box2D.Collision.Shapes.b2PolygonDef;
  4.     import Box2D.Collision.b2AABB;
  5.     import Box2D.Common.Math.b2Vec2;
  6.     import Box2D.Dynamics.b2Body;
  7.     import Box2D.Dynamics.b2BodyDef;
  8.     import Box2D.Dynamics.b2DebugDraw;
  9.     import Box2D.Dynamics.b2World;
  10.    
  11.     import flash.display.Sprite;
  12.     import flash.display.StageAlign;
  13.     import flash.events.Event;
  14.     import flash.events.MouseEvent;
  15.     import flash.utils.*;
  16.    
  17.     public class Box2DWorldTest extends Sprite
  18.     {
  19.         private var world:b2World;
  20.         private var floor:b2Body;
  21.         private var leafArea:Sprite;
  22.         private var dropArea:Sprite;
  23.        
  24.        
  25.         private var drop:b2Body;
  26.         private var circleDef:b2BodyDef;
  27.         private var dropShapeDef:b2CircleDef;
  28.        
  29.         private var f1:FlowLeaf;
  30.         private var f2:FlowLeaf;
  31.         private var f3:FlowLeaf;
  32.        
  33.         public function Box2DWorldTest()
  34.         {
  35.             stage.scaleMode = "noScale";
  36.             stage.align = StageAlign.TOP_LEFT;
  37.            
  38.             leafArea = new Sprite;
  39.             dropArea = new Sprite;
  40.            
  41.             this.addChild(dropArea);
  42.             this.addChild(leafArea);
  43.  
  44.             // 縦横200メートルの世界を作成
  45.             var worldAABB:b2AABB = new b2AABB();
  46.             worldAABB.lowerBound.Set(-100, -100);
  47.             worldAABB.upperBound.Set(100, 100);
  48.            
  49.             // 重力を下方向に10m/s^2とする 今回は風の感じで右方向にも1m/s^2
  50.             var gravity:b2Vec2 = new b2Vec2(-1, 10);
  51.            
  52.             // 外枠と重力を指定して、物理エンジン全体をセットアップする
  53.             world = new b2World(worldAABB, gravity, true);
  54.            
  55.             f1 = new FlowLeaf(5, 7, 2, 4, 0.5, world, "leaf");
  56.             leafArea.addChild(f1);
  57.             f2 = new FlowLeaf(4, 7, 2, 3, 0.5, world, "leaf");
  58.             leafArea.addChild(f2);
  59.             f3 = new FlowLeaf(3, 7, 2, 3, 0.5, world, "leaf");
  60.             leafArea.addChild(f3);
  61.            
  62.             var debugDraw:b2DebugDraw = new b2DebugDraw;
  63.             debugDraw.m_sprite = this;
  64.             debugDraw.m_drawScale = 45; // 1mを45ピクセルにする
  65.             debugDraw.m_fillAlpha = 60; // 不透明度
  66.             debugDraw.m_lineThickness = 2; // 線の太さ
  67.             debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
  68.            
  69.             world.SetDebugDraw(debugDraw);
  70.            
  71.             this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  72.            
  73.             circleDef = new b2BodyDef();
  74.             circleDef.userData = new Object;
  75.             circleDef.userData.id = "circle";
  76.                
  77.             var spt:Sprite = new Sprite;
  78.             spt.graphics.lineStyle(1, 0x6481F5);
  79.             spt.graphics.beginFill(0x6481f5, 50);
  80.             spt.graphics.drawCircle( 0, 0, 4 );
  81.             spt.graphics.endFill();
  82.             spt.y = -10;
  83.             circleDef.userData.spt = spt;
  84.             dropArea.addChild(spt);
  85.                
  86.             var randomX = Math.floor(Math.random()*(240))+100;
  87.             circleDef.position.Set(randomX / 45, -10);
  88.            
  89.             dropShapeDef = new b2CircleDef;
  90.             dropShapeDef.radius = 0.15;
  91.             dropShapeDef.restitution = 0.2;
  92.             dropShapeDef.density = 0.5;
  93.            
  94.             drop = world.CreateBody(circleDef);
  95.             drop.CreateShape(dropShapeDef);
  96.             drop.SetMassFromShapes();
  97.  
  98.             setInterval(dropRain, 2500);
  99.            
  100.         }
  101.        
  102.         private function dropRain():void{
  103.             world.DestroyBody(drop);
  104.             var randomX:Number = Math.floor(Math.random()*(240))+100;
  105.    
  106.             circleDef.position.Set(randomX / 45, -10 / 45);
  107.  
  108.             drop = world.CreateBody(circleDef);
  109.             drop.CreateShape(dropShapeDef);
  110.            
  111.             drop.SetMassFromShapes();
  112.    
  113.                
  114.         }
  115.        
  116.         private function enterFrameHandler(event:Event):void {
  117.                    
  118.             for (var bb:b2Body = world.m_bodyList; bb; bb = bb.m_next) {
  119.                     
  120.                  if (bb.m_userData != null && bb.m_userData.spt is Sprite) {
  121.                      bb.m_userData.spt.x = bb.GetPosition().x * 45;
  122.                      bb.m_userData.spt.y = bb.GetPosition().y * 45;
  123.                  }
  124.              }
  125.            
  126.          var random = Math.floor(Math.random()*10)+1;
  127.              if(random == 1){
  128.                 f1.wind(2);
  129.                 f2.wind(2);
  130.                 f3.wind(2);
  131.             }
  132.             world.Step(1 / 24, 10);
  133.         }
  134.     }
  135. }

FlowLeaf 葉っぱ一枚分

ACTIONSCRIPT:
  1. package
  2. {
  3.     import Box2D.Collision.Shapes.b2CircleDef;
  4.     import Box2D.Collision.Shapes.b2PolygonDef;
  5.     import Box2D.Common.Math.b2Vec2;
  6.     import Box2D.Dynamics.Joints.b2DistanceJointDef;
  7.     import Box2D.Dynamics.Joints.b2RevoluteJoint;
  8.     import Box2D.Dynamics.Joints.b2RevoluteJointDef;
  9.     import Box2D.Dynamics.b2Body;
  10.     import Box2D.Dynamics.b2BodyDef;
  11.     import Box2D.Dynamics.b2World;
  12.    
  13.     import flash.display.Sprite;
  14.     import flash.events.Event;
  15.     import flash.utils.*;
  16.    
  17.     public class FlowLeaf extends Sprite
  18.     {
  19.         private var flowBody:b2Body;
  20.         private var fixedBody:b2Body;
  21.         private var sinker:b2Body;
  22.         private var _height:Number;
  23.         private var _width:Number
  24.         private var _x:Number;
  25.         private var _y:Number;
  26.         private var barSize:Number;
  27.         private var bend:Number;
  28.        
  29.         public function FlowLeaf(x:Number,y:Number,width:Number, height:Number, bend:Number, world:b2World, id:String):void
  30.         {
  31.             barSize = width/10;
  32.            
  33.             this.x = 45 * x;
  34.             this.y = 45 * y;
  35.             this._height = height;
  36.             this._width = width;
  37.             this._x = x;
  38.             this._y = y;
  39.             this,bend = bend;
  40.            
  41.             var fixedBodyDef:b2BodyDef = new b2BodyDef;
  42.             fixedBodyDef.userData = new Object;
  43.             fixedBodyDef.userData.id = id;
  44.             fixedBodyDef.position.Set(x - barSize * 0.5, y - height * bend * 0.5);
  45.            
  46.             var fixedBodyPolygonDef:b2PolygonDef = new b2PolygonDef();
  47.             fixedBodyPolygonDef.friction = 0.1;
  48.             fixedBodyPolygonDef.density = 0.1;
  49.             fixedBodyPolygonDef.SetAsBox(barSize * 0.5, height * bend * 0.5);
  50.            
  51.             fixedBodyPolygonDef.filter.maskBits = 0x01;
  52.             fixedBodyPolygonDef.filter.categoryBits = 0x01;   
  53.            
  54.             fixedBody = world.CreateBody(fixedBodyDef);
  55.             fixedBody.CreateShape(fixedBodyPolygonDef);
  56.            
  57.             var flowBodyDef:b2BodyDef = new b2BodyDef;
  58.             flowBodyDef.userData = new Object;
  59.             flowBodyDef.userData.id = id;
  60.             flowBodyDef.position.Set(x - width, y - height);
  61.            
  62.             var flowBodyPolygonDef:b2PolygonDef = new b2PolygonDef;
  63.             flowBodyPolygonDef.vertices[0].Set(0,0);
  64.             flowBodyPolygonDef.vertices[1].Set(barSize*2, 0);
  65.             flowBodyPolygonDef.vertices[2].Set(width , height - height * bend);
  66.             flowBodyPolygonDef.vertices[3].Set(width -barSize*2, height - height * bend);
  67.             flowBodyPolygonDef.vertexCount = 4;
  68.             flowBodyPolygonDef.friction = 0.5;
  69.             flowBodyPolygonDef.density = 0.1;
  70.  
  71.           flowBody = world.CreateBody(flowBodyDef);
  72.           flowBody.CreateShape(flowBodyPolygonDef);
  73.           flowBody.SetMassFromShapes();
  74.           
  75.           var sinkerBodyDef:b2BodyDef = new b2BodyDef;
  76.           sinkerBodyDef.userData = new Object;
  77.           sinkerBodyDef.userData.id = id + "_sinker";
  78.           sinkerBodyDef.position.Set(x - width +barSize , y - height * bend);
  79.              
  80.           var sinkerShapeDef:b2CircleDef = new b2CircleDef;
  81.           sinkerShapeDef.radius = barSize;
  82.           sinkerShapeDef.density = 0.5;
  83.           sinkerShapeDef.filter.maskBits = 0x00;
  84.           
  85.           sinker = world.CreateBody(sinkerBodyDef);
  86.           sinker.CreateShape(sinkerShapeDef);
  87.  
  88.           sinker.SetMassFromShapes();
  89.              
  90.             var jointDef:b2RevoluteJointDef = new b2RevoluteJointDef;
  91.             jointDef.motorSpeed = 0.3;
  92.             jointDef.maxMotorTorque = 5;
  93.             jointDef.enableMotor = true;
  94.             jointDef.lowerAngle = -20 * Math.PI / 180;
  95.             jointDef.upperAngle = 15 * Math.PI / 180;
  96.             jointDef.enableLimit = true;
  97.       jointDef.Initialize(fixedBody, flowBody, new b2Vec2(flowBody.GetPosition().x + width - barSize / 2, flowBody.GetPosition().y + height * bend));
  98.       var joint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));     
  99.       var sinkerJointDef:b2DistanceJointDef = new b2DistanceJointDef;
  100.       sinkerJointDef.Initialize(flowBody, sinker, flowBody.GetPosition(), sinker.GetPosition());
  101.       var sinkerJoint = world.CreateJoint(sinkerJointDef);
  102.       
  103.       this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  104.         }
  105.        
  106.         private function enterFrameHandler(event:Event){
  107.             this.graphics.clear();
  108.             this.graphics.lineStyle(1,0x66FF66);
  109.             this.graphics.beginFill(0xCCFFCC, 0.8);
  110.             this.graphics.curveTo(0, - _height * 0.8 * 45,(flowBody.GetPosition().x - _x ) * 45, (flowBody.GetPosition().y - _y )* 45);
  111.             this.graphics.curveTo(0 - barSize * 4 * 45, - _height * 0.8 * 45,0 - barSize * 4 * 45, 0);
  112.             this.graphics.lineTo(0,0);
  113.             this.graphics.endFill();
  114.            
  115.         }
  116.        
  117.         public function wind(power:Number):void{
  118.             sinker.m_linearVelocity.y = power;
  119.         }
  120.  
  121.     }
  122. }

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://parpue.net/web/329/trackback
Listed below are links to weblogs that reference
Box2d で風雨に揺れる葉っぱのようなもの from parpue.net

Home > Flash | WEB > Box2d で風雨に揺れる葉っぱのようなもの

リンク
chocolataste-planner
millon

サーチ
Feeds
Meta
blog ranking ブログランキング・にほんブログ村へ
にほんブログ村 テクノラティのお気に入りに追加する

Return to page top