3.2 第二步:用canvas元素绘图
引擎所需的update及draw函数已经写好了,而且游戏也已经可以接受玩家的按键操作,并将相关信息打印到控制台了。然而本书却还没有讲到canvas的用法,在开发HTML5游戏时,该元素可以说是最为重要的HTML5元素。本步骤将通过canvas来绘制游戏背景。
对于初次接触canvas的开发者来说,采用atom.js来学习canvas是非常合适的,因为此引擎几乎没有改动这个元素。canvas的核心部分其实是一套相当简单的API,而其他游戏框架一般都会覆写其中的绘制方法,并将某些功能抽象出来。程序清单3.5展示了atom.js引擎是如何操作canvas元素的。由这段代码可知,经atom引擎封装过的canvas元素与原生的canvas用起来没有任何差别。
程序清单3.5 atom.js引擎在封装canvas元素时所使用的代码
想要基于canvas来绘制图像,就必须执行上面这两行重要的代码。第一行代码会在html文件中寻找首个canvas元素,并将其赋给atom.canvas。第二行定义了一套绘制二维图形所用的接口。调用getContext方法时,也可以传入另外一个参数值,那就是experimental-webgl,若想获取三维绘图接口(3-D context),则使用此选项。下面还有几行代码是绑定鼠标事件的,没有写在上述程序清单中。
提示
三维绘图接口相当复杂,若是想讲清楚如何用这套接口来实现二维绘图接口所具备的对应功能,那恐怕需要一两本专著才行。总之,二维游戏依然很流行,而且开发者并不需要具备太多的编程及图形学知识,就能制作出此种游戏。很多游戏都可以用二维方式呈现出来,比如本书所讲的全部游戏都是二维的,不仅如此,当前许多主流游戏大作也是二维的,如《Paper Mario》 、《Super Smash Brothers》 、《Street Fighter》 等,这说明二维绘图技术仍然非常有用。若是对三维绘图感兴趣,可以查阅附录C,从中找出深入研究所需的参考资料。
既然atom引擎已经把canvas元素及其二维绘图接口给我们准备好了,那么现在就开始绘制吧。用程序清单3.6中的代码替换掉game.js文件里的draw方法。
程序清单3.6 绘制背景
首先,使用beginPath函数新建一条路径。在调用绘图函数之前,最好先调用此函数。否则,上一次绘制时所用的形状会干扰到后续绘制。接下来,将context的fillStyle属性设为蓝色。其后那行代码,通过fillRect来填充canvas的上半部分。fillRect的四个参数分别表示矩形左上角的x坐标、y坐标,以及矩形的宽度和高度。接下来,再次调用fillStyle,将颜色设为黄色,为绘制太阳做准备。后面的arc方法用来定义代表太阳的那个圆形,其参数分别为:圆心x坐标(距离画面左边界140像素)、圆心y坐标(在画面中线稍微偏上的位置)、半径(90像素)、起始角(以弧度为单位,360度化为弧度就是2*pi)、终止角(0)。用arc将圆形确定好之后,调用fill方法来完成真正的绘制操作。最后两行代码采用与绘制天空时相似的办法来绘制地面。请记住,在绘制图形时,后画的会盖掉先画的。利用这一点,我们就可以先画太阳,然后再画地面了,若不这么做,那就比较麻烦了,需要绘制出地面之上的那个不规则形状。
提示
许多程序库与游戏引擎(比如第4章用到的easel.js)都自己实现了一些便捷方法,使开发者调用起来更加方便,比方说,只需要给出半径以及横纵坐标即可画出圆形。此外,它们通常不像本例这样,把描述图形与渲染图形的代码放在两个步骤中分开执行,而是只需要一个步骤即可。后续章节会介绍许多封装程度较高的绘制方式。
把绘制背景所用的draw方法修改好之后,用浏览器打开index.html,就会看到如图3.1所示的画面了。
图3.1 绘制好的游戏背景