一度、WorldAABBから出てしまうと、ジョイントできなくなるっぽい。

by mtok
...
@author ...
♥2 | Line 221 | Modified 2009-10-23 02:17:08 | MIT License
play

ActionScript3 source code

/**
 * Copyright mtok ( http://wonderfl.net/user/mtok )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6xKd
 */

package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	/**
	 * ...
	 * @author ...
	 */
	public class Box2DTest3 extends Sprite
	{
		
		public function Box2DTest3() 
		{
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
		}
		
		private function addedToStageHandler(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			initialize()
		}
		
		private function initialize():void
		{
			var app:Main = new Main();
			addChild(app);
		}
	}
}

import Box2D.Collision.b2Bound;
import Box2D.Collision.Shapes.b2CircleShape;
import Box2D.Collision.Shapes.b2PolygonDef;
import Box2D.Collision.Shapes.b2Shape;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.Joints.b2DistanceJoint;
import Box2D.Dynamics.Joints.b2DistanceJointDef;
import flash.display.Sprite;
import flash.events.Event;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2World;
import Box2D.Collision.b2AABB;
import flash.events.MouseEvent;
import flash.utils.getTimer;
import Box2D.Dynamics.Joints.b2MouseJointDef;
import Box2D.Dynamics.Joints.b2MouseJoint;

class BaseSprite extends Sprite {
	protected var _world:b2World;
	private var _isDebug:Boolean = true;
	private var _debugDraw:b2DebugDraw;
	protected var _dt:Number;
	public function BaseSprite() {		
		addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
	}
	
	private function addedToStageHandler(e:Event):void 
	{
		removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
		beforeInitialize();
		
		_dt = 1 / stage.frameRate;
		var g:b2Vec2 = new b2Vec2(0, 10);
		var worldAABB:b2AABB = new b2AABB();
		worldAABB.lowerBound.Set(0,0);
		worldAABB.upperBound.Set(465, 465);
		
		_world = new b2World(worldAABB, g, true);
		
		buildScene(_world);
		
		if (_isDebug) {
			_debugDraw = new b2DebugDraw();
			_debugDraw.m_sprite = new Sprite();
			_debugDraw.m_drawScale = 1;
			_debugDraw.m_fillAlpha = 0.25;
			_debugDraw.m_lineThickness = 1;
			addChild(_debugDraw.m_sprite);
			_debugDraw.m_drawFlags = /*DebugDraw.e_aabbBit | DebugDraw.e_centerOfMassBit | DebugDraw.e_coreShapeBit | DebugDraw.e_obbBit | DebugDraw.e_pairBit |*/ b2DebugDraw.e_shapeBit| b2DebugDraw.e_jointBit ;
			_world.SetDebugDraw(_debugDraw);
		}

		addEventListener(Event.ENTER_FRAME, enterFrameHanlder);
	}
	
	private function enterFrameHanlder(e:Event):void 
	{
		step();
	}
	protected function buildScene(world:b2World):void {
		
	}
	protected function beforeInitialize():void {
		
	}
	protected function step():void {
		_world.Step(_dt, 5);
	}
	
	public function get isDebug():Boolean { return _isDebug; }
	public function set isDebug(value:Boolean):void 
	{
		_isDebug = value;
	}
}

import Box2D.Dynamics.Joints.b2Joint;
import Box2D.Dynamics.Joints.b2JointDef;
import Box2D.Collision.Shapes.b2CircleDef;
class Main extends BaseSprite {
	private var _mouseJoint:b2MouseJoint;
	public function Main(){
		super();
	}
	
