[翻译]Akihabara 指南,第四个半部分:迁移

原文:http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-4-5-interlude/

Akihabara 指南,第四个半部分:迁移

Darius Kazemi 编写于 2010 年 07 月 21 日

这是系列指南的第四部分向第五部分过渡的内容,我们将向你演示如何使用基于 HTML5 和 JavaScript 的 Akihabara 框架来编写 8 向射击游戏。Akihabara 是一个利用 HTML5 功能帮助创建游戏的 Javascript 库。使用 HTML5 编写游戏最棒的事情是你可以在任何平台、任何支持 HTML5 的浏览器运行它。这包括 Chrome,Firefox,Safari 和 iPhone/iPad,WebOS 设备上的 WebKit 浏览器,或者其他移动平台。

在这一部分主要涵盖了一些游戏路线上的重要调整。

在这部分中,我们将扩大游戏的分辨率到 640×480,修改地图瓦片的分辨率为 16×16,移除摄影机的代码,并且创建帧计数器。

成品

这部分的最终制品应该像这样。我们调整地图的分辨率调整为原先的两倍,所以瓦片变成 16×16。这并没有什么让人激动的,只是让接下来的路好走一些。

重要提示

如果你于六月1日之间前,就开始阅读 Akihabara 指南,你需要更新 Akihabara 到 1.2.1 版本。下载这个版本,并且用这个版本替换你游戏的核心 *.js 文件。这个指南将不再支持之前的 Akihabara 版本。这里我们不会探究细节,不过 1.2.1 提供了多个 bug 的修复,改进了已有的功能,并且添加了用于音效和音乐的声音支持!

修改分辨率

我们对游戏的设计进行了一些思考,决定用一个高分辨率的固定地图来代替摄影机和卷动的地图。Akihabara 默认游戏显示在 640×480 大小的画布上,但是游戏本身放大了两倍,渲染在 320×240 的视图上。这让游戏的像素一格一格的,看起来像古老的 NES 游戏。我们考虑用显示完整的地图来代替,在 40 瓦片高,30 瓦片高的情况下,640×480 像素得到瓦片尺寸为 16×16。接下来要做的就是切换 320×240 两倍放大到 640×480 原尺寸。

为了实现这个,我们需要重写 help.akihabaraInit 函数的一些变量,它的第一个参数接受含有重写变量的对象。所以,我们在 loadResources 顶部,替换旧的 help.akihabaraInit 调用,像下面这样:

