首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

HTML5 2D 游戏开发 图形和动画(1)

HTML5 2D 游戏开发 图形和动画(1)

图形和动画是任何视频游戏最根本的方面,所以在本文中,我将从 Canvas2D API 的简要介绍开始,对 Snail Bait 的中央动画的实现进行讨论。在本文中,您将学习如何:
  • 将图像和图形基元绘制到画布上
  • 创建流畅的、无闪烁的动画
  • 实现游戏循环
  • 以帧数每秒为单位监视动画的速度
  • 滚动游戏的背景
  • 使用视差来模拟三维效果
  • 实现基于时间的运动
本文中所讨论的代码的最终结果如图 1 所示:
图 1. 滚动背景并监视帧速率背景和平台水平滚动。这些平台在前景中,所以它们的移动明显快于背景,这样会形成一个温和的视差效果。在游戏开始时,背景由右至左滚动。在结束某个级别时,背景和平台开始逆转方向。
在开发的这个阶段,跑步者不动。此外,游戏还没有经过碰撞检测,所以当跑步者的下面没有平台时,她会漂浮在半空中。
最后,游戏画布的上方和左侧的图标会显示剩余生命的数量(如  所示)。目前,该游戏会在这个位置上显示当前动画速度(以帧数每秒为单位)。
即时模式图形Canvas 是一个即时模式 图形系统,这意味着它会即时绘制您指定的内容,然后即时忘记。可伸缩矢量图形 (Scalable Vector Graphics, SVG) 等其他图形系统实现了保留模式 图形,这意味着它们会保存一个将要绘制的对象的列表。由于不会因保存显示列表而产生开销,所以 Canvas 的速度比 SVG 更快一些;但是,如果您想保存一个用户可以操作的对象列表,则必须自己在 Canvas 中实现该功能。

在继续后面的操作之前,您可能想尝试创建一个这类游戏,因为它就在  里;如果您创建了这样的游戏,就会更容易理解相关的代码。(请参阅 ,获得本期的 Snail Bait 实现。)
HTML5 Canvas 概述Canvas 2D 上下文提供了一个广泛的图形 API,让您可以在平台视频游戏中实现文本编辑器中的一切。在我撰写这篇文章的时候,该 API 包含了超过 30 个方法,但 Snail Bait 只使用了其中的极少数,如表 1 所示:
表 1. Snail Bait 使用的 Canvas 2D 上下文方法方法描述drawImage()您可以在画布的某个特定位置上绘制全部或部分图像,也可以绘制另一个画布或来自 video 元素的一个帧。save()在堆栈上保存上下文属性。restore()将上下文属性移出堆栈,并将它们应用于上下文。strokeRect()绘制一个未填充的矩形。fillRect()填充一个矩形。translate()平移坐标系。这是一个很强大的方法,在许多不同场景中都很有用。Snail Bait 中的所有滚动都是利用这一个方法调用来实现的。
基于路径的图形与 Apple 的 Cocoa 和 Adobe 的 Illustrator 类似,Canvas API 也是基于路径的,这意味着您可以先创建一条路径,然后描画或填充这条路径,在画布上绘制图形基元。strokeRect() 和 fillRect() 方法分别是描画或填充矩形的便捷方法。

除平台之外,Snail Bait 中的所有内容都是一个图像。背景、跑步者以及所有好人和坏人都是游戏使用 drawImage() 方法绘制的图像。
最终,Snail Bait 将使用 spritesheet(单个图像包含游戏的所有图形),但现在,我对背景和跑步者分别使用不同的图像。我使用  所示的函数绘制跑步者:
清单 1. 绘制跑步者
1
2
3
4
5
function drawRunner() {
   context.drawImage(runnerImage,                                        // image
                     STARTING_RUNNER_LEFT,                               // canvas left
                     calculatePlatformTop(runnerTrack) - RUNNER_HEIGHT); // canvas top
}




drawRunner() 函数将三个参数传递给了 drawImage():一个图像、左侧坐标和顶部坐标,将在画布的这个位置上绘制图像。左侧坐标是一个常数,而顶部坐标由跑步者所驻留的平台决定。
我以类似的方式绘制背景,如清单 2 所示:
清单 2. 绘制背景
1
2
3
function drawBackground() {
   context.drawImage(background, 0, 0);
}




多用途的  方法您可以使用 Canvas 2D 上下文的 drawImage() 方法在画布内的任何地方绘制一个完整的图像,或图像内的任何矩形区域,有选择地沿着路线缩放图像。除了图像外,您还可以利用 drawImage() 绘制另一个画布或一个 video 元素当前帧的内容。这只是其中一个方法,但 drawImage() 还有助于便利地实现有趣的或者难以实现的应用程序(如视频编辑软件)。

中的 drawBackground() 函数在画布的 (0,0) 绘制背景图像。稍后,我会在本文中修改该函数,以便滚动背景。
绘制平台(它们不是图像)需要更广泛地使用 Canvas API,如清单 3 所示:
清单 3. 绘制平台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var platformData = [
    // Screen 1.......................................................
    {
       left:      10,
       width:     230,
       height:    PLATFORM_HEIGHT,
       fillStyle: 'rgb(150,190,255)',
       opacity:   1.0,
       track:     1,
       pulsate:   false,
    },
    ...
],
...

function drawPlatforms() {
   var data, top;

   context.save(); // Save the current state of the context

   context.translate(-platformOffset, 0); // Translate the coord system for all platforms
   
   for (var i=0; i < platformData.length; ++i) {
      data = platformData;
      top = calculatePlatformTop(data.track);

      context.lineWidth   = PLATFORM_STROKE_WIDTH;
      context.strokeStyle = PLATFORM_STROKE_STYLE;
      context.fillStyle   = data.fillStyle;
      context.globalAlpha = data.opacity;

      context.strokeRect(data.left, top, data.width, data.height);
      context.fillRect  (data.left, top, data.width, data.height);
   }

   context.restore(); // Restore context state saved above
}




中的 JavaScript 定义一个名称为 platformData 的数组。该数组中的每个对象代表着描述一个独立平台的元数据。
drawPlatforms() 函数使用 Canvas 上下文的 strokeRect() 和 fillRect() 方法来绘制平台矩形。这些矩形的特征存储在 platformData 数组内的对象中,用于设置上下文的填充风格和 globalAlpha 属性,该属性设置您之后在画布上绘制的任何图形的不透明度。
调用 context.translate() 将画布的坐标系(如图 2 所示)在水平方向平移指定数量的像素。该平移和属性设置是临时的,因为这些操作是在 context.save() 和 context.restore() 调用之间执行的。
图 2. 默认的 Canvas 坐标系默认情况下,坐标系的原点位于画布的左上角。您可以使用 context.translate() 移动坐标系的原点。
我会在  中讨论如何使用 context.translate() 滚动背景。但现在,您几乎已经知道了实现 Snail Bait 需要了解的与 HTML5 Canvas 有关的一切内容。在本系列的其余部分中,我将侧重于 HTML5 游戏开发的其他方面,从动画开始。
返回列表