Box2D platform engine alternative
¡¡2009-10-18 00:00:00¡¡À´Ô´£ºWEB¿ª·¢Íø¡¡¡¡¡¡At line 5 the script imports levels (just one in this example) coded in this way:
package¡¡Levels¡¡{
¡¡
¡¡public¡¡class¡¡Level1¡¡extends¡¡GameLevel¡¡{
¡¡
¡¡¡¡public¡¡function¡¡Level1(k:keys)¡¡{
¡¡¡¡¡¡////¡¡Always¡¡remember¡¡to¡¡call¡¡the¡¡superior¡¡constructor¡¡first!
¡¡¡¡¡¡super(k);
¡¡
¡¡¡¡¡¡////¡¡The¡¡player:
¡¡¡¡¡¡createPlayer(250,¡¡50);
¡¡
¡¡¡¡¡¡////¡¡The¡¡moveable¡¡blocks:
¡¡¡¡¡¡addBox(110,¡¡110,¡¡50,¡¡50);
¡¡¡¡¡¡addBox(190,¡¡200,¡¡30,¡¡50);
¡¡¡¡¡¡addBox(100,¡¡50,¡¡120,¡¡20);
¡¡¡¡¡¡//¡¡Small¡¡see-saw:
¡¡¡¡¡¡addBox(400,¡¡250,¡¡30,¡¡30);
¡¡¡¡¡¡addBox(400,¡¡220,¡¡200,¡¡10);
¡¡¡¡¡¡addBox(480,¡¡200,¡¡20,¡¡20);
¡¡
¡¡¡¡¡¡////¡¡The¡¡ground¡¡block:
¡¡¡¡¡¡addStaticBox(550/2,¡¡300,¡¡550,¡¡20);
¡¡¡¡}
¡¡}
}
At line 10 the script calls the most important class, GameLevel, that’s made this way:
package¡¡{
¡¡import¡¡flash.display.Sprite;
¡¡
¡¡import¡¡Box2D.Dynamics.*;
¡¡import¡¡Box2D.Collision.*;
¡¡import¡¡Box2D.Collision.Shapes.*;
¡¡import¡¡Box2D.Common.Math.*;
¡¡
¡¡//¡¡Main¡¡Game¡¡Level¡¡class¡¡definition
¡¡public¡¡class¡¡GameLevel¡¡extends¡¡Sprite¡¡{
¡¡¡¡//¡¡Player:
¡¡¡¡public¡¡var¡¡playerBody:b2Body;¡¡¡¡
¡¡¡¡public¡¡var¡¡player:Player;
¡¡¡¡//¡¡Jump¡¡trigger:
¡¡¡¡public¡¡var¡¡upDown:Boolean¡¡=¡¡false;
¡¡
¡¡¡¡//¡¡Misc:
¡¡¡¡public¡¡var¡¡lastBody:b2Body;
¡¡
¡¡¡¡//¡¡Vars¡¡used¡¡to¡¡create¡¡bodies
¡¡¡¡public¡¡var¡¡body:b2Body;
¡¡¡¡public¡¡var¡¡bodyDef:b2BodyDef;
¡¡¡¡public¡¡var¡¡boxDef:b2PolygonDef;
¡¡¡¡public¡¡var¡¡circleDef:b2CircleDef;
¡¡
¡¡¡¡//¡¡Keyboard¡¡listener:
¡¡¡¡public¡¡var¡¡keyboard:keys;
¡¡
¡¡¡¡public¡¡function¡¡GameLevel(k:keys)¡¡{
¡¡¡¡¡¡keyboard¡¡=¡¡k;
¡¡
¡¡¡¡¡¡//¡¡World¡¡Setup:
¡¡¡¡¡¡var¡¡worldAABB:b2AABB¡¡=¡¡new¡¡b2AABB();
¡¡¡¡¡¡worldAABB.lowerBound.Set(-100.0,¡¡-100.0);
¡¡¡¡¡¡worldAABB.upperBound.Set(100.0,¡¡100.0);
¡¡
¡¡¡¡¡¡//¡¡Define¡¡the¡¡gravity¡¡vector
¡¡¡¡¡¡var¡¡gravity:b2Vec2¡¡=¡¡new¡¡b2Vec2(0.0,¡¡10.0);
¡¡
¡¡
¡¡¡¡¡¡//¡¡Allow¡¡bodies¡¡to¡¡sleep
¡¡¡¡¡¡var¡¡doSleep:Boolean¡¡=¡¡true;
¡¡
¡¡¡¡¡¡//¡¡Construct¡¡a¡¡world¡¡object
¡¡¡¡¡¡m_world¡¡=¡¡new¡¡b2World(worldAABB,¡¡gravity,¡¡doSleep);
¡¡
¡¡¡¡¡¡player¡¡=¡¡new¡¡Player();
¡¡¡¡}
¡¡
¡¡
¡¡
¡¡
¡¡¡¡public¡¡function¡¡Update()¡¡{
¡¡¡¡¡¡//¡¡Wake¡¡up¡¡the¡¡player¡¡body,¡¡if¡¡it¡¡falls¡¡asleep,¡¡the¡¡player¡¡cannot
¡¡¡¡¡¡//¡¡move¡¡anymore!
¡¡¡¡¡¡playerBody.WakeUp();
¡¡
¡¡¡¡¡¡//¡¡Jump:
¡¡¡¡¡¡if(keyboard.is_up()){
¡¡¡¡¡¡¡¡//¡¡Cheesy¡¡way¡¡to¡¡check¡¡if¡¡the¡¡button¡¡was¡¡hit,¡¡instead¡¡of¡¡being¡¡held¡¡down:
¡¡¡¡¡¡¡¡if(upDown¡¡==¡¡false){
¡¡¡¡¡¡¡¡¡¡var¡¡b1:b2Body¡¡=¡¡GetBodyAtPoint(player.x,¡¡player.y¡¡+¡¡player.height/2,¡¡true);
¡¡¡¡¡¡¡¡¡¡var¡¡b2:b2Body¡¡=¡¡GetBodyAtPoint(player.x-7,¡¡player.y¡¡+¡¡player.height¡¡-¡¡4,¡¡true);
¡¡¡¡¡¡¡¡¡¡var¡¡b3:b2Body¡¡=¡¡GetBodyAtPoint(player.x+7,¡¡player.y¡¡+¡¡player.height¡¡-¡¡4,¡¡true);
¡¡¡¡¡¡¡¡¡¡if((b1¡¡!=¡¡playerBody¡¡&&¡¡b2¡¡!=¡¡playerBody¡¡&&¡¡b3¡¡!=¡¡playerBody)¡¡&&¡¡b1¡¡!=¡¡null¡¡||¡¡b2¡¡!=¡¡null¡¡||¡¡b3¡¡!=¡¡null¡¡&&¡¡playerBody.m_linearVelocity.y¡¡>=¡¡0){
¡¡¡¡¡¡¡¡¡¡¡¡var¡¡DO¡¡=¡¡true;
¡¡
¡¡¡¡¡¡¡¡¡¡¡¡if(DO){
¡¡¡¡¡¡¡¡¡¡¡¡¡¡playerBody.ApplyImpulse(new¡¡b2Vec2(0,¡¡-10),¡¡playerBody.GetPosition());//playerBody.m_linearVelocity.y¡¡=¡¡-10;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡//¡¡If¡¡you¡¡want¡¡the¡¡underliying¡¡body¡¡to¡¡react¡¡according¡¡to¡¡Newton's
¡¡¡¡¡¡¡¡¡¡¡¡¡¡//¡¡second¡¡law¡¡of¡¡motion¡¡(it's¡¡pushed¡¡down),¡¡uncoment¡¡the¡¡following¡¡laws:
¡¡¡¡¡¡¡¡¡¡¡¡¡¡/*var¡¡bo¡¡=¡¡(b1¡¡!=¡¡null¡¡?¡¡b1¡¡:¡¡(b2¡¡!=¡¡null¡¡?¡¡b2¡¡:¡¡b3));
¡¡¡¡¡¡¡¡¡¡¡¡¡¡bo.ApplyImpulse(new¡¡b2Vec2(0,¡¡10),¡¡playerBody.GetPosition());*/
¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡upDown¡¡=¡¡true;
¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡}else{
¡¡¡¡¡¡¡¡upDown¡¡=¡¡false;
¡¡¡¡¡¡}
¡¡
¡¡¡¡¡¡//¡¡Side¡¡movements:
¡¡¡¡¡¡if(keyboard.is_right()){
¡¡¡¡¡¡¡¡playerBody.m_linearVelocity.x¡¡=¡¡3;
¡¡¡¡¡¡}
¡¡¡¡¡¡if(keyboard.is_left()){
¡¡¡¡¡¡¡¡playerBody.m_linearVelocity.x¡¡=¡¡-3;
¡¡¡¡¡¡}
¡¡
¡¡¡¡¡¡//¡¡Sted¡¡the¡¡world:
¡¡¡¡¡¡m_world.Step(m_timeStep,¡¡m_iterations);
¡¡
¡¡¡¡¡¡//¡¡Go¡¡through¡¡body¡¡list¡¡and¡¡update¡¡sprite¡¡positions/rotations
¡¡¡¡¡¡for¡¡(var¡¡bb:b2Body¡¡=¡¡m_world.m_bodyList;¡¡bb;¡¡bb¡¡=¡¡bb.m_next){
¡¡¡¡¡¡¡¡if¡¡(bb.m_userData¡¡is¡¡Sprite){
¡¡¡¡¡¡¡¡¡¡bb.m_userData.x¡¡=¡¡bb.GetPosition().x¡¡*¡¡30;
¡¡¡¡¡¡¡¡¡¡bb.m_userData.y¡¡=¡¡bb.GetPosition().y¡¡*¡¡30;
¡¡¡¡¡¡¡¡¡¡bb.m_userData.rotation¡¡=¡¡bb.GetAngle()¡¡*¡¡(180/Math.PI);
¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡}
¡¡¡¡}
¡¡
¡¡
¡¡
¡¡¡¡//¡¡Create¡¡the¡¡player¡¡using¡¡this¡¡function,¡¡_x¡¡and¡¡_y¡¡are¡¡the¡¡coordinates¡¡to¡¡place
¡¡¡¡//¡¡the¡¡object:
¡¡¡¡public¡¡function¡¡createPlayer(_x,¡¡_y)¡¡:¡¡b2Body¡¡{
¡¡¡¡¡¡bodyDef¡¡=¡¡new¡¡b2BodyDef();
¡¡¡¡¡¡bodyDef.position.x¡¡=¡¡_x¡¡/¡¡30;
¡¡¡¡¡¡bodyDef.position.y¡¡=¡¡_y¡¡/¡¡30;
¡¡¡¡¡¡circleDef¡¡=¡¡new¡¡b2CircleDef();
¡¡¡¡¡¡circleDef.radius¡¡=¡¡30¡¡/¡¡2¡¡/¡¡30;
¡¡¡¡¡¡circleDef.density¡¡=¡¡1.0;
¡¡¡¡¡¡circleDef.friction¡¡=¡¡1;
¡¡¡¡¡¡circleDef.restitution¡¡=¡¡0.1;
¡¡¡¡¡¡var¡¡mass:b2MassData¡¡=¡¡new¡¡b2MassData;
¡¡¡¡¡¡mass.mass¡¡=¡¡1;
¡¡¡¡¡¡bodyDef.userData¡¡=¡¡player;
¡¡¡¡¡¡player.x¡¡=¡¡_x;
¡¡¡¡¡¡player.y¡¡=¡¡_y;
¡¡¡¡¡¡addChild(player);
¡¡¡¡¡¡body¡¡=¡¡m_world.CreateDynamicBody(bodyDef);
¡¡¡¡¡¡body.SetMass(mass);
¡¡¡¡¡¡body.CreateShape(circleDef);
¡¡¡¡¡¡body.m_linearDamping¡¡=¡¡1;
¡¡¡¡¡¡playerBody¡¡=¡¡body;
¡¡
¡¡¡¡¡¡return¡¡playerBody;
¡¡¡¡}
¡¡
¡¡¡¡//¡¡Using¡¡this¡¡function,¡¡you¡¡can¡¡create¡¡dynamic¡¡(moveable)¡¡blocks.
¡¡¡¡//¡¡The¡¡parameters¡¡are¡¡self-explanatory.
¡¡¡¡//¡¡The¡¡userData¡¡parameter¡¡is¡¡optional¡¡and¡¡it¡¡replaces¡¡the¡¡boring
¡¡¡¡//¡¡sprite¡¡used¡¡to¡¡represent¡¡the¡¡box.
¡¡¡¡public¡¡function¡¡addBox(x,¡¡y,¡¡wid,¡¡heig,¡¡userData:*¡¡=¡¡null)¡¡:¡¡b2Body¡¡{
¡¡¡¡¡¡bodyDef¡¡=¡¡new¡¡b2BodyDef();
¡¡¡¡¡¡bodyDef.position.x¡¡=¡¡x/30;
¡¡¡¡¡¡bodyDef.position.y¡¡=¡¡y/30;
¡¡¡¡¡¡boxDef¡¡=¡¡new¡¡b2PolygonDef();
¡¡¡¡¡¡boxDef.SetAsBox(wid/30/2,¡¡heig/30/2);
¡¡¡¡¡¡boxDef.density¡¡=¡¡1.0;
¡¡¡¡¡¡boxDef.friction¡¡=¡¡0.7;
¡¡¡¡¡¡boxDef.restitution¡¡=¡¡0.2;
¡¡¡¡¡¡if(userData¡¡!=¡¡null){
¡¡¡¡¡¡¡¡bodyDef.userData¡¡=¡¡userData;
¡¡¡¡¡¡}else{
¡¡¡¡¡¡¡¡bodyDef.userData¡¡=¡¡new¡¡PhysBox(wid,¡¡heig);
¡¡¡¡¡¡¡¡//bodyDef.userData.width¡¡=¡¡wid¡¡*¡¡2;
¡¡¡¡¡¡¡¡//bodyDef.userData.height¡¡=¡¡heig¡¡*¡¡2;
¡¡¡¡¡¡¡¡addChild(bodyDef.userData);
¡¡¡¡¡¡}
¡¡¡¡¡¡body¡¡=¡¡m_world.CreateDynamicBody(bodyDef);
¡¡¡¡¡¡body.CreateShape(boxDef);
¡¡¡¡¡¡body.SetMassFromShapes();
¡¡
¡¡¡¡¡¡lastBody¡¡=¡¡body;
¡¡
¡¡¡¡¡¡return¡¡body;
¡¡¡¡}
¡¡
¡¡¡¡//¡¡Using¡¡this¡¡function,¡¡you¡¡can¡¡create¡¡static¡¡(non-moveable)¡¡blocks.
¡¡¡¡//¡¡The¡¡parameters¡¡are¡¡self-explanatory.
¡¡¡¡//¡¡The¡¡userData¡¡parameter¡¡is¡¡same¡¡as¡¡in¡¡addBox¡¡function.
¡¡¡¡public¡¡function¡¡addStaticBox(x,¡¡y,¡¡wid,¡¡heig,¡¡userData:*¡¡=¡¡null)¡¡:¡¡b2Body¡¡{
¡¡¡¡¡¡var¡¡bodyDef¡¡=¡¡new¡¡b2BodyDef();
¡¡¡¡¡¡bodyDef.position.x¡¡=¡¡x/30;
¡¡¡¡¡¡bodyDef.position.y¡¡=¡¡y/30;
¡¡¡¡¡¡boxDef¡¡=¡¡new¡¡b2PolygonDef();
¡¡¡¡¡¡boxDef.SetAsBox(wid/30/2,¡¡heig/30/2);
¡¡¡¡¡¡boxDef.density¡¡=¡¡0.0;
¡¡¡¡¡¡boxDef.friction¡¡=¡¡0.5;
¡¡¡¡¡¡boxDef.restitution¡¡=¡¡0.2;
¡¡¡¡¡¡if(userData¡¡!=¡¡null){
¡¡¡¡¡¡¡¡bodyDef.userData¡¡=¡¡userData;
¡¡¡¡¡¡}else{
¡¡¡¡¡¡¡¡bodyDef.userData¡¡=¡¡new¡¡PhysBox(wid,¡¡heig);
¡¡¡¡¡¡¡¡//bodyDef.userData.width¡¡=¡¡wid¡¡*¡¡2;
¡¡¡¡¡¡¡¡//bodyDef.userData.height¡¡=¡¡heig¡¡*¡¡2;
¡¡¡¡¡¡¡¡addChild(bodyDef.userData);
¡¡¡¡¡¡}
¡¡¡¡¡¡body¡¡=¡¡m_world.CreateStaticBody(bodyDef);
¡¡¡¡¡¡body.CreateShape(boxDef);
¡¡¡¡¡¡body.SetMassFromShapes();
¡¡
¡¡¡¡¡¡lastBody¡¡=¡¡body;
¡¡
¡¡¡¡¡¡return¡¡body;
¡¡¡¡}
¡¡
¡¡¡¡//¡¡Really,¡¡dunno¡¡how¡¡this¡¡works,¡¡but¡¡it¡¡does.¡¡And¡¡that's¡¡what¡¡matters.
¡¡¡¡public¡¡function¡¡GetBodyAtPoint(px:Number,¡¡py:Number,¡¡includeStatic:Boolean¡¡=¡¡false)¡¡:¡¡b2Body¡¡{
¡¡¡¡¡¡//¡¡Make¡¡a¡¡small¡¡box.
¡¡¡¡¡¡var¡¡px2¡¡=¡¡px/30;
¡¡¡¡¡¡var¡¡py2¡¡=¡¡py/30;
¡¡¡¡¡¡var¡¡PointVec:b2Vec2¡¡=¡¡new¡¡b2Vec2();
¡¡¡¡¡¡PointVec.Set(px2,¡¡py2);
¡¡¡¡¡¡var¡¡aabb:b2AABB¡¡=¡¡new¡¡b2AABB();
¡¡¡¡¡¡aabb.lowerBound.Set(px2¡¡-¡¡0.001,¡¡py2¡¡-¡¡0.001);
¡¡¡¡¡¡aabb.upperBound.Set(px2¡¡+¡¡0.001,¡¡py2¡¡+¡¡0.001);
¡¡
¡¡¡¡¡¡//¡¡Query¡¡the¡¡world¡¡for¡¡overlapping¡¡shapes.
¡¡¡¡¡¡var¡¡k_maxCount:int¡¡=¡¡10;
¡¡¡¡¡¡var¡¡shapes:Array¡¡=¡¡new¡¡Array();
¡¡¡¡¡¡var¡¡count:int¡¡=¡¡m_world.Query(aabb,¡¡shapes,¡¡k_maxCount);
¡¡¡¡¡¡var¡¡body:b2Body¡¡=¡¡null;
¡¡
¡¡¡¡¡¡//¡¡The¡¡loop¡¡that¡¡seeks¡¡for¡¡the¡¡body:
¡¡¡¡¡¡for¡¡(var¡¡i:int¡¡=¡¡0;¡¡i¡¡<count;¡¡++i)¡¡{
¡¡¡¡¡¡¡¡if¡¡(shapes[i].m_body.IsStatic()¡¡==¡¡false¡¡||¡¡includeStatic)¡¡{
¡¡¡¡¡¡¡¡¡¡var¡¡tShape:b2Shape¡¡=¡¡shapes[i]¡¡as¡¡b2Shape;
¡¡¡¡¡¡¡¡¡¡var¡¡inside:Boolean¡¡=¡¡tShape.TestPoint(tShape.m_body.GetXForm(),¡¡PointVec);
¡¡¡¡¡¡¡¡¡¡if¡¡(inside)¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡body¡¡=¡¡tShape.m_body;
¡¡¡¡¡¡¡¡¡¡¡¡break;
¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡return¡¡body;
¡¡¡¡}
¡¡
¡¡
¡¡¡¡//¡¡Physics¡¡world¡¡and¡¡definitions
¡¡¡¡public¡¡var¡¡m_world:b2World;
¡¡¡¡public¡¡var¡¡m_iterations:int¡¡=¡¡20;
¡¡¡¡public¡¡var¡¡m_timeStep:Number¡¡=¡¡1.0/25.0;
¡¡}
}
¸ü¶à¾«²Ê
ÔÞÖúÉÌÁ´½Ó