Java文本游戏世界生成代码触发多个ArrayIndexOutOfBoundsException如何修复
Java文本游戏世界生成模块数组越界问题修复方案
报错根本原因
Java数组的合法索引范围为[0, 数组长度-1],你的代码中所有循环均错误使用<= 数组长度作为终止条件,当索引等于数组长度时就会触发ArrayIndexOutOfBoundsException异常。你收到的报错就是填充宝箱X坐标时,索引等于num_of_chests(也就是X坐标数组的长度)导致的。
具体错误点&修复方案
1. 填充X/Y坐标数组的循环逻辑错误
原代码中X坐标数组长度为num_of_chests,但循环终止条件写为random_int_1 <= num_of_chests,会多循环1次直接越界。需要把两个填充坐标的循环条件都改为<。
2. 合并坐标数组的循环逻辑错误
原代码创建合并数组后,循环读取X/Y坐标数组时,终止条件用了合并数组的长度,远大于X/Y坐标数组本身的长度,会导致读取X/Y数组时越界,同时写入合并数组时也会超长度。
3. 额外死循环问题
main方法中选择生成世界后,没有重新读取用户输入更新option的值,会进入死循环一直生成世界。
4. 冗余优化
不需要每次生成随机数都创建新的Random实例,整个方法复用同一个实例即可;坐标均为整数值,不需要用double类型数组存储,改用int数组更节省内存。
修复后的完整代码
import java.util.Scanner; import java.util.Arrays; import java.util.Random; // 原有类声明保留即可 static int[] worldgen() { Random rand = new Random(); int num_of_chests = rand.nextInt(100); // 特殊情况处理:生成0个宝箱直接返回空数组 if (num_of_chests == 0) { return new int[0]; } int[] chest_x_values = new int[num_of_chests]; int[] chest_y_values = new int[num_of_chests]; // 填充X坐标 for (int i = 0; i < num_of_chests; i++) { chest_x_values[i] = rand.nextInt(301); // 调试打印可自行保留或删除 System.out.println(chest_x_values[i]); System.out.println(Arrays.toString(chest_x_values)); } // 填充Y坐标 for (int i = 0; i < num_of_chests; i++) { chest_y_values[i] = rand.nextInt(301); } // 合并数组结构:前num_of_chests位是X坐标,中间1位是分隔符-1,后num_of_chests位是Y坐标 int[] chest_x_and_y_values = new int[num_of_chests * 2 + 1]; // 批量复制X坐标到合并数组 System.arraycopy(chest_x_values, 0, chest_x_and_y_values, 0, num_of_chests); // 插入分隔符 chest_x_and_y_values[num_of_chests] = -1; // 批量复制Y坐标到合并数组 System.arraycopy(chest_y_values, 0, chest_x_and_y_values, num_of_chests + 1, num_of_chests); return chest_x_and_y_values; } public static void main(String[] args) { Scanner uIn = new Scanner(System.in); int option = 0; // 存储生成的世界数据,用于查看功能 int[] world = null; while (option != 4) { System.out.println("-------------------------------"); System.out.println(" *game name censored* "); System.out.println(" 1: Generate new world.. "); System.out.println(" 2: Generate w/ custom seed.. "); System.out.println(" 3: See world data "); System.out.println(" 4: Exit "); System.out.println("-------------------------------"); option = uIn.nextInt(); switch (option) { case 1: world = worldgen(); System.out.println("世界生成成功"); break; case 2: // 自定义种子逻辑可自行补充 System.out.println("功能开发中"); break; case 3: if (world == null) { System.out.println("请先生成世界"); } else { System.out.println(Arrays.toString(world)); } break; case 4: System.out.println("退出游戏"); break; default: System.err.println("Error 0x1: Not an option"); } } uIn.close(); }
内容的提问来源于stack exchange,提问作者EnZon3
相关产品推荐
相关产品推荐

