Pang游戏箭支异常生成致崩溃问题排查求助
问题分析与解决方案
你遇到的程序崩溃问题,核心是遍历集合时直接修改集合(添加/删除元素)导致的索引错乱,再加上气泡数量无限制指数级增长,最终引发内存耗尽或循环异常。咱们一步步拆解问题并解决:
核心问题点
遍历集合时的索引错乱:
不管是bubblesArray还是arrowArray,你在普通正序for循环里直接调用remove(),会让集合大小动态变化——比如删除bubblesArray.get(i)后,后面的元素会前移到i的位置,但循环的i还会自增,直接跳过这个元素;箭数组的遍历也存在同样的越界或跳元素问题。气泡数量爆炸式增长:
每次击中气泡时numberOfBubble *=2,几次击中后气泡数量会指数级飙升,很快耗尽内存或者让循环执行时间过长,直接导致程序崩溃。箭支移除的逻辑冗余:
if(arrowArray.size()>=0)这个判断完全多余(集合大小不可能小于0),而且移除箭后没有处理索引偏移,容易引发后续遍历异常。
修正后的代码示例
1. 修复集合遍历与修改逻辑
遍历需要修改的集合时,推荐用倒序遍历,这样删除元素后不会影响未遍历到的元素索引:
// 倒序遍历气泡数组,避免删除元素后索引错乱 for (int i = bubblesArray.size() - 1; i >= 0; i--) { Bubbles currentBubble = bubblesArray.get(i); currentBubble.move(); currentBubble.checkBorders(); currentBubble.display(); // 倒序遍历箭数组 for (int j = arrowArray.size() - 1; j >= 0; j--) { Arrow currentArrow = arrowArray.get(j); currentArrow.shoot(); currentArrow.display(); // 移除超出屏幕的箭 if (currentArrow.getPosYArrow() + currentArrow.getHeightArrow() < 0) { arrowArray.remove(j); continue; // 跳过后续判断,处理下一支箭 } // 检查箭是否击中气泡 if (currentBubble.checkHitArrow(currentArrow)) { timesHit += 1; // 限制新气泡数量,避免指数爆炸(比如最多生成2个) int newBubbleCount = Math.min(2, numberOfBubble); numberOfBubble = newBubbleCount; // 移除击中的箭 arrowArray.remove(j); // 生成带随机偏移的小气泡,避免重叠 bubbleWidth = bubble.width / 2; bubbleHeight = bubble.height / 2; bubble.resize(bubbleWidth, bubbleHeight); for (int k = 0; k < newBubbleCount; k++) { float offsetX = (float) Math.random() * 50 - 25; float offsetY = (float) Math.random() * 50 - 25; bubblesArray.add(new Bubbles( currentBubble.getPosXBubbles() + offsetX, currentBubble.getPosYBubbles() + offsetY, bubble )); } // 移除被击中的气泡 bubblesArray.remove(i); break; // 跳出箭循环,处理下一个气泡 } } }
2. 按键发射箭的代码(无需修改)
void keyPressed() { if (key == ' ') { arrowArray.add(new Arrow(arrow, p.getPosXPlayer() + p.getWidthPlayer()/2, p.getPosYPlayer())); printArray(arrowArray); } }
额外优化建议
- 限制气泡最小尺寸:当气泡缩小到一定程度后,击中不再生成新气泡,避免无限分裂。
- 添加调试打印:可以在循环中偶尔打印
bubblesArray.size()和arrowArray.size(),观察数量变化,方便排查问题。 - 使用迭代器遍历:如果倒序遍历不习惯,也可以用
Iterator进行安全遍历删除,比如:Iterator<Bubbles> bubbleIter = bubblesArray.iterator(); while (bubbleIter.hasNext()) { Bubbles b = bubbleIter.next(); // ... 处理逻辑 if (需要删除) { bubbleIter.remove(); // 安全删除,不会导致索引问题 } }
内容的提问来源于stack exchange,提问作者Mante
相关产品推荐
相关产品推荐

