Java 2D TileMap异常:grass tile转sand tile部分区域未生效
问题分析与修复方案
核心问题点
你的代码失效根源在sametile方法的逻辑错误,导致相邻海洋tile的统计完全混乱:
- 边界判断逻辑错误:原代码的越界判断完全不符合数组索引规则,还错误地给
counter加1,把不存在的越界位置当成有效计数,干扰了真实的海洋tile统计。 - 遍历范围不完整:循环条件
x < locx+diameter会漏掉locx+diameter这个位置,导致无法检查到目标tile右侧(或下侧)的相邻tile。 - 未排除当前tile自身:统计时会把当前tile也算进去,逻辑上不严谨,虽在当前场景影响不大,但可能引发后续问题。
修复后的代码
1. 修复sametile方法
public int sametile(int locx, int locy, int diameter, int tile) { int counter = 0; // 遍历以目标tile为中心的所有相邻区域(包含八方向) for (int x = locx - diameter; x <= locx + diameter; x++) { for (int y = locy - diameter; y <= locy + diameter; y++) { // 跳过当前tile自身 if (x == locx && y == locy) { continue; } // 正确判断数组边界:越界直接跳过 if (x < 0 || x >= width || y < 0 || y >= height) { continue; } // 匹配到目标tile则计数 if (map[x][y] == tile) { counter++; } } } return counter; }
2. 优化geography方法(更严谨)
原方法直接遍历修改原数组,虽当前场景无问题,但推荐先标记需修改的位置再统一更新,避免后续需求变更时出现逻辑冲突:
public void geography() { // 记录需要转换为sand的grass位置 boolean[][] needConvert = new boolean[width][height]; // 遍历所有tile,标记符合条件的grass for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (map[x][y] == 4) { int oceanNeighbors = sametile(x, y, 1, 3); if (oceanNeighbors > 0) { needConvert[x][y] = true; } } } } // 统一转换标记的tile for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (needConvert[x][y]) { map[x][y] = 1; } } } }
额外说明
如果只需要**四邻域(上下左右)**的相邻判断,可修改sametile的遍历逻辑,仅检查(x±1,y)和(x,y±1)四个位置,效率更高且符合常见地图规则。
内容的提问来源于stack exchange,提问作者Hakan Polat
相关产品推荐
相关产品推荐

