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

Java类布尔值调用set修改后update方法读取仍为旧值问题求助

问题原因分析

1. update方法无法识别removeSnake布尔值变更的原因

  • 实例不匹配:你调用setRemoveSnake(true)的Snake实例,和主update中遍历执行enemy.update(dt)的Snake实例不是同一个对象。比如你在碰撞检测时拿到的是临时创建的对象副本、或者取错了列表里的实例,修改的是副本的属性,原实例的removeSnake自然还是false。可以在setRemoveSnake和update方法中分别打印System.identityHashCode(this),如果两个日志输出的哈希值不一致,就可以确认是该问题。
  • 多线程可见性问题:libGDX中Box2D的碰撞回调是在物理计算线程执行,而游戏主update/render是在UI渲染线程执行,如果你是在碰撞回调里调用的setRemoveSnake,两个线程没有同步的话,布尔值的修改不会被渲染线程感知到。这种情况只要给removeSnake变量加volatile关键字即可:protected volatile boolean removeSnake;

2. 无法进入遍历enemies的for循环的原因

看日志可以发现,击杀Snake后,只有遍历死亡列表的work outside for loops日志输出,没有遍历敌人列表的work insade enemy for loop日志,说明creator.getEnemies()返回的列表在击杀后为空/遍历提前终止,常见原因如下:

  • 你在碰撞回调中直接把击杀的Snake从enemies列表中移除了:Box2D物理步执行过程中修改游戏对象集合,会触发ConcurrentModificationException,即使没有抛出异常,也会导致遍历集合的逻辑提前中断,没有输出后续日志。
  • 你修改deadEnemiesList和遍历deadEnemiesList的时机冲突:比如在遍历enemies的过程中同时修改deadEnemiesList的长度,导致内层循环判断i < creator.getDeadEnemiesList().size()直接不满足,跳过内层逻辑。
修复建议
  • 所有和Box2D相关的对象修改、列表修改操作,都不要直接在碰撞回调中执行,先把要删除的对象引用存入临时的死亡列表,等world.step()执行完毕后,再在主update的安全位置统一处理删除逻辑。
  • 不要用System.identityHashCode作为对象匹配的标识,直接存Snake对象的引用到死亡列表,避免哈希冲突、对象被回收后哈希复用的问题。
  • 删除对象时不要直接在增强for循环遍历的原集合上执行删除操作,可以先遍历把要保留的对象存入新列表,再替换原列表,或者用迭代器的remove()方法执行删除。

内容的提问来源于stack exchange,提问作者pga2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:36:04