<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Some reminiscences, some memories &#187; Game</title>
	<atom:link href="http://www.mikespook.com/index.php/category/game/feed" rel="self" type="application/rss+xml" />
	<link>http://www.mikespook.com</link>
	<description>Just another boring day</description>
	<lastBuildDate>Tue, 10 Jan 2012 03:14:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>今天的 Google Logo 很有爱</title>
		<link>http://www.mikespook.com/2011/06/%e4%bb%8a%e5%a4%a9%e7%9a%84-google-logo-%e5%be%88%e6%9c%89%e7%88%b1/</link>
		<comments>http://www.mikespook.com/2011/06/%e4%bb%8a%e5%a4%a9%e7%9a%84-google-logo-%e5%be%88%e6%9c%89%e7%88%b1/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 03:19:13 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[logo]]></category>
		<category><![CDATA[吉他]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=1029</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
http://www.google.com.hk/ 今天的 Logo 居然是一个 HTML5 的吉他，而且是可以弹得响的。小玩了一下，用键盘控制比较方便。

QWERTYU，分别对应 1-7；IOP，分别对应高音1-3。

于是，就有下面的曲子了：

<span class="readmore"><a href="http://www.mikespook.com/2011/06/%e4%bb%8a%e5%a4%a9%e7%9a%84-google-logo-%e5%be%88%e6%9c%89%e7%88%b1/" title="今天的 Google Logo 很有爱">阅读全文——共203字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p><a href="http://www.google.com.hk/" target="_blank"><a href="http://www.mikespook.com/wp-content/uploads/2011/06/Google.png"><img class="size-medium wp-image-1032 alignleft" title="Google" src="http://www.mikespook.com/wp-content/uploads/2011/06/Google-300x105.png" alt="" width="300" height="105" /></a>http://www.google.com.hk/</a> 今天的 Logo 居然是一个 HTML5 的吉他，而且是可以弹得响的。小玩了一下，用键盘控制比较方便。</p>
<p>QWERTYU，分别对应 1-7；IOP，分别对应高音1-3。</p>
<p>于是，就有下面的曲子了：</p>
<p><span style="text-decoration: underline;">TTT</span> <span style="text-decoration: underline;">TER</span> | T.U. | <span style="text-decoration: underline;">YYY</span> <span style="text-decoration: underline;">YRY</span> | T- X|</p>
<p><span style="text-decoration: underline;">TTT</span> <span style="text-decoration: underline;">TUY</span>| T.R. | <span style="text-decoration: underline;">RRR</span> <span style="text-decoration: underline;">REW</span> | Q- X||</p>
<p>X 是空拍。</p>
<p>和弦也是可以的，和弦音对应的键一起按即可。不过按得我手抽筋……就不娱乐了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2011/06/%e4%bb%8a%e5%a4%a9%e7%9a%84-google-logo-%e5%be%88%e6%9c%89%e7%88%b1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]6款用于在线游戏的基于 Html5 的 Javascript 游戏开发框架</title>
		<link>http://www.mikespook.com/2011/02/%e7%bf%bb%e8%af%916%e6%ac%be%e7%94%a8%e4%ba%8e%e5%9c%a8%e7%ba%bf%e6%b8%b8%e6%88%8f%e7%9a%84%e5%9f%ba%e4%ba%8e-html5-%e7%9a%84-javascript-%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91%e6%a1%86%e6%9e%b6/</link>
		<comments>http://www.mikespook.com/2011/02/%e7%bf%bb%e8%af%916%e6%ac%be%e7%94%a8%e4%ba%8e%e5%9c%a8%e7%ba%bf%e6%b8%b8%e6%88%8f%e7%9a%84%e5%9f%ba%e4%ba%8e-html5-%e7%9a%84-javascript-%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91%e6%a1%86%e6%9e%b6/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 01:15:15 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[game engine]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[游戏]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=847</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
原文在此：http://www.web-delicious.com/5-html5-javascript-game-development-frameworks-for-online-game-developers/

六款游戏引擎/框架都是好东西。Akihabara 我之前翻译的系列教程Akihabara指南里有介绍。而单从介绍和各引擎网站上来看，我对 Rocket 引擎还是很有期待的。

1. Gamequery – 用于 jQuery 的 Javascript 游戏引擎

<span class="readmore"><a href="http://www.mikespook.com/2011/02/%e7%bf%bb%e8%af%916%e6%ac%be%e7%94%a8%e4%ba%8e%e5%9c%a8%e7%ba%bf%e6%b8%b8%e6%88%8f%e7%9a%84%e5%9f%ba%e4%ba%8e-html5-%e7%9a%84-javascript-%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91%e6%a1%86%e6%9e%b6/" title="[翻译]6款用于在线游戏的基于 Html5 的 Javascript 游戏开发框架">阅读全文——共1799字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>原文在此：<a href="http://www.web-delicious.com/5-html5-javascript-game-development-frameworks-for-online-game-developers/" target="_blank">http://www.web-delicious.com/5-html5-javascript-game-development-frameworks-for-online-game-developers/</a></p>
<p>六款游戏引擎/框架都是好东西。Akihabara 我之前翻译的系列教程<a href="http://www.mikespook.com/index.php/akihabara-tutorial" target="_blank">Akihabara指南</a>里有介绍。而单从介绍和各引擎网站上来看，我对 Rocket 引擎还是很有期待的。</p>
<h1>1. Gamequery – 用于 jQuery 的 Javascript 游戏引擎</h1>
<p><a title="gamequery html5 game framework" href="http://gamequery.onaluf.org/">GameQuery</a> 是 <a title="Opens in a new window" href="http://jquery.com/" target="_blank">jQuery</a> 的 <a title="Opens in a new window" href="http://plugins.jquery.com/project/gameQuery" target="_blank">插件</a>，可帮助 javascript 游戏开发者更加容易的添加游戏相关的类。它还处于开发的初期，并且在将来的版本中可能会有许多变化。项目托管于 <a title="Opens in a new window" href="http://github.com/onaluf/gameQuery" target="_blank">GitHub</a> （它之前是托管在 <a title="Opens in a new window" href="http://code.google.com/p/jquery-gamequery/" target="_blank">Google Code</a> 的），你可以在这个 <a title="Opens in a new window" href="http://twitter.com/gameQuery" target="_blank">twitter 页面</a> 关注每日的开发进度。</p>
<div id="attachment_3703">
<p style="text-align: center;"><a href="http://www.mikespook.com/wp-content/uploads/2011/02/javascript-game-engine-with-jQuery.png"><img class="alignnone size-full wp-image-849" title="javascript-game-engine-with-jQuery" src="http://www.mikespook.com/wp-content/uploads/2011/02/javascript-game-engine-with-jQuery.png" alt="" width="417" height="264" /></a></p>
<p style="text-align: center;">Gamequery &#8211; 用于 jQuery 的 Javascript 游戏引擎</p>
<p><span id="more-847"></span></p>
</div>
<h1>2. processingjs – Processing Visualization Language 的移植<strong><br />
</strong></h1>
<p><a title="processingjs html5 game framework" href="http://processingjs.org/">Processing.js</a> 使你的数据可视化，数字艺术、交互动画、教育影像、视频游戏等，基于 Web 标准并且无须任何插件。使用 Processing language 编写代码，包含进 Web 页面中，Processing.js 会处理剩余的工作。这不是魔法，但是也差不多了。</p>
<p>最初由 <a href="http://benfry.com/">Ben Fry</a> 和 <a href="http://reas.com/">Casey Reas</a> 开发，Processing 标准就像一种基于 Java 的开源编程语言，用以帮助电子艺术和可视化设计团体在可视化环境中学习基本的计算机编程。Processing.js 将这个带入了更高的级别，允许任何支持 HTML5 的浏览器运行 Processing 代码，包括当前版本的 Firefox， Safari，  Chrome， Opera 和将要到来的 Internet Explorer 9。Processing.js  为 Processing 和 Web 开发者带来了最好的 Web 上的可视化编程。</p>
<div id="attachment_3704">
<p style="text-align: center;"><a href="http://www.mikespook.com/wp-content/uploads/2011/02/processingjs-exhibition.png"><img class="alignnone size-full wp-image-851" title="processingjs-exhibition" src="http://www.mikespook.com/wp-content/uploads/2011/02/processingjs-exhibition.png" alt="" width="625" height="374" /></a></p>
<p style="text-align: center;">processingjs 展示</p>
</div>
<h1>3.LimeJS 是 HTML5游戏框架</h1>
<p><a href="http://www.limejs.com/">LimeJS</a> 是基于 HTML5 的游戏框架，用于快速构建运行于所有现代触摸屏和桌面浏览器的纯正体验的游戏。</p>
<div id="attachment_3705">
<p style="text-align: center;"><a href="http://www.mikespook.com/wp-content/uploads/2011/02/LimeJS-HTML5-Game-Framework.png"><img class="alignnone size-full wp-image-852" title="LimeJS-HTML5-Game-Framework" src="http://www.mikespook.com/wp-content/uploads/2011/02/LimeJS-HTML5-Game-Framework.png" alt="" width="377" height="194" /></a></p>
<p style="text-align: center;">LimeJS HTML5游戏框架</p>
</div>
<h1>4.Akihabara html5/javascript 游戏引擎<strong><em><br />
</em></strong></h1>
<p><a title="akihabara html5 game framework" href="http://www.kesiev.com/akihabara/"><em>Akihabara</em></a> 是一系列的库、工具、预设置，用于使用 Javascript 创建像素化的8/16位时期的游戏，不使用 Flash 插件的情况下运行于浏览器，使用了相当小、相当小的 <a href="http://en.wikipedia.org/wiki/HTML_5">HTML5</a> 一部分特性，这些特性在大多数浏览器上已经实现。</p>
<p>Akihabara 用于快速游戏/原型开发，虽然 Javascript 不是唯一的有趣的脚本语言，但是在每日午饭后的餐余编码时间（我通常的自由时间）都还是可以用用的。引擎并不够精巧，但是可用在  <a href="http://www.kesiev.com/akihabara/sshot/chrome.png">Google Chrome</a>， <a href="http://www.kesiev.com/akihabara/sshot/safari.png">Safari</a>， <a href="http://www.kesiev.com/akihabara/sshot/firefox.png">Firefox</a>， <a href="http://www.kesiev.com/akihabara/sshot/opera.png">Opera</a>， <a href="http://www.kesiev.com/akihabara/sshot/konqueror.png">Konqueror</a> 和 <a href="http://www.kesiev.com/akihabara/sshot/ie9beta.png">Internet Explorer 9 Beta</a> 的 IE 9 模式。游戏在所有支持的浏览器和平台上都采用同样的模式运行，全部都是可见的。使用 Javascript 带来的另一个好处：游戏可在流行的移动设备，如 <a href="http://www.kesiev.com/akihabara/sshot/iphone.jpg">iPhone/iPod</a>， <a href="http://www.kesiev.com/akihabara/sshot/wii.jpg">Nintendo Wii</a> 的 Internet 通道，<a href="http://www.kesiev.com/akihabara/sshot/android.png">Android</a> 设备和 iPad。</p>
<div id="attachment_3706">
<p style="text-align: center;"><a href="http://www.mikespook.com/wp-content/uploads/2011/02/www_kesiev_com_akihabara.png"><img class="alignnone size-full wp-image-853" title="www_kesiev_com_akihabara" src="http://www.mikespook.com/wp-content/uploads/2011/02/www_kesiev_com_akihabara.png" alt="" width="554" height="356" /></a></p>
<p style="text-align: center;">akihabara html5游戏框架</p>
</div>
<h1>5. Rocket引擎</h1>
<p>由专家级游戏开发者为了同样级别的游戏开发者构建，<a title="rocketpack engine" href="http://rocketpack.fi/engine/">Rocket 引擎</a> 是唯一一个无须插件的浏览器游戏开发集成解决方案。如果你对构建夸平台的单人游戏、Facebook 游戏或者基于浏览器的MMO感兴趣，那么注意了！</p>
<p><a href="http://www.warimals.com/"><strong>Warimals，首款由 Rocket 引擎构建的游戏！</strong></a></p>
<div id="attachment_3707">
<p style="text-align: center;"><a href="http://www.mikespook.com/wp-content/uploads/2011/02/Rocket-Pack-html5-game-framework.png"><img class="alignnone size-full wp-image-854" title="Rocket-Pack-html5-game-framework" src="http://www.mikespook.com/wp-content/uploads/2011/02/Rocket-Pack-html5-game-framework.png" alt="" width="632" height="337" /></a></p>
<p style="text-align: center;">Rocket 集成 html5游戏框架</p>
</div>
<h1>6. Effect Games</h1>
<p><a title="effectgames html5 game framework" href="http://www.effectgames.com/effect/">Effect Games</a> 提供免费的在线工具，用于构建、分享和玩你自己的基于浏览器的游戏。</p>
<p>游戏可以包含音效、音乐和多个包含用于视差卷动的瓦片和精灵的层。</p>
<p>用户可以在浏览器里玩游戏，无须任何新的插件或扩展。可发布游戏到网站或者博客，在SNS上分享，或提交到我们的特色游戏专区！</p>
<p>使用 JavaScript、定制的浏览器游戏引擎、关卡编辑器和开发工具包构建游戏。Effect 引擎支持  Mac OS X，Windows，Linux和所有流行浏览器，包括 IE， Firefox，  Chrome， Opera 和 Safari。</p>
<div id="attachment_3708">
<p style="text-align: center;"><a href="http://www.mikespook.com/wp-content/uploads/2011/02/www_effectgames_com_effect.png"><img class="alignnone size-full wp-image-855" title="www_effectgames_com_effect" src="http://www.mikespook.com/wp-content/uploads/2011/02/www_effectgames_com_effect.png" alt="" width="411" height="353" /></a></p>
<p style="text-align: center;">effectgames 在线游戏构建工具</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2011/02/%e7%bf%bb%e8%af%916%e6%ac%be%e7%94%a8%e4%ba%8e%e5%9c%a8%e7%ba%bf%e6%b8%b8%e6%88%8f%e7%9a%84%e5%9f%ba%e4%ba%8e-html5-%e7%9a%84-javascript-%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91%e6%a1%86%e6%9e%b6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Akihabara 指南目录</title>
		<link>http://www.mikespook.com/2010/08/akihabara-%e6%8c%87%e5%8d%97%e7%9b%ae%e5%bd%95/</link>
		<comments>http://www.mikespook.com/2010/08/akihabara-%e6%8c%87%e5%8d%97%e7%9b%ae%e5%bd%95/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 14:46:17 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Stardy & Research]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=728</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
英文原版的指南已经撰写到第七部分，随着翻译内容越来越多，每次都更新每篇翻译的目录很辛苦。所以单独做了一个目录。以后只维护这个目录就可以了。

Akihabara 指南目录

由于最近工作上比较忙，翻译进度不是很快。大家着急就直接看英文版的吧。写得其实挺简明的。

]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>英文原版的指南已经撰写到第七部分，随着翻译内容越来越多，每次都更新每篇翻译的目录很辛苦。所以单独做了一个目录。以后只维护这个目录就可以了。</p>
<p><a href="http://www.mikespook.com/index.php/akihabara-tutorial">Akihabara 指南目录</a></p>
<p>由于最近工作上比较忙，翻译进度不是很快。大家着急就直接看英文版的吧。写得其实挺简明的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2010/08/akihabara-%e6%8c%87%e5%8d%97%e7%9b%ae%e5%bd%95/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[翻译]Akihabara 指南，第四个半部分：迁移</title>
		<link>http://www.mikespook.com/2010/08/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e4%b8%aa%e5%8d%8a%e9%83%a8%e5%88%86%ef%bc%9a%e8%bf%81%e7%a7%bb/</link>
		<comments>http://www.mikespook.com/2010/08/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e4%b8%aa%e5%8d%8a%e9%83%a8%e5%88%86%ef%bc%9a%e8%bf%81%e7%a7%bb/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 12:51:58 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Stardy & Research]]></category>
		<category><![CDATA[arkihabara]]></category>
		<category><![CDATA[game engine]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=711</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
原文：http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-4-5-interlude/

Akihabara 指南，第四个半部分：迁移

Darius Kazemi 编写于 2010 年 07 月 21 日

<span class="readmore"><a href="http://www.mikespook.com/2010/08/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e4%b8%aa%e5%8d%8a%e9%83%a8%e5%88%86%ef%bc%9a%e8%bf%81%e7%a7%bb/" title="[翻译]Akihabara 指南，第四个半部分：迁移">阅读全文——共3875字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>原文：<a href="http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-4-5-interlude/" target="_blank">http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-4-5-interlude/</a></p>
<h1>Akihabara 指南，第四个半部分：迁移</h1>
<p><em>Darius Kazemi 编写于 2010 年 07 月 21 日</em></p>
<p><span id="more-711"></span></p>
<p>这是系列指南的第四部分向第五部分过渡的内容，我们将向你演示如何使用基于 HTML5 和 JavaScript 的 Akihabara 框架来编写 8 向射击游戏。<a href="http://www.kesiev.com/akihabara/" target="_blank">Akihabara</a> 是一个利用 HTML5 功能帮助创建游戏的 Javascript 库。使用 HTML5 编写游戏最棒的事情是你可以在任何平台、任何支持 HTML5 的浏览器运行它。这包括 Chrome，Firefox，Safari 和 iPhone/iPad，WebOS 设备上的 WebKit 浏览器，或者其他移动平台。</p>
<p>在这一部分主要涵盖了一些游戏路线上的重要调整。</p>
<p>在这部分中，我们将扩大游戏的分辨率到 640×480，修改地图瓦片的分辨率为 16×16，移除摄影机的代码，并且创建帧计数器。</p>
<h2>成品</h2>
<p>这部分的最终制品应该像<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut4_5_interlude/" target="_blank">这样</a>。我们调整地图的分辨率调整为原先的两倍，所以瓦片变成 16×16。这并没有什么让人激动的，只是让接下来的路好走一些。</p>
<h2>重要提示</h2>
<p>如果你于六月1日之间前，就开始阅读 Akihabara 指南，你需要更新 Akihabara 到 <a href="http://www.kesiev.com/akihabara/demo/akihabara-core-1.2.1.zip" target="_blank">1.2.1</a> 版本。下载这个版本，并且用这个版本替换你游戏的核心 *.js 文件。这个指南将不再支持之前的 Akihabara 版本。这里我们不会探究细节，不过 1.2.1 提供了多个 bug 的修复，改进了已有的功能，并且添加了用于音效和音乐的声音支持！</p>
<h2>修改分辨率</h2>
<p>我们对游戏的设计进行了一些思考，决定用一个高分辨率的固定地图来代替摄影机和卷动的地图。Akihabara 默认游戏显示在 640×480 大小的画布上，但是游戏本身放大了两倍，渲染在 320×240 的视图上。这让游戏的像素一格一格的，看起来像古老的 NES 游戏。我们考虑用显示完整的地图来代替，在 40 瓦片高，30 瓦片高的情况下，640×480 像素得到瓦片尺寸为 16×16。接下来要做的就是切换 320×240 两倍放大到 640×480 原尺寸。</p>
<p>为了实现这个，我们需要重写 help.akihabaraInit 函数的一些变量，它的第一个参数接受含有重写变量的对象。所以，我们在 loadResources 顶部，替换旧的 help.akihabaraInit 调用，像下面这样：</p>
<pre class="brush: jscript; title: ; notranslate">
	function loadResources() {
	  // 我们传递重写“title”，“分辨率”，“缩放级别”的变量到 help.akihabaraInit
	  help.akihabaraInit({
	    title: '8by5',
	    width: 640,
	    height: 480,
	    zoom: 1
	    });
</pre>
<p>如果你现在运行这个程序，你会发现分辨率已经改变，因此我们可以在屏幕上看到整个地图！</p>
<h2>改变地图的瓦片</h2>
<p>在接下来的指南中，我们将放置敌人并为其建立简单的人工智能。我们希望保持敌人的寻路代码（这些代码告诉敌人如何在障碍物中移动）越简单越好。为了达到这个目的，地图瓦片的尺寸必须和敌人对象的尺寸相等。玩家是 16×16，所以敌人也是 16×16，也就是说地图的瓦片同样必须是16×16。</p>
<p>首先要将地图瓦片的图像尺寸扩大到原来的两倍。下载新的修改过尺寸的 <a href="http://tools.bostongamejams.com/akihabara_tutorials/tut4_5_interlude/map_pieces.png" target="_blank">map_pieces.png</a> 并替换原先那个。</p>
<p>然后我们告诉 Akihabara 新的地图瓦片的尺寸是 16×16。为了做到这个，更新 gbox.addTiles 调用：</p>
<pre class="brush: jscript; title: ; notranslate">
	gbox.addTiles({
	    id:      'map_pieces',
	    image:   'map_spritesheet',
	    tileh:   16,  // 4.5 部分：修改地图瓦片尺寸
	    tilew:   16,  // 4.5 部分：修改地图瓦片尺寸
	    tilerow: 1,
	    gapx:    0,
	    gapy:    0
	  });
</pre>
<p>我们改变了 tileh 和 tilew 为 16 像素。如果你现在运行程序，你会看到这样创建了一个非常大的地图，和玩家的开始的位置重叠，让我们永远陷入石头不能动弹。这不会真正发生。我们现在要做的是缩小地图到一半的尺寸，实际上，就是替换墙的瓦片从 2×2 到只有一块。我们的 loadMap 函数变为这样：</p>
<pre class="brush: jscript; title: ; notranslate">
	function loadMap() {
	  return help.asciiArtToMap([
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	&quot;x                  xx                  x&quot;,
	&quot;x                  xx                  x&quot;,
	&quot;xxxxxxxx      x    xx                  x&quot;,
	&quot;x             x    xxxxxxxxxx          x&quot;,
	&quot;x             x                        x&quot;,
	&quot;x             x                        x&quot;,
	&quot;x     xxxx  xxxxxxxxx           xxxxxxxx&quot;,
	&quot;x                  xx                  x&quot;,
	&quot;x                  xx                  x&quot;,
	&quot;xxxx               xx                  x&quot;,
	&quot;x      xxxxxxxxx   xx                  x&quot;,
	&quot;x                  xx                  x&quot;,
	&quot;x                  xx        x         x&quot;,
	&quot;xxxxxxx  xxxxxxxxxxxx        x         x&quot;,
	&quot;xxxxxxx  xxxxxxxxxxxx        x         x&quot;,
	&quot;x                  xx      xxxx        x&quot;,
	&quot;x                  xx        x         x&quot;,
	&quot;xxxxxxxx      x    xx        x         x&quot;,
	&quot;x             x    xx                  x&quot;,
	&quot;x             x    xx                  x&quot;,
	&quot;x             x    xx                  x&quot;,
	&quot;x     xxxx  xxxxxxxxx                  x&quot;,
	&quot;x                  xx                  x&quot;,
	&quot;xxxx                                   x&quot;,
	&quot;x                                      x&quot;,
	&quot;x      xxxxxxxxx   xx                  x&quot;,
	&quot;x                  xx                  x&quot;,
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	    ], [ [null, ' '], [0, 'x'] ])
	}
</pre>
<p>如果你现在执行程序，你会得到一个可以移动的好看的地图。</p>
<h2>屏蔽摄像机</h2>
<p>由于现在我们可以在屏幕上看到整个地图，我们不再需要卷动的摄影机。让我们彻底屏蔽摄影机，完全删除 followCamera 函数和 addMap 中的 followCamera 调用，所以看起来像这样：</p>
<pre class="brush: jscript; title: ; notranslate">
	// 这是用于添加地图对象的函数——以确保游戏主要代码优质且简明
	// 在第四部分，我们添加了这里你看到的“followCamera”那行
	function addMap() {
	  gbox.addObject({
	    id:    'background_id', // 这是对象 ID
	    group: 'background',    // 我们使用之前‘setGroups’调用中创建的‘backround’组

	    blit: function() {
	      gbox.blitFade(gbox.getBufferContext(), { alpha: 1 });
	      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 });
	    }
	  });
	}
</pre>
<h2>添加帧计数器</h2>
<p>帧计数器是一个全局变量，用于在游戏开始后统计帧的数量。帧计数器在各种各样的情况下都是很有用的，包括跟踪动画的长度或者调节运算的密度，例如运算可能每10帧才执行一次，而不是每帧一次。这实现起来很简单：设置一个全局变量为 0，并且在每一帧都使其加一。唯一棘手的是需要考虑什么时候增加它。</p>
<p>回顾一下，‘background’组是第一个被渲染/计算的。地图是当前 background 组中唯一的对象，所以我们增加帧计数器在它的 first 函数中。这样帧计数器就在这帧的第一个对象被计算时立刻增加了数值。</p>
<p>首先，在代码的最前面声明一个全局变量 frameCount，初始化为 0，跟另外两个全局变量 map 和 maingame 放在一起：</p>
<pre class="brush: jscript; title: ; notranslate">
	  &lt;script&gt;
	var maingame;
	var map;
	var frameCount = 0; // 4.5 部分新增
</pre>
<p>然后，我们在 addMap 中添加 first 函数：</p>
<pre class="brush: jscript; title: ; notranslate">
	// 这是用于添加地图对象的函数——以确保游戏主要代码优质且简明
	// 在第四部分，我们添加了这里你看到的“followCamera”那行
	function addMap() {
	  gbox.addObject({
	    id:    'background_id', // 这是对象 ID
	    group: 'background',    // 我们使用之前‘setGroups’调用中创建的‘backround’组

	    // 帧计数器在地图中进行处理
	    first: function() {
	      frameCount++;
	    },

	    blit: function() {
	      gbox.blitFade(gbox.getBufferContext(), { alpha: 1 });
	      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 });
	    }
	  });
	}
