3

Linked: Using MouseListener to select a range of cells in a grid

I am creating a Battleships game, with two grids. The user will place their ships on one grid and then bomb the other grid.

I have an abstract class called Grid which creates a 10x10 grid of cells (which extend JPanel class). It gives each cell a listener, like so:

public Grid() {
    setPreferredSize(new Dimension(300, 300));
    setLayout(new GridLayout(GRID_SIZE,GRID_SIZE));

    for (int x = 0; x < GRID_SIZE; x++)
        for (int y = 0; y < GRID_SIZE; y++) {
            final Cell cell = new Cell(x, y);
            cellArray[x][y] = cell;
            add(cell);
            cell.addMouseListener(new MouseListener() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    mouseClick(e, cellArray);
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                    mouseEnter(e, cellArray);
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    mouseExit(e, cellArray);
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    mousePress(e, cellArray);
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    mouseRelease(e, cellArray);
                }
            });
        }
}

So these listeners can be accessed from the two subclasses, the listeners call another method as can be seen in the code above. These methods are contained under the constructor and are all abstract:

public abstract void mouseClick(MouseEvent e, Cell[][] cellArray);
public abstract void mouseEnter(MouseEvent e, Cell[][] cellArray);
public abstract void mouseExit(MouseEvent e, Cell[][] cellArray);
public abstract void mousePress(MouseEvent e, Cell[][] cellArray);
public abstract void mouseRelease(MouseEvent e, Cell[][] cellArray);

I then have two concrete subclasses - one is for the "Player grid", the other for the "Computer grid". The main difference is that in the Player grid the listeners are used immediately to place the ships. In the Computer grid, the ships are placed automatically (done when an object of the class is constructed).

This means that the listeners in the Computer grid class are only there to respond to the user's attempt to bomb a square. The Player Grid, once the ships have been placed, should be automatically bombed by the computer.

This is where I've run into difficulties. I have written a method in the PlayerGrid class called computerAttack() - but I've no idea how to access it from outside the class. How can I make the two subclasses communicate? Additionally, is this even the proper way to do it, or am I trying to do too much in these two classes? I have tried to provide as much information as necessary here, but if the actual content of the two subclasses is needed, I can provide them.

4

2 回答 2

5

这是一个典型的应用程序,其中应用了MVC等模式。一种是单独实现游戏逻辑并用于常见用途,其中包含computerAttack(). 因此,游戏逻辑将包含对两个网格/玩家的引用,并且还将实现两个网格/玩家的事件接口。这样,网格不需要相互了解。

M - 网格状态的内部表示(船/水,轰炸/未轰炸,...)

V - GUI 组件(网格、按钮、UI 事件监听器接口,...)

C - 游戏逻辑(在单独的类或包中实现)

于 2013-04-27T16:39:40.117 回答
1

也许别想PlayerGridComputerGrid分开。将它们都视为Grids。将Grid保持Grid的游戏状态。您将有一个Grid用于播放器和一个用于计算机。

然后你可以有一个GridListener接口,它对Grid. 喜欢attackSuccess(int x, int y)attackFailed(int x, int y)

因此,如果有类似的方法Grid.attack(int x, int y),则大致是:

boolean shipRemoved = removeShipAt(x, y);
if (shipRemoved) {
    // return true means that a ship was present and was removed.
    for (GridListener l: gridListeners) {
        l.attackSuccess(x, y);
    }
} else {
    // return false means that a ship was not present.
    for (GridListener l: gridListeners) {
        l.attackFailed(x, y);
    }
}

这样,Grids 之间就不会直接相互通信,而是可以监听对方的事件。或者更高级别的游戏控制器可以监听两者Grid的事件,并适当地通知对方Grid

于 2013-04-27T16:42:13.807 回答