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

简介:

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

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

图3.1 滚动背景和监控帧频


690ec5a27259ea863c6f7868fbd7bee4ad45c154

在开发平台上,跑步小人并没有移动。而且游戏也没有冲突检测,实际上,跑步小人是浮在半空中的,在她脚下并没有平台。
最后版本的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元素的二维绘图环境方法


b9775649412f5b437226cccf9964d03107b0819a


d7d06ef8d374a10badd0f9081a1cf0ecb0afed7c

方法描述
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元素二维绘图环境属性


e1c6c20563f5f7e63416d078781a6019273720d6

属性描述
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 绘制背景(初始版本)


0ec326078ef5f98e741c8e5c3149ab084b3a88b0

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


b65eceff661f8df7c571c71d90227199289cdb74

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


ce0835994e4241fc969bbaff6424cbda527d7f56


f1c9ebd265f9eebf81061478a7e75fb9d4d2510f

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

图3.2 平台轨迹


ce7b65248c6226e1a0f2381b117e0027a4388e84

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游戏的代码做任何改变。

相关文章
|
8月前
|
移动开发 前端开发 Shell
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
|
17天前
超帅的主页命令滚动HTML源码
超帅的主页命令滚动HTML源码,超级好看的!作为网站跳转页还是挺不错的! 仅KB大小,喜欢的老铁可以下载收藏!
17 1
超帅的主页命令滚动HTML源码
|
2月前
|
容器
HTML标签之文字滚动效果(跑马灯效果)
HTML标签之文字滚动效果(跑马灯效果)
|
4月前
|
前端开发 JavaScript 定位技术
Flutter vs 前端 杂谈:SliverAppBar、手动实现Appbar、前端Html+JS怎么实现滚动变化型Appbar - 比较
Flutter vs 前端 杂谈:SliverAppBar、手动实现Appbar、前端Html+JS怎么实现滚动变化型Appbar - 比较
35 0
|
7月前
简单的 HTML 代码实现文字滚动效果
简单的 HTML 代码实现文字滚动效果
36 0
|
前端开发 JavaScript
开源超美css动态背景 可直接引入html文件使用 含注释、可更改
开源超美css动态背景 可直接引入html文件使用 含注释、可更改
309 0
开源超美css动态背景 可直接引入html文件使用 含注释、可更改
通过HTML+CSS+Javascript实现向下滚动滚动条出现导航栏并出现回到顶部按钮点击按钮回到顶部(一)...
通过HTML+CSS+Javascript实现向下滚动滚动条出现导航栏并出现回到顶部按钮点击按钮回到顶部(一)...
|
JavaScript 前端开发
【HTML背景的使用】
学习好一门语言贵在坚持之初识JavaScript🏹💁‍♂️!
57 0
【HTML背景的使用】
|
前端开发
HTML设置图片为页面背景
HTML设置图片为页面背景
HTML设置图片为页面背景
|
前端开发 JavaScript
酷炫一款动态背景+鼠标点击效果(HTML +js canvas)
前言 之前用于装饰个人的Hexo博客背景和点击事件,于是动手弄弄顺便学习学习,现在分享出来给有需要的人。 废话不多说 ,分享一款酷炫的页面动态背景 效果见( https://fivecc.cn )
261 1
酷炫一款动态背景+鼠标点击效果(HTML +js canvas)