2011-01-29 13 views
0

ための独自のメソッドを作成しようとしている私は2つのクラスがあります(私はいくつかのメソッドを定義する)にonKeyDownイベント(アンドロイド)

MainPanel(私は古典的なゲームの構造を作成するために、これらの方法でループを行う) MainThreadをそれは適切な方法としてonKeyDownメソッドを作成して、ループ内でそれを使用することが可能です場合、私はキーが押された場合には、右の作品

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
     switch(keyCode) { 
       case KeyEvent.KEYCODE_DPAD_UP: 
         Log.i(TAG,"key up was pressed"); 
         return true; 
     } 
     return false; 
} 

キャプチャするには、このメソッドを持っているMainPanelクラスで

は、私の質問はリスナーを避けるために。アイデアはMainPanelで、このような方法で定義することである。

public void myOwnOnKeyDown(int keyCode, KeyEvent event) { 
    switch(keyCode) { 
      case KeyEvent.KEYCODE_DPAD_UP: 
        Log.i(TAG,"key up was pressed"); 
    } 
} 

をそして、「私はドン次の行で

public class MainThread extends Thread { 
//... 

public void loop() { 
    Canvas canvas; 
    KeyEvent event; Log.d(TAG, "Starting game loop"); 

    while (running) { 

     this.MainPanel.MyOwnOnKeyDown(keyCode, event); 
     this.MainPanel.moveElements(); 
     this.MailPanel.drawElements(canvas); 
    } 
} 

...このようMainThreadクラスに私のループにそれを呼び出しますパラメータkeyCodeを渡す方法を知っています...

this.MainPanel.MyOwnOnKeyDown(keyCode, event); 

これは可能でしょうか?あなたがゲームやプログラムのいくつかの他の同様のタイプをオーサリングしようとしているよう

+0

私は本当にあなたの設計方法論に疑問を抱いています。私はあなたが解決しようとしている問題があれば、より洗練された解決策があるという事実に賭けるでしょう。 – user432209

答えて

3

が見える事前に

感謝。

独自のkeydownメソッドを呼び出そうとしているメインループでは、代わりに "handleInput()"のようなメソッドを呼び出してから、実際のAndroid keydownメソッドの実装でイベント情報を追加する必要がありますキーコードなど)をキューコレクションに追加します。 handleInput()メソッドは、ループの最後の時間以降に発生した(キューにある)すべてのキー押下を処理します。ここで

は、ゲームの例メイン・ループです:

private ConcurrentLinkedQueue<GameEvent> eventQueue = new ConcurrentLinkedQueue<GameEvent>(); 

「GameEvent:

public void run() { 

    initializeState(); 

    while (stillRunning) { // stillRunning is a flag that signals the user wants to exit 

     while(isPaused() && stillRunning) { // isPaused is a flag that is set in the if the user selects pause 
     try { 
      sleep(100); 
     } catch (InterruptedException e) { 
     } 
     } 
     if(!stillRunning) 
     break; 

     Canvas c = null; 
     try { 
     c = surfaceHolder.lockCanvas(null); // the game uses a Surface view for drawing 
     synchronized (surfaceHolder) { 
      updateState(); // update game entities - such as remove explosions that are finished, etc. 
      handleInput(); // handle user input (key presses, screen touches, etc.) 
      updatePhysics(); // collision detection, speed changes due to gravity, etc. 
      updateAnimations(); // update which frames need to draw for animating entities 
      updateSound(); // start/stop any sounds required by new game state/events 
      updateVideo(c); // draw the next frame of video 
     } 
     } finally { 
     // do this in a finally so that if an exception is thrown 
     // during the above, we don't leave the Surface in an 
     // inconsistent state 
     if (c != null) { 
      surfaceHolder.unlockCanvasAndPost(c); 
     } 
     } 
    } 
    } 

このループを持つクラスもプレイヤーから入ってくるすべてのイベントを保持するためのキューを持っています"クラスにはタイムスタンプメンバーがいます(イベントが発生したとき)。次いで、(キーボードイベント用)KeyGameEventとTouchGameEvent(画面タッチ用)、ScrollGameEvent、LongPressGameEvent(TouchGameEventのサブクラス)など

