【问题标题】:Java game board array not updatingJava 游戏板阵列未更新
【发布时间】:2023-04-09 06:12:02
【问题描述】:

我目前正在尝试复制黑白棋游戏(对于那些不熟悉的人,这里有一个示例:http://www.mathsisfun.com/games/reversi.html)。我目前遇到的问题与我尝试更新游戏板有关。我有一个称为板的 2D 数组,当用户单击特定单元格时,板意味着与该玩家一起更新。然而事实并非如此。这是我到目前为止的代码:

    /* Main.java
 *
 * this is a simple program that will implement the game of reversi, it will only deal with the game itself and a
 * simple scoreboard.
 */

/** includes **/
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import javax.swing.JComponent;
import javax.swing.JFrame;

/** classes **/

public class Reverse extends JFrame {

    /** constructors **/
    public Reverse() {
        setSize(648, 670);
        setTitle("Reversi");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(true);
        setLocationRelativeTo(null);

        //Initialize Widget
        widget = new ReversiWidget();
        //Initialize Content Pane
        getContentPane().add(widget);
    }

    /** public functions **/
    public static void main(String[] args) {
        Reverse w = new Reverse();
        w.setVisible(true);
    }

    /** private fields **/
    ReversiWidget widget;   // where the game is being played
}

class ReversiWidget extends JComponent implements MouseListener {

    int width = getWidth();
    int height = getHeight();
    int column = 8;
    int row = 8;


    /** constructors **/
    public ReversiWidget() {
        black = this.black;
        cyan = this.cyan;
        white = this.white;

        //Initialize game state
        initialState();

        //add mouse listener
        addMouseListener(this);
    }

    /** public functions **/

    // method required by MouseListener. not used
    public void mouseClicked(MouseEvent event) {

    }

    // method required by MouseListener. not used
    public void mouseEntered(MouseEvent event) {

    }

    // method required by MouseListener. not used
    public void mouseExited(MouseEvent event) {

    }

    // will react to mouse press events on the widget
    public void mousePressed(MouseEvent event) {
        //get value of left button clicked
        if(event.getButton() == 3){


        }
    }

    // will react to mouse release events on the widget
    public void mouseReleased(MouseEvent event) {
        //determine value for newx and newy
        //get mouse pressed
        int x = event.getX();
        int y = event.getY();
        setX(x);
        setY(y);
        rowSelected = x / sqaure_size;
        colSelected = y / sqaure_size;
        current_player = 1;
        if (rowSelected >= 0 && rowSelected < row && colSelected >= 0 && colSelected < column){
            System.out.println("C Row && C Col: "+rowSelected+"  | "+colSelected);
            System.out.println(oldx+" | "+oldy);
            board[rowSelected][colSelected] = current_player;
            System.out.println("Board Test: "+board[0][0]+", "+board[0][1]+", "+board[0][2]+", "+board[0][3]+", ");
            attemptMove(rowSelected, colSelected, current_player);
        }

    }

    // repaints the widget when an update of any kind is made
    public void paintComponent(Graphics g) {
        //paint background
        //type cast graphics object

        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.CYAN);
        g2d.fillRect(0,0,640, 640);
        //run draw grid method
        drawGrid(g2d);
        drawPieces(g2d);
    }


    /** private functions **/

    // will take in a position (x,y) a player and will attempt to make a move. if successful then it will place the
    // piece and update the game board.
    private void attemptMove(int x, int y, int player) {

        //repaint();

    }   

    // checks if there is a piece in a given position. returns 0 if empty, -1 if out of bounds, 1 for player 1, and
    // 2 for player 2
    private int checkPiece(int x, int y) {
        return -5;
    }

    // determines if a valid reverse chain can be made from the position (x, y) in the given direction (dx, dy) and a
    // given player
    private boolean determineChain(int x, int y, int dx, int dy, int player) {
        return false;
    }

    // determines if an end game state has been reached. this will happen if there are zero spaces on the board, if one
    // player has lost all of their pieces, or there are no valid moves left for either player
    private boolean determineEndGame() {
        return false;
    }

    // will draw the grid for the game. this assumes a 640 by 640 grid
    private void drawGrid(Graphics2D g2d) {
        //type cast graphics component
        //This is where it gets tricky

                //Here we're going to draw our grid
                int rowCount = width / row;
                int colCount  = height / column;
                int cell = 79;

                //Create Rows
                for(int a=0;a<row;a++){
                    g2d.setColor(Color.BLACK);
                    g2d.drawLine(0, colCount, 638, rowCount);
                    colCount = colCount + cell;
                    rowCount = rowCount + cell;
                }

                colCount = 79;
                rowCount = 79;
                //Create Columns
                for(int b=0;b<column;b++){
                    g2d.setColor(Color.BLACK);
                    //x1,y1  - x2,y2
                    System.out.println("ColCount: "+colCount);
                    g2d.drawLine(colCount, 0, rowCount, 675);
                    colCount = colCount + cell;
                    rowCount = rowCount + cell;

                }

                for (int rows = 0; rows < row; rows++) {
                 for (int col = 0; col < column; col++) {
                    board[row][column] = 0; // all cells empty
                    System.out.print(board[row][column]);
                 }
                 System.out.println();
              }

    }

    // will draw the pieces that are currently on the board. assumes a widget size of 640 square
    private void drawPieces(Graphics2D g2d) {

        int x = getX();
        int y = getY();
        System.out.println("drawPieces: "+x+" | "+y);
        //Traverse the entire board length to see if a move has been made

        //Black Initial Pieces
        g2d.setColor(Color.BLACK);
        g2d.fillOval(316, 237, 78,78);
        g2d.fillOval(238, 317, 78,78);

        //White Initial Pieces
        g2d.setColor(Color.WHITE);
        g2d.fillOval(238, 239, 78,78);
        g2d.fillOval(317, 317, 78,78);
        board[3][3] = 1;
        board[4][3] = 2;
        board[3][4] = 2;
        board[3][3] = 1;
        setBoard(3,3,1);
        setBoard(4,3,1);
        setBoard(3,4,1);
        //setBoard();

        //If move is made draw black piece

                        if(board[rowSelected][colSelected] == 2){
                           g2d.setColor(Color.BLACK);
                           g2d.fillOval(rowSelected, colSelected, 79, 79);
                        }


        //if move is made draw white pieces

                        if(board[rowSelected][colSelected] == 1){
                            g2d.setColor(Color.WHITE);
                            g2d.fillOval(rowSelected, colSelected, 79, 79);   
                        }





    }

    // will initialise the game board to the starting state
    private void initialState() {
        inPlay = true;
    }

    // given a position (x, y) and a player this will determine if there is a valid move to be made at the given
    // position by checking for the availability of a reverse chain in any direction
    private boolean reverseChainAvailable(int x, int y, int player) {
        return false;
    }   

    // given a position (x, y), direction (dx, dy) and a player this will reverse all opponents pieces in a given
    // direction. NOTE: this assumes that determineChain has been used first. method does not perform checks
    private void reversePieces(int x, int y, int dx, int dy, int player) {

    }

    // called at the end of a valid turn this will swap the current players
    private void swapPlayers() {

    }

    // updates the player scores after a piece has been placed
    private void updatePlayerScores() {

    }

    public void setX(int x){this.oldx = x;}
    public void setY(int y){this.oldy = y;}
    public void setBoard(int x, int y, int player){this.board[x][y] = board[x][y] = player;}

    /** private fields **/
    //initial board state
    public int board[][] = new int[9][9];
    int oldx;
    int oldy;   // denotes where the player clicked when he pressed the mouse button
    int current_player;                 // denotes who the current player is
    int player_1_score, player_2_score; // denotes the score each player has in the game thus far
    boolean inPlay;                     // indicates if the game is being played at the moment
    Color black, cyan, white;           // color objects that represent their named colours
    int sqaure_size = 79;
    int rowSelected = oldx / sqaure_size;
    int colSelected = oldy / sqaure_size;
}

