вторник, 24 мая 2011 г.

Box2D Jump in Platformer Engine




Вот мой код для реализации проверки может/не может герой прыгать. За одно тут же и проверка на пересечение героем платформ-"облаков" снизу.
Устанавливаем свой contactListener в world. В конце каждого обновления мира делаем сброс значению canJump.

Here is my code for jumping check (can/can't jump). Also cloud platforms realization.
Setting up custom contactListener into world. On every world update function making reset for canJump variable (in the end of update function).

package 
{
  import Box2D.Dynamics.*;
  import Box2D.Collision.*;
  import Box2D.Collision.Shapes.*;
  import Box2D.Dynamics.Joints.*;
  import Box2D.Dynamics.Contacts.*;
  import Box2D.Common.*;
  import Box2D.Common.Math.*;

  public class customb2ContactListener extends b2ContactListener
  {
    private var canJump:Boolean = false;

    public function ResetCanJump():void
    {
      canJump = false;
    }

    public function CanJump():Boolean
    {
      return canJump;
    }

    public function customb2ContactListener()
    {
    }

    override public function BeginContact(contact:b2Contact):void 
    {
    }

    override public function PreSolve(contact:b2Contact, oldManifold:b2Manifold):void 
    {
      var fixtureA:b2Fixture=contact.GetFixtureA();
      var fixtureB:b2Fixture=contact.GetFixtureB();
      var local_canJump:Boolean = false;
      if ((fixtureA.GetBody().GetUserData()=="platform" && fixtureB.GetBody().GetUserData()=="hero")||
          (fixtureA.GetBody().GetUserData()=="hero" && fixtureB.GetBody().GetUserData()=="platform")||
          (fixtureA.GetBody().GetUserData()=="cloud" && fixtureB.GetBody().GetUserData()=="hero")||
          (fixtureA.GetBody().GetUserData()=="hero" && fixtureB.GetBody().GetUserData()=="cloud")) 
      {
        if(contact.IsTouching())
        {
          if(fixtureA.GetBody().GetUserData() == "platform" || fixtureA.GetBody().GetUserData() == "cloud")
          {
            local_canJump = fixtureA.TestPoint(new b2Vec2(fixtureB.GetBody().GetPosition().x, 
                                                          fixtureB.GetBody().GetPosition().y + 0.6));//y + half of hero height + 0.1
          }else{
            local_canJump = fixtureB.TestPoint(new b2Vec2(fixtureA.GetBody().GetPosition().x, 
                                                          fixtureA.GetBody().GetPosition().y + 0.6));//y + half of hero height + 0.1
          }
          if (fixtureA.GetBody().GetUserData()=="cloud" || fixtureB.GetBody().GetUserData()=="cloud") 
          {
            if(local_canJump)
            {
              //check if we are still inside platform
              var inside:Boolean = false;
              if(fixtureA.GetBody().GetUserData() == "cloud")
              {
                inside = fixtureA.TestPoint(new b2Vec2(fixtureB.GetBody().GetPosition().x, 
                                                       fixtureB.GetBody().GetPosition().y + 0.45));//y + half of hero height - 0.5
              }else{
                inside = fixtureB.TestPoint(new b2Vec2(fixtureA.GetBody().GetPosition().x, 
                                                       fixtureA.GetBody().GetPosition().y + 0.45));//y + half of hero height - 0.5
              }
              if(inside == true)
              {
                local_canJump = false;
                canJump = false;
                contact.SetEnabled(false);
              }
            }else{
              contact.SetEnabled(false);
            }
          }
        }
      }
      //if canJump once set to true - do not change on next contacts
      if(canJump == false)
      {
        canJump = local_canJump;
      }
    }
  }
}

Комментариев нет:

Отправить комментарий