二维宇宙飞船运动数学
我正在尝试制作一款自上而下的宇宙飞船游戏,我希望动作更加真实。 360 度惯性、重力等。
我的问题是我可以让船在惯性下移动 360° 没有问题,但我需要做的是限制发动机的速度,同时不限制其他推动力/拉船。
因此,如果发动机速度最大为 500,并且船舶从重力井处以 1000 的速度行驶,则当发动机打开时,船舶不会达到 1500,但如果指向远离正在行驶的角度,那么它可能会减慢向下。
就其价值而言,我正在使用 Construct,我所需要的只是它的数学。
感谢您的帮助,我因为试图解决这个问题而变得秃头。
I'm trying to make a top-down spaceship game and I want the movement to somewhat realistic. 360 degrees with inertia, gravity, etc.
My problem is I can make the ship move 360° with inertia with no problem, but what I need to do is impose a limit for how fast the engines can go while not limiting other forces pushing/pulling the ship.
So, if the engines speed is a maximum of 500 and the ship is going 1000 from a gravity well, the ship is not going to go 1500 when it's engines are on, but if is pointing away from the angle is going then it could slow down.
For what it's worth, I'm using Construct, and all I need is the math of it.
Thanks for any help, I'm going bald from trying to figure this out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从相对物理中获取页面,其中对象不能超过光速:
(请参阅下面的我的工作 C++ 代码片段和 运行演示 [仅限 Windows]。)
说明:
洛伦兹因子的定义,其中 v 是速度,c 是光速:
这是有效的,因为洛伦兹因子随着速度的增加而接近无穷大。物体需要施加无穷大的力才能穿过光速。在较低速度下,洛伦兹因子非常接近 1,接近经典牛顿物理学。
洛伦兹因子随速度增加的图表:
注意:我之前尝试通过使用摩擦设置来解决小行星游戏中的类似问题。我在读到你的问题时才想出了这个解决方案^^
更新:
我尝试实现这个并发现一个潜在的缺陷:当接近光速 c 时,所有方向的加速度都受到限制,包括减速! (违反直觉,但是现实世界中狭义相对论会发生这种情况吗?)我想可以修改该算法以考虑速度和力矢量的方向...该算法已被进行了修改以考虑矢量方向,以便船舶在高速行驶时不会“失去可控性”。更新:这是我的小行星游戏中的代码片段,它使用洛伦兹因子限制游戏对象的速度。效果非常好!
更新:*添加了可下载演示(仅限Windows;从其他平台的源代码构建) 我不确定 zip 中是否包含所有依赖项;如果缺少某些内容,请告诉我。并且玩得开心^^
Take a page from relative physics, where objects cannot exceed the speed of light:
(See below for my working C++ code snippet and running demo [Windows only].)
Explanation:
Definition of Lorentz factor, where v is velocity and c is the speed of light:
This works because the Lorentz factor approaches infinity as velocity increases. Objects would need an infinite amount of force applied to cross the speed of light. At lower velocities, the Lorentz factor is very close to 1, approximating classical Newtonian physics.
Graph of Lorentz factor as velocity increases:
Note: I previously tried to solve a similar problem in my asteroids game by playing with friction settings. I just came up with this solution as I read your question^^
Update:
I tried implementing this and found one potential flaw: acceleration in all directions is limited as the speed of light c is approached, including deceleration! (Counter-intuitive, but does this happen with special relativity in the real world?) I guess this algorithm could be modified to account for the directions of the velocity and force vectors...The algorithm has been modified to account for directions of vectors so the ship does not "lose controllability" at high speeds.Update: Here is a code snippet from my asteroids game, which uses the Lorentz factor to limit the speed of game objects. It works pretty well!
update:* added downloadable demo (Windows only; build from source code for other platforms) of this algorithm in action. I'm not sure if all the dependencies were included in the zip; please let me know if something's missing. And have fun^^
好吧,让我们首先考虑现实问题,看看为什么这行不通,以及我们必须如何与之不同。在太空中,只要你的引擎在点火,你就会加速。你的速度仅受燃料限制(事实上,一旦你消耗了一些燃料,你就可以加速得更快,因为你移动的质量更小)。
为了给这个模型一个有效的最大速度,您可以考虑空间中的粒子会减慢您的速度并引起摩擦。你走得越快,你击中的粒子就越多,击中它们的速度也越快,所以最终以足够快的速度,你将击中足够多的粒子,它们的减速量恰好抵消了引擎的加速量正在做。
这个现实的模型听起来不像你想要的。原因是:你必须引入摩擦。这意味着如果您关闭引擎,您将自动开始减速。您可能可以将其视为您不想要的意外力量之一。
这使得我们在达到一定速度时将发动机的有效力降低到 0。现在请记住,如果您向北方向行驶最大速度,您仍然希望力量能够将您推向东方向,因此您的引擎不应仅通过原始速度来关闭,而是基于您的速度朝着你的引擎指向的方向行驶。
因此,对于数学:
您需要在引擎指向向量和速度向量之间进行
十字点积,以获得引擎指向方向的有效速度。一旦达到这个速度,例如 125 英里/小时(最大速度为 150),您就可以将发动机施加的力缩小到 (150-125)/150*(发动机力)。这将极大地改变加速到全速所需时间的速度图。当您接近全速时,您的发动机的动力会变得越来越弱。测试一下,看看它是否是您想要的。另一种方法是,如果点积 >=150,则仅说发动机力 = 0,否则为满力。这将使您能够线性加速到最大速度,但不能再进一步。
现在我想起来,这个模型并不完美,因为你可以向北方向加速到 150 英里/小时,然后向东转向,朝那个方向加速到 150 英里/小时,总共在东北方向加速到 212 英里/小时,所以不是一个完美的解决方案。
Well, lets consider the realistic problem first and see why this doesn't work and how we have to differ from it. In space as long as your engines are firing, you will be accelerating. Your speed is only limited by your fuel (and in fact you can accelerate faster once you've spent some fuel because your moving less mass).
To give this model an effective maximum speed, you can consider particles in space slowing you down and causing friction. The faster you go, the more particles you're hitting and the faster you're hitting them, so eventually at some fast enough speed, you will be hitting enough particles the amount of decelerating they do exactly cancels out the amount of accelerating your engine is doing.
This realistic model does NOT sound like what you want. The reason being: You have to introduce friction. This means if you cut your engines, you will automatically start to slow down. You can probably count this as one of the unintended forces you do not want.
This leaves us with reducing the effective force of your engine to 0 upon reaching a certain speed. Now keep in mind if your going max speed in the north direction, you still want force to be able to push you in the east direction, so your engines shouldn't be cut out by raw velocity alone, but instead based on the velocity your going in the direction your engines are pointing.
So, for the math:
You want to do a
crossdot product between your engine pointing vector and your velocity vector to get the effective velocity in the direction your engines are pointing. Once you have this velocity, say, 125 mph (with a max speed of 150) you can then scale back the force of your engines is exerting to (150-125)/150*(Force of Engines).This will drastically change the velocity graph of how long it will take you to accelerate to full speed. As you approach the full speed your engines become less and less powerful. Test this out and see if it is what you want. Another approach is to just say Force of Engines = 0 if the dot product is >=150, otherwise it is full force. This will allow you to accelerate linearly to your max speed, but no further.
Now that I think about it, this model isn't perfect, because you could accelerate to 150 mph in the north direction, and then turn east and accelerate to 150 mph going in that direction for a total of 212 mph in the north east direction, so not a perfect solution.
我真的很喜欢 Wongsungi 的答案(带有洛伦兹因子),但我想指出的是,可以简化代码以减少浮点运算。
不是计算洛伦兹因子(其本身是倒数)然后除以它,如下所示:
只需乘以洛伦兹因子的倒数,如下所示:
这从代码中消除了一个浮点运算,并且还消除了需要将 b 限制为 DBL_MIN(现在可以将其限制为 0,因为我们不再进行除法)。当您可以乘以 x 时,为什么要除以 x 的倒数呢?
此外,如果您可以保证 v 的大小永远不会超过 c,那么您可以消除 b 小于零的测试。
最后,您可以通过在外部
if< 中使用
length_squared()
而不是length()
来消除两个额外的sqrt()
操作。 /code> 语句:这可能只会造成 0.1% 的速度差异,但我认为这样代码更简单。
I really do like Wongsungi's answer (with the Lorentz factor), but I wanted to note that the code can be simplified to have fewer floating-point operations.
Instead of calculating the Lorentz factor (which itself is a reciprocal) and then dividing by it, like this:
simply multiply by the reciprocal of the Lorentz factor, like this:
This eliminates one floating-point operation from the code, and also eliminates the need to clamp b to DBL_MIN (it can now be clamped to 0 because we're not dividing anymore). Why divide by the reciprocal of x when you can just multiply by x?
Additionally, if you can guarantee that the magnitude of v will never exceed c, then you can eliminate the testing of b being less than zero.
Finally, you can eliminate two additional
sqrt()
operations by usinglength_squared()
instead oflength()
in the outerif
statement:This may only make a 0.1% difference in speed, but I think the code is simpler this way.
您的飞船需要三个变量,您可以根据作用在其上的力在每个物理时间步长更新这些变量。这些将是质量、位置和速度。 (请注意,位置和速度是单个数字,而是矢量)。在每个物理时间步,您根据速度更新位置,并根据加速度更新速度。您可以根据作用在船上的力(重力、摩擦力、发动机)来计算加速度。
牛顿力方程为
F = M*A
我们可以将其重新排列为A = F/M< /code> 获得加速度。基本上,您需要计算出船舶应加速多少以及方向(矢量),然后将该加速度添加到船舶的速度,并将船舶的速度添加到其位置。
这是您应该执行每个物理时间步骤的代码(我希望您可以填写空白)请询问这是否还不够详细
You need to have three variables for your ship, which you update at each physics time step based on the forces that are acting on it. These will be mass, position, and velocity. (note that position and velocity are single numbers but vectors). At each physics time step you update the position based on the velocity, and the velocity based on the acceleration. you calculate the acceleration based on the forces acting on the ship (gravity, friction, engines)
Newton's equation for force is
F = M*A
We can rearrange that toA = F/M
to get Acceleration. Basically you need to figure out how much the ship should accelerate, and in which direction (vector), then add that acceleration to the ship's velocity, and add the ship's velocity to its position.Here is the code you should execute each physics time step (I hope you can fill in the blanks) please ask if this is not enough detail
你的问题对我来说很难理解,但似乎你没有在这个游戏中使用真实的物理原理。您是否考虑过使用真实的物理方程,例如速度、加速度、力等?
编辑:
经过您的编辑,我想我有了更好的理解。您只是跟踪当前速度(或类似的速度),但没有跟踪该速度来自的力。船舶不应该存储任何该信息(除了发动机推力)——它应该来自船舶所在的环境。
例如,环境有一个重力矢量(方向力),因此您需要将其考虑到在计算发动机提供的方向力时要考虑这一点。
你的船应该存储自己的发动机力、加速度和速度。
Your question is difficult for me to understand but it seems like you're not using real physics for this game. Have you considered using real physics equations such as velocity, acceleration, force, etc?
Edit:
After your edits, I think I have a better understanding. You are simply keeping track of the current velocity (or something similar) but you don't keep track of the force where that velocity comes from. The ship should not be storing any of that information (other than engine thrust) -- it should come from the environment the ship is in.
For instance, the environment has a gravity vector (directional force) so you would need to take that into account when calculating the directional force provided by the engine.
Your ship should be storing its own engine force, acceleration, and velocity.