具体问题与此方法有关:

public void mouseReleased(MouseEvent event) {
        //determine value for newx and newy
        //get mouse pressed
        int x = event.getX();
        int y = event.getY();
        setX(x);
        setY(y);
        rowSelected = x / sqaure_size;
        colSelected = y / sqaure_size;
        current_player = 1;
        if (rowSelected >= 0 && rowSelected < row && colSelected >= 0 && colSelected < column){
            System.out.println("C Row && C Col: "+rowSelected+"  | "+colSelected);
            System.out.println(oldx+" | "+oldy);
            board[rowSelected][colSelected] = current_player;
            System.out.println("Board Test: "+board[0][0]+", "+board[0][1]+", "+board[0][2]+", "+board[0][3]+", ");
            attemptMove(rowSelected, colSelected, current_player);
        }

    }

编辑*请原谅混乱!

【问题讨论】:

  • Unlrelated - 看看Initial Threads 并始终确保您正在调用super.paintXxx,尤其是在与JComponent 打交道时,否则您最终会得到不需要的油漆工艺。
  • 相关 - 您在 attemptMove 中注释掉了 repaint 有什么原因吗?
  • 是的,奇怪的是它更新(重新绘制)第一个单元板[0][0],但没有其他。我只是将其注释掉以进行测试。 @MadProgrammer 会的,谢谢!

