KeyListener在窗口中停止工作

时间:2014-01-25 15:10:39

标签: java swing keylistener

周末我试图创建一个Pong的克隆。第一次关键听取工作,但没有。

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.util.Random;

import javax.swing.JFrame;

public final class PingPong extends Canvas implements KeyListener {
    private static final long serialVersionUID = 381061428448529952L;

    public static final long FPS_LIMIT = 500;

    public static final int BALL_SIZE = 10;
    public static final int BALL_SPEED = 3;

    public static final int BAT_LENGTH = 64;
    public static final int BAT_WIDTH = 16;
    public static final int BAT_POSITION_SHIFT_X = 16;
    public static final int BAT_SPEED = 2;

    private long fps_;

    public void run() {
        long last = System.currentTimeMillis();
        long now;
        long delta = 0;

        this.resetGame_();
        while(true) {
            now = System.currentTimeMillis();
            delta = now - last;

            if(delta >= 1000 / FPS_LIMIT) {
                this.process_();
                this.draw_();

                this.fps_ = 1000 / delta;

                last = now;
            }
        }
    }

    enum EDirection { LEFT, RIGHT }

    int ballPosX;
    int ballPosY;
    EDirection ballDirection;
    float ballRoll = 0;

    int firstBatPosY;
    int leftScore = 0;

    int secondBatPosY;
    int rightScore = 0;

    private void process_() {
        if(ballDirection == null) {
            Random rnd = new Random();
            ballDirection = rnd.nextBoolean() == true ? EDirection.LEFT : EDirection.RIGHT;
        }

        /*
         * Bats
         */
        if(this.keyW)
            firstBatPosY -= BAT_SPEED;
        else if(this.keyS)
            firstBatPosY += BAT_SPEED;

        if(this.keyUp)
            secondBatPosY -= BAT_SPEED;
        else if(this.keyDown)
            secondBatPosY += BAT_SPEED;

        if(firstBatPosY < 0)
            firstBatPosY = 0;

        if(secondBatPosY < 0)
            secondBatPosY = 0;


        /*
         * Ball
         */
        switch(ballDirection) {
        case LEFT:
            ballPosX -= BALL_SPEED;
            break;
        case RIGHT:
            ballPosX += BALL_SPEED;
            break;
        }
        ballPosY += ballRoll;

        if(ballPosX <= 0) {
            ballDirection = EDirection.RIGHT;
        } else {
            switch(ballDirection) {
            case LEFT:
                if(ballPosX <= BAT_POSITION_SHIFT_X + BAT_WIDTH) {
                    if((ballPosY >= firstBatPosY && ballPosY <= firstBatPosY + BAT_LENGTH)
                       || (ballPosY + BALL_SIZE >= firstBatPosY && ballPosY + BALL_SIZE <= firstBatPosY + BAT_LENGTH)) {
                        ballDirection = EDirection.RIGHT;
                        break;
                    } else {
                        if(ballPosX <= 0) {
                            rightScore++;
                            this.resetGame_();
                        }
                    }
                }
                break;
            case RIGHT:
                if(ballPosX >= super.getWidth() - BAT_POSITION_SHIFT_X - BAT_WIDTH) {
                    if((ballPosY >= secondBatPosY && ballPosY <= secondBatPosY + BAT_LENGTH)
                       || (ballPosY + BALL_SIZE >= secondBatPosY && ballPosY + BALL_SIZE <= secondBatPosY + BAT_LENGTH)) {
                        ballDirection = EDirection.LEFT;
                        break;
                    } else {
                        if(ballPosX >= super.getWidth()) {
                            leftScore++;
                            this.resetGame_();
                        }
                    }
                }
                break;
            }
        }
    }

    private void draw_() {
        BufferStrategy bs = super.getBufferStrategy();

        if(bs == null) {
            super.createBufferStrategy(2);
            super.requestFocus();
            return;
        }

        Graphics gfx = bs.getDrawGraphics();

        gfx.setColor(Color.BLACK);
        gfx.fillRect(0, 0, super.getWidth(), super.getHeight());

        gfx.setColor(Color.GRAY);
        gfx.fillRect(super.getWidth() / 2 - 5, 10, 10, super.getHeight() - 20);

        gfx.setColor(Color.WHITE);
        gfx.fillRect(ballPosX, ballPosY, BALL_SIZE, BALL_SIZE);
        gfx.fillRect(BAT_POSITION_SHIFT_X, firstBatPosY, BAT_WIDTH, BAT_LENGTH);
        gfx.fillRect(super.getWidth() - BAT_POSITION_SHIFT_X - BAT_WIDTH, secondBatPosY, BAT_WIDTH, BAT_LENGTH);

        gfx.setColor(Color.WHITE);
        gfx.drawString(String.valueOf(this.fps_), 10, 20);
        gfx.drawString(String.valueOf(leftScore), super.getWidth() / 2 / 2, 64);
        gfx.drawString(String.valueOf(rightScore), super.getWidth() - (super.getWidth() / 2 / 2), 64);

        gfx.dispose();
        bs.show();
    }

    private void resetGame_() {
        ballPosX = super.getWidth() / 2 - BALL_SIZE / 2;
        ballPosY = super.getHeight() / 2 - BALL_SIZE / 2;
        ballDirection = null;
        ballRoll = 0;

        firstBatPosY = super.getHeight() / 2 - BAT_LENGTH /  2;

        secondBatPosY = super.getHeight() / 2 - BAT_LENGTH /  2;
    }

    boolean keyW, keyS, keyUp, keyDown;

    @Override
    public void keyPressed(KeyEvent _key) {
        switch(_key.getKeyCode()) {
        case KeyEvent.VK_W:    keyW = true; break;
        case KeyEvent.VK_S:    keyS = true; break;
        case KeyEvent.VK_UP:   keyUp = true; break;
        case KeyEvent.VK_DOWN: keyDown = true; break;
        }
    }

    @Override
    public void keyReleased(KeyEvent _key) {
        switch(_key.getKeyCode()) {
        case KeyEvent.VK_W:    keyW = false; break;
        case KeyEvent.VK_S:    keyS = false; break;
        case KeyEvent.VK_UP:   keyUp = false; break;
        case KeyEvent.VK_DOWN: keyDown = false; break;
        }
    }

    @Override
    public void keyTyped(KeyEvent _key) {

    }

    public static void main(String[] args) {
        PingPong game = new PingPong();

        JFrame frame = new JFrame("DrMGC's Ping-Pong");
        frame.setSize(1024, 512);
        frame.setLayout(new BorderLayout());
        frame.setFocusable(true);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addKeyListener(game);
        frame.add(game, BorderLayout.CENTER);

        frame.setVisible(true);
        game.run();
    }

}

即使方法keyPressed()不是按帧键调用也不起作用,即问题不在键的代码中。

1 个答案:

答案 0 :(得分:0)

商定: 代替

frame.addKeyListner(game);

game.addKeyListner(game);

或方法run()

super.addKeyListener(this);