Math and (Quasi) Physics in Action Script 3

Box 2D - simulation of thrown blocks

A physical simulation of tetris blocks thrown into the air

Clicking on the stage restarts the movie.

Main.as

´╗┐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 flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;



  public class Main extends Sprite {
    private var world:b2World;
    private var fps:uint;
    private var cnt:uint = 0;
    public function Main():void {
      fps = stage.frameRate;
      stage.addEventListener(MouseEvent.CLICK, init);
      addEventListener(Event.ENTER_FRAME, h_enterFrame);
      init();
    }
    private function init(event:MouseEvent = null):void {

      // create the world
      var worldAABB:b2AABB = new b2AABB();
      worldAABB.lowerBound.Set(-10, -10);
      worldAABB.upperBound.Set(10, 10);
      var gravity:b2Vec2 = new b2Vec2(0,10);
      world = new b2World(worldAABB,gravity,true);

      // create a floor box
      var floorBodyDef:b2BodyDef = new b2BodyDef();
      floorBodyDef.position.Set(3.5, 4.5);
      var floorShapeDef:b2PolygonDef = new b2PolygonDef();
      floorShapeDef.SetAsBox(1.5, 0.05);
      var floor:b2Body = world.CreateBody(floorBodyDef);
      floor.CreateShape(floorShapeDef);

      var debugDraw:b2DebugDraw = new b2DebugDraw();
      debugDraw.m_sprite = this;
      debugDraw.m_drawScale = 100;
      debugDraw.m_fillAlpha = 0.3;
      debugDraw.m_lineThickness = 1;
      debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
      world.SetDebugDraw(debugDraw);
    }

    private function h_enterFrame(event:Event):void {
      if (world == null) {
        return;
      }
      
      if (++ cnt % 10 == 0) {
        var block = createBlock();
      }
      world.Step(1 / fps, 10);
    }
    
    private function createBlock() {
      var blockBodyDef:b2BodyDef;
      var blockShapeDef:b2PolygonDef;
      var blockBody:b2Body;
      blockBodyDef = new b2BodyDef();

      var blockDef:Array = [
            [[0,0],[0.2,0],[0.2,0.2],[0,0.2]],
            [[0.2,0],[0.4,0],[0.6,0],[0.8,0]],
            [[0,0],[0,0.2],[0,0.4],[0.2,0.2]],
            [[0,0],[0.2,0],[0.2,0.2],[0.4,0.2]],
            [[0,0.2],[0.2,0.2],[0.2,0],[0.4,0]]
            ]
        var i:uint, j:uint;
        
        blockBodyDef.position.Set(6, 3);
        blockBody = world.CreateBody(blockBodyDef);
        
        j = Math.random() * blockDef.length;
          
        
        for (i = 0; i < blockDef[j].length; i ++) {
            blockShapeDef = new b2PolygonDef();
            blockShapeDef.vertexCount = 4;
            
            blockShapeDef.vertices[0].Set(blockDef[j][i][0], blockDef[j][i][1]);
            blockShapeDef.vertices[1].Set(blockDef[j][i][0] + 0.2, blockDef[j][i][1]);
            blockShapeDef.vertices[2].Set(blockDef[j][i][0] + 0.2, blockDef[j][i][1] + 0.2);
            blockShapeDef.vertices[3].Set(blockDef[j][i][0], blockDef[j][i][1] + 0.2);
            blockShapeDef.density = 1;
            blockShapeDef.restitution = 0.4;
            blockBody.CreateShape(blockShapeDef);
        }
        
        blockBody.SetMassFromShapes();
        blockBody.SetLinearVelocity(new b2Vec2( - Math.random() * 5, - Math.random() * 5 - 2));
        blockBody.ApplyTorque(Math.random() / 5 - 0.2);
        return blockBody;
    }
  }
}