我有两个类(class):
MainPanel(我在其中定义一些方法) MainThread(我使用这些方法进行循环以创建经典的游戏结构)
在 MainPanel 类中,我有此方法来捕获是否按下了某个键
@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;
}
它工作正常,我的问题是是否可以创建 onKeyDown 作为正确的方法并在循环中使用它来避免监听器。这个想法是在 MainPanel 中定义这样的方法:
public void myOwnOnKeyDown(int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
Log.i(TAG,"key up was pressed");
}
}
然后,将其调用到 MainThread 类上的循环中,如下所示...
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);
}
}
在下面一行我不知道如何传递参数keyCode...
this.MainPanel.MyOwnOnKeyDown(keyCode, event);
这可能吗?
提前致谢
最佳答案
看起来您正在尝试编写游戏或其他类似类型的程序。
在你的主循环中,当你尝试调用你自己的 keydown 方法时,你应该调用像“handleInput()”这样的方法,然后你的真正的 Android keydown 方法的实现应该添加事件信息(keycode等)到队列集合。然后,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.
}
}
显然(我希望)在 handeInput() 调用的 processKeyGameEvent() 等方法中,您实际上检查按下/释放了哪些键,并让游戏逻辑执行适合此类按键的操作/释放。
如果您的游戏只对键盘输入事件(而不是触摸等)感兴趣,那么您可以放弃创建 GameEvent 类层次结构,而只需将 onKeyDown() 接收到的 KeyEvent 放入队列中。
关于java - 尝试为 onKeyDown 事件创建自己的方法(Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4838350/