Box2D C++ 教程-跳跃

声明:本教程翻译自:Box 2D C++ turorials - Jumping,仅供学习参考

跳跃(Jumping)

水平滚轴游戏中的角色可以进行跳跃,是吧?现在就让我们看看几种不同实现跳跃的方法。我们已经在之前力和冲量(force and impulses)中进行过相关问题的讨论,但是现在就让我们考虑一下如何把这些方法整合到游戏中。我们可以从匀速运动(moving at constant speed)这个话题开始,在一定范围内左/右控制移动一个动态物体。

 

直接设置速度

当玩家跳跃的时候他们的速度就会改变,让我们以此为起点。首先在Keyboard()方法中添加一个case分支,来获得玩家的跳跃输入:

case 'j': //jump
{
  b2Vec2 vel = body->GetLinearVelocity();
  vel.y = 10;//upwards - don't change x velocity
  body->SetLinearVelocity( vel );
}
break;

现在按下键盘j就会直接改变物体的速度,当然我们知道,这种方式并不是真实世界里 的物理方法。关于这种方法,对于横屏滚轴游戏来说可能会产生不恰当的跳跃现象。首先这样做物体自身的动量没有考虑其中,有可能发生当玩家正在快速下降的时 候突然产生跳跃现象。当然了玩家也可以在半空中进行跳跃-也许这种现象正是你想要的,美其名曰‘连跳’特性。接下来我们会解决这个半空跳跃的问题,并且在 稍后的话题中我们讨论玩家跳跃之后是否落地进行判断。

使用力

现实生活中,当你真正跳跃的时候,你会在自己身体上施加一个向上的力,那么让我们 看看对物体连续几帧施加强力的效果。在Keyboard()方法中我们将简单做一个跳跃开始的标记,在Step()方法中完成力的施加。使用一个类的成员 变量来记录每次的每次应该施加多少帧的力:

//class member variable
int remainingJumpSteps;
  
//in constructor
remainingJumpSteps = 0;
  
//keyboard function
case 'k': //jump
  remainingJumpSteps = 6;// 1/10th of a second at 60Hz
  break;
  
//in Step() function
if ( remainingJumpSteps > 0 ) {
  body->ApplyForce( b2Vec2(0,500), body->GetWorldCenter() );
  remainingJumpSteps--;
}

现在尝试着按下k键。行为很像之前的效果,但是这次当物体下落的时候,因为下降的动量考虑在内,所以跳跃效果会小很多。这里使用的力只是一个看起来 差不多大小的数值而已。如果你想让物体产生‘起飞(tall-off)’的效果,你需要使用之前以适当速度左/右移动物体的公式(f=mv/t),在每一 帧中对物体施加作用力:

if ( remainingJumpSteps > 0 ) {
  //to change velocity by 10 in one time step
  float force = body->GetMass() * 10 / (1/60.0); //f = mv/t
  //spread this over 6 time steps
  force /= 6.0;
  body->ApplyForce( b2Vec2(0,force), body->GetWorldCenter());
  remainingJumpSteps--;
}

使用冲量

这种方法可能会是你经常用到的,特别是像上面所提到的那样,只在一帧中对物体施加作用力来实现相应的效果。在上面方法的基础上,我们可以丢弃时间部分:

case 'l':
{
  //to change velocity by 10
  float impulse = body->GetMass() * 10;
  body->ApplyLinearImpulse(b2Vec2(0, impulse),body->GetWorldCenter());
}
break;

这种方法所实现的效果比直接作用力更接近直接改变速度的效果,因为每一帧都会有力对物体的作用,重力起到了下降的作用。其实,如果你离近点仔细观 看,会发现直接使用作用力来实现跳跃并不能和另外两种方法那样跳的一样高。然而,如果你想实现一种缓慢跳起的效果,来取代径直跳起,那么使用作用力会更 好。

其它方法

在真实世界里,每一个动作都会产生一个大小相等,方向相反的作用。如果你使用腿推动身体跳向空中,无论你站在哪里,都会产生一个相等的向下推力。上 面的所提到的方法都没有把这一点考虑在内,然而大部分游戏里也不需要考虑这些。但是如果你需要模拟这种情况,这里有两种可以实现的方法,这两种方法需要我 们再多学习一点才能实现,所以现在我只是顺带提一下。

当确定玩家站在什么物体上之后,如果此物体是动态物体,那么你应该对此物体施加相同的力/冲量。这就像你站在秋千桥(swing bridge)上进行跳跃一样,比如说,当玩家跳起的时候,桥会瞬间得到一个取代玩家重力的向下推力。为了达到这种效果,我们需要知道如何告诉玩家角色接 触的是什么。

使用棱镜(滑动)连接器(prismatic(sliding)joint)把两个物体连接起来能更快的模拟物体跳跃的效果。使用这种方法,玩家需 要拥有一个主物体,比如我们正在使用的这个,另一个连接着的是可以上下滑动的小物体。连接器马达(joint motor)可以向下推小物体,就像是你用腿进行起跳一样。这么做有一个好的优点是我们不用很麻烦的去检查,物体到底站在一个什么样的地方,因为如果玩家 所站立的下方不能保证‘腿’能将身体推向上方,那么玩家什么也不发生。此外,如果玩家站立的地方比较‘软’,就像秋千桥一样,那么玩家的跳起效果将会降 低,就像真实世界一样。当然除了能够完成更多效果以外,还是会有它自身需要考虑的问题的。我希望这个话题可以放到连接器以及马达连接器讲解之后再进行深入 探讨。

让物体从旋转中停止

你可能已经注意到那个让被我们看做玩家的物体不停的在一定区域内自由的做旋转。一个简单而又奏效的方法是把物体设置成固定旋转体:

body->SetFixedRotation(true);

转载于:https://www.cnblogs.com/stop/articles/2720348.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值