不知道大家玩過奇異吸引子遊戲沒有,這個遊戲有點類似於打磚塊,不過是通過引力把小球吸附過來,再反彈出去,去撞擊目標。用了box2d,才發現開發物理遊戲,用box2d確實要輕鬆很多啊。
遊戲運行圖片:
actionscript3 代碼
package self{import Box2D.Collision.Shapes.b2CircleShape;import Box2D.Collision.Shapes.b2PolygonShape;import Box2D.Collision.b2AABB;import Box2D.Common.Math.b2Vec2;import Box2D.Dynamics.Joints.b2GearJoint;import Box2D.Dynamics.Joints.b2RevoluteJoint;import Box2D.Dynamics.Joints.b2RevoluteJointDef;import Box2D.Dynamics.b2Body;import Box2D.Dynamics.b2BodyDef;import Box2D.Dynamics.b2DebugDraw;import Box2D.Dynamics.b2FixtureDef;import Box2D.Dynamics.b2World;import flash.display.Sprite;import flash.events.Event;import flash.events.MouseEvent;public class Main2 extends Sprite{private var world:b2World;private var body:b2Body;private var center:b2Body;private var ball:b2Body;private var attractVector:b2Vec2;private var attractAmount:Number = 100;private var isMouseDown:Boolean = false;private var ground:b2Body;public var m_physScale:Number = 30;public function Main2(){addEventListener(Event.ADDED_TO_STAGE,init);}private function init(e:Event):void{createWorld();createDebug();createFixedCenter();createWalls();addEventListener(Event.ENTER_FRAME, loop);stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);attractVector = new b2Vec2();}private function onStageMouseDown(e:MouseEvent):void{//ball.ApplyForce(ball.GetPosition(),center.GetPosition());isMouseDown = true;}private function onStageMouseUp(e:MouseEvent):void{isMouseDown = false;attractVector.SetZero();}private function loop(e:Event):void{if(isMouseDown){var centerVec:b2Vec2 = center.GetWorldCenter();var ballVec:b2Vec2 = ball.GetWorldCenter();var dx:Number = centerVec.x-ballVec.x;var dy:Number = centerVec.y-ballVec.y;var dx2:Number = dx>0 ? dx : -dx;var dy2:Number = dy>0 ? dy : -dy;attractVector.x = attractAmount * dx/(dx2+dy2);attractVector.y = attractAmount * dy/(dx2+dy2);ball.ApplyForce(attractVector,ball.GetWorldCenter());}graphics.clear();world.Step(1/30, 10,10);world.ClearForces();world.DrawDebugData();}private function createWorld():void{//2.聲明重力var gravity:b2Vec2 = new b2Vec2(0.0, 0.0);//3.睡著的對象是否類比var doSleep:Boolean = true;//4.建立b2World世界world = new b2World(gravity, doSleep);world.SetWarmStarting(true);ball = createBall(625,15,15,1);createBall(550,35,25,1);createBall(150,55,45,0.8);createBall(222,133,32,1.8);createBall(310,40,30,1.0);createBall(120,340,50,.1);createSquare(550,230,0);createSquare(470,200,0);createSquare(70,240,0);ground = world.GetGroundBody();creatRevoluteJoint();}private function createDebug():void{var debugDraw:b2DebugDraw = new b2DebugDraw();debugDraw.SetSprite(this);debugDraw.SetDrawScale(30.0);debugDraw.SetFillAlpha(0.3);debugDraw.SetLineThickness(1.0);debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);world.SetDebugDraw(debugDraw);}private function createSquare(posX:Number,posY:Number,angle:Number):void{var bodyRequest:b2BodyDef = new b2BodyDef();bodyRequest.type = b2Body.b2_dynamicBody;bodyRequest.angle = angle;bodyRequest.position.Set(posX / 30, posY / 30);body=world.CreateBody(bodyRequest);var shapeRequest:b2PolygonShape = new b2PolygonShape();shapeRequest.SetAsBox(22/m_physScale,22/m_physScale);var fixtureRequest:b2FixtureDef = new b2FixtureDef();fixtureRequest.shape=shapeRequest;fixtureRequest.density = 0.5;fixtureRequest.restitution = 1;body.CreateFixture(fixtureRequest);body.SetLinearDamping(0.1);body.SetAngularDamping(0.1);}private function createBall(posX:Number,posY:Number,radius:Number,density:Number,isFixed:Boolean=false):b2Body{//1.建立剛體需求b2BodyDefvar bodyRequest:b2BodyDef = new b2BodyDef();if(isFixed){bodyRequest.type = b2Body.b2_staticBody;}else{bodyRequest.type = b2Body.b2_dynamicBody;}bodyRequest.position.Set(posX / 30, posY / 30);//記得米和像素的轉換關係//2.Box2D世界工廠更具需求建立createBody()生產剛體body=world.CreateBody(bodyRequest);//3.建立敢提形狀需求b2ShapeDef的子類var shapeRequest:b2CircleShape = new b2CircleShape(radius/m_physScale);var fixtureRequest:b2FixtureDef = new b2FixtureDef();fixtureRequest.shape=shapeRequest;fixtureRequest.density = density;fixtureRequest.restitution = 1;//4.b2Body剛體工廠根據需求createShape生產形狀body.CreateFixture(fixtureRequest);body.SetLinearDamping(0.2);body.SetAngularDamping(0.2);return body;}private function createFixedCenter():void{center = createBall(320,200,40,0,true);}//建立移動關節private function creatRevoluteJoint():void{var rect:b2PolygonShape = new b2PolygonShape();rect.SetAsBox(10/m_physScale,20/m_physScale);var fixtureDef:b2FixtureDef = new b2FixtureDef();fixtureDef.shape = rect;fixtureDef.density = 0.3;var bd1:b2BodyDef = new b2BodyDef();bd1.type = b2Body.b2_dynamicBody;bd1.position.Set(200 / m_physScale, 360/2 / m_physScale);var body1:b2Body = world.CreateBody(bd1);body1.CreateFixture(fixtureDef);body1.SetAngularDamping(0.4);var jd1:b2RevoluteJointDef = new b2RevoluteJointDef();jd1.Initialize(ground, body1, bd1.position);world.CreateJoint(jd1);}private function createWalls():void{var wall:b2PolygonShape= new b2PolygonShape();var wallBd:b2BodyDef = new b2BodyDef();var wallB:b2Body;// LeftwallBd.position.Set( -95 / m_physScale, 360 / m_physScale / 2);wall.SetAsBox(100/m_physScale, 400/m_physScale/2);wallB = world.CreateBody(wallBd);wallB.CreateFixture2(wall);// RightwallBd.position.Set((640 + 95) / m_physScale, 360 / m_physScale / 2);wallB = world.CreateBody(wallBd);wallB.CreateFixture2(wall);// TopwallBd.position.Set(640 / m_physScale / 2, -95 / m_physScale);wall.SetAsBox(680/m_physScale/2, 100/m_physScale);wallB = world.CreateBody(wallBd);wallB.CreateFixture2(wall);// BottomwallBd.position.Set(640 / m_physScale / 2, (360 + 95) / m_physScale);wallB = world.CreateBody(wallBd);wallB.CreateFixture2(wall);}}}