标签: java swing multidimensional-array


【解决方案1】:

g2d.fillOval(rowSelected, colSelected, 79, 79) 将是一个问题,因为rowSelectedcolSelected 是您的板阵列的索引并且不反映视图/虚拟板偏移量,这些需要转换以反映图形网格。 ..

尝试改用g2d.fillOval(rowSelected * 79, colSelected * 79, 79, 79)

还应避免使用“魔术”数字,并为这些值创建常量或查找,这样您就可以更轻松地更改它们...

您需要取消注释 repaint 请求才能使其正常工作...

哦,您似乎也在从您的绘画方法中修改游戏状态,我建议您不要这样做,因为绘画可以随时发生。

另外,请确保在执行任何绘画之前调用 super.paintComponent,这将防止出现任何令人讨厌的绘画伪影,尤其是在处理从 JComponent 扩展的组件时

更新

Swing 中的绘画具有破坏性。也就是说,每次绘制周期发生时,您都应该重新绘制组件的整个状态。绘制过程的一部分是“清理”Graphics 上下文,这就是为什么调用super.paintXxx 很重要。

您将需要遍历您的板子开始并重新绘制它,例如...

for (int y = 0; y < row; y++) {
    for (int x = 0; x < col; x++) {
        if(board[y][x] == 2){
           g2d.setColor(Color.BLACK);
           g2d.fillOval(y * 79, x * 79, 79, 79);
        } else if(board[y][x] == 1){
            g2d.setColor(Color.WHITE);
           g2d.fillOval(y * 79, x * 79, 79, 79);
        }
    }
}

【讨论】:

  • 谢谢!它正在填充单元格:broconut.com/i/504ef539a9c82.png
  • 只是另一个问题,存储已经移动的玩家的最佳方法是什么?看来我的游戏板仍然没有更新。
  • 几乎没有其他事情我可能会因为没有提及而受到打击。一般来说,我们不鼓励直接从JFrame 扩展,一般来说,你不会在类中添加任何东西。相反,只需创建一个实例并将您的 ReversiWidget 添加到其中。让paintComponentpublic真的没有意义,你真的不希望任何人乱叫,最好留下protected
  • 我只看到你在mouseReleased方法中将当前播放器设置为1 (current_player = 1;)。您每次都需要更改...
  • 我已经排序了,但我现在得到的是这个:Image Example 我可以随意将圆圈放在单元格中,但我想要的是将它们保留在那里。这就是我想要用游戏板做的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
相关资源
最近更新 更多