1

これが私の問題です。KB イベントを処理しようとしても、プログラムは何もしません。一部の人々は、忙しく待機しているために発生していると信じています (新しいスレッドがメインスレッドと競合している)。どうすれば修正できますか?

public class GameCanvas extends Canvas {
    int myX = 250;
    int myY = 0;
    int speedValue = 15;
    int bottom = 480;

    GameCanvas() {
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent event) {
                switch (event.getKeyCode()) {
                    case KeyEvent.VK_LEFT:
                        if (myX > 5) myX -= 5;
                        break;
                    case KeyEvent.VK_RIGHT:
                        if (myX < 480) myX += 5;
                        break;
                }
                repaint();
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    setGameSpeed(speedValue);
                    if (myY < bottom) {
                        myY += 5;
                    } else {
                        bottom -= 20;
                        myY = 0;
                    }
                    repaint();
                }
            }
        }).start();
    }

    public void setGameSpeed(int value) {
        try {
            sleep(value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void paint(Graphics g) {
        g.setColor(Color.darkGray);
        g.fillRect(myX, myY - 5, 25, 25);
        buildGameBottom(g);
    }

    void buildGameBottom(Graphics g){
        g.setColor(Color.WHITE);
        g.fillRect(0, bottom + 20, 500, bottom + 20);
    }

    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame();
        GameCanvas gameCanvas = new GameCanvas();
        gameCanvas.setSize(new Dimension(500, 500));
        gameCanvas.setBackground(Color.LIGHT_GRAY);
        gameCanvas.requestFocus();
        frame.add(gameCanvas);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
    }
}
4

1 に答える 1

2

ここでの問題は、忙しく待っていることではありません (ここで忙しく待っているわけではありません)。

唯一の問題は、KeyListenerが に接続されているCanvasが、Frameに入力フォーカスがあることです。をクリックしてみてくださいCanvas

また、再描画ループを使用している場合は、 で再描画を呼び出す必要はありませんKeyListener

SwingUtilities.invokeLaterまた、異なるスレッドからの Swing/AWT 関数の呼び出しにもご利用ください。

フレームを表示に設定した後に呼び出しを移動するrequestFocusと、問題が解決するはずです (まだ表示されていないものにフォーカスを与えることはできないため)。

于 2013-10-08T09:22:02.330 に答える