《HTML5 2D游戏编程核心技术》——第3章,第3.1节滚动背景和监控帧频

    xiaoxiao2024-04-17  7

    本节书摘来自华章出版社《HTML5 2D游戏编程核心技术》一书中的第3章,第3.1节滚动背景和监控帧频,作者[美] 戴维·吉尔里,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

    第3章图形和动画是视频游戏的基础。能够绘制图形和图像是创造平滑的、不闪烁的动画最重要的技能之一,也是游戏开发人员必须要掌握的能力。动画会持续地绘制动画帧,一般每秒30~60次。这个速率称为动画帧速率。每一个动画帧如同连环画的一页,每帧几乎和上一帧一样,仅仅存在着微小的差别,这样就可以在游戏快速显示动画帧时,创造出运动的效果。更多有关连环画的内容请阅读3.2节。图3.1显示了一个单独的动画帧截图。这个游戏版本会保持这一状态到本章结束,图中显示了背景和平台从右向左滚动时的动画帧速率。平台在动画画面的前景,因此它们的移动速度要比背景快得多,从而产生了深度假象,这个假象也称为视差效应。

    图3.1 滚动背景和监控帧频

    在开发平台上,跑步小人并没有移动。而且游戏也没有冲突检测,实际上,跑步小人是浮在半空中的,在她脚下并没有平台。最后版本的Snail Bait游戏在canvas元素左上角的图标处将会显示剩余生命的数量。但是现在,Snail Bait游戏在该位置显示当前动画的帧速率。本章首先简单地介绍canvas元素的二维API,然后讨论Snail Bait游戏中一些重要动画的实现。在本章中,你将会学习以下内容:绘制canvas中的原始图形和图像(3.1节)创造平滑的、无闪烁的动画(3.2节)实现游戏主循环(3.3节)计算帧速率(3.4节)滚动游戏背景(3.5节)实现不受隐藏帧速率干扰的动画(3.6节)反转滚动方向(3.7节)绘制单个动画帧(3.8节)使用视差效应模拟三维空间(3.9节)在继续之前,你也许想试着完成本章图3.1显示的游戏版本,如果你做了尝试,会发现代码还是比较容易理解的。

    **立即模式图形系统**

    canvas元素是立即模式的图形系统,意味着当你提出要求时,它会立即绘制,然后立即忘记。其他图形系统,例如SVG,使用了保留模式的图形系统,也即绘制时会保留一系列将要绘制的对象。由于不需要维护显示列表,所以canvas元素运行速率要比SVG快。然而,如果你想获取一个用户可以操作的对象列表,你必须在canvas元素的绘图环境中自己完成该功能。

    canvas元素的双缓存机制

    之前的注意事项提到了canvas元素会立即绘制出你指定的内容,此处需要进一步解释。当浏览器调用Snail Bait游戏的animate()方法绘制当前动画帧时,canvas元素不是立即绘制出你指定的内容;相反,它会绘制一个后台canvas元素来代替当前的canvas元素。在animate()方法返回之后,浏览器通过一个图形操作,复制后台canvas元素的整个内容到屏幕上。这种技术,也称为双缓存技术,该技术能够让动画更加平滑,如果浏览器第一时间将图形绘制到canvas元素上,则不会有这样的效果。

    基于路径的图形系统

    像Apple的Cocoa和Adobe的Illustrator一样,canvas元素的API也是基于路径的,即通过创造路径来制作图元,然后顺序地绘制和填充该路径。strokeRect()和f?illect()方法分别可以很方便地绘制或填充矩形。

    HTML5 canvas元素是由Apple引进的

    在2004年,Apple在Webkit内核中添加了最终成为HTML5 canvas元素的相关内容。可以从http://en.wikipedia.org/wiki/Html5_canvas网页上了解到更多的相关内容。3.1 使用HTML5 canvas元素绘制图形和图像canvas元素的二维绘图环境提供了一个功能极为丰富的图形API,可以让你绘制从文本编辑器到平台视频游戏的任何内容。在写作本书时,这个API包含了超过30种方法,Snail Bait游戏大约只使用了其中三分之一,如表3.1所示。表3.1 canvas元素的二维绘图环境方法

    方法描述arc (x,y,radius, start-Angle,endAngle, coun-terClockwise) 为当前路径添加一个弧度。可以使用arc()方法给当前的路径添加一段圆弧,通过指定0~2π或(0°~360°)的值来确定圆弧的角度beginPath() 结束当前路径并开始一个新的路径drawImage (image, sx, sy, sw, sh, dx,dy, dw, dh) 在目标canvas元素(目的地)的指定位置绘制指定图像(源)的所有或者部分内容。实参中的s和d分别表示源和目的地,即sx代表source x,dh代表destination height,依此类推。除了图像之外,源也可以是视频或者其他canvas元素。目的地总是和上下文相关的canvas元素可以调用带有所有9个参数的drawImage()函数,也可以调用带有3个或者5个参数的函数,drawImage (image, sx, sy, sw, sh, dx,dy, dw, dh) 例如:drawImage (image, dx, dy)或者drawImage (image, dx, dy, dw, dh)。3个参数或者5个参数的版本会在canvas元素指定位置绘制出整个图像。5个参数的版本允许你通过设置图像的宽度和高度进行缩放。9个参数的drawImage()函数允许你绘制全部或者部分图像,并可以同时调节图像的大小f?ill() 使用当前填充风格填充路径内部,可以是颜色、图案或者过渡f?illRect (x, y, w, h) 使用当前填充风格填充矩形isPointInPath() 确定一个点是否位于当前路径中,路径可以是一个不规则的形状rect (x, y, w, h) 给当前路径添加一个矩形框restore() 恢复当前绘图环境的状态到上一次你调用save()时所存储的状态save() 存储绘图环境的状态。可以使用restore()函数恢复该状态。在调用save()和restore()之间做出的任何改变都是临时的stroke() 用当前的画笔样式绘制路径的轮廓,可以是颜色、图案或过渡strokeRect (x, y, w, h) 用当前的画笔样式绘制一个未填充的矩形translate (x, y) 平移坐标系统。这是一个强大的方法,可以在许多不同的情况下使用。Snail Bait游戏中的所有水平滚动都是通过调用该方法实现的

    canvas元素的二维绘图环境也有超过30种属性,但Snail Bait游戏仅使用了其中的少量属性,如表3.2所示。表3.2 Snail Bait游戏中使用的canvas元素二维绘图环境属性

    属性描述lineWidth 线条的宽度以及圆、矩形、圆弧和曲线的轮廓厚度f?illStyle 取值为任何有效的CSS颜色,例如rgb(0,0,0),#ffffff或者skyblue。用于填充形状。除了颜色之外,也可以指定过渡或者图案作为填充样式strokeStyle 任何有效的CSS颜色字符串,用于绘制形状轮廓或者线条。也可以指定过渡或者图案作为笔画样式,使其与填充样式保持一致globalAlpha 所有图形操作的不透明度,例如stroke(),f?ill()和drawImage(),但是要除去getImageData()和putImageData(),因为它们可以直接操作canvas元素的像素

    在Snail Bait游戏中,除了平台之外,其他所有内容都是图像。背景、跑步小人、好家伙和坏家伙都是drawImage()方法绘制的游戏图像。在最终完成的Snail Bait游戏版本中,Snail Bait游戏会使用sprite图像表单来存储游戏用到的所有图像,但在现阶段,我们仍会使用单独的图像来绘制背景和跑步小人。3.1.1 绘制背景Snail Bait游戏使用drawBackground()函数绘制背景。该函数的初始版本如程序清单3.1所示。程序清单3.1 绘制背景(初始版本)

    程序清单3.1中的drawBackground()函数会在canvas元素的(0,0)位置绘制背景图像。这个位置是将图像的左上角放到了canvas元素的绘图区域的左上角。在3.5节中,我们将修改这个函数,让背景可以水平滚动。3.1.2 绘制跑步小人第6章会介绍sprite对象,在这之前,Snail Bait游戏使用drawRunner()函数来绘制跑步小人,如程序清单3.2所示。程序清单3.2 绘制跑步小人

    drawRunner()函数向drawImage()函数传递了三个参数:一个图像源以及图像在canvas元素中绘制的左侧坐标和顶部坐标。左边的坐标是一个常数RUNNER_LEFT;drawRunner()函数是通过从跑步小人所在平台的上边缘坐标减去跑步小人的高度,来计算跑步小人顶部的坐标。函数减去跑步小人的高度使得跑步小人的脚站在平台上。你或许认为应该加上跑步小人的高度,而不是减去,但是canvas元素的坐标系是从顶部向底部增加的,因此如果要在canvas元素中向上移动一段距离,应该减少它的Y坐标值。3.1.3 绘制平台Snail Bait游戏的平台不是图像,因此绘制它们需要使用多个canvas元素的API,仅仅调用drawImage()函数是无法完成平台绘制的,如程序清单3.3所示。程序清单3.3 drawPlatforms()函数

    程序清单3.3中的JavaScript代码定义了一个名为platformData的队列。队列中的每一个对象都描述了一个单独的平台。这些平台包含诸如left、width、height、track等属性,这些属性涵盖了平台的位置信息以及外观信息。平台以水平轨迹移动,如图3.2所示。drawPlatforms()函数会遍历platformData数组,将数组中的每一个对象依次传递给drawPlatform()函数,该函数会计算平台的顶部位置,设置环境变量,并绘制出平台矩形。

    图3.2 平台轨迹

    drawPlatform()函数使用canvas元素绘图环境的strokeRect()和f?illRect()方法来绘制平台矩形。它使用存储在platformData数组中的矩形对象的特征,设置环境线条的宽度、画笔风格、填充样式等信息,并使用globalAlpha属性来设置平台的透明度。现在,你已经了解了所有用于编程实现Snail Bait游戏的canvas元素二维绘图环境的内容。本书接下来的章节将会聚焦HTML5游戏开发的其他方面,首先开始讲解动画。

    存储和恢复canvas元素绘图环境的属性

    当你设置canvas元素绘图环境的属性时,例如lineWidth或f?illStyle,设置操作的作用将是永久的,这意味着它们将会影响到接下来你在canvas元素绘图环境上执行的图形操作。为了让设置操作只是临时发挥作用,可以在save()方法和restore()方法之间完成图像绘制,这样就可以保存和恢复绘图环境的所有属性。

    保持sprite对象数据和创建sprite对象的代码分开

    Snail Bait游戏所有的图形对象(称为sprite对象)都是数据驱动的,也即Snail Bait游戏会通过包含sprite对象属性的数据对象来创建它们,例如left,top等属性,同platformData队列中的对象类似。sprite对象元数据提供了一个重要的解耦方式。例如,尽管Snail Bait游戏在静态队列中存储了sprite对象的元数据,但相同的元数据也可以由一个复杂的关卡生成器产生,这可以用于在游戏运行时,根据游戏状态生成游戏关卡。这样的关卡生成器不需要在创造sprite对象时对Snail Bait游戏的代码做任何改变。

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)