You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:32:55