繁体   English   中英

Java Swing:将游戏板绘制为由2D对象数组支持的JButton网格

[英]Java Swing: Draw a gameboard as a JButton grid backed by a 2D array of objects

我正在用Java的Swing制作的GUI编写一个小型的太空主题地牢爬虫游戏。 我正在使用MVC编程范例。 游戏被表示为一个网格,在该网格上可以单击按钮以将玩家移到棋盘上或攻击敌人。

在游戏的模型/逻辑中,我使用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;
        }
    }
}

现在,我想使用JButtons网格在JPanel容器中绘制由该2D对象数组支持的实际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存储的对象的最佳策略是什么,以便可以使用数组中对象的变量在按钮上在网格中绘制具有对应坐标的图像。

/ * EDIT感谢以下友善人士的建议和链接的教程,我使它成功了! 以下是有类似问题的任何人的Board View代码:

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("");
            }
        }
    }   
}

确切的细节取决于您如何实现观察者模式 按照此轮廓此处引用的示例游戏仅使主视图RCView保留对名为board的数组的私有引用,该数组由游戏模型RCModel 因为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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM