简体   繁体   中英

Android Java Battleship Game: Drawing ships on a 2D grid

I'm currently programming a battleship game, and I've made the 10x10 grid using 2 for loops. Now what I want to do is change the cell color depending on whether there is a ship there or not.

Currently as a test case, I have a size 3 ship at coordinates (1,4) going horizontally. Ships are stored as ships[i] = ShipData(int size, boolean isHorizontal, int left, int top). I have several different paints in my view, and the shipPaint should fill the cells as black, however I am unsure on how to proceed as I do not know how to check for the ship during my onDraw method.

So here is my method to draw the initial grid, inside the onDraw method:

for (int i = 0; i < noOfColumns; i++) {
    int ystart = i * boxWidth;
    for (int j = 0; j < noOfRows; j++) {
        int xstart = j * boxWidth;


            box = new Rect(ystart, xstart, (ystart+boxWidth), (xstart+boxWidth));
            int var = mGame.cellStatus(i, j);
            switch (var)
                {
                    case -1: paint = fillPaint;

                    case 0: case 1: case 2: case 3: case 4: paint = shipPaint;
                }


            canvas.drawRect(box, paint);
            canvas.drawRect(box, borderPaint);

    }
}

The problem is, I do not know how to write the cellStatus method, which needs to return -1 if it's an empty cell, or 0 to 4 if its part of a certain ship (5 ships in total.

So I need to pull data from the ShipData class that has 4 variables, ie ships[i] = ShipData(size, isHorizontal, left, top),and calculate whether there is a ship block at any given cell, and paint the cell accordingly. Currently every cell is the same color as my method has not yet been written.

ships[0] = new ShipData(3, true, 1, 4);

So I need to check (1,4) (2,4) (3,4) and return 0 from cellStatus, but I have no idea how to write cellStatus. The parameters for cellStatus are (column, row), and its a public int inside my game class.

To clarify, my cellStatus method needs to check whether there is a ship block at any given coordinate, presumably by reading from the ShipData class variable type. ShipData has several methods, such as getLeft, getTop, getRight and getBottom, and I'm unsure on how to turn the input of column, row into actual data about each cell, as described above. So the output of cellStatus needs to be -1 for an empty cell, and 0-4 for each of the 5 ships.

Apologies for the long winded question, I've tried to be as precise as I can. If you need further information please let me know and I'll provide it.

Unfortunately my old post didn't get any answers, and I've made some progress since then,

@Override
public int cellStatus(int column, int row) {
int cellStatus = 0;
for (int i = 0; i < 5; i++){
    int maxSize = ships[i].getSize();
    for (int size = 0; size < maxSize; size++ ) {
        ships[i].getLeft();
    }
    cellStatus = ships[i].getLeft();

}

return cellStatus;
}    

This is what I've got so far, but I'm unsure on how to make cellStatus return the desired value for EACH coordinate of a ship, I just dont know how to iterate through the values using startLeft, startTop and orientation etc

Here's one way:

In this example (x ≡ col and y ≡ row)

Add this method to your Ship class:

  /** @return true if this Ship contains the point */
    public boolean contains(int x, int y) {
        int myX = left; int myY = top;
        int xInc = (isHorizontal ? 1 : 0);
        int yInc = ((xInc+1)%2);

        for (int z = 0; z < size; z++) {
            if (myX == x && myY == y) {
                return true;
            }
            myX += xInc; myY += yInc;
        }
        return false;
    }

And your cellStatus method becomes:

public static int cellStatus (int column, int row) {
    for (int shipIdx = 0; shipIdx < 5; shipIdx++) {
        if (ships[shipIdx].contains(column,  row)) {
            return shipIdx;
        }
    }
    return -1;
}

So this test case:

    ships[0] = new Ship(3, true, 1, 4);
    ships[1] = new Ship(2, false, 1, 6);
    ships[2] = new Ship(2, true, 0, 9);
    ships[3] = new Ship(4, true, 5, 1);
    ships[4] = new Ship(5, false, 7, 5);

With this test code:

    for (int row = 0; row < 10; row++) { 
        for (int col = 0; col < 10; col++) {
            int cellStat = cellStatus(col, row);
            String shipSymbol = (cellStat == -1 ? "-" : Integer.toString(cellStat));
            System.out.print(shipSymbol+" ");
        }
        System.out.println();
    }

Produces:

  - - - - - - - - - - 
  - - - - - 3 3 3 3 - 
  - - - - - - - - - - 
  - - - - - - - - - - 
  - 0 0 0 - - - - - - 
  - - - - - - - 4 - - 
  - 1 - - - - - 4 - - 
  - 1 - - - - - 4 - - 
  - - - - - - - 4 - - 
  2 2 - - - - - 4 - - 

If you can't modify the Ship class then simply change the contains method defined above to :

public static boolean contains(Ship ship, int x, int y) {
    // modify all field accesses to ship.get...() accesses.
}

And modify the ship loop to:

if (contains(ships[shipIdx],column,row) {...}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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