debug抵到人憔悴啊我了个去!

用cocos2d-html5重现一个示例的时候,总是出现各种诡异的显示bug。一开始不够重视,只是让自己的代码越来越接近原本的示例代码,但眼看我整个复制粘贴都不能重现,我就急了。
示例是cocos2d自己的大sample,有一部分framework的,我不能全复制,所以我开始还是怀疑框架中某部分我没有做到。但是朝这个思路走怎么也走不通,甚至一点点苗头都没有,我折磨得肚子都疼了。
真的,因为心急而导致如此明显的生理反应,这已经是多少年不见了……搞不好是第一次遇到这种情况(汗)。
好,你不仁,莫怪我不义。于是开始逐行深入地跟踪,对照着同时单步调试可以正确运行的示例和我的程序。
突然!我发现在让程序停在某个断点处再重新执行的话,断点后面的部分就可以正常显示了!我靠,还有这种bug?我最先想到的是多线程bug,但是在想不通这框架哪里需要用到多线程呢。一边琢磨,一边拿到firefox下试了试,同样是断点后的程序执行正常,排除了跨平台bug的可能。有这个线索就好办了,我一行一行移动这个断点,找到一个关键行“default_item.setSize(default_button.getSize());”。调试时发现getSize值正确,把断点下在下一行,set的结果为0。这样看来是setSize比较可疑吧。一看,setSize果然不是单纯的赋值操作,里面根据几个flag,行为会完全改变的!其中有一个根据this._running来改变行为的逻辑,我想了想,是不是多线程,让这个_runnding时false时true,所以我得到的结果时好时坏呢?朝着这个方向又调试了半天,无果。至此,我调试中作出的每一个预测都落空了。我终于对自己失去了信心,开始无脑单步调试。最后发现getSize的返回值是0(刚才为什么不是0!欺骗我的感情!)。再进一步,是图片取到的size是(0,0)。到这里,我总算是正确理解到问题的原因了。回头想想,确实,helloworld那种只有三张图片的程序里都有一个resource.js文件,还正儿八经的预读了一下,看来预读是很有必要啊。再细追踪了几步,确实是取的图没有在cache里,从这里开始和示例程序的执行流程不同了。这就可以了,不跟踪了,三两下填上预读列表,再试,成功。
其实我之前所在的C++3D射击游戏项目组一直是异步读取图片的(我估计大型游戏都需要异步读取资源)。明明有轮询资源读好了没读好了没的模式的编程经验,自己遇到时却完全没有想到这个原因。反省了一下,应该是我平时自己写程序规模都太小,全是同步读取资源,这么多年思维定势严重了。得赶紧找个大项目参与一下,换换脑子了。

Comments

  1. 异步加载资源其实端游中很少见。因为必须多线程,加大了开发难度。而且硬件发展很迅速,软件内性能的压榨越来越不受重视,预加载的依然比较多。
    另外DEBUG一直是程序最重要的工作之一,必须学会很多DEBUG技巧以及拥有良好的耐心。

回复 kira 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注