2015-04-23 109 views
1

我正在制作一个游戏,玩家试图在迷宫中导航,但是我遇到了两个让我绝对难倒的bug。我的第一个问题是使用setContentPane()。每当我将它设置为我的预期背景时,它都会覆盖屏幕上的其他所有内容。我试图将它重新安置到我认为可能的每个地方,但它仍然覆盖了它。我的第二个问题是关于我的JButton。每当我点击它时,它会根据预期改变播放速度,但我不能在之后移动。它在我的Keylistener中使用该方法时有效,并且它们内部具有相同的代码。我已经包含了我认为必要的所有代码,但如果您需要更多,请告诉我。该项目的完整源代码可以在Here找到。setContentPane覆盖所有东西,JButton不能正常工作

package game; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 
import java.util.Random; 

public class Game extends JPanel implements ActionListener, KeyListener { 

    private boolean upPressed = false; 
    private boolean downPressed = false; 
    private boolean rightPressed = false; 
    private boolean leftPressed = false; 

    private int tileSize = 200; 
    private int playerSize = tileSize/4; 
    private int playerSpeed = playerSize/10; 
    private int mazeX = 51; 
    private int mazeY = 51; 

    private int[][] maze = new int[mazeX][mazeY]; 
    private int[][] initX = new int[mazeX][mazeY]; 
    private int[][] initY = new int[mazeX][mazeY]; 
    private boolean[][] visited = new boolean[mazeX][mazeY]; 

    private int currentCellX = 0; 
    private int currentCellY = 0; 
    private int deltaX = 0; 
    private int deltaY = 0; 

    JComponent background = new JLabel(new ImageIcon(Main.class.getResource("/assets/ui/mainMenu.png"))); 
    JButton adventure = new JButton(); 
    JButton freePlay = new JButton(); 
    JButton exit = new JButton(); 
    JButton pause = new JButton(); 
    JButton resume = new JButton(); 

    private String screen = "menu"; 
    public Main main; 


    public Game(Main main) { 
     this.main = main; 

     setFocusable(true); 
     addKeyListener(this); 
     addButtons(); 
     setUpInitialCoordinates(); 
     Timer timer = new Timer(1000/120, this); 
     timer.start(); 
    } 


    private void tick() { 
     switch (screen) { 
      case "playing" : 
       background.setVisible(false); 
       if (upPressed) { 
        deltaY += playerSpeed; 
       } else if (downPressed) { 
        deltaY -= playerSpeed; 
       } 
       if (rightPressed) { 
        deltaX -= playerSpeed; 
       } else if (leftPressed) { 
        deltaX += playerSpeed; 
       } 
       break; 
      case "paused": 
       background.setVisible(false); 
       adventure.setVisible(false); 
       freePlay.setVisible(false); 
       pause.setVisible(false); 
       exit.setVisible(true); 
       break; 
      case "menu": 
       main.setContentPane(new JLabel(new ImageIcon(Main.class.getResource("/assets/ui/mainMenu.png")))); 
       adventure.setVisible(true); 
       freePlay.setVisible(true); 
       pause.setVisible(false); 
       exit.setVisible(true); 
       break; 
     } 
     repaint(); 
    } 

    private void addButtons() { 
     setLayout(null); 
     add(freePlay); 
     freePlay.setBounds(10, 100, 180, 80); 
     freePlay.setSize(180, 80); 
     freePlay.setAction(new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       downPressed = false; 
       rightPressed = false; 
       leftPressed = false; 
       generateMaze(); 
       screen = "playing"; 
      } 
     }); 
     freePlay.setIcon(new ImageIcon(Main.class.getResource("/assets/ui/buttons/freePlayUnselected.png"))); 
     freePlay.setRolloverIcon(new ImageIcon(Main.class.getResource("/assets/ui/buttons/freePlaySelected.png"))); 
    } 

    private void setUpInitialCoordinates() { 
    } 


    private void generateMaze() { 
    } 


    private boolean checkForUnvisitedCells() { 
    } 


    private boolean checkForUnvisitedAdjacentCells() { 
    } 


    @Override 
    public void actionPerformed(ActionEvent e) { 
     tick(); 
    } 


    @Override 
    public void keyTyped(KeyEvent e) {} 


    @Override 
    public void keyPressed(KeyEvent e) { 
    } 


    @Override 
    public void keyReleased(KeyEvent e) { 
    } 


    @Override 
    public void paintComponent(Graphics g) { 
    } 
} 
+0

确切地说,你是什么'setContentPane'呢?也许你应该看看[如何使用根窗格](https://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html) – MadProgrammer

+0

*“我的第二个问题是关于我的JButton。每当我点击它,它会根据预期改变到播放速度,但是我不能在之后移动。当我在我的Keylistener中使用该方法时,它就起作用了。“* - 欢迎来到为什么你不应该使用KeyListener的奇妙世界,按钮已盗取键盘焦点并且“KeyListener”将不再响应键盘输入,因为它依赖于它所注册的可聚焦和聚焦的组件。改为使用键绑定。 [如何使用键绑定](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html) – MadProgrammer

+0

@MadProgrammer keyListener是工作的方法,JButton的一半工作,但阻止了我移动。至于'setContentPane()'我的朋友告诉我如何为JFrame设置背景。 – jklsfdgs

回答

1

setContentPane这样做,它取代了以前用作内容的新组件。

RootPane

采取在How to Use Root Panes仔细一看更多的细节。

我建议一个更好的解决办法是使用一个CardLayout,但在这种情况下,一个更好的解决办法是只改变当前的内容窗格icon财产...

background.setIcon(new ImageIcon(Main.class.getResource("/assets/ui/mainMenu.png"))); 

并简单地使background框架的内容窗格中......

JLabel background = new JLabel(new ImageIcon(Main.class.getResource("/assets/ui/mainMenu.png"))); 

//.... 
public Game(Main main) { 
    this.main = main; 
    setContentPane(background); 
    //... 

然后永远不变的内容窗格......

然后,您可以使用CardLayout更改内容窗格上显示的内容

我的第二个问题是关于我的JButton。每当我点击它时,它会根据预期改变播放速度,但我不能在之后移动。它的工作原理,当我用我的KeyListener

欢迎的,为什么你不应该使用KeyListener的精彩世界,按钮偷走了键盘焦点的方法和KeyListener将不再键盘输入作出响应,因为它依赖于它所注册的组件是可以聚焦和聚焦的。改为使用键绑定。 How to Use Key Bindings

+0

如果我对此的假设是正确的,那么我无法在此之后更改背景,对吗? – jklsfdgs

+0

是的,你可以,当你想要的时候,简单地改变'background'' icon'属性(如演示)到任何你想要的东西...... – MadProgrammer

相关问题