【问题标题】:Smoother transition in movement?运动过渡更顺畅?
【发布时间】:2013-05-13 21:24:54
【问题描述】:

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

【问题讨论】:

  • 那么你到底想要什么?您想要更平滑的过渡,但又说想要即时移动?
  • 当您当前使用两个移动键中的任何一个时,您首先会看到汽车在开始以一个动作移动之前确实像一个 8 个单位的跳跃,而不是从一开始就以一个动作移动.如果我必须编辑问题,你会怎么称呼它?
  • 看来您正在从事件侦听器更新汽车位置。这意味着跳过与键盘重复之间的延迟有关。输入文本时按住任意键,您会看到。如果您想要正确的动画,则需要正确的循环设置。如果您愿意,我可以进一步解释,或者您可以四处寻找游戏设计教程。
  • 我很想请您解释一下!如果您愿意,可以将其作为答案包含在内,我可以接受:)
  • 我会在稍后写一个答案,除非有人先写。

标签: c# sfml


【解决方案1】:

您可能想从 SFML 的网站上阅读此 short tutorial

这些事件由操作系统触发,适用于某些用途(退出事件、按下某个键、单击鼠标左键),但不适用于需要经常更新的事情。想象一下,您正在编写一些文本,并按住“A”键。您的文本会像aaaaaaaaaaa 一样逐渐增长,但在 a 生成之间会有一点延迟,这是由操作系统强加的。比如说,你每秒会收到 6 个字母。这与事件相同。当游戏以 60 fps 运行和显示时,很明显您的移动将不会顺畅且难以控制。

希望 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++)。

另外,你不再需要你的事件处理程序,所以我评论了它。 但是如果您正在检查其他键(例如暂停键或其他键),请不要删除它,只需删除您写的关于移动汽车的部分。

【讨论】:

  • 我接受我得到答案的问题的答案。不过我明天会检查你说的内容!
  • 好的,希望对你有帮助!网站上的教程是针对 C++ 的,但您可以轻松地将它们翻译成 C#。
  • 我希望我真的可以做 C++ T_T
  • 我编辑了答案,根据您的程序为您提供一个小例子。
猜你喜欢
  • 2020-09-19
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多