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

HTML5 2D 游戏开发 Sprites(5)将 sprites 合并到游戏循环中

HTML5 2D 游戏开发 Sprites(5)将 sprites 合并到游戏循环中

将 sprites 合并到游戏循环中回顾一下本系列第二篇文章(参阅其  小节),Snail Bait 中几乎所有水平运动都是平移 Canvas 2D 上下文的结果。Snail Bait 总是将大多数 sprite 绘制在同一水平位置,表面上的水平运动完全是平移的结果。大多数 Snail Bait 的 sprite 与游戏平台同时水平移动,如清单 15 所示:
清单 15. 更新 sprite 位移
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
38
39
40
SnailBait.prototype = {
   draw: function (now) {
      this.setPlatformVelocity();
      this.setTranslationOffsets();

      this.drawBackground();

      this.updateSprites(now);
      this.drawSprites();
   },

   setPlatformVelocity: function () {
      // Setting platform velocity was discussed in the second article in this series

      this.platformVelocity = this.bgVelocity * this.PLATFORM_VELOCITY_MULTIPLIER;
   },

   setTranslationOffsets: function () {
      // Setting the background translation offset was discussed
      // in the second article in this series

      this.setBackgroundTranslationOffset();
      this.setSpriteTranslationOffsets();
   },
   
   setSpriteTranslationOffsets: function () {
      var i, sprite;

      this.spriteOffset += this.platformVelocity / this.fps; // In step with platforms
   
      for (i=0; i < this.sprites.length; ++i) {
         sprite = this.sprites;
      
         if ('runner' !== sprite.type) {
            sprite.offset = this.platformOffset; // In step with platforms
         }
      }
   },
   ...
};




draw() 方法为所有 sprite(除了跑步小人)设置平台速率以及平移位移。(跑步小人的水平位置是固定的,不会随着平台的移动而移动。)
设置平移位移以及绘制背景之后,draw() 方法使用 updateSprites()  和 drawSprites() 更新并绘制游戏 sprite。这些方法如清单 16 所示:
清单 16. 更新和绘制 sprite
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
SnailBait.prototype = {
   ...
   updateSprites: function (now) {
      var sprite;
   
      for (var i=0; i < this.sprites.length; ++i) {
         sprite = this.sprites;

         if (sprite.visible && this.spriteInView(sprite)) {
            sprite.update(now, this.fps);
         }
      }
   },
   
   drawSprites: function() {
      var sprite;
   
      for (var i=0; i < this.sprites.length; ++i) {
         sprite = this.sprites;
   
         if (sprite.visible && this.spriteInView(sprite)) {
            this.context.translate(-sprite.offset, 0);

            sprite.draw(this.context);

            this.context.translate(sprite.offset, 0);
         }
      }
   },
   
   spriteInView: function(sprite) {
      return sprite === this.runner || // runner is always visible
         (sprite.left + sprite.width > this.platformOffset &&
          sprite.left < this.platformOffset + this.canvas.width);   
   },




当 sprite 不在视野范围内时Snail Bait 最终版本有一个游戏场,其宽度是游戏画布的 4 倍(宽度是任意的,可以更宽)。在任何给定时间内,Snail Bait 背景的四分之三都不在视野范围内。因此不需要更新或绘制这四分之三背景中的 sprite,Snail Bait 也不需要这样做。严格地说,绘图时不需要排除那些 sprite,因为 Canvas 上下文会排除它们。

updateSprites() 和 drawSprites() 对所有游戏 sprite 都可进行迭代,然后分别更新和绘制 sprite,但只有 sprite 是可见的,或者出现在目前显示的画布中。
在绘制 sprite 之前,drawSprites() 方法使用 setTranslationOffsets() 方法中计算的 sprite 位移来平移背景,然后将背景平移回原始位置,使 sprite 看起来像是在进行水平运动。
返回列表