Canvas在超级玛丽游戏中的应用

网站建设3年前发布
17 0 0

在上一篇文章中, 我们基于 DOM 体系构建了超级玛丽。,线上体验地址:,canvas 标签可以让我们能够使用 JavaScript 在网页上绘制各种样式的图形。要访问实际的绘图接口, 首先我们需要创建一个上下文 (context), 它是一个对象, 提供了绘图的接口。目前有两种广受绘图的样式: 用于二维图形的”2d“以及通过OpenGL接口的三维图形的webgl。,比如, 我们可以使用 <canvas /> DOM 元素上的 getContext方法创建上下文。,我们绘制了一个宽度和高度都为 400 像素的黄色正方形, 并且其左上角顶点处的坐标为 (10, 10)。canvas 的坐标系(0, 0) 在其左上角.,在画布的接口中, fillRect 方法用于填充矩形。fillStyle 用于控制填充形状的方法。比如,strokeStyle 属性与 fillStyle 属性类似, 但是 strokeStyle 作用与描边线的颜色。线条的宽度由 lineWidth属性决定。,比如我想绘制一个边框宽度为 6 的黄色正方形。,路径是很多线条的组合。如果想要绘制各种各样的形状, 我们会频繁用到 moveTo 和 lineTo 两个函数。,moveTo 表示我们当前画笔起点的位置, lineTo 表示我们画笔从起点到终点的连线。以上代码执行后就是如下所示:,当然我们可以为线条绘制的图形进行填充。,在计算机图形学中, 通常需要对矢量图形和位图图形进行区分。矢量图形是指: 通过给出形状的逻辑来描述指定的图片。而位图图形是指使用像素数据, 而不指定实际形状。,canvas 中的 drawImage 方法允许我们将像素数据绘制到画布上。像素的数据可以来自于元素或者另外一个画布。,drawImage 支持传递 9 个参数, 第 2 到 5 个参数表明源图像中被复制的 (x, y, 高度, 宽度), 第 6 到 9 个参数给出被复制的图像在 canvas 画布上的位置以及宽高。,下图是玛丽多个姿势的汇总图, 我们使用 drawImage 先让他能够正常跑起来。,我们需要大致截取玛丽的大小, 通过 cycle 锁定玛丽在动画中的位置。在合成中, 我们只需要让前面 8 个动作循环播放即可实现玛丽的一个奔跑动作了。,现在我们已经可以让玛丽朝着右边跑了, 但是在实际的游戏中 玛丽是可以左右跑的。这里的话 有两个方案: 1. 我们再绘制一组朝着左边跑的组合图 2. 控制画布反过来绘制图片。第一种方案比较简单, 因此我们就选择第二种比较复杂一点的方案。,canvas 中可以调用 scale 方法按照比例尺调整然后绘制。此方法有两个参数, 第一个参数用于设置水平方向比例尺, 另外一个设置垂直方向的比例尺。,上面是对 scale 的简单应用。我们调用了 scale 使得圆的水平方向被拉伸了 3 倍, 垂直方向被缩小了 0.5 倍。,如果 scale 中的参数为负数 - 1 时, 在 x 位置为 100 的位置绘制的形状最终会被绘制到 - 100 的位置。因此为了转化图片, 我们不能仅仅在 drawImage 的之前调用 ctx.scale(-1, 1) , 因为在当前画布中是看不到转化后的图片的。这里有两种方案: 1. 调用 drawImage 的时候设置 x 为 - 50 的时候来绘制图形 2. 通过调整坐标轴, 这种做法的好处在于我们编写的绘图不需要关心比例尺的变化。,我们采用 rotate 来渲染绘制的图形, 并且通过translate方法移动他们。,我们的思路大概是这样子:,如果我们在正 x 处绘制三角形, 默认情况下它会位于 1 位置。调用 flip 函数后首先进行右边平移, 得到三角形 2. 然后通过调用 scale 进行翻转得到三角形 3。最后再次通过调用 translate 方法, 对三角形 3 进行平移得到三角形 4, 也就是最后我们想要的图案。,看, 他已经被我们转过来了!,在上一篇文章中, 我们所有的元素都是直接通过 DOM 来显示的, 那么在我们学完 canvas 之后, 我们可以使用 drawImage 来绘制元素。,我们定义 CanvasDisplay 替换掉之前的 DOMDisplay, 除此之外, 我们新增了跟踪自己视图窗口, 他可以告诉我们当前正在那部分的关卡, 此外我还新增了 flipPlayer 属性, 这样即使玛丽不动, 它仍然面对着它最后移动的方向。,syncState 方法首先计算新视图窗口, 然后在适当的位置绘制。,在之前的更新相反, 我们现在必须在每次更新的时候, 重新绘制背景。因为画布上的形状只是像素, 所以我们在绘制完后没有好的方法来移动或者删除他们。因此更新画布的唯一方法是清除并且重绘。,updateViewport方法跟 scrollPlayerIntoView 方法一样。它会检查玩家是否太靠近视图边缘。,当我们成功或者失败的时候, 我们需要清除当前场景, 因为如果失败了, 我们需要重新来, 如果成功了, 我们需要删除当前场景, 重新绘制一个新的场景。,接下来, 我们需要绘制墙壁和熔岩。首先, 我们遍历当前视图中所有的墙壁和砖头。我们使用 sprites.png 绘制所有非空的墙砖 (墙、熔岩、金币)。在提供的素材中, 我们墙壁是 20px * 20px, 偏移量是 0,熔岩也是 20px * 20px, 但是偏移量是 20px.,最后我们需要绘制玩家的模型。,在前面的 8 个图像中, 是一个完整的运动过程。第九个画像是玩家静止不动的状态, 第 10 个画像是玩家在离地时候的状态。因此当玩家移动的时候, 我们需要每 60ms 切换一帧。当玩家不动的时候绘制第九个画面, 当玩家跳跃的时候绘制第十个画面。,对于不是玩家的模型, 我们根据对应模型的偏移量找到对应的图像。,ok! 至此, 我们的超级玛丽就改造完成, 后面会陆续加上一些其他的地图元素 ~ 有兴趣的小伙伴可以关注一下哦 ~,

© 版权声明

相关文章