不知道大家玩过奇异吸引子游戏没有,这个游戏有点类似于打砖块,不过是通过引力把小球吸附过来,再反弹出去,去撞击目标。用了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.创建刚体需求b2BodyDef var 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; // Left wallBd.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); // Right wallBd.position.Set((640 + 95) / m_physScale, 360 / m_physScale / 2); wallB = world.CreateBody(wallBd); wallB.CreateFixture2(wall); // Top wallBd.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); // Bottom wallBd.position.Set(640 / m_physScale / 2, (360 + 95) / m_physScale); wallB = world.CreateBody(wallBd); wallB.CreateFixture2(wall); } } }