2

私はC#でビデオゲームを書いていますが、ゲームループの特定のポイントでのみ特定のイベント(キーボード/マウスイベントなど)を処理したいと思います。たとえば、次のようなものを書く方法はありますか?

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

ループ内の他のポイントでイベントが発生した場合は、それらを処理するまで待ちたいと思いhandleAllEvents()ます。「イベント」とは、標準のC#イベントシステムを意味します。例:

public event Action<object, KeyboardEventArgs> KeyPressed;

質問が明確に表現されていない場合はお知らせください。ありがとう!

4

3 に答える 3

5

の呼び出しを削除Application.Run()し、独自のメッセージループを構築します。たとえば、次のようになります。

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

次に、レンダリングがそれほど長くそこにとどまらないことを確認する必要があります。

詳細については、Applicationクラス、特にメソッドRun()とを学習することをお勧めしますDoEvents()

于 2011-11-23T21:55:21.897 に答える
1

OpenTKでそれを行う適切な方法は、GameWindowクラスから継承してから、とをオーバーライドすることだOnUpdateFrameと思いますOnRenderFrame。トランクをチェックアウトし、ファイルをチェックするときに含まれるクイックスタートソリューションがありGame.csます。

[編集]さらに明確にするために、OpenTK.GameWindowクラスは( OpenTK.Input.KeyboardDeviceKeyboardタイプの)プロパティを提供します。これは内部で読み取る必要があります。キーボードイベントは基本クラスによってすでに処理されているため、個別に処理する必要はありません。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();
    }
}

また、より複雑な例については、Webページからさらに別のスターターキットをダウンロードしてください。クラスは次のようになります。

// 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をダウンロードして、そこでどのように実装されているかを確認することをお勧めします。

于 2011-11-23T22:00:53.143 に答える
1

通常はイベントを処理しないゲームループを使用している場合は、必要なときに(つまり、handleAllEvents()メソッド内で)入力デバイスをポーリングします。いくつかの簡単な調査によると、OpenTK.Inputでは、名前空間、特にKeyboardDeviceクラスでこのようなものを見つけることができます。

于 2011-11-23T22:01:33.787 に答える