运动的过渡更平滑
本文关键字:平滑 运动 | 更新日期: 2023-09-27 18:14:12
我又问了一个问题。我仍然是SFML的新手,所以这个似乎有点难。我试过使用while循环等,但无济于事。
我现在正在做的游戏是一辆在X轴上来回行驶的汽车,然后我猜它将能够拾取点和东西,或者只是简单地避开朝向汽车的物体,直到它最终死亡。
如何使运动更流畅?目前,汽车会先移动8个单位,然后再向我想要的方向移动8个单位,直到我松开按钮。反过来也是一样的。我希望当我按任意一个键时,它能立即移动并保持移动。
static void OnKeyPressed(object sender, EventArgs e)
{
Vector2f newPos = new Vector2f(0, car.Position.Y);
KeyEventArgs ke = (KeyEventArgs)e;
if (ke.Code.Equals(Keyboard.Key.A))
{
if (car.Position.X != 0)
{
newPos.X = car.Position.X - 8;
car.Position = newPos;
}
else if (car.Position.X < 0)
{
newPos.X = 0;
car.Position = newPos;
}
else if(car.Position.X == 0)
{
// Do nothing
}
}
else if (ke.Code.Equals(Keyboard.Key.D))
{
if (car.Position.X != window.Size.X - 32)
{
newPos.X = car.Position.X + 8;
car.Position = newPos;
}
else if (car.Position.X > window.Size.X)
{
newPos.X = window.Size.X;
car.Position = newPos;
}
else if (car.Position.X == window.Size.X)
{
// Do nothing
}
}
}
和整个东西作为参考:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using SFML.Audio;
using SFML.Graphics;
using SFML.Window;
namespace SFMLCarGame
{
class Program
{
private static RenderWindow window;
private static Sprite car;
static void Main(string[] args)
{
window = new RenderWindow(new VideoMode(256,512), "Car Game");
window.Closed += new EventHandler(OnClose);
window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
Sprite bg = new Sprite(new Texture("road.png"));
car = new Sprite(new Texture("car.png"));
car.Position = new Vector2f(window.Size.X / 2, window.Size.Y - 96);
while (window.IsOpen())
{
window.DispatchEvents();
window.Clear();
window.Draw(bg);
window.Draw(car);
window.Display();
}
}
static void OnClose(object sender, EventArgs e)
{
RenderWindow window = (RenderWindow)sender;
window.Close();
}
static void OnKeyPressed(object sender, EventArgs e)
{
Vector2f newPos = new Vector2f(0, car.Position.Y);
KeyEventArgs ke = (KeyEventArgs)e;
if (ke.Code.Equals(Keyboard.Key.A))
{
if (car.Position.X != 0)
{
newPos.X = car.Position.X - 8;
car.Position = newPos;
}
else if (car.Position.X < 0)
{
newPos.X = 0;
car.Position = newPos;
}
else if(car.Position.X == 0)
{
// Do nothing
}
}
else if (ke.Code.Equals(Keyboard.Key.D))
{
if (car.Position.X != window.Size.X - 32)
{
newPos.X = car.Position.X + 8;
car.Position = newPos;
}
else if (car.Position.X > window.Size.X)
{
newPos.X = window.Size.X;
car.Position = newPos;
}
else if (car.Position.X == window.Size.X)
{
// Do nothing
}
}
}
}
}
你可以从SFML的网站上阅读这个简短的教程。
事件是由操作系统触发的,并且对于某些目的(退出事件,按下一个键,单击鼠标左键)是有好处的,但是对于需要经常更新的东西不是很有用。假设你正在写一些文本,并一直按下"A"键。你的文本将像aaaaaaaaaaa
一样逐渐增长,但在a刷出之间有一点延迟,这是由操作系统强加的。每秒钟你会得到6个字母。事件也是如此。当游戏以60帧/秒的速度运行和显示时,很明显你的移动将不顺畅,几乎无法管理。
希望SFML提供一种方法来检查键盘(鼠标和操纵杆)的即时状态。使用c#绑定(我假设你使用的是2.0版本的绑定,如果你没有,那么你应该),你只需要检查Keyboard.isKeyPressed(yourKey)
。在主循环中这样做将在每一帧检查键被按下,而不是等待操作系统事件,这是慢得多的。
顺便说一句,如果你之前的问题回答正确,请通过接受答案来标记它们。
编辑:我的电脑上没有安装。net的SFML,但它可能是这样的
static void Main(string[] args)
{
window = new RenderWindow(new VideoMode(256,512), "Car Game");
window.Closed += new EventHandler(OnClose);
// Note this
// window.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
Sprite bg = new Sprite(new Texture("road.png"));
car = new Sprite(new Texture("car.png"));
car.Position = new Vector2f(window.Size.X / 2, window.Size.Y - 96);
while (window.IsOpen())
{
window.DispatchEvents();
CheckInputs(); // and this !
window.Clear();
window.Draw(bg);
window.Draw(car);
window.Display();
}
}
void CheckInputs()
{
if(Keyboard.isKeyPressed(Keyboard.key.A))
{
if(car.Position.X < 0)
car.Position.X = 0
else if(car.Position.X > 0)
car.Position.X -= 8; // shortcut for 'car.Position.X = car.Position.X - 8'
}
else if(Keyboard.isKeyPressed(Keyboard.key.D))
{
// etc
}
}
这样你的过渡应该更平滑,但要注意,8像素可能会非常快!我强烈建议你阅读我链接的教程,因为它以一种与语言无关的方式解释了输入的功能(即使示例是用c++编写的)。
另外,你不再需要你的事件处理程序了,所以我注释了它。但是如果您正在检查其他键(如escape for pause或其他)不要删除它,只需删除您写的关于移动汽车的部分。