2014-12-23 37 views
2

我正在用Java中的Swing編寫一個小型以太空爲主題的地下城爬蟲遊戲。我正在使用MVC編程範例。遊戲被表示爲一個網格,在該網格上點擊按鈕可將玩家移動到棋盤上或攻擊敵人。Java Swing:將遊戲板繪製爲由二維數組對象支持的JButton網格

在模型/遊戲的邏輯我生成使用2D陣列由隨機分配對象到x(柱)和y(行)的遊戲環境的抽象表示使用以下方法座標:

//methods 
public void setGalaxy() { 
    galaxyArray = new GalacticObject[this.row][this.col]; 

    //construct the array 
    Random rand = new Random(); 
    int random; 
    for (int i = 0; i < this.row; i++) { 
     for (int j = 0; j < this.col; j++) { 
      GalacticObject obj = new GalacticObject(i,j); 
      random = rand.nextInt(100); 
      if (random < 5) { 
       //asteroid (5 percent chance) 
       obj.makeAsteroid(); 
      } else if (random < 9) { 
       //blackhole (4 percent chance) 
       obj.makeBlackHole(); 
      } else { 
       //rest is open (= empty) 
       obj.makeOpen(); 
      } 
      galaxyArray[i][j] = obj; 
     } 
    } 
} 

現在我想用一個JButton網格在JPanel容器中繪製由這個二維對象數組支持的實際GUI遊戲板。我想基本上調用galaxyArray中的所有對象,並在ButtonGrid中相應的座標處繪製一個帶有相應圖像疊加的JButton。使用Swing實現這個最好的方法是什麼?

目前,我還爲繪製JButtonGrid的方法編寫了以下草稿,但我仍然無法看到以2D對象陣列作爲後盾的最佳策略。 此外,添加按鈕的圖標不起作用,原因不明。 (我評論的那部分。)

public JPanel makeGameBoard() { 
    /** This method makes a first version of the game board when the object is first called */ 
    //create a new JPanel 
    JPanel boardPanel = new JPanel(); 

    // create a gridButton of JButtons defined by the width and length 
    JButton[][] gridButton = new JButton[this.boardWidth][this.boardLength]; 

    // set layout 
    boardPanel.setLayout(new GridLayout(this.boardWidth,this.boardLength)); 

    //for-loops to place buttons in gridButton 
    for(int y = 0; y < this.boardLength; y++) { 
     for(int x = 0; x < this.boardWidth; x++){ 
      // creates new button (with coordinates as string); gridButton[x][y] needs to be reused as coordinate system 
      gridButton[x][y]=new JButton(x+":"+y); 
      gridButton[x][y].setActionCommand(x+":"+y); 
      gridButton[x][y].setText(""); 
      gridButton[x][y].addActionListener(new ActionListener(){ 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        String com = e.getActionCommand(); 
        System.out.println(com);   
       } 
      }); 
       // add icon to every button 
//    try { 
//     Image img = ImageIO.read(getClass().getResource("resources/invisible.png")); 
//     gridButton[x][y].setIcon(new ImageIcon(img)); 
//    } 
//     catch (IOException ex) { 
//     System.out.println("Image file for gridButton not found!"); 
//     } 
       // add the gridButton to the panel 
       boardPanel.add(gridButton[x][y]); 
      } 
     } 
     //return boardPanel 
     return boardPanel; 
    } 

基本上我想知道什麼是從我的makeGameBoard方法訪問存儲在galaxyArray的對象,最好的策略,以使數組中的對象的變量可以用來在網格中用相應座標在按鈕上繪製圖像。

/*編輯感謝以下友好的人的建議和鏈接教程,我已經做到了!下面是主板信息查看有任何類似的問題代碼:

public void updateGameBoard(Galaxy board) { 
/** This method initializes the board when the galaxy is first created in the game logic and updates it throughout the game */ 
    Galaxy galaxyArray = board; 
    for (int r = 0; r < this.boardWidth; r++) { 
     for (int c = 0; c < this.boardLength; c++) { 
      //make galactic object and extract info from Galaxy 
      GalacticObject temporary = new GalacticObject(r,c); 
      temporary = galaxyArray.getGalacticObject(r,c); 

      //check the object and set the corresponding tile image 
      if (temporary.isAsteroid()) { 
       gridButton[r][c].setText("A"); 
      } else if (temporary.isAsteroidField()) { 
       gridButton[r][c].setText("AF"); 
      } else if (temporary.isBlackHole()) { 
       gridButton[r][c].setText("BH"); 
      } else if (temporary.isOpen()) { 
       gridButton[r][c].setText(""); 
      } 
     } 
    } 
} 
+2

贊[this](http://stackoverflow.com/a/7706684/230513)? – trashgod

+0

在這個例子中,板子沒有更高層次的代表作爲獨立於視圖的2D對象陣列。我實際上要求的是如何從我的makeBoard方法中最好地訪問存儲在galaxyArray中的對象,以便可以使用數組中的對象的變量在網格中使用相應的座標在按鈕上繪製圖像。 – GJacobs

+1

[製作健壯,可調整大小的Swing Chess GUI](http://stackoverflow.com/q/21142686/418556)中的代碼存儲了一組按鈕。 –

回答

3

的具體細節取決於你如何實現observer pattern。在outline之後,示例game引用here只是讓主視圖RCView保留對由遊戲模型RCModel維護的名爲board的陣列的私人引用。因爲RCView實現了Observer接口,所以視圖的update()實現只是遍歷board並更新其響應的tiles的數組。請注意,update()方法簽名包含對請求更新的Observable的引用。在你的例子中,

public void update(Observable model, Object arg) { 
    GalacticObject galaxyArray = ((GameModel) model).getGalaxyArray(); 
    //loop though model, updating view components 
    this.repaint(); 
} 
+0

這是我最終採取的方法,謝謝! – GJacobs