WEB开发网
开发学院图形图像Flash Platform engine using Box2D – Step 3 阅读

Platform engine using Box2D – Step 3

 2009-10-18 00:00:00 来源:WEB开发网   
核心提示:In this third part of the platform engine, it’s time to make our hero jump.First, I suggest you to read parts 1 and 2 if you already didn’t, then yo

In this third part of the platform engine, it’s time to make our hero jump.

First, I suggest you to read parts 1 and 2 if you already didn’t, then you should know something about the magic of compound objects and how Box2D manages collisions.

Then, you’re ready to follow the tutorial :)

The hero in order to jump must be on the ground, or over some solid object.

The main idea is creating the hero as a compound object made with the hero itself (the big rectangle) and a ground sensor (the small rectangle under the big one) that will be triggered every time the hero stands over something solid, without interacting with the world.

Then, we should check the sensor to collide with objects according to the response decide if the hero can or can’t jump.

Believe me, it’s easier than it seems. This is the main script:

package {
 import flash.display.Sprite;
 import flash.events.Event;
 import Box2D.Dynamics.*;
 import Box2D.Collision.*;
 import Box2D.Collision.Shapes.*;
 import Box2D.Common.Math.*;
 import General.Input;
 import flash.events.MouseEvent;
 public class HelloWorld extends Sprite {
  public var m_world:b2World;
  public var pixels_in_a_meter:int=30;
  public var bodyDef:b2BodyDef;
  public var boxDef:b2PolygonDef;
  public var m_input:Input;
  public var xspeed:int=0;
  public var bazooka:zooka=new zooka();
  public var bazooka_angle:Number;
  public var m_contactListener=new b2ContactListener();
  var body:b2Body;
  public function HelloWorld() {
   addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
   var worldAABB:b2AABB = new b2AABB();
   worldAABB.lowerBound.Set(-100.0, -100.0);
   worldAABB.upperBound.Set(100.0, 100.0);
   var gravity:b2Vec2=new b2Vec2(0.0,10.0);
   var doSleep:Boolean=true;
   m_world=new b2World(worldAABB,gravity,doSleep);
   var m_sprite:Sprite;
   m_sprite = new Sprite();
   addChild(m_sprite);
   var dbgDraw:b2DebugDraw = new b2DebugDraw();
   var dbgSprite:Sprite = new Sprite();
   m_sprite.addChild(dbgSprite);
   dbgDraw.m_sprite=m_sprite;
   dbgDraw.m_drawScale=30;
   dbgDraw.m_alpha=1;
   dbgDraw.m_fillAlpha=0.5;
   dbgDraw.m_lineThickness=1;
   dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit;
   m_world.SetDebugDraw(dbgDraw);
   var bodyDef:b2BodyDef;
   var boxDef:b2PolygonDef;
   var circleDef:b2CircleDef;
   square_tile(250,395,500,10);
   hero(100,370,20,40);
   //
   // adding the contact listener
   m_world.SetContactListener(m_contactListener);
   //
   // Box2D input class - why should I bother making my one?
   m_sprite = new Sprite();
   addChild(m_sprite);
   // input
   m_input=new Input(m_sprite);
   addChild(bazooka);
   stage.addEventListener(MouseEvent.CLICK, shoot);
  }
  public function shoot(event:Event) {
   bodyDef = new b2BodyDef();
   bodyDef.position.Set((bazooka.x+(bazooka.width+3)*Math.cos(bazooka_angle))/pixels_in_a_meter, (bazooka.y+(bazooka.width+3)*Math.sin(bazooka_angle))/pixels_in_a_meter);
   boxDef = new b2PolygonDef();
   boxDef.SetAsBox(10/pixels_in_a_meter,10/pixels_in_a_meter);
   boxDef.friction=0.3;
   boxDef.density=1;
   body=m_world.CreateBody(bodyDef);
   body.CreateShape(boxDef);
   body.SetMassFromShapes();
   body.ApplyImpulse(new b2Vec2(Math.cos(bazooka_angle)*4, Math.sin(bazooka_angle)*4),body.GetWorldCenter());
  }
  public function square_tile(px:int,py:int,w:int,h:int) {
   bodyDef = new b2BodyDef();
   bodyDef.position.Set(px/pixels_in_a_meter, py/pixels_in_a_meter);
   boxDef = new b2PolygonDef();
   boxDef.SetAsBox(real_pixels(w), real_pixels(h));
   boxDef.friction=0.3;
   boxDef.density=0;
   body=m_world.CreateBody(bodyDef);
   body.CreateShape(boxDef);
   body.SetMassFromShapes();
  }
  public function hero(px:int, py:int, w:int, h:int) {
   bodyDef = new b2BodyDef();
   bodyDef.position.Set(px/pixels_in_a_meter, py/pixels_in_a_meter);
   boxDef = new b2PolygonDef();
   boxDef.SetAsBox(real_pixels(w), real_pixels(h));
   boxDef.density=1.0;
   boxDef.friction=0.3;
   boxDef.restitution=0.2;
   bodyDef.userData = new Sprite();
   bodyDef.userData.name="Player";
   body=m_world.CreateBody(bodyDef);
   body.SetBullet(true);
   body.CreateShape(boxDef);
   //
   var ground_sensor:b2PolygonDef = new b2PolygonDef();
   ground_sensor.isSensor=true;
   ground_sensor.userData="groundsensor";
   ground_sensor.SetAsOrientedBox(10/pixels_in_a_meter,5/pixels_in_a_meter,new b2Vec2(0,27/pixels_in_a_meter), 0);
   body.CreateShape(ground_sensor);
   //
   body.SetMassFromShapes();
  }
  public function real_pixels(n:int) {
   return (n/pixels_in_a_meter/2);
  }
  public function Update(e:Event):void {
   m_world.Step(1/30, 10);
   xspeed=0;
   for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
    if (bb.GetUserData()!=null) {
     if (Input.isKeyDown(39)) { // right arrow
      xspeed=3;
     } else if (Input.isKeyDown(37)) { // left arrow
      xspeed=-3;
     }
     if (Input.isKeyDown(38)) {// up arrow
      if (m_contactListener.can_jump()) { // checking if the hero can jump
       bb.ApplyImpulse(new b2Vec2(0.0, -1.0), bb.GetWorldCenter());
      }
     }
     if (xspeed) {
      bb.WakeUp();
      bb.m_linearVelocity.x=xspeed;
     }
     bb.m_sweep.a=0;
     bazooka.x=bb.m_userData.x=bb.GetPosition().x*30;
     bazooka.y=bb.m_userData.y=bb.GetPosition().y*30;
     var dist_x=bazooka.x-mouseX;
     var dist_y=bazooka.y-mouseY;
     bazooka_angle=Math.atan2(- dist_y,- dist_x);
     bazooka.rotation=bazooka_angle*57.2957795;
    }
   }
   Input.update();
  }
 }
}

1 2  下一页

Tags:Platform engine using

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接