如何修复FileWriter追加模式下无限写入分数的Bug?
问题分析与简单解决方案
你的问题根源非常明确:碰撞发生后,控制游戏循环的Timer没有停止,导致actionPerformed会被无限次触发,每次都会执行checkTouch。而碰撞后障碍物和主车的坐标不会变化,所以每次checkTouch都会检测到碰撞条件成立,重复调用writeScore,最终导致文件里全是重复的分数。
最简单的修复步骤
1. 保存Timer的引用
首先,你需要在类里保存Timer的实例引用,这样才能在碰撞时停止它。比如:
// 在你的游戏类中添加成员变量 private Timer gameTimer;
然后在初始化Timer的地方(比如构造函数里):
gameTimer = new Timer(16, this); // 假设你用的是16ms间隔(约60帧) gameTimer.start();
2. 修改checkTouch方法,碰撞后停止Timer并避免重复写入
修改后的checkTouch要做这几件事:
- 先判断如果已经不在游戏中,直接返回,避免无效检查
- 检测到碰撞后,立即停止Timer,切断后续的循环触发
- 找到第一个碰撞的障碍物后就退出循环,避免多次调用
writeScore
修正后的代码:
private void checkTouch() { // 游戏已经结束,直接返回,不用再检查碰撞 if (!inGame) { return; } for(Cars car : cars) { // 注意修正语法错误:cars.getX() → car.getX(),getCarPos_X → getCarPos_X() if(car.getX() == getCarPos_X() && car.getY() == getCarPos_Y()) { inGame = false; gameTimer.stop(); // 停止Timer,不再触发actionPerformed writeScore(); break; // 找到一个碰撞就退出循环,避免多次写入 } } }
3. 修复writeScore的空指针隐患
你的writeScore方法的finally块里,如果fw或bw初始化失败(比如文件无法打开),直接调用bw.close()会抛出空指针异常。可以修改成:
public void writeScore() { File scoresTxt = new File("scores.txt"); FileWriter fw = null; BufferedWriter bw = null; try { fw = new FileWriter(scoresTxt, true); bw = new BufferedWriter(fw); bw.write(scores + "\n"); } catch (IOException e) { e.printStackTrace(); } finally { try { // 先判断对象是否存在,再关闭 if (bw != null) { bw.flush(); bw.close(); } if (fw != null) { fw.close(); } } catch(IOException e) { e.printStackTrace(); } } }
为什么这样有效?
停止Timer后,actionPerformed就不会再被调用,checkTouch和writeScore也就不会重复执行,自然就不会出现无限写入分数的问题了。同时在checkTouch开头加!inGame的判断,是双重保险,防止意外情况。
内容的提问来源于stack exchange,提问作者Gipsy King
相关产品推荐
相关产品推荐

