精华游戏算法整理_整理游戏

精华游戏算法整理

HTML5 2D游戏开发系列的上一部分文章结尾,Snail Bait处于可玩但原始的状态。 在这一期的最后一部分中,我将向您展示如何将Snail Bait从该状态带到最终版本,如图1所示的精美游戏:

图1. Snail Bait的最终版本
Snail Bait最终版本的屏幕截图

在本文中,您将学习如何:

  • 用CSS渐变替换背景图片。
  • 微调游戏和图形。
  • 保持得分。
  • 监视帧速率并在游戏运行缓慢时显示警告。
  • 实现摇动背景的特殊效果。
  • 追踪生活。
  • 生活之间的过渡。
  • 显示积分。
  • 鸣叫分数。
  • 将游戏部署到服务器。

请参阅下载以获取完整的最终Snail Bail代码。

用CSS渐变替换背景图片

在当前状态下,Snail Bait在游戏启动时会加载三个图像:网站的背景,游戏的背景和游戏的精灵表。 在最终版本中,我通过消除网站背景并将游戏的背景并入精灵表中,将其缩小为一张图像。 为了消除网站背景,我使用CSS3线性渐变创建背景,如图2所示:

图2. Snail Bait的背景
游戏背景的屏幕截图

清单1中是背景CSS:

清单1. Snail Bait的背景(摘自game.css)
body {
   /* Background from CSS3 Patterns Gallery by Anna Kassner */

   background-color: #6d6aff;

   background-image:
      repeating-linear-gradient(120deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, 
                                transparent 1px, transparent 60px),

      repeating-linear-gradient(60deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, 
                                transparent 1px, transparent 60px),

      linear-gradient(60deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, 
                      rgba(0,0,0,.1) 75%, rgba(0,0,0,.1)),

      linear-gradient(120deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, 
                      rgba(0,0,0,.1) 75%, rgba(0,0,0,.1));

   background-size: 70px 120px;
}
...

CSS3 Patterns Gallery包含CSS片段,您可以复制这些CSS片段以创建各种背景(请参阅参考资料 )。 图3显示了画廊背景的一部分:

图3. CSS3模式库
部分CSS3模式库的屏幕截图

我从CCC3模式库下载了清单1中CSS,以在Snail Bait中使用。 我选择了Argyle模式并将背景颜色更改为蓝色阴影。

微调游戏和图形

游戏开发人员在实施游戏时会不断调整游戏玩法和图形。 对于Snail Bait的最后一轮微调,我:

  • 更改平台的位置和大小。
  • 将跳动行为添加到所有Ruby和硬币。
  • 将蜗牛移到游戏结束。
  • 实施一个引爆按钮。
  • 更换硬币。

这些变化中的大多数在图4中显而易见,该图显示了游戏即将结束时的蜗牛射击炸弹:

图4.游戏结束时躲避蜗牛炸弹的角色
屏幕快照,躲在蜗牛诱饵尽头的蜗牛炸弹周围

大约在游戏进行到一半时,跑步者遇到了如图5所示的僵局:蜜蜂位于跑步者和下一个平台之间。 为了越过蜜蜂并通过游戏的这一部分,跑步者必须引爆蓝色按钮,从而炸毁蜜蜂。

图5.用于炸毁保护下一个平台的蜜蜂的蓝色按钮
Snail Bait的最后一段的屏幕截图

图6显示了按钮爆炸和蜜蜂爆炸。 当精灵爆炸时,Snail Bait取消了它们的碰撞检测资格。 爆炸蜜蜂因碰撞检测而被取消比赛资格,使奔跑者能够跳过蜜蜂到达下一个平台。

图6.引爆按钮的作用
Snail Bait的屏幕截图显示了炸毁蜜蜂的引爆按钮

像Snail Bait的所有动作一样,按钮爆炸是一种行为。 清单2显示了按钮爆炸行为的实现:

清单2.按钮引爆行为
var SnailBait = function () {
   ...
   this.buttonDetonateBehavior = {
      execute: function(sprite, now, fps, lastAnimationFrameTime) {
         var BUTTON_REBOUND_DELAY = 1000;

         if ( ! sprite.detonating) { // trigger
            return;
         }

         sprite.artist.cellIndex = 1; // flatten the button

         snailBait.explode(snailBait.bees[5]);

         setTimeout( function () {
            sprite.artist.cellIndex = 0; // rebound
            sprite.detonating = false; // reset trigger
         }, BUTTON_REBOUND_DELAY);
      }
   }
};

