java - 如何将鼠标位置(以像素为单位)转换为网格上的行和列?

标签 java processing

我基本上是在制作一个战舰猜测游戏,你必须通过单击鼠标来确定船只的位置。当正确猜测船舶的位置时,它会从数组中删除该船舶单元,当正确猜测每个单元时,游戏结束。

我现在正在努力的是

  1. 将船舶单元保留在 Canvas 内
  2. 将鼠标位置(以像素为单位)转换为网格上的行和列
  3. 如果猜测正确,则将猜测添加到 hit 数组中,如果猜错了,则将其添加到 miss 数组中。
  4. 当进行猜测时,除了给单元格着色之外,还打印“Hit!”或“小姐!”在细胞上
  5. 当所有单元都被击中后沉船

最佳答案

在您的代码中,您混合了行和列。 x 坐标从左到右,这是列。 y 轴从上到下并对应于行。

不要将columnrowhitmiss存储在数组中。但使用二维数组来存储船的位置和鼠标点击的位置:

boolean [][] ship;
boolean [][] click;
  1. keep the ship cells within the canvas

如果方向是水平的,则船舶的 x 起始位置必须小于NUM_COLS - ShipLength:

randomX = (int)random(NUM_COLS - shipLength);
randomY = (int)random(NUM_ROWS);

如果方向是水平的,那么船舶的 y 起始位置必须小于NUM_ROWS - ShipLength:

randomX = (int)random(NUM_COLS);
randomY = (int)random(NUM_ROWS - shipLength);

setup中调用randomShip而不是draw:

void setup() {
    size(600, 500);
    randomShip();
    println(store);
}

void draw() {
    // randomShip(); <---- delete
    drawCells (row, column, shipLength, (255) );
}

randomShip中生成船舶的随机位置和大小;

void randomShip () {

    ship = new boolean[NUM_COLS][NUM_ROWS];
    click = new boolean[NUM_COLS][NUM_ROWS];

    shipLength = (int)random (3, 8);

    int store = (int)random(vert, horz);  
    if (store >= 0) {

        int randomX = (int)random(NUM_COLS - shipLength);
        int randomY = (int)random(NUM_ROWS);

        for (int i = 0; i < shipLength; i++ ) {
            ship[randomX + i][randomY] = true;
        }
    } else  {

        int randomX = (int)random(NUM_COLS);
        int randomY = (int)random(NUM_ROWS - shipLength); 

        for (int i = 0; i < shipLength; i++ ) {
            ship[randomX][randomY+1] = true;
        }
    }
    println(shipLength);
}
  1. convert the mouse position in pixels into the row and column on the grid
  2. if the guess is correct, add the guess to the hit array and if missed adding it to the miss array.

鼠标坐标mouseXmouseY除以CELLSIZE即可得到被点击的单元格

int cell_x = mouseX / CELLSIZE; 
int cell_y = mouseY / CELLSIZE; 

mouseClicked中存储标记被点击的单元格并计算命中和未命中:

void mouseClicked () {

    int cell_x = mouseX / CELLSIZE; 
    int cell_y = mouseY / CELLSIZE;

    if (!click[cell_x][cell_y]) {
        click[cell_x][cell_y] = true;

        if ( ship[cell_x][cell_y] ) {
            hitCount ++;
        } else {
            missCount ++;
        }
    }
}
  1. when a guess is made, in addition to colouring the cell, print either “Hit!” or “Miss!” on the cell

评估绘制单元格中的船舶位置 (ship[][]) 和点击位置 (click[][])。根据 2 个嵌套循环中的状态绘制单元格和文本:

void drawCells(int colour) {

    for (int i = 0; i < NUM_COLS; i++) {
        for (int j = 0; j < NUM_ROWS; j++) {

            float x = i * CELLSIZE;
            float y = j * CELLSIZE;

            if (ship[i][j]) {
                fill (colour);
                rect(x, y, CELLSIZE, CELLSIZE);
            }

            if (click[i][j]) {
                fill(255, 0, 0);
                textSize(15);
                text(ship[i][j] ? "hit" : "miss", x+10, y+30); 
            }
        }
    }
}
  1. sinking the ship when all cells have been hit

draw中处理游戏结束:

例如

void draw() {

    drawCells(255);

    if (hitCount == shipLength ) {

        // [...]

    }
}
<小时/>

完整代码 list :

final int CELLSIZE = 50;
final int NUM_ROWS = 10;
final int NUM_COLS = 12;

int horz = (int)random(50);
int vert = (int)random(-50);

int store;
int shipLength;

boolean [][] ship;
boolean [][] click;

int hitCount = 0;
int missCount = 0;

void setup() {
    size(600, 500);
    randomShip();
    println(store);
}

void draw() {

    drawCells(255);

    if (hitCount == shipLength ) {

        // [...]

    }
}

void drawCells(int colour) {

    for (int i = 0; i < NUM_COLS; i++) {
        for (int j = 0; j < NUM_ROWS; j++) {

            float x = i * CELLSIZE;
            float y = j * CELLSIZE;

            if (ship[i][j]) {
                fill (colour);
                rect(x, y, CELLSIZE, CELLSIZE);
            }

            if (click[i][j]) {
                fill(255, 0, 0);
                textSize(15);
                text(ship[i][j] ? "hit" : "miss", x+10, y+30); 
            }
        }
    }
}

void randomShip () {

    ship = new boolean[NUM_COLS][NUM_ROWS];
    click = new boolean[NUM_COLS][NUM_ROWS];
    hitCount = 0;
    missCount = 0;

    shipLength = (int)random (3, 8);

    int store = (int)random(vert, horz);  
    if (store >= 0) {

        int randomX = (int)random(NUM_COLS - shipLength);
        int randomY = (int)random(NUM_ROWS);

        for (int i = 0; i < shipLength; i++ ) {
            ship[randomX + i][randomY] = true;
        }
    } else  {

        int randomX = (int)random(NUM_COLS);
        int randomY = (int)random(NUM_ROWS - shipLength); 

        for (int i = 0; i < shipLength; i++ ) {
            ship[randomX][randomY+1] = true;
        }
    }
    println(shipLength);
}

void mouseClicked () {

    int cell_x = mouseX / CELLSIZE; 
    int cell_y = mouseY / CELLSIZE;

    if (!click[cell_x][cell_y]) {
        click[cell_x][cell_y] = true;

        if ( ship[cell_x][cell_y] ) {
            hitCount ++;
        } else {
            missCount ++;
        }
    }
}

关于java - 如何将鼠标位置(以像素为单位)转换为网格上的行和列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55527159/

相关文章:

serial-port - void serialEvent Arduino - 处理以避免滞后

Java:带有管道特殊字符的 split() 方法

java - 为枚举实现 MessageBodyReader

java - jOOQ - dao - 插入对象的主键

java - 如何判断一个点是在线段的左侧还是右侧?

java - 如何在处理中创建单个草图的多个窗口?

java - 处理中的 OOP,我应该如何构建我的类?

java - 处理:尝试在没有绘图功能的情况下对线条的绘制进行动画处理

java - 尝试在 Java 中实现 Bridge 模式时出错

java - 在父上下文或祖先上下文中找不到方法