Похоже, вы пытаетесь создать игру или программу подобного типа.
В вашем основном цикле, где вы пытаетесь вызвать свой собственный метод keydown, вам следует вместо этого вызвать методкак "handleInput ()", и тогда ваша реализация реального метода Android keydown должна добавить информацию о событии (код ключа и т. д.) в коллекцию очередей.Затем метод handleInput () будет обрабатывать все нажатия клавиш, которые произошли (находятся в очереди) с момента последнего цикла в цикле.
Вот пример основного цикла игры:
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);
}
}
}
}
Класс с этим циклом также имеет очередь для хранения всех событий, поступающих от игрока:
private ConcurrentLinkedQueue<GameEvent> eventQueue = new ConcurrentLinkedQueue<GameEvent>();
Класс "GameEvent" имеет отметку времени (для случая, когда событие произошло).Затем имеются подклассы, такие как 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.
}
}
Очевидно (я надеюсь) в методах, таких как processKeyGameEvent (), которые вызываются функцией handeInput (), вы фактически проверяете, какие клавиши были нажаты / отпущены, и позволяете ли игровой логике делать то, что подходит для такой клавишинажмите / отпустите.
Если ваша игра заинтересована только событиями ввода с клавиатуры (не касанием и т. д.), то вы можете отказаться от создания иерархии классов GameEvent и просто поместить KeyEvent, полученный onKeyDown (), в очередь.