【问题标题】:Game Physics - Not very life-like游戏物理 - 不是很逼真
【发布时间】:2012-12-19 23:51:19
【问题描述】:

在一个简单的游戏 (cocos2d) 中,我制作了一个小型物理引擎来移动精灵,以便它可以跳跃和站立在平台等上。

为了更新位置(垂直运动),我在每次更新中使用基本运动学方程:

  • position = oldPosition + velocity(delta) +1/2(gravity)(delta)^2
  • 速度 = oldVelocity + (gravity)(delta)

由于某种原因,游戏看起来不太逼真。尽管我的重力有多大,但在弧顶附近似乎需要很长时间。如果我想让我的精灵跳相同的高度,但减速和加速更快,但仍然跳得和以前一样高,我应该怎么做?我希望这是有道理的。

【问题讨论】:

    标签: iphone cocos2d-iphone sprite physics game-physics


    【解决方案1】:

    这里的问题是你在物理上犯了一个错误!但这没关系,因为它很容易解决。

    在精灵位置调用更新方法时,应首先设置加速度。我假设这个游戏的重力是一个常数,所以你只需要设置一次。 (-9.81,或类似的东西。)

    然后您想通过速度 = old_velocity + 加速度 * 时间来更新角色在 y 方向上的速度。

    完成此操作后,您以类似的方式更新位置:位置 = old_position + 速度 * 时间。

    仅当 delta 是总经过时间而不是时间步长时,您用于更新位置的等式才有效! (我假设 delta 是一个时间步长,因为这就是物理游戏通常的编程方式。)

    我希望这会有所帮助!如果您想了解更多信息,请查看 suvat 方程,如果您知道初始速度和恒定加速度,您可以计算出最终位置,因为您的游戏在跳跃和碰撞时速度会发生变化,所以它不现实也就不足为奇了!如有更多问题,请发表评论,我会尽力为您提供进一步的帮助。

    编辑:我用 OpenGL 绘制的一些框重新编程了你在这里所做的。您更新职位的方法似乎不起作用。只有当dt 或时间步长为 1.0d 时,这些框才会正确落下,我不知道为什么。然后,当它们与某物发生碰撞时,它们会一起停止而不是弹跳。我不确定到底是为什么。

    但是,屏幕上还有另一个框,它使用了我描述的物理: v = u + a*ts = s_last + v*t 盒子完全按照预期落下并正确反弹。由于简化,在弹跳过程中会损失能量。

    【讨论】:

    • 看第二个运动学方程:physics.info/kinematics-calculus我的方程是一样的。
    • 是的,但不幸的是它不适用于此类工作。
    • 正如 Edward 所说,在每次更新时更新速度并通过 dt * newSpeed 移动对象,确实是实现简单 psysics 的更方便的方法。需要使用 suvat 公式进行计算以预测总行程或目标跳跃所需的初始速度(例如,让 Boss 跳跃并降落在玩家上方)。
    • 但你所说的其余部分无关紧要。正如您所说,您在不同的环境中尝试了 suvat 方程,但您不确定它为什么不起作用。这并不意味着等式是错误的。只要加速度恒定(并且重力恒定),您就可以使用它。它应该有效,并且确实如提问者所说的那样有效。可能是您没有正确实施它
    • 爱德华是正确的。您的论坛y = y0 + v0y*t + 1/2*g*t^2 是总行驶距离的公式。您不能在时间步中使用它。您需要使用此公式的微分,dy = v0y*dt + g*t*dt。这是微积分的属性。查找“全导数”。基本上,对于任何函数 f(t),df = (df/dt) * dt,其中(df/dt) 是函数相对于t 的偏导数。
    【解决方案2】:

    您可能更愿意在 cocos2d-iphone 游戏中尝试 Box2d 或 Chipmunk 物理引擎,以获得更逼真的效果。此外,它们相对容易实施。

    无需制作自己的物理系统——记得让技术为你工作;D

    【讨论】:

    • 我确实尝试过实现 Box2d。这是一款非常轻量级且简单的游戏,它不需要那么大的物理引擎。我发现将新速度乘以 5 左右的系数会有所帮助。
    • @bluestunt:我明白,但我敢肯定,无数涉及乒乓球之类的简单游戏都使用了这种“矫枉过正”的引擎。它只会让你的生活更轻松。有余力总比没有动力好!另外,使用 Box2d 或 Chipmunk 并不意味着更复杂的配置 - 如果您需要的只是基本功能,那么您将获得的只是基本配置。
    • 没有必要实现物理引擎,改变你的方程使其正确就可以了。 PS:现在我已经使用您的方程式和我使用的方程式编写了一个程序,因此我编辑了我的答案。我对结果感到很困惑,因为我一直在考虑这个问题太久了,但长话短说是使用:v = v_last + accel * timestep 获得新的 y 速度,然后使用:y = y_last + v * timestep 获得新的 y 位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多