としてサブクラスここある例である。

public class KeyGameEvent extends GameEvent { 

    public int keyCode; 
    public KeyEvent keyEvt; 
    public boolean up; 

    public KeyGameEvent(int keyCode, boolean keyUp, KeyEvent evt) { 
    this.keyCode = keyCode; 
    this.up = keyUp; 
    this.keyEvt = evt; 
    } 

} 

これらGameEventこのようなインスタンス化され、標準のAndroidイベントハンドラメソッドでキューに置かれます、その後クラス:

public boolean onKeyDown(int keyCode, KeyEvent event) { 
    KeyGameEvent kge = new KeyGameEvent(keyCode, false, evt); 
    eventQueue.add(kge); 
    return true; 
    } 

    public boolean onKeyUp(int keyCode, KeyEvent event) { 
    KeyGameEvent kge = new KeyGameEvent(keyCode, true, evt); 
    eventQueue.add(kge); 
    return true; 
    } 

    public void onLongPress(MotionEvent evt) { 
    LongPressGestureGameEvent lpe = new LongPressGestureGameEvent(evt); 
    eventQueue.add(lpe); 
    } 

最後に、handleInput()メソッドは次のようになります。

private void handleInput() { 

    while(true) { 
     GameEvent evt = eventQueue.poll(); 
     if(evt == null) 
     break; 

     if(evt instanceof KeyGameEvent) { 
     processKeyGameEvent((KeyGameEvent)evt); 
     } 
     else if(evt instanceof TouchGameEvent) { 
     processTouchGameEvent((TouchGameEvent)evt); 
     } 
     // ... etc. for the different types of events. 
    } 
    } 

handeInput()によって呼び出されるprocessKeyGameEvent()などのメソッド内では、明らかにどのキーが押されたか/解放されたかを調べて、ゲームロジックでそのような主要なプレスリリース。

あなたのゲームがキーボード入力イベント(タッチなどではない)だけに興味があるならば、GameEventクラス階層を作成するのを忘れて、onKeyDown()で受け取ったKeyEventをキューに入れるだけです。

+0

応答に感謝、私もこれを試してみましょう! – karse23

+0

これの例を挙げていただけますか? – karse23

+0

確かに、あなたがそれに従うことができる十分なコードを含めるようにしましょうが、それはあまりにも大きくはないほど少しです... – jhouse

1

私はあなたがしたいと思うのは、キーがアクティブで、あなたのメインループを参照する変数を設定することです。

例えば

// some constants 
static int NONE = 0; 
static int UP = 1; 
static int DOWN = 2; 
static int LEFT = 3; 
static int RIGHT = 4; 
// state fields 
private volatile int movement = NONE; 
private volatile boolean jumping = false; 

次に、あなたのonKeyDownメソッドは、のようになります:MainPanelでは、次のようないくつかのクラスのフィールドを持っている

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
     switch(keyCode) { 
       case KeyEvent.KEYCODE_DPAD_UP: 
         Log.i(TAG,"key up was pressed"); 
         movement = UP; 
         return true; 
     } 
     return false; 
} 

メソッドとonKeyUpはのようになります。

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
     switch(keyCode) { 
       case KeyEvent.KEYCODE_DPAD_UP: 
         Log.i(TAG,"key up was pressed"); 
         movement = NONE; 
         return true; 
     } 
     return false; 
} 

メインループは次のようになります。

while (running) { 
    if (this.movement == UP) { 
     // update stuff 
    } else if (this.movement == DOWN) { 
     // update other stuff 
    } // etc ... 
    this.MainPanel.moveElements(); 
    this.MailPanel.drawElements(canvas); 
} 

キープレスをトラッキングするためにはもっと洗練されたロジックが必要になるでしょうが、これはボタンイベントを更新から隔てるので、連続した動きが可能です。

+0

私が探していたようです。どうもありがとうございました! =) – karse23

関連する問題