java程序中的游戏循环是否总是在事件派发线程中运行? 因为我的keylisteners在AWT事件线程中运行,我希望在与游戏其余部分相同的线程中处理关键事件,以避免基于线程的错误。 如果我不在事件线程中运行游戏循环,我可以使用ArrayBlockingQueue将事件从事件处理程序发送到游戏循环吗?有更好的解决方案吗? 感谢
也许是这样的?
ConcurrentLinkedQueue<AWTEvent> eventQueue = new ConcurrentLinkedQueue<AWTEvent>();
JFrame frame = new JFrame() {
@override
protected void processEvent(AWTEvent e) {
if(e instanceof InputEvent) eventQueue.add(e);
else super.processEvent(e);
}
}
//game loop
while(true) {
while(!eventQueue.isEmpty()) frame.super.processEvent(eventQueue.poll());
...
}
编辑:谢谢,我想我现在知道怎么做了。我会这样做的
import java.util.concurrent.ConcurrentLinkedQueue;
import java.awt.AWTEvent;
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;
public class QueueTest {
static ConcurrentLinkedQueue<AWTEvent> eventQueue = new ConcurrentLinkedQueue<AWTEvent>();
public static void main(String[] args) {
final JPanel panel = new JPanel() {
@Override
protected void processEvent(AWTEvent e) {
eventQueue.add(e);
}
{
enableEvents( AWTEvent.MOUSE_EVENT_MASK
| AWTEvent.MOUSE_MOTION_EVENT_MASK
| AWTEvent.KEY_EVENT_MASK);
}
};
final JFrame frame = new JFrame();
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
panel.requestFocusInWindow();
}
});
frame.add(panel);
panel.setPreferredSize(new Dimension(800,600));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
while(true) {
while(!eventQueue.isEmpty()) System.out.println(eventQueue.poll()+"\n");
}
}
}
答案 0 :(得分:1)
我不是游戏程序员所以你的问题引发了一些研究:)你无法在事件调度线程中运行游戏循环,因为它处于自己的服务用户输入的循环中。您的应用程序基本上会冻结,不会响应任何进一步的输入事件。您的游戏循环应该是一个单独的线程,其中包含游戏事件的线程安全队列 - 队列应该是非阻塞的,因为即使没有用户输入,您也希望游戏循环继续。由于输入而需要进行的任何渲染可能必须放回到事件队列中 - swing为此提供SwingUtilities,但不确定您所处的环境。
我现在可能会被经验丰富的游戏开发者抨击。
答案 1 :(得分:1)
我在我写的游戏引擎中遇到了类似的问题。
最后,我必须为我的游戏引擎循环设置一个单独的线程。当AWT事件被触发时,我必须存储它们,并在游戏循环中的下一次逻辑更新期间触发它们。
这是我的解决方案,然而,我相信事件的“最简单”事实是实际轮询它们!:)