2011-01-29 6 views
0

에 대한 자신의 방법을 만들려고 그것은 적절한 방법으로 onKeyDown에를 생성하고 루프를 사용하는 것이 가능하다면 나는 키를 누를 경우 그것은 잘 작동내가이 개 수업을하는 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 클래스에서

, 내 질문은 청취자를 피하십시오. 나는 '돈 다음 줄에 ...

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

을 다음

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

과 같은 MainThread 클래스 내 루프로 전화 : 아이디어는 MainPanel이 같은 방법을 정의하는 것입니다 매개 변수 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); 
     } 
     } 
    } 
    } 

이 루프와 클래스 또한 플레이어에서 들어오는 모든 이벤트를 유지하는 큐를 가지고 "클래스에는 타임 스탬프 멤버가 있습니다 (이벤트 발생시).

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 : 다음 예 (키보드 이벤트) KeyGameEvent 및 (스크린 터치에 대한) TouchGameEvent, ScrollGameEvent, LongPressGameEvent (TouchGameEvent의 서브 클래스 등) 여기서

같은 서브 클래스 일례가되어있다 이와 같은 인스턴스 표준 안드로이드 이벤트 핸들러 메서드에 큐에 배치받을 다음 클래스 :

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

관련 문제