	private function mouseDownHanlder(e:MouseEvent):void 
	{
		stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		var body:b2Body = getBodyAtMouse();
		if (body) {
			var mjd:b2MouseJointDef = new b2MouseJointDef();
			mjd.body1 = _world.GetGroundBody();
			mjd.body2 = body;
			mjd.target.Set(mouseX, mouseY);
			mjd.maxForce = body.GetMass() * 4000;
			mjd.timeStep = _dt;
			body.WakeUp();
			_mouseJoint = _world.CreateJoint(mjd) as b2MouseJoint;
		}
		
		stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
	}
	override protected function beforeInitialize():void 
	{
		stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHanlder);
	}
	private function mouseMoveHandler(e:MouseEvent):void 
	{
		if (e.buttonDown) {
			if (_mouseJoint) {
				_mouseJoint.m_target.x = mouseX;
				_mouseJoint.m_target.y = mouseY;
			}
		}else {
			mouseUpHandler();
		}
	}
	
	private function mouseUpHandler(e:MouseEvent = null):void 
	{
		stage.removeEventListener(e.type, arguments.callee);
		stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
		deleteMouseJoint();
	}
	private function deleteMouseJoint():void {
		if (_mouseJoint) {
			_world.DestroyJoint(_mouseJoint);
			_mouseJoint = null;
		}		
	}
	private function getBodyAtMouse():b2Body {
		trace('getBodyAtMouse');
		
		var body:b2Body = null;
		var range:Number = 10;
		var shapes:Array = [];
		var aabb:b2AABB = new b2AABB();
		aabb.lowerBound.Set(mouseX - range, mouseY - range);
		aabb.upperBound.Set(mouseX + range, mouseY + range);
		
		var shape:b2Shape;
		var resultCount:int;
		resultCount = _world.Query(aabb, shapes, 10);
		if (resultCount > 0) {
			for (var i:int = 0; i < resultCount; i++) {
				shape = shapes[i] as b2Shape;
				body = shape.GetBody();
				break;
			}
		}
		return body;
		
	}
	override protected function buildScene(world:b2World):void 
	{
		buildGround(world);
		buildChaine(world);
	}
	
	private function buildChaine(world:b2World):void
	{
		var len:int = 20;
		var sw:Number = stage.stageWidth;
		var sh:Number = stage.stageHeight;
		var yPos:Number = 50;
		var bDef:b2BodyDef;
		var body:b2Body;
		var bodys:Array = [];
		
		var shape:b2CircleDef = new b2CircleDef();
		shape.density = 10;
		shape.friction = 0.3;
		shape.restitution = 0.7;
		shape.radius = 10;
		
		for (var i:int = 0; i < len; i++) {
			bDef = new b2BodyDef();
			bDef.position.Set(sw * 0.5, yPos);
			body = world.CreateBody(bDef);
			
			body.CreateShape(shape);
			body.SetMassFromShapes();
			yPos += 20;
			
			bodys.push(body);
		}
		
		var jointDef:b2DistanceJointDef
		var joint:b2DistanceJoint;
		body = bodys[0] as b2Body;
		if (body) {
			jointDef = new b2DistanceJointDef();
			jointDef.Initialize(
				world.GetGroundBody(), body,
				new b2Vec2(sw*0.5,0), body.GetPosition());
				
			joint = world.CreateJoint(jointDef) as b2DistanceJoint;
		}
		for ( i = 1; i < len; i++) {
			var b1:b2Body = bodys[i-1] as b2Body;
			var b2:b2Body = bodys[i] as b2Body;
			jointDef = new b2DistanceJointDef();
			jointDef.Initialize(b1, b2, b1.GetPosition(), b2.GetPosition());
			world.CreateJoint(jointDef);
		}
		
	}
	
	private function buildGround(world:b2World):void
	{
		var sw:Number = stage.stageWidth;
		var sh:Number = stage.stageHeight;
		var bodyWidth:Number = sw + 20;
		var bodyHeight:Number = 60;
		var bodyDef:b2BodyDef = new b2BodyDef();
		bodyDef.position.Set(bodyWidth *.5, sh + bodyHeight - 5 );
		var ground:b2Body = world.CreateBody(bodyDef);
		
		var groundShape:b2PolygonDef = new b2PolygonDef();
		groundShape.SetAsBox( bodyWidth, bodyHeight);
		//groundShape.density = 1;
		ground.CreateShape(groundShape);
		
		ground.SetMassFromShapes();
	}
}