Java中用for循环将drawLine星星扩展为网格布局的技术求助
解决Java星星网格布局的问题
嘿,刚看了你的代码和问题,你已经搞定了单颗星星和背景条纹,现在卡在星星的网格布局上对吧?其实核心就是用嵌套for循环来控制行列位置,你之前的循环逻辑有点绕,导致位置计算出错,咱们一步步来修正。
先说说你当前代码的问题
你原来的星星循环部分逻辑太复杂,比如x1/5*4 == stars这种判断完全没道理,而且x1每次只加1,相当于遍历每个像素,大部分时候都不会触发画星星的条件,同时y方向的循环也没和x方向联动,导致星星要么重叠要么显示不出来。
正确的思路:嵌套循环+均匀间距计算
网格布局本质是二维的,所以必须用外层循环控制行(y方向),内层循环控制列(x方向)。关键是要给每个星星计算出正确的起始坐标,保证它们之间有均匀的间距,不会重叠。
修改后的代码示例
先保留你已经正确的部分(背景、条纹、蓝色星区),只替换星星绘制的循环部分:
public static void drawFlag(int stars, int stripes, java.awt.Graphics g, int x, int y, int width, int height) { // Sets backround rectangle color to white g.setColor(Color.WHITE); g.fillRect(x, y, width, height); // Draw filled red rectangles *stripes* int stripeHeight = height/stripes; g.setColor(Color.RED); int lastStripeDrawnY = 0; // For loop runs red stripes for (int i = y; i < y + height - 2*stripeHeight; i = i + 2*stripeHeight) { g.fillRect(x, i, width, stripeHeight); lastStripeDrawnY = i; } // expands strips across the rectangle int lastStripeY = lastStripeDrawnY+2*stripeHeight; int lastStripeHeight = y + height - lastStripeY; if (stripes%2!= 0) { g.fillRect(x, lastStripeY, width, lastStripeHeight); } // Draws the starField int numberOfRedStripes = (int)Math.ceil(stripes/2.0); int starFieldHeight = numberOfRedStripes*stripeHeight; int starFieldWidth = starFieldHeight*width/height; g.setColor(Color.BLUE); g.fillRect(x, y, starFieldWidth, starFieldHeight); // ------------------- 修改后的星星网格绘制部分 ------------------- int starSize = 50; // 星星的大小,和你drawStar里的参数对应 int starSpacing = 15; // 星星之间的间距,可根据需要调整 int starRows = 5; // 想要的行数,比如5行 int starCols = 6; // 想要的列数,比如6列 // 嵌套循环:外层遍历行,内层遍历列 for (int row = 0; row < starRows; row++) { for (int col = 0; col < starCols; col++) { // 计算当前星星的X坐标:星区起始X + 列索引*(星星大小+间距) int currentStarX = x + col * (starSize + starSpacing); // 计算当前星星的Y坐标:星区起始Y + 行索引*(星星大小+间距) int currentStarY = y + row * (starSize + starSpacing); // 额外判断:确保星星不会超出蓝色星区的范围 if (currentStarX + starSize <= x + starFieldWidth && currentStarY + starSize <= y + starFieldHeight) { drawStar(g, currentStarX, currentStarY, starSize); } } } } // drawLine the star(这个方法没问题,不用改) public static void drawStar(java.awt.Graphics g, int x, int y, int size) { g.setColor(Color.WHITE); g.drawLine(x+size/2, y+size/6, x+4*size/5, y+5*size/6); g.drawLine(x+4*size/5,y+5*size/6, x+size/6, y+2*size/5); g.drawLine(x+size/6, y+2*size/5, x+5*size/6, y+2*size/5); g.drawLine(x+5*size/6, y+2*size/5, x+size/5, y+5*size/6); g.drawLine(x+size/5, y+5*size/6, x+size/2, y+size/6); }
额外优化:自动适配星区大小
如果你不想手动指定行列数,也可以根据蓝色星区的大小自动计算能放下多少颗星星:
// 替换上面的starRows和starCols为自动计算 int maxCols = starFieldWidth / (starSize + starSpacing); int maxRows = starFieldHeight / (starSize + starSpacing); // 然后用maxRows和maxCols作为循环的上限 for (int row = 0; row < maxRows; row++) { for (int col = 0; col < maxCols; col++) { // 坐标计算逻辑和上面一样 int currentStarX = x + col * (starSize + starSpacing); int currentStarY = y + row * (starSize + starSpacing); drawStar(g, currentStarX, currentStarY, starSize); } }
总结一下
- 网格布局必须用嵌套for循环,因为要同时控制x(列)和y(行)两个维度的位置。
- 星星的位置计算核心是
索引*(星星大小+间距),这样能保证每个星星之间的间距均匀,不会重叠。 - 可以手动指定行列数,也可以根据星区大小自动计算,灵活调整。
内容的提问来源于stack exchange,提问作者Woop
相关产品推荐
相关产品推荐