清单3显示了Snail Bait如何将引爆行为添加到蓝色按钮:

清单3.创建具有爆炸行为的蓝色按钮
var SnailBait = function () {

SnailBait.prototype = {
   ... 
   createButtonSprites: function () {
      var button,
         blueButtonArtist = new SpriteSheetArtist(this.spritesheet, this.blueButtonCells),
         goldButtonArtist = new SpriteSheetArtist(this.spritesheet, this.goldButtonCells);

      for (var i = 0; i < this.buttonData.length; ++i) {
         if (i === this.buttonData.length - 1) {
            button = new Sprite('button', 
                                goldButtonArtist,  
                                [ this.paceBehavior ]);
         }
         else {
            button = new Sprite('button',
                                 blueButtonArtist, 
                                 [ this.paceBehavior, 
                                   this.buttonDetonateBehavior ]);
         }

         button.width = this.BUTTON_CELLS_WIDTH;
         button.height = this.BUTTON_CELLS_HEIGHT;

         this.buttons.push(button);
      }
   }, 
};

回想一下,对于每个动画帧,Snail Bait都会迭代所有可见的精灵。 对于每个子画面,Snail Bait会在子画面的行为数组上进行迭代,并调用每个行为的execute()方法。 在大多数情况下,按钮爆炸行为的execute()方法不execute()任何操作,因为按钮的detonating属性为false 。 当Snail Bait将蓝色按钮的detonating属性设置为true ,如清单4所示,按钮起爆行为:

  1. 展平按钮。
  2. 炸蜜蜂。
  3. 延迟一秒钟。
  4. 重置按钮的原始图像。
  5. 将按钮的detonating属性设置为false

从那时起,爆炸行为一直处于Hibernate状态,直到跑步者下次按下按钮时为止。

清单4.触发爆炸行为
var SnailBait = function () {
   ...

   // The collide behavior is attached to the runner

   this.collideBehavior = {
      ...

      detonateButton: function (otherSprite) {
         otherSprite.detonating = true; // trigger
      },

      processCollision: function (sprite, otherSprite) {
         if (otherSprite.value) { 
            this.adjustScore(otherSprite);
         }

         if ('button' === otherSprite.type && sprite.falling)) {
            this.detonateButton(otherSprite);
         }
         ...
      },
   };
   ...
};

保持得分

自从本系列的第一篇文章以来,Snail Bait的记分牌一直无法正常工作。 现在是时候使记分板发挥作用了。 第一步是为某些类型的精灵指定值。 例如,清单5显示了游戏的createRubySprites()方法,该方法为每个Ruby分配了100分的值:

清单5.分配精灵值
SnailBait.prototype = {
   ...
   createRubySprites: function () {
      var ruby,
          rubyArtist = new SpriteSheetArtist(this.spritesheet, this.rubyCells);
   
      for (var i = 0; i < this.rubyData.length; ++i) {
         ruby = new Sprite('ruby', rubyArtist, 
                   [ new CycleBehavior(this.RUBY_SPARKLE_DURATION,
                                          this.RUBY_SPARKLE_INTERVAL),
                     new BounceBehavior(800, 600, 120) ]);

         ruby.width = this.RUBY_CELLS_WIDTH;
         ruby.height = this.RUBY_CELLS_HEIGHT;
         
         ruby.value = 100;

         this.rubies.push(ruby);
      }
   },
   ...
};

清单4所示,当跑步者与另一个具有值的精灵碰撞时,碰撞行为的adjustScore()方法将调整游戏的得分并更新HTML score元素。 清单6显示了adjustScore()方法:

清单6.碰撞后调整分数
var SnailBait = function () {
   ...
   // The collide behavior is attached to the runner

   this.collideBehavior = {
      ...
      adjustScore: function (otherSprite) {
         if (otherSprite.value) {
            snailBait.score += otherSprite.value;
            snailBait.score = snailBait.score < 0 ? 0 : snailBait.score;
            snailBait.scoreElement.innerHTML = snailBait.score;
         }
      },
      ...
   };
};

