简体   繁体   English

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

[英]howto generate a smooth movement in xna for wp7?

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. pos是图像中位置的向量。

how to make it more smooth? 如何使其更平滑?

If you want movement to be smooth without adding a physics library you just have to factor in gameTime to your position update. 如果您想在不添加物理库的情况下使运动保持平稳,则只需将gameTime纳入位置更新中即可。

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. 我目前无法使用XNA + Visual Studio,但是我所做的更改应该使您知道如何尝试。 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. 请记住,Update调用每秒发生多次,因此经过的时间很小,因此在这种情况下,我必须将其乘以较大的“运动”值。我将其设置为100。调整100,直到您看到运动速度为止欲望。

Beanish is right, you should multiply by GameTime if you want smoothness. Beanish是正确的,如果要平滑,则应乘以GameTime。 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. 如果要在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);
}

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: 为此,只需将Power操作添加到interpolator参数:

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. 这将使图像在到达B时变慢。您可以使用指数值(0.5)来获得不同的结果,例如尝试2.0。

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. 另一个重要的事情是您的图像将始终停在B点。如果您使用Euler积分方法(您的方法,每帧增加一个速度),则可能难以使图像停在正确的位置(也称为B点),并且使用2或3个维度时甚至更糟。

To know more about easing, check Robert Penner's Easing Equations . 要了解有关宽松的更多信息,请查看Robert Penner的Easing Equations

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). 并且将Update更改为包括ElapsedGameTime不会对平滑度造成任何影响(假设您尚未将IsFixedTimestep的默认值IsFixedTimestep为false)。 When there is a fixed timestep, ElapsedGameTime will always have the same value, it will not vary. 当有固定的时间步长时, ElapsedGameTime将始终具有相同的值,并且不会变化。

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. 我并没有在代码中做多少事情,但是如果过多,XNA将开始跳过代码的Draw部分,这肯定会引起混乱。 One way to check: in your Update method, test the value of IsRunningSlowly . 一种检查方式:在Update方法中,测试IsRunningSlowly的值。 Whenever it is true, XNA will skip some Draw calls. 只要为真,XNA都会跳过一些Draw调用。

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. 如果将其设置为60Hz以外的任何其他值,则可能会出现混响。 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. 或者,您可以更改TargetElapsedTime的值以匹配监视器的速率。

You should consider adding to your game a library for handling physics, as for example FarseerPhysics . 您应该考虑在游戏中添加一个用于处理物理的库,例如FarseerPhysics By calculating the position in a per time base with physics rules applied your movements will be smooth and natural. 通过应用物理规则计算每个时基的位置,您的动作将变得顺畅自然。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM