为了通过考核,我从两个星期前开始筹划游戏设计。经过两个星期的各种问题的出现与解决,我终于可以看到成品了。当我实际运行的时候,看到屏幕上出现由我亲手制造的游戏时,我超多开心。
但是在我尝试进行游戏操作时,却发现控制台抛出了一个异常,经过我反复的测试和对代码的审视,依旧无法发现异常的根源,而且这个异常神出鬼没,有时候刚开始玩就突然蹦出来,有时候玩一会才会出现。
我很懵逼,于是就去查阅资料,找关于这个抛出的异常的解释。
经过查阅后,我发现这个异常是在向数组内添加元素时抛出的。经过仔细的查阅,我终于发现了这个异常出现的原因:在它被迭代器历遍的时候对数组进行了修改。
因为我的游戏有两个线程,一个负责游戏逻辑( loop() 方法),一个负责绘制图( paint() 方法)。
当我进行鼠标点击时,就会添加一个子弹对象到一个数组里,游戏逻辑线程会历遍这个数组,并把里面的对象进行位置的更新。
这样一来,bug就产生了,有时候游戏逻辑正在历遍保存子弹对象的数组,正好我点击了一下屏幕,导致向它添加了元素,从而出现了异常。
为什么迭代器会抛出异常呢?是因为迭代器为了迭代数据的准确性,每次获取迭代的下一个元素时,会访问其容器对象的一个整数类型的成员变量。这个变量保存了对容器操作的次数,迭代器在开始迭代时会先将这个数值保存在自己的对象中去,一旦迭代时发现两者不对应,就会报错。
既然我知道异常产生的原因,自然就能想到办法去解决他。
有两种方法:
1.直接在迭代器中进行增删操作,这样不会影响其对应容器的数据,但是这种方法需要每次迭代开始时获取迭代器,有些麻烦,而且并不能保证100%的不会抛出异常,所以舍弃。
2.新建两个列表作为添加队列,并且新建一个布尔类型的成员变量,当这个布尔值为false时使用第一个列表接收新添加的元素,为true时用另一个。并且在历遍前,先把这个布尔值设为跟原来相反的值use0 = !use0
然后通过需要历遍的数组.addAll(当前不使用的那个队列数组)
添加进去,之后通过当前不使用的数组.clear()
进行清空,最后进行历遍。
网友评论