监视帧频并在必要时显示警告

与在严格控制的环境中运行的控制台游戏不同,HTML5游戏在混乱中运行。 视频播放器,操作系统备份软件,甚至像具有局部透明背景的终端窗口这样平凡的东西,都可以使性能最佳的游戏屈膝。 由于您无法控制HTML5游戏的运行环境,因此您必须监视帧频并在游戏运行缓慢到令人无法接受时警告玩家。 图7显示了Snail Bait的警告:

图7.运行缓慢警告
Snail Bait运行缓慢警告的屏幕截图

当Snail Bait警告玩家游戏运行缓慢时,它会显示当前帧速率。 Snail Bait通过在运行时将帧速率插入其他静态文本中来实现此目的。 清单7显示了静态文本HTML:

清单7.运行缓慢警告HTML
<html>
   <body>
      <div id='arena'>
         ...

         <!-- Running slowly........................................-->

         <div id='running-slowly'>

            <h1>Snail Bait is running slowly</h1>

            <p id='slowly-warning'></p>
            
            <p>High-performance applications, such as video players or 
              software that backs up your computer, can slow this game down. 
              For best results, hide all other windows on your desktop and 
              close CPU- or GPU- intensive apps when you play HTML5 games.
            </p>

            <p>You should also upgrade your browser to the latest version and make 
            sure that it has hardware accelerated HTML5 Canvas. Any version of Chrome 
            starting with version 18, for example, has hardware accelerated
               Canvas. Here is a link where you can download the 
               <a href='http://www.google.com/chrome/'>latest version of Chrome</a>.
            </p>

            <a id='slowly-okay' href='#'>
               Okay
            </a>

            <a  id='slowly-dont-show' href='#'>
               Do not show this warning again
            </a>
         </div>
         ...
      </div>
   </div>
</div>

清单8显示了Snail Bait如何显示和隐藏运行缓慢的警告:

清单8.显示和隐藏运行缓慢的警告
SnailBait.prototype = {
   ...
   revealRunningSlowlyWarning: function (now, averageSpeed) {
      this.slowlyWarningElement.innerHTML =
      "Snail Bait is running at " +
      "<font color='red'> averageSpeed.toFixed(0)" + "</font>" +
      " frames/second (fps), but it needs more than " +
      this.runningSlowlyThreshold + " fps for the game to work correctly."

      this.runningSlowlyElement.style.display = 'block';

      setTimeout( function () {
         snailBait.runningSlowlyElement.style.opacity = 1.0;
      }, this.SHORT_DELAY);

      this.lastSlowWarningTime = now;
   },  

   hideRunningSlowlyWarning: function () {
      snailBait.runningSlowlyElement.style.display = 'none'; 
      snailBait.runningSlowlyElement.style.opacity = 0;
   },
   ...
};

当Snail Bait显示运行缓慢的警告时,它将创建警告文本,并将其分配给slowly-warning段落元素。 然后,它将该元素的display属性设置为block以便浏览器显示它。 但是,该元素最初是透明的,因此在短暂的延迟后, revealRunningSlowlyWarning()方法将元素的不透明度设置为1.0以使其不透明。 该设置将触发CSS过渡,将元素从透明渐变为不透明1秒钟。 清单9显示了running-slowly警告元素CSS:

清单9. running-slowly警告元素CSS
#running-slowly {
   position: absolute;
   width: 600px;
   margin-top: 85px;
   margin-left: 90px;
   text-align: center;
   background: rgba(255,255,255,0.85);
   text-align: left;
   padding: 0px 20px 20px 20px;
   color: navy;
   text-shadow: 1px 1px 1px rgba(255,255,255,0.5);

   -webkit-transition: opacity 1s;
   -moz-transition: opacity 1s;
   -o-transition: opacity 1s;
   transition: opacity 1s;
   
   -webkit-box-shadow: rgba(0,0,0,0.5) 4px 4px 8px;
   -moz-box-shadow: rgba(0,0,0,0.5) 4px 4px 8px;
   -o-box-shadow: rgba(0,0,0,0.5) 4px 4px 8px;
   box-shadow: rgba(0,0,0,0.5) 4px 4px 8px;

   opacity: 0;
   display: none;

   z-index: 2;
}

