如何在 xna 中为 wp7 生成平滑的运动?

发布于 2024-11-26 19:16:43 字数 389 浏览 0 评论 0原文

我想创建一个游戏并向我的游戏添加图像,现在我希望它能够顺利向下移动。我有这样的代码:

protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            pos.Y = pos.Y + 1;
            base.Update(gameTime);
        }

运动有效,但看起来不平滑,看起来像摇晃。 pos 是图像中位置的向量2。

如何让它更顺畅?

i want to create a game and addes a image to my game, now i want it to move down smoothly. i have a code like this:

protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            pos.Y = pos.Y + 1;
            base.Update(gameTime);
        }

the movement works but it dont looks smooth, it looks like it jiggle. pos is a vector2 for the position in the image.

how to make it more smooth?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凡尘雨 2024-12-03 19:16:43

如果您希望移动平滑而不添加物理库,您只需在位置更新中考虑游戏时间。

protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            pos.Y = pos.Y * 100 * (float)gameTime.ElapsedGameTime.TotalSeconds;
            base.Update(gameTime);
        }

我现在无法访问 XNA + Visual Studio,但我所做的更改应该能让您了解要尝试什么。请记住,更新调用每秒发生多次,因此经过的时间将是一个很小的数字,因此您必须将其乘以更大的“移动”值,在本例中我输入 100。调整 100 直到您看到您的移动速度欲望。

If you want movement to be smooth without adding a physics library you just have to factor in gameTime to your position update.

protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            pos.Y = pos.Y * 100 * (float)gameTime.ElapsedGameTime.TotalSeconds;
            base.Update(gameTime);
        }

I don't have access to XNA + visual studio right now, but the changes I made should give you an idea of what to try out. Keep in mind the Update call happens multiple times a second so the elapsed time will be a small number so then you have to multiply it by a larger "movement" value in this case I put 100. Tweak 100 until you see the movement speed you desire.

青衫负雪 2024-12-03 19:16:43

Beanish 是对的,如果你想要流畅,你应该乘以 GameTime。如果您只想让动画看起来流畅,那么物理就有点矫枉过正了。

我发现制作动画的最佳方法是使用位置插值,要实现此目的,您必须知道图像的初始位置(您已经知道这一点)和最终位置。

如果您想假设在 2 秒内从 A 移动到 B,您可以使用以下代码。

Vector2 a = new Vector2(0, 0);
Vector2 b = new Vector2(0, 100);

float elapsedTime = 0;
float duration = 2.0;

public override void Update(GameTime gameTime)
{
    float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
    elapsedTime += dt;
    if (elapsedTime > 1)
        elapsedTime = 1;

    float param = elapsedTime / duration;
    pos = Vector2.Lerp(a, b, param);
}

使用这种方法的最好的一点是,您现在可以使用“缓动”来使动画看起来非常非常漂亮。

为此,只需向插值器参数添加幂运算:

pos = Vector2.Lerp(a, b, (float)Math.Pow(param /2.0, 0.5));

这将使图像在到达 B 时减慢速度。您可以使用指数值 (0.5) 来获得不同的结果,例如尝试 2.0。

另一件重要的事情是你的图像将始终停在 B 处。如果你使用欧拉积分方法(你的方法,每帧添加一个速度),你可能会在使图像停在正确的位置(又名 B)处时遇到一些麻烦,并且它得到使用 2 或 3 维时情况更糟。

要了解有关缓动的更多信息,请查看Robert Penner 的缓动方程

Beanish is right, you should multiply by GameTime if you want smoothness. Physics is an overkill if you only want your animation to look smooth.

The best way I've found to do animation is by using position interpolation, for this to work you have to know the initial (you already know this) and final position of the image.

If you want to move from A to B in, say, 2 seconds, you can use the following code.

Vector2 a = new Vector2(0, 0);
Vector2 b = new Vector2(0, 100);

float elapsedTime = 0;
float duration = 2.0;

public override void Update(GameTime gameTime)
{
    float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
    elapsedTime += dt;
    if (elapsedTime > 1)
        elapsedTime = 1;

    float param = elapsedTime / duration;
    pos = Vector2.Lerp(a, b, param);
}

The best thing about using this approach is that you can now use "easing" to make you animation look really really nice.

To do this just add a Power operation to the interpolator parameter:

pos = Vector2.Lerp(a, b, (float)Math.Pow(param /2.0, 0.5));

This will make you image slow down as it arrives to B. You can play with the exponent value (0.5) to get different results, try 2.0 for example.

Another important thing is that your image will always stop at B. If you use the Euler integration approach (your approach, adding a velocity each frame) you might have some trouble making the image stop at the right position (aka B) and it gets even worse when using 2 or 3 dimesions.

To know more about easing, check Robert Penner's Easing Equations.

悲喜皆因你 2024-12-03 19:16:43

首先,我可以告诉您问题不是什么。您不需要物理引擎来实现平滑的运动。更改 Update 以包含 ElapsedGameTime 不会对平滑度产生任何影响(假设您没有更改 IsFixedTimestep 的默认值)为假)。当有固定的时间步长时,ElapsedGameTime 将始终具有相同的值,不会发生变化。

我不知道你在代码中做了多少,但如果太多,XNA 将开始跳过代码的 Draw 部分,这肯定会导致抖动。一种检查方法:在 Update 方法中,测试 IsRunningSlowly 的值。只要它为 true,XNA 将跳过一些 Draw 调用。

如果您没有做任何复杂的事情,那么罪魁祸首可能是显示器的刷新率。如果将其设置为 60Hz 以外的任何值,则会出现抖动现象。您可以通过更改显示器的刷新率来解决此问题。或者,您可以更改 TargetElapsedTime 的值以匹配您的显示器的速率。

First I can tell you what the problem isn't. You don't need a physics engine to have smooth movement. And changing the Update to include the ElapsedGameTime will not make a lick of difference for the smoothness (assuming you haven't changed the default of IsFixedTimestep to false). When there is a fixed timestep, ElapsedGameTime will always have the same value, it will not vary.

I don't how much you are doing in your code, but if it's too much, XNA will start skipping the Draw portion of your code, and this can definitely cause jerkiness. One way to check: in your Update method, test the value of IsRunningSlowly. Whenever it is true, XNA will skip some Draw calls.

If you are not doing anything complicated, then the culprit may be the refresh rate of your monitor. If it is set to anything other than 60Hz, you will have jerkiness. You could fix this by changing your monitor's refresh rate. Alternatively you can change the value of TargetElapsedTime to match your monitor's rate.

苍风燃霜 2024-12-03 19:16:43

您应该考虑在游戏中添加一个用于处理物理的库,例如 FarseerPhysics。通过应用物理规则计算每个时基的位置,您的动作将变得平滑自然。

You should consider adding to your game a library for handling physics, as for example FarseerPhysics. By calculating the position in a per time base with physics rules applied your movements will be smooth and natural.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文