2011-11-23 6 views
2

C#でビデオゲームを作成しています。ゲームループの特定のポイントで特定のイベント(キーボード/マウスイベントなど)を処理したいと思います。たとえば、以下のようなものを書くための方法があります:C#で特定の時刻に発生したイベントのみを処理します。

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

イベントは、ループ内の他のいくつかのポイントで発生した場合、私はそれらを処理するためにhandleAllEvents()まで待つしたいと思います。 「イベント」私は例えば、標準的なC#のイベントシステムを意味することにより:

public event Action<object, KeyboardEventArgs> KeyPressed; 

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

+2

イベントの全体的なポイントが同期的に処理されないのではなく、特定のコード行に達したときですか?おそらく、「イベント」が本当に「イベント」でない場合、調査するべき異なる設計戦略があります。また、リアクティブエクステンションは、イベントを処理するための本当に強力なフレームワークです - http://msdn.microsoft.com/en-us/data/gg577609見てみな。 –

+0

ゲームの一般的なアプローチ(ポーリング)については、[mine](http://stackoverflow.com/q/8249664/593627)を参照してください。 –

+0

@Sean:ゲームループは、ゲームプログラミングのかなり一般的なパターンです。必ずしもこのように実装する必要はありませんが、各フレームをレンダリングする前に入力ロジックとゲームロジックを完全に処理することがポイントです。イベントがランダムに発生する可能性があると、ゲームの設計が著しく複雑になります。 – Groo

答えて

5

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

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

レンダリングが長続きしないようにする必要があります。

詳細についてはApplicationクラス、特に方法Run()DoEvents()を勉強することをお勧めします。

+0

これは良い方法ですが、再考する必要はありません。 'OpenTK.GameWindow'クラスは既にvsyncing、タイムスライシング、ダブルバッファリングなどの処理を行っています。ソースコード[here](http://www.opentk.com/files/doc/_game_window_8cs_source.html)を確認できます。 )それはボンネットの下で行うすべてのものを見るために。 – Groo

+0

私は既にGameWindowを使用しています。私の問題は、いくつかのイベント(OSイベントなど)が発生したときや、他のいくつかのイベントが発生したときに気にしないことです(例えば、キーの押下を待つことができれば、フレーム初期化)。それは合理的に聞こえるのですか、私は私のプログラムを構造化する他の方法を考えなければなりませんか? – fyhuang

1

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

[編集]さらに明確にするために、OpenTK.GameWindowクラスはOnUpdateFrame内部に読まれるべき、(タイプOpenTK.Input.KeyboardDeviceの)Keyboard性を提供します。キーボードイベントは別に処理する必要はありません。これは、すでにベースクラスによって処理されているためです。

/// <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ページからYet another starter kitをダウンロードしてください。私はあなたがYaskをダウンロードし、それがそこに実装されていますどのように確認することをお勧めし

// 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); 
     } 
    } 
} 

:クラスは次のようになります。

+0

それは入力を処理する方法を彼に教えてくれません。それは彼が求めていたものです。 –

+0

@George:答えを更新しました。 – Groo

+0

+1私から。素晴らしい答え。 –

1

一般的にイベントを処理しないゲームループを使用している場合は、入力デバイスを必要に応じてポーリングします(handleAllEvents()メソッド)。いくつかの素早く調査されたところでは、ではOpenTK.Input名前空間、特にKeyboardDeviceクラスでこのようなものが見つかります。

+0

お寄せいただきありがとうございます!何らかの種類の入力を「イベント」として扱うほうが簡単ではありませんか?たとえば、テキスト入力のキー入力を処理するなどです。私は「連続」入力(右に文字を移動するための右矢印を保持するような)のためのポーリングを理解することができますが、イベントのようなモデルがより適切であるような状況があればどうなりますか? – fyhuang

+0

ゲームでより典型的なもの(文字を右に動かす)を処理してポーリングで行う場合は、入力テキストを処理してはい、イベントモデルを使用する方が良いです。 –

関連する問題