<br />
	function loadResources() {<br />
	  // 我们传递重写“title”,“分辨率”,“缩放级别”的变量到 help.akihabaraInit<br />
	  help.akihabaraInit({<br />
	    title: '8by5',<br />
	    width: 640,<br />
	    height: 480,<br />
	    zoom: 1<br />
	    });<br />

如果你现在运行这个程序,你会发现分辨率已经改变,因此我们可以在屏幕上看到整个地图!

改变地图的瓦片

在接下来的指南中,我们将放置敌人并为其建立简单的人工智能。我们希望保持敌人的寻路代码(这些代码告诉敌人如何在障碍物中移动)越简单越好。为了达到这个目的,地图瓦片的尺寸必须和敌人对象的尺寸相等。玩家是 16×16,所以敌人也是 16×16,也就是说地图的瓦片同样必须是16×16。

首先要将地图瓦片的图像尺寸扩大到原来的两倍。下载新的修改过尺寸的 map_pieces.png 并替换原先那个。

然后我们告诉 Akihabara 新的地图瓦片的尺寸是 16×16。为了做到这个,更新 gbox.addTiles 调用:

<br />
	gbox.addTiles({<br />
	    id:      'map_pieces',<br />
	    image:   'map_spritesheet',<br />
	    tileh:   16,  // 4.5 部分:修改地图瓦片尺寸<br />
	    tilew:   16,  // 4.5 部分:修改地图瓦片尺寸<br />
	    tilerow: 1,<br />
	    gapx:    0,<br />
	    gapy:    0<br />
	  });<br />

我们改变了 tileh 和 tilew 为 16 像素。如果你现在运行程序,你会看到这样创建了一个非常大的地图,和玩家的开始的位置重叠,让我们永远陷入石头不能动弹。这不会真正发生。我们现在要做的是缩小地图到一半的尺寸,实际上,就是替换墙的瓦片从 2×2 到只有一块。我们的 loadMap 函数变为这样:

<br />
	function loadMap() {<br />
	  return help.asciiArtToMap([<br />
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,<br />
	&quot;x                  xx                  x&quot;,<br />
	&quot;x                  xx                  x&quot;,<br />
	&quot;xxxxxxxx      x    xx                  x&quot;,<br />
	&quot;x             x    xxxxxxxxxx          x&quot;,<br />
	&quot;x             x                        x&quot;,<br />
	&quot;x             x                        x&quot;,<br />
	&quot;x     xxxx  xxxxxxxxx           xxxxxxxx&quot;,<br />
	&quot;x                  xx                  x&quot;,<br />
	&quot;x                  xx                  x&quot;,<br />
	&quot;xxxx               xx                  x&quot;,<br />
	&quot;x      xxxxxxxxx   xx                  x&quot;,<br />
	&quot;x                  xx                  x&quot;,<br />
	&quot;x                  xx        x         x&quot;,<br />
	&quot;xxxxxxx  xxxxxxxxxxxx        x         x&quot;,<br />
	&quot;xxxxxxx  xxxxxxxxxxxx        x         x&quot;,<br />
	&quot;x                  xx      xxxx        x&quot;,<br />
	&quot;x                  xx        x         x&quot;,<br />
	&quot;xxxxxxxx      x    xx        x         x&quot;,<br />
	&quot;x             x    xx                  x&quot;,<br />
	&quot;x             x    xx                  x&quot;,<br />
	&quot;x             x    xx                  x&quot;,<br />
	&quot;x     xxxx  xxxxxxxxx                  x&quot;,<br />
	&quot;x                  xx                  x&quot;,<br />
	&quot;xxxx                                   x&quot;,<br />
	&quot;x                                      x&quot;,<br />
	&quot;x      xxxxxxxxx   xx                  x&quot;,<br />
	&quot;x                  xx                  x&quot;,<br />
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,<br />
	    ], [ [null, ' '], [0, 'x'] ])<br />
	}<br />

如果你现在执行程序,你会得到一个可以移动的好看的地图。

屏蔽摄像机

由于现在我们可以在屏幕上看到整个地图,我们不再需要卷动的摄影机。让我们彻底屏蔽摄影机,完全删除 followCamera 函数和 addMap 中的 followCamera 调用,所以看起来像这样:

<br />
	// 这是用于添加地图对象的函数——以确保游戏主要代码优质且简明<br />
	// 在第四部分,我们添加了这里你看到的“followCamera”那行<br />
	function addMap() {<br />
	  gbox.addObject({<br />
	    id:    'background_id', // 这是对象 ID<br />
	    group: 'background',    // 我们使用之前‘setGroups’调用中创建的‘backround’组</p>
<p>	    blit: function() {<br />
	      gbox.blitFade(gbox.getBufferContext(), { alpha: 1 });<br />
	      gbox.blit(gbox.getBufferContext(), gbox.getCanvas('map_canvas'), { dx: 0, dy: 0, dw: gbox.getCanvas('map_canvas').width, dh: gbox.getCanvas('map_canvas').height, sourcecamera: true });<br />
	    }<br />
	  });<br />
	}<br />

添加帧计数器

帧计数器是一个全局变量,用于在游戏开始后统计帧的数量。帧计数器在各种各样的情况下都是很有用的,包括跟踪动画的长度或者调节运算的密度,例如运算可能每10帧才执行一次,而不是每帧一次。这实现起来很简单:设置一个全局变量为 0,并且在每一帧都使其加一。唯一棘手的是需要考虑什么时候增加它。

回顾一下,‘background’组是第一个被渲染/计算的。地图是当前 background 组中唯一的对象,所以我们增加帧计数器在它的 first 函数中。这样帧计数器就在这帧的第一个对象被计算时立刻增加了数值。

首先,在代码的最前面声明一个全局变量 frameCount,初始化为 0,跟另外两个全局变量 map 和 maingame 放在一起:

<br />
	  &lt;script&gt;<br />
	var maingame;<br />
	var map;<br />
	var frameCount = 0; // 4.5 部分新增<br />

然后,我们在 addMap 中添加 first 函数:

<br />
	// 这是用于添加地图对象的函数——以确保游戏主要代码优质且简明<br />
	// 在第四部分,我们添加了这里你看到的“followCamera”那行<br />
	function addMap() {<br />
	  gbox.addObject({<br />
	    id:    'background_id', // 这是对象 ID<br />
	    group: 'background',    // 我们使用之前‘setGroups’调用中创建的‘backround’组</p>
<p>	    // 帧计数器在地图中进行处理<br />
	    first: function() {<br />
	      frameCount++;<br />
	    },</p>
<p>	    blit: function() {<br />
	      gbox.blitFade(gbox.getBufferContext(), { alpha: 1 });<br />
	      gbox.blit(gbox.getBufferContext(), gbox.getCanvas('map_canvas'), { dx: 0, dy: 0, dw: gbox.getCanvas('map_canvas').width, dh: gbox.getCanvas('map_canvas').height, sourcecamera: true });<br />
	    }<br />
	  });<br />
	}<br />

我们所做的一切只是在 first 函数中增加 frameCount。这样,我们有了一个在每帧开始都增加的全局的帧计数器。

不需要什么回报,不过你很快会感谢我们……

我们知道,在这部分指南中没有做很多的内容,但是这将帮助我们在接下来开始放置动画并修改游戏的设计。你可以在这里看到完整的程序。

Akihabara 指南目录

Leave a Reply

Your email address will not be published. Required fields are marked *