</pre>
<p>我们所做的一切只是在 first 函数中增加 frameCount。这样，我们有了一个在每帧开始都增加的全局的帧计数器。</p>
<p>不需要什么回报，不过你很快会感谢我们……</p>
<p>我们知道，在这部分指南中没有做很多的内容，但是这将帮助我们在接下来开始放置动画并修改游戏的设计。你可以在<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut4_5_interlude/" target="_blank">这里</a>看到完整的程序。</p>
<p><a href="http://www.mikespook.com/index.php/akihabara-tutorial" target="_blank">Akihabara 指南目录</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2010/08/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e4%b8%aa%e5%8d%8a%e9%83%a8%e5%88%86%ef%bc%9a%e8%bf%81%e7%a7%bb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]Akihabara 指南，第四部分：地图的卷动</title>
		<link>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e9%83%a8%e5%88%86%ef%bc%9a%e5%9c%b0%e5%9b%be%e7%9a%84%e5%8d%b7%e5%8a%a8/</link>
		<comments>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e9%83%a8%e5%88%86%ef%bc%9a%e5%9c%b0%e5%9b%be%e7%9a%84%e5%8d%b7%e5%8a%a8/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 05:44:42 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Stardy & Research]]></category>
		<category><![CDATA[akihabara]]></category>
		<category><![CDATA[game engine]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=676</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
原文：http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-4-scrolling-map/

这部分有不少视频是在 youtubo 上的，你说我应该把它移到国内哪个视频网站上呢？

Akihabara 指南，第四部分：地图的卷动

<span class="readmore"><a href="http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e9%83%a8%e5%88%86%ef%bc%9a%e5%9c%b0%e5%9b%be%e7%9a%84%e5%8d%b7%e5%8a%a8/" title="[翻译]Akihabara 指南，第四部分：地图的卷动">阅读全文——共5154字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>原文：<a href="http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-4-scrolling-map/" target="_blank">http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-4-scrolling-map/</a><br />
<em>这部分有不少视频是在 youtubo 上的，你说我应该把它移到国内哪个视频网站上呢？</em></p>
<h1>Akihabara 指南，第四部分：地图的卷动</h1>
<p><em>Darius Kazemi 编写于 2010 年 06 月 27 日</em></p>
<p><span id="more-676"></span></p>
<p>这是系列指南的第四部分，我们将向你演示如何使用基于 HTML5 和 JavaScript 的 Akihabara 框架来编写 8 向射击游戏。<a href="http://www.kesiev.com/akihabara/" target="_blank">Akihabara</a> 是一个利用 HTML5 功能帮助创建游戏的 Javascript 库。使用 HTML5 编写游戏最棒的事情是你可以在任何平台、任何支持 HTML5 的浏览器运行它。这包括 Chrome，Firefox，Safari 和 iPhone/iPad，WebOS 设备上的 WebKit 浏览器，或者其他移动平台。</p>
<p>在这一部分，我们将创建一个比<a href="http://www.mikespook.com/index.php/archives/658" target="_blank">第三部分</a>中的地图大得多的地图，然后将演示如何建立摄影机，以便于玩家移动时卷动地图。</p>
<h2>开始前的重要提示</h2>
<p>为了让这个指南起作用，你应当<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut3_basic_mapping/index.html" target="_blank">下载</a>我们整理过的第三部分的代码，并从此处开始学习：为了使得代码更加一致，我们对变量命名进行了一些修改。同时，你应当重命名工作目录下的 playerSprite.png 为 player_sprite.png。</p>
<h2>成品</h2>
<p>本次课程结束后，你会得到类似<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut4_scrolling_map/index.html" target="_blank">这样</a>的一个游戏。按下 Z 越过标题屏幕，然后使用方向键移动。注意摄影机是如何跟随玩家对象移动的。</p>
<h2>大地图</h2>
<p>好吧，卷动地图首先需要的是让地图尺寸大于屏幕的尺寸。做到这点是相当的容易。只需要添加一些数据到 loadMap 函数，让它的宽度和高度翻倍。</p>
<pre class="brush: jscript; title: ; notranslate">
	function loadMap() {
	  return help.asciiArtToMap([
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xxxxxxxxxxxxxxxx            xx        xxxx                                    xx&quot;,
	&quot;xxxxxxxxxxxxxxxx            xx        xxxxxxxxxxxxxxxxxxx                     xx&quot;,
	&quot;xx                          xx        xxxxxxxxxxxxxxxxxxx                     xx&quot;,
	&quot;xx                          xx                                                xx&quot;,
	&quot;xx                          xx                                                xx&quot;,
	&quot;xx                          xx                                                xx&quot;,
	&quot;xx                          xx                                                xx&quot;,
	&quot;xx                          xx                                                xx&quot;,
	&quot;xx          xxxxxxxx   xxxxxxxxxxxxxxxxxxx                     xxxxxxxxxxxxxxxxx&quot;,
	&quot;xx          xxxxxxxx   xxxxxxxxxxxxxxxxxxx                     xxxxxxxxxxxxxxxxx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xxxxxxxx                              xxxx                                    xx&quot;,
	&quot;xxxxxxxx                              xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx            xxxxxxxxxxxxxxxxxx      xxxx                                    xx&quot;,
	&quot;xx            xxxxxxxxxxxxxxxxxx      xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                xx                  xx&quot;,
	&quot;xxxxxxxxxxxxxxxx  xxxxxxxxxxxxxxxxxxxxxxxx                xx                  xx&quot;,
	&quot;xxxxxxxxxxxxxxxx  xxxxxxxxxxxxxxxxxxxxxxxx                xx                  xx&quot;,
	&quot;xxxxxxxxxxxxxxxx  xxxxxxxxxxxxxxxxxxxxxxxx                xx                  xx&quot;,
	&quot;xxxxxxxxxxxxxxxx  xxxxxxxxxxxxxxxxxxxxxxxx                xx                  xx&quot;,
	&quot;xx                                    xxxx            xxxxxxxx                xx&quot;,
	&quot;xx                                    xxxx            xxxxxxxx                xx&quot;,
	&quot;xx                                    xxxx                xx                  xx&quot;,
	&quot;xx                                    xxxx                xx                  xx&quot;,
	&quot;xxxxxxxxxxxxxxxx            xx        xxxx                xx                  xx&quot;,
	&quot;xxxxxxxxxxxxxxxx            xx        xxxx                xx                  xx&quot;,
	&quot;xx                          xx        xxxx                xx                  xx&quot;,
	&quot;xx                          xx        xxxx                                    xx&quot;,
	&quot;xx                          xx        xxxx                                    xx&quot;,
	&quot;xx                          xx        xxxx                                    xx&quot;,
	&quot;xx                          xx        xxxx                                    xx&quot;,
	&quot;xx                          xx        xxxx                                    xx&quot;,
	&quot;xx          xxxxxxxx   xxxxxxxxxxxxxxxxxxx                                    xx&quot;,
	&quot;xx          xxxxxxxx   xxxxxxxxxxxxxxxxxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xxxxxxxx                                                                      xx&quot;,
	&quot;xxxxxxxx                                                                      xx&quot;,
	&quot;xx                                                                            xx&quot;,
	&quot;xx            xxxxxxxxxxxxxxxxxx      xxxx                                    xx&quot;,
	&quot;xx            xxxxxxxxxxxxxxxxxx      xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xx                                    xxxx                                    xx&quot;,
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	    ], [ [null, ' '], [0, 'x'] ])
	}
</pre>
<h2>初始化摄影机</h2>
<p>接下来，我们实现摄影机本身。我们将在地图的 blit 函数中，在调用 gbox.blit 前实现。</p>
<pre class="brush: jscript; title: ; notranslate">
	// 将玩家对象至于摄影机中央。map.w 和 map.h 数据告诉摄影机什么时候碰撞到地图边缘，以便停止卷动。
	gbox.centerCamera(gbox.getObject('player', 'player_id'), {w: map.w, h: map.h});
</pre>
<p>gbox.centerCamera 函数接受两个参数：想要摄影机跟随的对象，以及不希望摄影机卷动出去的盒子的边界。为了避免看到地图之外的区域，盒子的边界设置为整个地图的宽和高。</p>
<p>注意：添加了这个以后，你可能在 firefox 中遇到玩家精灵不能正确显示的 bug，在我们用自己编写的代码修复替换并修补这个 bug 之前，请在 Safari 或者 Chrome 中测试。</p>
<p>gbox.getObject 函数返回了指定对象的句柄。它的两个参数分别是对象的组和 ID。这是在其他对象中引用对象最好的办法。</p>
<h2>活了！</h2>
<p>我们的摄影机现在可以工作了。你的代码应当看起来像<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut4_scrolling_map/index_camera.html" target="_blank">这样</a>工作。但是我们的摄像机移动的时候，有些东西似乎不太对劲。看看这个（youtubo 视频，翻墙吧！）：<br />
<object width="640" height="505" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"><param value="true" name="allowFullScreen"><param value="always" name="allowscriptaccess"><param value="http://www.youtube.com/v/Th4wv4rj1Fg&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0xe1600f&amp;color2=0xfebd01" name="src"><param value="true" name="allowfullscreen"><embed width="640" height="505" allowfullscreen="true" allowscriptaccess="always" src="http://www.youtube.com/v/Th4wv4rj1Fg&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0xe1600f&amp;color2=0xfebd01" type="application/x-shockwave-flash"></object></p>
<p>即使是我们的玩家对象一个极小的移动，摄影机都会跟着一起动。这让游戏看起来很愚蠢。你可能会由于游戏中的移动而引起眩晕。而我们解决这个问题的办法就是给摄影机增加死区。</p>
<h2>摄影机的“死区”</h2>
<p>死区是屏幕中间的一个区域，在这个区域内，摄影机不会跟随玩家。当玩家在死区内移动时，摄影机不会移动。当玩家越过了死区的边缘后，摄影机会跟随玩家移动。这意味着在屏幕中央微小的移动（一些重要区域的局部操作）不会让屏幕移动。这感觉起来好一些。下面的视频展示了《Super Mario Bros. 3.》中的死区（youtubo 视频，翻墙吧！）。</p>
<p><object width="640" height="505" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"><param value="true" name="allowFullScreen"><param value="always" name="allowscriptaccess"><param value="http://www.youtube.com/v/89TRXUm8jMI&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0xe1600f&amp;color2=0xfebd01" name="src"><param value="true" name="allowfullscreen"><embed width="640" height="505" allowfullscreen="true" allowscriptaccess="always" src="http://www.youtube.com/v/89TRXUm8jMI&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0xe1600f&amp;color2=0xfebd01" type="application/x-shockwave-flash"></object></p>
<p>《Super Mario Bros. 3》中的死区是非常窄的一个竖条，几乎不被察觉，但它确实存在于此。死区通常会非常微小——直到阅读了 <a href="http://www.steveswink.com/" target="_blank">Steve Swink</a> 超级棒的书 <a href="http://www.amazon.com/gp/product/0123743281?ie=UTF8&#038;tag=tinysubversio-20" target="_blank">Game Feel</a> 以后，我们才留意到它。</p>
<h2>死区的实现</h2>
<p>我们将创建一个新的摄影机函数，跟 centerCamera 函数一样，我们向其传递玩家对象和整个地图的尺寸信息。将这部分代码放在 </script> 标签前。</p>
<pre class="brush: jscript; title: ; notranslate">
	function followCamera(obj,viewdata) {
	}
</pre>
<p><img src='http://bostongamejams.com/wp-content/uploads/2010/06/deadzone012.png' /><br />
这个图片阐明了摄影机、死区、地图和玩家的位置关系。</p>
<p>死区的数学原理是很简单的，先让你有个简单的了解。首先是定义 xbuf 和 ybuf，用于指定死区的缓冲区域的大小，就像上图所示那样。我们也需要知道摄影机当前的 x 和 y 的位置。我们在函数内定义这些：</p>
<pre class="brush: jscript; title: ; notranslate">
	xbuf = 96;
	ybuf = 96;
	xcam = gbox.getCamera().x;
	ycam = gbox.getCamera().y;
</pre>
<p>我们设置死区的宽高都是 96 像素，并且调用 gbox.getCamera 函数获取摄影机对象用于计算。</p>
<p>由于在玩家出了死区后需要移动摄影机，我们需要编写代码来检测这种情况。</p>
<p><img src="http://bostongamejams.com/wp-content/uploads/2010/06/deadzone02.png" /><br />
这展示了当对象离开死区时重新计算摄影机位置的情况。</p>
<p>让我们从玩家向右移动开始。就像你看到的上面的图那样，玩家相对于死区向右移动时，（obj.x – xcam）表示屏幕左边到玩家对象的距离，这是大于屏幕左边到死区最右边的距离（gbox._screenw – xbuf）的。如果前一个距离大于后一个，就需要向右移动摄影机，距离是它们之间的差值，这样玩家精灵总是跟死区的最右边保持一定距离。代码看起来是这样的，向死区的右边移动，然后给 xcam 变量增加一个距离，并将摄影机定位到这个新数值上：</p>
<pre class="brush: jscript; title: ; notranslate">
	if ((obj.x - xcam) &gt; (gbox._screenw - xbuf)) gbox.setCameraX( xcam + (obj.x - xcam)-(gbox._screenw - xbuf),viewdata);
</pre>
<p>同样的，我们希望知道什么时候玩家对象到屏幕左边的距离（obj.x-xcam）小于死区左边（xbuf）到屏幕左边的距离。就像上面一样，我们计算这个差值，不过这次是从 xcam 减出来的负数，并向左移动摄影机。</p>
<pre class="brush: jscript; title: ; notranslate">
	if ((obj.x - xcam) &lt; (xbuf)) gbox.setCameraX(xcam + (obj.x - xcam) - (xbuf),viewdata);
</pre>
<p>幸运的是，我们可以替换“x”为“y”并且替换“w”为“h”就得到了 y 轴的相同算法，不同变量的代码。</p>
<pre class="brush: jscript; title: ; notranslate">
	if ((obj.y - ycam) &gt; (gbox._screenh - ybuf)) gbox.setCameraY( ycam + (obj.y - ycam)-(gbox._screenh - ybuf),viewdata);
	if ((obj.y - ycam) &lt; (ybuf)) gbox.setCameraY(ycam + (obj.y - ycam) - (ybuf),viewdata);
</pre>
<p>好了，就是这样。完整的 followCamera() 代码看起来是这样的：</p>
<pre class="brush: jscript; title: ; notranslate">
	function followCamera(obj,viewdata) {
	  xbuf = 96;
	  ybuf = 96;
	  xcam = gbox.getCamera().x;
	  ycam = gbox.getCamera().y;

	  if ((obj.x - xcam) &gt; (gbox._screenw - xbuf)) gbox.setCameraX(xcam + (obj.x - xcam) - (gbox._screenw - xbuf), viewdata);
	  if ((obj.x - xcam) &lt; (xbuf))                 gbox.setCameraX(xcam + (obj.x - xcam) - xbuf,                   viewdata);
	  if ((obj.y - ycam) &gt; (gbox._screenh - ybuf)) gbox.setCameraY(ycam + (obj.y - ycam) - (gbox._screenh - ybuf), viewdata);
	  if ((obj.y - ycam) &lt; (ybuf))                 gbox.setCameraY(ycam + (obj.y - ycam) - ybuf,                   viewdata);
	}
</pre>
<h2>添加新的摄影机</h2>
<p>最后，我们只要用新的摄影机函数替换 gbox.centerCamera 函数。回到 addMap 函数中，用 followCamera 替换 gbox.centerCamera，就像这样：</p>
<pre class="brush: jscript; title: ; notranslate">
	// 将玩家对象至于摄影机中央。map.w 和 map.h 数据告诉摄影机什么时候碰撞到地图边缘，以便停止卷动。
	followCamera(gbox.getObject('player', 'player_id'), { w: map.w, h: map.h });
</pre>
<h2>Lights, something, action!</h2>
<p>代码最终完成后应当像<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut4_scrolling_map/index.html" target="_blank">这样</a>。这里有个视频演示了期望的行为，在屏幕的中央有一个死区，这样微小的移动不会造成摄影机移动（youtubo 视频，翻墙吧！）。</p>
<p><object width="640" height="505" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"><param value="true" name="allowFullScreen"><param value="always" name="allowscriptaccess"><param value="http://www.youtube.com/v/ylHXo98G1hM&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0xe1600f&amp;color2=0xfebd01" name="src"><param value="true" name="allowfullscreen"><embed width="640" height="505" allowfullscreen="true" allowscriptaccess="always" src="http://www.youtube.com/v/ylHXo98G1hM&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0xe1600f&amp;color2=0xfebd01" type="application/x-shockwave-flash"></object></p>
<p><a href="http://www.mikespook.com/index.php/akihabara-tutorial" target="_blank">Akihabara 指南目录</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e5%9b%9b%e9%83%a8%e5%88%86%ef%bc%9a%e5%9c%b0%e5%9b%be%e7%9a%84%e5%8d%b7%e5%8a%a8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[翻译]Akihabara 指南，第三部分：基本的地图</title>
		<link>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%89%e9%83%a8%e5%88%86%ef%bc%9a%e5%9f%ba%e6%9c%ac%e7%9a%84%e5%9c%b0%e5%9b%be/</link>
		<comments>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%89%e9%83%a8%e5%88%86%ef%bc%9a%e5%9f%ba%e6%9c%ac%e7%9a%84%e5%9c%b0%e5%9b%be/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 08:13:08 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Stardy & Research]]></category>
		<category><![CDATA[akihabara]]></category>
		<category><![CDATA[game engine]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=658</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
原文：http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-3-basic-mapping/

Akihabara 指南，第三部分：基本的地图

Darius Kazemi 编写于 2010 年 06 月 14 日

<span class="readmore"><a href="http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%89%e9%83%a8%e5%88%86%ef%bc%9a%e5%9f%ba%e6%9c%ac%e7%9a%84%e5%9c%b0%e5%9b%be/" title="[翻译]Akihabara 指南，第三部分：基本的地图">阅读全文——共6989字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>原文：<a href="http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-3-basic-mapping/" target="_blank">http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-3-basic-mapping/</a></p>
<h1>Akihabara 指南，第三部分：基本的地图</h1>
<p><em>Darius Kazemi 编写于 2010 年 06 月 14 日</em></p>
<p><span id="more-658"></span></p>
<p>这是系列指南的第三部分，我们将向你演示如何使用基于 HTML5 和 JavaScript 的 Akihabara 框架来编写 8 向射击游戏。<a href="http://www.kesiev.com/akihabara/" target="_blank">Akihabara</a> 是一个利用 HTML5 功能帮助创建游戏的 Javascript 库。使用 HTML5 编写游戏最棒的事情是你可以在任何平台、任何支持 HTML5 的浏览器运行它。这包括 Chrome，Firefox，Safari 和 iPhone/iPad，WebOS 设备上的 WebKit 浏览器，或者其他移动平台。</p>
<p>在这一部分，我们将向你演示如何在游戏中创建一个包含可见的背景的地图，地图中的“墙”是可碰撞的，这样我们在第二部分中实现的玩家对象碰到的时候，就会停下来。在快速开发游戏的时候 Akihabara 的一个最好的功能之一，就是创建一个基本的地图的过程是相当的容易。所以，这部分将是一个简短的指南，不过我们仍然会花一些时间用于理清这个基本地图的核心思想上面。而且，我们添加了碰撞，所以玩家对象可以撞到墙上去。</p>
<h2>成品</h2>
<p>本次课程结束后，你会得到类似<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut3_basic_mapping/" target="_blank">这样</a>的一个游戏。按下 Z 越过标题屏幕，然后使用方向键移动。注意你是如何同墙碰撞的！</p>
<h2>定义地图</h2>
<p>在 Akihabara 中，定义地图是非常容易的。你只需要调用 help.asciiArtToMap 函数，然后用 ASCII 绘制出来！我们将在 main 函数后面，写一个叫做 load_map 的函数。看起来是这样的：</p>
<pre class="brush: jscript; title: ; notranslate">
	function loadMap() {
	  return help.asciiArtToMap([
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xxxxxxxxxxxxxxxx            xx        xx&quot;,
	&quot;xxxxxxxxxxxxxxxx            xx        xx&quot;,
	&quot;xx                          xx        xx&quot;,
	&quot;xx                          xx        xx&quot;,
	&quot;xx                          xx        xx&quot;,
	&quot;xx                          xx        xx&quot;,
	&quot;xx                          xx        xx&quot;,
	&quot;xx                          xx        xx&quot;,
	&quot;xx          xxxxxxxx   xxxxxxxxxxxxxxxxx&quot;,
	&quot;xx          xxxxxxxx   xxxxxxxxxxxxxxxxx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xxxxxxxx                              xx&quot;,
	&quot;xxxxxxxx                              xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx            xxxxxxxxxxxxxxxxxx      xx&quot;,
	&quot;xx            xxxxxxxxxxxxxxxxxx      xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xx                                    xx&quot;,
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;,
	    ], [ [null, ' '], [0, 'x'] ])
	}
</pre>
<p>help.asciiArtToMap 函数接受两个参数。第一个传递的是持久化的描绘地图的字符数组——很容易看出，我们使用“x”和“ ”（空格）字符绘制了地图。然后，我们传递了一个翻译数组，一个数组的数组，格式类似</p>
<pre class="brush: jscript; title: ; notranslate">
[ [null, char1], [0, char2], [1, char3] ]
</pre>
<p>你至少需要一个 null 的条目，紧接着数字条目的对应想要渲染的瓦片。null 条目映射 char1（在这个例子里是“ ”（空格））到空白位置。接下来的映射对应地图的 tilesheet 部分。在上面的例子中，我们映射“x”到 tilesheet 中编号0（第一个）的瓦片。在这个例子中，我们只有一个瓦片，所以不需要继续定义更多的瓦片了。</p>
<h2>加载地图的瓦片</h2>
<p>在 Akihabara 引擎中，地图只是游戏世界中的一个对象，跟第二部分那个可移动的精灵一样。跟可移动的玩家对象一样，需要渲染一个图像，所以我们将从加载<br />
用于渲染墙的图片开始。我们使用的图片叫做 <a href="http://tools.bostongamejams.com/akihabara_tutorials/tut3_basic_mapping/map_pieces.png" target="_blank">map_pieces.png</a>，你需要系在并保存在 index.html 相同目录。</p>
<pre class="brush: jscript; title: ; notranslate">
	function loadResources() {
	...
	  // ** 这些代码在 gbox.addFont() 之前 **
	  // 添加提供“墙”的地图精灵表
	  gbox.addImage('map_spritesheet', 'map_pieces.png');

	  // 瓦片集合从精灵表中获得
	  gbox.addTiles({
	    id:      'map_pieces',
	    image:   'map_spritesheet',
	    tileh:   8,
	    tilew:   8,
	    tilerow: 1,
	    gapx:    0,
	    gapy:    0
	  });
</pre>
<h2>main() 方法的改动</h2>
<p>下面，我们将更新 main 方法。首先要做的是修改 main 函数中的 gbox.setGroups 调用，添加用于渲染地图本身的组。我们将把这个组叫做‘background’并将其放到数组定义的第一个，这样它会被首先渲染。这样做的原因是我们希望 ‘player’ 和 ‘game’ （玩家精灵和 UI 元素）组在墙的上层被渲染。</p>
<pre class="brush: jscript; title: ; notranslate">
	function main() {
	  // ** 在第三部分中，我们在下面的行中添加了 ‘background’ **
	  gbox.setGroups(['background', 'player', 'game']);
</pre>
<p>接着，我们跳转到 maingame.initializegame 函数。在紧接着 addPlayer 调用的位置，我们添加 addMap 调用。现在还没有定义这个函数，但是就像 addPlayer 添加玩家对象到游戏世界一样，addMap 将会添加地图。由于这个在 maingame.initializegame 内调用，在游戏第一次加载的时候，会被执行一次。</p>
<pre class="brush: jscript; title: ; notranslate">
	maingame.initializeGame = function() {
	  // 来自于第二部分的代码……
	  addPlayer();

	  // 这里我们创建了背景对象，它在每次游戏世界被渲染的时候，被绘制在‘background’层。
	  addMap();
	};
</pre>
<p>在完成了 maingame.initializeGame 函数的定义后，我们定义 map 函数本身。地图是一个包含三个信息的结构体：tileset，是我们在 loadResources 中定义的地图的瓦片集合的名字；map，实际上通过调用上面的 load_map 函数从 ASCII 艺术中转换地图信息；然后还有 tileIsSolid 函数，内建的碰撞代码，判断哪个瓦片是可碰撞的，哪个不是。例如，草地的瓦片不可碰撞，而墙的瓦片则可碰撞。</p>
<pre class="brush: jscript; title: ; notranslate">
	// 这里我们定义了地图，包括 tileset，实际的地图数据，以及碰撞的帮助函数
	map = {
	  tileset: 'map_pieces', // 指定使用 loadResources 函数中创建的‘map_pieces’瓦片

	  // 这里加载了 ASCII 码定义的地图的内容，用数组的形式定义了整数编号作为类型的地图瓦片
	  // 每个‘类型’对应 tileset 的一个精灵。例如地图瓦片有类型 0，则使用地图瓦片（上面定义的‘map_pieces’）中的第一个精灵
	  // 如果地图瓦片有类型 1，则使用地图瓦片中的第二个精灵，以此类推。
	  // 同时，需要注意类型 null 也是被接受的，不使用地图瓦片中的任何精灵
	  map: loadMap(),

	  // 如果检测到对象‘obj’所在的瓦片‘t’是墙的话，这个函数返回 true，所以……
	  tileIsSolid: function(obj, t) {
	    return t != null; // 如果不是空地，就是墙
	  }
	}
</pre>
<p>（补充一下：虽然在调用 addMap 之后才定义地图，但是要记得 addMap 只是一个函数定义！在 main 函数结束前的 gbox.go 调用时，才会真正执行。所以，安顺序说：我们告诉游戏准备好调用 addMap，然后定义了地图，然后 addMap 才真正执行。）</p>
<p>在定义了地图之后，我们调用 help.finalizeTilemap，用来计算并且正确设置 map.h 和 map.w，也就是地图的高和宽。</p>
<pre class="brush: jscript; title: ; notranslate">
	// 这个函数通过统计瓦片的数量，来计算地图完整的宽高。
	map = help.finalizeTilemap(map);
</pre>
<p>当我们执行 gbox.createCanvas 时，传递 map.h 和 map.w 设定地图画布的尺寸。画布是地图实际绘制的位置，所以接下来调用 gbox.blitTilemap 真正在画布上绘制地图。</p>
<pre class="brush: jscript; title: ; notranslate">
	  // 地图最终的宽高被计算出来的时候，就可以创建适合于地图的画布了。就叫画布为“map_canvas”。
	  gbox.createCanvas('map_canvas', { w: map.w, h: map.h });

	  // 这个函数从“map”对象中获取地图，并将其绘制到“map_canvas”。这样地图就在渲染管道中了。
	  gbox.blitTilemap(gbox.getCanvasContext('map_canvas'), map);

	  gbox.go();
	}
</pre>
<p>然后，跟之前一样在 main 函数结束前调用 gbox.go。</p>
<h2>添加地图对象</h2>
<p>现在，在 addPlayer 函数定义之前，定义 addMap 函数。addMap 函数向游戏世界添加地图。之前的代码中，我们告诉 Akihabara 在游戏初始化时，玩家对象已经被添加后调用。下面是 addMap：</p>
<pre class="brush: jscript; title: ; notranslate">
	// 这是用于添加地图对象的函数——以确保游戏主要代码优质且简明
	function addMap() {
	  gbox.addObject({
	    id:    'background_id', // 这是对象 ID
	    group: 'background',    // 我们使用之前‘setGroups’调用中创建的‘backround’组

	    // blit 函数说明了游戏绘制圆的时候发生了什么。所有跟渲染和绘制有关的内容都放在了这里
	    blit: function() {
	      // 首先，擦除整个屏幕。blitFade 填充制指定的矩形区域（在这个例子中，就是屏幕）
	      gbox.blitFade(gbox.getBufferContext(), { alpha: 1 });

	      // 由于我们在 main 函数中已经将将 tilemap 渲染到了‘map_canvas’，现在可以将‘map_canvas’绘制到屏幕。
	      // ‘map_canvas’仅仅是 tilemap 的一个图片，在这里渲染，以确保在每帧都被重绘。
	      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 });
	    }
	  });
	}
