gpt4 book ai didi

actionscript-3 - 物理恢复公式中的数学错误

转载 作者:行者123 更新时间:2023-12-04 22:07:36 26 4
gpt4 key购买 nike

我承认。我是一个数学白痴。我应该在家里尝试这个吗?可能不是没有受重伤。反正。任何在游戏和物理方面有一点经验的人都可以查看此代码并深入了解为什么原型(prototype)中的速度存在内置“损失”,这将受到极大的钦佩。

概念: Actor 从天而降,在某个点与边界 (trampoline.y) 相交,之后重力(在本例中为 1.6)停止运行,恢复因子(在本例中为 -6)采用超过。

现在,我正在尝试创建一个零和情况,在这种情况下,您从蹦床“弹跳”(hero.y >= trampoline.y)中出来的速度与您进入时的速度相同。情况并非如此痕迹显露。

我已经尝试了大约五种不同的方法,这是最新的,因为在我的游戏计时器(33 毫秒)的任何​​给定“tic”中,我们可能已经通过了蹦床的边界,因此加速规则将会改变。我真的以为我做到了,但结果显示每次反弹后速度都会下降,这不是我的预期。

我将以下代码提交给您枯燥的评论:

var newV:Number;
if (hero.y < trampoline.y) { newV = hero.velocityY + gravityAccelerationInPixels }
else { newV = hero.velocityY + TrampolineActor.SPRING_ACCELERATION }

var newY:Number = hero.y + newV;
trace("Coming in: y=" + hero.y + " oldVelocity=" + hero.velocityY + " newVelocity=" + newV + " Change in V: " + (newV - hero.velocityY) + ". Testing for newY=" + newY);

if ((hero.y < trampoline.y && newY < trampoline.y) || (hero.y >= trampoline.y && newY >= trampoline.y)) {
hero.y = newY;
hero.velocityY = newV;
} else {
trace("SPLIT");

var percent:Number = (trampoline.y - hero.y) / newV; trace("Percent: " + percent);
var newVV:Number;
if (hero.y < trampoline.y) {
// going down!
newVV = hero.velocityY + percent * gravityAccelerationInPixels; trace("New velocity before split: " + hero.velocityY + " Change in V: " + (newVV - hero.velocityY));
newVV += (1 - percent) * TrampolineActor.SPRING_ACCELERATION; trace("Percent after split: " + (1 - percent) + " Change in V: " + (newVV - hero.velocityY));
} else {
// movin on up!
newVV = hero.velocityY + percent * TrampolineActor.SPRING_ACCELERATION; trace("New velocity before split: " + hero.velocityY + " Change in V: " + (newVV - hero.velocityY));
newVV += (1 - percent) * gravityAccelerationInPixels; trace("Percent after split: " + (1 - percent) + " Change in V: " + (newVV - hero.velocityY));
}
trace("New velocity: " + newVV + " Change in V: " + (newVV - hero.velocityY));

hero.velocityY = newVV;

hero.y += hero.velocityY;
}

附加信息:
屏幕原点在左上角,所以 y-- = 更高
我的 tic 当前设置为 33 毫秒
GravityAccelerationInPixels 当前为 1.62(合理任意)
SPRING_ACCELERATION 是任意的 6,但我希望调整该数字以控制角色在减速/吸收周期中可以走多远低于蹦床。

现在我希望有一个解决方案,其中角色离开蹦床后的抽动速度与进入之前的速度相同(但为负)。哎呀,我什至尝试存储和检索进入位置和速度,但这看起来像打嗝。

最佳答案

以下是此类仿真的一些调试技术:

  • 首先:确保您知道每个变量和常量的单位。例如,如果 hero.y是以像素为单位的距离,那么因为它是由 hero.y + newV 调整的, 一定是 newV也是像素;除了它应该是速度(每次距离),所以它实际上必须是pixels per frame (时间步长是隐式的,因为您每帧执行一次)。

    对于接下来的调试步骤,最好确保所有值都以“每秒”而不是“每帧”表示;为此,请引入一个等于您的时间步长的值(以每帧秒为单位)。然后你有 hero.y + newV * timestep同样newV = hero.velocityY + gravityAccelerationInPixelsPerSecondSquared * timestep .

    可以计算gravityAccelerationInPixelsPerSecondSquared * timestep作为一个常数,但要确保所有硬编码的值不依赖于你的时间步长,这样你就可以轻松地:
  • 尝试将时间步长减少某个因子 k。如果这样做会减少您的错误,那么您的问题是因为您的离散时间步长计算与完美的时间积分答案不匹配。如果这不能减少您的错误,那么您的模拟是一致的,但在某种意义上是“非物理的”。
  • 尝试计算系统的总能量。也就是说,总和
  • 任何运动物体的动能,1/2·m·v²(m = 质量,v = 速度)
  • 任何落体的势能,m·g·h(g = 重力加速度常数,h = 任意引用点上方的高度)
  • 任何 Spring 的势能,1/2·k·d²(k = Spring 常数,希望等于您的“恢复因子”(但为正),d = 从松弛状态位移的距离)

  • 如果你让 h = hero.y - trampoline.y ,那么对于您的特定系统,您有

    E = 1/2·m·v² + m·g·max(h, 0) + 1/2·k·(min(h, 0))²

    (根据我对您的代码的阅读,角色在蹦床上时不应用重力;如果是,请将 max(h, 0) 更改为仅 h。)

    确保以一致的尺寸(不能将每秒像素添加到像素)和单位(不能将每秒像素添加到每帧像素或每秒英寸)执行此操作。不要忘记平方也是单位的平方。

    对于你的既定目标——角色以相同的速度弹起——你有一个无摩擦的系统,因此系统的能量在弹跳之前、期间和之后应该是相同的。如果能量发生变化,请注意它何时发生变化。例如:
  • 如果它在角色下落时发生变化,那么您对这种情况的模拟,即恒定加速度,是不正确的。 一个常见的错误(看起来你在代码中犯了这个错误)是忘记了位置 under constant acceleration 公式的第三项。 : newPos = pos + velocity * timestep + 1/2 * acceleration * timestep^2 ,其中加速度是重力。 (在更新速度之前更新位置也很重要,这样您就不会在位置计算中使用“明天的”速度和“昨天的”位置。)尝试模拟在硬表面而不是蹦床上的弹跳以简化情况。
  • 如果它在角色接触或离开蹦床时发生变化,您的percent计算没有达到它的目标。
  • 关于actionscript-3 - 物理恢复公式中的数学错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7055214/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com