Box2D C++ 跳跃

本文介绍了在Box2D C++中实现跳跃的四种方法:直接设置速度、使用力、使用冲量和考虑实际物理效应。通过示例和分析,详细解释了每种方法的适用场景和效果,特别探讨了如何处理物体旋转和跳跃后的落地问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

~~~~我的生活,我的点点滴滴!!


跳跃


水平滚轴游戏中的角色可以进行跳跃,现在就让我们看看几种不同实现跳跃的方法,上篇文章中我们用到了速度与力,但是我们那时

只是设置了水平的速度,并没有设置竖直方向的速度,如果我们同时设置一个竖直方向的速度,会不会就能跳跃了?下面还是上篇例

子中的物体测试环境



1、直接设置速度



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

case 'j':
{
	b2Vec2 vel = m_body[0]->GetLinearVelocity();
	vel.x += 2;
	vel.y = 10;
	m_body[0]->SetLinearVelocity(vel);
}
break;

现在按下键盘j就会直接改变物体的速度,当然我们知道,这种方式并不是真实世界里的物理方法。对于横屏游戏中的跳跃使用这种

方法可能不太合适,这里有几点需要注意的地方。首先这样做物体自身的动量没有考虑其中,当玩家快速掉落的时候可以用相等的力

跳起。玩家可以在半空中进行跳跃-也许这种现象正是你想要的,美其名曰‘连跳’特性。接下来我们会解决这个半空跳跃的问题,

稍后我们会讨论玩家跳跃之后是否着地。


2、使用力


现实生活中,当你真正跳跃的时候,你会在自己身体上施加一个向上的力,那么让我们看看对物体连续几帧施加强力能否达到此效果。

在Keyboard()方法中我们将简单做一个跳跃开始的标记,在Step()方法中完成力的施加。

if( m_remainJump )
{
	//ApplyForec里面的牛顿力计算 f*t = m * deltaV
	//t = 1/60, 故 f = m * 60 * deltaV
	//m = 2 * 2 * 10, f = 40 * 60 这里设置成2400 那就能在1/60里面产生向上速度为1
	m_body[0]->ApplyForce(b2Vec2(0, 2400), m_body[0]->GetWorldCenter());
	//m_body[0]->ApplyLinearImpulse(b2Vec2(0,40), m_body[0]->GetWorldCenter());
	m_remainJump --;
}

Test::Step(settings);

现在尝试着按下j键。和之前类似,但是这次当物体下落的时候,因为下降的动量考虑在内,所以跳跃效果会减小很多。这里使用的力只

是一个看起来差不多的数值。如果你想指定物体产生起飞(take-off)的速度,需要使用之前推算力矩的公式,根据你想让物体左/右移动

的速度推算出相应的力矩(f=mv/t),在每一帧中对物体施加此作用力:

if( m_remainJump )
{
	//ApplyForec里面的牛顿力计算 f*t = m * deltaV
	//t = 1/60, 故 f = m * 60 * deltaV
	//m = 2 * 2 * 10, f = 40 * 60 这里设置成2400 那就能在1/60里面产生向上速度为1
	float force = m_body[0]->GetMass() * 10 / (1*1.0/60);
	force /= 4;
	m_body[0]->ApplyForce(b2Vec2(0, force), m_body[0]->GetWorldCenter());
	//m_body[0]->ApplyLinearImpulse(b2Vec2(0,40), m_body[0]->GetWorldCenter());
	m_remainJump --;
}
Test::Step(settings);


3、使用冲量



这种方法可能会是你经常用到的,本质上是使用上面相同的力,只在一个时间步长中完全实现相应的效果。正如之前话题中提到的那样我们

可以忽略时间部分:

//只需要Keyboard()中添加
switch (key)
{
case 'j':
	{
		m_remainJump = 4;
		float impulse = m_body[0]->GetMass() * 10;
		m_body[0]->ApplyLinearImpulse(b2Vec2(0, impulse),m_body[0]->GetWorldCenter());
	}
	break;

default:
	Test::Keyboard(key);
}

这种方法比施加作用力更接近直接改变速度的效果,因为每一帧都会有力对物体的作用,重力起到了下降的作用。其实,如果你离近点仔细观看,

会发现直接使用作用力来实现跳跃并不能和另外两种方法那样跳的一样高。然而,如果你想实现一种缓慢跳起的效果,来取代直接跳起,那么作用力

方法会更有用。


4、其它方法


在真实世界里,每一个动作都会产生一个大小相等,方向相反的作用。如果你使用腿推动身体跳向空中,无论你站在哪里,都会产生一个相等的向

下推力。上面的所提到的方法都没有把这一点考虑在内,然而大部分游戏里也不需要考虑这些。但是如果你需要模拟这种情况,这里有两种可以实

现的方法,这两种方法需要我们再多学习一点才能实现,所以现在我只是顺带提一下。

当确定玩家站在什么物体上之后,如果此物体是动态物体,那么你应该对此物体施加相同的力/冲量。这就像你站在秋千桥(swing bridge)上进行

跳跃一样,比如说,当玩家跳起的时候,桥会瞬间得到一个取代玩家重力的向下推力。为了达到这种效果,我们需要知道如何告诉玩家接触到了什么。

使用棱镜(滑动)连接器(prismatic(sliding)joint)把两个物体连接起来能更快的模拟物体跳跃的效果。使用这种方法,玩家需要拥有一个主物体,

比如我们正在使用的这个,另一个连接着的是可以上下滑动的小物体。连接器马达(joint motor)可以向下推小物体,就像是你用腿进行起跳一样。

这么做有一个好的优点是我们不用很麻烦的去检查,物体到底站在一个什么样的地方,因为如果玩家所站立的下方不能保证‘腿’能将身体推向上方,

那么玩家什么也不发生。此外,如果玩家站立的地方比较‘软’,就像秋千桥一样,那么玩家的跳起效果将会减小,就像真实世界一样。当然除了能够

完成更多效果以外,还是会有它自身需要考虑的问题的。我希望这个话题可以放到连接器以及马达连接器讲解之后再进行深入探讨。


5、让物体从旋转中停止


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

m_body[0]->SetFixedRotation(true);


由于上面设置给他的力或者冲量值都很小,所以物体往上就移了一点点。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值