0

我制作了一个 pacman 游戏,我想将 aJFrame作为引导加载显示到游戏本身。所以我做了一个类 launcher.java extendsJFrame包含一个单一JPanel的来呈现游戏的图像。

在另一个名为 Game.java 的类中,它还扩展JFrame了 Iv'e 设置一个计时器并使用setVisible(false).

激活游戏时,启动器显示三秒钟,然后触发计时器并运行游戏,尽管按键监听器没有响应。

请帮我理解为什么。

启动器类

package PacMan;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Launcher extends JFrame {

    private static final long serialVersionUID = -7949539876450449197L;

    private JPanel launchImage;

    public Launcher() {

        launchImage = new JPanel();
        launchImage.add(new JLabel(new ImageIcon("main.png")));
        launchImage.setVisible(true);
        setUndecorated(true);
        setSize(560,620);
        setLocationRelativeTo(null);
        getContentPane().add(launchImage);
        setVisible(true);

    }
}

package PacMan;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

class Game extends JFrame implements MouseListener, KeyListener, ActionListener{

    private static final long serialVersionUID = -7132848196338970451L;

    int posX=0,posY=0;

    private Controller upper;
    private JLabel[] lives;
    public static Timer timer;
    private int livesCounter, lifeIndex;
    private JPanel livesPanel;
    private double secondsSaver;
    private Launcher launcher;


    public Game() {

        timer = new Timer(50,this);

        JPanel gamePanel = new JPanel();
        gamePanel.setLayout(new BorderLayout());

        setUndecorated(true);

        setSize(560,620);
        setLocationRelativeTo(null);


        this.upper = new Controller();
        this.addKeyListener(upper);
        upper.setBorder(BorderFactory.createEmptyBorder(-5, -5, -5, -5));
        upper.setBounds(-5, -5, -5, -5);


        JPanel lower = new JPanel();
        lower.setBackground(Color.BLACK);
        lower.setLayout(new GridLayout(1,4));
        lower.setSize(560, 100);

        JLabel livesLabel = new JLabel(new ImageIcon("lives.png"));
        livesLabel.setHorizontalTextPosition(new Integer(0));
        lower.add(livesLabel);

        livesPanel = new JPanel();
        livesPanel.setLayout(new GridLayout(1,3));
        lives = new JLabel[3];
        for(int i=0; i<3; i++){
            lives[i] = new JLabel(new ImageIcon("life.png"));
            livesPanel.add(lives[i]);
        }
        livesPanel.setOpaque(false);
        lower.add(livesPanel);
        lifeIndex = 2;
        livesCounter=3;


        JButton restart = new JButton(new ImageIcon("Restart.png"));
        restart.setBackground(Color.black);
        restart.setBorderPainted(false);
        lower.add(restart);
        restart.addActionListener(new ActionListener() { // action for the quit button
            public void actionPerformed(ActionEvent arg0) {
                getContentPane().remove(upper);
                upper = new Controller();
            }
        });

        JButton quit = new JButton(new ImageIcon("quit.png"));
        quit.setBackground(Color.black);
        quit.setBorderPainted(false);
        lower.add(quit);
        quit.addActionListener(new ActionListener() { // action for the quit button
            public void actionPerformed(ActionEvent arg0) {
                System.exit(0);         
            }
        });


        upper.getComponentListeners();


        gamePanel.add(upper, BorderLayout.NORTH);
        gamePanel.add(lower, BorderLayout.SOUTH);

        getContentPane().add(gamePanel);
        pack();

        this.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                posX=e.getX();
                posY=e.getY();
            }
        });

        this.addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent evt) {
                //sets frame position when mouse dragged            
                setLocation (evt.getXOnScreen()-posX,evt.getYOnScreen()-posY);          
            }
        });

        timer.start();

        launcher = new Launcher();
    }



    public Controller getController(){
        return upper;
    }

    public static void main(String args[]) {
        new Game();
    }


    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub  
    }
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
    }
    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub  
    }
    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub  
    }
    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
    }


    @Override
    public void keyPressed(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }


    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }


    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        if (secondsSaver==3) {
            this.setVisible(true);
            launcher.setVisible(false);
        }
        if ((livesCounter>upper.getLives()) && (secondsSaver>=3)) {
            lives[lifeIndex].setVisible(false);
            lifeIndex--;
        }
        this.livesCounter=upper.getLives();
        secondsSaver+=0.05;
    }

}
4

1 回答 1

2

我建议不要使用 KeyListener。它有一个特殊的问题,它注册到的组件不仅必须是可聚焦的,而且在触发关键事件之前必须具有焦点。

相反,我建议使用Key Bindings API

我还建议您在关闭启动屏幕时requetsFocusInWindow在游戏框架中调用actionListener

于 2013-06-15T21:13:19.133 回答