不知道大家玩过奇异吸引子游戏没有,这个游戏有点类似于打砖块,不过是通过引力把小球吸附过来,再反弹出去,去撞击目标。用了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);
}
}
}
本文介绍了一个使用Box2D物理引擎开发的游戏,该游戏通过引力操控小球进行弹射以撞击目标。文章提供了ActionScript 3代码示例,展示了如何创建动态刚体、固定点以及各种关节。

4537

被折叠的 条评论
为什么被折叠?