在Snail Bait运行时,它监视帧速率,如清单10所示:

清单10.监视帧速率
SnailBait.prototype = {
   ...
   animate: function (now) { 
      if (snailBait.paused) {
         setTimeout( function () {
            requestNextAnimationFrame(snailBait.animate);
         }, snailBait.PAUSED_CHECK_INTERVAL);
      }
      else {
         snailBait.fps = snailBait.calculateFps(now); 

         if (snailBait.windowHasFocus && !snailBait.paused &&
             snailBait.showSlowWarning &&
             now - snailBait.lastSlowWarningTime > 
             snailBait.FPS_SLOW_CHECK_INTERVAL) {
            snailBait.checkFps(now); 
         }

         snailBait.draw(now);
         requestNextAnimationFrame(snailBait.animate);
      }
   },

   checkFps: function (now) {
      var averageSpeed;

      this.updateSpeedSamples(snailBait.fps);

      averageSpeed = this.calculateAverageSpeed();

      if (averageSpeed < this.runningSlowlyThreshold) {
         this.revealRunningSlowlyWarning(now, averageSpeed);
      }
   },
   ...
};

每隔FPS_SLOW_CHECK_INTERVAL秒(设置为4秒),Snail Bait都会通过更新速度样本数组并计算平均速度来检查帧速率。 如果平均速度小于游戏的慢跑阈值,则Snail Bait会显示慢跑警告。 清单11显示了Snail Bait更新速度样本和计算平均速度的方法:

清单11.更新速度样本并计算平均速度
SnailBait.prototype = {
   ...
   updateSpeedSamples: function (fps) {
      this.speedSamples[this.speedSamplesIndex] = fps;

      if (this.speedSamplesIndex !== this.NUM_SPEED_SAMPLES-1) {
         this.speedSamplesIndex++;
      }
      else {
         this.speedSamplesIndex = 0;
      }
   },

   calculateAverageSpeed: function () {
      var i,
      total = 0;

      for (i=0; i < this.NUM_SPEED_SAMPLES; i++) {
         total += this.speedSamples[i];
      }

      return total/this.NUM_SPEED_SAMPLES;
   },
   ...
};

当玩家单击运行缓慢警告的“ 确定”按钮时,Snail Bait将隐藏警告并重置速度样本。 当播放器单击“不再显示此警告”按钮时,Snail Bait将隐藏警告并设置一个标志,使其不再监视帧速率。 清单12中是这两个事件处理程序的代码:

清单12.运行缓慢的事件处理程序
snailBait.slowlyDontShowElement.onclick = function (e) {
   snailBait.hideRunningSlowlyWarning();
   snailBait.showSlowWarning = false;
};


snailBait.slowlyOkayElement.onclick = function (e) {
   snailBait.hideRunningSlowlyWarning();
   snailBait.speedSamples = [60,60,60,60,60,60,60,60,60,60]; // reset
};

添加特殊效果

当跑步者与另一个精灵碰撞并爆炸时,最终版本的Snail Bait会震动游戏的背景。 清单13显示了跑步者的碰撞行为的摘录,当发生这种碰撞时,该行为将调用Snail Bait的shake()方法:

清单13.晃动背景
var SnailBait = function () {
   ...
   // The collide behavior is attached to the runner

   this.collideBehavior = {
      ...
      processCollision: function (sprite, otherSprite) {
         ...
         if ('bat' === otherSprite.type || 'bee' === otherSprite.type   ||
         'snail' === otherSprite.type || 'snail bomb' === otherSprite.type) {
            snailBait.explode(sprite);

            snailBait.shake();

            setTimeout( function () {
               snailBait.loseLife();
               snailBait.reset();
               snailBait.fadeAndRestoreCanvas();
            }, snailBait.EXPLOSION_DURATION);
         }
      },
   };
   ...
};

Snail Bait的shake()方法由对setTimeout()的一系列嵌套调用组成,如清单14所示:

