我回来了另一个问题。我还是SFML的新手,所以这个看起来有点难。我尝试过使用while循环等但无济于事。
我现在正在做的游戏是一辆汽车在X轴上前后移动然后我想能够拿起点和东西,或者只是避免物体朝向汽车直到最终死亡。 / p>
如何使动作更流畅?目前,汽车将首先移动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
}
}
}
}
}
答案 0 :(得分:2)
您可能希望从SFML的网站上阅读此short tutorial。
事件由操作系统触发,并且对于某些目的有好处(退出事件,按下键,单击鼠标左键)但不适用于需要经常更新的事物。想象一下,你正在写一些文字,并按下'A'键。你的文本将逐渐增长,如aaaaaaaaaaa
,但由OS强加的产生之间会有一点延迟。比方说你会得到6个字母。这与事件相同。游戏运行并以60 fps的速度显示,很明显你的动作不会流畅,几乎无法控制。
希望SFML提供一种检查键盘(以及鼠标和操纵杆)即时状态的方法。使用C#绑定(我假设你使用2.0版本的绑定,如果你没有,那么你应该),你只需要检查Keyboard.isKeyPressed(yourKey)
。
在主循环中执行此操作将在每个帧检查按下该键,而不是等待速度较慢的OS事件。
在旁注中,如果您之前的问题得到了正确回答,请通过接受答案进行标记。
编辑:我的计算机上没有安装SFML for .NET,但这可能是它的样子
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 ++编写的)。
此外,您不再需要事件处理程序,所以我对它进行了评论。 但是如果您正在检查其他按键(例如暂停等等),请不要将其删除,只需删除您撰写的有关移动汽车的部分。