Answers:
首先,您需要确定所需的跳转外观。
在现实生活中,跳跃高度是在您离开地面时决定的。当你已经处于空中时,你不能继续跳得更高。
因此,如果您可以在空中时控制自己的跳跃高度,那么您将获得某种类似于“喷气背包”的效果。
我似乎记得有一款具有两种不同跳跃高度的侧滑车,我认为这是超级马里奥游戏之一。按住跳转按钮时会出现较高的跳跃,然后实际上是一个两部分的跳跃,从最初的常规跳跃开始,然后是第二次冲动,使您更高。
那么,您希望您的跳跃看起来像什么?您想让玩家对跳跃有什么样的控制?
我将从这里开始:
别管重力(即永远不要改变它)。当玩家按下跳转按钮时,只要玩家按下跳转按钮(不超过某个时间限制),就施加跳跃力。然后,当玩家释放跳跃按钮时,他无法再次施加任何跳跃力(即,他不能再次发起跳跃),直到他首先接触地面,然后才重新启用跳跃。
super meat boy
,我认为它具有与您想要的跳跃效果相同的效果,好像您只要按住跳跃按钮,就可以向角色施加力,它与重力相反并且比重力小,并且休息就像阿尔霍夫斯基所说的。如果我要实现这样的功能,我将以重力的60%-80%作为跳跃力。
我见过有人这样做:
创建一个变量(我称之为jumpTime
)(数字/双精度/浮点数)。当按下跳转键时,将其设置jumpTime
为某个数字(即0.5
,这将是按住跳转键将影响的秒数)。
然后,对于每一个步骤中,设置速度jumpTime
乘以某个其他数目,并降低jumpTime
由delta
(各步骤之间的时间差)。
重复该操作,直到jumpTime
达到零或更低,或者播放器释放跳跃键。在此之后,请使用常规物理方法(施加恒定的负加速度,直到玩家到达地面为止)。
除非您知道如何做,否则您可能需要使用反复试验(或“逻辑猜测”)来为那些“一些数字”找到合适的值。
更新:我发现了使跳跃更加逼真的技巧(因为它原本是缓慢上升但随后迅速下降)。Infinite Mario还使用以下行(JavaScript版本的Character.js的293)... this.Ya *= 0.85;
这就像“空气阻力”,并且在空中时限制/降低角色的速度。因此,在每一帧中,将y速度(垂直速度)乘以小于一的数字,以使它在回落时会减慢速度(因此,在跳跃过程中向上和向下的运动都将是相似且更实际的)。我知道,我不好解释...
当角色使用我上面最初描述的方法进行跳跃时,角色“上升”的速度更快,然后又“回落”。但是,阻力会降低垂直速度。由于我们将垂直速度设置为与jumpTime
每一帧成比例,因此此阻力对跳跃的前半部分影响不大。但是,在下半部分(向下倾斜)中,并不是每帧都设置垂直速度,而只是将其与另一个数字相加(在这种情况下,这是重力常数)。因此,阻力在下降时生效,并且由于它降低了速度(在任何方向上),因此减慢了下降速度,使其类似于上半部分。
但是,还有其他方法可以解决此问题,例如在重力下降时减小重力对角色的影响。但是,我们需要找到应减少多少重力的方法。
这是我发现的(来自Markus Persson(Notch)的Mario.java的206行):
if (keys[KEY_JUMP] || (jumpTime < 0 && !onGround && !sliding))
{
if (jumpTime < 0)
{
xa = xJumpSpeed;
ya = -jumpTime * yJumpSpeed;
jumpTime++;
}
else if (onGround && mayJump)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
xJumpSpeed = 0;
yJumpSpeed = -1.9f;
jumpTime = 7;
ya = jumpTime * yJumpSpeed;
onGround = false;
sliding = false;
}
else if (sliding && mayJump)
{
world.sound.play(Art.samples[Art.SAMPLE_MARIO_JUMP], this, 1, 1, 1);
xJumpSpeed = -facing * 6.0f;
yJumpSpeed = -2.0f;
jumpTime = -6;
xa = xJumpSpeed;
ya = -jumpTime * yJumpSpeed;
onGround = false;
sliding = false;
facing = -facing;
}
else if (jumpTime > 0)
{
xa += xJumpSpeed;
ya = jumpTime * yJumpSpeed;
jumpTime--;
}
}
else
{
jumpTime = 0;
}
javascript版本基本上是相同的https://github.com/robertkleffner/mariohtml5/blob/master/code/character.js
这类似于Olhovsky的建议,但是在这种情况下,力将与玩家按下跳转键后经过的时间成正比。
if ( onGround && jump && !jumped ) {
jumpTime = maxJumpTime;
onGround = false;
jumped = true;
this.vel.y = jumpTime * jumpConstant;
A = true;
} else if ( !onGround && jump && jumpTime > 0 && !released ) {
jumpTime -= evt.delta;
this.vel.y = jumpTime * jumpConstant;
B = true;
} else if ( !onGround && ( !jump || jumpTime <= 0 ) ) {
this.vel.y -= gravityConstant * evt.delta;
jumpTime = 0
released = true;
} if ( this.pos.y < 0 && !A && !B ) {
onGround = true;
released = false;
this.pos.y = 0;
this.vel.y = 0;
}
if ( !jump && onGround ) jumped = false;
但是,常量的某些值(例如“ gravityConstant”和“ jumpConstant”)会产生不切实际的跳跃。但是有时候游戏不一定要现实!(更新请参见上面的更新部分)
这个问题已经有一年多了,但是我希望这会有所帮助!
正如Olhovsky所说,跳跃高度是在您离开地面的那一刻决定的,而不是在那之后。
如果您真的想避免喷气背包效应,我只会看到两种方式:组合键可以跳得更高,或者从根本上改变跳转键的工作方式:
与其让玩家一按键就跳起来,不如将释放延迟到键被释放为止。因此,基本上,按键的持续时间控制着玩家腿部弹簧的弹力大小,然后释放。
当然,这从根本上改变了游戏机制,并且可能令玩家不熟悉。但是这种效果可能会很有趣,可能值得不熟悉。
我在David Gouveia对“ 如何使角色跳跃? ” 这一问题的答案中找到了另一种解决方案。
他的想法是在玩家按下跳跃按钮时设定速度。在每帧中,它仅计算重力。但是,当播放器释放按钮时,如果速度大于该速度,则会将速度设置为较小的值。速度仅在每帧重力的作用下递减。
我不应该偷他的答案,所以继续阅读他的帖子。他的解决方案在“ 可变高度跳跃 ”部分下。
所以人们真的想出了许多解决这个问题的方法...
http://excitemike.com/JumpingControlTester(说明了各种游戏中的不同跳跃机制)
http://meyermike.com/wp/?p=175(还讨论了Mario的跳跃路径)
http://www.flatredball.com/frb/docs/index.php?title=Tutorials:Platforer:Variable-Height_Jumps(描述3种不同的方法)
可能更多(没有经过太多搜索结果,但是使用Google搜索的“可变跳跃高度”很有帮助)