清单14.实现shake()方法
SnailBait.prototype = function () {
   ... 
   shake: function () {
      var SHAKE_INTERVAL = 90, // milliseconds
          v = snailBait.BACKGROUND_VELOCITY,
          ov = snailBait.bgVelocity; // ov means original velocity
   
      this.bgVelocity = -this.BACKGROUND_VELOCITY;

      setTimeout( function (e) {
       snailBait.bgVelocity = v;
       setTimeout( function (e) {
          snailBait.bgVelocity = -v;
          setTimeout( function (e) {
             snailBait.bgVelocity = v;
             setTimeout( function (e) {
                snailBait.bgVelocity = -v;
                setTimeout( function (e) {
                   snailBait.bgVelocity = v;
                   setTimeout( function (e) {
                      snailBait.bgVelocity = -v;
                      setTimeout( function (e) {
                         snailBait.bgVelocity = v;
                         setTimeout( function (e) {
                            snailBait.bgVelocity = -v;
                            setTimeout( function (e) {
                               snailBait.bgVelocity = v;
                               setTimeout( function (e) {
                                  snailBait.bgVelocity = -v;
                                  setTimeout( function (e) {
                                     snailBait.bgVelocity = v;
                                     setTimeout( function (e) {
                                        snailBait.bgVelocity = ov;
                                     }, SHAKE_INTERVAL);
                                  }, SHAKE_INTERVAL);
                               }, SHAKE_INTERVAL);
                            }, SHAKE_INTERVAL);
                         }, SHAKE_INTERVAL);
                      }, SHAKE_INTERVAL);
                   }, SHAKE_INTERVAL);
                }, SHAKE_INTERVAL);
             }, SHAKE_INTERVAL);
          }, SHAKE_INTERVAL);
       }, SHAKE_INTERVAL);
     }, SHAKE_INTERVAL);
   },
   ...
};

每隔90毫秒,Snail Bait的shake()方法会反转游戏背景速度的方向,从而产生游戏晃动的错觉。

追踪生活

Snail Bait的最终版本在游戏开始时为玩家提供了三个生命。 当跑步者与恶意小精灵碰撞并爆炸时,玩家会丧生,Snail Bait将跑步者带回游戏开始。

Snail Bait通过用跑步者的微型图标表示每个生命来显示游戏画布上方的剩余生命数。 这些图像在游戏HTML中指定,如清单15所示:

清单15.生活元素
<html>
   ...
   <body>
      <div id='arena'>
         <div id='header'>
            <div id='score'>0</div>

            <div id='lives'>
               <img id='life-icon-left'   src='images/runner-small.png'/>
               <img id='life-icon-middle' src='images/runner-small.png'/>
               <img id='life-icon-right'  src='images/runner-small.png'/>
            </div>
         </div>
         ...
      </div>
      ...
   <body>
</html>

在运行时,Snail Bait的loseLife()方法(当跑步者与恶意精灵碰撞时被调用)(请参见清单13 )-更新了lives元素。 清单16显示了updateLivesElement函数和loseLife()方法:

清单16.更新生活元素
SnailBait.prototype = {
   ...

   updateLivesElement: function () {
      if (this.lives === 3) {
         this.lifeIconLeft.style.opacity   = 1.0;
         this.lifeIconMiddle.style.opacity = 1.0;
         this.lifeIconRight.style.opacity  = 1.0;
      }
      else if (this.lives === 2) {

         this.lifeIconLeft.style.opacity   = 1.0;
         this.lifeIconMiddle.style.opacity = 1.0;
         this.lifeIconRight.style.opacity  = 0;
      }
      else if (this.lives === 1) {
         this.lifeIconLeft.style.opacity   = 1.0;
         this.lifeIconMiddle.style.opacity = 0;
         this.lifeIconRight.style.opacity  = 0;
      }
      else if (this.lives === 0) {
         this.lifeIconLeft.style.opacity   = 0;
         this.lifeIconMiddle.style.opacity = 0;
         this.lifeIconRight.style.opacity  = 0;
      }
   },

   loseLife: function () {
      this.lives--;
      this.updateLivesElement();

      if (this.lives === 1) {
         snailBait.revealToast('Last chance!');
      }

      if (this.lives === 0) {
         this.gameOver();
      }
   },
   ...
};

生活之间的过渡

如图8所示,除了减少玩家失去生命时的生命图标数量之外,Snail Bait还将画布淡出直到几乎透明为止,然后使画布淡入直到完全不透明。 Snail Bait还将跑步者从第三(最高)赛道上摔下来,以强调新生活的开始。