</pre>
<p>这跟玩家对象相比是非常简单的。我们定义了对象 ID；将其指定它到‘background’组，以便让其在其他所有对象渲染前被渲染；然后我们定义了 blit 函数，用于擦除屏幕和绘制地图。blit 函数绘制 map_canvas 的内容——还记得吗，我们在 main 函数中保存了一个地图的图像在 map_canvas 中。 所以我们只需要确保在每帧重绘这个图像。这就是地图对象！</p>
<h2>修复……呃，问题</h2>
<p>对于已经讨论过擦除屏幕，这里必须要澄清一下。我们在第二部分的指南里范了个错误。为了方便起见，我们让你在玩家对象的 blit 函数中擦除屏幕。这绝对是错误的。像你在上面看到的那样，背景是最佳的擦除屏幕的地方。这是因为它是第一个被渲染的，所以如果期望擦除上一屏幕，则直接渲染背景以及其上的所有内容。否则，我们会在玩家对象中将背景（也就是地图）也擦除，这是我们所不希望的。</p>
<p>我们需要从第二部分的旧的玩家对象的代码中删除下面的两行：</p>
<pre class="brush: jscript; title: ; notranslate">
	// 擦除屏幕
	gbox.blitFade(gbox.getBufferContext(), {});
</pre>
<p>对这个真实抱歉啊！</p>
<h2>添加碰撞</h2>
<p>我们要感谢 Akihabara，对玩家对象添加碰撞是相当简单的。首先要做的是重定义碰撞盒，一个不可见的套在玩家对象外面的盒子，用来计算碰撞的发生。新的代码添加在 tileset 定义之后。</p>
<pre class="brush: jscript; title: ; notranslate">
	function addPlayer() {
	  gbox.addObject({
	    id:      'playerid',    // 对象引用的 ID
	    group:   'player',       // 渲染组
	    tileset: 'playerTiles', // tileset 表示图像的来源

	    // ** 第三部分的新代码 **
	    // 我们重写了对象的 colh 属性的默认值。“colh”表示碰撞的高度，这个高是我们的碰撞盒的高度。
	    colh:gbox.getTiles('playerTiles').tileh,
</pre>
<p>colh 属性是顶视图对象的默认属性。它表示“碰撞高度”，也就是碰撞盒的高度。对象同时也有 colw（碰撞盒宽度）和 colx 以及 coly （碰撞盒的 x/y 偏移量）。</p>
<p>我们重写 toys.topview 对象的 colh 的值，是因为 colh 的默认值被设定为精灵高度的一半。这是因为顶视图通常使用在《塞尔达》模式的游戏，它们的碰撞盒只有精灵的下半部分，上半部分可以遮盖在其后的布景上。因此，我们需要设置 colh 为默认的瓦片高度， 这样对于我们的圆型，碰撞盒可以想象成这个圆的外切正方形。</p>
<p>在我们的初始化函数中，设置了玩家的初始位置为 (20, 20) 代替默认的 (0, 0)。这样做是因为在 (0, 0) 有瓦片存在，所以如果玩家从这个坐标开始，他会被永远卡住！</p>
<pre class="brush: jscript; title: ; notranslate">
	initialize: function() {

	  // 这里我们初始化对象，也就是玩家。
	  toys.topview.initialize(this, {});

	  // ** 第三部分的新代码 **
	  // 然后设置玩家的新的初始位置。
	  this.x = 20;
	  this.y = 20;
	},
</pre>
<p>最后在 first 函数中，我们在改变应用到对象后检查碰撞。</p>
<pre class="brush: jscript; title: ; notranslate">
	first: function() {
	  // Toys.topview.controlKeys 设置主要的控制按键。在这个例子中，我们使用映射到英文名字的方向键。
	  // 在这个函数中，它根据方向应用加速度。
	  toys.topview.controlKeys(this, { left: 'left', right: 'right', up: 'up', down: 'down' });

	  // 这个添加了加速度的控制，这样当没有加速度的时候就会停下来，否则游戏控制就会像 Asteroids 那样。
	  toys.topview.handleAccellerations(this);

	  // 这告诉物理引擎产生实际的影响
	  toys.topview.applyForces(this);

	  // ** 第三部分的新代码 **

	  // 这里我们通过 colx、coly、colh 和 colw 参数来设置碰撞盒的边缘。因为我们的精灵是圆的，所以容差设置为 6。
	  // 容差设置为 6 让我们的对象圆角的感觉更好一些，而不会过于尖锐的感觉。
	  // 我们通过尝试和错误得到这个数值——通常来说，容差应当是 0 到你的精灵的宽或者高的一半的某个数值。
	  // 当然，在代码中它被拼写为 “tollerance”！
	  toys.topview.tileCollision(this, map, 'map', null, { tollerance: 6, approximation: 3 });
	},
</pre>
<p>我们将碰撞检测放到移动应用到对象后进行，是因为 tileCollision 函数通过检测象是否跟地图上的固有瓦片重叠。如果是，则立刻让对象离开瓦片。最基本的就是设置回对象移动前的位置，这样结果看起来就像我们期望的那样。 </p>
<p>tileCollision 函数本身得到玩家对象、地图对象、一个叫做‘map’的字符串（我们也不确定它具体应该是做什么的），和无须关心的 null 值，以及容差[sic]和误差。</p>
<p>参数容差决定了碰撞检测算法的严格程度。通常，容差决定了碰撞盒的边缘有多“圆滑”。我们测试了一大堆数，最后决定使用 6。</p>
<p>参数误差决定了碰撞检测算法的精确程度。通常来说，越小的数字，碰撞检测越精密。注意：越精密的算法，需要越多的资源。然后，我们通过不断尝试和错误得到 3。要小心的是误差设置为 0 或者更小的值会让你的游戏挂掉！</p>
<h2>撞进墙：来自于传统视频游戏 Breakout</h2>
<p>你现在可以保存 HTML 文件，然后在合适的浏览器里打开；你应当看到这样的内容。你会看到第一部分的标题屏幕。按 Z 键跳过标题屏幕，一个蓝色的圆会显示在屏幕上，被漂亮的迷宫包围。用方向键控制这个圆，并且享受撞墙的快乐吧！</p>
<p><a href="http://www.mikespook.com/index.php/akihabara-tutorial" target="_blank">Akihabara 指南目录</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%89%e9%83%a8%e5%88%86%ef%bc%9a%e5%9f%ba%e6%9c%ac%e7%9a%84%e5%9c%b0%e5%9b%be/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[翻译]Akihabara 指南，第二部分：精灵的移动</title>
		<link>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%ba%8c%e9%83%a8%e5%88%86%ef%bc%9a%e7%b2%be%e7%81%b5%e7%9a%84%e7%a7%bb%e5%8a%a8/</link>
		<comments>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%ba%8c%e9%83%a8%e5%88%86%ef%bc%9a%e7%b2%be%e7%81%b5%e7%9a%84%e7%a7%bb%e5%8a%a8/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 13:51:50 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Stardy & Research]]></category>
		<category><![CDATA[akihabara]]></category>
		<category><![CDATA[game engine]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=635</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
原文：http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-2-moving-a-sprite/

Akihabara 指南，第二部分：精灵的移动

Darius Kazemi 编写于 2010 年五月 21 日

<span class="readmore"><a href="http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%ba%8c%e9%83%a8%e5%88%86%ef%bc%9a%e7%b2%be%e7%81%b5%e7%9a%84%e7%a7%bb%e5%8a%a8/" title="[翻译]Akihabara 指南，第二部分：精灵的移动">阅读全文——共6091字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>原文：<a href="http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-2-moving-a-sprite/" target="_blank">http://bostongamejams.com/akihabara-tutorials/akihabara-tutorial-part-2-moving-a-sprite/</a></p>
<h1>Akihabara 指南，第二部分：精灵的移动</h1>
<p><em>Darius Kazemi 编写于 2010 年五月 21 日</em></p>
<p><span id="more-635"></span></p>
<p>这是系列指南的第二部分，我们将向你演示如何使用基于 HTML5 和 JavaScript 的 Akihabara 框架来编写 8 向射击游戏。<a href="http://www.kesiev.com/akihabara/" target="_blank">Akihabara</a> 是一个利用 HTML5 功能帮助创建游戏的 Javascript 库。使用 HTML5 编写游戏最棒的事情是你可以在任何平台、任何支持 HTML5 的浏览器运行它。这包括 Chrome，Firefox，Safari 和 iPhone/iPad，WebOS 设备上的 WebKit 浏览器，或者其他移动平台。</p>
<p>在这个部分中，我们将向你演示如何渲染精灵到屏幕上，并且移动它。这个指南包含精灵的渲染、输入、基本的游戏对象创建和控制。我们将在<a href="http://www.mikespook.com/index.php/archives/622" target="_blank">第一部分</a>创建的基础上进行开发，所以将假设你已经完成了第一部分的指南。</p>
<h2>成品</h2>
<p>在<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut2_moving_sprite/">这里</a>查看本课结束后的成果。按“Z”键跳过标题屏幕，然后使用方向键控制圈点移动。</p>
<h2>整体思路</h2>
<p>现在，我们将开始编写实际的游戏代码，我们需要回头看看，考虑一下视频游戏的屏幕是怎么样的。</p>
<p>游戏是由相互作用的对象组成：在像《太空侵略者》这样的游戏中，对象包括玩家的飞船、敌人、护盾和子弹。然后，我们设定对象行为的规则。一个敌人的对象可能包含代码，说“向前和向后移动我，当碰到屏幕边缘时消失。在一个随机的时间间隔中，向前进方向上射击。”</p>
<p>对象是游戏的核心组件，但是只有一大堆对象并不是游戏。我们需要将这些对象放在世界中，并提供一个整体的概念：“在玩家的四个方向上放置 10 个敌人。”；“玩家对象死亡三次后游戏结束。”</p>
<p>Akihabara 是一个基于对象的游戏引擎。在指南的这一部分，我们将尝试创建第一个玩家对象，定义它的行为，然后将它放入游戏世界中。在这个部分的指南中，不会有其他相互作用的对象或者游戏的整体概念出现——我们刻意略过这些在以后的指南中会出现的内容。</p>
<h2>玩家对象</h2>
<p>我们的玩家对象将会包含一些定义。我们会通过指定一个精灵来定义对象的外观（一个 2D 的图形，等一下详细说），并且设置它的控制方式，以及如何移动。</p>
<h2>精灵</h2>
<p>精灵是图片的梦幻般的称呼，或者说用代码来控制的一组图像。它是关联到游戏对象的图形，并且是这个对象的图形化描述。</p>
<p>我们的精灵将使用的图像是这个蓝色的圆形：<a href="http://tools.bostongamejams.com/akihabara_tutorials/tut2_moving_sprite/playerSprite.png" target="_blank">playerSprite.png</a>。这是一个 PNG 文件：Akihabara 可以处理透明的 PNG 文件，所以它可以正确渲染含有透明部分的 PNG，所以你可以穿过去看到背景。虽然图像本身是 16 x16 像素的方块，在我们的游戏中它将是一个圆形。下载并保存到 index.html 的同一目录下，跟第一部分中的其他 PNG 文件一样。</p>
<p>为了在游戏中使用这个精灵，我们需要像其他图像一样单独加载它。打开第一部分的代码，添加下面的代码到 loadResources 紧接着加载 logo.png 文件的那行下面。</p>
<pre class="brush: jscript; title: ; notranslate">
	gbox.addImage('logo', 'logo.png');

	// ** 下面是第二部分代码 **

	// 在这里添加我们的圆形主角
	gbox.addImage('playerSprite', 'playerSprite.png');

	// 在这里剪切精灵层，设置格子的尺寸，每行的精灵数和间隙。
	gbox.addTiles({
	  id:      'playerTiles', // 设置一个唯一的 ID，以便将来调用
	  image:   'playerSprite', // 使用上面加载的‘精灵’图像
	  tileh:   16,
	  tilew:   16,
	  tilerow: 1,
	  gapx:    0,
	  gapy:    0
	});
</pre>
<p>首先，我们调用第一部分已经学过的 gbox.addImage 加载 PNG 文件。</p>
<p>然后调用 gbox.addTiles。许多 2D 游戏引擎支持<strong>精灵表（sprite sheet）</strong>，它是一张大图，含有若干相同尺寸、按格网排列的小图。精灵图被剪切，并通过定义网格的尺寸和每行、每列的格子数量建立<strong>瓦片地图（tile map）</strong>。游戏引擎可以通过瓦片的编号访问到每个瓦片——2D 的动画可以定义为一格一个接一个的显示瓦片。</p>
<p>gbox.addTiles 函数需要知道图片和其拆分方式。你可以单独指定每个瓦片的高和宽，以及每行希望有多少个瓦片。我们的圆形是 16×16 像素，所以我们设置 tileh 和 tilew （高和宽）为 16。在这个例子中我们仅仅处理一个格，所以我们让它每行只用一个瓦片。gapx 和 gapy 变量定义每个格之间有多少偏移量（或者说需要忽略的“空白”），这里我们设为 0。</p>
<p>过一会我们定义玩家对象时，会使用我们定义的 playerTiles ID 来访问。</p>
<h2>玩家对象的结构</h2>
<p>定义一个对象的代码是非常冗长的，所以我们首先看一下定义一个对象的大致结构，然后再讨论一些特殊的实现。下面是部分从我们的对象中摘抄出的部分代码，包括了 addPlayer 函数。先参照注释阅读一遍代码，应当是相当清晰的。</p>
<pre class="brush: jscript; title: ; notranslate">
	function main() {
	  // 第一部分的代码放在这里
	}

	// 添加玩家对象的包裹函数——这是我们良好并且清晰的游戏的主要代码
	function addPlayer() {
	  // gbox.addObject 用变量和方法创建一个游戏中的新对象。在这里我们创建了玩家。
	  gbox.addObject({
	  // id 指向指定的对象，group 用于渲染的分组，tileset 指定了图像的来源
	    id: 'playerid',
	    group: 'player',
	    tileset: 'playerTiles',

	  // 包含了对象第一次被创建时的初始化函数。在这里玩家对象只出现一次，要么是游戏开始，要么是玩家死亡然后重来。
	    initialize: function() {
	  // ...
	    },

	    // first 函数是一个单步函数。它在每帧运行处理碰撞。被称为 first 是因为在渲染前执行，这样我们计算出新的位置和动作，&lt;strong&gt;然后&lt;/strong&gt;渲染对象
	    first: function() {
	      // ...
	    },

	    // blit 函数说明了游戏绘制圆的时候发生了什么。所有跟渲染和绘制有关的内容都放在了这里
	    blit: function() {
	      // ...
	    },
	  }); // 玩家的 gbox.addObject 结束
	} // 结束 addPlayer()
</pre>
<p>在 main 函数后面我们创建了addPlayer 函数用于封装，以保证我们的游戏主要代码清晰。这个函数在内部调用 gbox.addObject 进行了大量的设置。</p>
<p>最开始要做的是定义一些基本的识别变量。首先，为 玩家对象指定了 id，这样可以在其他函数中使用它。然后设置了组 ID，用于渲染的顺序。这让我们实现了“确保在背景组之上绘制玩家组的所有内容”，所以就不会发生玩家消失在背景之后的事情。然后我们设置了对象的 tileset 为‘playerTiles’，这是之前我们 tilemap 的图像的 ID。</p>
<p>剩下的部分分为三个函数：initialize， first 和 blit。</p>
<p>initialize 函数包含的所有代码在对象创建时运行一次以后再也不执行了。这通常包括如最大生命值、初始速度和对象的任何可以进行“设置”的内容。</p>
<p>first 函数在游戏图像绘制前的每一帧执行。游戏帧是一个用于计算和更新对象行为的小的时间片段。我们将对象的所有行为放在这个函数内，例如检查玩家的输入、检查一个对象是否同其他对象碰撞、根据当前的速度更新位置，更新人工智能等等。许多我们认为的“游戏编程”的内容都在这个函数内实现。</p>
<p>blit 函数包括对象的所有渲染代码。如果必须对在屏幕上显示图像做一些处理，就是在这里进行。跟 first 函数一样，在每帧都会调用，只不过是紧接着 first 函数。这是因为我们希望首先更新自己的位置，然后在屏幕上用已经更新过的位置绘制精灵。</p>
<p>下面的三个章节我们将讨论在这三个函数里放些什么内容。</p>
<h2>initialize 函数</h2>
<p>在这个例子中，我们的函数是空白的：</p>
<pre class="brush: jscript; title: ; notranslate">
	initialize: function() {
	  // Toys 是用于指定确切样式的帮助函数。
	  // 为了创建顶视图，我们使用“topview”这个 Akihabara 提供的帮助函数实现它。

	  // 这里我们只是调用并初始化玩家对象。
	  toys.topview.initialize(this, {
	  });
	},
</pre>
<p>上面的代码我们告诉游戏使用 toys.topview 类型初始化玩家对象，所有需要的初始化在 toys.topview 中完成。这对于下面的 first 和 blit 是很方便的。</p>
<h2>first 函数</h2>
<p>在 first 函数中，我们告诉对象在游戏的每一帧，它应当检查方向键是否被按下，并根据按键修改对象的加速度，告诉物理引擎这是对象的加速度，并强制对象更新对象的位置。</p>
<pre class="brush: jscript; title: ; notranslate">
	first: function() {
	  // Toys.topview.controlKeys 设置主要的控制按键。在这个例子中，我们使用映射到英文名字的方向键。
	  // 在这个函数中，它根据方向应用加速度。
	  toys.topview.controlKeys(this, { left: 'left', right: 'right', up: 'up', down: 'down' });

	  // 这个添加了加速度的控制，这样当没有加速度的时候就会停下来，否则游戏控制就会像 Asteroids 那样。
	  toys.topview.handleAccellerations(this);

	  // 这告诉物理引擎产生实际的影响
	  toys.topview.applyForces(this);
	},
</pre>
<p>toys.topview.controlKeys 函数是一个帮助函数，用于映射每个方向上的加速度到控制键。在这个例子中，我们希望映射到方向键，所以这个函数最终实现了这个功能：是的，左是左，右是右。但是有时，需要编程实现这些功能。</p>
<p>当我们调用 toys.topview.handleAccellerations （是的，这里的函数名拼写有错误），我们是在告诉游戏引擎如果没有在指定方向上的加速度，则减速到 0。如果我们不使用这个函数，我们的玩家对象会在冰面上一样。在这里我们必须实现摩擦力。</p>
<p>toys.topview.applyForces 函数提供了根据最后的位置，以及当前的速度和加减速度确定新的位置。这是实际的移动发生的位置。</p>
<h2>blit 函数</h2>
<p>在 blit 函数中要做的事情是清除屏幕，然后根据新的位置绘制玩家对象。</p>
<pre class="brush: jscript; title: ; notranslate">
	blit: function() {
	  // 清除屏幕。
	  gbox.blitFade(gbox.getBufferContext(),{});

	  // 渲染当前的精灵……不要担心这里接下来的内容。我们将使用默认的绘制函数处理 tileset、帧信息、坐标、精灵是否进行切换，摄像机信息和 alpha 透明值。
	  gbox.blitTile(gbox.getBufferContext(), {
	    tileset: this.tileset,
	    tile:    this.frame,
	    dx:      this.x,
	    dy:      this.y,
	    fliph:   this.fliph,
	    flipv:   this.flipv,
	    camera:  this.camera,
	    alpha:   1.0
	  });
	},
</pre>
<p>gbox.blitFade 函数清除屏幕——调用 gbox.getBufferContext 获得当前的屏幕缓冲并传递进去，所以它知道要清理什么内容。</p>
<p>向 gbox.blitTile 函数传递了渲染这个瓦片的对象的信息。就像第一部分解释过的那样，“this”意味着我们正在写代码的那个对象，所以我们最终传递了当前的 tileset，当前的 x/y 坐标，和关于这个瓦片是否被垂直和水平翻转的信息（默认不进行），摄像机的信息，和 alpha 透明值 1（意味着完全不透明）。虽然我们传递了几乎 this.* 的所有数据，但只是传递了默认的值，对于现在来说足够了。</p>
<h2>main 函数的一些组成</h2>
<p>现在，我们需要对 main 函数设置一些内容，然后就大功告成了！</p>
<p>首先要做的是设置玩家对象的渲染层。在定义玩家对象的时候，我们指定这个对象到‘player’组。这里是 main 函数的首行调用 gbox.setGroups 添加 ‘player’ 组到内部的组存储的数组。</p>
<pre class="brush: jscript; title: ; notranslate">
	function main() {
	  // ** 在第二部分我们在这行之后添加了‘player’ **
	  gbox.setGroups(['player', 'game']);
</pre>
<p>gbox.setGroups 函数告诉游戏用什么顺序渲染物体。物体按照 setGroups 列出的从左到右的顺序进行渲染。通过在最开始添加‘player’组，玩家对象将会首先被渲染，但是在‘game’组的内容将会被渲染在其之上。这样做的好处是‘game’组包括类似“Game Over”的消息将会显示在玩家的精灵上。</p>
<p>现在，我们需要剔除默认的难度选择，以及 ”Let’s begin!” 消息。为了实现这个，我们只要重写这些函数，使其什么也不做。在定义 maingame 之后的代码中，编写这些重写：</p>
<pre class="brush: jscript; title: ; notranslate">
	maingame = gamecycle.createMaingame('game', 'game');
	  // ** 下面是第二部分代码 **

	  // 屏蔽默认的难度选择菜单；在我们的指南中不需要这个
	  maingame.gameMenu = function() { return true; };

	  // 屏蔽默认的“get ready”屏幕；在我们的指南中不需要这个
	  maingame.gameIntroAnimation = function() { return true; };
</pre>
<p>在 main 函数的结束，我们调用 gbox.go 去执行游戏，我们需要通过向游戏世界放置玩家对象初始化游戏。</p>
<pre class="brush: jscript; title: ; notranslate">
	  // maingame.initializeGame 是游戏对象和行为定义的地方。这是你的游戏代码存在的地方！
	  maingame.initializeGame = function() {
	    addPlayer();
	  };

	  gbox.go();
	}
</pre>
<p>maingame.initializeGame 函数中的代码设置游戏。跟之前的代码类似的方法，这里像《太空入侵者》那样设置玩家和所有的敌人。在这个代码中所要做的所有事情就是调用 addPlayer 函数初始化玩家对象。因为我们没有对玩家对象定义任何的坐标，默认的坐标是 (0,0)，相对于屏幕的顶部和左边。</p>
<p>嘿，你已经可以移动了！</p>
<p>现在你可以保存你的 HTML 文件，并在兼容的浏览器中打开；你应该看到类似这样的内容。你会看到来自于第一部分的标题屏幕。按 Z 键跳过标题屏幕，蓝色的圆形会显示在屏幕上。并可以通过键盘上的方向键进行控制。</p>
<p><a href="http://www.mikespook.com/index.php/akihabara-tutorial" target="_blank">Akihabara 指南目录</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2010/07/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%ba%8c%e9%83%a8%e5%88%86%ef%bc%9a%e7%b2%be%e7%81%b5%e7%9a%84%e7%a7%bb%e5%8a%a8/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>[翻译]Akihabara 指南，第一部分：标题屏幕</title>
		<link>http://www.mikespook.com/2010/06/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%80%e9%83%a8%e5%88%86%ef%bc%9a%e6%a0%87%e9%a2%98%e5%b1%8f%e5%b9%95/</link>
		<comments>http://www.mikespook.com/2010/06/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%80%e9%83%a8%e5%88%86%ef%bc%9a%e6%a0%87%e9%a2%98%e5%b1%8f%e5%b9%95/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 15:29:11 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[Stardy & Research]]></category>
		<category><![CDATA[akihabara]]></category>
		<category><![CDATA[game engine]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=622</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
翻序：Akihabara 是一个基于 HTML5 的 2D 游戏引擎，对 iphone 等移动平台有针对性优化。但是 Akihabara 本身文档并不十分充足，仅有一些例程参考。这个指南补充了这个不足，让学习 Akihabara 的陡峭曲线骤然平缓。在我作这个翻译的时候，作者已经完成了第四部分的编写。

原文：http://bostongamejams.com/akihabara-tutorials/akihabara-1/

Akihabara 指南，第一部分：标题屏幕

<span class="readmore"><a href="http://www.mikespook.com/2010/06/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%80%e9%83%a8%e5%88%86%ef%bc%9a%e6%a0%87%e9%a2%98%e5%b1%8f%e5%b9%95/" title="[翻译]Akihabara 指南，第一部分：标题屏幕">阅读全文——共5189字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>翻序：<a href="http://www.kesiev.com/akihabara/" target="_blank">Akihabara</a> 是一个基于 HTML5 的 2D 游戏引擎，对 iphone 等移动平台有针对性优化。但是 Akihabara 本身文档并不十分充足，仅有一些例程参考。这个指南补充了这个不足，让学习 Akihabara 的陡峭曲线骤然平缓。在我作这个翻译的时候，作者已经完成了第四部分的编写。</p>
<p>原文：<a href="http://bostongamejams.com/akihabara-tutorials/akihabara-1/" target="_blank">http://bostongamejams.com/akihabara-tutorials/akihabara-1/</a></p>
<h1>Akihabara 指南，第一部分：标题屏幕</h1>
<p><em>Darius Kazemi 编写于 2010 年五月 6 日</em></p>
<p><span id="more-622"></span></p>
<p>在这个连载的指南中，我们将向你演示如何使用基于 HTML5 和 JavaScript 的 Akihabara 框架来编写 8 向射击游戏。Akihabara 是一个利用 HTML5 功能帮助创建游戏的 Javascript 库。使用 HTML5 编写游戏最棒的事情是你可以在任何平台、任何支持 HTML5 的浏览器运行它。这包括 Chrome，Firefox，Safari 和 iPhone/iPad，WebOS 设备上的 WebKit 浏览器，或者其他移动平台。</p>
<p>在第一部分中，我们将逐步使用 Akihabara 的基本功能演示如何产生一个标题屏幕。</p>
<h2>成品</h2>
<p>在<a href="http://tools.bostongamejams.com/tutorials/8by5.html" target="_blank">这里</a>查看本指南的成品：游戏“8by5”的标题屏幕。</p>
<h2>安装 Akihabara</h2>
<p><a href="http://www.kesiev.com/akihabara/demo/akihabara-1.1.zip" target="_blank">下载 Akihabara 1.1</a> 并解压缩。Zip 文件中有一堆 Akihabara 的例子。那些值得等一会好好看看（也值得玩一下！），现在你只需要叫做 akihabara 的那个有一些按钮的图片和核心 JK 文件的目录。将 akihabara 目录放入项目目录中。然后用你喜欢的文本编辑器创建一个叫做 8by5.html 的空的文件，也放入项目目录中。最后，下载 <a href="http://tools.bostongamejams.com/tutorials/font.png" target="_blank">font.png</a> 和 <a href="http://tools.bostongamejams.com/tutorials/logo.png" target="_blank">logo.png</a> 保存它们到项目目录。项目目录现在应该包括 8by5.html，logo.png，font.png 和 akihabara 文件夹。</p>
<h2>文档结构</h2>
<p>打开 8by5.html 并创建基本的页面框架：</p>
<pre class="brush: xml; title: ; notranslate">
	&lt;html&gt;
	  &lt;head&gt;
	  &lt;/head&gt;
	  &lt;body&gt;&lt;/body&gt;
	  &lt;script&gt;
	  &lt;/script&gt;
	&lt;/html&gt;
</pre>
<p>在 head 标签中包含所有需要用到的 Akihabara JS 文件，并且为不同的显示设备设置合适的缩放信息。游戏运行的所有代码放在 script 标签。保持 body 标签为空。</p>
<h2>文档头</h2>
<p>头部是引入所需的 JS 文件的地方。在 Akihabara 1.1 中，即便有部分确定不使用的功能，你也需要引入所有的 JS 文件。头部看起来应当像这样：</p>
<pre class="brush: xml; title: ; notranslate">
	&lt;head&gt;
	  &lt;script type=&quot;text/javascript&quot; src=&quot;akihabara/gbox.js&quot;&gt;&lt;/script&gt;
	  &lt;script type=&quot;text/javascript&quot; src=&quot;akihabara/iphopad.js&quot;&gt;&lt;/script&gt;
	  &lt;script type=&quot;text/javascript&quot; src=&quot;akihabara/trigo.js&quot;&gt;&lt;/script&gt;
	  &lt;script type=&quot;text/javascript&quot; src=&quot;akihabara/toys.js&quot;&gt;&lt;/script&gt;
	  &lt;script type=&quot;text/javascript&quot; src=&quot;akihabara/help.js&quot;&gt;&lt;/script&gt;
	  &lt;script type=&quot;text/javascript&quot; src=&quot;akihabara/tool.js&quot;&gt;&lt;/script&gt;
	  &lt;script type=&quot;text/javascript&quot; src=&quot;akihabara/gamecycle.js&quot;&gt;&lt;/script&gt;
	  &lt;style&gt;BODY { -webkit-user-select: none; margin: 0px }&lt;/style&gt;
	  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;&quot; /&gt;
	&lt;/head&gt;
</pre>
<p>每个 script 标签告诉浏览器加载指定的 JavaScript 库。style 标签设置的 CSS 使得游戏在 WebKit（iPhone）中也可以渲染得很好。而 meta 标签设置了用于手机浏览器缩放的一些信息。</p>
<p>这里没有更多的头部信息了，所以让我们来看看游戏代码本身。</p>
<h2>加载资源</h2>
<p>从这里开始，我们开始讨论在 HTML 文档中，body 标签下面的主要的 script 标签里的代码。由于游戏主要是图像内容，我们需要在游戏开始前加载所有的资源。首先，我们创建游戏：</p>
<pre class="brush: jscript; title: ; notranslate">
	var maingame;
</pre>
<p>这个作为存储所有游戏信息的全局变量放在脚本的最顶部，这样我们可以在任何函数中调用它。</p>
<p>现在，我们用一些魔法以确保资源在游戏前被加载。我们将使用 JavaScript 的 <a href="http://www.javascriptkit.com/domref/windowmethods.shtml" mce_href="http://www.javascriptkit.com/domref/windowmethods.shtml" target="_blank">addEventListener</a> 函数，像这样 window.addEventListener(eventType, functionName, useCapture);</p>
<p>这短代码让 JavaScript 在发生 eventType 类型的事件后，执行叫做 functionName 的函数。这里我们不关心 useCapture，只要知道这是一个布尔值，应当被设置为 false。在我们的游戏中，将使用的 eventType 叫做“load”。我们的事件监听像这样：</p>
<pre class="brush: jscript; title: ; notranslate">
	window.addEventListener('load', loadResources, false);
</pre>
<p>这里是这段代码的作用：一旦浏览器完成加载 HTML 文档，它将执行 loadResources 函数。就这样。所以，现在我们应当定义 loadResources。下面的代码是完整的，先阅读一遍，然后我们一步一步来看。</p>
<pre class="brush: jscript; title: ; notranslate">
	function loadResources() {
	  // 用 Akihabara 的默认设置初始化
	  // 标题 (显示在浏览器标题上)是我们传递给函数的参数
	  help.akihabaraInit('8by5');

	  // 这里告诉游戏在当前目录下寻找图像 ‘font.png’，并命名为 ‘font’
	  gbox.addImage('font', 'font.png');

	  // 对 logo 做同样的事情
	  gbox.addImage('logo', 'logo.png');

	  // 字体是通过图片来映射的，设置首字母，字母尺寸，一行的长度，还有水平和垂直的间隙
	  gbox.addFont({ id: 'small', image: 'font', firstletter: ' ', tileh: 8, tilew: 8, tilerow: 255, gapx: 0, gapy: 0 });

	  // ‘main’函数注册为回调：这也就是说“当我们完成了这些，调用它”
	  gbox.setCallback(main);

	  // 当所有的都完成了，‘loadAll’下载所有需要的资源。
	  gbox.loadAll();
	}
</pre>
<p>相当简单。我们使用了默认的初始化函数，help.akihabaraInit(…)，并且传递了我们希望当作 HTML 文档标题的参数。调用 gbox.addImage(…) 加载字体和 logo。然后调用不能省略的，奇怪并且结构复杂的 gbox.addFont(…)。只需要知道这是“精灵字（sprite font）”，也就是说它看起来是一个数字、字幕和符号的大表格（在这个例子里是 font.png），并且被拆分成正确的顺序，以便知道哪个图像对应哪个字符。在我们的例子中，我们使用来自于 Akihabara 例子中的 8 x 8 像素的“精灵字”。</p>
<p>接下来的内容有些让人迷惑。调用了 gbox.setCallback(main)，用于告诉 Akihabara 当 gbox.loadAll() 完成了资源加载，调用 main() 函数，以便开始游戏！最后，调用 gbox.loadAll() 加载资源并且调用刚才设置的回调函数。</p>
<h2>现在，猛料来了</h2>
<p>现在上路了，我们创建游戏循环并开始渲染到屏幕。首先，设置基本的 main 函数，这是所有游戏代码存在的地方。</p>
<pre class="brush: jscript; title: ; notranslate">
	function main() {
	  gbox.setGroups(['game']);
	  maingame = gamecycle.createMaingame('game', 'game');

	  // 一会，我们将会在这里添加更多的代码

	  gbox.go();
	}
</pre>
<p>这个函数的第一行创建了一个叫做 “game” 的组。组用来确定游戏渲染的顺序。这个部分的指南只有一个组，所以我们并不需要过分担心它。但是最起码你要知道这是“渲染所有玩家组的内容在背景组之前，这样玩家总是在背景前面。”</p>
<p>接着一行用在最开始我们设置的全局变量 maingame 存储了一个具有状态机的游戏对象。它提供了游戏所必须的最基本的结构。调用 gamecycle.createMaingame 函数赋值 maingame 变量，使其保存所有的信息，如动画、主游戏、游戏结束、玩家死亡、游戏终止等等。我们传递了‘game’两次是为了让它知道主要操作的组，这些组就会有更高的优先权（由于我们只有一个组，所以我们还没有其他优先级）。</p>
<p>最后，我们调用 gbox.go() 告诉 Akihabara 执行游戏。</p>
<p>这时，你可以在浏览器里测试你的游戏，然后你会看到默认的标题屏幕：“GAME TITLE”。</p>
<p><b>这是因为 gamecycle.createMaingame 函数定义了默认的标题屏幕，并且足够聪明的知道标题屏幕是游戏首先应展示的。但是我们不需要默认的标题屏幕，谁会希望他们的游戏被叫做“GAME TITLE”呢？</b></p>
<h2>自定义的标题屏幕</h2>
<p>如果你深入到 gamecycle.js 中，你会发现一个叫做 gameTitleIntroAnimation() 的函数，它是真正渲染那个愚蠢的“GAME TITLE”的家伙。我们不会去直接修改 gamecycle.js —— 我们需要做的是重写这个函数，例如，用我们自己的函数替换默认的。幸运的是，在 JavaScript 中，重写一个函数你所需要做的只是使用“=”号重新定义它。将这些放在 gbox.go() 之前，替换 “我们将会在这里添加更多的代码”的注释：</p>
<pre class="brush: jscript; title: ; notranslate">
	maingame.gameTitleIntroAnimation=function(reset) {
	  if (reset) {
	    toys.resetToy(this, 'rising');
	  }

	  gbox.blitFade(gbox.getBufferContext(),{ alpha: 1 });

	  toys.logos.linear(this, 'rising', {
	    image: 'logo',
	    sx:    gbox.getScreenW()/2-gbox.getImage('logo').width/2,
	    sy:    gbox.getScreenH(),
	    x:     gbox.getScreenW()/2-gbox.getImage('logo').width/2,
	    y:     20,
	    speed: 1
	  });
	};
</pre>
<p>if 条件仅仅在 reset 为 true 时执行，是介绍动画开始前的帧。这行说明在介绍动画开始前，让 toys 类了解一个叫做“rising”的本地数据，而rising 是 maingame 对象的一部分（这是第一个我们开始工作于 maingame 内部的地方）。</p>
<p>gbox.blitFade 函数仅仅是清除屏幕。toys.logos.linear 函数设置实际显示的动画。我们让他执行于 maingame 内（就像这个例子），使用我们另外设置的 rising 保存数据，然后传递一堆数据的一个结构给它。我们传递了图片（logo），sx 和 sy（logo 一开始初始的坐标）x 和 y (logo 最终结束的坐标)，和移动的速度。告诉它图像叫做‘logo’，是最开始在 loadResources 中定义的。定义 sx 和 x 相同，这样图像在 y 坐标轴上移动，x 轴上不移动。设置屏幕宽度的一半减去 logo 宽度的一半，用来让 logo 显示在屏幕中间。然后定义 sy 跟屏幕高度相同（使得图片的顶部贴着屏幕的下边，使其不可见），y 等于 20。这使得 logo 从底部升起，直到屏幕上方 20 像素下的位置。</p>
<h2>Hello, World</h2>
<p>好，接下来！你可以在浏览器中打开这个 HTML 文件运行这个游戏，应当看到类似<a href="http://tools.bostongamejams.com/tutorials/8by5.html" mce_href="http://tools.bostongamejams.com/tutorials/8by5.html" target="_blank">这样</a>的内容。</p>
<p>你会发现，你可以按键盘上的“Z”键（在游戏中被绑定为“A”键）选择难度，然后游戏进入黑屏。这是因为 maingame 控制着游戏的整个流程，它自动产生了难度选择，然后让你进入到游戏中。由于我们还未对游戏本身进行任何的编码，所以除了黑暗，你看不到其他任何内容。</p>
<p><a href="http://www.mikespook.com/index.php/akihabara-tutorial" target="_blank">Akihabara 指南目录</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2010/06/%e7%bf%bb%e8%af%91akihabara-%e6%8c%87%e5%8d%97%ef%bc%8c%e7%ac%ac%e4%b8%80%e9%83%a8%e5%88%86%ef%bc%9a%e6%a0%87%e9%a2%98%e5%b1%8f%e5%b9%95/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ubuntu 9.10 下安装 OpenTTD 1.0.0 中文版</title>
		<link>http://www.mikespook.com/2010/04/ubuntu-9-10-%e4%b8%8b%e5%ae%89%e8%a3%85-openttd-1-0-0-%e4%b8%ad%e6%96%87%e7%89%88/</link>
		<comments>http://www.mikespook.com/2010/04/ubuntu-9-10-%e4%b8%8b%e5%ae%89%e8%a3%85-openttd-1-0-0-%e4%b8%ad%e6%96%87%e7%89%88/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 01:33:18 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[openttd]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[中文]]></category>
		<category><![CDATA[乱码]]></category>
		<category><![CDATA[方块]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=535</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
OpenTTD是开源版本的《运输大亨》，这两天刚刚发布了 1.0.0，中文汉化很完整。经本人验证，使用官方提供的 deb 包安装后，对于中文的显示需要小小调整。本着 Mr&#8217;Hu 的 BuZheTeng 原理，现记录一下较为简单的安装过程。

下载 openttd 的 1.0.0 版本：http://binaries.openttd.org/releases/1.0.0/openttd-1.0.0-linux-ubuntu-karmic-i386.deb。

使用命令 dpkg -i openttd-1.0.0-linux-ubuntu-karmic-i386.deb 安装。或双击 deb 文件，使用 GDebi 在图形界面下安装。安装过程可能提示软件库中有旧的版本，更为稳定，忽略不管即可。

<span class="readmore"><a href="http://www.mikespook.com/2010/04/ubuntu-9-10-%e4%b8%8b%e5%ae%89%e8%a3%85-openttd-1-0-0-%e4%b8%ad%e6%96%87%e7%89%88/" title="Ubuntu 9.10 下安装 OpenTTD 1.0.0 中文版">阅读全文——共1204字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>OpenTTD是开源版本的《运输大亨》，这两天刚刚发布了 1.0.0，中文汉化很完整。经本人验证，使用官方提供的 deb 包安装后，对于中文的显示需要小小调整。本着 Mr&#8217;Hu 的 BuZheTeng 原理，现记录一下较为简单的安装过程。<span id="more-535"></span></p>
<p>下载 openttd 的 1.0.0 版本：<a href="http://binaries.openttd.org/releases/1.0.0/openttd-1.0.0-linux-ubuntu-karmic-i386.deb" target="_blank">http://binaries.openttd.org/releases/1.0.0/openttd-1.0.0-linux-ubuntu-karmic-i386.deb</a>。</p>
<p>使用命令 dpkg -i openttd-1.0.0-linux-ubuntu-karmic-i386.deb 安装。或双击 deb 文件，使用 GDebi 在图形界面下安装。安装过程可能提示软件库中有旧的版本，更为稳定，忽略不管即可。</p>
<p>安装好后，在终端执行 openttd 会报错“Error: Failed to find a graphics set. Please acquire a graphics set for OpenTTD. See section 4.1 of readme.txt.”。如果乐意，直接去看 readme.txt 的 4.1 节，或者照着下面的步骤做也不错。</p>
<p>下载：<a href="http://binaries.openttd.org/extra/opengfx/0.2.3/opengfx-0.2.3-all.zip" target="_blank">http://binaries.openttd.org/extra/opengfx/0.2.3/opengfx-0.2.3-all.zip</a></p>
<p>下载：<a href="http://binaries.openttd.org/extra/opensfx/0.2.3/opensfx-0.2.3-all.zip" target="_blank">http://binaries.openttd.org/extra/opensfx/0.2.3/opensfx-0.2.3-all.zip</a></p>
<p>下载：<a href="http://binaries.openttd.org/extra/openmsx/0.2.1/openmsx-0.2.1-all.zip" target="_blank">http://binaries.openttd.org/extra/openmsx/0.2.1/openmsx-0.2.1-all.zip</a></p>
<p>解压缩。</p>
<p>在 $HOME/.openttd/ 下建立 data 目录。将上面解压缩的三个目录移入 $HOME/.openttd/data/ 中：</p>
<pre class="brush: bash; title: ; notranslate">
$HOME/.openttd/data/opengfx-0.2.3/
$HOME/.openttd/data/openmsx-0.2.1/
$HOME/.openttd/data/opensfx-0.2.3/
</pre>
<p>这时执行 openttd 就可以启动 OpenTTD 了。不过中文会是方块，如图：</p>
<p><img class="size-full wp-image-537 alignnone" title="openttd-no-chinese" src="http://www.mikespook.com/wp-content/uploads/2010/04/openttd-no-chinese.png" alt="" width="267" height="204" /></p>
<p>需要修改 $HOME/.openttd/openttd.cfg 的 18 至 23 行，增加字体文件路径，例如我使用 uming 字体：</p>
<pre class="brush: bash; title: ; notranslate">
small_font = /usr/share/fonts/truetype/arphic/uming.ttc
medium_font = /usr/share/fonts/truetype/arphic/uming.ttc
large_font = /usr/share/fonts/truetype/arphic/uming.ttc
small_size = 12
medium_size = 14
large_size = 16
</pre>
<p>在进入 OpenTTD，世界清爽了：</p>
<p><a href="http://www.mikespook.com/wp-content/uploads/2010/04/openttd-with-chinese.png" target="_blank"><img class="size-medium wp-image-538 alignnone" title="openttd-with-chinese" src="http://www.mikespook.com/wp-content/uploads/2010/04/openttd-with-chinese-300x225.png" alt="" width="300" height="225" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2010/04/ubuntu-9-10-%e4%b8%8b%e5%ae%89%e8%a3%85-openttd-1-0-0-%e4%b8%ad%e6%96%87%e7%89%88/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[翻译]游戏引擎即服务</title>
		<link>http://www.mikespook.com/2009/09/%e7%bf%bb%e8%af%91%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8e%e5%8d%b3%e6%9c%8d%e5%8a%a1/</link>
		<comments>http://www.mikespook.com/2009/09/%e7%bf%bb%e8%af%91%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8e%e5%8d%b3%e6%9c%8d%e5%8a%a1/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 15:27:32 +0000</pubDate>
		<dc:creator>mikespook</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[SaaS]]></category>
		<category><![CDATA[游戏引擎]]></category>
		<category><![CDATA[翻译]]></category>

		<guid isPermaLink="false">http://www.mikespook.com/?p=400</guid>
		<description><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
在赖神的 Google Reader 的分享中看到，觉得很有意义。或许可以作为现有的大量的游戏平台的下一步发展方向吧。结合SaaS的思想，以及网络游戏的实际运营模式，特别是webgame。将游戏底层技术支撑和游戏的策划、运营上端建筑分离应该会是一个很有前景的事情。

为了分享给更多的朋友，特别的翻译一下。

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;开心翻译分界线，下面是未来&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;

<span class="readmore"><a href="http://www.mikespook.com/2009/09/%e7%bf%bb%e8%af%91%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8e%e5%8d%b3%e6%9c%8d%e5%8a%a1/" title="[翻译]游戏引擎即服务">阅读全文——共1519字</a></span>]]></description>
			<content:encoded><![CDATA[<style type="text/css">
#leftcontainerBox {
	float:left;
	position: fixed;
	top: 60%;
	left: 70px;
}
#leftcontainerBox .buttons {
	float:left;
	clear:both;
	margin:4px 4px 4px 4px;
	padding-bottom:2px;
}
#bottomcontainerBox {
	width: 50%;
	padding-top: 1px;
}
#bottomcontainerBox .buttons {
	float: left;
	margin: 4px 4px 4px 4px;
}
</style>
<p>在赖神的 Google Reader 的分享中看到，觉得很有意义。或许可以作为现有的大量的游戏平台的下一步发展方向吧。结合SaaS的思想，以及网络游戏的实际运营模式，特别是webgame。将游戏底层技术支撑和游戏的策划、运营上端建筑分离应该会是一个很有前景的事情。</p>
<p>为了分享给更多的朋友，特别的翻译一下。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;开心翻译分界线，下面是未来&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<span id="more-400"></span></p>
<p>原文：<a href="http://blog.ubeegame.com/?p=16">http://blog.ubeegame.com/?p=16</a></p>
<p>作者：<a title="Posts by Tom" href="http://blog.ubeegame.com/?author=2">Tom</a></p>
<p>每个游戏开发者都应该了解“游戏引擎”，或者至少听说过这个名词。那么什么是游戏引擎呢？这里有在 <a href="http://en.wikipedia.org/wiki/Game_engine">Wikipedia</a> 上的定义：</p>
<blockquote><p>游戏引擎是被设计用于创建和开发<a title="Video game" href="http://en.wikipedia.org/wiki/Video_game">视频游戏</a>的<a title="Software" href="http://en.wikipedia.org/wiki/Software">软件</a>系统……通常游戏引擎的功能包括用于 <a title="2D computer graphics" href="http://en.wikipedia.org/wiki/2D_computer_graphics">2D</a> 或 <a title="3D computer graphics" href="http://en.wikipedia.org/wiki/3D_computer_graphics">3D</a> <a title="Computer graphics" href="http://en.wikipedia.org/wiki/Computer_graphics">图像</a>的<a title="Rendering (computer graphics)" href="http://en.wikipedia.org/wiki/Rendering_%28computer_graphics%29">渲染引擎</a>，<a title="Physics engine" href="http://en.wikipedia.org/wiki/Physics_engine">物理引擎</a>或<a title="Collision detection" href="http://en.wikipedia.org/wiki/Collision_detection">碰撞检测</a>（以及碰撞响应），<a title="Sound" href="http://en.wikipedia.org/wiki/Sound">声音</a>，<a title="Scripting language" href="http://en.wikipedia.org/wiki/Scripting_language">脚本</a>，<a title="Computer animation" href="http://en.wikipedia.org/wiki/Computer_animation">动画</a>，<a title="Game AI" href="http://en.wikipedia.org/wiki/Game_AI">人工智能</a>，<a title="Computer networking" href="http://en.wikipedia.org/wiki/Computer_networking">网络</a>，数据流，现金管理，线程和场景图。</p></blockquote>
<p>这看起来即恐怖，又复杂，不是么？然而，个人拙见，游戏引擎本质上只是一个资源管理系统，管理着游戏的所有资源（图像、动画、声音、游戏对象、财物、GUI等等）和渲染，并且在正确的时间、正确的地点呈现给玩家。在这一观点之上，游戏逻辑、 物理逻辑、AI逻辑，都可以当作游戏的资源来处理。一句话来说，游戏中的一切都是资源，而游戏引擎管理它们。这样可以给出一个更容易理解的定义。</p>
<p>然后我有这样一个想法，既然所有的游戏元素都只是资源，为什么不将它们放到 Internet 上，并让游戏引擎通过 Web service 访问它们。这样这些资源可以被多个游戏共享、并且玩家也无须在他们的计算机上下载或安装游戏。借鉴最近热辣的词语如 <a href="http://en.wikipedia.org/wiki/Software_as_a_service">SaaS</a> (Soft­ware as-a Ser­vice)， <a href="http://en.wikipedia.org/wiki/Platform_as_a_service">PaaS</a> (Plat­form as-a Ser­vice)，我将介绍一个更加热辣的词：<strong>GEaaS (Game Engine as-a Ser­vice)</strong>。下面是定义：</p>
<blockquote><p><strong>游戏引擎即服务(GEaaS)</strong> 说明了将游戏元素/资产（包括游戏逻辑和游戏数据）作为资源组织于“云（Internet）”上的游戏引擎设计方式。而游戏资源被<a href="http://en.wikipedia.org/wiki/Service_oriented">面向服务</a>的游戏引擎管理，并且一般通过 <a href="http://en.wikipedia.org/wiki/Web_service">Web Ser­vices</a> 在运行时调用。</p></blockquote>
<p>在这种游戏引擎下，可以预见到对于开发者和游戏玩家有以下好处：</p>
<ol>
<li><em>泛在接入：</em>当游戏包的所有元素，包含引擎被组织于 Internet，游戏就可以在有 Internet 接入的几乎任何地方、任何设备上玩；</li>
<li><em>更低的游戏障碍：</em>有了 GEaaS，玩家无须为了玩游戏而下载或安装任何东西，这会降低新玩家的安全顾虑，从而降低入门门槛；</li>
<li><em>重用游戏资源：</em>使得在游戏、以及开发者之间共享游戏资源成为可能；</li>
<li><em>轻松开发：</em>大型多人在线游戏开发变得更容易，因为引擎作为服务，已经处理了大多数MMOG开发的通常任务，因此可以解放开发者集中精力在游戏玩法的开发上；</li>
<li><a href="http://en.wikipedia.org/wiki/Mashup_%28web_application_hybrid%29"><em>聚合</em></a><em>：</em>可以轻松的将游戏同第三方服务集成或用于平衡其他服务。</li>
</ol>
<p>当然，GEaaS 同样有它的不足：</p>
<ol>
<li><em>网络速度/带宽限制</em> — 用这种类型的引擎开发的游戏会限制其资源大小，同时在网速低的情况下一定会极大的降低玩家体验。</li>
<li><em>浏览器渲染/计算能力</em> — 虽然在定义中，GEaaS 没有限制客户端技术的使用，但是方向是开发不依赖任何插件支持的基于浏览器的游戏。在这种情况下，游戏的图像等级受到浏览器渲染能力的制约。</li>
<li><em>版权/知识产权问题</em> — 当游戏资源和代码可以被重用时，开发者必须留意版权和知识产权问题，因此需要应用一些适当的许可证。</li>
</ol>
<p><a href="http://www.ubeegame.com/">UbeeGame</a> 正在专注构建这样的游戏引擎服务，我相信这将改变游戏工业的未来。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikespook.com/2009/09/%e7%bf%bb%e8%af%91%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8e%e5%8d%b3%e6%9c%8d%e5%8a%a1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

