绘制一个棋盘,其中每个方块都有 0.4 的机会被填充

drawing a board in which each tile has a 0.4 chance to be filled

我刚开始制作 java 游戏,尤其是 java 图形。 我正在尝试制作一款游戏,其中棋盘上的每一块棋子都有 40% 的机会成为填充障碍。 我已经对一些部分进行了编码,但它并没有按照我想要的方式工作 to.It 填满了整个板,但我只希望某些部分成为障碍。 这是我的机会和绘制方法代码:

    /////////////////////////////////////////
    //Draws the graphics needed for the game.
    ////////////////////////////////////////
    public void paint(Graphics g) { 
        
        g.setColor(Color.BLUE);
        
        
        for(int i=1;i<boardWidth/10;i++) {
            g.drawLine(i*100, 100, i*100, HEIGHT-100);
        }
        
        
        for(int j=1;j<boardHeight/10;j++)
            g.drawLine(100, j*100, WIDTH-100, j*100);
        
        
        for(int i=100;i<WIDTH-200;i++)
            for(int j=100;j<HEIGHT-200;j++)
                if(randomBarrier()) 
                g.fillRect(i, j, 100, 100);
               
        
    }
    
    
    
    
    ///////////////////////////////////////////////////////////////////////////
    //finds a random place for the barrier objects in the beginning of the game.
    ///////////////////////////////////////////////////////////////////////////

    public static boolean randomBarrier() {  //Should put all the parts to this method to see if the are barrier material or not.
        
        
        int row = WIDTH/100;
        int column = HEIGHT/100;
        
        int min = 0;
        int max = row*column;
        
        double random = Math.random();
        
        if(random<0.4)
            return true;
        
        else if(random>=0.4)
           return false;
        
        return true;
        
    }

有人可以帮我解决这个问题吗?

绘画方法不应该改变组件的状态(您无法控制 Swing 何时确定组件需要重新绘制)。

因此您不应该在绘画方法中使用随机代码。

相反,您可以:

  1. 在您的 class 中创建一个包含布尔值
  2. 的二维数组作为实例变量
  3. 在 class 的构造函数中,您遍历数组中的所有项目并根据您的随机逻辑分配一个 true/false 值
  4. 在绘画方法中,然后遍历二维数组并根据值绘制每个矩形。

此外,自定义绘画是通过覆盖 paintComponent() 方法而不是 paint() 完成的,您需要调用 super.paintComponent().

您的绘画代码使用了太多的硬编码值。相反,您应该在 class 中使用实例变量以避免混淆。类似于:

int rows = 100;
int columns = 200;
int tileSize = 10;

然后你的绘画代码变成(未经测试)类似于:

    super.paintComponent();

    int width = columns * tileSize;
    int height = rows * tileSize;

    for(int i = 0; i <= rows; i++) {
        int lineY = i * tileSize;
        g.drawLine(0, lineY, width, lineY);
    }
    
    
    for(int j = 1; j <= columns; j++) {
        int lineX = j * tileSize;
        g.drawLine(lineX, 0, lineX, height);
    }
    
    
    for(int i = 0;i < rows;i++)
        for(int j=0; j < columns;j++)
            if( randomBarrier[i][j]) 
                g.fillRect(i * tileSize, j * tileSize, tileSize, tileSize);
           

现在您可以动态更改 rows/columns/cell 大小而不影响绘画代码。避免在程序中使用硬编码值。让你的价值观属性 class.

您可能会为棋盘上的每个像素绘制一个 100x100 的图块,因为 ij 递增 1。绘制图块的概率为 40%,您极有可能结束绘制在板上的所有像素上。您应该将 ij 增加 tile 大小 100:

    for(int i=100; i<WIDTH-200; i += 100)
        for(int j=100; j<HEIGHT-200; j += 100)
            if (randomBarrier()) g.fillRect(i, j, 100, 100);

您还应该遵循 camickr 的回答中的建议:使用您当前的代码,重新绘制动画中的组件会填充不同的图块集,并且您会得到闪烁的效果。或者你会看到所有的图块都被填满了,因为组件背景没有被绘制。