2015-04-23 42 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

相關問題