Box2d - “怪物”和玩家相撞问题

发布于 2024-11-10 07:00:37 字数 358 浏览 3 评论 0原文

好吧,这是一个一般性问题,只是我的游戏系统应该如何工作。 所以有很多敌人和玩家。当敌人接触玩家时,玩家会受到怪物的打击和“推”,然后闪烁 1.5 秒。当“推”(非常非常快)时,玩家什么也做不了。 此外,所有怪物的移动方式始终相同。怪物的行动永远不会受到玩家的影响。我不能做运动学,因为它们确实受到重力的影响。那么我该怎么做呢?所有这些,包括“推”,我该怎么办?

在这个 0:27 的 YT 视频中,还有一个很好的例子来说明我的意思:http://www .youtube.com/watch?v=tVr8S6WXdog

谢谢。

OK it's a general question, just how the system of my game should work.
So there are lots of enemies and a player. When a enemy touch a player, the player gets a hit and a "push" from the monster, and then blinks to 1.5 seconds. Wile the "push" (really really fast), the player can't do nothing.
Also, all the monsters will always move the same. The move of the monsters will never be affected by the player. I can't do it kinematic because they DO affect from the gravity. So how can I do that? All that thing, include the "push", what should I do?

There's also a good example for what I mean in this YT video from 0:27 : http://www.youtube.com/watch?v=tVr8S6WXdog

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事灯 2024-11-17 07:00:37

以你的例子为例,我假设你并不打算让怪物和人类对彼此做出反应。

无论哪种方式,向世界添加一个自定义接触监听器,并在接触监听器内检查玩家和敌人形状是否创建接触点。如果是这样,请将 Linearimpulse() 应用于玩家身体以达到您想要的效果,并禁用用户的所有按键输入以防止运动发生任何变化。然后,只要玩家有一个属性,防止它在刚刚被怪物击中时施加脉冲。

另外,当您创建身体时,您需要将玩家和敌人实例设置为 body.UserData()

public class Player extends MovieClip
{
     public const MAX_EFFECT_TIME = 1.5 * framerate;

     public var effectTime:int = 0;
     public var body:b2Body;

 public function step():void
 {
       if (effectTime > 0)
       {
              effectTime--;
              //do awesome animation
       }
       else 
       {  
              //move normally
       }

 }

 public function Hit(enemy:Enemy)
 {
       if (effectTime == 0)
       {
              //apply linear impulse to object
              if (enemy.body.GetPosition().x < this.body.GetPosition().x)
              {
                    //apply impulse left in left direction
                    b2Vec2 force = b2Vec2(-8, 10);

                    body.ApplyLinearImpulse(force, body.GetWorldCenter());
              }
              else
              {
                    //apply impulse in right direction
                    b2Vec2 force = b2Vec2(8, 10);

                    body.ApplyLinearImpulse(force, body.GetWorldCenter());
              } 

              //reset effect time
              effectTime = MAX_EFFECT_TIME;
       }
 }

}

public class Game extends MovieClip
{
      public var world:b2World;
      public var player:Player;

      public Game()
      {
            world = initWorld();
            player = initPlayer();

            var cl = new CustomContactListener();
            world.SetContactListener(cl);

            this.addEventListener(Event.ENTER_FRAME, step);
      }

      private void step(e:Event)
      {
            world.step();
            player.step();
      }

}

public class CustomContactListener extends b2ContactListener
{
      //Called when a contact point is added.
      public override function Add(point:b2ContactPoint):void 
      {
            //checks if the first shape is a player and second is an enemy if true call Hit
            if (point.shape1.GetBody().GetUserData().isPlayer && point.shape2.GetBody().GetUserData().isEnemy)
            {
                 point.shape1.GetBody().GetUserData().Hit(point.shape2.GetBody().GetUserData());
            }
            else if (point.shape2.GetBody().GetUserData().isPlayer && point.shape1.GetBody().GetUserData().isEnemy)
            {
                 point.shape2.GetBody().GetUserData().Hit(point.shape1.GetBody().GetUserData());


      }
      }
}

然后您可以根据需要编辑值。希望这有帮助,祝你好运!

With your example I'm presuming that you don't plan on actually having the monster and humans reacting to one another.

Either way, add a custom contact listener to the world and within the contact listener check if a player and a enemy shape create a contact point. If so applylinearimpulse() to the playerbody to the effect that you would like and disable all key input from the user to prevent any change in motion. Then just have a property on player preventing it from applying the impulse if its just been hit by the monster.

Also when you create the bodies you'll need to set the player and enemy instance as the body.UserData()

public class Player extends MovieClip
{
     public const MAX_EFFECT_TIME = 1.5 * framerate;

     public var effectTime:int = 0;
     public var body:b2Body;

 public function step():void
 {
       if (effectTime > 0)
       {
              effectTime--;
              //do awesome animation
       }
       else 
       {  
              //move normally
       }

 }

 public function Hit(enemy:Enemy)
 {
       if (effectTime == 0)
       {
              //apply linear impulse to object
              if (enemy.body.GetPosition().x < this.body.GetPosition().x)
              {
                    //apply impulse left in left direction
                    b2Vec2 force = b2Vec2(-8, 10);

                    body.ApplyLinearImpulse(force, body.GetWorldCenter());
              }
              else
              {
                    //apply impulse in right direction
                    b2Vec2 force = b2Vec2(8, 10);

                    body.ApplyLinearImpulse(force, body.GetWorldCenter());
              } 

              //reset effect time
              effectTime = MAX_EFFECT_TIME;
       }
 }

}

public class Game extends MovieClip
{
      public var world:b2World;
      public var player:Player;

      public Game()
      {
            world = initWorld();
            player = initPlayer();

            var cl = new CustomContactListener();
            world.SetContactListener(cl);

            this.addEventListener(Event.ENTER_FRAME, step);
      }

      private void step(e:Event)
      {
            world.step();
            player.step();
      }

}

public class CustomContactListener extends b2ContactListener
{
      //Called when a contact point is added.
      public override function Add(point:b2ContactPoint):void 
      {
            //checks if the first shape is a player and second is an enemy if true call Hit
            if (point.shape1.GetBody().GetUserData().isPlayer && point.shape2.GetBody().GetUserData().isEnemy)
            {
                 point.shape1.GetBody().GetUserData().Hit(point.shape2.GetBody().GetUserData());
            }
            else if (point.shape2.GetBody().GetUserData().isPlayer && point.shape1.GetBody().GetUserData().isEnemy)
            {
                 point.shape2.GetBody().GetUserData().Hit(point.shape1.GetBody().GetUserData());


      }
      }
}

Then you can just edit values as necessary. Hope this helps and good luck!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文