Posts Tagged ‘ActionScript3’

Box2DFlashAS3 v2.1a HelloWorld

Box2D demo

Box2D demo

Click the image above for the demo.
Click here or right click on the demo to view the source code.

Inspired by of Box2D running on Android, I decided to dive into this 2D physics engine I have heard so much about.  While the version of Box2D I used is the AS3 version called Box2DFlashAS3, the original version is written in C++.  Basically it very simply lets you apply 2D physics to your objects, or “bodies,” in AS3.

Most of the examples and tutorials I saw were lacking 2 things:

  1. A way to apply sprites to my “bodies” without the use of a flash project (FLA) file.
  2. Code that was compatible with the latest version of Box2DFlashAS3, v2.1a at the time of this post.

So to resolve that situation, or to account for my search engine deficiency, I present the HelloWorld example from the Box2DFlashAS3 2.1a distribution modified to be pure AS3:

package{
package {
  /*
   * Tony Lukasavage - SavageLook.com - 8/18/2010
   * Box2DFlashAS3 2.1a HelloWorld example, minus the need for an accompanying FLA
   *
   * This the basic Box2DFlashAS3 HelloWorld.as file from the source distribution
   * with some adjustments made so that you do not need an FLA file to compile and
   * run the code.  A simple bonus for us pure AS3 guys.  Also a few minor modifications
   * are made to account for changes between version 2.0 and 2.1, like adding a type
   * for body definitions.  Finally, I threw in an click handler to toggle between
   * normal and debug drawing.
   *
   */
 
  import Box2D.Collision.*;
  import Box2D.Collision.Shapes.*;
  import Box2D.Common.Math.*;
  import Box2D.Dynamics.*;
 
  import __AS3__.vec.Vector;
 
  import com.adobe.viewsource.ViewSource;
 
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.geom.Matrix;
  import flash.text.TextField;
  import flash.text.TextFormat;
 
  [SWF(width="800", height="600", frameRate="30")]
  public class box2d extends Sprite
  {
    private var _world:b2World;
    private var _velocityIterations:int = 10;
    private var _positionIterations:int = 10;
    private var _timeStep:Number = 1.0 / 30.0;
    private var _showDebug:Boolean = true;
    private var _debugSprite:Sprite;
    private var _bodySprites:Vector. = new Vector.();
 
    // Box2D uses meters for measurement, AS3 uses pixels.  1 meter = 30 pixels
    public var _worldRatio:int = 30;
 
    public function box2d()
    {
      // Add event for main loop
      addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
      stage.addEventListener(MouseEvent.CLICK, onClick );
 
      // add background gradient
      var bg:Sprite = new Sprite();
      var matrix:Matrix = new Matrix();
      matrix.createGradientBox(stage.stageWidth, stage.stageHeight, Math.PI/2, 0, 0);
      bg.graphics.beginGradientFill("linear", [0x9999ff, 0xffffff], [1, 1], [0, 255], matrix);
      bg.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
      bg.graphics.endFill();
      addChild(bg);
 
      // Define the gravity vector
      var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
 
      // Allow bodies to sleep
      var doSleep:Boolean = true;
 
      // Construct a world object
      _world = new b2World(gravity, doSleep);
 
      // set debug draw
      var debugDraw:b2DebugDraw = new b2DebugDraw();
      _debugSprite = new Sprite();
      addChild(_debugSprite);
      debugDraw.SetSprite(_debugSprite);
      debugDraw.SetDrawScale(_worldRatio);
      debugDraw.SetFillAlpha(0.5);
      debugDraw.SetLineThickness(2);
      debugDraw.SetAlpha(1);
      debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
      _world.SetDebugDraw(debugDraw);
 
      // Vars used to create bodies
      var body:b2Body;
      var bodyDef:b2BodyDef;
      var boxShape:b2PolygonShape;
      var circleShape:b2CircleShape;
 
      // Adding sprite variable for dynamically creating body userData
      var sprite:Sprite;
      var groundHeight:int = 60;
 
      sprite = new Sprite();
      sprite.graphics.lineStyle(1);
      sprite.graphics.beginFill(0x444444);
      sprite.graphics.drawRect(-stage.stageWidth/2, -groundHeight/2, stage.stageWidth, groundHeight);
      sprite.graphics.endFill();
 
      bodyDef = new b2BodyDef();
      bodyDef.type = b2Body.b2_staticBody;
      bodyDef.position.Set(stage.stageWidth / _worldRatio / 2, (stage.stageHeight - sprite.height/2) / _worldRatio);
      bodyDef.userData = sprite;
      addChild(bodyDef.userData);
 
      boxShape = new b2PolygonShape();
      boxShape.SetAsBox(sprite.width/_worldRatio/2, sprite.height/_worldRatio/2);
 
      var fixtureDef:b2FixtureDef = new b2FixtureDef();
      fixtureDef.shape = boxShape;
      fixtureDef.friction = 0.3;
      fixtureDef.density = 0; // static bodies require zero density
 
      body = _world.CreateBody(bodyDef);
      body.CreateFixture(fixtureDef);
 
      // Add some objects
      for (var i:int = 1; i < 20; i++) {
        // create generic body definition
        bodyDef = new b2BodyDef();
        bodyDef.type = b2Body.b2_dynamicBody;
        bodyDef.position.x = Math.random() * 15 + 5;
        bodyDef.position.y = Math.random() * 10;
        var rX:Number = Math.random() + 0.5;
        var rY:Number = Math.random() + 1;
        var spriteX:Number = rX * 30 * 2;
        var spriteY:Number = rY * 30 * 2;
 
        // Box
        if (Math.random() < 0.5) {
          sprite = new Sprite();
          sprite.graphics.lineStyle(1);
          sprite.graphics.beginFill(0xff6666);
          sprite.graphics.drawRect(-spriteX/2, -spriteY/2, spriteX, spriteY);
          sprite.graphics.endFill();
          bodyDef.userData = sprite;
 
          boxShape = new b2PolygonShape();
          boxShape.SetAsBox(rX, rY);
 
          fixtureDef.shape = boxShape;
          fixtureDef.density = 1.0;
          fixtureDef.friction = 0.5;
          fixtureDef.restitution = 0.2;
 
          body = _world.CreateBody(bodyDef);
          body.CreateFixture(fixtureDef);
        }
        // Circle
        else {
          sprite = new Sprite();
          sprite.graphics.lineStyle(1);
          sprite.graphics.beginFill(0x44ff44);
          sprite.graphics.drawCircle(0, 0, spriteX/2);
          sprite.graphics.endFill();
          bodyDef.userData = sprite;
 
          circleShape = new b2CircleShape(rX);
 
          fixtureDef.shape = circleShape;
          fixtureDef.density = 1.0;
          fixtureDef.friction = 0.5;
          fixtureDef.restitution = 0.2;
 
          body = _world.CreateBody(bodyDef);
          body.CreateFixture(fixtureDef);
        }
 
        _bodySprites.push(bodyDef.userData as Sprite);
        addChild(bodyDef.userData);
      }
 
      // enable view source
      ViewSource.addMenuItem(this, "srcview/index.html");
      var text:TextField = new TextField();
      text.text = "Right click to view source";
      text.setTextFormat(new TextFormat("arial", 14, 0, true));
      text.x = 20;
      text.y = 20;
      text.width = 200;
      addChild(text);
    }
 
    public function onClick(e:MouseEvent):void {
      _showDebug = !_showDebug;
      if (!_showDebug) {
        _debugSprite.graphics.clear();
      }
      for each (var sprite:Sprite in _bodySprites) {
        sprite.visible = !_showDebug;
      }
    }
 
    public function Update(e:Event):void{
      _world.Step(_timeStep, _velocityIterations, _positionIterations);
      if (_showDebug) {
        _world.DrawDebugData();
      }
 
      // Go through body list and update sprite positions/rotations
      for (var bb:b2Body = _world.GetBodyList(); bb; bb = bb.GetNext()){
        if (bb.GetUserData() is Sprite){
          var sprite:Sprite = bb.GetUserData() as Sprite;
          sprite.x = bb.GetPosition().x * 30;
          sprite.y = bb.GetPosition().y * 30;
          sprite.rotation = bb.GetAngle() * (180/Math.PI);
        }
      }
    }
  }
}

Very cool stuff that adds lots of possibilities to your Flash projects.  I can’t wait to start playing with the more complex aspects like joints, buoyancy and breakable bodies.  More intensely awesome demos sure to follow.

Webcam Video in Actionscript3

Webcam test in AS3

Click the above picture for the webcam demo (webcam required).
Right click on the demo, or click here for the source code.

This is a pretty simple demo compared to some of my other stuff, but it’s a key point for a lot of them.  Knowing how to use the webcam independently of an existing library can open up lots of options beside augmented reality.  For that reason, I present this small demo showing off how easy it is to do so in Actionscript3.

Here’s a slightly modified excerpt from the full source code that is the meat and potatoes of the demo:

var camera:Camera = Camera.getCamera();
camera.setQuality(0,100);
camera.setMode(800,600,60,true);
 
var video:Video = new Video(800,600);
video.attachCamera(camera);
addChild(video);

As you can see, its as simple as creating a Camera object, attaching it to a Video object and adding the Video object to the main sprite.  The demo will show you how to manipulate image quality, camera frame rate, and viewport size.  For more details on all the properties and methods of each, check out the ASDocs on Camera and Video.

What can you do with this besides making yet another video chat application?  I don’t know about you, but I’m planning an Away3DLite project that will involve multiple levels of “reflection” based on the images from the webcam.  It will be awesome.  Now I just need to figure out how I’m going to do it.  Details…