C# 中仅在特定时间触发事件

发布于 2024-12-17 12:01:34 字数 379 浏览 1 评论 0原文

我正在用 C# 编写一个视频游戏,我想仅在游戏循环中的特定点处理某些事件(例如键盘/鼠标事件)。例如,有没有办法编写如下内容:

void gameLoop()
{
    // do updates
    handleAllEvents();
    render();
}

如果事件发生在循环中的其他点,我想等到 handleAllEvents() 来处理它们。我所说的“事件”是指标准 C# 事件系统,例如:

public event Action<object, KeyboardEventArgs> KeyPressed;

如果问题表述不清楚,请告诉我。谢谢!

I am writing a video game in C#, and I would like to handle certain events (e.g. keyboard/mouse events) only at a specific point in my game loop. For example, is there a way to write something like the following:

void gameLoop()
{
    // do updates
    handleAllEvents();
    render();
}

If an event occurs at some other point in the loop, I would like to wait until handleAllEvents() to handle them. By "events" I mean the standard C# event system, for example:

public event Action<object, KeyboardEventArgs> KeyPressed;

Please let me know if the question is not phrased clearly. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别低头,皇冠会掉 2024-12-24 12:01:34

删除对 Application.Run() 的调用,并构建您自己的消息循环。例如这样:

void GameLoop()
{
      while (!exitSignal)
      {
          Application.DoEvents();
          render();
      }
}

然后您必须确保渲染不会在那里停留太久。

有关详细信息,我建议您研究 Application 类,特别是方法 Run()DoEvents()

Remove the call to Application.Run(), and build up your own message loop. For example like this:

void GameLoop()
{
      while (!exitSignal)
      {
          Application.DoEvents();
          render();
      }
}

You must then ensure, that render will not stay there for so long.

For more info I suggest you to study the Application class, especially methods Run() and DoEvents().

┾廆蒐ゝ 2024-12-24 12:01:34

如果您使用游戏循环,通常不会处理事件,您会在需要时轮询输入设备(即在 handleAllEvents() 方法中)。一些快速研究告诉我,在 你可以找到这些东西位于 OpenTK.Input 命名空间中,特别是 KeyboardDevice 类中。

If you're using a game loop you generally wouldn't handle events, you'd poll input devices when you need them (i.e. in your handleAllEvents() method). Some quick researched told me that in you can find this stuff in the OpenTK.Input namespace and in particular the KeyboardDevice class.

豆芽 2024-12-24 12:01:34

我相信在 OpenTK 中执行此操作的正确方法是从 GameWindow 类继承,然后重写 OnUpdateFrameOnRenderFrame。当您签出主干时,其中包含一个快速入门解决方案,请检查 Game.cs 文件。

[编辑]为了进一步澄清,OpenTK.GameWindow< /code>类提供了一个 Keyboard 属性(类型为 OpenTK.Input.KeyboardDevice),应在 OnUpdateFrame。无需单独处理键盘事件,因为这已经由基类处理。

/// <summary>
/// Called when it is time to setup the next frame. Add you game logic here.
/// </summary>
protected override void OnUpdateFrame(FrameEventArgs e)
{
    base.OnUpdateFrame(e);
    TimeSlice();

    // handle keyboard here
    if (Keyboard[Key.Escape])
    {
        // escape key was pressed
        Exit();
    }
}

另外,要获得更详细的示例,请从其网页下载另一个入门工具包。该类应该看起来像这样:

// Note: Taken from http://www.opentk.com
// Yet Another Starter Kit by Hortus Longus
// (http://www.opentk.com/project/Yask)
partial class Game : GameWindow
{        
    /// <summary>Init stuff.</summary>
    public Game()
      : base(800, 600, OpenTK.Graphics.GraphicsMode.Default, "My Game")
    { VSync = VSyncMode.On; }

    /// <summary>Load resources here.</summary>
    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);
      // load stuff
    }

    /// <summary>Called when your window is resized.
    /// Set your viewport/projection matrix here.
    /// </summary>
    protected override void OnResize(EventArgs e)
    {
      base.OnResize(e);
      // do resize stuff
    }

    /// <summary>
    /// Called when it is time to setup the next frame. Add you game logic here.
    /// </summary>
    protected override void OnUpdateFrame(FrameEventArgs e)
    {
      base.OnUpdateFrame(e);
      TimeSlice();
      // handle keyboard here
    }

    /// <summary>
    /// Called when it is time to render the next frame. Add your rendering code here.
    /// </summary>
    protected override void OnRenderFrame(FrameEventArgs e)
    {
      base.OnRenderFrame(e);
      // do your rendering here
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        using (Game game = new Game())
        {
            game.Run(30.0);
        }
    }
}

我建议您下载 Yask 并检查它是如何实现的。

I believe the proper way to do it in OpenTK would be to inherit from the GameWindow class, and then override OnUpdateFrame and OnRenderFrame. There is a QuickStart solution included when you checkout the trunk, check the Game.cs file.

[Edit] To clarify further, OpenTK.GameWindow class provides a Keyboard property (of type OpenTK.Input.KeyboardDevice), which should be read inside OnUpdateFrame. There is no need to handle keyboard events separately, as this is already handled by the base class.

/// <summary>
/// Called when it is time to setup the next frame. Add you game logic here.
/// </summary>
protected override void OnUpdateFrame(FrameEventArgs e)
{
    base.OnUpdateFrame(e);
    TimeSlice();

    // handle keyboard here
    if (Keyboard[Key.Escape])
    {
        // escape key was pressed
        Exit();
    }
}

Also, for a more elaborate example, download Yet another starter kit from their webpage. The class should look something like this:

// Note: Taken from http://www.opentk.com
// Yet Another Starter Kit by Hortus Longus
// (http://www.opentk.com/project/Yask)
partial class Game : GameWindow
{        
    /// <summary>Init stuff.</summary>
    public Game()
      : base(800, 600, OpenTK.Graphics.GraphicsMode.Default, "My Game")
    { VSync = VSyncMode.On; }

    /// <summary>Load resources here.</summary>
    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);
      // load stuff
    }

    /// <summary>Called when your window is resized.
    /// Set your viewport/projection matrix here.
    /// </summary>
    protected override void OnResize(EventArgs e)
    {
      base.OnResize(e);
      // do resize stuff
    }

    /// <summary>
    /// Called when it is time to setup the next frame. Add you game logic here.
    /// </summary>
    protected override void OnUpdateFrame(FrameEventArgs e)
    {
      base.OnUpdateFrame(e);
      TimeSlice();
      // handle keyboard here
    }

    /// <summary>
    /// Called when it is time to render the next frame. Add your rendering code here.
    /// </summary>
    protected override void OnRenderFrame(FrameEventArgs e)
    {
      base.OnRenderFrame(e);
      // do your rendering here
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        using (Game game = new Game())
        {
            game.Run(30.0);
        }
    }
}

I would recommend that you download Yask and check how it's implemented there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文