运动过程更顺畅?

时间:2013-05-19 01:18:14

标签: c# sfml

我回来了另一个问题。我还是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
                }
            }
        }
    }
}

1 个答案:

答案 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 ++编写的)。

此外,您不再需要事件处理程序,所以我对它进行了评论。 但是如果您正在检查其他按键(例如暂停等等),请不要将其删除,只需删除您撰写的有关移动汽车的部分。