用box2d开发奇异吸引子游戏

不知道大家玩过奇异吸引子游戏没有,这个游戏有点类似于打砖块,不过是通过引力把小球吸附过来,再反弹出去,去撞击目标。用了box2d,才发现开发物理游戏,用box2d确实要轻松很多啊。

游戏运行图片:

用box2d开发奇异吸引子游戏_第1张图片


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);
		}
	}
}


你可能感兴趣的:(游戏,function,Class,import,360,actionscript)