在画板上,每个方块有40%的概率被填充。

huangapple go评论73阅读模式
英文:

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

问题

我刚开始制作Java游戏,对Java图形编程也不太了解。我正在尝试制作一个游戏,其中棋盘上的每个方块有40%的几率成为填充障碍物。我已经编写了一些代码,但它的运行方式不符合我的预期。它填满了整个棋盘,但我只希有些部分成为障碍物。以下是我绘制和绘图方法的代码:

/////////////////////////////////////////
//绘制游戏所需的图形。
////////////////////////////////////////
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);
           
}

///////////////////////////////////////////////////////////////////////////
//在游戏开始时为障碍物对象找一个随机位置。
///////////////////////////////////////////////////////////////////////////

public static boolean randomBarrier() {  //应该将所有部分放入此方法中,以查看它们是否是障碍物材料。
    
    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;
}

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

英文:

I'm new to making java games and especially new to java graphics.
I'm trying to make a game in which each tile of the board has a 40% chance to be a filled barrier.
I have coded some parts,but it doesn't work the way I want it to.It fills up the entire board,but I want only some parts to be a barrier.
Here is my chance and drawing method code:

    /////////////////////////////////////////
	//Draws the graphics needed for the game.
	////////////////////////////////////////
	public void paint(Graphics g) { 
		
		g.setColor(Color.BLUE);
		
		
		for(int i=1;i&lt;boardWidth/10;i++) {
			g.drawLine(i*100, 100, i*100, HEIGHT-100);
		}
		
		
		for(int j=1;j&lt;boardHeight/10;j++)
			g.drawLine(100, j*100, WIDTH-100, j*100);
		
		
		for(int i=100;i&lt;WIDTH-200;i++)
			for(int j=100;j&lt;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&lt;0.4)
			return true;
		
	    else if(random&gt;=0.4)
		   return false;
		
		return true;
		
	}

Could someone please help me with this?

答案1

得分: 3

绘画方法绝对不应该改变组件的状态(你无法控制 Swing 何时决定重新绘制组件)。

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

相反,你可以:

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

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

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

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);

现在你可以动态地更改行数/列数/单元格大小,而不影响绘画代码。避免在程序中使用硬编码的值,将这些值作为你的类的属性。

英文:

A painting method should NEVER change the state of the component (you can't control when Swing determines the component needs to be repainted).

Therefore you should NOT be using random code in the painting method.

Instead you can:

  1. create a 2D array as an instance variable in your class containing boolean values
  2. in the constructor of your class you iterate through all the items in the array and assign a true/false value based on your random logic
  3. in the painting method, then you then iterate through the 2D array and paint each rectangle based on the value.

Also, custom painting is done by overriding the paintComponent() method not paint() and you need to invoke super.paintComponent().

Your painting code uses too many hard coded values. Instead you should be using instance variables in your class to avoid confusion. Something like:

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

Then your painting code becomes (untested) something like:

    super.paintComponent();

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

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

Now you can dynamically change the rows/columns/cell size without affecting the painting code. Avoid the usage of hard coded values in your programs. Make the values properties of you class.

答案2

得分: 2

你正在为棋盘上的每个像素绘制一个100x100的瓦片,因为ij都增加了1。由于有40%的概率绘制该瓦片,你极有可能最终绘制了棋盘上的所有像素。你应该将ij按照瓦片大小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的答案中的建议:在当前的代码中,通过动画重新绘制组件会填充不同的一组瓦片,从而产生闪烁效果。或者你会看到所有的瓦片都被填充,因为组件背景没有被绘制出来。

英文:

You are potentially drawing a 100x100 tile for every pixel on the board because i and j increment by 1. With a 40% probability of drawing the tile, it's extremely likely you end drawing on all pixels on the board. You should increment i and j by the tile size 100:

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

You should also follow the advice in camickr's answer: With your current code, repainting the component in an animation would fill a different set of tiles and you would get a flickering effect. Or you will see all tiles get filled in because the component background does not get drawn.

huangapple
  • 本文由 发表于 2020年7月25日 22:33:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63089575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定