重力与空中时间、加速度和速度增加

9

我正在尝试实现一个包括空中时间和加速度的重力效果。
我已经尝试使用通常的重力效果,大致如下:

velocity += gravity * dt;
position += velocity * dt;

这可能对于普通的平台游戏已经足够了,但我正在尝试制作一款受“直升机游戏”启发的游戏,在游戏中你需要在不触碰墙壁的情况下穿越一个隧道。我的想法是让玩家在下降过程中积攒速度,并在上升时使用,这样开始时就会有一定的加速度。此外,我还希望有某种形式的空中时间,这样当你达到顶部时,它就不会像使用代码示例中的重力那样迫使你快速下降。这张图片说明了我想要的曲线: Link to curve 请注意,整个控制都由一个键完成,例如如果你按住空格键,你将飞向上方;如果你松开空格键,则会俯冲。角色也永远不会左右移动,因为它在屏幕上拥有静态的X位置,所以无法使用向量。我已经花了几个小时来尝试让它工作,但没有成功。我也试着在互联网上搜索,但没有任何运气。游戏“鲸鱼小径”具有我想要的重力效果。这是游戏视频的链接: http://www.youtube.com/watch?v=5OQ0OWcuDJs。我不是特别精通物理学,所以如果你能给出实际代码的示例就太好了。希望有人能帮我解决这个问题。

这不是一个坏问题,但展示一些代码来说明你尝试了什么 - 以及它为什么不起作用的描述 - 将有助于你获得答案。 :) - Dan J
我也不是物理专家,但我猜想你需要深入了解物理学才能实现你想要的。所以我认为飞机物理学应该是你进入正确方向的关键。也许这个链接可以帮助你至少找到正确的词汇来寻找解决问题的方法:http://www.ucmp.berkeley.edu/vertebrates/flight/physics.html。此外,在最新的蝙蝠侠-阿卡姆城市游戏中,你有一个类似的机制,也许值得一试。 - dowhilefor
@djacobson 主要只是随机代码,因为我不知道该怎么做,所以没有什么用:) - Basic
@dowhilefor 你可能是对的,但如果已经有相关代码那就太好了 ;) - Basic
在“鲸鱼小径”游戏中,尽管鲸鱼保持在屏幕上的同一位置,水平速度似乎会发生变化。屏幕滚动会加快和减慢。看起来你需要使用2D向量来复制这种行为。 - JohnPS
3个回答

4

重力是将物体向下拉的力。您的玩家是将物体向上拉的力。因此,您的代码必须是:

if(keyPressed) {
  velocity += POWER_OF_PLAYER;
}

velocity += G;
position += velocity;

这已经足够创建像你所示的曲线了。当然,POWER_OF_PLAYER必须是不同的符号,绝对值必须更大才能使其起作用。

G = -9.81
POWER_OF_PLAYER = 20

节能是一个简单的检查。
if(keyPressed) {
  if(powerSaved > 0) {
    velocity += POWER_OF_PLAYER;
    powerSaved -= SOMETHING;
  }
} else if (velocity >= SOME_MINIMUM_SPEED_BEFORE_GETTING_POWER) {
  powerSaved += SOMETHING;
}

SOME_MINIMUM_SPEED_BEFORE_GETTING_POWER 应该小于等于 0。

附注:我假设您的 Y 轴从地面开始,向天空射出。符号相应放置。


我相当确定我已经尝试过这个,但我会用你的代码再试一次,看看它是否有效 :) - Basic
这是标准公式,游戏的物理规则是不同的。 - Klas Lindbäck
你的数学有误。重力是一种力,即它具有质量*加速度的单位,而速度具有距离/时间的单位,因此设置 velocity += GRAVITY 是根本错误的。 - rcollyer
@rcollyer 变量必须命名为 G 或 STRENGTH_OF_THE_GRAVITATIONAL_FIELD(它是与物体的重力加速度无关且等效的),以解决这个问题,或者我们必须假设该系统中所有物体的质量都为1。但这并不否定答案的其他部分。 - Marcel Jackwerth
是的,假设质量为1公斤,它是接近的。您仍然需要将“G”乘以时间增量以获得正确的单位,同样适用于“Power_Of_Player”,前提是它也是一个力。 - rcollyer

0
似乎将基于水平速度的“提升”结合起来,并通过按下按钮触发“向上转鼻”运动会很好地起作用。
因此,lift 将是某个常量 k 乘以水平速度 Vx,而垂直速度 Vy 将是 gravitylift 的差乘以变化时间 dt
lift = k * Vx
Vy += ( lift - gravity ) * dt

def noseup
  k = 0.01 #some small chunk
  dx = k * Vx
  dy = k * Vy
  Vx -= dy
  Vy += dx

当飞机(或其他物体)向上倾斜时,它基本上会降低一个轴上的速度,同时增加另一个轴上的速度。
也许在这里加入“阻力”不是个坏主意,现在我想起来了,这将取决于绝对速度 V = ( Vx**2 + Vy**2 )**0.5...而在这种情况下,重量比重力更合适的词(少一些混淆,单位方面),但我猜这样也可以。
虽然不完全是“物理学”,但是这是一个相当接近的近似值,应该能够很好地工作。尝试调整 k 的值,看看是否能够达到你想要的效果。
顺便说一句,对于那个超级糟糕的伪代码,抱歉哈 :-P

0

看起来鱼的速度是恒定不变的。

尝试以下操作:

速度是固定的,不应该改变(除非鱼吃了速度提升道具)。 角度= 0相当于水平飞行。

angle -= gravity * dt;
if (angle < - Math.PI / 2) {
  angle = Math.PI / 2;
}
if (keyPressed) { 
  angle += power * dt;
}

if (angle < - Math.PI / 2) {
  // Stop the player from doing a looping
  angle = - Math.PI / 2;
}
if (angle > Math.PI / 2) {
  // Stop the player from doing an inverted looping
  angle = Math.PI / 2;
}
// Move the fish (vertical component of velocity)
position += velocity * dt * Math.sin(angle);
// Move the background (horizontal component of velocity)
background_position -= velocity * dt * Math.sin(angle);

当使用您的代码时,玩家只会直行,除非按下键盘,它才会稍微向下移动。 - Basic
尝试将角度变化变小 - angle -= gravity * dt / 100.0;angle += power * dt / 100.0; - Klas Lindbäck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接