图8.游戏在生活之间过渡时使画布褪色
Snail Bait的屏幕截图显示了生活之间的过渡

清单17显示了Snail Bait的reset()方法, 清单13中的跑步者碰撞行为调用了该方法:

清单17.对画布进行褪色和还原
SnailBait.prototype = {
   ...
   fadeAndRestoreCanvas: function () {
      snailBait.canvas.style.opacity = 0.2;

      setTimeout( function () {
         snailBait.canvas.style.opacity = 1.0;
      }, 2500);
   },

   resetRunner: function () {
      snailBait.runner.exploding = false; 
      snailBait.runner.visible = false;
      snailBait.runner.opacity = snailBait.OPAQUE;
      snailBait.runner.artist.cells = snailBait.runnerCellsRight;

      if (snailBait.runner.jumping) { snailBait.runner.stopJumping(); }
      if (snailBait.runner.falling) { snailBait.runner.stopFalling(); }
   },

   reset: function () {
      var CANVAS_TRANSITION_DURATION = 2000,
          CONTINUE_RUNNING_DURATION = 1000;

      this.resetRunner();

      setTimeout( function () {
         snailBait.backgroundOffset = 
            snailBait.INITIAL_BACKGROUND_OFFSET;

         snailBait.spriteOffset = snailBait.INITIAL_BACKGROUND_OFFSET;
         snailBait.bgVelocity = snailBait.INITIAL_BACKGROUND_VELOCITY;

         snailBait.runner.track = 3;
         snailBait.runner.top = snailBait.calculatePlatformTop(snailBait.runner.track) - 
                                snailBait.runner.height;

         for (var i=0; i < snailBait.sprites.length; ++i) { 
            snailBait.sprites[i].visible = true;
         }

         setTimeout( function () {
            snailBait.runner.runAnimationRate = 0; // stop running
         }, CONTINUE_RUNNING_DURATION);
      }, CANVAS_TRANSITION_DURATION);
   },
   ...
};

reset()方法通过以下方法重置游戏并使游戏为新生活做好准备:

  1. 将精灵和背景偏移重置为其初始值。
  2. 将跑步者置于第三轨道。
  3. 使所有游戏的精灵都可见。

调用reset()之后,跑步者从下一个动画帧开始掉落,因为她位于第三条轨道上,下方没有平台。 因此,她的跌倒行为会引发跌倒,然后她跌倒直到降落在第一个平台上。

显示积分

在游戏结束时,Snail Bait将显示积分,如图9所示:

图9.在游戏结束时显示积分
Snail Bait显示游戏点数的屏幕截图

清单18中显示和隐藏信用有关的Snail Bait方法:

清单18.显示和隐藏信用
SnailBait.prototype = {
   ...
   
   gameOver: function () {
      snailBait.revealCredits();
   },

   restartGame: function () {
      this.hideCredits();

      this.lives = this.MAX_NUMBER_OF_LIVES;
      this.updateLivesElement();

      this.score = 0;
      this.updateScoreElement();
   },

   revealCredits: function () {
      this.creditsElement.style.display = 'block';
      this.revealLivesIcons();

      this.tweetElement.href = TWEET_PREAMBLE + this.score + TWEET_PROLOGUE;

      setTimeout( function () {
         snailBait.creditsElement.style.opacity = 1.0;
      }, snailBait.SHORT_DELAY);
   },

   hideCredits: function () {

      var CREDITS_REVEAL_DELAY = 2000;

      this.creditsElement.style.opacity = this.TRANSPARENT;

      setTimeout( function (e) {
         snailBait.creditsElement.style.display = 'none';
      }, this.CREDITS_REVEAL_DELAY);
   }, 
};

Snail Bait的gameOver()方法gameOver()loseLife()方法调用loseLife() (请参见清单16 )显示了积分,而restartGame()方法则隐藏了积分。 与点数的“再次播放”链接关联的事件处理程序将调用restartGame()方法。 该事件处理程序如清单19所示:

清单19.信用屏幕事件处理程序
snailBait.newGameLink.onclick = function (e) {
   snailBait.restartGame();
};

鸣叫分数

