In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Box2Dの練習

あまり変更しない範囲でなんとかアーティファクトを押さえ込んでみました。
・iterationsを増加
・エレベーターを座標の指定ではなく目標座標への速度を与えて動かしてみた。
・fixedRotationで回転を抑制し、かつ質量をかなり重くして動かないように。
 (1つあたり100トンありますw Infinityが設定できないかと試したけど無理だった)
角度固定のRevolute Jointで間接的に動かしてもいいかもしれません。
もっといい方法があるかも?
Get Adobe Flash player
by k0rin 06 Apr 2009
    Embed
/**
 * Copyright k0rin ( http://wonderfl.net/user/k0rin )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sdpJ
 */

// forked from rsakane's Box2Dの練習

// あまり変更しない範囲でなんとかアーティファクトを押さえ込んでみました。
//
// ・iterationsを増加
// ・エレベーターを座標の指定ではなく目標座標への速度を与えて動かしてみた。
// ・fixedRotationで回転を抑制し、かつ質量をかなり重くして動かないように。
//  (1つあたり100トンありますw Infinityが設定できないかと試したけど無理だった)
//
// 角度固定のRevolute Jointで間接的に動かしてもいいかもしれません。
// もっといい方法があるかも?
package
{
	import Box2D.Collision.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.*;
	import Box2D.Collision.Shapes.*;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;
	import flash.events.Event;
	import flash.utils.*;
	
	[SWF(width="465", height="465", frameRate="30", backgroundColor="0x000000")]
	public class Test extends Sprite
	{
		private var iterations:int = 10;
		private var timeStep:Number = 1.0 / 30.0;
		private var world:b2World;
		private const SCALE:Number = 100;
		
		public function Test()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;  
	        stage.align = StageAlign.TOP_LEFT;
			
			box2dInit();
			addEventListener(Event.ENTER_FRAME, step, false, 0, true);
		}
		
		public function box2dInit():void
		{
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100.0, -100.0);
			worldAABB.upperBound.Set(100.0, 100.0);
			
			var gravity:b2Vec2 = new b2Vec2(0.0, 10);
			var doSleep:Boolean = true;
			
			world = new b2World(worldAABB, gravity, doSleep);
			
			
			var dbgDraw:b2DebugDraw = new b2DebugDraw();
			dbgDraw.m_sprite = this;
			dbgDraw.m_drawScale = SCALE;
			dbgDraw.m_fillAlpha = 0.3;
			dbgDraw.m_lineThickness = 1.0;
			dbgDraw.m_alpha = 1.0;
			dbgDraw.m_xformScale = 1.0
			dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
			world.SetDebugDraw(dbgDraw);
			
			createPolygon(stage.stageWidth / 2 / SCALE, 1.0, 354, 1.1, 0.1);
			createPolygon(stage.stageWidth / 4 / SCALE, 2.1, 20, 1.2, 0.1);
			createPolygon(stage.stageWidth / 2 / SCALE, 3.2, 354, 1.1, 0.1);
			createPolygon(stage.stageWidth / 4 / SCALE, 4.0, 12, 2.3, 0.1);
			createPolygon(0.5, 5.1, 0, 6, 0.5);
			createPolygon(0, stage.stageHeight / 2 / SCALE, 90, stage.stageHeight / 2 / SCALE, 0.1);
			createPolygon(3.32, stage.stageHeight / 2 / SCALE, 90, 1.5, 0.1);
			createPolygon(4.58, stage.stageHeight / 2 / SCALE, 90, stage.stageHeight / 2 / SCALE, 0.1);
			
			
			for (var i:int = 0; i < 14; i++)
			{
				//if (i % 2) createPolygon(3.7, i * 0.4, 0, 0.23, 0.1, "elevator");
				//else       createPolygon(4.2, i * 0.4, 0, 0.23, 0.1, "elevator");
			}
			
			for (i = 0; i < 20; i++)
			{
				createCircle(0.7, -i * 0.05, 0.1, true, 1.0, 0.5);
			}
		}
		
		private function createCircle(posX:Number, posY:Number, radius:Number, setMass:Boolean = false, density:Number = 0.0, restitution:Number = 0.0):void
		{
			var ballBodyDef:b2BodyDef = new b2BodyDef();
			ballBodyDef.position.Set(posX, posY);
			
			var ballShape:b2CircleDef = new b2CircleDef();
			ballShape.radius = radius;
			ballShape.density = density;
			ballShape.restitution = restitution;
			
			var ballBody:b2Body = world.CreateBody(ballBodyDef);
			ballBody.CreateShape(ballShape);
			
			if (setMass) ballBody.SetMassFromShapes();
		}
		
		private function createPolygon(posX:Number, posY:Number, degree:Number, hx:Number, hy:Number, id:String = "", density:Number = 0.0, restitution:Number = 0.0,
									 setMass:Boolean = false):void
		{
			var blockBodyDef:b2BodyDef = new b2BodyDef();
			blockBodyDef.position.Set(posX, posY);
			blockBodyDef.angle = degree * Math.PI / 180;
			if (id)
			{
				blockBodyDef.userData = new Object();
				blockBodyDef.userData.id = id;
				blockBodyDef.userData.posX = posX;
				blockBodyDef.userData.posY = posY;
			}
			blockBodyDef.fixedRotation = true;
			
			var blockShape:b2PolygonDef = new b2PolygonDef();
			blockShape.SetAsBox(hx, hy);
			blockShape.density = density;
			blockShape.restitution = restitution;
			blockShape.filter.groupIndex = -1;
			
			var blockBody:b2Body = world.CreateBody(blockBodyDef);
			blockBody.CreateShape(blockShape);
			
			if (setMass) blockBody.SetMassFromShapes();
		}
		
		private var elevatorCount:int = 0;
		private var elevatorLR:int = 0;
		
		private function step(event:Event):void
		{
			if (++elevatorCount >= 25) {
				elevatorCount = 0;
				elevatorLR = 1 - elevatorLR;
				createPolygon(3.7 + elevatorLR * 0.5, 4.8, 0, 0.23, 0.1, "elevator", 1000000, 0.3, true);
			}
			
			var num:int = 0;
			for (var b2body:b2Body = world.m_bodyList; b2body; b2body = b2body.m_next)
			{
				if (b2body.m_userData)
				{
					if (b2body.m_userData.id == "elevator")
					{
						b2body.m_userData.posY -= 0.02;
						var pos:b2Vec2 = b2body.GetPosition();
						b2body.SetLinearVelocity(new b2Vec2((b2body.m_userData.posX - pos.x) * 10, (b2body.m_userData.posY - pos.y) * 10));
						if (b2body.GetPosition().y < -0.1) world.DestroyBody(b2body);
						if (b2body.GetPosition().y < 0.8) b2body.SetXForm(b2body.GetPosition(), -0.2);
					}
				}
			}
			
			world.Step(timeStep, iterations);
		}
	}
}