我想创建一个游戏并将图像添加到我的游戏中,现在我希望它能够顺利地向下移动。我有这样的代码:
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是图像中位置的vector2。
如何让它更顺畅?
答案 0 :(得分:3)
如果你想在没有添加物理库的情况下保持平滑运动,你只需要将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);
}
我现在无法访问XNA + visual studio,但我所做的更改应该让您了解要尝试的内容。请记住,更新呼叫每秒发生多次,因此经过的时间将是一个小数字,所以你必须将它乘以一个更大的“移动”值,在这种情况下,我把100.调整100直到你看到移动速度你欲望。
答案 1 :(得分:2)
Beanish是对的,如果你想要平滑,你应该乘以GameTime。如果你只想让你的动画看起来流畅,那么物理学是一种矫枉过正。
我发现做动画的最佳方法是使用位置插值,为此工作你必须知道初始(你已经知道这一点)和图像的最终位置。 < / p>
如果你想在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);
}
使用这种方法的最好的事情是你现在可以使用“缓动”来让动画看起来非常好。
要执行此操作,只需在插补器参数中添加Power操作:
pos = Vector2.Lerp(a, b, (float)Math.Pow(param /2.0, 0.5));
这会使你的图像到达B时变慢。你可以使用指数值(0.5)来获得不同的结果,例如尝试2.0。
另一个重要的事情是你的图像将始终停在B.如果你使用欧拉积分方法(你的方法,每帧添加一个速度)你可能有一些麻烦使图像停在正确的位置(又名B)当使用2或3个硬币时,它会变得更糟。
要了解有关宽松的更多信息,请查看Robert Penner's Easing Equations。
答案 2 :(得分:1)
首先我可以告诉你不是什么问题。你不需要物理引擎来平稳移动。将Update
更改为包含ElapsedGameTime
不会对平滑性产生任何影响(假设您没有将IsFixedTimestep
的默认值更改为false)。如果有固定的时间步长,ElapsedGameTime
将始终具有相同的值,则不会发生变化。
我不知道你在代码中做了多少,但是如果它太多了,XNA将开始跳过代码的Draw
部分,这肯定会导致急躁。一种检查方法:在Update
方法中,测试IsRunningSlowly
的值。只要是真的,XNA就会跳过一些Draw
次呼叫。
如果你不做任何复杂的事情,那么罪魁祸首可能是你的显示器的刷新率。如果它设置为60Hz以外的任何值,你就会有急动。您可以通过更改显示器的刷新率来解决此问题。或者,您可以更改TargetElapsedTime
的值以匹配您的显示器的费率。
答案 3 :(得分:0)
您应该考虑在游戏中添加用于处理物理的库,例如FarseerPhysics。通过应用物理规则计算每个时基的位置,您的动作将是平滑自然的。