基于关卡从LinkedList移除对象时触发NullPointerException问题求助
解决你的空指针问题与Boss生成逻辑优化
看起来你遇到的NullPointerException根源非常清晰——你的BasicEnemy类中的hud引用没有被正确初始化,导致在执行if(hud.level % 10 == 0)这行代码时,无法访问hud对象的level属性。我们一步步来解决这个问题,同时优化你的敌人移除和Boss生成逻辑:
核心问题:HUD引用未初始化
你在BasicEnemy的tick方法里直接访问hud.level,但如果没有在BasicEnemy的构造过程中传入并保存当前的HUD实例,这个hud变量就会是null,触发空指针异常。
修复步骤:
- 修改
BasicEnemy类,添加HUD成员变量并在构造函数中初始化:
public class BasicEnemy extends GameObject { private HUD hud; // 添加HUD成员变量 // 修改构造函数,传入HUD实例 public BasicEnemy(float x, float y, ID id, HUD hud) { super(x, y, id); this.hud = hud; // 初始化hud引用 } // 你的tick方法 public void tick() { // 增加空判断,避免极端情况下的空指针 if(hud != null && hud.level % 10 == 0) { this.removed = true; } // 其他逻辑... } }
- 生成
BasicEnemy时传入当前的HUD实例:
确保你在创建BasicEnemy对象的地方(比如游戏的敌人生成逻辑里),把当前的HUD对象传进去,例如:
// 假设你有一个当前的hud实例 HUD gameHud = new HUD(); handler.addObject(new BasicEnemy(100, 100, ID.BasicEnemy, gameHud));
优化LinkedList的元素移除逻辑
你当前的移除逻辑存在一个隐藏问题:使用索引遍历LinkedList并删除元素时,会导致后续元素前移,从而跳过下一个元素的检查。比如删除索引i的元素后,原来的i+1元素会移到i的位置,但你的循环i++会直接跳过它。
推荐的两种修复方式:
方式1:使用迭代器遍历(LinkedList的最优遍历删除方式)
// 在Handler类中 Iterator<GameObject> iterator = object.iterator(); while(iterator.hasNext()) { GameObject obj = iterator.next(); if(obj.removed) { iterator.remove(); // 用迭代器的remove方法安全删除 } }
方式2:从后往前遍历索引
// 在Handler类中 for(int i = object.size() - 1; i >= 0; i--) { GameObject obj = object.get(i); if(obj.removed) { object.remove(i); } }
完善Boss生成与敌人清除的触发逻辑
你当前的逻辑是每帧都检查关卡并标记敌人为移除,这可能导致重复操作。建议改为当关卡提升到10的倍数时,一次性触发敌人清除和Boss生成,避免每帧执行判断:
示例实现(在HUD的关卡提升逻辑中扩展):
// HUD类的tick方法修改 public void tick() { HEALTH = Game.clamp(HEALTH, 0, 100); greenValue = Game.clamp(greenValue, 0, 255); greenValue = HEALTH * 2; score++; scoreKeep ++; if(scoreKeep >= 100) { scoreKeep = 0; int oldLevel = this.getLevel(); this.setLevel(oldLevel + 1); int newLevel = oldLevel + 1; // 当新关卡是10的倍数时,触发清除和Boss生成 if(newLevel % 10 == 0) { // 调用Handler的方法清除所有非Boss敌人 handler.clearNonBossEnemies(); // 生成Boss(假设BossEnemy是你的Boss类) handler.addObject(new BossEnemy(Game.WIDTH/2 - 50, Game.HEIGHT/2 - 50, ID.Boss, this)); } } } // 在Handler类中添加clearNonBossEnemies方法 public void clearNonBossEnemies() { Iterator<GameObject> iterator = object.iterator(); while(iterator.hasNext()) { GameObject obj = iterator.next(); if(obj.getId() != ID.Boss) { // 假设Boss的ID是ID.Boss iterator.remove(); } } }
这样可以确保只有在关卡真正提升到10的倍数时才执行一次清除和Boss生成,而不是每帧都标记敌人移除,逻辑更高效清晰。
内容的提问来源于stack exchange,提问作者John-
相关产品推荐
相关产品推荐

