package { import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2CircleDef; import Box2D.Collision.Shapes.b2CircleShape; import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Collision.Shapes.b2ShapeDef; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2World; import flash.display.Shape; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFormatAlign; import flash.utils.Timer; import flash.utils.setTimeout; import net.hires.debug.Stats; /** * ... * @author 9re */ [SWF(backgroundColor="#000000", frameRate="30")] public class Impact extends Sprite { private const TIME:int = 250; private var _world:b2World; private var _results:Vector.<Results>; private var _shapes:Vector.<Shape>; private var _bulletShape:Shape; private var _time:int; private var _timer:Timer; private var _progress:TextField; private var _stats:Stats; public function Impact() { Wonderfl.disable_capture(); //Wonderfl.capture_delay(60); _stats = new Stats(); //addChild(_stats); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set( -5, -5); worldAABB.upperBound.Set(200, 100); _world = new b2World(worldAABB, new b2Vec2(0, 9.8), true); var floorDef:b2BodyDef = new b2BodyDef(); floorDef.position.Set(24, 45); var floorShapeDef:b2PolygonDef = new b2PolygonDef(); floorShapeDef.SetAsBox(20, 1); var floor:b2Body = _world.CreateBody(floorDef); floor.CreateShape(floorShapeDef); var tileShape:b2PolygonDef = new b2PolygonDef(); tileShape.SetAsBox(0.25, 0.25); tileShape.density = 8; tileShape.friction = 3; tileShape.restitution = 0.7; var tileDef:b2BodyDef; var tile:b2Body; var i:int, j:int, id:int = 0; for (j = 0; j < 10; ++j) { for (i = 0; i < 50; ++i) { tileDef = new b2BodyDef(); tileDef.position.Set(22 + j / 2, 44 - 0.25 - i / 2); tile = _world.CreateBody(tileDef); tile.CreateShape(tileShape); tile.SetMassFromShapes(); tile.SetUserData( { id: id++ } ); tile.PutToSleep(); } } var bulletDef:b2BodyDef = new b2BodyDef(); bulletDef.position.Set(1, 27); var bulletShapeDef:b2CircleDef = new b2CircleDef(); bulletShapeDef.radius = 1; bulletShapeDef.density = 12; bulletShapeDef.friction = 2; bulletShapeDef.restitution = 0.3; var bullet:b2Body = _world.CreateBody(bulletDef); bullet.CreateShape(bulletShapeDef); bullet.SetMassFromShapes(); bullet.SetLinearVelocity(new b2Vec2(50, 0)); bullet.SetUserData( { id: -1 } ); _results = new Vector.<Results>; _progress = new TextField(); _progress.defaultTextFormat = new TextFormat("_sans", 14, 0xffffff, true, null, null, null, null, TextFormatAlign.CENTER); _progress.width = 465; _progress.y = 200; _progress.selectable = false; addChild(_progress); timerHandler(null); _timer = new Timer(100); _timer.addEventListener(TimerEvent.TIMER, timerHandler); _timer.start(); } private function timerHandler(e:TimerEvent):void { var t:Number = (new Date()).getTime(); var time:Number = t; var b:b2Body; var ud:Object; var i:int, id:int; while (time - t < 75) { _world.Step(1 / 30, 10); i = _results.push(new Results(500)); --i; for (b = _world.GetBodyList(); b; b = b.GetNext()) { ud = b.GetUserData(); if (ud) { id = ud.id; if (id == -1) { _results[i].bulletX = b.GetPosition().x * 10; _results[i].bulletY = b.GetPosition().y * 10; } else { _results[i].xs[id] = b.GetPosition().x * 10; _results[i].ys[id] = b.GetPosition().y * 10; _results[i].rotations[id] = b.GetAngle() * 180 / Math.PI; } } } _progress.text = "calculating: " + makeString(Math.floor(i / TIME * 1000) / 10) + "%"; time = (new Date()).getTime(); } if (_results.length == TIME) { _timer.stop(); _timer.removeEventListener(TimerEvent.TIMER, timerHandler); onCalculationComplete(); removeChild(_progress); } } private function makeString(num:Number):String { var n:int = num; if (n == num) return n + ".0"; return num.toString(); } private function onCalculationComplete():void { _shapes = new Vector.<Shape>(); var shp:Shape; for (var i:int = 0; i < 500; ++i) { shp = new Shape(); shp.graphics.beginFill(0xffffff); shp.graphics.drawRect( -2.5, -2.5, 5, 5); shp.graphics.endFill(); addChild(shp); _shapes.push(shp); } _bulletShape = new Shape(); _bulletShape.graphics.beginFill(0xff0000); _bulletShape.graphics.drawCircle(0, 0, 10); _bulletShape.graphics.endFill(); addChild(_bulletShape); addEventListener(Event.ENTER_FRAME, onEnterFrameHandler); setTimeout(function ():void { Wonderfl.capture(stage); }, 200); } private function onEnterFrameHandler(e:Event):void { var i:int = Math.floor(_results.length * mouseX / 465); i = Math.min(Math.max(0, i), _results.length - 1); var result:Results = _results[i]; var shp:Shape; var len:int = result.length; for (i = 0; i < len; ++i) { shp = _shapes[i]; shp.x = result.xs[i]; shp.y = result.ys[i]; shp.rotation = result.rotations[i]; } _bulletShape.x = result.bulletX; _bulletShape.y = result.bulletY; } } } class Results { public var xs:Vector.<int>; public var ys:Vector.<int>; public var rotations:Vector.<int>; public var bulletX:int; public var bulletY:int; public var length:int; public function Results(numParticles:int) { xs = Vector.<int>(new Array(numParticles)); ys = Vector.<int>(new Array(numParticles)); rotations = Vector.<int>(new Array(numParticles)); length = numParticles; } } Time of Imapct