我正在为我的学习制作游戏'Breakout'的重新制作版本,并面临一个奇怪的问题:
我有一个简单的开始屏幕,玩家应该可以输入名称并查看当前的高分等。要开始游戏,我使用CardLayout,它应切换到gamePanel
。不知怎的,这不会发生,但游戏循环开始了,当球离开JPanel时,我得到游戏结束消息。奇怪的是,gamePanel
与游戏Over JOptionPane一起出现,切换回开始屏幕正常工作。我在StackOverflow上也搜索了很多,但我发现的解决方案都没有对我有用。这是我的代码:
这是我的Game.java,主要方法位于:
public class Game extends JFrame {
private static final int width = 1280;
private static final int height = 720;
private static final String LOBBY_PANEL = "Lobby Panel";
private static final String GAME_PANEL = "Game Panel";
private boolean run = false;
private CardLayout cardLayout;
private JPanel cardPanel = new JPanel();
private LobbyPanel lobbyPanel;
private GamePanel gamePanel;
public Game(){
super("Breakout Remastered");
cardPanel.setLayout(new CardLayout());
cardLayout = (CardLayout) cardPanel.getLayout();
lobbyPanel = new LobbyPanel(this);
gamePanel = new GamePanel(this);
cardPanel.add(lobbyPanel, LOBBY_PANEL);
cardPanel.add(gamePanel, GAME_PANEL);
this.add(cardPanel);
this.pack();
this.setSize(width, height);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
cardLayout.show(cardPanel, LOBBY_PANEL);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Game gameFrame = new Game();
gameFrame.setVisible(true);
});
}
public void playGame() {
cardLayout.show(cardPanel, GAME_PANEL);
this.validate();
this.repaint();
this.run = true;
while (run) {
gamePanel.move();
gamePanel.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException iEx) {
iEx.printStackTrace();
}
}
}
public void stopGame() {
cardLayout.show(cardPanel, LOBBY_PANEL);
this.run = false;
}
}
这是我的GamePanel.java:
public class GamePanel extends JPanel {
private Game game;
private Ball ball = new Ball(this);
private Racquet racquet = new Racquet(this);
public GamePanel(Game game) {
this.game = game;
KeyListener keyListener = new KeyListener() {
@Override
public void keyTyped(KeyEvent keyEvent) {
}
@Override
public void keyPressed(KeyEvent keyEvent) {
racquet.keyPressed(keyEvent);
}
@Override
public void keyReleased(KeyEvent keyEvent) {
racquet.keyReleased(keyEvent);
}
};
addKeyListener(keyListener);
setFocusable(true);
}
public void move() {
ball.move();
racquet.move();
}
public void reset() {
}
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
Graphics2D g2d = (Graphics2D) graphics;
g2d.setColor(Color.BLACK);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
racquet.paint(g2d);
}
public void gameOver() {
JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.YES_NO_OPTION);
game.stopGame();
}
public Racquet getRacquet() {
return racquet;
}
public void setRacquet(Racquet racquet) {
this.racquet = racquet;
}
}
这是我的LobbyPanel.java:
public class LobbyPanel extends JPanel implements ActionListener {
private static final JLabel labelForUserTextField = new JLabel("Username");
private JTextField userName = new JTextField("", 20);
private JButton startButton = new JButton("Play!");
private JButton highScoreButton = new JButton("View Best");
private JButton cancelButton = new JButton("Cancel");
private Game game;
public LobbyPanel(Game game) {
startButton.addActionListener(this);
this.game = game;
this.setLayout(new GridBagLayout());
this.setBorder(new EmptyBorder(10, 10, 10, 10));
GridBagConstraints labelConst = new GridBagConstraints();
labelConst.insets = new Insets(3, 3, 3, 3);
labelConst.gridx = 0;
labelConst.gridy = 0;
this.add(labelForUserTextField, labelConst);
labelConst.gridx = 1;
this.add(userName, labelConst);
labelConst.gridx = 0;
labelConst.gridy = 1;
this.add(cancelButton, labelConst);
labelConst.gridx = 1;
this.add(highScoreButton, labelConst);
labelConst.gridx = 2;
this.add(startButton, labelConst);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
try {
if(actionEvent.getSource() == this.startButton) {
this.game.playGame();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
我希望有人能够弄清楚为什么这段代码不能按预期工作。 提前谢谢!