3.3 第三步:绘制鼠洞

我们已经为这个“打地鼠”(whack-a-mole)类型的游戏绘制好背景了。下一步就该画鼹鼠钻出来的地方了。我们把这叫“鼠洞”。在绘制它之前,先把draw方法精简一下,请按照程序清单3.7来调整上个步骤中所写的那些绘制代码。

程序清单3.7 精简draw方法

原来draw函数里的代码现在都放到game.drawBackground的方法里了。draw函数调用这个方法来完成绘制。如果开始阅读本书前不太熟悉JavaScript,那你可能仍然不太明白draw函数里的this是什么意思。this的含义与其所处的运行环境相关,在game.draw函数中,this指的就是game对象。在编写JavaScript代码时,如果不清楚某个变量的含义,可以打开控制台,以此变量为参数调用console.log(),看看打印出来的信息,也许就会明白了。附录B详细讲解了开发者在遇到编程问题时可以采取的措施。

技巧

在不改变功能的前提下移动代码,就叫做重构。我们不可能一开始就把程序规划得很完美。在构建过程中,应该花些时间重新组织一下代码,不要使其变得一团糟。重构是个相当大的话题,有很多种重构的办法。一般来说,这几种代码应该重构:太过冗长的函数、太过庞大的文件、表意不清晰的函数名、设置了太多变量的函数,以及使用条件控制逻辑(比如if语句)过于频繁的函数。上述写法都会使游戏项目的代码难于维护,而且也不利于多人协作,所以,应该尽量通过重构来解决这些问题。

接下来,将程序清单3.8中的代码加入game.js,用以绘制鼠洞。这段代码定义了drawHoles方法,其中会画出四个圆形来表示鼠洞,同时还会画出表示按键的文本,玩家稍后可以按下键盘上对应的键来打鼹鼠。我们可以在draw函数里调用这个drawHoles方法。

程序清单3.8 绘制鼠洞

由于引擎能够保证在游戏循环的每一帧中,都去执行draw函数里的代码(这正是atom.js引擎的一项主要功能),所以,只需把绘制代码放在draw函数中,等着引擎来调用即可。为了绘制鼠洞,我们在draw函数里调用drawHoles方法,它接受三个参数。第一个参数是个数组,表示将要写在每个鼠洞下面的字母。第二个参数表示最左侧那个鼠洞的横向偏移量,第三个参数表示全部鼠洞的纵向偏移量。请注意,在一般的绘图系统中,左下角是原点,而在使用canvas来绘图时,y轴却在顶端,所以原点(0,0)位于左上角。

drawHoles函数在执行时会遍历holeLabels数组,以确定每个鼠洞的位置,并调用hole对象的draw函数来绘制它们,此函数将于稍后定义。game.hole对象先定义了一些属性,有的是字符串,有的是数字,然后再定义刚说的draw函数。想在这个draw函数里引用hole对象中的那些字符串和数字是非常简单的,只需调用“this.属性名”即可。在game.hole对象的draw函数里,大部分代码看上去应该都比较熟悉,因为它们与前面绘制太阳时所用的代码类似,只是最后两行不一样。在这两行代码中,第一行用context.font来设置文本大小及字型。第二行用context.fillText来绘制文本,此方法接受三个参数,分别表示待绘制的文本及其横、纵坐标。

编好上面这段代码后,用浏览器打开index.html文件,就会看到图3.2中的画面了。

图3.2 画好的鼠洞