许多HTML5游戏都具有社交方面的内容,例如在游戏期间发推分数或与其他玩家互动。 当游戏结束时,Snail Bait玩家可以在积分显示中单击“ Tweet我的得分”链接来鸣叫他们的得分(请参见图9 )。 播放器的浏览器会在新选项卡中打开Twitter,Snail Bait会在“撰写新推文”对话框中自动输入一个准备发送的推文。 图10显示了一个示例:

图10.鸣叫分数
Twitter上发推Snail Bait分数的屏幕截图

Snail Bait通过构造URL字符串并将该字符串分配给Tweet my score链接的href属性来鸣叫得分,如清单20所示:

清单20.鸣叫分数
SnailBait = function () {
   ...
   this.TWEET_PREAMBLE = 'https://twitter.com/intent/tweet?text=I scored ';
   this.TWEET_PROLOGUE = ' playing this HTML5 Canvas platformer: ' +
                         'http://bit.ly/NDV761 &hashtags=html5';
   ...
};

SnailBait.prototype = {
   ...
   
   revealCredits: function () {
      this.creditsElement.style.display = 'block';
      this.revealLivesIcons();

      this.tweetElement.href = TWEET_PREAMBLE + this.score + TWEET_PROLOGUE;

      setTimeout( function () {
         snailBait.creditsElement.style.opacity = 1.0;
      }, snailBait.SHORT_DELAY);
   },
   ...
};

部署到服务器

将HTML5游戏部署到服务器带来了两个主要问题:游戏开始时必须从客户端传输到服务器的数据量,以及客户端和服务器之间必须进行的往返次数。 理想情况下,您传输的数据越少越好,发出的HTTP请求越少越好。 为了实现这些目标,Snail Bait执行三个步骤:

  1. 压缩JavaScript文件。
  2. 将所有JavaScript文件复制到一个文件(all.js)。
  3. 压缩JavaScript,CSS和HTML。

首先,一个简单的shell脚本找到所有的蜗牛诱饵JavaScript文件,并使用YUI压缩机(见压缩他们每个人的相关主题有关压缩机的详细信息),如清单21所示:

清单21.压缩Snail BaitJavaScript文件的Shell脚本
#!/bin/bash

mkdir tmp

for f in `find . -name "*.js"`
   do
      echo 'Compressing ' $f
         java -jar ~/Utilities/yuicompressor-2.4.7.jar $f >> tmp/all.js
   done

压缩文件被串联到一个名为all.jsJavaScript文件中,该文件包含在Snail BaitHTML文件中。

清单22中所示的另一个shell脚本通过运行清单21中的compress脚本,然后压缩游戏JavaScript,HTML和CSS来部署游戏:

清单22.部署Snail Bait的Shell脚本
#!/bin/bash

rm -rf tmp
rm all.js
rm *.gz

echo 'Compressing...'
echo
./compress.sh

echo 'Deploying...'
echo

gzip < all.js > all.js.gz
gzip < index.html > index.html.gz
gzip < snailbait.css > snailbait.css.gz

rm -rf tmp

您必须将服务器配置为接受ZIP文件,以便它使用压缩文件而不是原始文件。 不同服务器之间的配置详细信息有所不同。

结论

本文涵盖了很多领域,整个系列文章也是如此。 您已经看到Snail Bait从第一期的谦虚开始(仅显示背景,运行器和平台)到完善的游戏。 您已经了解了如何使用2D Canvas API以及其他HTML5 API(例如requestAnimationFrame )来实现滚动背景和视差。 您已经实现了精灵和精灵行为。 您还了解了如何随心所欲地实现非线性运动,以及如何检测碰撞并为子画面设置动画。 但是2D游戏开发还可能涉及我在本系列中未讨论的许多其他方面,例如:

  • 实施时间系统来修改整个游戏的时间流。
  • 在服务器上保存高分和实时的游戏内指标。
  • 创建开发人员的后门,使开发人员可以使用特殊功能。
  • 实施粒子系统以模拟烟雾和火灾。
  • 用于移动设备的微调游戏。

我鼓励您探索所有这些主题,并开始开发自己HTML5 2D游戏。


翻译自: https://www.ibm.com/developerworks/web/library/wa-html5-game10/index.html

精华游戏算法整理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值