aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/games
diff options
context:
space:
mode:
Diffstat (limited to 'files/zh-cn/games')
-rw-r--r--files/zh-cn/games/anatomy/index.html326
-rw-r--r--files/zh-cn/games/examples/index.html123
-rw-r--r--files/zh-cn/games/index.html106
-rw-r--r--files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html107
-rw-r--r--files/zh-cn/games/publishing_games/game_distribution/index.html127
-rw-r--r--files/zh-cn/games/publishing_games/game_promotion/index.html79
-rw-r--r--files/zh-cn/games/publishing_games/index.html23
-rw-r--r--files/zh-cn/games/publishing_games/游戏货币化/index.html95
-rw-r--r--files/zh-cn/games/techniques/2d_collision_detection/index.html82
-rw-r--r--files/zh-cn/games/techniques/3d_collision_detection/index.html153
-rw-r--r--files/zh-cn/games/techniques/3d_on_the_web/basic_theory/index.html127
-rw-r--r--files/zh-cn/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js/index.html258
-rw-r--r--files/zh-cn/games/techniques/3d_on_the_web/glsl_shaders/index.html180
-rw-r--r--files/zh-cn/games/techniques/3d_on_the_web/index.html118
-rw-r--r--files/zh-cn/games/techniques/async_scripts/index.html49
-rw-r--r--files/zh-cn/games/techniques/control_mechanisms/index.html78
-rw-r--r--files/zh-cn/games/techniques/control_mechanisms/移动端触摸控制/index.html152
-rw-r--r--files/zh-cn/games/techniques/controls_gamepad_api/index.html238
-rw-r--r--files/zh-cn/games/techniques/index.html34
-rw-r--r--files/zh-cn/games/tools/index.html40
-rw-r--r--files/zh-cn/games/tools/引擎和工具/index.html68
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/animations_and_tweens/index.html117
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html49
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html164
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/buttons/index.html104
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html59
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html124
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/game_over/index.html53
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/index.html57
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html90
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html71
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html49
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/physics/index.html99
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html122
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/randomizing_gameplay/index.html61
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/scaling/index.html64
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/the_score/index.html76
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html59
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.html99
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html106
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html126
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html114
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/game_over/index.html81
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/index.html60
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html143
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/paddle_and_keyboard_controls/index.html122
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/track_the_score_and_win/index.html92
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/收尾工作/index.html113
-rw-r--r--files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/鼠标控制/index.html61
-rw-r--r--files/zh-cn/games/tutorials/html5_gamedev_phaser_device_orientation/index.html449
-rw-r--r--files/zh-cn/games/tutorials/index.html25
-rw-r--r--files/zh-cn/games/简介/index.html118
52 files changed, 5690 insertions, 0 deletions
diff --git a/files/zh-cn/games/anatomy/index.html b/files/zh-cn/games/anatomy/index.html
new file mode 100644
index 0000000000..8964577ef2
--- /dev/null
+++ b/files/zh-cn/games/anatomy/index.html
@@ -0,0 +1,326 @@
+---
+title: 剖析游戏结构
+slug: Games/Anatomy
+tags:
+ - Games
+ - JavaScript
+ - Main Loop
+ - requestAnimationFrame
+translation_of: Games/Anatomy
+---
+<div>{{GamesSidebar}}</div>
+
+<p>{{IncludeSubnav("/en-US/docs/Games")}}</p>
+
+<div class="summary">
+<p>本文从技术角度分析了一般电子游戏的结构和工作流程,就此介绍主循环是如何运行的。它有助于初学者了解在现代游戏开发领域构建游戏时需要什么,以及如何将JavaScript这样的Web标准工具作为自己的工具使用。游戏开发经验丰富但不熟悉Web开发的开发者也能从中受益。</p>
+</div>
+
+<h2 id="呈现,接收,解释,计算,重复">呈现,接收,解释,计算,重复</h2>
+
+<p>所有电子游戏的目标都是向用户(们)<strong>呈现</strong>一个场景,<strong>接收</strong>他们的输入,将这些输入信号<strong>解释</strong>为动作,并<strong>计算</strong>出由这些动作产生的新场景。游戏不断地循环遍历,一遍又一遍,直到遇到某些终止条件(比如赢,输或者退出睡觉)。毫不奇怪,这种模式与游戏引擎的编程方式相呼应。</p>
+
+<p>具体情况取决于游戏本身。</p>
+
+<p>一些游戏通过<strong>用户输入</strong>来驱动这个循环。想象一下,你正在开发一种“大家来找茬”类型的游戏。这些游戏向用户<strong>呈现</strong>两张图片,游戏<strong>接收</strong>点击(或触摸);将用户输入<strong>解释</strong>为成功,失败,暂停,菜单交互等。最后,游戏根据用户的输入<strong>计算并更新</strong>游戏场景。这种游戏是由用户的输入驱动,也就是说,它会在用户进行输入之后冻结画面,等待玩家进行新的输入。这是一种基于回合的游戏类型,它不需要每帧持续更新画面,只有当玩家作出反应时才会。</p>
+
+<p>另一些游戏需要尽可能控制每一个细微的时间片(动画)。与上述原理有点小区别:每个动画帧都将循环遍历,并在之后第一个可用的轮次捕获玩家输入的任何变化。这种 <strong>每帧一次</strong> 的模型是通过一个叫<strong>主循环</strong>的东西实现的。如果您的游戏循环是基于时间的,则必须保证对主循环精准的模拟。</p>
+
+<p>但它也可能不需要逐帧控制。您的游戏循环可能类似找不同的例子,并以输入事件作为基础。它可能需要输入和模拟时间片。它甚至可以基于其他的东西来循环。</p>
+
+<p>现代JavaScript - 正如下一节中所描述的 - 它可以轻松开发出一个高效的,逐帧执行的主循环,这很值得庆幸。当然,您的游戏只会按照您所做的那样优化。如果某些东西看起来应该被添加到一个更罕见的事件里,那么将它从主循环中剥离出来通常是个好主意(但并非总是如此)。</p>
+
+<h2 id="在JavaScript中构建一个主循环">在JavaScript中构建一个主循环</h2>
+
+<p>JavaScript能很好的处理事件和回调函数。现代浏览器努力在需要的时候调用方法,并在间隙中闲下来(或做其他任务)。将您的代码附加到适合它们的时刻是一个很好的主意。考虑一下你的函数是需要在严格的时间周期内,还是每一帧,或者仅仅是在发生了其他情况之后执行。当您的函数需要被调用时,要更具体地使用浏览器,这样浏览器就可以在调用时进行优化。而且,这可能会让你的工作更轻松。</p>
+
+<p>有些代码需要逐帧运行,所以应将其附加到浏览器的重绘周期中,没有比这更好的了!在Web 中,通常 <code>window.requestAnimationFrame()</code>方法是大多数良好的逐帧循环的基础。在调用该方法时必须传入一个回调函数,这个回调函数将在下一次重新绘制之前执行。下面是一个简单的主循环的例子。:</p>
+
+<pre class="brush: js notranslate">window.main = function(){
+ window.requestAnimationFrame(main);
+
+ //无论你的主循环需要做什么
+};
+
+main(); //开始循环</pre>
+
+<div class="blockIndicator note">
+<p>注意:在这里讨论的每个 <code>main()</code> 方法中,在执行循环内容之前,我们会递归调用一个新的<code>requestAnimationFrame</code>,这不是随意的,它被认为是最佳实践。如果你的当前帧错过了它的垂直同步窗口的周期,你也在下一个帧通过<code>requestAnimationFrame</code> 尽早的调用<code>main()</code>,从而确保浏览器能够及时地执行。</p>
+</div>
+
+<p>上面的代码块有两个语句。第一个语句创建一个名为<code>main()</code>中的全局变量的函数。这个函数做一些工作,也告诉浏览器在下一帧通过<code>window.requestAnimationFrame()</code>调用本身。第二个语句调用第一个语句中定义的<code>main()</code>函数。因为<code>main()</code>中在第二个语句中被调用一次,而每次调用都将自身又放置到下一个帧的执行队列中,因此<code>main()</code>的调用与您的帧率同步。</p>
+
+<p>当然,这个循环并不完美。不过在讨论如何改善之前,让我们先讨论一下它已经做好了什么。</p>
+
+<p>将主循环的时机安排在浏览器每次的绘制显示中,允许您能像浏览器想要绘制的那样频繁的运行您的循环。你能够控制每一帧动画,并且<code>main()</code>是循环中唯一执行的函数,所以这很简单。主视角射击游戏(或类似的游戏)每一帧都会出现一个新的场景。没有比这种方法更平滑并绘制及时的了。</p>
+
+<p>但是不要马上认为动画必需要帧帧控制。通过CSS动画或浏览器中的其他工具,可以很容易实现简单的动画,甚至GPU加速。有很多这样的东西,它们会让你的工作更轻松。</p>
+
+<h2 id="在Javascript中构建一个更好的主循环">在Javascript中构建一个更好的主循环</h2>
+
+<p>在前面的主循环中有两个明显的问题:<code>main()</code>污染了 <code>window</code><code>对象</code>(所有全局变量存储的对象),并且示例代码没有给我们留下一个停止循环的方法,除非整个浏览器选项卡被关闭或刷新。对于第一个问题,如果您希望主循环只运行,并且不需要被简单(直接)访问它,您可以将它作为一个立即调用的函数表达式(IIFE)创建。</p>
+
+<pre class="brush: js notranslate" dir="rtl">/*
+*
+*/
+
+(function(){
+ function main(){
+ window.requestAnimationFrame(main);
+
+ //你的主循环内容。
+ }
+
+ main(); //开始循环
+})();</pre>
+
+<p>当浏览器遇到这个IIFE时,它将定义您的主循环,并立即将其加入下一个帧的更新队列中。<code>main</code>(或<code>main()</code>方法)不会被附加到任何对象,在应用程序的其他地方仍是一个有效的未使用的名称,仍可以自由地定义为其他的东西。</p>
+
+<div class="blockIndicator note">
+<p>注意:在实践中,更常见的终止下一个<code>requestAnimationFrame()</code>方式是使用if语句,而不是调用<code>cancelAnimationFrame()</code>。</p>
+</div>
+
+<p>对于第二个问题,要终止循环,您需要调用<code> </code><code>window.cancelAnimationFrame()</code>来取消<code>main()</code>的调用。该方法需要传入你最后一次调用<code>requestAnimationFrame()</code>时返回的ID。让我们假设您的游戏的函数和变量是建立在您称为MyGame的名称空间上。扩展我们的最后一个例子,主循环现在看起来是这样的:</p>
+
+<pre class="brush: js notranslate">/*
+* 让我们假设MyGame是之前定义的。
+*/
+
+;(function(){
+ function main(){
+ MyGame.stopMain = window.requestAnimationFrame(main);
+
+ //你的主循环内容
+ }
+
+ main(); //开始循环
+})();</pre>
+
+<p>现在,我们在MyGame名称空间中声明了一个变量<code>stopMain</code>,其值为主循环最后调用<code>requestAnimationFrame()</code>时返回的ID。任何时候,我们可以通过告诉浏览器取消与ID相对应的请求来停止主循环。</p>
+
+<pre class="notranslate">window.cancelAnimationFrame(MyGame.stopMain);</pre>
+
+<p>在JavaScript的中编写<strong>主循环</strong>的关键在于,考虑到任何会驱动你行为的事件,并注意不同的系统是如何相互作用的。您可能拥有多个由多个不同类型的事件驱动的组件。这看起来像是不必要的复杂性,但它可能就是一个很好的优化(当然,不一定是这样的)。问题是,您并不是在编写一个典型的主循环。在Java脚本中,您使用的是浏览器的主循环,并且您正在尝试这样做。</p>
+
+<h2 id="用JavaScript构建一个更优化的主循环">用JavaScript构建一个更优化的主循环</h2>
+
+<p>基本上,在JavaScript的中,浏览器有它自己的主循环,而你的代码存在于循环某些阶段。上面描述的主循环,试图避免脱离浏览器的控制。这种主循环附着于<code>window.requestAnimationFrame()</code>方法,该方法将在浏览器的下一帧中执行,具体取决于浏览器如何与将其自己的主循环关联起来。<a href="https://developer.mozilla.org/en-US/docs/Games/Anatomy">W3C规范</a>并没有真正定义什么时候浏览器必须执行requestAnimationFrame回调。这有一个好处,浏览器厂商可以自由地实现他们认为最好的解决方案,并随着时间的推移进行调整。</p>
+
+<p>现代版的Firefox和Google Chrome(可能还有其他版本)试图在框架的时间片的开始时将请求AnimationFrame回调与它们的主线程进行连接。因此,浏览器的主线程看起来就像下面这样:</p>
+
+<ol>
+ <li>启动一个新帧(而之前的帧由显示处理)。</li>
+ <li>遍历requestAnimationFrame回调并调用它们。</li>
+ <li>当上面的回调停止控制主线程时,执行垃圾收集和其他帧任务。</li>
+ <li>睡眠(除非事件打断了浏览器的小睡),直到显示器准备好你的图像(VSYNC)并重复。</li>
+</ol>
+
+<p>您可以考虑开发实时应用程序,因为有时间做工作。所有上述步骤都必须在每16毫秒内进行一次,以保持60赫兹的显示效果。浏览器会尽可能早地调用您的代码,从而给它最大的计算时间。您的主线程通常会启动一些甚至不在主线程上的工作负载(如WebGL的中的光栅化或着色器)。在浏览器使用其主线程管理垃圾收集,其他任务或处理异步事件时,可以在Web Worker或GPU上执行长时间的计算。</p>
+
+<p>当我们讨论预算时,许多网络浏览器都有一个称为高分辨率时间的工具.{{ domxref("Date") }} 对象不再是计时事件的识别方法,因为它非常不精确,可以由系统时钟进行修改。另一方面,高分辨率的时间计算自navigationStart(当上一个文档被卸载时)的毫秒数。这个值以小数的精度返回,精确到千分之一毫秒。它被称为{{ domxref("DOMHighResTimeStamp") }},但是,无论出于什么目的和目的,都认为它是一个浮点数。</p>
+
+<p>注意:系统(硬件或软件)不能达到微秒精度,可以提供毫秒精度的最小值然而,如果他们能够做到这一点,他们就应该提供0.001的准确性。</p>
+
+<p>这个值本身并不太有用,因为它与一个相当无趣的事件相关,但它可以从另一个时间戳中减去,以便准确准确地确定这两个点之间的时间间隔。要获得这些时间戳中的一个,您可以调用window.performance.now()并将结果存储为一个变量。</p>
+
+<pre class="brush: js notranslate">var tNow = window.performance.now();
+</pre>
+
+<p>回到主循环的主题。您将经常想知道何时调用主函数。因为这是常见的,window.requestAnimationFrame()总是提供一个DOMHighResTimeStamp执行时回调函数作为参数。这将导致我们之前的主循环的另一个增强。</p>
+
+<pre class="brush: js notranslate">/*
+* 以分号开始,以上例子中的代码行都是这样的
+* 依靠自动分号插入(ASI)。浏览器可能会意外
+* 认为这个整个例子从上一行继续。领先分号
+* 标记我们的新行的开始,如果前一个不是空或终止。
+*
+* 我们还假设MyGame是以前定义的。
+*/
+
+;(function(){
+ function main(tFrame){
+ MyGame.stopMain = window.requestAnimationFrame(main);
+
+ //你的主循环内容
+ // tFrame,来自"function main(tFrame)",现在是由rAF提供的DOMHighResTimeStamp。
+ }
+
+ main(); //开始循环
+})();</pre>
+
+<p>其他一些优化是可能的,这取决于你的游戏想要完成什么。你的游戏类型显然会有所不同,但它甚至可能比这更微妙。您可以在画布上单独绘制每个像素,也可以将DOM元素(包括具有透明背景的多个WebGL的画布)放入复杂的层次结构中。每条路径都将导致不同的机会和约束。</p>
+
+<h2 id="决定......时间">决定......时间</h2>
+
+<p>您将需要对您的主循环作出艰难的决定:如何模拟准确的时间进度。如果你想要控制每一帧,那么你需要确定你的游戏更新和绘制的频率,您甚至可能希望以不同的速率进行更新和绘制。您还需要考虑如果用户的系统无法跟上工作负载,那么您还需考虑如何优雅降级,以保证性能。让我们首先假定你会在每次绘制时,同时处理用户的输入,并更新游戏状态。我们稍后再细讲。</p>
+
+<p>注意:改变主循环如何处理时间是非常困难的,在进行主循环之前,请仔细考虑您的需求。</p>
+
+<h3 id="大多数浏览器游戏应该是什么样的">大多数浏览器游戏应该是什么样的</h3>
+
+<p>如果你的游戏可以达到你所支持的任何硬件的最大刷新率,那么你的工作就变得相当容易了。 你可以简单地进行更新,渲染,然后在垂直同步之前什么都不用做。</p>
+
+<pre class="notranslate">/*
+* 以分号开始,以上例子中的代码行都是这样的
+* 依靠自动分号插入(ASI)。浏览器可能会意外
+* 认为这个整个例子从上一行继续。领先分号
+* 标记我们的新行的开始,如果前一个不是空或终止。
+*
+* 我们还假设MyGame是以前定义的。
+*/
+
+;(function(){
+ function main(tFrame){
+ MyGame.stopMain = window.requestAnimationFrame(main);
+
+ update(Frame); //调用update方法。在我们的例子中,我们给它rAF的时间戳。
+ render();
+ }
+
+ main(); //开始循环
+})();</pre>
+
+<p>如果无法达到最大刷新率,可以调整画面质量设置以保持你的时间预算。这个概念最有名的例子是ID Software的RAGE游戏 ,这个游戏取消了用户的控制权,以使其计算时间保持在大约16ms(或大约60fps)。如果计算时间过长,则提交的解析度就降低,纹理和其他资源将无法加载或绘制等。这个(非网络)案例研究做了一些假设和折衷:</p>
+
+<ul>
+ <li>每个动画帧都占用户输入。</li>
+ <li>没有帧需要外推(猜测),因为每个绘图都有自己的更新。</li>
+ <li>仿真系统基本上可以假定每次完全更新间隔约16ms。</li>
+ <li>给用户控制质量设置将是一场噩梦。</li>
+ <li>不同的监视器以不同的速率输入:30FPS,75FPS,100FPS,120FPS,144FPS等</li>
+ <li>无法跟上60 FPS的系统会失去视觉质量,以保持游戏运行的最佳速度(最终如果质量太低,则会彻底失败)。</li>
+</ul>
+
+<h3 id="处理可变刷新率需求的其他方法">处理可变刷新率需求的其他方法</h3>
+
+<p>存在其他解决问题的方法。</p>
+
+<p>一种常见的技术是以恒定的频率更新模拟,然后绘制尽可能多的(或尽可能少的)实际帧。更新方法可以继续循环,而不用考虑用户看到的内容。绘图方法可以查看最后的更新以及发生的时间。由于绘制知道何时表示,以及上次更新的模拟时间,它可以预测为用户绘制一个合理的框架。这是否比官方更新循环更频繁(甚至更不频繁)无关紧要。更新方法设置检查点,并且像系统允许的那样频繁地,渲染方法画出周围的时间。在Web标准中分离更新方法有很多种方法:</p>
+
+<ul>
+ <li>绘制<code>requestAnimationFrame</code>并更新 {{ domxref("window.setInterval") }}或{{domxref("window.setTimeout")}}。
+
+ <ul>
+ <li>即使在未聚焦或最小化的情况下,使用处理器时间,也可能是主线程,并且可能是传统游戏循环的工件(但是很简单)。</li>
+ </ul>
+ </li>
+ <li>绘制<code>requestAnimationFrame</code>和更新一个<code>setInterval</code>或<code>setTimeout</code>一个<a href="/en-US/docs/Web/Guide/Performance/Using_web_workers">Web工作者</a>。
+ <ul>
+ <li>这与上述相同,除了更新不会使主线程(主线程也没有)。这是一个更复杂的解决方案,并且对于简单更新可能会有太多的开销。</li>
+ </ul>
+ </li>
+ <li>绘制<code>requestAnimationFrame</code>并使用它来戳一个包含更新方法的Web Worker,其中包含要计算的刻度数(如果有的话)。
+ <ul>
+ <li>这个睡眠直到<code>requestAnimationFrame</code>被调用并且不会污染主线程,加上你不依赖于老式的方法。再次,这比以前的两个选项更复杂一些,并且<em>开始</em>每个更新将被阻止,直到浏览器决定启动rAF回调。</li>
+ </ul>
+ </li>
+</ul>
+
+<p>这些方法中的每一种都有类似的权衡:</p>
+
+<ul>
+ <li>用户可以跳过渲染帧或根据其性能内插额外的帧。</li>
+ <li>您可以指望所有用户以相同的恒定频率更改打嗝的更新非美容变量。</li>
+ <li>程序比我们前面看到的基本循环要复杂得多。</li>
+ <li>用户输入完全被忽略,直到下次更新(即使用户具有快速设备)。</li>
+ <li>强制性内插具有性能损失。</li>
+</ul>
+
+<p>单独的更新和绘图方法可能如下面的示例。为了演示,该示例基于第三个项目符号,只是不使用Web Workers进行可读性(而且我们诚实地说可写性)。</p>
+
+<p><em>注意:这个例子,具体来说,需要进行技术审查。</em></p>
+
+<pre class="brush: js notranslate">/*
+* 以分号开始,以上例子中的代码行都是这样的
+* 依靠自动分号插入(ASI)。浏览器可能会意外
+* 认为这个整个例子从上一行继续。领先分号
+* 标记我们的新行的开始,如果前一个不是空或终止。
+*
+* 我们还假设MyGame是以前定义的。
+*
+* MyGame.lastRender跟踪最后提供的requestAnimationFrame时间戳。
+* MyGame.lastTick跟踪最后更新时间。始终以tickLength递增。
+* MyGame.tickLength是游戏状态更新的频率。这是20 Hz(50ms)。
+*
+* timeSinceTick是requestAnimationFrame回调和最后一次更新之间的时间。
+* numTicks是这两个呈现帧之间应该发生的更新次数。
+*
+* render() 传入tFrame, 因为render方法可能需要计算
+* tFrame 距离最近的更新已经过去了多久,通过外推的方式
+* 来获得场景数据。(对于快速设备,render方法是纯表现性的)。
+* 用以绘制场景。
+*
+* update() 根据给定时间点计算游戏状态。通常需要用tickLength
+* 作为循环参数,递增更新。来保证游戏状态的严谨。传入 DOMHighResTimeStamp
+* 格式的当前时间。(除非需要增加暂停功能, 传入的时间应该总是
+* 最后更新时间 + 游戏的tick间隔。)
+*
+* setInitialState() 执行在运行mainloop之前需要的任何任务。
+* 它只是一个普通的示例函数,表示您在mainloop前做过的事。
+*/
+
+;(function(){
+ function main(tFrame){
+ MyGame.stopMain = window.requestAnimationFrame(main);
+ var nextTick = MyGame.lastTick + MyGame.tickLength;
+ var numTicks = 0;
+
+ //如果tFrame &lt;nextTick,则需要更新0个ticks(对于numTicks,默认为0)。
+ //如果tFrame = nextTick,则需要更新1 tick(等等)。
+ //注意:正如我们在总结中提到的那样,您应该跟踪numTicks的大小。
+ //如果它很大,那么你的游戏是睡着了,或者机器无法跟上。
+ if(tFrame&gt; nextTick){
+ var timeSinceTick = tFrame - MyGame.lastTick;
+ numTicks = Math.floor(timeSinceTick / MyGame.tickLength);
+ }
+
+ queueUpdates(numTicks);
+ render(tFrame);
+ MyGame.lastRender = tFrame;
+ }
+
+ function queueUpdates(numTicks){
+ for(var i = 0; i &lt;numTicks; i ++){
+ MyGame.lastTick = MyGame.lastTick + MyGame.tickLength; //现在lastTick是这个刻度。
+ update(MyGame.lastTick);
+ }
+ }
+
+ MyGame.lastTick = performance.now();
+ MyGame.lastRender = MyGame.lastTick; //假装第一次绘制是在第一次更新。
+ MyGame.tickLength = 50; //这将使您的模拟运行在20Hz(50ms)
+
+ setInitialState();
+ main(performance.now()); //开始循环
+})();</pre>
+
+<p>另一个选择是简单地做一些事情不那么频繁。如果您的更新循环的一部分难以计算但对时间不敏感,则可以考虑缩小其频率,理想情况下,在延长的时间段内将其扩展成块。这是一个隐含的例子,在火炮博物馆的炮兵游戏中,他们<a href="http://blog.artillery.com/2012/10/browser-garbage-collection-and-framerate.html">调整垃圾发生率</a>来优化垃圾收集。显然,清理资源不是时间敏感的(特别是如果整理比垃圾本身更具破坏性)。</p>
+
+<p>这也可能适用于您自己的一些任务。那些是当可用资源成为关注点时的好候选人。</p>
+
+<h2 id="概要">概要</h2>
+
+<p>我知道上述的任何一种,或许没有适合你的游戏。正确的决定完全取决于你愿意(和不愿意)做出的权衡。主要关心的是切换到另一个选项。幸运的是,我没有任何经验,但我听说这是一个令人难以置信的游戏的Whack-a-Mole。</p>
+
+<p>像Web这样的受管理平台,要记住的一件重要的事情是,您的循环可能会在相当长的一段时间内停止执行。当用户取消选择您的标签并且浏览器休眠(或减慢)其<code>requestAnimationFrame</code>回调间隔时,可能会发生这种情况。你有很多方法来处理这种情况,这可能取决于你的游戏是单人游戏还是多人游戏。一些选择是:</p>
+
+<ul>
+ <li>考虑差距“暂停”并跳过时间。
+
+ <ul>
+ <li>你可能会看到这对大多数多人游戏来说都是有问题的。</li>
+ </ul>
+ </li>
+ <li>你可以模拟差距赶上。
+ <ul>
+ <li>这可能是长时间丢失和/或复杂更新的问题。</li>
+ </ul>
+ </li>
+ <li>您可以从联机设备或服务器恢复游戏状态。
+ <ul>
+ <li>除非联机设备/服务器的游戏状态已经过期,或者这是一个没有没服务器的纯单机游戏。</li>
+ </ul>
+ </li>
+</ul>
+
+<p>一旦你的主循环被开发出来,你已经决定了一套适合你的游戏的假设和权衡,现在只需要用你的决定来计算任何适用的物理,AI,声音,网络同步,以及你游戏可能需要。</p>
diff --git a/files/zh-cn/games/examples/index.html b/files/zh-cn/games/examples/index.html
new file mode 100644
index 0000000000..25df2f2f52
--- /dev/null
+++ b/files/zh-cn/games/examples/index.html
@@ -0,0 +1,123 @@
+---
+title: Examples
+slug: Games/Examples
+tags:
+ - 游戏
+translation_of: Games/Examples
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/zh-CN/docs/Games")}}</div>
+
+<p class="summary">这个页面列出了许多令人印象深刻的web技术演示,你可以从中获得灵感和乐趣。这里证明了可以利用JavaScript,WebGL和相关的技术做些什么。前两个部分列出了可以玩的游戏,其中在第二个部分中列出的演示不一定是可交互的或是游戏。</p>
+
+<div class="column-container">
+<div class="column-half">
+<h2 id="免费演示游戏">免费/演示游戏</h2>
+
+<dl>
+ <dt><a href="http://www.beloola.com">Beloola</a></dt>
+ <dd>一个连接充满激情的人们的网络虚拟现实(WebVR)平台。 可以同时在2D屏幕和虚拟现实头盔显示器(设置/转为VR模式)上体验。</dd>
+ <dt><a href="http://playcanv.as/p/aP0oxhUr">Tanx</a></dt>
+ <dd>一个多人坦克对战游戏,由<a href="https://playcanvas.com/">PlayCanvas</a>开发。</dd>
+ <dt><a href="https://robertsspaceindustries.com/comm-link/transmission/14704-Hyper-Vanguard-Force">Hyper Vanguard Force</a></dt>
+ <dd>一个优雅的纵向卷轴太空射击游戏。</dd>
+ <dt><a href="http://playcanv.as/p/JtL2iqIH">Swooop</a></dt>
+ <dd>一个飞行游戏:控制你的飞机并收集宝石。也是由<a href="https://playcanvas.com/">PlayCanvas</a>所开发。</dd>
+ <dt><a href="https://ga.me/games/save-the-day">Save the Day</a></dt>
+ <dd>在受灾区域驾驶你的救援直升机以拯救被困的受灾者(ga.me.)。</dd>
+ <dt><a href="https://ga.me/games/polycraft">Polycraft</a></dt>
+ <dd>一个海难生存游戏。探索岛屿、打败怪物。</dd>
+ <dt><a href="http://hexgl.bkcore.com/">HexGL</a></dt>
+ <dd>一个快节奏、未来主义的赛车游戏。</dd>
+ <dt><a href="http://beta.unity3d.com/jonas/DT2/">Dead Trigger 2</a></dt>
+ <dd>经典的僵尸溅射游戏,使用<a href="http://unity3d.com/">Unity3D</a>开发。</dd>
+ <dt><a href="http://beta.unity3d.com/jonas/AngryBots/">Angry Bots</a></dt>
+ <dd>一个未来风格的外星人式的第三人称射击游戏,使用<a href="http://unity3d.com/">Unity3D</a>开发。</dd>
+ <dt><a href="http://sandbox.photonstorm.com/html5/nutmeg/">Nutmeg</a></dt>
+ <dd>可爱的复古卷轴平台动作游戏。</dd>
+ <dt><a href="http://www.zibbo.com/game/match-3-games-top/back-to-candyland-episode-1">Back to Candyland</a></dt>
+ <dd>一个match-3(Candy Crush)风格的游戏。</dd>
+ <dt><a href="http://playbiolab.com/">Biolab Disaster</a></dt>
+ <dd>横向卷轴平台射击游戏。</dd>
+ <dt><a href="http://phoboslab.org/xtype/">X-Type</a></dt>
+ <dd>纵向卷轴太空射击游戏演示。</dd>
+ <dt><a href="http://phoboslab.org/xibalba/">Xibalba</a></dt>
+ <dd>复古(Doom风格)的第一人称射击游戏。</dd>
+ <dt><a href="https://timeinvariant.github.io/gorescript/play/">Gorescript</a></dt>
+ <dd>另一个复古风格的第一人称射击游戏。</dd>
+ <dt><a href="http://hypnoticowl.com/games/the-wizard/">The Wizard</a></dt>
+ <dd>一个回合制的地下城解谜游戏。</dd>
+ <dt><a href="http://hextris.io/">Hextris</a></dt>
+ <dd>类似于俄罗斯方块的六边形解谜游戏。</dd>
+ <dt><a href="https://gabrielecirulli.github.io/2048/">2048</a></dt>
+ <dd>一个滑动数字方块的解谜游戏。</dd>
+ <dt><a href="/en-US/demos/detail/bananabread" title="/en-US/demos/detail/bananabread">BananaBread</a></dt>
+ <dd>多玩家的3D第一人称射击游戏,使用Emscripten,WebGL和WebRTC开发。</dd>
+ <dt><a href="https://hacks.mozilla.org/2013/12/monster-madness-creating-games-on-the-web-with-emscripten/">Monster Madness</a></dt>
+ <dd>一个基于WebGL和asm.js的多人在线射击游戏,由Nom Nom Games 和Trendy entertainment开发。</dd>
+ <dt><a href="http://www.auraluxgame.com/game/">Auralux</a></dt>
+ <dd>基于WebGL和asm.js的策略游戏 :捕获所有的太阳以获取胜利!</dd>
+ <dt><a href="http://browserquest.mozilla.org/">BrowserQuest</a></dt>
+ <dd>由Little Workshop和Mozilla开发的MMORPG。</dd>
+</dl>
+
+<h2 id="商业游戏">商业游戏</h2>
+
+<dl>
+ <dt><a href="http://oortonline.com/">Oort Online</a></dt>
+ <dd>一个大型多人网游:在游戏中探索、建造和战斗(目前仍在开发中)。</dd>
+ <dt><a href="http://www.wizardslizard.com/">A Wizard's Lizard</a></dt>
+ <dd>自上而下的塞尔达式的探索/RPG游戏。</dd>
+ <dt><a href="http://qbqbqb.rezoner.net/">QbQbQb </a></dt>
+ <dd>一个科幻主题的解谜游戏。</dd>
+ <dt><a href="http://elliotquest.com/">Elliot Quest</a></dt>
+ <dd>复古的8-bit画面风格冒险游戏。</dd>
+</dl>
+</div>
+
+<div class="column-half">
+<h2 id="混合演示">混合演示</h2>
+
+<dl>
+ <dt><a href="http://greweb.me/wavegl/">WaveGL</a></dt>
+ <dd>音频资源的WebGL可视化展示。</dd>
+ <dt><a href="http://codepen.io/jackrugile/pen/CdKGx/">Canvas Airport Simulation</a></dt>
+ <dd>可以显示飞机在机场起飞和降落的地图动画,也可以显示航线。</dd>
+ <dt><a href="http://alteredqualia.com/xg/examples/animation_physics_terrain.html">Animation Physics</a></dt>
+ <dd>地形和汽车的3D渲染,其中的物理计算使用了<a href="https://github.com/kripken/ammo.js">ammo.js</a> 。</dd>
+ <dt><a href="http://david.li/flow/">Volumetric Particle Flow</a></dt>
+ <dd>流体的物理模拟。</dd>
+ <dt><a href="http://codepen.io/artzub/pen/gszpJ/">Explosion and chain reaction</a></dt>
+ <dd>会引发更多爆炸的爆炸粒子。</dd>
+ <dt><a href="http://codepen.io/AshKyd/pen/sylFw">Canvas generated planet</a></dt>
+ <dd>一个具有小行星带的星球。</dd>
+ <dt><a href="http://codepen.io/zadvorsky/pen/FAmuL">Digital Fireworks</a></dt>
+ <dd>在canvas上渲染出的焰火动画效果。</dd>
+ <dt><a href="http://oos.moxiecode.com/js_webgl/autumn/">Autumn</a></dt>
+ <dd>秋叶飘落,光源在其后闪烁。使用<a href="https://github.com/mrdoob/three.js">Three.js</a>开发。</dd>
+ <dt><a href="http://inear.se/fireshader/">Fire walk with me</a></dt>
+ <dd>翻腾的火云效果。</dd>
+ <dt><a href="http://codepen.io/jackrugile/pen/AokpF">Rainbow Firestorm</a></dt>
+ <dd>下雨般的七彩粒子,在由圆组成的地形上跳跃。</dd>
+ <dt><a href="http://visualiser.fr/babylon/crowd/">Crowd Simulation</a></dt>
+ <dd>模拟想到达他们相反方向的拥挤人群。</dd>
+ <dt><a href="http://codepen.io/noeldelgado/pen/ByxQjL">SVG Masking Experiment</a></dt>
+ <dd>一台X光机,由SVG蒙版创建。</dd>
+ <dt><a href="https://www.shadertoy.com/view/Ms2SD1">Realistic Water Simulation</a></dt>
+ <dd>如海浪的流水。</dd>
+ <dt><a href="http://www.haxor.xyz/demos/1.0/dungeon/">Dungeon demo</a></dt>
+ <dd>基于Haxor的地下城场景,拥有可行走的人物。</dd>
+ <dt><a href="http://massiveassaultnetwork.com/html5/">Massive Assault tech demo</a></dt>
+ <dd>渲染出的具有未来派的军用车辆的群岛。</dd>
+ <dt><a href="https://callumprentice.github.io/apps/flight_stream/index.html">Flight Stream</a></dt>
+ <dd>具有模拟航线的3D球体。</dd>
+ <dt><a href="http://pixelscommander.com/polygon/htmlgl/demo/filters.html">WebGL filters</a></dt>
+ <dd>用于向HTML元素添加效果的WebGL过滤器演示。</dd>
+ <dt><a href="http://codepen.io/AshKyd/pen/zxmgzV">SVG isometic tiles</a></dt>
+ <dd>Generating isometric tiles with SVG matricies.</dd>
+ <dt><a href="https://jsfiddle.net/jetienne/rkth90c9/">ThreeJS App Player</a></dt>
+ <dd>你可以在其中载入和运行Three.js的示例。</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/demos/detail/escher-puzzle/launch">WebGL + Three.js Demo</a></dt>
+ <dd>警告:可能造成眩晕。</dd>
+</dl>
+</div>
+</div>
diff --git a/files/zh-cn/games/index.html b/files/zh-cn/games/index.html
new file mode 100644
index 0000000000..12c6230442
--- /dev/null
+++ b/files/zh-cn/games/index.html
@@ -0,0 +1,106 @@
+---
+title: 游戏开发环境
+slug: Games
+tags:
+ - Apps
+ - Game Development
+ - Gamedev
+ - Games
+ - HTML5 Games
+ - JavaScript Games
+ - TopicStub
+ - Web
+translation_of: Games
+---
+<div>{{GamesSidebar}}</div>
+
+<div class="summary">
+<p><span class="seoSummary">游戏是在计算机上最风靡的活动之一。新技术不断发展已使开发出能在任何符合标准的浏览器上运行更好更炫的游戏成为可能。</span></p>
+</div>
+
+<div>{{EmbedGHLiveSample("web-tech-games/index.html", '100%', 820)}}</div>
+
+<div class="column-container">
+<div class="column-half">
+<h2 id="开发网页游戏">开发网页游戏</h2>
+
+<p>欢迎来到MDN游戏开发中心! 在网站的这个模块我们为想要开发游戏的web开发者提供了资源。你可以在主菜单的左边找到很多有用的教程和技术文档,放轻松去探索吧。</p>
+
+<p>我们同样包含了参考书库,因此你可以轻易的找到有关游戏开发所有常用的API以及有用的<a href="/zh-CN/docs/Games/Tools/Engines_and_tools">引擎和工具</a>清单和<a href="/zh-CN/docs/Games/Examples">游戏案例</a>.</p>
+
+<div class="note">
+<p><strong>注解</strong>: 在你开始尝试创建一个网页游戏之前你至少要掌握基础的核心web技术 —— 例如HTML、CSS和Javascript。如果你是一个完全的初学者, <a href="/zh-CN/docs/Learn">这里</a> 将会是一个很好的学习领域。</p>
+</div>
+
+<dl>
+</dl>
+</div>
+
+<div class="column-half">
+<h2 id="将本地游戏移植到Web">将本地游戏移植到Web</h2>
+
+<p>如果你是一个本地游戏开发者(例如你用C++开发游戏),并且你对如何将本地游戏移植到Web感兴趣,你应该更多的学习关于我们的<a href="http://kripken.github.io/emscripten-site/index.html">Emscripten</a> 工具—— 这是一个LLVM JavaScript 编译器。它能获取LLVM字节码(例如用Clang编译C/C++或者其他语言生成的字节码)并且将它们编译成<a href="/en-US/docs/Games/Tools/asm.js">asm.js</a>以在Web上运行。</p>
+
+<p>开始,查看以下:</p>
+
+<ul>
+ <li><a href="http://kripken.github.io/emscripten-site/docs/introducing_emscripten/about_emscripten.html">关于Emscripten</a>——简介和高级特性。</li>
+ <li><a href="http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html">下载和安装</a>——安装工具链。</li>
+ <li><a href="http://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html">Emscripten教程</a>——指导你如何开始。</li>
+</ul>
+</div>
+</div>
+
+<div class="column-container">
+<div class="column-half">
+<h2 id="示例">示例</h2>
+
+<p>有关网页游戏示例的列表,请参阅我们的<a href="/zh-CN/docs/Games/Examples">示例页</a>。也可以查看 <a href="http://www.openwebgames.com/">openwebgames.com</a> 以获得更多有用的资源和示例!</p>
+</div>
+</div>
+
+<p><a href="http://www.openwebgames.com"><img alt="" src="https://mdn.mozillademos.org/files/12790/owg-logo-dark.svg" style="display: block; margin: 0px auto; width: 400px;"></a></p>
+
+<h2 id="请参见">请参见</h2>
+
+<div class="column-container">
+<div class="column-half">
+<dl>
+ <dt><a href="http://buildnewgames.com/">Build New Games</a></dt>
+ <dd>这是一个以大量开放式网页游戏开发教程为特色的协作网站。 最近还不是很活跃,但还是拥有一些不错的资源。</dd>
+ <dt><a href="http://creativejs.com/">Creative JS</a></dt>
+ <dd>一个令人印象深刻的JavaScript技术和实验的集合,并不全是游戏技术,但还是对开发有帮助。 最近并不非常活跃,但仍然拥有一些不错的资源。</dd>
+ <dt><a href="http://gameprogrammingpatterns.com/">Game programming patterns</a></dt>
+ <dd>在线书籍,作者Bob Nystrom,其中讨论了游戏开发环境中的编程模式,旨在帮助游戏开发人员生成更有效,更高效的代码。</dd>
+ <dt><a href="http://blog.artillery.com/">Artillery blog</a></dt>
+ <dd>HTML5游戏公司Artillery在他们的博客上发表的一些有用的文章。</dd>
+ <dt><a href="https://leanpub.com/buildinggamesforfirefoxos/">Building games for Firefox OS</a></dt>
+ <dd>使用HTML5创建2D游戏的快速指南,针对在Firefox OS和其他移动平台上分发。</dd>
+ <dt><a href="http://gamedevjsweekly.com/">Gamedev.js Weekly</a></dt>
+ <dd>关于HTML5游戏开发的每周新闻,每星期五发送。 包含最新的文章,教程,工具和资源。</dd>
+ <dt><a href="http://www.html5gamedevs.com/">HTML5 Game Devs Forum</a></dt>
+ <dd>开发者,架构师,发布者的论坛。提出问题,获得帮助,帮助他人。</dd>
+</dl>
+</div>
+
+<div class="column-half">
+<dl>
+ <dt><a href="http://html5gameengine.com/">HTML5游戏引擎</a></dt>
+ <dd>眼下最流行的HTML5游戏框架列表,包含评分,特色和案例。</dd>
+ <dt><a href="http://www.jsbreakouts.org/">JSBreakouts</a></dt>
+ <dd>比较在不同的框架中的JavaScript Breakout clones,以帮助您作出正确的选择。</dd>
+ <dt><a href="http://gamedevelopment.tutsplus.com/">Tuts与游戏开发</a></dt>
+ <dd>关于游戏开发的教程和案例。</dd>
+ <dt><a href="http://webchat.freenode.net/?channels=bbg">#BBG IRC chat</a></dt>
+ <dd>实时在线与开发者直接对话。</dd>
+ <dt><a href="http://html5devstarter.enclavegames.com/">HTML5 Gamedev Starter</a></dt>
+ <dd>Starter针对游戏开发新手,在网络上提供一个策划列表链接到各种,有用的资源。</dd>
+ <dt><a href="http://js13kgames.com/">js13kGames</a></dt>
+ <dd>针对HTML5游戏开发人员的JavaScript编码竞赛,文件大小限制设置为13千字节。 所有提交的游戏都以可读的形式在GitHub上提供。</dd>
+ <dt><a href="https://hacks.mozilla.org/category/games/">Mozilla Hacks blog</a></dt>
+ <dd>在Mozilla Hacks博客包含关于游戏类别的有趣的游戏开发的相关文章。</dd>
+ <dt><a href="Games/Visual-js_game_engine">Visual-js game engine</a></dt>
+ <dd>2d / 3d / webSocket定向游戏引擎。 只有window下的工具。 托管在bitbucket项目网站。</dd>
+</dl>
+</div>
+</div>
diff --git a/files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html b/files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html
new file mode 100644
index 0000000000..6d5cd2014a
--- /dev/null
+++ b/files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html
@@ -0,0 +1,107 @@
+---
+title: HTML5游戏开发简介
+slug: Games/Introduction_to_HTML5_Game_Gevelopment_(summary)
+tags:
+ - Games
+ - HTML5
+translation_of: Games/Introduction_to_HTML5_Game_Development_(summary)
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/zh-CN/docs/Games")}}</div>
+
+<div>
+<h2 style="line-height: 30px;" id="优点">优点</h2>
+
+<ol>
+ <li>使用HTML5构建的游戏可以在智能手机,平板电脑,个人电脑和智能电视上工作。</li>
+ <li>通过网络以及其他媒体广告宣传您的游戏。</li>
+ <li>付款。收取你想要的,并使用任何你喜欢的付款处理服务。</li>
+ <li>随时更新游戏。</li>
+ <li>收集您自己的分析!</li>
+ <li>更密切地与客户联系。</li>
+ <li>玩家可随时随地玩游戏。</li>
+</ol>
+
+<h2 style="line-height: 30px;" id="网络技术">网络技术</h2>
+</div>
+
+<div> </div>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col" style="text-align: left;"><strong>Function</strong></th>
+ <th scope="col" style="text-align: left;"><strong>Technology</strong></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>Audio</strong></td>
+ <td><a href="/en-US/docs/Web_Audio_API" title="/en-US/docs/Web_Audio_API">Web Audio API</a></td>
+ </tr>
+ <tr>
+ <td><strong>Graphics</strong></td>
+ <td><a href="/en-US/docs/WebGL" title="/en-US/docs/WebGL">WebGL</a> (<a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0)</td>
+ </tr>
+ <tr>
+ <td><strong>Input</strong></td>
+ <td><a href="/en-US/docs/DOM/Touch_events" title="/en-US/docs/DOM/Touch_events">Touch events</a>, <a href="/en-US/docs/API/Gamepad/Using_Gamepad_API" title="/en-US/docs/API/Gamepad/Using_Gamepad_API">Gamepad API</a>, device sensors, <a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a>, <a href="/en-US/docs/DOM/Using_fullscreen_mode" title="/en-US/docs/DOM/Using_fullscreen_mode">Full Screen API</a>, <a href="/en-US/docs/WebAPI/Pointer_Lock" title="/en-US/docs/WebAPI/Pointer_Lock">Pointer Lock API</a></td>
+ </tr>
+ <tr>
+ <td><strong>Language</strong></td>
+ <td><a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a> (or C/C++ using <a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a> to compile to JavaScript)</td>
+ </tr>
+ <tr>
+ <td><strong>Networking</strong></td>
+ <td><a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a> and/or <a href="/en-US/docs/WebSockets" title="/en-US/docs/WebSockets">WebSockets</a></td>
+ </tr>
+ <tr>
+ <td><strong>Storage</strong></td>
+ <td><a href="/en-US/docs/IndexedDB" title="/en-US/docs/IndexedDB">IndexedDB</a> or the "cloud"</td>
+ </tr>
+ <tr>
+ <td><strong>Web</strong></td>
+ <td><a href="/en-US/docs/HTML" title="/en-US/docs/HTML">HTML</a>, <a href="/en-US/docs/CSS" title="/en-US/docs/CSS">CSS</a>, <a href="/en-US/docs/SVG" title="/en-US/docs/SVG">SVG</a>, <a href="/en-US/docs/Social_API" title="/en-US/docs/Social_API">Social API</a> (and much more!)</td>
+ </tr>
+ </tbody>
+</table>
+
+<div class="twocolumns">
+<dl>
+ <dt><a href="/en-US/docs/DOM/Using_fullscreen_mode" title="/en-US/docs/DOM/Using_fullscreen_mode">Full Screen API</a></dt>
+ <dd>全屏游戏。</dd>
+ <dt><a href="/en-US/docs/API/Gamepad/Using_Gamepad_API" title="/en-US/docs/API/Gamepad/Using_Gamepad_API">Gamepad API</a></dt>
+ <dd>使用游戏手柄或其他游戏控制器。</dd>
+ <dt><a href="/en-US/docs/HTML" title="/en-US/docs/HTML">HTML</a> and <a href="/en-US/docs/CSS" title="/en-US/docs/CSS">CSS</a></dt>
+ <dd>构建,样式和布局游戏的用户界面。</dd>
+ <dt><a href="/en-US/docs/HTML/Element/audio" title="/en-US/docs/HTML/Element/audio">HTML audio</a></dt>
+ <dd>轻松播放简单的音效和音乐。</dd>
+ <dt><a href="/en-US/docs/IndexedDB" title="/en-US/docs/IndexedDB">IndexedDB</a></dt>
+ <dd>将用户数据存储在他们自己的计算机或设备上。</dd>
+ <dt><a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a></dt>
+ <dd>快速的网页编程语言为您的游戏编写代码。轻松移植您现有的游戏 <a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a> 或 <a href="http://asmjs.org/spec/latest/" title="http://asmjs.org/spec/latest/">Asm.js</a></dd>
+ <dt><a href="/en-US/docs/WebAPI/Pointer_Lock" title="/en-US/docs/WebAPI/Pointer_Lock">Pointer Lock API</a></dt>
+ <dd>在游戏界面中锁定鼠标或其他指针设备。</dd>
+ <dt><a href="/en-US/docs/SVG" title="/en-US/docs/SVG">SVG</a> (Scalable Vector Graphics)</dt>
+ <dd>构建能够顺利扩展的矢量图形,无论用户显示器的大小或分辨率如何。</dd>
+ <dt><a href="/en-US/docs/JavaScript/Typed_arrays" title="/en-US/docs/JavaScript/Typed_arrays">Typed Arrays</a></dt>
+ <dd>从JavaScript中访问原始二进制数据; 操纵GL纹理,游戏数据或其他任何东西。</dd>
+</dl>
+
+<p><a href="/en-US/docs/Web_Audio_API" title="/en-US/docs/Web_Audio_API">Web Audio API</a></p>
+
+<dl>
+ <dd>实时控制音频的播放,合成和操纵。</dd>
+ <dt><a href="/en-US/docs/WebGL" title="/en-US/docs/WebGL">WebGL</a></dt>
+ <dd>创建高性能,硬件加速的3D(和2D)图形。<a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0.</dd>
+ <dt><a href="/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a></dt>
+ <dd>实时通讯控制音频和视频数据,包括电话会议,并在两个用户之间来回传送其他应用数据,如聊天。</dd>
+ <dt><a href="/en-US/docs/WebSockets" title="/en-US/docs/WebSockets">WebSockets</a></dt>
+ <dd>将您的应用程序或站点连接到一个服务器以实时传输数据。适合多人游戏动作,聊天服务等。</dd>
+ <dt><a href="/en-US/docs/DOM/Using_web_workers" title="/en-US/docs/DOM/Using_web_workers">Web Workers</a></dt>
+ <dd>生成后台线程为多核处理器运行自己的JavaScript代码。</dd>
+ <dt><a href="/en-US/docs/DOM/XMLHttpRequest" title="/en-US/docs/DOM/XMLHttpRequest">XMLHttpRequest</a> and <a href="/en-US/docs/DOM/File_API" title="/en-US/docs/DOM/File_API">File API</a></dt>
+ <dd>从一个Web服务器发送和接收任何您想要的数据,如下载新的游戏级别和艺术品,以便来回传送非实时游戏状态信息。</dd>
+</dl>
+</div>
+
+<p> </p>
diff --git a/files/zh-cn/games/publishing_games/game_distribution/index.html b/files/zh-cn/games/publishing_games/game_distribution/index.html
new file mode 100644
index 0000000000..c643e5804a
--- /dev/null
+++ b/files/zh-cn/games/publishing_games/game_distribution/index.html
@@ -0,0 +1,127 @@
+---
+title: Game distribution
+slug: Games/Publishing_games/Game_distribution
+translation_of: Games/Publishing_games/Game_distribution
+---
+<div>{{GamesSidebar}}</div>
+
+<p class="summary">你已经跟着一两个<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript">教程</a>做了一个HTML5游戏了——真棒 ! 这篇文章介绍了一些可以让你投放你的游戏的方式。 包括自己建立网站,在公开的应用市场上线,或是发布到Google Play或IOS的App Store。</p>
+
+<h2 id="HTML5相较于传统的好处">HTML5相较于传统的好处</h2>
+
+<p>用HTML5构筑游戏有许多好处,例如</p>
+
+<h3 id="多平台兼容">多平台兼容</h3>
+
+<p>  HTML5本身是多平台的,所以你只需要写一种代码就可以适配不同的平台。 从小型的智能手机和平板电脑,到笔记本电脑和台式电脑, 再到智能电视,智能手表甚至是智能冰箱(如果它内置现代化浏览器的话)。</p>
+
+<p>  你并不需要数个开发小组去编写不同平台的代码,你们只需要维护这一种基础代码。 你可以花更多时间去<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">推广游戏</a>和促进<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization">游戏收益化</a>。</p>
+
+<h3 id="即时更新">即时更新</h3>
+
+<p>  你不需要花数日去上传你的游戏代码.。如果你发现了漏洞,你可以立即修复它,升级系统和在服务端上传代码以为你的用户更新游戏几乎都是即时的</p>
+
+<h3 id="直连,直玩">直连,直玩</h3>
+
+<p>  若是HTML5游戏,你无需让大家去应用商店搜索,只需要给他们URL链接即可,他们点击链接就可以直接玩游戏,而不需要使用第三方平台或是下载一个很大的安装包来安装游戏。不过你仍需考虑你的游戏的大小是否可能会让用户花一点时间来加载资源,以及你的游戏对网速的需求。总之,如果你把你的游戏按照你的设想构建,并且在开玩之前没有那么多弯弯绕绕,推广它还是很容易的</p>
+
+<h2 id="电脑还是手机?">电脑还是手机?</h2>
+
+<p>  我们感兴趣的绝大部分流量——HTML5游戏玩家——都来自移动设备,所以如果你真的想要成功,你就必须专注于这一点。手机端是HTML5真正发光发热的地方,那里没有Flash,HTML5便是全部。</p>
+
+<p>  要与PC端游直接竞争是很困难的,当然你也可以在PC端发布你的游戏(见下文的{{anch("电脑平台")}})你也应该这么做,因为这可以让你的游戏支持的平台变得多样化,但谨记,电脑游戏的开发者拥有多年的经验,优秀的工具和稳定的发行渠道。许多HTML5游戏会与传统电脑游戏面向不同的受众市场。例如,简单的的小游戏比大型的沉浸式游戏更有人气,这类游戏通常设计成用两根手指,甚至一根手指玩,所以你可以拿着设备玩游戏,还可以用第二只手做你目前需要的任何事情。</p>
+
+<p>  话又说回来,电脑平台易于发行游戏,因为有许多好用的打包软件帮助你构造游戏的架构(见下文{{anch("游戏打包")}}),为你的游戏配置适应电脑端的控制器也是很不错的做法——即使你的游戏主要面向手机用户。用户可以在任何平台畅玩你的游戏,电脑端也应该是其中之一。此外,在电脑端先构建和测试游戏通常更为便捷,然后再到手机端测试BUG</p>
+
+<h2 id="发布游戏">发布游戏</h2>
+
+<p>当你要发行游戏时,通常有三种主要的方式可供选择</p>
+
+<ul>
+ <li>自运营</li>
+ <li>发行商代理</li>
+ <li>上架商店</li>
+</ul>
+
+<p>记住你的游戏名应该要足够独特,这样可以在发布之后迅速地<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">推广</a>, 但也要同样朗朗上口,这样人们才不会忘记。</p>
+
+<h3 id="自运营">自运营</h3>
+
+<p>如果你是前端开发者,你应该已经知道要做什么了. 一个HTML5游戏不过是又一个网站而已.。你可以将它上传到远程服务器,设置一个好记的域名,然后就可以自己开始运营游戏了。</p>
+
+<p>如果你想从游戏开发中赚钱,你应该用多种方法保护你的源码,这样其他人不会轻易地取得你的源码并且拿去当成自己的去出售. 你可以压缩和精简代码,让它变得更小,更难读,这样他人就不能轻易的复刻你的游戏。一个更好的方法是在网上发布测试版如果你打算打包你的项目并把它出售给Steam或者iTunes。</p>
+
+<p>如果你只是为了娱乐性质的话, 开放源码可以让那些想要从你的作品中学习的人收益.你甚至不需要担心主机提供商,因为你可以<a href="http://dev.end3r.com/2014/02/host-your-html5-games-on-github-pages/">在Github上托管游戏</a>. 你可以有一个免费的主机,可控制的版本,以及可能的贡献者——如果这个项目足够有趣的话.</p>
+
+<h3 id="发行商和门户网站">发行商和门户网站</h3>
+
+<p>  顾名思义,开发商可以帮助你发行游戏,是否交给开发商则取决于你的游戏开发计划:你想在全平台发行么?或你只向<a href="https://developer.mozilla.org/en-US/docs/Games/Publishing_games/Game_monetization">购买了游戏</a>的用户开放游戏?这都取决于你,考虑各个选项,试验和结论。你可以在<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization/">游戏收益化</a>这篇文章中得到更详细的关于发行商的解释。</p>
+
+<p>  这里还有许多独立的门户网站收集HTML5游戏,例如 <a href="http://html5games.com/">HTML5Games.com</a>, <a href="http://www.marketjs.com/">MarketJS.com</a>, <a href="http://clay.io/">Clay.io</a>, or <a href="https://developers.poki.com/">Poki</a>  你可以把你的游戏发布上去,它会得到一些自然的推广,因为这些网站吸引了大量的流量。一些网站会把你的文件放在他们的服务器上运营,而其他网站则只链接到你的网站或将你的游戏嵌入他们的网站,这样的曝光可能只是为你的游戏提供宣传,如果你的游戏旁边有广告(或其他赚钱的选项),它也可能为你的游戏提供收益化。</p>
+
+<h3 id="网络和应用商店">网络和应用商店</h3>
+
+<p>你也可以直接把游戏发布到不同的应用商店里, 或者是应用市场,要做到这一点,你必须准备好并将其打包为针对您想要针对的每个应用程序生态系统的特定构建格式. 见下文 {{anch("应用市场—多样化平台")}}来获取更多关于应用市场的细节</p>
+
+<h2 id="应用市场—多样化平台">应用市场—多样化平台</h2>
+
+<p>让我们看看针对不同平台和操作系统的市场/商店有哪些可用选项。</p>
+
+<div class="note">
+<p><strong>Note</strong>: 这些是最流行的发行平台,但这并不是说这些是唯一的选择。你也可以尝试找到一个对口的平台,并直接向那些对你的游戏感兴趣的观众推广你的游戏。在这里,你的创造力至关重要。</p>
+</div>
+
+<h3 id="网络商店">网络商店</h3>
+
+<p>  最适合HTML5的平台是基于web的商店. 为它们<a href="http://code.tutsplus.com/tutorials/preparing-for-firefox-os--mobile-18515">准备一款游戏</a>很容易,因为这样的操作几乎不需要修改游戏本身——通常在包含所有资源的压缩包中添加包含必要信息的清单文件就足够了。</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/pl/docs/Mozilla/Firefox_OS">Firefox OS</a> 是HTML5游戏的完美硬件平台,因为系统本身是用JavaScript编写的,而且是开源的。您可以快速访问控制硬件的核心应用程序,<a href="https://marketplace.firefox.com/">Firefox Marketplace</a> 是推广你的游戏的好地方,你也可以更进一步,允许人们直接从网络上安装你的游戏。</li>
+ <li><a href="https://chrome.google.com/webstore/">The Chrome Web Store</a> 也是一个吸引人的选择——同样,准备好一个清单文件,压缩你的游戏并填写在线提交表单就足够了。</li>
+ <li><a href="http://www.tizenstore.com/">Tizen</a> 还高度重视支持用JavaScript编写的应用程序。他们的商店是另一个可用的选择。</li>
+</ul>
+
+<h3 id="手机应用商店">手机应用商店</h3>
+
+<p>  在移动市场上,iOS版的苹果应用商店(Apple App Store)、Android版的谷歌Play以及其他竞争对手。原生商店中已经充斥着销售优秀游戏的成熟开发者,所以你必须具备足够的天赋和幸运才能获得关注。</p>
+
+<ul>
+ <li>iOS App Store 很难进入,因为游戏必须满足严格的要求,你必须等待一到两周才能被接受。此外,它是最著名的移动商店,有成千上万的应用程序,所以很难从人群中脱颖而出。</li>
+ <li>Google Play's 的要求不那么严格,所以商店被低质量的游戏污染了。由于每天提交的应用程序数量庞大,因此很难被注意到。在这里赚钱也更加困难——大多数来自iOS的付费游戏都是在Android上作为免费游戏发布的,盈利来自于应用内购买(IAPs)或广告。</li>
+ <li>其他面向Windows Phone或黑莓(Blackberry)等本土移动平台的商店也在努力分一杯羹,而且远远落后于竞争对手。在那里提交你的游戏是很好的,因为它会更容易被注意到。</li>
+</ul>
+
+<p>如果你想了解更多关于不同类型的应用程序商店的信息,你可以在维基百科上查看<a href="https://en.wikipedia.org/wiki/List_of_mobile_software_distribution_platforms">手机软件发布平台列表</a>。</p>
+
+<h3 id="电脑平台">电脑平台</h3>
+
+<p>  为了扩大你的受众,你也可以使用HTML5游戏去占据电脑游戏市场——只要记住那些已经占据了大部分市场份额的AAA级游戏,并仔细考虑这是否适合你的策略。要正确的在电脑端运行,您应该支持所有三种操作系统:Windows、Mac OS和Linux。最大的电脑游戏商店无疑是<a href="http://steamcommunity.com/">Steam</a> — 独立开发者可以通过 <a href="https://steamcommunity.com/greenlight/">Greenlight</a> 接触steam. 请记住,您必须通过为不同的平台上传不同的版本来处理跨平台问题。</p>
+
+<p>  在你入驻Steam之后,便会有许多类似于<a href="http://www.humblebundle.com/">Humble Bundle</a>等项目的讨论,这些项目可以把最受欢迎的独立游戏能够呈现给更多人。不过,这更像是一个绝佳的促销机会,而不是一种赚大钱的方式,因为捆绑游戏的价格通常相当低。</p>
+
+<h2 id="打包游戏">打包游戏</h2>
+
+<p>    网页是HTML5游戏的首选也是最好的选择,但如果你想接触到更广泛的受众并在封闭的生态系统中发行你的游戏,你仍然可以通过打包它来做到这一点。好在你不需要几个独立的团队在不同的平台上致力于同一款游戏——你可以一次性构建它,并使用像 <a href="/en-US/docs/">Phonegap</a> 或<a href="/en-US/docs/"> CocoonIO</a> 这样的工具为本地商店打包游戏。生成的包通常非常可靠,但是您仍然应该测试它们,并注意要修复的小问题或bug。</p>
+
+<h3 id="实用工具">实用工具</h3>
+
+<p>  根据您的技能、首选框架或目标平台,可以选择多种工具。关键是为你的特定任务选择最好的工具。</p>
+
+<ul>
+ <li><a href="http://phonegap.com/">Phonegap</a> —基于Cordova,这是为本地平台构建/打包JavaScript应用程序最流行的工具</li>
+ <li><a href="http://cocoon.io/">CocoonIO</a> — 为多个本地商店构建HTML5游戏的最流行的工具。它对画布上呈现的游戏有自己的性能优化,并支持许多游戏框架。</li>
+ <li><a href="http://impactjs.com/ejecta">Ejecta</a> — 一个专门用于为iOS打包使用<a href="http://impactjs.com/">the ImpactJS</a>框架创建的游戏的工具,由ImpactJS作者构建。它提供了与ImpactJS的无缝集成,但只支持一个框架和应用程序商店。</li>
+ <li><a href="http://nwjs.io/">NW.js</a> — 这款游戏的前身是Node-Webkit,它是开发适用于Windows、Mac和Linux的桌面游戏的首选。这些发行版与WebKit引擎打包在一起,可以在任何平台上提供呈现。</li>
+</ul>
+
+<p>  其他替代工具包括:</p>
+
+<ul>
+ <li><a href="https://software.intel.com/en-us/intel-xdk">Intel XDK</a> — 一个很棒的的替代品,类似CocoonIO。</li>
+ <li><a href="http://electron.atom.io/">Electron</a> — 或者叫Atom Shell,是GitHub的一个开源跨平台工具。.</li>
+ <li><a href="http://manifoldjs.com/">Manifold.js</a> — 微软团队的这个工具可以从iOS、Android和Windows创建HTML5游戏的本地发行版。</li>
+</ul>
+
+<h2 id="总结">总结</h2>
+
+<p>  发行游戏是让你的世界为世界所知的方式,选择很多,但没有上上策。当你发行了游戏之后,便是专注于<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion/">推广</a>的时候了——让人们知道你的游戏的存在。没有推广,它们甚至都可能不知道有这个游戏,更别说玩了。</p>
diff --git a/files/zh-cn/games/publishing_games/game_promotion/index.html b/files/zh-cn/games/publishing_games/game_promotion/index.html
new file mode 100644
index 0000000000..e6d5e756be
--- /dev/null
+++ b/files/zh-cn/games/publishing_games/game_promotion/index.html
@@ -0,0 +1,79 @@
+---
+title: Game promotion
+slug: Games/Publishing_games/Game_promotion
+translation_of: Games/Publishing_games/Game_promotion
+---
+<div>{{GamesSidebar}}</div>
+
+<p class="summary">开发与发行你的游戏并不是全部.。你应该让大家知道你有个大家会喜欢玩的游戏。这儿有很多方法去推广你的游戏——大部分方法是免费的, 所以即使即使你正努力以一名零预算的独立开发者的身份谋生,你也可以让人们知道你的新游戏.。推广游戏也对之后的<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization">游戏收益化</a>大有裨益, 所以正确地推广游戏是很重要的。</p>
+
+<h2 id="竞赛">竞赛</h2>
+
+<p>       参加竞赛不仅将提升您的游戏开发技能,让你认识新朋友、学习开发,它还将让你参与到社区之中。如果你在比赛中做了一个好的游戏并赢得了一些奖品,你的游戏就会自然而然地被组织者和其他参与者推广开来。你会变得富有和出名,至少他们是这么说的。<br>
+        许多优秀的游戏都是从一个游戏制作比赛上的demo开始的。如果你的想法和执行力都足够好,你就会成功。另外,比赛通常要求游戏有一个固定的主题,所以如果你一筹莫展,你也可以围绕这个主题进行创作。</p>
+
+<h2 id="网站与博客">网站与博客</h2>
+
+<p>  你应该创建自己的网站,包含所有关于游戏的信息,这样人们就可以看到你在做什么。你能包含的信息越多越好 — 包括截图,简报,预告,宣传资料, 需求,可用的平台,赞助以及其他. 让你的用户在网上直接玩你的游戏——或者说测试版可以让你得到许多电子。同时,为了让你的用户能够更好的玩游戏,你应该做些网站优化(SEO)</p>
+
+<p>  你也应该在博客公布所有与你游戏开发有关的动作,写下你的开发历程,严重的bug,有趣的事情,经验教训,以及作为游戏开发者的起起伏伏。坚持发布信息有助于他人从中学习,提高你在社区中的声誉,改进你的网站优化。另一种选择是发布<a href="http://dev.end3r.com/?s=monthly+report">每月报告</a>——总结你所有进展的报告——它能够帮助你看到你在整个月都完成了什么,还有什么需要去做,并不断提醒人们你的游戏即将发行——创造口碑总是好的。</p>
+
+<h2 id="社交媒体">社交媒体</h2>
+
+<p>  你的社交媒体的风格很重要 — 选择正确的<a href="https://twitter.com/hashtag/gamedev">标签</a>,交朋结友, 参与交流, 帮助其他开发者. 保持真诚,这是你与人结交的关键, 因为没有人喜欢无聊的新闻发布或者硬广告.。一旦游戏完成,你的社区会帮助你宣传你的小宝贝游戏的</p>
+
+<p>你应该至少使用推特(Twitter)和脸书(Facebook)之中的一个,并且入驻一个合适的论坛,最出名的就是 <a href="http://www.html5gamedevs.com/">HTML5GameDevs.com</a>. 分享你的游戏开发信息,回答别人的问题, 这样人们会在心里衡量你所做的一切并且知道你做的很好.。记住也别逢人就说你的游戏——你可不是行走的广告</p>
+
+<p>发展你的粉丝,你可以与他们交流,分享一些小贴士,提供一些福利, 在比赛中分发奖品,或者只是抱怨天气或者浏览器的问题,举止冷静,慷慨大方, 做你自己,去帮助别人,你就会得到尊重。</p>
+
+<h2 id="游戏门户网站">游戏门户网站</h2>
+
+<p>设立门户网站主要与<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization">收益化</a>挂钩,  但是如果你不打算<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization#Licensing">售卖许可</a>来让人们可以购买你的游戏而是打算<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization#Advertisements">发布广告</a> , 在免费的门户网站上推广游戏会更有效. 你可以在公共门户网站,比如<a href="http://html5games.com/">HTML5Games.com</a>发布游戏, 比起传统的游戏发行平台,它更像一个宣传平台.</p>
+
+<p>免费的门户网站带来了流量, 但是,只有最好的广告才足够受欢迎,能够从发布的广告中获得一些业绩. 另一方面,如果你没有预算和有限的时间,门户网站也是一个完美的工具,它可以让更多人看到你的游戏</p>
+
+<h2 id="媒体宣传">媒体宣传</h2>
+
+<p>你可以试着联系媒体去宣传你的游戏,不过要记住,他们每天都在处理成吨的请求, 所以如果它们没有及时回复你,请保持耐心, 在于他们交流时保持礼貌. 一定要先检查他们是否只接纳特定类型的游戏或平台,这样你才不会发送与之无关的内容。如果你方式恰当并且你的游戏很好,那么你就有更多的成功机会</p>
+
+<p>如果你想了解更多关于联系媒体的礼仪,你可以阅读 <a href="http://www.pixelprospector.com/how-to-contact-press/">How To Contact Press</a> - 由 Pixel Prospector编写的一篇很棒的指南, 还有<a href="http://videogamejournaliser.com/">Video Game Journaliser</a>,他们创建的一个记录媒体联络名单的网站.</p>
+
+<h2 id="教程">教程</h2>
+
+<p>与其他开发者互通有无是很好的 — 毕竟你可能也曾在网上的一两篇文章上学到了些东西, 所以你要花时间把这些知识传递出去. 谈论或写一些你取得的成就或克服的问题是人们会感兴趣的事情. 你可以拿你自己的游戏做例子, 特别是当你<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Controls_Gamepad_API">展示你已经实现的事情</a>. 这样每个人都会受益——人们学习新的技能,你的游戏会得到推广,如果你足够幸运,你甚至可以因为编写教程而获得报酬</p>
+
+<p>像是<a href="http://gamedevelopment.tutsplus.com/">Tuts+ Game Development</a> 这样的网站可能会更让人开心——他们为文章付稿费。 但并不是所有的主旨都会被接受。当你在写教程的时候,记住要把重点放在给读者提供一些有价值的东西上。他们想要学习一些东西——提供你的专业知识并将你的游戏作为案例研究。专注于一个方面,并试图解释它的全部和细节。如果人们有任何问题,请记得在评论中跟进讨论.</p>
+
+<p>如果您联系的门户网站因你未写过教程而未采纳你的教程,可以在<a href="/en-US/docs/Games/Publishing_games/Game_promotion#Website_and_blog">自己的博客</a>先发布教程,这是锻炼你的写作技巧的最简单的方式.</p>
+
+<h2 id="YouTuber视频主(YouTubers)">YouTuber视频主(YouTubers)</h2>
+
+<p>这是一种趋势 — 别低估了YouTuber视频主(YouTubers)们对游戏的影响力, 与他们交流,让他们做游戏实况会极大的宣传你的游戏. 不过,你也应该现实一点——不要认为仅仅这一点就会让你的下载量或访问量飙升,而且要准备好处理好不好的评论.</p>
+
+<p>有两种方法可以让Youtubers选择你的游戏:第一种方法是你直接联系他们,并通过电子邮件或私人信息向他们发送游戏链接. 第二种方法更省时 - 如果你很有名,Youtubers可能会向你索要游戏链接或游戏文件. 这个<a href="http://videogamecaster.com/big-list-of-youtubers">YouTuber的名单</a>是个很好的开始.</p>
+
+<h2 id="活动">活动</h2>
+
+<p>如果你已经完成了上面列出的所有选项,你仍然可以找到新的、创造性的方式去推广你的游戏——活动便是另一个很好的例子。参加本地和全球的活动,让您能够面对面地与您的粉丝以及开发社区的其他成员见面。别辜负了他们专程花时间来看你的心思。.</p>
+
+<h3 id="会议">会议</h3>
+
+<p>在许多会议上,您可以发表演讲,解释您克服的一些技术困难,或者如何实现特定的API;其次,以你的游戏为例。专注于知识部分并降低市场营销是很重要的——开发者对这个问题很敏感,如果你只是想向他们推销一些东西,他们可能会对此不满。.</p>
+
+<h3 id="展会">展会</h3>
+
+<p>另一个与活动相关的选项是展会(或博览会)——在这样的活动中,您可以在其他开发者中获得一个摊位,并向所有经过的参与者推广您的游戏。如果你这样做了,那就试着做得独特而有创意,这样你就很容易从人群中脱颖而出。以正确的方式去做,每个人都会谈论你和你的游戏。有一个展台可以让你与你的粉丝直接互动——除了推广部分,你还可以在普通人身上测试你的游戏的新版本,并修复他们发现的任何bug(或包含任何反馈)。你无法想象人们在玩你的游戏时可能会想到什么,以及你在花费数小时打磨游戏时错过了哪些明显的问题。</p>
+
+<h2 id="优惠码">优惠码</h2>
+
+<p>如果你是在销售游戏,那么你应该发行优惠码让人们免费游玩你的游戏(或至少是一个演示版或限时版), 并把它们发送到各地——给媒体,Youtuber,作为比赛奖品等等。如果游戏符合某些人的胃口,就相当于为成千上万人打了一次免费广告。如果你幸运的话,它比任何其他东西都能提高人们对你的游戏的兴趣</p>
+
+<h2 id="培养社区">培养社区</h2>
+
+<p>你可以帮助社区成长,同时推广你自己和你的游戏。发布<a href="http://gamedevjsweekly.com/">每周时事通讯</a>,组织<a href="http://js13kgames.com/">在线竞赛</a>或者<a href="http://gamedevjs.com/">线下聚会</a>,这些都能让别人知道你对自己的工作充满激情,他们可以依靠你。当你需要帮助的时候,他们会在你身边</p>
+
+<h2 id="总结">总结</h2>
+
+<p>任何推广你的游戏的方法都是好的。你有很多选择,其中大部分都是免费的,所以关键在于你的热情和可用时间。有时候你不得不花更多的时间去推广一款游戏,而不是真正去开发它。记住,如果没有人知道世界上最好的游戏的存在,那么拥有它是没有任何意义的。</p>
+
+<p>现在让我们进入<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_monetization">游戏收益化</a>部分,然后挣口饭吃吧。</p>
diff --git a/files/zh-cn/games/publishing_games/index.html b/files/zh-cn/games/publishing_games/index.html
new file mode 100644
index 0000000000..dd51db6761
--- /dev/null
+++ b/files/zh-cn/games/publishing_games/index.html
@@ -0,0 +1,23 @@
+---
+title: 发布游戏
+slug: Games/Publishing_games
+tags:
+ - 发布
+ - 推广
+ - 游戏
+ - 获利
+translation_of: Games/Publishing_games
+---
+<div>{{GamesSidebar}}</div><p class="summary"><span class="seoSummary">HTML5游戏在发布和分发上具有极大的优势--你可以通过网络自由地发布,推广,获利,并且不受分发商的限制。你可以实现通过多种平台获利。这一系列的案例关注在当你想要发布,推广你的游戏,并当游戏变得有名时获取一些回报。</span></p>
+
+<h2 id="游戏发布">游戏发布</h2>
+
+<p>你按照一个或两个教程(<a href="/zh-CN/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript">1</a>,<a href="/zh-CN/docs/Games/Workflows/2D_Breakout_game_Phaser">2</a>)制作了一个HTML5游戏。<a href="/zh-CN/docs/Games/Publishing_games/Game_distribution">Game distribution</a>提供了你发布游戏时所需的一切知识。包括如何在线托管游戏,提交游戏到开放的游戏市场,或封闭的游戏市场,如Google Play,iOS App Store.</p>
+
+<h2 id="游戏推广">游戏推广</h2>
+
+<p>开发完成游戏并不是结束。你必须让世界知道你制作了一些有趣的东西能使他们乐在其中。这些<a href="/zh-CN/docs/Games/Publishing_games/Game_promotion">游戏推广</a>技术— 有些是免费的 — 即使你作为一名0预算的独立开发者为生活奔波,你依旧可以让很多人知道你制作的这个新游戏。推广游戏或许能够使你获得收入。高效的推广非常重要。</p>
+
+<h2 id="游戏获利">游戏获利</h2>
+
+<p>当你开发,发布并推广你的游戏后,你可以考虑通过游戏来获得收入。<a href="/zh-CN/docs/Games/Publishing_games/Game_monetization">游戏获利</a>对于考虑从业余转为全职并以此为生的开发者来说是必要的一个手段。现在来看看你的选择,技术已经足够成熟,现在只差一个合适的机会了。</p>
diff --git a/files/zh-cn/games/publishing_games/游戏货币化/index.html b/files/zh-cn/games/publishing_games/游戏货币化/index.html
new file mode 100644
index 0000000000..5ab915f6b3
--- /dev/null
+++ b/files/zh-cn/games/publishing_games/游戏货币化/index.html
@@ -0,0 +1,95 @@
+---
+title: 游戏货币化
+slug: Games/Publishing_games/游戏货币化
+tags:
+ - 推广
+ - 收入
+ - 游戏
+ - 销售
+translation_of: Games/Publishing_games/Game_monetization
+---
+<div>{{GamesSidebar}}</div>
+
+<p class="summary">当你花时间创造一个游戏的时候, 从<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_distribution">发布</a>和<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">促销</a>中赚钱是你应该考虑的事. 如果你正做出大量努力去成为一个能够以此为生的独立游戏开发者, 接下去, 看看你有哪些选择. 技术手段已经足够成熟; 接下来只是选择正确的方法.</p>
+
+<h2 id="付费游戏">付费游戏</h2>
+
+<p>你可能想到的第一个,也是最明显的选择便是以面向AAA级游戏的方式销售游戏——即固定的预付款。即使数字市场是关键,你也不需要打印封面,也不需要将游戏放在实体店的盒子里,但要想以固定的价格销售游戏赚取可观的利润,你必须将时间和金钱投入到市场营销中去。只有最好的游戏才能做到收支平衡,或者赚得比制作成本还要多,你仍然需要很多的运气。</p>
+
+<p>你为你的游戏收取多少费用取决于市场,游戏的质量和许多其他小因素。一款街机iOS游戏售价为0.99美元,但一款更长的rpg风格的Steam桌面游戏售价为20美元;两个价格都可以。你必须跟随市场,做自己的研究——迅速从错误中吸取教训是很重要的。</p>
+
+<h2 id="应用内购买内容">应用内购买内容</h2>
+
+<p>你可以提供一款带有应用内购买功能(IAP)的免费游戏,而不是让人们预先为你的游戏付费。在这种情况下,玩家不需要花一分钱就可以获得游戏——将游戏交给玩家,但要提供游戏内的货币、奖金或福利。具体的例子可以包括奖金水平,更好的武器或咒语,或补充所需的能量发挥。设计一个好的IAP系统本身就是一门艺术。</p>
+
+<p>记住,你需要下载数千次游戏才能使IAPs有效——只有一小部分玩家会真正为IAPs付费。多小?情况各不相同,但大约每千人中就有一个人处于平均水平。玩你的游戏的人越多,别人就越有可能付钱,所以你的收入很大程度取决于你的<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">推广</a>方式.</p>
+
+<h3 id="免费增值模式">免费增值模式</h3>
+
+<p>带有IAPs功能的游戏通常被称为免费增值游戏——免费增值游戏可以免费取得与游玩,但你可以为额外的(高级)功能、虚拟物品或其他好处付费。在大公司专注于创造游戏后,这个词本身就带有负面含义,其主要目的是为了从玩家那里获得尽可能多的钱,而不是提供一种有趣的体验。最糟糕的情况是,你可以用真金实银来获得相对于其他玩家的优势,或限制玩家进入游戏的下一阶段,除非玩家付费。“为赢付费”这个术语是被创造出来的,并且这种方法不受许多玩家和开发者的欢迎。如果你想要实现IAPs,那就试着用玩家喜欢的东西来为游戏增加价值,而不是把它拿出来然后收费。</p>
+
+<h3 id="扩展包(Add-on)和可下载内容(DLC)">扩展包(Add-on)和可下载内容(DLC)</h3>
+
+<p>扩展包和可下载内容是为已经发行的游戏提供额外价值的好方法,但请记住,您必须提供体面的、有趣的内容来吸引人们购买它。一套全新的带有新角色、武器和故事的关卡对于DLC来说是一个很好的素材,但要想获得足够的销量,游戏本身必须是受欢迎的,否则就不会有玩家愿意将他们辛苦赚来的钱花在这上面。</p>
+
+<h2 id="推广">推广</h2>
+
+<p>除了积极销售游戏以外,你也可以尝试被动销售 — 投放广告和开展相关活动或许有益于<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">推广</a>你的游戏,但你的游戏必须让人上瘾,这并不像听起来那么容易。你仍然需要计划好,在某种程度上,你也需要一些运气。如果你的游戏像病毒一样传播开来,人们开始分享它,你就能从广告中获得大量的下载和收益。</p>
+
+<p>有许多公司提供广告系统——你注册后,允许他们展示广告,以换取一定比例的利润。谷歌AdSense被认为是最有效的一个,但它不是为游戏而设计的,使用它来达到这个目的是一个非常糟糕的做法。不要冒着让你的账户被封禁,资产被冻结的风险,游戏开发者们更青睐门户网站,如<a href="https://www.leadbolt.com/">LeadBolt</a>。他们提供了易于实现的系统,以在您的游戏显示广告并与您分享收益。</p>
+
+<p>视频广告正变得越来越受欢迎,特别是以预播放的形式——它们会在游戏开始时显示,而此时游戏还在加载中。至于在游戏中放置广告的位置,这完全取决于你自己。它应该尽可能的微妙,以避免过多地惹恼玩家,但又足够的可见性让玩家点击它或至少注意到它。通过屏幕在游戏会话之间添加广告是一种流行的方法。</p>
+
+<h2 id="授权证书">授权证书</h2>
+
+<p>有一种方法可以作为自己的盈利模式,即出售游戏发行许可。越来越多的门户网站有兴趣在他们的网站上展示你的游戏。他们遵循各种策略来通过你的游戏赚钱,但你不必担心所有这些,因为出售许可通常是一次性的交易。你得到了钱,他们就可以创造性地使用你的游戏来赚钱。</p>
+
+<p>一开始寻找发行商是件困难的事情 — 你可以在<a href="http://www.html5gamedevs.com/">HTML5 Gamedevs forums</a>联络他们.。如果你很有名,他们可能会联系你。大多数交易都是通过电子邮件与出版商一方的专业人士进行沟通的。一些出版商的网站很容易获得这些信息,而另一些则很难找到。当接触出版商的时候,尽量友好而直接——他们都是很忙的人。</p>
+
+<h3 id="独家许可">独家许可</h3>
+
+<p>独家性许可是针对一个发行商的一种许可类型——你创造了一款游戏,并将其所有权利出售给了一个实体,同时还拥有重新发行该游戏的权利 — <a href="http://www.softgames.de/">Softgames</a>就是这样一家发行商。 在出版商拥有版权的情况下,你不能再以任何形式出售它——这就是独家交易价值不菲的原因。到底是多少?这取决于游戏的质量,游戏类型,发行商,以及其他许多因素,但通常价格在2000到5000美元之间。一旦你卖出了独家授权,你就不用再参与推广这款游戏了,因为你赚不到更多钱,所以只有在你确信这款游戏足够盈利的情况下,你才会参与这样的交易。</p>
+
+<h3 id="独家许可_2">独家许可</h3>
+
+<p>这种方法不那么严格——您可以将许可证出售给多个发布者。这是最受欢迎的方法,因为对于每一个新的发行商(总会有的),你都可以以非独家的条款出售你的游戏。请记住,有了这个许可,发行商就不能再对其进行重新发行了——这通常被称为站点锁定交易,因为他们购买了在自己的门户网站上发布游戏的权利。非独家许可的通常成本约为500美元。</p>
+
+<h3 id="定期付费">定期付费</h3>
+
+<p>此外,用户还可以通过购买服务来月付你的游戏而不是一次性付款,每一款游戏每月都能为你提供一定的钱——大约20-50美元。你可以决定是一次性付清一段时间还是每月付一次。记住它可以被随时取消,所以它不是一个通解。</p>
+
+<h3 id="推广收入">推广收入</h3>
+
+<p>你可以在自己的游戏中发布广告,并试图找到流量来赚取一些钱,但你也可以与发行商达成收益分成协议。他们将负责吸引流量,并将分享收益——通常是每月73开或者五五开的交易。</p>
+
+<p>请记住,许多新的、低质量的发行商会希望你的游戏获得广告收入而不是授权,因为这对他们来说更便宜,并且你可能只会在整个交易中获得每款游戏约2美元的收益。在与新出版商打交道时要小心——有时候,降低已知出版商的许可成本比冒着被未知出版商骗钱的风险要好。</p>
+
+<p>发行商从你的游戏中获取收益分成,以及/或许可可能需要实现他们自己的API,这可能需要额外的工作,所以你也要考虑到这一点。</p>
+
+<h3 id="品牌">品牌</h3>
+
+<p>你可以出售你的游戏的品牌使用权,也可以用你自己的游戏来招揽其他人的品牌。在第一种情况下,它几乎类似于非独占许可,但是你的客户通常会购买代码的权限并构建自己的游戏。在第二种情况下,它就像一个自由的交易,但你将会在代码中加入客户的品牌图形,或有时会按照他们的指示实现需求。举个例子,如果你有一个游戏,玩家点击食物,你可以把食物换成客户的产品来给他们做广告。这个模型中的价格根据品牌、客户和工作量的不同而有很大的差异。</p>
+
+<h2 id="其他不以游戏为主题的变现手段">其他不以游戏为主题的变现手段</h2>
+
+<p>在开发HTML5游戏时,你还可以通过其他方式赚钱,而这甚至不需要与游戏相关。</p>
+
+<h3 id="销售资源">销售资源</h3>
+
+<p>如果你是一名平面设计师,你可以出售你所创造的游戏的资产,或一些全新的专为这一目的的在线商店,如<a href="http://market.envato.com/">Envato Market</a>. 虽然卖的钱并不多,但如果你是一个著名的设计师,它就是一个额外的被动收入流。</p>
+
+<h3 id="撰写文章和教程">撰写文章和教程</h3>
+
+<p>你可以写一些关于你的游戏的文章,甚至可以从中获得报酬。可以同时取得游戏<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Publishing_games/Game_promotion">推广</a>和收益化的双赢,如果你不滥用它与太多的广告,读者将享受阅读他们以及学习一两个东西。如果你专注于先分享知识,并将游戏作为例子来使用,这应该是可以的。 浏览<a href="http://gamedevelopment.tutsplus.com/">Tuts+ Game Development</a> 或相似的网站来找寻协作机会</p>
+
+<h3 id="周边商品">周边商品</h3>
+
+<p>你可以售卖T恤,<a href="https://www.stickermule.com/user/1070634890/stickers">贴纸</a>或其他周边 — 有些开发者从这些商品中赚的钱比从游戏本身中赚的钱还多,但它只适用于像愤怒的小鸟这样非常受欢迎且易于识别的游戏。不过,这也可能是另一种小的被动收入来源。你的收入越多样化,你的生意就越稳定。</p>
+
+<h3 id="捐助">捐助</h3>
+
+<p>当其他方法都失败时,你可以尝试在你的游戏页面上放置一个捐赠按钮并寻求社区的支持。有时候它是有效的,但前提是玩家了解你并觉得它能够帮助你。这就是为什么小心管理你的社区是如此重要。这在<a href="http://js13kgames.com/">js13kGames</a>比赛中很管用 — 每个参与者都得到了一件免费的t恤,有些人甚至还退了一些钱,以帮助它在未来几年继续运行下去。</p>
+
+<h2 id="小结">小结</h2>
+
+<p>赚钱的方法有很多种——所有适用于“普通”AAA级游戏世界的东西,或多或少都可以应用于休闲HTML5游戏。然而,你也可以专注于销售许可证,做品牌,或者从广告中获得收入分成。你要走哪条路完全取决于你自己。</p>
diff --git a/files/zh-cn/games/techniques/2d_collision_detection/index.html b/files/zh-cn/games/techniques/2d_collision_detection/index.html
new file mode 100644
index 0000000000..dcc688643f
--- /dev/null
+++ b/files/zh-cn/games/techniques/2d_collision_detection/index.html
@@ -0,0 +1,82 @@
+---
+title: 2D collision detection
+slug: Games/Techniques/2D_collision_detection
+translation_of: Games/Techniques/2D_collision_detection
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<div class="summary">
+<p>检测2D游戏中的碰撞算法,依赖于可碰撞物体的形状(例如:矩形与矩形,矩形与圆形,圆形与圆形)。通常情况下,你使用的的简单通用形状,会被称为“hitbox”的实体所覆盖,尽管发生的碰撞并不是像素完美契合的,它看起来也足够好,而且可跨多个实体执行碰撞。本文提供了一系列较为通用的2D游戏中碰撞侦测技术。</p>
+</div>
+
+<h2 id="Axis-Aligned_Bounding_Box">Axis-Aligned Bounding Box</h2>
+
+<p>碰撞侦测其中一种简单的形式是,在两个轴对齐的矩形之间碰撞 — 这意味着没有旋转。这个算法是确定两个矩形任意4边之间不再有间隔,存在间隔代表没有发生碰撞。</p>
+
+<pre class="brush: js">var rect1 = {x: 5, y: 5, width: 50, height: 50}
+var rect2 = {x: 20, y: 10, width: 10, height: 10}
+
+if (rect1.x &lt; rect2.x + rect2.width &amp;&amp;
+   rect1.x + rect1.width &gt; rect2.x &amp;&amp;
+   rect1.y &lt; rect2.y + rect2.height &amp;&amp;
+   rect1.height + rect1.y &gt; rect2.y) {
+ // collision detected!
+}
+
+// filling in the values =&gt;
+
+if (5 &lt; 30 &amp;&amp;
+ 55 &gt; 20 &amp;&amp;
+ 5 &lt; 20 &amp;&amp;
+ 55 &gt; 10) {
+ // collision detected!
+}</pre>
+
+<div class="note">
+<p><strong>Note</strong>: You can see a <a href="http://jsfiddle.net/knam8/">live example of Axis-Aligned Bounding Box collision detection</a> on jsFiddle, to illustrate how this code would work in practice. <a href="https://jsfiddle.net/jlr7245/217jrozd/3/">Here is another example without Canvas or external libraries</a>.</p>
+</div>
+
+<h2 id="圆形碰撞">圆形碰撞</h2>
+
+<p>碰撞测试的另一种形状是两个圆形间的碰撞,该算法是通过获取两个圆心点,并确定圆心距离小于两个圆形的半径和实现的。</p>
+
+<pre class="brush: js">var circle1 = {radius: 20, x: 5, y: 5};
+var circle2 = {radius: 12, x: 10, y: 5};
+
+var dx = circle1.x - circle2.x;
+var dy = circle1.y - circle2.y;
+var distance = Math.sqrt(dx * dx + dy * dy);
+
+if (distance &lt; circle1.radius + circle2.radius) {
+ // collision detected!
+}</pre>
+
+<div class="note">
+<p><strong>Note</strong>: You can see a <a href="http://jsfiddle.net/gQ3hD/2/">live example of Circle collision detection</a> on jsFiddle, to illustrate how this code would work in practice.</p>
+</div>
+
+<h2 id="Separating_Axis_Theorem">Separating Axis Theorem</h2>
+
+<p>This is a collision algorithm that can detect a collision between any two *convex* polygons. It's more complicated to implement than the above methods but is more powerful. The complexity of an algorithm like this means we will need to consider performance optimization, covered in the next section.</p>
+
+<p>Implementing SAT is out of scope for this page so see the recommended tutorials below:</p>
+
+<ol>
+ <li><a href="http://www.sevenson.com.au/actionscript/sat/">Separating Axis Theorem (SAT) explanation</a></li>
+ <li><a href="http://www.metanetsoftware.com/technique/tutorialA.html">Collision detection and response</a></li>
+ <li><a href="http://gamedevelopment.tutsplus.com/tutorials/collision-detection-using-the-separating-axis-theorem--gamedev-169">Collision detection Using the Separating Axis Theorem</a></li>
+ <li><a href="http://www.codezealot.org/archives/55">SAT (Separating Axis Theorem)</a></li>
+ <li><a href="http://rocketmandevelopment.com/blog/separation-of-axis-theorem-for-collision-detection/">Separation of Axis Theorem (SAT) for Collision Detection</a></li>
+</ol>
+
+<h2 id="Collision_Performance">Collision Performance</h2>
+
+<p>While some of these algorithms for collision detection are simple enough to calculate, it can be a waste of cycles to test *every* entity with every other entity. Usually games will split collision into two phases, broad and narrow.</p>
+
+<h3 id="Broad_Phase">Broad Phase</h3>
+
+<p>Broad phase should give you a list of entities that *could* be colliding. This can be implemented with a spacial data structure that will give you a rough idea of where the entity exists and what exist around it. Some examples of spacial data structures are Quad Trees, R-Trees or a Spacial Hashmap.</p>
+
+<h3 id="Narrow_Phase">Narrow Phase</h3>
+
+<p>When you have a small list of entities to check you will want to use a narrow phase algorithm (like the ones listed above) to provide a certain answer as to whether there is a collision or not.</p>
diff --git a/files/zh-cn/games/techniques/3d_collision_detection/index.html b/files/zh-cn/games/techniques/3d_collision_detection/index.html
new file mode 100644
index 0000000000..4d4786f336
--- /dev/null
+++ b/files/zh-cn/games/techniques/3d_collision_detection/index.html
@@ -0,0 +1,153 @@
+---
+title: 3D 碰撞检测
+slug: Games/Techniques/3D_collision_detection
+translation_of: Games/Techniques/3D_collision_detection
+---
+<div>{{GamesSidebar}}</div><p class="summary">本文介绍了用于在3D环境中实现不同边界体积碰撞检测的技术。 后续文章将讨论特定3D库中的实现。</p>
+
+<h2 id="Axis-aligned_bounding_boxes(AABB包围盒)">Axis-aligned bounding boxes(<strong>AABB包围盒</strong>)</h2>
+
+<p> </p>
+
+<p>在游戏中,为了简化物体之间的碰撞检测运算,通常会对物体创建一个规则的几何外形将其包围。其中,AABB(axis-aligned bounding box)包围盒被称为轴对齐包围盒。</p>
+
+<p>与2D碰撞检测一样,轴对齐包围盒是判断两个物体是否重叠的最快算法,物体被包裹在一个非旋转的(因此轴对齐的)盒中,并检查这些盒在三维坐标空间中的位置,以确定它们是否重叠。</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/11797/Screen%20Shot%202015-10-16%20at%2015.11.21.png" style="display: block; height: 275px; margin: 0px auto; width: 432px;"></p>
+
+<p>由于性能原因,轴对齐是有一些约束的。两个非旋转的盒子之间是否重叠可以通过逻辑比较进行检查,而旋转的盒子则需要三角运算,这会导致性能下降。如果你有旋转的物体,可以通过修改边框的尺寸,这样盒子仍可以包裹物体,或者选择使用另一种边界几何类型,比如球体(球体旋转,形状不会变)。下图是一个AABB物体旋转,动态调节盒大小适应物体的例子。</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/11799/rotating_knot.gif" style="display: block; height: 192px; margin: 0px auto; width: 207px;"></p>
+
+<div class="note">
+<p><strong>Note:</strong> 参考<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection/Bounding_volume_collision_detection_with_THREE.js">这里</a>,<font><font>使用</font></font><font><font>Three</font></font><font><font>.js进行</font><font>边界体积碰撞检测。</font></font></p>
+</div>
+
+<h3 id="点与_AABB">点与 AABB</h3>
+
+<p>如果检测到一个点是否在AABB内部就非常简单了 — 我们只需要检查这个点的坐标是否在AABB内; 分别考虑到每种坐标轴. 如果假设  <em>P<sub>x</sub></em>, <em>P<sub>y</sub> 和</em> <em>P<sub>z</sub></em> 是点的坐标,  <em>B<sub>minX</sub></em>–<em>B<sub>maxX</sub></em>, <em>B<sub>minY</sub></em>–<em>B<sub>maxY</sub></em>, 和 <em>B<sub>minZ</sub></em>–<em>B<sub>maxZ</sub></em> 是AABB的每一个坐标轴的范围, 我们可以使用以下公式计算两者之间的碰撞是否发生:</p>
+
+<p><math><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>P</mi><mo>,</mo><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><msub><mi>P</mi><mi>x</mi></msub><mo>&gt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>X</mi></mrow></msub><mo>∧</mo><msub><mi>P</mi><mi>x</mi></msub><mo>&lt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>X</mi></mrow></msub><mo stretchy="false">)</mo><mo>∧</mo><mo stretchy="false">(</mo><msub><mi>P</mi><mi>y</mi></msub><mo>&gt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>Y</mi></mrow></msub><mo>∧</mo><msub><mi>P</mi><mi>y</mi></msub><mo>&lt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>Y</mi></mrow></msub><mo stretchy="false">)</mo><mo>∧</mo><mo stretchy="false">(</mo><msub><mi>P</mi><mi>z</mi></msub><mo>&gt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>Z</mi></mrow></msub><mo>∧</mo><msub><mi>P</mi><mi>z</mi></msub><mo>&lt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>Z</mi></mrow></msub><mo stretchy="false">)</mo></mrow><annotation encoding="TeX">f(P,B)= (P_x &gt;= B_{minX} \wedge P_x &lt;= B_{maxX}) \wedge (P_y &gt;= B_{minY} \wedge P_y &lt;= B_{maxY}) \wedge (P_z &gt;= B_{minZ} \wedge P_z &lt;= B_{maxZ})</annotation></semantics></math></p>
+
+<p>或者用JavaScript:</p>
+
+<pre class="brush: js">function isPointInsideAABB(point, box) {
+ return (point.x &gt;= box.minX &amp;&amp; point.x &lt;= box.maxX) &amp;&amp;
+ (point.y &gt;= box.minY &amp;&amp; point.y &lt;= box.maxY) &amp;&amp;
+ (point.z &gt;= box.minY &amp;&amp; point.z &lt;= box.maxZ);
+}</pre>
+
+<h3 id="AABB_与_AABB">AABB 与 AABB</h3>
+
+<p>检查一个AABB是否和另一个AABB相交类似于检测两个点一样. 我们只需要基于每一条坐标轴并利用盒子的边缘去检测. 下图显示了我们基于 X 轴的检测 — 当然,  <em>A<sub>minX</sub></em>–<em>A<sub>maxX</sub></em> 和 <em>B<sub>minX</sub></em>–<em>B<sub>maxX</sub></em> 会不会重叠?</p>
+
+<p><img alt="updated version" src="https://mdn.mozillademos.org/files/11813/aabb_test.png" style="display: block; height: 346px; margin: 0px auto; width: 461px;"></p>
+
+<p>在数学上的表示就像这样:</p>
+
+<p><math><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>A</mi><mo>,</mo><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><msub><mi>A</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>X</mi></mrow></msub><mo>&lt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>X</mi></mrow></msub><mo>∧</mo><msub><mi>A</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>X</mi></mrow></msub><mo>&gt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>X</mi></mrow></msub><mo stretchy="false">)</mo><mo>∧</mo><mo stretchy="false">(</mo><msub><mi>A</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>Y</mi></mrow></msub><mo>&lt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>Y</mi></mrow></msub><mo>∧</mo><msub><mi>A</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>Y</mi></mrow></msub><mo>&gt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>Y</mi></mrow></msub><mo stretchy="false">)</mo><mo>∧</mo><mo stretchy="false">(</mo><msub><mi>A</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>Z</mi></mrow></msub><mo>&lt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>Z</mi></mrow></msub><mo>∧</mo><msub><mi>A</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mi>Z</mi></mrow></msub><mo>&gt;=</mo><msub><mi>B</mi><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mi>Z</mi></mrow></msub><mo stretchy="false">)</mo></mrow><annotation encoding="TeX">f(A,B) =</annotation></semantics></math></p>
+
+<p>在JavaScript我们可以这样:</p>
+
+<pre class="brush: js">function intersect(a, b) {
+ return (a.minX &lt;= b.maxX &amp;&amp; a.maxX &gt;= b.minX) &amp;&amp;
+ (a.minY &lt;= b.maxY &amp;&amp; a.maxY &gt;= b.minY) &amp;&amp;
+ (a.minZ &lt;= b.maxZ &amp;&amp; a.maxZ &gt;= b.minZ);
+}
+</pre>
+
+<h2 id="球体碰撞">球体碰撞</h2>
+
+<p>球体碰撞边缘检测比AABB盒子稍微复杂一点,但他的检测仍相当容易的。球体的主要优势是他们不变的旋转,如果包装实体旋转,边界领域仍将是相同的。他们的主要缺点是,除非他们包装的实体实际上是球形,包装的实体通常不是一个完美的球形(比如用这样的球形包装一个人将导致一些错误,而AABB盒子将更合适)。</p>
+
+<h3 id="点与球">点与球</h3>
+
+<p>检查是否一个球体包含一个点,我们需要计算点和球体的中心之间的距离。如果这个距离小于或等于球的半径,这个点就在里面。</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/11803/point_vs_sphere.png" style="display: block; height: 262px; margin: 0px auto; width: 385px;"></p>
+
+<p>两个点A和B之间的欧氏距离是<br>
+ <math><semantics><msqrt><mrow><mo stretchy="false">(</mo><msub><mi>A</mi><mi>x</mi></msub><mo>-</mo><msub><mi>B</mi><mi>x</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo stretchy="false">)</mo><mo>+</mo><mo stretchy="false">(</mo><msub><mi>A</mi><mi>y</mi></msub><mo>-</mo><msub><mi>B</mi><mi>y</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>A</mi><mi>z</mi></msub><mo>-</mo><msub><mi>B</mi><mi>z</mi></msub><mo stretchy="false">)</mo></mrow></msqrt><annotation encoding="TeX">\sqrt{(A_x - B_x) ^ 2) + (A_y - B_y)^2 + (A_z - B_z)}</annotation></semantics></math> ,我们的公式指出,球体碰撞检测是:</p>
+
+<p><math><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>P</mi><mo>,</mo><mi>S</mi><mo stretchy="false">)</mo><mo>=</mo><msub><mi>S</mi><mrow><mi>r</mi><mi>a</mi><mi>d</mi><mi>i</mi><mi>u</mi><mi>s</mi></mrow></msub><mo>&gt;=</mo><msqrt><mrow><mo stretchy="false">(</mo><msub><mi>P</mi><mi>x</mi></msub><mo>-</mo><msub><mi>S</mi><mi>x</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>P</mi><mi>y</mi></msub><mo>-</mo><msub><mi>S</mi><mi>y</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>P</mi><mi>z</mi></msub><mo>-</mo><msub><mi>S</mi><mi>z</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></msqrt></mrow><annotation encoding="TeX">f(P,S) = S_{radius} &gt;= \sqrt{(P_x - S_x)^2 + (P_y - S_y)^2 + (P_z - S_z)^2}</annotation></semantics></math></p>
+
+<p>或者用JavaScript:</p>
+
+<pre class="brush: js">function isPointInsideSphere(point, sphere) {
+ // we are using multiplications because is faster than calling Math.pow
+ var distance = Math.sqrt((point.x - sphere.x) * (point.x - sphere.x) +
+ (point.y - sphere.y) * (point.y - sphere.y) +
+ (point.z - sphere.z) * (point.z - sphere.z));
+ return distance &lt; sphere.radius;
+}
+</pre>
+
+<div class="note">
+<p>上面的代码有一个平方根,是一个开销昂贵的计算。一个简单的优化,以避免它由半径平方,所以优化方程不涉及<code>distance &lt; sphere.radius * sphere.radius</code>.</p>
+</div>
+
+<h3 id="球体与球体">球体与球体</h3>
+
+<p>球体与球体的距离类似于点和球体。我们需要测试是球体的中心之间的距离小于或等于半径的总和。</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/11805/sphere_vs_sphere.png" style="display: block; height: 262px; margin: 0px auto; width: 414px;"></p>
+
+<p>在数学上,像这样:</p>
+
+<p><math><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>A</mi><mo>,</mo><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><msqrt><mrow><mo stretchy="false">(</mo><msub><mi>A</mi><mi>x</mi></msub><mo>-</mo><msub><mi>B</mi><mi>x</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>A</mi><mi>y</mi></msub><mo>-</mo><msub><mi>B</mi><mi>y</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>A</mi><mi>z</mi></msub><mo>-</mo><msub><mi>B</mi><mi>z</mi></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></msqrt><mo>&lt;=</mo><msub><mi>A</mi><mrow><mi>r</mi><mi>a</mi><mi>d</mi><mi>i</mi><mi>u</mi><mi>s</mi></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mi>r</mi><mi>a</mi><mi>d</mi><mi>i</mi><mi>u</mi><mi>s</mi></mrow></msub></mrow><annotation encoding="TeX">f(A,B) = \sqrt{(A_x - B_x)^2 + (A_y - B_y)^2 + (A_z - B_z)^2} &lt;= A_{radius} + B_{radius}</annotation></semantics></math></p>
+
+<p>或者JavaScript:</p>
+
+<pre class="brush: js">function intersect(sphere, other) {
+ // we are using multiplications because it's faster than calling Math.pow
+ var distance = Math.sqrt((sphere.x - other.x) * (sphere.x - other.x) +
+ (sphere.y - other.y) * (sphere.y - other.y) +
+ (sphere.z - other.z) * (sphere.z - other.z));
+ return distance &lt; (sphere.radius + other.radius); }
+}</pre>
+
+<h3 id="球体与AABB">球体与AABB</h3>
+
+<p>测试一个球和一个AABB的碰撞是稍微复杂,但过程仍然简单和快速。一个合乎逻辑的方法是,检查AABB每个顶点,计算每一个点与球的距离。然而这是大材小用了,测试所有的顶点都是不必要的,因为我们可以侥幸计算AABB最近的点(不一定是一个顶点)和球体的中心之间的距离,看看它是小于或等于球体的半径。我们可以通过逼近球体的中心和AABB的距离得到这个值。</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/11837/sphere_vs_aabb.png" style="display: block; height: 282px; margin: 0px auto; width: 377px;"></p>
+
+<p>在 JavaScript, 我们可以像这样子做:</p>
+
+<pre class="brush: js">function intersect(sphere, box) {
+ // get box closest point to sphere center by clamping
+ var x = Math.max(box.minX, Math.min(sphere.x, box.maxX));
+ var y = Math.max(box.minY, Math.min(sphere.y, box.maxY));
+ var z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ));
+
+ // this is the same as isPointInsideSphere
+ var distance = Math.sqrt((x - sphere.x) * (x - sphere.x) +
+ (y - sphere.y) * (y - sphere.y) +
+ (z - sphere.z) * (z - sphere.z));
+
+ return distance &lt; sphere.radius;
+}
+
+</pre>
+
+<h2 id="使用一个物理引擎">使用一个物理引擎</h2>
+
+<p><strong>3D physics engines</strong> provide collision detection algorithms, most of them based on bounding volumes as well. The way a physics engine works is by creating a <strong>physical body</strong>, usually attached to a visual representation of it. This body has properties such as velocity, position, rotation, torque, etc., and also a <strong>physical shape</strong>. This shape is the one that is considered in the collision detection calculations.</p>
+
+<p>We have prepared a <a href="http://mozdevs.github.io/gamedev-js-3d-aabb/physics.html">live collision detection demo</a> (with <a href="https://github.com/mozdevs/gamedev-js-3d-aabb">source code</a>) that you can take a look at to see such techniques in action — this uses the open-source 3D physics engine <a href="https://github.com/schteppe/cannon.js">cannon.js</a>.</p>
+
+<h2 id="See_also">See also</h2>
+
+<p>Related articles on MDN:</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection/Bounding_volume_collision_detection_with_THREE.js">Bounding volumes collision detection with Three.js</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a></li>
+</ul>
+
+<p>External resources:</p>
+
+<ul>
+ <li><a href="http://www.gamasutra.com/view/feature/3383/simple_intersection_tests_for_games.php">Simple intersection tests for games</a> on Gamasutra</li>
+ <li><a href="https://en.wikipedia.org/wiki/Bounding_volume">Bounding volume</a> on Wikipedia</li>
+</ul>
diff --git a/files/zh-cn/games/techniques/3d_on_the_web/basic_theory/index.html b/files/zh-cn/games/techniques/3d_on_the_web/basic_theory/index.html
new file mode 100644
index 0000000000..4e4041a8da
--- /dev/null
+++ b/files/zh-cn/games/techniques/3d_on_the_web/basic_theory/index.html
@@ -0,0 +1,127 @@
+---
+title: 解释基本的3D原理
+slug: Games/Techniques/3D_on_the_web/Basic_theory
+tags:
+ - 3D
+ - 坐标
+ - 片段
+ - 顶点
+translation_of: Games/Techniques/3D_on_the_web/Basic_theory
+---
+<div>{{GamesSidebar}}</div>
+
+<p>这篇文章解释了当你开始使用 3D 工作的时候需要的所有有用的基本理论</p>
+
+<h2 id="坐标系统">坐标系统</h2>
+
+<p>3D 指的是有关在 3D 空间中所有形状的表示,并且可以使用坐标系统来计算其位置。</p>
+
+<p><img alt="Coordinate system" src="https://mdn.mozillademos.org/files/13326/mdn-games-3d-coordinate-system.png" style="height: 338px; width: 600px;"></p>
+
+<p>WebGL使用右手坐标系统 — <code>x</code> 轴向右, <code>y</code> 轴向上 <code>z</code> 轴指向屏幕外, 在上图可以看到.</p>
+
+<h2 id="物体">物体</h2>
+
+<p>使用顶点建立不同类型的物体.  <strong>一个顶点</strong>是在3D坐标系中拥有坐标位置的一个点以及一些额外可以定义它的信息。 每个点都包含这些属性:</p>
+
+<ul>
+ <li><strong>位置</strong>: 在3D空间用来辨认 (<code>x</code>, <code>y</code>, <code>z</code>).</li>
+ <li><strong>颜色</strong>: 包含RGBA (R, G 和 B 分别是红, 绿, 蓝和alpha通道, alpha通道控制透明度 — 所有通道值的范围都是 <code>0.0</code> 到 <code>1.0</code>).</li>
+ <li><strong>法线:</strong> 描述顶点朝向.</li>
+ <li><strong>纹理</strong>: 顶点用来装饰模型表面的一张2D图片, 它是代替简单颜色的选择之一.</li>
+</ul>
+
+<p>你可以使用这些信息建立几何体 — 这是一个立方体的例子:</p>
+
+<p><img alt="Cube" src="https://mdn.mozillademos.org/files/13324/mdn-games-3d-cube.png" style="height: 265px; width: 600px;"></p>
+
+<p>给定形状的一个面是顶点之间的一个平面. 例如, 一个立方体有8个不同的顶点和6个不同的面 每个面由4个顶点构成. 一条法线定义面的朝向. 同时, 连接这些点可以创建立方体的边. 这个几何体通过点和面构成, 材质使用的是一张纹理贴图, 这里使用一个纯蓝色或一张图片. 该物体的几何形状(geometry)由顶点和面构成,而材质(material)则是由纹理构成。如果我们将几何体和材质连接起来会得到一个网格(mesh).</p>
+
+<h2 id="渲染流程">渲染流程</h2>
+
+<p>渲染流程是个将之前准备好的模型输出到屏幕的过程. 3D渲染流程会接受使用顶点描述3D物体的原始数据作为输入用于处理, 并计算其片段(fragment), 然后渲染为像素(pixels)输出到屏幕.</p>
+
+<p><img alt="Rendering pipeline" src="https://mdn.mozillademos.org/files/13334/mdn-games-3d-rendering-pipeline.png" style="height: 225px; width: 600px;"></p>
+
+<p>上图中用到了如下术语:</p>
+
+<ul>
+ <li><strong>原始数据</strong>: 渲染流程中的输入 — 用顶点生成, 它可能是三角形, 点或线.</li>
+ <li><strong>片段</strong>: 一个像素的3D投射, 有着和像素一样的属性.</li>
+ <li><strong>像素</strong>: 屏幕上的2D网格中的点布置的点, 包含RGBA.</li>
+</ul>
+
+<p>顶点和片段处理是可编程的 — 你可以<a href="https://developer.mozilla.org/zh-CN/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders">编写自己的着色器</a> 来控制输出.</p>
+
+<h2 id="顶点处理">顶点处理</h2>
+
+<p>顶点处理是将独立的顶点信息组合成原始数据并设置其在3D空间中的坐标, 方便显示器识别. 就像是对你准备的场景进行拍照 — 你必须先放置物品, 设置相机参数, 然后开拍.</p>
+
+<p><img alt="Vertex processing" src="https://mdn.mozillademos.org/files/13336/mdn-games-3d-vertex-processing.png" style="height: 338px; width: 600px;"></p>
+
+<p>这个过程分为四步: 第一步是筹备世界坐标中的物体, 也被称为<strong>模型转换(model transformation)</strong>. 然后是<strong>视图转换(view transformation)</strong> , 这一步只关心位置和3D空间中摄像机的朝向设置. 摄像机有三个参数(位置, 方向和朝向), 在新创建的场景中必须定义这三个参数.</p>
+
+<p><img alt="Camera" src="https://mdn.mozillademos.org/files/13322/mdn-games-3d-camera.png" style="height: 225px; width: 600px;"></p>
+
+<p><strong>投射转换</strong>(projection transformation), 也被称作透视转换(perspective transformation), 这一步定义摄像机设置, 在此过程会设置哪些在摄像机中可见, 配置包含视野(field of view), 宽高比例(aspect ratio) 和可选的近裁剪和远裁剪参数. 阅读Three.js文章<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js#Camera">摄像机</a>了解更多.</p>
+
+<p><img alt="Camera settings" src="https://mdn.mozillademos.org/files/13320/mdn-games-3d-camera-settings.png" style="height: 338px; width: 600px;"></p>
+
+<p>最后一步是<strong>视图窗口转换</strong>(viewport transformation), 这一步会将一切都输出给渲染流程中的下一步.</p>
+
+<h2 id="栅格化">栅格化</h2>
+
+<p>栅格化将原始数据(从顶点信息转换过来的)转换为一系列的片段.</p>
+
+<p><img alt="Rasterization" src="https://mdn.mozillademos.org/files/13332/mdn-games-3d-rasterization.png" style="height: 338px; width: 600px;"></p>
+
+<p>那些片段(2D像素的3D投射)是对应到像素网格的, 所以在渲染合成阶段最后他们会被2D的屏幕直接打印到像素点上.</p>
+
+<h2 id="片段合成">片段合成</h2>
+
+<p>片段合成关注关注的是纹理和光照 — 它会基于给定参数计算最终的颜色.</p>
+
+<p><img alt="Fragment processing" src="https://mdn.mozillademos.org/files/13328/mdn-games-3d-fragment-processing.png" style="height: 338px; width: 600px;"></p>
+
+<h3 id="纹理">纹理</h3>
+
+<p>纹理是在3D空间中用了是模型看起来更加真实的2D图片. 纹理是由称为纹素的单个纹理元素组合, 和像素组合的原理一样. 如果必要的话, 在渲染流程中的片段处理阶段添加纹理到模型上允许我们使用包装(wrapping)和过滤(filtering)进行适配.</p>
+
+<p>纹理包装允许你在3D模型上重复使用2D图片. 纹理过滤是纹理贴图的原始分辨率和将要呈现的片段的分辨率不同的时候, 会根据情况对纹理进行缩放.</p>
+
+<h3 id="光照">光照</h3>
+
+<p>我们在屏幕上看到的颜色是光照和模型颜色, 材质进行交互之后的最终结果. 灯光会被吸收和反射, 在WebGL中实现的标准<strong>Phong光照模型</strong> 有一下四种光照参数:</p>
+
+<ul>
+ <li><strong>漫反射</strong>: 遥远的直接光照, 就像太阳.</li>
+ <li><strong>高光</strong>: 点光源, 就像房间的白炽灯或闪光灯.</li>
+ <li><strong>环境色</strong>: 常量灯光, 可影响场景中的所有模型.</li>
+ <li><strong>自发光</strong>: 模型自身发出的光.</li>
+</ul>
+
+<h2 id="输出合成">输出合成</h2>
+
+<p>在输出操作阶段所有来自3D空间的原始数据的片段会被转换到2D像素网格中, 然后打印到屏幕像素上.</p>
+
+<p><img alt="Output merging" src="https://mdn.mozillademos.org/files/13330/mdn-games-3d-output-merging.png" style="height: 338px; width: 600px;"></p>
+
+<p>在输出合成阶段同样可以忽略不必要的信息, 例如在屏幕外的模型参数或者被其他模型遮挡的模型, 因为是不可见的所以不会被计算.</p>
+
+<ul>
+</ul>
+
+<h2 id="总结">总结</h2>
+
+<p>现在你知道了3D操作背后的基本原理. 如果你想去练习或者看学习demo, 看看下面的教程:</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">用Three.js创建基本demo</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Babylon.js">用Babylon.js创建基本demo</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_PlayCanvas">用PlayCanvas创建基本demo</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">用A-Frame创建基本demo</a></li>
+</ul>
+
+<p>继续, 去创建一些炫酷3D实验吧!</p>
+
+<div class="grammarly-disable-indicator"> </div>
diff --git a/files/zh-cn/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js/index.html b/files/zh-cn/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js/index.html
new file mode 100644
index 0000000000..5826579352
--- /dev/null
+++ b/files/zh-cn/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js/index.html
@@ -0,0 +1,258 @@
+---
+title: Building up a basic demo with Three.js
+slug: Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js
+translation_of: Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js
+---
+<div>{{GamesSidebar}}</div><p class="summary">游戏中一个典型的3D场景(最简单的那种)  包含标准的物品比如在坐标轴中的形状, 一个实际可看到他们的摄像机, 灯光和材质让其看起来不错, 动画使其生动等等.<strong> Three.js</strong>, 和其他3D库一样, 提供内置的helper 函数来帮助你尽可能快地实现通用的3D功能 . 在这篇文章我们会带你了解使用Three的基本知识, 包含设置开发者环境, 必要的HTML结构, Three.js对象基础, 以及如何创建一个基本的demo.</p>
+
+<div class="note">
+<p><strong>注意</strong>: 我们选择Three.js因为它是最流行的<a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> 库之一, 并且很容易上手. 我们不会介绍任何其他更好的WebGL库, 你可以自由选择其他库做尝试, 比如 <a href="http://www.ambiera.com/copperlicht/index.html">CopperLicht</a>, <a href="http://www.glge.org/">GLGE</a>, <a href="http://osgjs.org/">OSG.js</a>, <a href="https://code.google.com/p/o3d/">O3D</a>, 或者其他你喜欢的库.</p>
+</div>
+
+<h2 id="环境设置">环境设置</h2>
+
+<p>开始用 Three.js, 你不需要准备太多, 只需:</p>
+
+<ul>
+ <li>确保使用的支持 <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> 的现代浏览器, 例如最新版的Firefox 或 Chrome.</li>
+ <li>创建一个目录保存例子.</li>
+ <li>复制最新的压缩版<a href="http://threejs.org/build/three.min.js"> Three.js</a> 到你的目录.</li>
+ <li>用单独的浏览器tab打开 <a href="http://threejs.org/docs/">Three.js </a>文档 — 对应参考很有用.</li>
+</ul>
+
+<h2 id="HTML_结构">HTML 结构</h2>
+
+<p>这是将用到的HTML结构.</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;MDN Games: Three.js demo&lt;/title&gt;
+ &lt;style&gt;
+ body { margin: 0; padding: 0; }
+ canvas { width: 100%; height: 100%; }
+ &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src="three.min.js"&gt;&lt;/script&gt;
+&lt;script&gt;
+ var WIDTH = window.innerWidth;
+ var HEIGHT = window.innerHeight;
+ /* all our JavaScript code goes here */
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>It contains some basic information like the document {{htmlelement("title")}}, and some CSS to set the <code>width</code> and <code>height</code> of the {{htmlelement("canvas")}} element that Three.js will insert on the page to 100% so that it will fill the entire available viewport space. The first {{htmlelement("script")}} element includes the Three.js library in the page, and we will write our example code into the second one. There are two helper variables already included, which store the window's <code>width</code> and <code>height</code>.</p>
+
+<p>Before reading on, copy this code to a new text file, and save it in your working directory as <code>index.html</code>.</p>
+
+<h2 id="渲染器">渲染器</h2>
+
+<p>A renderer is a tool that displays scenes right in your browser. There are a few different renderers: WebGL is the default one, and the others you can use are Canvas, SVG, CSS and DOM. They differ in a way everything is rendered, so the WebGL implementation will work differently than the CSS one, but the idea is to have it look exactly the same for the end user. Thanks to this approach, a fallback can be used if the primary technology is not supported by the browser.</p>
+
+<pre class="brush: js">var renderer = new THREE.WebGLRenderer({antialias:true});
+renderer.setSize(WIDTH, HEIGHT);
+renderer.setClearColor(0xDDDDDD, 1);
+document.body.appendChild(renderer.domElement);
+</pre>
+
+<p>We are creating a new WebGL renderer, setting it's size to fit the whole available space on the screen and appending the DOM structure to the page. You probably noticed the <code>antialias</code> parameter in the first line — this enables the edges of the shapes to be rendered a little more smoothly. The <code>setClearColor()</code> method sets our background to a light gray colour instead of the default black one.</p>
+
+<p>Add this code into the second {{htmlelement("script")}} element, just below the JavaScript comment.</p>
+
+<h2 id="场景">场景</h2>
+
+<p>A scene is the place where everything happens. When creating new objects in the demo, we will be adding them all to the scene to make them visible on the screen. In three.js, the scene is reperesented by a <code>Scene</code> object. Let's create it, by adding the following line below our previous lines:</p>
+
+<pre class="brush: js">var scene = new THREE.Scene();
+</pre>
+
+<p>Later on we will be using the <code>.add()</code> method to add objects to the scene.</p>
+
+<h2 id="摄像机">摄像机</h2>
+
+<p>我们有渲染场景,但是我们仍然需要一个摄像机来观察场景-想象没有摄像机的电影场景。下面的代码将摄像机放在三维坐标系中,并将其指向我们的场景,这样人们就能看到一些东西:</p>
+
+<pre class="brush: js">var camera = new THREE.PerspectiveCamera(70, WIDTH/HEIGHT);
+camera.position.z = 50;
+scene.add(camera);
+</pre>
+
+<p>Add these lines to your code, below the prevous ones.</p>
+
+<p>There are other types of camera available (Cube, Orthographic), but the simplest is the Perspective one. To initialize it we have to set its field of view and aspect ratio — the first one is used to set how much is seen, and a proper aspect ratio is important for the objects on the screen to have the right proportions when rendered and not look stretched. Let's explain the values we are setting in the code above:</p>
+
+<ul>
+ <li>The value we set for the field of view, 70, is something we can experiment with — the higher the value, the greater the amount of scene the camera will show. Imagine a normal camera view, versus a fish eye effect, which allows a lot more to be seen. The default value is 50.</li>
+ <li>The aspect ratio is set to the current width and height of the window so it will be dynamically adjusted. We could set a fixed ratio — for example 16 ⁄ 9, which is the aspect ratio of a widescreen TV. The default value is 1.</li>
+ <li>The <code>z</code> position with the value of 50 units is the distance between the camera and the center of the scene on the <code>z</code> axis — here we're moving the camera back so the objects on the scene can be viewed. 50 feels ok as it's not too near and not too far and the sizes of the objects allow them to stay on the scene within the given field of view. The <code>x</code> and <code>y</code> values, if not specified, will default to 0.</li>
+</ul>
+
+<p>You should experiment with these values and see how they change what you see in the scene.</p>
+
+<div class="note">
+<p><strong>Note</strong>: The distance values (e.g. for the camera z position) are unitless, and can basically be anything you deem suitable for your scene — milimeters, meters, feet, or miles — it's up to you.</p>
+</div>
+
+<h2 id="Rendering_the_scene">Rendering the scene</h2>
+
+<p>Everything is ready, but we still can't see anything. Although we set the renderer up, we still have to actually render everything. Our <code>render()</code> function will do this job, with a little help from <code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code>, which causes the scene to be re-rendered constantly on every frame:</p>
+
+<pre class="brush: js">function render() {
+ requestAnimationFrame(render);
+ renderer.render(scene, camera);
+}
+render();
+</pre>
+
+<p>On every new frame the <code>render</code> function is invoked and the <code>renderer</code> renders the <code>scene</code> and the <code>camera</code>. Right after the function declaration we're invoking it for the first time to start the loop, after which it will be used indefinitely.</p>
+
+<p>Again add the new code below your previous additions, then try saving the file and loading it in your browser. You should now see a gray window. Congratulations!</p>
+
+<h2 id="Geometry">Geometry</h2>
+
+<p>Now the scene is properly rendering we can start adding 3D shapes to it. To speed up development Three.js provides a bunch of predefined primitives that you can to create shapes instantly in a single line of code. There's cubes, spheres, cylinders and more complicated shapes available. Drawing the needed vertices and faces for given shape is taken care of by the framework, so we can focus on the high level coding. Let's start by defining the geometry for a cube shape — add the following just above the <code>render()</code> function:</p>
+
+<pre class="brush: js">var boxGeometry = new THREE.BoxGeometry(10, 10, 10);
+</pre>
+
+<p>In this case we define a simple cube that is 10 x 10 x 10 units. The geometry itself is not enough though — we also need a material that will be used for our shape.</p>
+
+<h2 id="Material">Material</h2>
+
+<p>Material is that thing covering the object — the colors or texture on its surface. In our case we will use a simple blue color to paint our box. There are predefined materials that can be used: Basic, Phong, Lambert. We will play with the last two later on, but for now the Basic one should be enough:</p>
+
+<pre class="brush: js">var basicMaterial = new THREE.MeshBasicMaterial({color: 0x0095DD});
+</pre>
+
+<p>Add this line below the previous one.</p>
+
+<p>Our material is ready, but what to do next?</p>
+
+<h2 id="Mesh">Mesh</h2>
+
+<p>To apply the material to a geometry a mesh is used. It takes a shape and adds the specified material to every face:</p>
+
+<pre class="brush: js">var cube = new THREE.Mesh(boxGeometry, basicMaterial);
+</pre>
+
+<p>Again, add this line below the previous one.</p>
+
+<h2 id="Adding_the_cube_to_the_scene">Adding the cube to the scene</h2>
+
+<p>We've now created the actual cube using the geometry and material defined earlier. The last thing to do is to actually add the cube to our scene — add this line below the previous one:</p>
+
+<pre class="brush: js">scene.add(cube);
+</pre>
+
+<p>If you save and refresh now, your object will look like a square, because it's facing the camera. The good thing about objects is that we can move them on the scene however we want, for example rotating and scaling as we like. Let's apply a little bit of rotation to the cube, so we can see more than one face — again, add below the previous one:</p>
+
+<pre class="brush: js">cube.rotation.set(0.4, 0.2, 0);
+</pre>
+
+<p>Congratulations, you've created your first object in a 3D environment! It was easier than you thought, right? Here's how it should look:</p>
+
+<p><img alt="Blue cube on a gray background rendered with Three.js." src="https://mdn.mozillademos.org/files/11849/cube.png" style="display: block; height: 400px; margin: 0px auto; width: 600px;"></p>
+
+<p>And here's the code we have created so far:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/bwup75fa/","","350")}}</p>
+
+<p>You can also <a href="https://github.com/end3r/MDN-Games-3D/blob/gh-pages/Three.js/cube.html">check it out on GitHub</a>.</p>
+
+<h2 id="More_shapes_and_materials">More shapes and materials</h2>
+
+<p>Now we will add more shapes to the scene and explore other shapes, materials, lighting, and more. Let's move the cube to the left to make space for some friends — add the following line just below the previous one:</p>
+
+<pre class="brush: js">cube.position.x = -25;
+</pre>
+
+<p>Now onto the shapes and materials: what would you say for a torus using the Phong material? Try adding the following lines just below the lines that define the cube.</p>
+
+<pre class="brush: js">var torusGeometry = new THREE.TorusGeometry(7, 1, 6, 12);
+var phongMaterial = new THREE.MeshPhongMaterial({color: 0xFF9500});
+var torus = new THREE.Mesh(torusGeometry, phongMaterial);
+scene.add(torus);
+</pre>
+
+<p>Thee lines will add a torus geometry; the <code>TorusGeometry()</code> method's parameters define and the parameters are <code>radius</code>, <code>tube diameter</code>, <code>radial segment count</code> and <code>tubular segment count</code>. The Phong material should look more glossy than the simple color of the box that was using the Basic material, although at the moment it will just look black.</p>
+
+<p>We can have even crazier predefined shapes; let's play some more — add the following lines below the ones that defined the torus:</p>
+
+<pre class="brush: js">var dodecahedronGeometry = new THREE.DodecahedronGeometry(7);
+var lambertMaterial = new THREE.MeshLambertMaterial({color: 0xEAEFF2});
+var dodecahedron = new THREE.Mesh(dodecahedronGeometry, lambertMaterial);
+dodecahedron.position.x = 25;
+scene.add(dodecahedron);
+</pre>
+
+<p>This time we are creating a dodecahedron, which is a shape containing twelve flat faces. The parameter <code>DodecahedronGeometry()</code> takes is the size of the object. We're using a Lambert material here, which is similar to Phong, but should be less glossy (again, black for now.) We're moving the object to the right, so it's not in the same place as the box or torus.</p>
+
+<p>As mentioned above, the new objects currently just look black. To have both the Phong and Lambert materials properly visible we need a source of light.</p>
+
+<h2 id="Lights">Lights</h2>
+
+<p>There are various types of light sources available in Three.js; the most basic one is the <code>PointLight</code>, which works like a flashlight — shinig a spotlight in a given direction. Add the following below your shapre definitions:</p>
+
+<pre class="brush: js">var light = new THREE.PointLight(0xFFFFFF);
+light.position.set(-10, 15, 50);
+scene.add(light);
+</pre>
+
+<p>We define a white point of light, set it's position a bit away from the center of the scene so it can light up some parts of the shapes, and add it to the scene. Now everything works as it should — all three shapes are visible. You should check the documentation for other types of light like Ambient, Directional, Hemisphere or Spot, and experiment with placing them on the scene to see the effects.</p>
+
+<p><img alt="Shapes: blue cube, dark yellow torus and dark gray dodecahedron on a gray background rendered with Three.js." src="https://mdn.mozillademos.org/files/11851/shapes.png" style="height: 400px; width: 600px;"></p>
+
+<p>This looks a little bit boring though. In a game something is usually happening — we can see animations and such — so let's try to breathe a little life into those shapes by animating them.</p>
+
+<h2 id="Animation">Animation</h2>
+
+<p>We already used rotation to adjust the position of the cube; we could also scale the shapes, or change thier positions. To show actual animation, we need to make changes to these values inside the render loop so, they are updated on every frame.</p>
+
+<h3 id="Rotation">Rotation</h3>
+
+<p>Rotating is quite easy — all you need to do is to add a defined value to the given direction of the rotation on each frame. Add this line of code right after the <code>requestAnimationFrame()</code> invocation in the <code>render</code> function:</p>
+
+<pre class="brush: js">cube.rotation.y += 0.01;
+</pre>
+
+<p>It will rotate the cube on every frame by a tiny bit, so it will look like a smooth animation.</p>
+
+<h3 id="Scaling">Scaling</h3>
+
+<p>We can also scale a given object. By applying a constant value we could make it grow or shrink once, but let's make it more interesting. First, we will need a helper variable called <code>t</code> for counting the elapsed time. Add it right before the <code>render()</code> function:</p>
+
+<pre class="brush: js">var t = 0;
+</pre>
+
+<p>Now let's increase the value by a given constant value on each frame of the animation; add the following lines just below the <code>requestAnimationFrame()</code> invocation:</p>
+
+<pre class="brush: js">t += 0.01;
+torus.scale.y = Math.abs(Math.sin(t));
+</pre>
+
+<p>This way we'll be able to use <code>Math.sin</code> and end up with quite an interesting result: this will scale the torus and repeat the whole process, as <code>sin</code> is a periodic function. We're wrapping the scale value in <code>Math.abs</code> to pass the absolute values (greater or equal to 0), because sin is between -1 and 0, and for negative values the torus might render unexpectedly (in this case it looks black half the time.)</p>
+
+<p>Now onto the movement part.</p>
+
+<h3 id="Moving">Moving</h3>
+
+<p>Beside rotation and scaling we can also move objects around the scene. Add the following, again just below the <code>requestAnimationFrame()</code> invocation:</p>
+
+<pre class="brush: js">dodecahedron.position.y = -7*Math.sin(t*2);
+</pre>
+
+<p>This will move the dodecahedron up and down by applying the <code>sin()</code> value to the y axis on each frame, with a little bit of adjustment to make it look cooler. Try changing the values to see how it affects the animations.</p>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>Here's the final piece of the code:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/rybr720u/","","350")}}</p>
+
+<p>You can also <a href="https://github.com/end3r/MDN-Games-3D/blob/gh-pages/Three.js/shapes.html">see it on GitHub</a> and <a href="https://github.com/end3r/MDN-Games-3D/">fork the repository</a> if you want to play with it yourself locally. Now you know the basics of Three.js, you can get back to the parent page about <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web">3D on the Web</a>.</p>
+
+<p>You should also try learning raw WebGL, so you can get a better understanding of what's going on. See our <a href="/en-US/docs/Web/API/WebGL_API">WebGL documentation</a>.</p>
diff --git a/files/zh-cn/games/techniques/3d_on_the_web/glsl_shaders/index.html b/files/zh-cn/games/techniques/3d_on_the_web/glsl_shaders/index.html
new file mode 100644
index 0000000000..34e20c994d
--- /dev/null
+++ b/files/zh-cn/games/techniques/3d_on_the_web/glsl_shaders/index.html
@@ -0,0 +1,180 @@
+---
+title: GLSL着色器
+slug: Games/Techniques/3D_on_the_web/GLSL_Shaders
+tags:
+ - GLSL
+ - 片段着色器
+ - 着色器
+ - 顶点着色器
+translation_of: Games/Techniques/3D_on_the_web/GLSL_Shaders
+---
+<div>{{GamesSidebar}}</div><p class="summary"><span class="seosummary">使用GLSL的着色器(shader), GLSL是一门特殊的有着类似于C语言的语法, 在图形管道(graphic pipeline)中直接可执行的OpenGL着色语言. 着色器有两种类型 -- 顶点着色器(Vertex Shader)和片段着色器(Fragment Shader). 前者是将形状转换到真实的3D绘制坐标中, 后者是计算最终渲染的颜色和其他属性用的.</span></p>
+
+<p>GLSL不同于JavaScript, 它是强类型语言, 并且内置很多数学公式用于计算向量和矩阵. 快速编写着色器非常复杂, 但创建一个简单的着色器并不难. 在这篇文章我们将介绍使用着色器的基础知识, 并且构建一个使用Three.js的例子来加速代码编写.</p>
+
+<p>你可能记得<a href="/en-US/docs/Games/Techniques/3D_on_the_web/Basic_theory">基本原理</a>那篇文章, 一个顶点(vertex)是在空间中有自己3D坐标的点, 并且通常包含些被定义的其他信息. 空间本身会被坐标系统定义. 在那个3D空间中一切都是关于形状的呈现.</p>
+
+<h2 id="着色器类型">着色器类型</h2>
+
+<p>一个着色器实际上就是一个绘制东西到屏幕上的函数. 着色器运行在GPU中, 它对这些操作进行了很多的优化, 这样你就可以卸载很多不必要的CPU, 然后集中处理能力去执行你自己的代码.</p>
+
+<h3 id="顶点着色器">顶点着色器</h3>
+
+<p>顶点着色器操作3D空间的坐标并且每个顶点都会调用一次这个函数. 其目的是设置 <code>gl_Position</code> 变量 -- 这是一个特殊的全局内置变量, 它是用来存储当前顶点的位置:</p>
+
+<pre class="brush: glsl">void main() {
+ gl_Position = makeCalculationsToHaveCoordinates;
+}
+</pre>
+
+<p>这个 <code>void main()</code> 函数是定义全局<code>gl_Position</code> 变量的标准方式. 所有在这个函数里面的代码都会被着色器执行.  如果将3D空间中的位置投射到2D屏幕上这些信息都会保存在计算结果的变量中.</p>
+
+<h3 id="片段着色器">片段着色器</h3>
+
+<p>片段 (或者纹理) 着色器 在计算时定义了每像素的 RGBA 颜色 — 每个像素只调用一次片段着色器. 这个着色器的作用是设置 <code>gl_FragColor</code> 变量, 也是一个GLSL内置变量:</p>
+
+<pre class="brush: glsl">void main() {
+ gl_FragColor = makeCalculationsToHaveColor;
+}
+</pre>
+
+<p>计算结果包含RGBA颜色信息.</p>
+
+<h2 id="例子">例子</h2>
+
+<p>让我们构建一个简单的例子来解释这些着色器的动作. 假设你已经看过<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Three.js 教程</a>并掌握了场景, 物体和材质的基本概念.</p>
+
+<div class="note">
+<p><strong>注意</strong>: 记住你没必要使用Three.js或者其他库来编写着色器 -- 纯<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API">WebGL</a> 完全够了. 我们这里使用Three.js来制作背景代码更简单和易理解. 所以你只需关注着色器代码. Three.js和其他3D库给你抽象了很多东西出来 -- 如果你想要用纯WebGL创建这个例子, 你得写很多其他的代码才能运行.</p>
+</div>
+
+<h3 id="环境设置">环境设置</h3>
+
+<p>要开始编写WebGL着色器你不需要做太多, 只需:</p>
+
+<ul>
+ <li>确保你在使用对 <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API">WebGL</a> 有良好支持的现代浏览器, 比如最新版的Firefox或Chrome.</li>
+ <li>创建一个目录保存你的实验.</li>
+ <li>拷贝一份的 <a href="http://threejs.org/build/three.min.js">压缩版的Three.js 库</a> 到你的目录.</li>
+</ul>
+
+<h3 id="HTML_结构">HTML 结构</h3>
+
+<p>这是将用到的HTML结构.</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;MDN Games: Shaders demo&lt;/title&gt;
+ &lt;style&gt;
+ body { margin: 0; padding: 0; font-size: 0; }
+ canvas { width: 100%; height: 100%; }
+ &lt;/style&gt;
+ &lt;script src="three.min.js"&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+ &lt;script id="vertexShader" type="x-shader/x-vertex"&gt;
+ // 顶点着色器代码在这里
+ &lt;/script&gt;
+ &lt;script id="fragmentShader" type="x-shader/x-fragment"&gt;
+ // 片段着色器代码在这里
+ &lt;/script&gt;
+ &lt;script&gt;
+ // 场景设置在这里
+ &lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>他包含了一些基本信息比如 文档的 {{htmlelement("title")}}, 并且设置了{{htmlelement("canvas")}}元素css样式的宽高, Three.js会插入到页面中占满整个可视区域.  {{htmlelement("script")}}元素在包含Three.js库的{{htmlelement("head")}}中. 我们的代码将卸载{{htmlelement("body")}}标签中的script标签中:</p>
+
+<ol>
+ <li>首先将包含顶点着色器.</li>
+ <li>然后包含片段着色器.</li>
+ <li>最后会包含一些生成实际场景的JavaScript代码.</li>
+</ol>
+
+<p>阅读之前, 复制这些代码到一个新的文本文件中, 保存到你的工作目录作为 <code>index.html</code>. 我们将在这个文件中创建一个简单的立方体来解释着色器是如何工作的.</p>
+
+<h3 id="立方体源代码">立方体源代码</h3>
+
+<p>我们可以复用<a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a> 中立方体的源代码, 大多数元素例如渲染器, 摄像机和灯光都没有发生改变, 但是基本的材质会用到自己写的着色器.</p>
+
+<p>去<a href="https://github.com/end3r/MDN-Games-3D/blob/gh-pages/Three.js/cube.html">cube.html file on GitHub</a>中, 复制第二个{{htmlelement("script")}}元素中所有的JavaScript代码, 粘贴到当前例子中的第三个<code>&lt;script&gt;</code>  标签中. 保存并运行 <code>index.html</code> — 然后你会看到一个蓝色立方体</p>
+
+<h3 id="顶点着色器代码">顶点着色器代码</h3>
+
+<p>让我们继续编写顶点着色器 — 添加下面这段代码到你body的第一个 <code>&lt;script&gt;</code> 标签:</p>
+
+<pre class="brush: glsl">void main() {
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position.x+10.0, position.y, position.z+5.0, 1.0);
+}
+</pre>
+
+<p>每次的<code>gl_Position</code> 的结果是计算model-view矩阵和投射矩阵和投射矩阵相乘并得到最后的顶点位置.</p>
+
+<div class="note">
+<p><strong>注意</strong>: 你可以在 <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Basic_theory#Vertex_processing">顶点处理</a>中学到更多关于模型, 视图和投射变换, 并且你可以在文末看到更多学习链接.</p>
+</div>
+
+<p><code>projectionMatrix</code> 和 <code>modelViewMatrix</code> 两个函数都是Three.js提供的, 并且传入了一个新的3D位置向量, 转成着色器之后直接导致立方体向 <code>x</code> 轴移动10个单位, 向<code>z</code> 轴移动了5个单位. 我们可以忽略第四个参数并且保持为默认的<code>1.0</code> ; 这是用来控制3D空间中订单位置裁剪的, 这个例子中不需要.</p>
+
+<h3 id="纹理着色器代码">纹理着色器代码</h3>
+
+<p>现在我们将添加纹理着色器代码 — 将以下代码复制到第二个 <code>&lt;script&gt;</code> 标签中:</p>
+
+<pre class="brush: glsl">void main() {
+ gl_FragColor = vec4(0.0, 0.58, 0.86, 1.0);
+}
+</pre>
+
+<p>这将设置一个RGBA颜色来重建当前的蓝色灯光 — 前三个浮点数(范围是0.0到1.0) 代表红, 绿, 蓝, 第四个值代表alpha通道, 控制透明度(0.0完全透明, 1.0是完全不透明).</p>
+
+<h3 id="设置着色器">设置着色器</h3>
+
+<p>实际上是创建了一个新的着色器给立方体, 先用 <code>basicMaterial</code> 来定义:</p>
+
+<pre class="brush: js">// var basicMaterial = new THREE.MeshBasicMaterial({color: 0x0095DD});
+</pre>
+
+<p>然后创建 <a href="http://threejs.org/docs/#Reference/Materials/ShaderMaterial"><code>shaderMaterial</code></a>:</p>
+
+<pre class="brush: js">var shaderMaterial = new THREE.ShaderMaterial( {
+ vertexShader: document.getElementById( 'vertexShader' ).textContent,
+ fragmentShader: document.getElementById( 'fragmentShader' ).textContent
+});
+</pre>
+
+<p>这个着色器材质使用脚本中的代码并将它们赋予给材质所赋予的物体</p>
+
+<p>然后, 在定义立方体材质那一行我们需要替换<code>basicMaterial</code> :</p>
+
+<pre class="brush: js">var cube = new THREE.Mesh(boxGeometry, basicMaterial);
+</pre>
+
+<p>使用新创建的 <code>shaderMaterial</code>:</p>
+
+<pre class="brush: js">var cube = new THREE.Mesh(boxGeometry, shaderMaterial);
+</pre>
+
+<p>Three.js编译和运行这两个这两个着色器到材质所在的网格(mesh)上. 在这个例子中, 为立方体添加了有顶点和纹理着色器. 好了, 你已经创建了最简单的着色器, 祝贺!</p>
+
+<p>下图是立方体最终效果:</p>
+
+<p><img alt="Three.js blue cube demo" src="http://end3r.github.io/MDN-Games-3D/Shaders/img/cube.png" style="display: block; margin: 0px auto;"></p>
+
+<p>它看起来好像和Three.js的立方体demo一样, 但不同的是, 位置有点轻微变化, 而且同样的蓝色使用的是着色器实现. 你可以看看实际操作, 这里有最终代码:{{JSFiddleEmbed("https://jsfiddle.net/end3r/LL55bhrz/","","350")}}</p>
+
+<p>你也可以在 <a href="https://github.com/end3r/MDN-Games-3D/blob/gh-pages/Shaders/shaders.html">GitHub</a> 看这个例子.</p>
+
+<h2 id="总结">总结</h2>
+
+<p>本文教了你最基本的着色器实现. 我们虽然只能做这么多, 但你可以用着色器做很更多炫酷的事情 — 在 <a href="http://shadertoy.com/">ShaderToy</a> 上去看真正炫酷的例子找找灵感吧</p>
+
+<h2 id="其他链接">其他链接</h2>
+
+<ul>
+ <li><a href="http://learningwebgl.com/blog/?page_id=1217">学习WebGL</a> — 基本WebGL知识</li>
+ <li><a href="http://webglfundamentals.org/webgl/lessons/webgl-shaders-and-glsl.html">WebGL着色器和WebGL中的GLSL基础</a> — GLSL特定信息</li>
+</ul>
diff --git a/files/zh-cn/games/techniques/3d_on_the_web/index.html b/files/zh-cn/games/techniques/3d_on_the_web/index.html
new file mode 100644
index 0000000000..08e1fe27a7
--- /dev/null
+++ b/files/zh-cn/games/techniques/3d_on_the_web/index.html
@@ -0,0 +1,118 @@
+---
+title: 3D games on the Web
+slug: Games/Techniques/3D_on_the_web
+tags:
+ - Games
+ - Graphics
+ - NeedsContent
+ - NeedsExample
+ - NeedsTranslation
+ - TopicStub
+ - WebGL
+ - three.js
+translation_of: Games/Techniques/3D_on_the_web
+---
+<div>{{GamesSidebar}}</div>
+
+<p class="summary">为了web上丰富的游戏体验,一个好武器是webGL, 并呈现在HTML的 {{htmlelement("canvas")}}元素上。WebGL基本上是Web的OpenGL ES 2.0版本 — 作为一个JavaScript API,它提供了能构建丰富的交互式动画和游戏的工具。你可以使用硬件加速的JavaScript 生成和呈现动态3D图像。</p>
+
+<h2 id="文档和浏览器支持">文档和浏览器支持</h2>
+
+<p> <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a>项目的文档和规范由<a href="https://www.khronos.org/">Khronos Group维护</a>,而非大部分Web APIs采用的W3C。它很好地支持了现代浏览器甚至是移动手机,由此你无需担心太多。主流浏览器均支持WebGL,你需要关注的仅仅是在你使用的设备上进行优化。</p>
+
+<p>目前进行的尝试是在不久的将来促成WebGL 2.0版本(基于OpenGL ES 3.0版本)的发布,WebGL 2.0版本将会带来许多改进,并且将会帮助开发者使用现在强大的硬件,为现代Web开发游戏。</p>
+
+<h2 id="对基本3D理论的解释">对基本3D理论的解释</h2>
+
+<p>基本3D理论的核心围绕在3D空间的形状呈现上,通过使用坐标系计算出它们的位置。寻找你所要的信息,请参考我们的文章 <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Basic_theory">Explaining basic 3D theory</a> 。</p>
+
+<h2 id="预先概念">预先概念</h2>
+
+<p>你可以使用 WebGL 做很多事情。你需要深入了解和学习一些预先的理念——像着色器、碰撞检测或最新的热门话题——Web上的虚拟现实。</p>
+
+<h3 id="着色器">着色器</h3>
+
+<p>值得提及的是着色器,着色器本身就是一个独立的故事。着色器使用GLSL,一个特殊的和C语言相似的 OpenGL 着色语言,但C语言直接通过图像管道执行。</p>
+
+<h3 id="碰撞检测">碰撞检测</h3>
+
+<p>很难想象没有碰撞检测的游戏——我们总是需要计算出一个物体什么时候会撞击到另一个物体。我们有一些可利用的信息供你学习:</p>
+
+<ul>
+ <li><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D 碰撞检测</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/3D_collision_detection">3D 碰撞检测</a></li>
+</ul>
+
+<h3 id="Web虚拟现实">Web虚拟现实</h3>
+
+<p>虚拟现实这一概念并不新鲜,但由于硬件的进步,它大有席卷网络之势,如<a href="https://www.oculus.com/en-us/rift/">Oculus Rift</a>和(目前实验性的) <a href="/en-US/docs/Web/API/WebVR_API">WebVR API</a>,它们从VR硬件中捕获信息并使其可在JavaScript中应用。有关的详细信息请阅读 <a href="/en-US/docs/Games/Techniques/3D_on_the_web/WebVR">WebVR-Web 虚拟现实</a>。</p>
+
+<p>还有一篇<a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">用A-Frame构建基本demo</a>的文章,向您展示了使用<a href="http://aframe.io/">A-Frame</a>框架构建3D环境的虚拟现实是多么的简单。</p>
+
+<h2 id="库和框架的兴起">库和框架的兴起</h2>
+
+<p>编码原生WebGL是相当复杂的,但从长远来看,您需要了解它,如果您的项目变得更加先进(请从参阅我们的<a href="/en-US/docs/Web/API/WebGL_API">WebGL文档</a>开始)。对于现实世界中的项目,您可能还会使用框架来加快开发,并帮助您管理正在处理的项目。使用3D游戏框架还有助于优化性能,因为您使用的工具会处理很多问题,因此您可以专注于构建游戏本身。</p>
+
+<p>最流行的JavaScript 3D库是<a href="http://threejs.org/">Three.js</a>,这是一个多用途工具,它使常见的3D技术更易于实现。还有其他流行的游戏开发库和框架值得检查。<a href="https://aframe.io">A-Frame</a>、<a href="https://playcanvas.com/">PlayCanvas</a>和<a href="http://www.babylonjs.com/">Babylon.js</a>是最容易辨认的,拥有丰富的文档、在线编辑器和活跃的社区。</p>
+
+<h3 id="使用_A-Frame_搭建一个基础Demo">使用 A-Frame 搭建一个基础Demo</h3>
+
+<p>A-Frame是一个用于搭建3D和VR体验的Web框架。在内部,它是一个具有已声明的实体组件模式的three.js框架,也就是说我们只需借助HTML即可搭建场景。请参阅<a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a>子页面来了解创建Demo的步骤。</p>
+
+<h3 id="使用_Babylon.js_搭建一个基础Demo">使用 Babylon.js 搭建一个基础Demo</h3>
+
+<p><span class="seosummary">Babylon.js 是最受开发者欢迎的3D游戏引擎之一。与其他任何3D库一样,它提供了内置函数,帮助您更快地实现常见的3D功能。请参阅 <a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</a>   子页,其中包括建立一个开发环境,构建必要的HTML,以及编写JavaScript代码。</span></p>
+
+<h3 id="使用_PlayCanvas_搭建一个基础Demo">使用 PlayCanvas  搭建一个基础Demo</h3>
+
+<p>PlayCanvas是一个流行的GitHub开源3D WebGL游戏引擎,有在线编辑器和良好的文档。更多详细信息 请参阅<a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</a>  ,文章将进一步介绍如何使用PlayCanvas库和联机编辑器搭建例子。</p>
+
+<h3 id="使用_Three.js_搭建一个基础Demo">使用 Three.js  搭建一个基础Demo</h3>
+
+<p>Three.js,与任何其他库一样,它给了您一个巨大的便利:不必编写数百行WebGL代码来构建任何有趣的东西,您可以使用内置的helper函数来轻松、快速地完成任务。请参阅 <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a> 子页 逐步创建Demo。</p>
+
+<h3 id="使用_Whitestorm.js_搭建一个基础Demo">使用  Whitestorm.js  搭建一个基础Demo</h3>
+
+<p>Whitestorm.js 是一个基于 <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Three.js</a> 技术上的框架。它的主要区别是内置的物理引擎和插件系统 基于NPM。请参阅  <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Whitestorm.js">Building up a basic demo with Whitestorm.js</a>   了解更多信息、教程和例子制作基本的,甚至配合Three.js 制作更复杂的应用程序或游戏.</p>
+
+<h3 id="其它工具">其它工具</h3>
+
+<p><a href="http://unity3d.com/">Unity</a> 和 <a href="https://www.unrealengine.com/">Unreal</a> 可以将你的游戏通过 <a href="/en-US/docs/Games/Tools/asm.js">asm.js</a> 输出到WebGL,因此你可以自由地使用这些工具与技术来构建可被输出到Web上的游戏。</p>
+
+<p><img alt="" src="http://end3r.github.io/MDN-Games-3D/A-Frame/img/shapes.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<h2 id="Where_to_go_next">Where to go next</h2>
+
+<p>With this article we just scratched the surface of what's possible with currently available technologies. You can build immersive, beautiful and fast 3D games on the Web using WebGL, and the libraries and frameworks build on top of it.</p>
+
+<h3 id="Source_code">Source code</h3>
+
+<p>You can find all the source code for this series <a href="http://end3r.github.io/MDN-Games-3D/">demos on GitHub</a>.</p>
+
+<h3 id="APIs">APIs</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Web/API/Canvas_API">Canvas API</a></li>
+ <li><a href="/en-US/docs/Web/API/WebGL_API">WebGL API</a></li>
+ <li><a href="/en-US/docs/Web/API/WebVR_API">WebVR API</a></li>
+</ul>
+
+<h3 id="Frameworks">Frameworks</h3>
+
+<ul>
+ <li><a href="http://threejs.org/">Three.js</a></li>
+ <li><a href="http://whitestormjs.xyz/">Whitestorm.js</a> (based on Three.js)</li>
+ <li><a href="https://playcanvas.com/">PlayCanvas</a></li>
+ <li><a href="http://www.babylonjs.com/">Babylon.js</a></li>
+ <li><a href="http://aframe.io/">A-Frame</a></li>
+</ul>
+
+<h3 id="Tutorials">Tutorials</h3>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js">Building up a basic demo with Three.js</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Whitestorm.js">Building up a basic demo with Whitestorm.js</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_PlayCanvas">Building up a basic demo with PlayCanvas</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Babylon.js">Building up a basic demo with Babylon.js</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame">Building up a basic demo with A-Frame</a></li>
+</ul>
diff --git a/files/zh-cn/games/techniques/async_scripts/index.html b/files/zh-cn/games/techniques/async_scripts/index.html
new file mode 100644
index 0000000000..2f34e0d144
--- /dev/null
+++ b/files/zh-cn/games/techniques/async_scripts/index.html
@@ -0,0 +1,49 @@
+---
+title: asm.js的异步脚本
+slug: Games/Techniques/Async_scripts
+translation_of: Games/Techniques/Async_scripts
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/zh-CN/docs/Games")}}</div>
+
+<div class="summary">
+<p><span class="seoSummary">每个中型或大型游戏都应编译<a href="https://developer.mozilla.org/en-US/docs/Games/Tools/asm.js">asm.js</a>代码作为异步脚本的一部分,以便浏览器能够最大限度地灵活地优化编译过程。 在Gecko中,异步编译允许JavaScript引擎在游戏加载时缓存主线程的asm.js,并缓存生成的机器代码,这样游戏就不需要在随后的加载中编译(从Firefox 28开始)。 要查看差异,请切换<code>javascript.options.parallel_parsing</code> in <code>about:config</code>.</span></p>
+</div>
+
+<h2 id="异步执行">异步执行</h2>
+
+<p>获取异步编译非常简单:编写JavaScript时,只需使用<code>async</code>属性即可:</p>
+
+<pre class="brush: js">&lt;script async src="file.js"&gt;&lt;/script&gt;</pre>
+
+<p>或者,通过脚本来做同样的事情:</p>
+
+<pre class="brush: js">var script = document.createElement('script');
+script.src = "file.js";
+document.body.appendChild(script);</pre>
+
+<p>(从脚本中创建的脚本默认为异步。) 默认的HTML shell Emscripten生成后者。</p>
+
+<h2 id="什么时候用async或者不用">什么时候用async或者不用?</h2>
+
+<p>两种常见的情况下是脚本是<strong>非</strong>异步的(由<a href="https://www.w3.org/TR/html5/scripting-1.html">HTML规范</a>定义)</p>
+
+<pre class="brush: js">&lt;script async&gt;code&lt;/script&gt;</pre>
+
+<p>以及</p>
+
+<pre class="brush: js">var script = document.createElement('script');
+script.innerHTML = "code";
+document.body.appendChild(script);</pre>
+
+<p>两者都被视为“内联”脚本,阻塞其余所有任务,进行编译,编译完成后立即执行。</p>
+
+<p>如果你的代码是一个JS字符串呢? 而不是使用eval或innerHTML,这两者都会触发同步编译,您应该使用Blob和URL对象:</p>
+
+<pre class="brush: js">var blob = new Blob([codeString]);
+var script = document.createElement('script');
+var url = URL.createObjectURL(blob);
+script.onload = script.onerror = function() { URL.revokeObjectURL(url); };
+script.src = url;
+document.body.appendChild(script);</pre>
+
+<p>使用<code>src</code>而不是<code>innerHTML,则该</code>脚本是异步的。</p>
diff --git a/files/zh-cn/games/techniques/control_mechanisms/index.html b/files/zh-cn/games/techniques/control_mechanisms/index.html
new file mode 100644
index 0000000000..07b6e0b6e1
--- /dev/null
+++ b/files/zh-cn/games/techniques/control_mechanisms/index.html
@@ -0,0 +1,78 @@
+---
+title: Implementing game control mechanisms
+slug: Games/Techniques/Control_mechanisms
+tags:
+ - Controls
+ - Desktop
+ - Gamepad
+ - Games
+ - JavaScript
+ - Laptop
+ - Mobile
+ - NeedsTranslation
+ - TopicStub
+ - keyboard
+ - mouse
+ - touch
+translation_of: Games/Techniques/Control_mechanisms
+---
+<div>{{GamesSidebar}}</div><p class="summary">One of HTML5's main advantages as a game development platform is the ability to run on various platforms and devices. Streamlining cross device differences creates multiple challenges, not least when providing appropriate controls for different contexts. In this series of articles we will show you how you can approach building a game that can be played using touchscreen smartphones, mouse and keyboard, and also less common mechanisms such as gamepads.</p>
+
+<h2 id="Case_study">Case study</h2>
+
+<p>We'll be using the <a href="http://rogers2.enclavegames.com/demo/">Captain Rogers: Battle at Andromeda demo</a> as an example.</p>
+
+<p><img alt="Captain Rogers: Battle at Andromeda - cover of the game containing Enclave Games and Blackmoon Design logos, Roger's space ship and title of the game." src="https://mdn.mozillademos.org/files/13849/captainrogers2-cover.png" style="display: block; height: 325px; margin: 0px auto; width: 575px;"></p>
+
+<p>Captain Rogers was created using the <a href="http://phaser.io/">Phaser</a> framework, the most popular tool for simple 2D game development in JavaScript right now, but it should be fairly easy to reuse the knowledge contained within these articles when building games in pure JavaScript or any other framework. If you're looking for a good introduction to Phaser, then check the <a href="/en-US/docs/Games/Tutorials/2D_breakout_game_Phaser">2D breakout game using Phaser</a> tutorial.</p>
+
+<p>In the following articles we will show how to implement various different control mechanisms for Captain Rogers to support different platforms — from touch on mobile, through keyboard/mouse/gamepad on desktop, to more unconventional ones like TV remote, shouting to or waving your hand in front of the laptop, or squeezing bananas.</p>
+
+<h2 id="Setting_up_the_environment">Setting up the environment</h2>
+
+<p>Let's start with a quick overview of the game's folder structure, JavaScript files and in-game states, so we know what's happening where. The game's folders look like this:</p>
+
+<p><img alt="Captain Rogers: Battle at Andromeda - folder structure of the games' project containing JavaScript sources, images and fonts." src="https://mdn.mozillademos.org/files/13851/captainrogers2-folderstructure.png" style="border-style: solid; border-width: 1px; display: block; height: 479px; margin: 0px auto; width: 575px;"></p>
+
+<p>As you can see there are folders for images, JavaScript files, fonts and sound effects. The <code>src</code> folder contains the JavaScript files split as a separate states — <code>Boot.js</code>, <code>Preloader.js</code>, <code>MainMenu.js</code> and <code>Game.js</code> — these are loaded into the index file in this exact order. The first one initializes Phaser, the second preloads all the assets, the third one controls the main menu welcoming the player, and the fourth controls the actual gameplay.</p>
+
+<p>Every state has its own default methods: <code>preload()</code>, <code>create()</code>, and <code>update()</code>. The first one is needed for preloading required assets, <code>create()</code> is executed once the state had started, and <code>update()</code> is executed on every frame.</p>
+
+<p>For example, you can define a button in the <code>create()</code> function:</p>
+
+<pre class="brush: js">create: function() {
+ // ...
+ var buttonEnclave = this.add.button(10, 10, 'logo-enclave', this.clickEnclave, this);
+ // ...
+}
+</pre>
+
+<p>It will be created once at the start of the game, and will execute <code>this.clickEnclave()</code> action assigned to it when clicked, but you can also use the mouse's pointer value in the <code>update()</code> function to make an action:</p>
+
+<pre class="brush: js">update: function() {
+ // ...
+ if(this.game.input.mousePointer.isDown) {
+ // do something
+ }
+ // ...
+}
+</pre>
+
+<p>This will be executed whenever the mouse button is pressed, and it will be checked against the input's <code>isDown</code> boolean variable on every frame of the game.</p>
+
+<p>That should give you some understanding of the project structure. We'll be playing mostly with the <code>MainMenu.js</code> and <code>Game.js</code> files, and we'll explain the code inside the <code>create()</code> and <code>update()</code> methods in much more detail in later articles.</p>
+
+<h2 id="Pure_JavaScript_demo">Pure JavaScript demo</h2>
+
+<p>There's also a <a href="https://end3r.github.io/JavaScript-Game-Controls/">small online demo</a> with full source code <a href="https://github.com/end3r/JavaScript-Game-Controls/">available on GitHub</a> where the basic support for the control mechanisms described in the articles is implemented in pure JavaScript. It will be explained in the given articles themselves below, but you can play with it already, and use the code however you want for learning purposes.</p>
+
+<h2 id="The_articles">The articles</h2>
+
+<p>JavaScript is the perfect choice for mobile gaming because of HTML5 being truly multiplatform; all of the following articles focus on the APIs provided for interfacing with different control mechanisms:</p>
+
+<ol>
+ <li><a href="/en-US/docs/Games/Techniques/Control_mechanisms/Mobile_touch">Mobile touch controls</a> — The first article will kick off with touch, as the mobile first approach is very popular.</li>
+ <li><a href="/en-US/docs/Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard">Desktop mouse and keyboard controls</a> — When playing on a desktop/laptop computer, providing keyboard and mouse controls is essential to provide an acceptable level of accessibility for the game.</li>
+ <li><a href="/en-US/docs/Games/Techniques/Control_mechanisms/Desktop_with_gamepad">Desktop gamepad controls</a> — The Gamepad API rather usefully allows gamepads to be used for controlling web apps on desktop/laptop, for that console feel.</li>
+ <li><a href="/en-US/docs/Games/Techniques/Control_mechanisms/Other">Unconventional controls</a> — The final article showcases some unconventional control mechanisms, from the experimental to the slightly crazy, which you might not believe could be used to play the game.</li>
+</ol>
diff --git a/files/zh-cn/games/techniques/control_mechanisms/移动端触摸控制/index.html b/files/zh-cn/games/techniques/control_mechanisms/移动端触摸控制/index.html
new file mode 100644
index 0000000000..e9a9abaf15
--- /dev/null
+++ b/files/zh-cn/games/techniques/control_mechanisms/移动端触摸控制/index.html
@@ -0,0 +1,152 @@
+---
+title: 移动端触摸控制
+slug: Games/Techniques/Control_mechanisms/移动端触摸控制
+translation_of: Games/Techniques/Control_mechanisms/Mobile_touch
+---
+<div>{{GamesSidebar}}</div>
+
+<p>{{NextMenu("Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard", "Games/Techniques/Control_mechanisms")}}</p>
+
+<p class="summary">未来手游一定是Web的天下,许多开发在游戏开发过程中首先选择手游 — 既然如此,触摸控制是不可少的。我们将在本教程中了解怎样简单地在移动端H5游戏中实现触摸控制 ,只要移动端支持触摸,你就可以尽情的玩。</p>
+
+<p class="note"><strong>说明</strong>:游戏 <a class="external external-icon" href="http://rogers2.enclavegames.com/demo/">Captain Rogers: Battle at Andromeda</a> 是基于<a href="http://phaser.io/">Phaser</a> 和Phaser-based管理控制,但它也可以用纯JavaScript实现。使用Phaser的好处它提供了辅助变量和方法可以直接调用,有助于快速的开发游戏,这需要根据项目实际情况选择。</p>
+
+<h2 id="纯_JavaScript_方式实现">纯 JavaScript 方式实现</h2>
+
+<p>我们可以实现自己的触摸事件 — 给document添加事件监听,并传入自定义功能的方法,非常简单:</p>
+
+<pre class="brush: js">var el = document.getElementsByTagName("canvas")[0];
+el.addEventListener("touchstart", handleStart);
+el.addEventListener("touchmove", handleMove);
+el.addEventListener("touchend", handleEnd);
+el.addEventListener("touchcancel", handleCancel);</pre>
+
+<p>这样, 在移动设备上屏幕上触摸游戏的 {{htmlelement("canvas")}} 将触发这些事件,因为我们就可以随意操控游戏(如:移动太空船)。 事件如下所示:</p>
+
+<ul>
+ <li><a href="/en-US/docs/Web/API/GlobalEventHandlers/ontouchstart">touchstart</a> 当用户手指放在屏幕上触发。</li>
+ <li><a href="/en-US/docs/Web/API/GlobalEventHandlers/ontouchmove">touchmove</a> 当他们在屏幕上移动手指时触发。</li>
+ <li><a href="/en-US/docs/Web/API/GlobalEventHandlers/ontouchend">touchend</a> 当用户在屏幕上停止移动时触发。</li>
+ <li><a href="/en-US/docs/Web/API/GlobalEventHandlers/ontouchcancel">touchcancel</a> 触摸被取消是触发,例如当用户将他们的手指移动到屏幕之外时。</li>
+</ul>
+
+<div class="note">
+<p><strong>说明</strong>: 这篇 <a href="/en-US/docs/Web/API/Touch_events">touch events</a> 参考文章提供了更多的实例和介绍。</p>
+</div>
+
+<h3 id="纯JavaScript示例">纯JavaScript示例</h3>
+
+<p>这个实现了移动端触摸的<a href="https://github.com/end3r/JavaScript-Game-Controls/">little demo</a>代码已经放到了GibHub上,我们下载这个示例就可以实现在移动端屏幕上移动飞船。</p>
+
+<p>我们将两种事件:<code>touchstart </code>和<code>touchmove</code> 放到一个方法里处理. 为什么呢? <code>touchHandler</code> 方法定义的飞船位置变量适合下面两种情况下: 当玩家触摸时,但不移动它(<code>touchstart</code>)和当手指在屏幕上开始移动 (<code>touchmove</code>):</p>
+
+<pre class="brush: js">document.addEventListener("touchstart", touchHandler);
+document.addEventListener("touchmove", touchHandler);</pre>
+
+<p><code>touchHandler</code> 方法的代码如下:</p>
+
+<pre class="brush: js">function touchHandler(e) {
+ if(e.touches) {
+ playerX = e.touches[0].pageX - canvas.offsetLeft - playerWidth / 2;
+ playerY = e.touches[0].pageY - canvas.offsetTop - playerHeight / 2;
+ output.innerHTML = "Touch: "+ " x: " + playerX + ", y: " + playerY;
+ e.preventDefault();
+ }
+}</pre>
+
+<p>If the touch occurs (<code>touches</code> object is not empty), then we will have all the info we need in that object. We can get the first touch (<code>e.touches[0]</code>, our example is not multitouch-enabled), extract the <code>pageX</code> and <code>pageY</code> variables and set the player's ship position on the screen by subtracting the Canvas offset (distance from the Canvas and the edge of the screen) and half the player's width and height.</p>
+
+<p><img alt="Touch controls for the player's ship, with visible output of the x and y position." src="https://mdn.mozillademos.org/files/14201/controls-touch.png" style="border-style: solid; border-width: 1px; display: block; height: 436px; margin: 0px auto; width: 575px;"></p>
+
+<p>To see if it's working correctly we can output the <code>x</code> and <code>y</code> positions using the <code>output</code> element. The <code>preventDefault()</code> function is needed to prevent the browser from moving — without it you'd have the default behaviour, and the Canvas would be dragged around the page, which would show the browser scroll bars and look messy.</p>
+
+<h2 id="Touch_events_in_Phaser">Touch events in Phaser</h2>
+
+<p>We don't have to do this on our own; frameworks like Phaser offer systems for managing touch events for us — see <a href="http://phaser.io/docs/2.6.1/Phaser.Touch.html">managing the touch events</a>.</p>
+
+<h3 id="Pointer_theory">Pointer theory</h3>
+
+<p>A <a href="http://phaser.io/docs/2.6.1/Phaser.Pointer.html">pointer</a> represents a single finger on the touch screen. Phaser starts two pointers by default, so two fingers can perform an action at once. Captain Rogers is a simple game — it can be controlled by two fingers, the left one moving the ship and the right one controlling the ship's gun. There's no multitouch or gestures — everything is handled by single pointer inputs.</p>
+
+<p>You can add more pointers to the game by using; <code>this.game.input.addPointer</code> up to ten pointers can be managed simultaneously. The most recently used pointer is available in the <code>this.game.input.activePointer</code> object — the most recent finger active on the screen.</p>
+
+<p>If you need to access a specific pointer, they are all available at, <code>this.game.input.pointer1</code><code>this.game.input.pointer2</code>, etc. They are assigned dynamically, so if you put three fingers on the screen, then, <code>pointer1</code><code>pointer2</code>, and <code>pointer3</code> will be active. Removing the second finger, for example, won't affect the other two, and setting it back again will use the first available property, so <code>pointer2</code> will be used again.</p>
+
+<p>You can quickly get the coordinates of the most recently active pointer via the <code>this.game.input.x</code> and <code>this.game.input.y</code> variables.</p>
+
+<h3 id="Input_events">Input events</h3>
+
+<p>Instead of using the pointers directly it is also possible to listen for <code>this.game.input</code> events, like <code>onDown</code>, <code>onUp</code>, <code>onTap</code> and <code>onHold</code>:</p>
+
+<pre class="brush: js">this.game.input.onDown.add(itemTouched, this);
+
+function itemTouched(pointer) {
+ // do something
+}</pre>
+
+<p>The <code>itemTouched()</code> function will be executed when the <code>onDown</code> event is dispatched by touching the screen. The <code>pointer</code> variable will contain the information about the pointer that activated the event.</p>
+
+<p>This approach uses the generally available <code>this.game.input</code> object, but you can also detect the actions on any game objects like sprites or buttons by using <code>onInputOver</code>, <code>onInputOut</code>, <code>onInputDown</code>, <code>onInputUp</code>, <code>onDragStart</code>, or <code>onDragStop</code>:</p>
+
+<pre class="brush: js">this.button.events.onInputOver.add(itemTouched, this);
+
+function itemTouched(button, pointer) {
+ // do something
+}</pre>
+
+<p>That way you'll be able to attach an event to any object in the game, like the player's ship, and react to the actions performed by the user.</p>
+
+<p>An additional advantage of using Phaser is that the buttons you create will take any type of input, whether it's a touch on mobile or a click on desktop — the framework sorts this out in the background for you.</p>
+
+<h3 id="Implementation">Implementation</h3>
+
+<p>The easiest way to add an interactive object that will listen for user input is to create a button:</p>
+
+<pre class="brush: js">var buttonEnclave = this.add.button(10, 10, 'logo-enclave', this.clickEnclave, this);</pre>
+
+<p>This one is formed in the <code>MainMenu</code> state — it will be placed ten pixels from the top left corner of the screen, use the <code>logo-enclave</code> image, and execute the <code>clickEnclave()</code> function when it is touched. This will work on mobile and desktop out of the box. There are a few buttons in the main menu, including the one that will start the game.</p>
+
+<p>For the actual gameplay, instead of creating more buttons and covering the small mobile screen with them, we can use something a little bit different: we'll create invisible areas which respond to the given action. From a design point of view, it is better to make the field of activity bigger without covering half of the screen with button images. For example, tapping on the right side of the screen will fire the weapon:</p>
+
+<pre class="brush: js">this.buttonShoot = this.add.button(this.world.width*0.5, 0, 'button-alpha', null, this);
+this.buttonShoot.onInputDown.add(this.goShootPressed, this);
+this.buttonShoot.onInputUp.add(this.goShootReleased, this);</pre>
+
+<p>The code above will create a new button using a transparent image that covers the right half of the screen. You can assign functions on input down and input up separately if you'd like to perform more complicated actions, but in this game touching the right side of the screen will simply fire the bullets to the right — this is all we need in this case.</p>
+
+<p>Moving the player could be managed by creating the four directional buttons, but we can take the advantage of touch screens and drag the player's ship around:</p>
+
+<pre class="brush: js">var player = this.game.add.sprite(30, 30, 'ship');
+player.inputEnabled = true;
+player.input.enableDrag();
+player.events.onDragStart.add(onDragStart, this);
+player.events.onDragStop.add(onDragStop, this);
+
+function onDragStart(sprite, pointer) {
+ // do something when dragging
+}</pre>
+
+<p>We can pull the ship around and do something in the meantime, and react when the drag is stopped. Hauling in Phaser, if enabled, will work out of the box — you don't have to set the position of the sprite yourself manually, so you could leave the <code>onDragStart()</code> function empty, or place some debug output to see if it's working correctly. The <code>pointer</code> element contains the <code>x</code> and <code>y</code> variables storing the current position of the dragged element.</p>
+
+<h3 id="Dedicated_plugins">Dedicated plugins</h3>
+
+<p>You could go even further and use dedicated plugins like <a href="http://phaser.io/shop/plugins/virtualjoystick">Virtual Joystick</a> — this is a paid, official Phaser plugin, but you can find free and <a href="https://github.com/Gamegur-us/phaser-touch-control-plugin">open source alternatives</a>. The initialization of Virtual Joystick looks like this:</p>
+
+<pre class="brush: js">this.pad = this.game.plugins.add(Phaser.VirtualJoystick);
+this.stick = this.pad.addStick(30, 30, 80, 'generic');</pre>
+
+<p>In the <code>create()</code> function of the <code>Game</code> state we're creating a virtual pad and a generic stick that has four directional virtual buttons by default. This is placed 30 pixels from the top and left edges of the screen and is 80 pixels wide.</p>
+
+<p>The stick being pressed can be handled during the gameplay in the <code>update</code> function like so:</p>
+
+<pre class="brush: js">if(this.stick.isDown) {
+ // move the player
+}</pre>
+
+<p>We can adjust the player's velocity based on the current angle of the stick and move him appropriately.</p>
+
+<h2 id="摘要">摘要</h2>
+
+<p>这篇文章主要讲解如何在移动端实现触摸控制; 下一篇文章我们将看到怎样添加键盘和鼠标支持。</p>
+
+<p>{{NextMenu("Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard", "Games/Techniques/Control_mechanisms")}}</p>
diff --git a/files/zh-cn/games/techniques/controls_gamepad_api/index.html b/files/zh-cn/games/techniques/controls_gamepad_api/index.html
new file mode 100644
index 0000000000..34b033d854
--- /dev/null
+++ b/files/zh-cn/games/techniques/controls_gamepad_api/index.html
@@ -0,0 +1,238 @@
+---
+title: 使用 Gamepad API 实现控制
+slug: Games/Techniques/Controls_Gamepad_API
+translation_of: Games/Techniques/Controls_Gamepad_API
+---
+<div>{{GamesSidebar}}</div><p class="summary">这篇文章着眼于使用 Gamepad API 为网页游戏实现一个有效的跨浏览器控制系统,可以让你使用端游控制器来控制你的网页游戏。Hungry Fridge,就是 <a href="http://enclavegames.com/">Enclave Games</a> 以此制作的游戏。</p>
+
+<h2 id="网页游戏的控制">网页游戏的控制</h2>
+
+<p>在历史上,在连接主机(console)的电视上玩游戏和在电脑(PC)上玩游戏是两种完全不一样的体验,最大的区别就是它们的控制方式。后来,额外的驱动程序和插件让我们能够使用主机控制器来游玩电脑端的游戏--不论是本地游戏,还是运行在浏览器中的游戏。 到现在的 HTML5 时代,我们终于有了 <a href="/en-US/docs/Web/API/Gamepad_API">Gamepad API</a> ,让我们能够在不安装任何插件的情况下,可以使用控制器来游玩基于浏览器的游戏。Gamepad API 通过提供一个接口公开按钮的按下和坐标的变化来实现这一点,在 JavaScript 中我们可以用这些变化来处理输入。这对于网页游戏来说是非常棒的特性。</p>
+
+<p><img alt="gamepad-controls" src="http://end3r.com/tmp/gamepad/gamepadapi-hungryfridge-img01.png" style="display: block; height: 400px; margin: 0px auto; width: 600px;"></p>
+
+<h2 id="API_状态与浏览器支持">API 状态与浏览器支持</h2>
+
+<p><a href="http://www.w3.org/TR/gamepad/">Gamepad API</a> 在 W3C 的进程中仍然还是工作草案的状态,这意味着它的实现方法可能还会出现变动,但是就目前来说<a href="http://caniuse.com/gamepad">浏览器的支持性</a>相当不错。Firefox 29+ 和 Chrome 35+ 对其支持得非常好。Opera 在版本 22+ 对 API 进行了支持 (一点也不奇怪,因为他们现在使用 Chrome 的引擎了。) 并且微软最近在 Edge 中对 API 实现了支持,也就是说四大主流浏览器现在都支持 Gamepad API。</p>
+
+<h2 id="哪种控制器最好?">哪种控制器最好?</h2>
+
+<p><img alt="gamepad devices" src="http://end3r.com/tmp/gamepad/devices.jpg" style="display: block; height: 450px; margin: 0px auto; width: 600px;"></p>
+
+<p>目前最受欢迎的控制器是来自 XBox 360、XBox One、PS3 和 PS4 的 — 它们经受过时间的检验,并且在浏览器跨 Windows 与 Mac OS 平台中对  Gamepad API 的实现中工作良好。</p>
+
+<p>还有一些其他各种各样不同布局的控制器或多或少的支持跨浏览器的实现。本文中讨论的代码使用了一些控制器进行测试,但是笔者比较喜欢的配置是:无线 XBox 360 控制器和 Mac OS X 平台的 Firefox 浏览器。</p>
+
+<h2 id="实例分析:Hungry_Fridge">实例分析:Hungry Fridge</h2>
+
+<p><a href="https://github.com/blog/1674-github-game-off-ii">GitHub Game Off II</a> 比赛举行于2013年11月,<a href="http://enclavegames.com/">Enclave Games</a> 决定参加比赛。比赛的主题为“改变”(change),所以他们提交了这样一个游戏——你需要通过点击来喂食饥饿的冰箱健康的食物 (苹果、萝卜、莴苣) 并避开“坏”的食物 (啤酒、汉堡、披萨) 。其中会有倒计时会改变接下来几秒内冰箱想吃的东西,所以你又要小心动作又要块。你可以<a href="http://enclavegames.com/games/hungry-fridge/">在这里尝试 Hungry Fridge</a>。</p>
+
+<p><img alt="hungryfridge-mainmenu" src="http://end3r.com/tmp/gamepad/gamepadapi-hungryfridge-img02.png" style="display: block; height: 333px; margin: 0px auto; width: 500px;"></p>
+
+<p>第二个隐藏的“改变”的实现是可以从单纯静态的冰箱改变成涡轮驱动、射击和吞食的机器能力。当你连接控制器后,游戏会有很明显的改变 (饥饿冰箱会变成超级涡轮的饥饿冰箱) 并且你可以使用 Gamepad API 来控制装甲冰箱。你需要击落食物但是你仍然需要找到冰箱目前想吃的食物,否则你会失去能量。</p>
+
+<p><img alt="hungryfridge-howtoplay-gamepad" src="http://end3r.com/tmp/gamepad/gamepadapi-hungryfridge-img03.png" style="display: block; height: 333px; margin: 0px auto; width: 500px;"></p>
+
+<p>游戏封装了两种截然不同的“变化”(change) ——好食物对坏食物,与移动端对桌面端。</p>
+
+<p><img alt="hungryfridge-gameplay-gamepad" src="http://end3r.com/tmp/gamepad/gamepadapi-hungryfridge-img04.png" style="display: block; height: 333px; margin: 0px auto; width: 500px;"></p>
+
+<h2 id="示例">示例</h2>
+
+<p>Game API 的动作展示与JavaScript的源代码公布是在完整版的 Hungry Fridge 构建之后才开始的,然后据此创建了一个 <a href="https://end3r.github.io/Gamepad-API-Content-Kit/demo/demo.html">简单的示例</a>。部分 <a href="https://end3r.github.io/Gamepad-API-Content-Kit/">Gamepad API Content Kit</a> 在Github 上供你分析代码并研究其如何工作。</p>
+
+<p><img alt="Hungry Fridge demo using Gamepad API" src="http://end3r.com/tmp/gamepad/super-turbo.png" style="display: block; height: 333px; margin: 0px auto; width: 500px;"></p>
+
+<p>以下讨论的代码来自于完整的 Hungry Fridge 游戏中,除了原代码需要 <code>turbo</code> 变量来决定是否启动“超级涡轮模式”以外几乎一模一样。此代码可以独立运行,就算不连接控制器也可以。</p>
+
+<div class="note">
+<p><strong>注:</strong>一个彩蛋:点击界面右上角的控制器图标有个隐藏选项——不连接控制器也能启动“超级涡轮模式” 。你可以使用键盘上的 A 和 D 控制左右旋转,W 射击,方向键移动。</p>
+</div>
+
+<h2 id="实现方法">实现方法</h2>
+
+<p>使用Gamepad API时有两个重要的事件—— <code>gamepadconnected</code>  和 <code>gamepaddisconnected</code>。 前者将于浏览器侦测到新控制器连接时触发;而后者则是断开连接 (不管是物理断开还是无响应了) 的时候触发。在示例中 <code>gamepadAPI</code> 对象通常存储着所有关于 API 的东西:</p>
+
+<pre class="brush: js"><code>var gamepadAPI = {
+ controller: {},
+ turbo: false,
+ connect: function() {},
+ disconnect: function() {},
+ update: function() {},
+ buttonPressed: function() {},
+ buttons: [],
+ buttonsCache: [],
+ buttonsStatus: [],
+ axesStatus: []
+};</code></pre>
+
+<p>数组 <code>buttons</code> 存储着 XBox 360 控制器的按键布局button layout:</p>
+
+<pre class="brush: js"><code>buttons: [
+ 'DPad-Up','DPad-Down','DPad-Left','DPad-Right',
+ 'Start','Back','Axis-Left','Axis-Right',
+ 'LB','RB','Power','A','B','X','Y',
+],</code></pre>
+
+<p>这可能和例如 PS3 控制器 (或者其他没名字的通用控制器) 等其他控制器有所不同,所以你需要注意并不要假设你期望的布局和你真正使用的控制器布局是一样。接下来我们设置两个事件侦听器来获取数据:</p>
+
+<pre class="brush: js"><code>window.addEventListener("gamepadconnected", gamepadAPI.connect);
+window.addEventListener("gamepaddisconnected", gamepadAPI.disconnect);</code></pre>
+
+<p>由于安全策略,你必须先与控制器产生交互才能触发当前显示页面的事件。如果 API 在没有接收到用户交互的时候工作,那它可能会在不知情的情况下被用来识别指纹。</p>
+
+<p>两个函数都十分简单:</p>
+
+<pre class="brush: js"><code>connect: function(evt) {
+ gamepadAPI.controller = evt.gamepad;
+ gamepadAPI.turbo = true;
+ console.log('控制器已连接。');
+},</code></pre>
+
+<p>函数 <code>connect()</code> 接受一个事件作为参数,并将其中的 <code>gamepad</code> 对象分配给 <code>gamepadAPI.controller</code> 变量。我们在这个游戏中只使用一个控制器,所以这个变量是一个单独的对象而不是控制器的数组。然后我们设置  <code>turbo</code> 属性为 <code>true</code>。 (这个可以直接用 <code>gamepad.connected</code> 实现,但我们想单独设置一个变量来控制“涡轮模式”而不需要连接控制器,原因已在前面说明过了。)</p>
+
+<pre class="brush: js"><code>disconnect: function(evt) {
+ gamepadAPI.turbo = false;
+ delete gamepadAPI.controller;
+ console.log('控制器已断开。');
+},</code></pre>
+
+<p>函数 <code>disconnect</code> 设置 <code>gamepad.turbo</code> 属性为 <code>false</code> 并移除存储着 <code>gamepad</code> 对象的变量。</p>
+
+<h3 id="Gamepad_对象">Gamepad 对象</h3>
+
+<p>对象 <code>gamepad</code> 中有包含了许多有用的信息,其中就包括按钮和坐标轴的状态等重要信息:</p>
+
+<ul>
+ <li><code>id</code>: 一个包含关于控制器信息的字符串。</li>
+ <li><code>index</code>: 一个为已连接的设备分配的唯一标识。</li>
+ <li><code>connected</code>: 一个布尔变量,<code>true</code> 表示设备已连接。</li>
+ <li><code>mapping</code>: 键位的布局类型;现在只有 <code>standard</code> 是唯一可用的值。</li>
+ <li><code>axes</code>: 每一个坐标轴的状态。表示为存储浮点值的数组。</li>
+ <li><code>buttons</code> : 每个按钮的状态,表示为一个 <code>GamepadButton</code> 对象,其包含 <code>pressed</code> 和 <code>value</code> 属性。</li>
+</ul>
+
+<p>变量 <code>index</code> 在我们连接了多个控制器时非常有用,我们可以用此来区分它们的操作——例如我们有一个需要连接两个控制器的双人游戏。</p>
+
+<h3 id="查询控制器对象">查询控制器对象</h3>
+
+<p>除了 <code>connect()</code> 和 <code>disconnect()</code> ,<code>gamepadAPI</code> 对象中还有另外两个方法:<code>update()</code> 和 <code>buttonPressed()</code>。<code>update()</code> 会在游戏循环的每一帧中执行,来更新 gamepad 对象的实时状态:</p>
+
+<pre class="brush: js"><code>update: function() {
+ // 清除按钮缓存
+ gamepadAPI.buttonsCache = [];
+ // 从上一帧中移动按钮状态到缓存中
+ for(var k=0; k&lt;gamepadAPI.buttonsStatus.length; k++) {
+ gamepadAPI.buttonsCache[k] = gamepadAPI.buttonsStatus[k];
+ }
+ // 清除按钮状态
+ gamepadAPI.buttonsStatus = [];
+ // 获取 gamepad 对象
+ var c = gamepadAPI.controller || {};
+
+ // 遍历按键,并将按下的按钮加到数组中
+ var pressed = [];
+ if(c.buttons) {
+ for(var b=0,t=c.buttons.length; b&lt;t; b++) {
+ if(c.buttons[b].pressed) {
+ pressed.push(gamepadAPI.buttons[b]);
+ }
+ }
+ }
+ // 遍历坐标值并加到数组中
+ var axes = [];
+ if(c.axes) {
+ for(var a=0,x=c.axes.length; a&lt;x; a++) {
+ axes.push(c.axes[a].toFixed(2));
+ }
+ }
+ // 分配接收到的值
+ gamepadAPI.axesStatus = axes;
+ gamepadAPI.buttonsStatus = pressed;
+ // 返回按钮以便调试
+ return pressed;
+},</code></pre>
+
+<p>在每一帧上,<code>update()</code> 都会将上一帧的按钮状态保存至数组 <code>buttonsCache</code> 中,并在 <code>gamepadAPI.controller</code> 对象提取出新的状态信息。然后它就能轮询按钮和坐标值并获得它们的实时状态和值。</p>
+
+<h3 id="监测按钮按下">监测按钮按下</h3>
+
+<p>方法 <code>buttonPressed()</code> 也位于主游戏循环中来监听按钮的按下。它有两个参数——我们想要监听的按钮和 (可选) 用来告诉游戏接收的按键是(从之前就)被按住了的。没了它你需要松开并再按一次按钮才能得到想要的结果。</p>
+
+<pre class="brush: js"><code>buttonPressed: function(button, hold) {
+ var newPress = false;
+ // 轮询按下的按钮
+ for(var i=0,s=gamepadAPI.buttonsStatus.length; i&lt;s; i++) {
+ // 如果我们找到我们想要的按钮
+ if(gamepadAPI.buttonsStatus[i] == button) {
+ // 设置布尔变量(newPress)为 true
+ newPress = true;
+ // 如果我们想检查按住还是单次按下
+ if(!hold) {
+ // 从上一帧轮询缓存状态
+ for(var j=0,p=gamepadAPI.buttonsCache.length; j&lt;p; j++) {
+ // 如果按钮(之前)已经被按下了则忽略新的按下状态
+ if(gamepadAPI.buttonsCache[j] == button) {
+ newPress = false;
+ }
+ }
+ }
+ }
+ }
+ return newPress;
+},</code></pre>
+
+<p>在一个按钮中有两种动作:单次按下和按住。变量 <code>newPress</code> 布尔变量将会指出这个是不是一个按钮新的按下操作。下次我们再轮询已按下按钮的数组——如果有按钮是我们正在找的,那么设 <code>newPress</code> 变量为 <code>true</code> 。通过检查本次按下是不是新按下的,就能得出玩家是不是按住按钮了。我们从游戏循环中的上一帧轮询按钮的缓存状态,如果我们找到了,就说明按钮被按住了,所以就不是新的按下。最后 <code>newPress</code> 变量被返回。函数 <code>buttonPressed</code> 通常这样来更新游戏循环:</p>
+
+<pre class="brush: js"><code>if(gamepadAPI.turbo) {
+ if(gamepadAPI.buttonPressed('A','hold')) {
+ this.turbo_fire();
+ }
+ if(gamepadAPI.buttonPressed('B')) {
+ this.managePause();
+ }
+}</code></pre>
+
+<p>如果 <code>gamepadAPI.turbo</code> 为 <code>true</code> 并有按钮被按下(或被按住),我们就会为其分配恰当的操作。在本例中,按下或按住 <code>A</code> 开火,按下 <code>B</code> 暂停游戏。</p>
+
+<h3 id="坐标阈值">坐标阈值</h3>
+
+<p>按钮只有两种状态:<code>0</code> 或 <code>1</code>,但是摇杆可以有许多不同的值——他们在 <code>X</code> 和 <code>Y</code> 轴上都有一个范围为 <code>-1</code> 到 <code>1</code> 的浮点值。</p>
+
+<p><img alt="axis threshold" src="http://end3r.com/tmp/gamepad/axis-threshold.png" style="display: block; height: 300px; margin: 0px auto; width: 400px;"></p>
+
+<p>控制器放在一边不活动时轴值也可能有一定波动 (get dusty) ,这也就是说通过判断等于绝对的 -1 或 1 来可能是会有问题的。因此对此最好是给轴值设定一个阈值来触发生效。比如说,“冰箱坦克”仅会在 <code>X</code> 值大于 <code>0.5</code> 的时候向右转:</p>
+
+<pre><code>if(gamepadAPI.axesStatus[0].x &gt; 0.5) {
+ this.player.angle += 3;
+ this.turret.angle += 3;
+}</code></pre>
+
+<p>即使我们稍微误推摇杆或者摇杆没有弹回原始位置,“冰箱坦克”也不会意外转向。</p>
+
+<h2 id="规范更新">规范更新</h2>
+
+<p>经过长达一年多的规范化,W3C Gamepaf API 于2015年4月更新了规范 (<a href="https://w3c.github.io/gamepad/">查看最新信息</a>)。更新的改动并不是很大,但是我们最好了解一下到底更新了些什么—— 以下为更新。</p>
+
+<h3 id="获取控制器">获取控制器</h3>
+
+<p>{{domxref("Naviagator.getGamepads()")}} 方法已用<a href="https://w3c.github.io/gamepad/#navigator-interface-extension">更长的说明和示例代码</a>更新。现在控制器数组的长度必须为 <code>n+1</code> ( <code>n</code> 是已连接设备的数量) —— 当设备连接且其有索引 1,数组长度为 2,那么它将会是这样: <code>[null, [object Gamepad]]</code>。如果设备被断开或不可用的话,值将被设为 <code>null</code>。</p>
+
+<h3 id="映射标准">映射标准</h3>
+
+<p>布局类型现在是一个可枚举的对象而不是字符串:</p>
+
+<pre>enum GamepadMappingType {
+ "",
+ "standard"
+};</pre>
+
+<p>此枚举中定义了已知的控制器映射集。目前只有 <code>standard</code> 布局可用,但是未来可能会有新的布局。如果布局未知,那么将会是空字符串。</p>
+
+<h3 id="事件">事件</h3>
+
+<p>除了当前可用的 <code>gamepadconnected</code> 和 <code>gamepaddisconnected</code> 事件,其实还有其它事件也曾在规范中,但它们因为不是非常的有用所以被移出了规范。相关讨论仍在进行中,关于它们是否应该恢复规范,以及以什么形式恢复。</p>
+
+<h2 id="总结">总结</h2>
+
+<p>Gamepad API 非常易于开发。现在它比以往更容易向浏览器提供游戏主机的体验而不需要任何插件。你可以直接在你的浏览器中游玩完整的 <a href="http://enclavegames.com/games/hungry-fridge/">Hungry Fridge</a> 游戏。你可以从 <a href="https://marketplace.firefox.com/app/hungry-fridge">Firefox Marketplace</a> 中安装,或者可以在 <a href="https://github.com/EnclaveGames/Hungry-Fridge">Gamepad API Content Kit</a> 中查看示例源代码。</p>
diff --git a/files/zh-cn/games/techniques/index.html b/files/zh-cn/games/techniques/index.html
new file mode 100644
index 0000000000..f80eff7adc
--- /dev/null
+++ b/files/zh-cn/games/techniques/index.html
@@ -0,0 +1,34 @@
+---
+title: Techniques for game development
+slug: Games/Techniques
+tags:
+ - Games
+ - Guide
+ - NeedsTranslation
+ - TopicStub
+translation_of: Games/Techniques
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<div class="summary">
+<p><span class="seoSummary">这个页面为想要使用开放的网页技术来开发游戏的人列举出了必要的核心技术。</span></p>
+</div>
+
+<dl>
+ <dt><a href="/en-US/docs/Games/Techniques/Async_scripts">使用asm.js中的异步脚本</a></dt>
+ <dd>尤其在制作中大型游戏时,异步脚本是一项必备技术,你游戏中的JavaScript因此可以在主进程之外被编译,并被缓存以之后游戏的运行,这会带来显著的性能提升。这篇文章解释了如何做到。</dd>
+ <dt><a href="/en-US/docs/Apps/Developing/Optimizing_startup_performance" title="/en-US/docs/Apps/Developing/Optimizing_startup_performance">Optimizing startup performance</a></dt>
+ <dd>How to make sure your game starts up quickly, smoothly, and without appearing to lock up the user's browser or device.</dd>
+ <dt><a href="/en-US/docs/Games/WebRTC_data_channels" title="/en-US/docs/Games/WebRTC_data_channels">Using WebRTC peer-to-peer data channels</a></dt>
+ <dd>In addition to providing support for audio and video communication, WebRTC lets you set up peer-to-peer data channels to exchange text or binary data actively between your players. This article explains what this can do for you, and shows how to use libraries that make this easy.</dd>
+ <dt><a href="/en-US/docs/Games/Techniques/Efficient_animation_for_web_games">Efficient animation for web games</a></dt>
+ <dd>This article covers techniques and advice for creating efficient animation for web games, with a slant towards supporting lower end devices such as mobile phones. We touch on CSS transitions and CSS animations, and JavaScript loops involving {{ domxref("window.requestAnimationFrame") }}.</dd>
+ <dt><a href="/en-US/docs/Games/Techniques/Audio_for_Web_Games">Audio for Web Games</a></dt>
+ <dd>Audio is an important part of any game — it adds feedback and atmosphere. Web-based audio is maturing fast, but there are still many browser differences to negotiate. This article provides a detailed guide to implementing audio for web games, looking at what works currently across as wide a range of platforms as possible.</dd>
+ <dt><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a></dt>
+ <dd>A concise introduction to collision detection in 2D games.</dd>
+ <dt><a href="/en-US/docs/Games/Techniques/Tilemaps">Tilemaps</a></dt>
+ <dd>Tiles are a very popular technique in 2D games for building the game world. These articles provide an introduction to tilemaps and how to implement them with the Canvas API.</dd>
+</dl>
diff --git a/files/zh-cn/games/tools/index.html b/files/zh-cn/games/tools/index.html
new file mode 100644
index 0000000000..1d026dae28
--- /dev/null
+++ b/files/zh-cn/games/tools/index.html
@@ -0,0 +1,40 @@
+---
+title: Tools for game development
+slug: Games/Tools
+tags:
+ - Games
+ - Gecko
+ - Guide
+ - JavaScript
+ - NeedsTranslation
+ - TopicStub
+translation_of: Games/Tools
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<div class="summary">
+<p><span class="seoSummary">On this page you can find links to our game development tools articles, which eventually aims to cover frameworks, compilers, and debugging tools.</span></p>
+</div>
+
+<dl>
+ <dt><a href="/en-US/docs/Games/Tools/asm.js">asm.js</a></dt>
+ <dd>asm.js is a very limited subset of the JavaScript language, which can be greatly optimized and run in an ahead-of-time (AOT) compiling engine for much faster performance than your typical JavaScript performance. This is, of course, great for games.</dd>
+ <dt><a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a></dt>
+ <dd>
+ <p>An LLVM to JavaScript compiler; with Emscripten, you can compile C++ and other languages that can compile to LLVM bytecode into high-performance JavaScript. This is a great tool for porting applications to the Web! There is a <a href="https://github.com/kripken/emscripten/wiki/Tutorial">useful Emscripten tutorial</a> available on the wiki. Note that we are <a href="/en-US/docs/Emscripten">aiming to cover Emscripten in its own section of MDN</a>.</p>
+ </dd>
+ <dt><a href="https://addons.mozilla.org/en-us/firefox/addon/gecko-profiler/" title="https://addons.mozilla.org/en-us/firefox/addon/gecko-profiler/">Gecko profiler</a></dt>
+ <dd>The Gecko profiler extension lets you profile your code to help figure out where your performance issues are so that you can make your game run at top speed.</dd>
+ <dt><a href="/en-US/docs/Games/Tools/Engines_and_tools">Game engines and tools</a></dt>
+ <dd>A list of engines, templates and technologies useful to game developers.</dd>
+ <dt><a href="/en-US/docs/Mozilla/Projects/Shumway">Shumway</a></dt>
+ <dd>Shumway is a renderer for Adobe Flash built entirely in JavaScript, WebGL, etc., bridging the gap between Flash and web standards. This article shows how to make use of Shumway, and how to contribute fixes and bugs to the project.</dd>
+ <dt>Toolchain for developing and debugging games</dt>
+ <dd>How does this differ from normal web app debugging? What specialist tools are available? A lot of this is going to be covered by Will in <a href="/en-US/docs/Tools">tools</a>, but here we should provide a kind of practical toolchain tutorial for debugging games, with links to Will's stuff:
+ <ul>
+ <li>Basic tools overview</li>
+ <li><a href="/en-US/docs/Tools/Shader_Editor">Shader editor</a></li>
+ <li>Performance tools (still in production, estimated early 2014)</li>
+ </ul>
+ </dd>
+</dl>
diff --git a/files/zh-cn/games/tools/引擎和工具/index.html b/files/zh-cn/games/tools/引擎和工具/index.html
new file mode 100644
index 0000000000..082f9e0f39
--- /dev/null
+++ b/files/zh-cn/games/tools/引擎和工具/index.html
@@ -0,0 +1,68 @@
+---
+title: 游戏引擎和工具
+slug: Games/Tools/引擎和工具
+translation_of: Games/Tools/Engines_and_tools
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<h2 id="HTML5_游戏引擎">HTML5 游戏引擎</h2>
+
+<p>下面是用HTML5和JavaScript实现的游戏引擎:</p>
+
+<ul>
+ <li><a href="https://aframe.io">A-Frame</a>: 一个用于构建3D和虚拟现实体验的web框架。使用HTML和实体组件生态系统。HTC Vive、Oculus Rift、桌面端和移动平台都可以使用。来自Mozilla虚拟现实团队。</li>
+ <li><a class="external" href="http://www.canvace.com/">Canvace</a>: 一个用于创建2D和2.5 D游戏的HTML5游戏平台。</li>
+ <li><a class="external" href="http://craftyjs.com/">Crafty</a>: 一个基于javascript的2D游戏框架。</li>
+ <li><a class="external" href="http://cocos2d-x.org/wiki/Cocos2d-js">Cocos2D JS</a>: 为您想要发布的任何平台提供一致的开发经验,无论是web还是本地平台。“一套代码,可在任何地方运行”在Cocos2D JS中是非常容易和自然的。用一个独立的JavaScript代码库,你就可以在web浏览器和本地平台上运行你的游戏,包括Mac OS X、Windows、iOS和Android。你的游戏可以在所有主流应用商店和其他分销渠道上发布。</li>
+ <li><a class="external" href="http://www.scirra.com/">Construct 2</a>: 它是第一个支持HTML5的HTML5游戏引擎,它只支持HTML5和JavaScript。只使用Canvas,并且通过JavaScript插件可扩展。</li>
+ <li><a class="external" href="http://www.divgo.net/">Div GO</a>: 基于Div游戏工作室开发的2D和3D游戏的开发引擎。它包含了新的函数和变量来增强HTML5和canvas。Div GO还提供了一个集成开发环境,其中包括代码编辑器、进程和函数列表、图形编辑器、运行过程列表、编译器和生成器/包装器项目。</li>
+ <li><a class="external" href="http://enchantjs.com/">EnchantJS</a>: 一个简单的用于创建2D和3D HTML5游戏的JavaScript框架。它有良好的文档和易于遵循的入门教程。</li>
+ <li><a class="external" href="http://www.compilgames.net">GDevelop</a>: 一个面向本地和HTML5的游戏开发平台。它用基于WebGL/canvas的Pixi.js渲染项目。</li>
+ <li><a class="external" href="http://www.isogenicengine.com/">Isogenic Engine</a>: 目前最有前途的游戏引擎之一。内置大规模的多人联网,在服务器端使用Node.js和MongoDB,并且可以输出canvas或dom节点的图形。</li>
+ <li><a class="external" href="http://impactjs.com/">Impact</a>: 一个带有编辑器和其他工具的JavaScript游戏引擎,会产生各种各样的游戏风格(例如2D和3D),并且可以发布到web、Android和iOS。</li>
+ <li><a href="http://jawa.games">Jawa</a> : A browser based point'n'click adventure game engine, with a built-in very easy to use authoring tool. Games are exportable as HTML5 objects. Free for personal and educational purposes</li>
+ <li><a href="http://Lance.gg">Lance.gg</a>: A game engine suitable for multiplayer games.  Handles networking code (authoritative server), implements real-time extrapolation of game object positions, a.k.a. client-side prediction.  Supports 2D and 3D game worlds. Works with either simplified physics or full-featured physics engine <a href="http://www.cannonjs.org/">cannon.js</a>.  Supported renderers: <a href="http://www.pixijs.com/">PIXI.js</a>, plain HTML, canvas / Three.js, and <a href="https://aframe.io">A-Frame</a>.</li>
+ <li><a class="external" href="http://melonjs.org/">melonJS</a>: A fresh and lightweight 2D sprite–based engine with WebGL and Tiled map support.</li>
+ <li><a class="external" href="http://mightyfingers.com/">MightyEngine</a>: 2D game engine supporting Web, Android, and iOS platforms. It includes a built in editor to manage projects, assets, and maps.</li>
+ <li><a class="external" href="http://phaser.io">Phaser</a>: A 2D game engine supporting Web, Android, and IOS platforms.</li>
+ <li><a class="external" href="http://playcanvas.com/">PlayCanvas</a>: A collaborative, cloud–hosted game engine with a visual editor, in-browser code editing and one–click publishing.</li>
+ <li><a class="external" href="http://piqnt.com/stage.js/">Stage.js</a>: A Lightweight and fast HTML5 2D rendering engine for cross-platform game development.</li>
+ <li><a class="external" href="http://superpowers-html5.com/index.en.html">Superpowers</a>: A 2D and 3D collaborative, open-source, HTML5 game dev environment using TypeScript.</li>
+ <li><a class="external" href="http://www.wimi5.com">WiMi5</a>: An online framework to create, publish and monetize HTML5 games. It includes a visual scripting editor so programming is not required. One-click publishing for several Web Market Places. You can also download your game as a zip and publish it where ever you want, including native desktop and mobile platforms. Easy in-app purchases integration. </li>
+ <li><a class="external" href="http://www.rpgmakerweb.com/products/programs/rpg-maker-mv">RPG Maker MV: </a>This particular version from the "RPG Maker" series is built on JavaScript. You can add custom code or addons, and deploy projects as Windows, Mac and web application. In addition, anime and manga–style models are included to make use of.</li>
+ <li><a href="https://bitbucket.org/nikola_l/visual-js/">visual-js</a>: This is JavaScript game engine canvas 2d (native js) / 3d( three.js) . Server part works on node.js. Windows users can use GUI editor (game instance creator) with gui tools (encript , multilanguage , build engine library , build resourse). Try <a href="https://jsfiddle.net/user/zlatnaspirala/fiddles/">Api examples on jsfiddle</a>. You can create game objects direct on web page (editor mode). Build images resource object with node.js tool. Any app created in this game engine works on all modern browsers. </li>
+</ul>
+
+<h2 id="HTML5_game_tools">HTML5 game tools</h2>
+
+<ul>
+ <li><a class="external" href="http://clay.io/development-tools">Clay.io</a>: Distribution, Retention, Social and Monetization tools. Easy integration of user accounts, high scores, achievements, cross promotion, in-game payments, analytics etc.</li>
+ <li><a class="external" href="https://github.com/mrdoob/stats.js">stat.js</a>: Simple JavaScript performance monitor.</li>
+ <li><a href="http://phasereditor.boniatillo.com">Phaser Editor</a>: an IDE to build Phaser based games. Provides several built-in tools like a scene builder, texture packer, asset manager and an improved JavaScript editor.</li>
+ <li><a href="https://github.com/shakiba/planck.js">Planck.js</a>: 2D JavaScript physics engine for cross-platform game development, rewrite of Box2D.</li>
+</ul>
+
+<h2 id="Useful_technologies">Useful technologies</h2>
+
+<p>The following can be useful when developing games based on Web technologies.</p>
+
+<ul>
+ <li><a href="/en-US/docs/Web/HTML/Element/canvas">Canvas</a>: 2D graphics.</li>
+ <li><a href="/en-US/docs/Web/WebGL">WebGL</a>: 3D graphics.</li>
+ <li>Audio: {{htmlelement("audio")}} element, <a href="/en-US/docs/Web_Audio_API">Web Audio API.</a></li>
+ <li><a href="/en-US/docs/WebSockets">WebSockets</a>: Can be used for real-time communication between a player and the game server, to support multi-player games.</li>
+ <li><a class="external" href="http://nodejs.org/">Node.js</a>: Node is often used as a multiplayer game server, controlling the logic and handling the WebSockets connections to the players. It can be used for player authentication and the storage of data so gameplay can persist over multiple game sessions. This is all made relatively easy with great third-party modules, like Socket.IO for WebSockets, and others that handle Redis and MongoDB for storage.</li>
+ <li><a href="/en-US/docs/Web/Guide/DOM/Storage">DOM Storage</a>: Great for storing data locally on the player's device. This way you can cache game data and allow the game to continue where the player left off.</li>
+ <li><a href="/en-US/docs/Web/Guide/DOM/Using_full_screen_mode">Full Screen API</a> : Allows you to expand any HTML element to fill the user's screen, even if the browser isn’t running full-screen itself.</li>
+ <li><a href="/en-US/docs/Web/API/ServiceWorker_API">ServiceWorker API</a>: Traditionally one of the main differences between Web apps and native apps was that unlike web apps, native apps could be run offline. This has changed — technologies such as Service Workers allow for a website or web app to cache necessary assets so it can still run while offline. This includes things like JavaScript files, CSS and images. Combining this technique with intelligent use of things like localStorage will allow your game to continue working even if the Internet connection goes down. You just need to sync up all the changes when it gets connected again.</li>
+ <li><a href="/en-US/docs/API/Gamepad/Using_Gamepad_API">Gamepad API</a>: Allows you to control web–based games via a gamepad. This might be just what finally justifies HTML5 gaming on a TV or console. Who wants to use a keyboard and mouse while sitting on the sofa?</li>
+ <li><a href="/en-US/docs/WebAPI/Pointer_Lock">Pointer Lock API</a>: An attempt to improve the mouse as an input device, in situations such as games and 3D visualizations where the mouse position rotates or moves you around a 3D space. As it stands, there would still be a cursor moving around the screen causing all sorts of trouble when you want to click on something in your game. With this API, you can lock your mouse position, or even hide it altogether, using the mouse movement to move the game world instead.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Not every browser supports every part of HTML5. For example, Canvas isn’t supported out of the box by any Internet Explorer version below 9. However, you can use Explorer Canvas to replicate canvas functionality (but that is not ideal and does not perform as well). WebSockets is supported by IE only in IE 10, and it isn’t supported in the stock browser of Android. But again, you can fake this by using Flash for the sockets, such as with Socket.IO. While supported in the latest versions of every other browser, WebGL in Internet Explorer requires at least version 11.</p>
+</div>
+
+<h2 id="Game_template">Game template</h2>
+
+<p>You can use the <a href="https://github.com/mozilla/mortar-game-stub">Mortar Game Stub</a> template to get a quick start on an HTML5 game, or you can use it to get ideas on best practices.</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/animations_and_tweens/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/animations_and_tweens/index.html
new file mode 100644
index 0000000000..ff5aa23230
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/animations_and_tweens/index.html
@@ -0,0 +1,117 @@
+---
+title: Animations and tweens
+slug: Games/Tutorials/2D_breakout_game_Phaser/Animations_and_tweens
+tags:
+ - 2D
+ - Animation
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - tween
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Animations_and_tweens
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Extra_lives", "Games/Workflows/2D_Breakout_game_Phaser/Buttons")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第14步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson14.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson14.html</font></a><font>完成本课程后找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>为了使游戏看起来更加多汁和活泼,我们可以使用动画和补间。</font><font>这将导致更好,更有趣的体验。</font><font>让我们来探讨如何在游戏中实现Phaser动画和补间。</font></p>
+
+<h2 id="动画">动画</h2>
+
+<p><font><font>在Phaser,动画中,涉及从外部来源获取spritesheet并依次显示sprites。</font><font>作为一个例子,当碰到一些东西时,我们会让球摇摆。</font></font></p>
+
+<p><font><font>首先,</font></font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/img/wobble.png"><font><font>从Github抓取spritesheet</font></font></a><font><font>并将其保存在您的</font></font><code>/img</code><font><font>目录中。</font></font></p>
+
+<p><font><font>接下来,我们将加载spritesheet - 将以下行放在</font></font><code>preload()</code><font><font>函数</font><font>的底部</font><font>:</font></font></p>
+
+<pre class="brush: js">game.load.spritesheet('ball', 'img/wobble.png', 20, 20);
+</pre>
+
+<p><font><font>而不是加载单个图像的球,我们可以加载整个spritesheet - 不同图像的集合。</font><font>我们将按顺序显示精灵,创造动画的幻觉。</font><font>该</font></font><code>spritesheet()</code><font><font>方法的两个额外的表格确定给定spritesheet文件中每个单个框架的宽度和高度,指示程序如何切割以获取单个框架。</font></font></p>
+
+<h2 id="加载动画"><font><font>加载动画</font></font></h2>
+
+<p><font><font>接下来,进入你的create()函数,找到加载球精灵的行,下面的调用</font></font><code>animations.add()</code><font><font>如下所示:</font></font></p>
+
+<pre class="brush: js">ball = game.add.sprite(50, 250, 'ball');
+ball.animations.add('wobble', [0,1,0,2,0,1,0,2,0], 24);
+</pre>
+
+<p><font><font>要向对象添加动画,我们使用该</font></font><code>animations.add()</code><font><font>方法,其中包含以下参数</font></font></p>
+
+<ul>
+ <li><font><font>我们为动画选择的名称</font></font></li>
+ <li><font><font>一个数组,定义在动画过程中显示帧的顺序。</font><font>如果您再次查看</font></font><code>wobble.png</code><font><font>图像,您会看到有三个框架。</font><font>Phaser提取它们并将它们存储在数组中 - 位置0,1和2.上面的数组表示我们显示帧0,然后是1,然后是0等。</font></font></li>
+ <li><font><font>帧速率,以fps为单位。</font><font>由于我们以24fps运行动画,有9帧,动画每秒将显示三次以下。</font></font></li>
+</ul>
+
+<h2 id="当球击中桨时应用动画"><font><font>当球击中桨时应用动画</font></font></h2>
+
+<p><font><font>在</font></font><code>arcade.collide()</code><font><font>处理球和桨(第一行内部</font></font><code>update()</code><font><font>,见下文)</font><font>之间的碰撞</font><font>的</font><font>方法调用中,</font><font>我们可以添加一个额外的参数,该参数指定每次发生碰撞时执行的功能,与该</font></font><code>ballHitBrick()</code><font><font>功能</font><font>相同</font><font>。</font><font>更新内部的第一行</font></font><code>update()</code><font><font>,如下所示:</font></font></p>
+
+<pre class="brush: js">function update() {
+ game.physics.arcade.collide(ball, paddle, ballHitPaddle);
+ game.physics.arcade.collide(ball, bricks, ballHitBrick);
+ paddle.x = game.input.x || game.world.width*0.5;
+}
+</pre>
+
+<p><font><font>然后我们可以创建</font></font><code>ballHitPaddle()</code><font><font>函数(具有</font></font><code>ball</code><font><font>和</font></font><code>paddle</code><font><font>作为默认参数),在调用时播放摆动动画。</font><font>在结束</font></font><code>&lt;/script&gt;</code><font><font>标签</font><font>之前添加以下方法</font><font>:</font></font></p>
+
+<pre class="brush: js">function ballHitPaddle(ball, paddle) {
+ ball.animations.play('wobble');
+}
+</pre>
+
+<p><font><font>每次球击中桨时都会播放动画。</font><font>你也可以</font></font><code>animations.play()</code><font><font>在</font></font><code>ballHitBrick()</code><font><font>函数</font><font>内</font><font>添加</font><font>调用</font><font>,如果你觉得它会使游戏看起来更好。</font></font></p>
+
+<h2 id="补间">补间</h2>
+
+<p>而动画依次播放外部精灵,补间游戏中物体的属性平滑,如宽度或不透明度。</p>
+
+<p><font><font>让我们在游戏中增加一个补间,使砖块在被球击中时顺利消失。</font><font>转到您的</font></font><code>ballhitBrick()</code><font><font>功能,找到您的</font></font><code>brick.kill();</code><font><font>行,并将其替换为以下内容:</font></font></p>
+
+<pre class="brush: js">var killTween = game.add.tween(brick.scale);
+killTween.to({x:0,y:0}, 200, Phaser.Easing.Linear.None);
+killTween.onComplete.addOnce(function(){
+ brick.kill();
+}, this);
+killTween.start();
+</pre>
+
+<p>让我们来看看这里,看看这里发生了什么:</p>
+
+<ol>
+ <li><font><font>当定义一个新的补间时,你必须指定哪些属性将被补间 - 在我们的例子中,而不是在被球击中时立即隐藏砖块,我们将把它们的宽度和高度缩放到零,所以它们将很好地消失。</font><font>最后,我们使用该</font></font><code>add.tween()</code><font><font>方法,指定</font></font><code>brick.scale</code><font><font>为参数,因为这是我们想要补间。</font></font></li>
+ <li><font><font>该</font></font><code>to()</code><font><font>方法定义补间结束时对象的状态。</font><font>它需要一个包含所选参数的期望结束值的对象(比例取尺度值,1为大小的100%,0为大小的0%等),补间的时间(以毫秒为单位)以及使用的宽松类型补间。</font></font></li>
+ <li><font><font>我们还将添加可选的</font></font><code>onComplete</code><font><font>事件处理程序,该处理程序定义了在补间程序完成时要执行的函数。</font></font></li>
+ <li><font><font>最后一件事是立即开始补间</font></font><code>start()</code><font><font>。</font></font></li>
+</ol>
+
+<p>这是补间定义的扩展版本,但是我们也可以使用速记语法:</p>
+
+<pre class="brush: js">game.add.tween(brick.scale).to({x:2,y:2}, 500, Phaser.Easing.Elastic.Out, true, 100);
+</pre>
+
+<p>这个补间将使用弹性宽松在半秒内将砖的比例翻倍,将自动启动,延迟100毫秒。</p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/9o4pakrb/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>动画和tweens看起来很不错,但我们可以添加更多的我们的游戏 - 在下一节我们将看看处理</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Buttons"><font><font>按钮</font></font></a><font><font>输入。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Extra_lives", "Games/Workflows/2D_Breakout_game_Phaser/Buttons")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html
new file mode 100644
index 0000000000..2cc91361c6
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/bounce_off_the_walls/index.html
@@ -0,0 +1,49 @@
+---
+title: Bounce off the walls
+slug: Games/Tutorials/2D_breakout_game_Phaser/Bounce_off_the_walls
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - bouncing
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Bounce_off_the_walls
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Physics", "Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font>的</font></font><strong><font><font>第</font></font></strong><font><font> 6 </font><strong><font>步</font></strong><font>。</font><font>在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson06.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson06.html</font></a><font>完成本课后,您可以找到源代码</font><font>。</font></font></p>
+</div>
+
+<p>现在已经介绍了物理引擎,我们可以开始在游戏中实现碰撞检测 - 首先我们来看看墙壁。</p>
+
+<h2 id="反弹边界"><font><font>反弹边界</font></font></h2>
+
+<p><font><font>让我们的球从墙壁上弹起的最简单的方法是告诉框架,我们想要将</font></font><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas" title="HTML &lt;canvas>元素可用于通过脚本(通常为JavaScript)绘制图形。 例如,它可以用于绘制图形,制作照片,甚至执行动画。 您可以(并且应该)在&lt;canvas>块内提供备用内容。 该内容将在不支持画布的旧浏览器和禁用JavaScript的浏览器中呈现。"><code>&lt;canvas&gt;</code></a><font><font>元素</font><font>的边界</font><font>视为墙壁,而不是让球移过它们。</font><font>在Phaser中,可以使用该</font></font><code>collideWorldsBound</code><font><font>属性</font><font>轻松实现</font><font>。</font><font>在现有</font></font><code>game.physics.enable()</code><font><font>方法调用</font><font>之后添加此行</font><font>:</font></font></p>
+
+<pre class="brush: js">ball.body.collideWorldBounds = true;
+</pre>
+
+<p><font>现在球将停在屏幕的边缘,而不是消失,但它不会弹起。</font><font>为了使这种情况发生,我们必须设置它的bounciness。</font><font>在上一行下面添加以下行:</font></p>
+
+<pre class="brush: js">ball.body.bounce.set(1);
+</pre>
+
+<p>再次尝试重新加载index.html - 现在您应该看到球从墙壁上弹起并在画布区域内移动。</p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/dcw36opz/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>现在开始看起来更像是一个游戏,但是我们无法以任何方式控制它 - 现在是介绍</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls"><font><font>玩家挡板和控制的时候了</font></font></a><font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Physics", "Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html
new file mode 100644
index 0000000000..981b592469
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/build_the_brick_field/index.html
@@ -0,0 +1,164 @@
+---
+title: Build the brick field
+slug: Games/Tutorials/2D_breakout_game_Phaser/Build_the_brick_field
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Build_the_brick_field
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Game_over", "Games/Workflows/2D_Breakout_game_Phaser/Collision_detection")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第9步</font></font></strong><font><font>。</font><font>在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson09.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson09.html</font></a><font>完成本课后,您可以找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>建立砖块比将单个对象添加到屏幕要复杂一点,尽管使用Phaser还是比纯JavaScript更容易。</font><font>我们来探讨如何创建一组砖块,并使用循环在屏幕上打印。</font></p>
+
+<h2 id="定义新变量"><font><font>定义新变量</font></font></h2>
+
+<p>首先,我们定义所需的变量 - 在以前的变量定义中添加以下内容:</p>
+
+<pre class="brush: js">var bricks;
+var newBrick;
+var brickInfo;
+</pre>
+
+<p><font><font>该</font></font><code>bricks</code><font><font>变量将用于创建一个组,</font></font><code>newBrick</code><font><font>将在循环的每次迭代中添加到组中的新对象,</font></font><code>brickInfo</code><font><font>并将存储我们需要的所有数据。</font></font></p>
+
+<h2 id="渲染砖图像"><font><font>渲染砖图像</font></font></h2>
+
+<p><font><font>接下来,我们加载砖的图像 - </font></font><code>load.image()</code><font><font>在其他地方</font><font>添加以下</font><font>调用:</font></font></p>
+
+<pre class="brush: js">function preload() {
+ // ...
+ game.load.image('brick', 'img/brick.png');
+}
+</pre>
+
+<p><font><font>您还需要</font></font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/img/brick.png"><font><font>从Github抓取砖图像</font></font></a><font><font>并将其保存在您的</font></font><code>/img</code><font><font>目录中。</font></font></p>
+
+<h2 id="画砖"><font><font>画砖</font></font></h2>
+
+<p><font><font>我们将将所有用于绘制砖块的代码放在一个</font></font><code>initBricks</code><font><font>函数中,以使其与其余代码分离。</font></font><code>initBricks</code><font><font>在</font></font><code>create()</code><font><font>函数</font><font>末尾</font><font>添加一个调用</font><font>:</font></font></p>
+
+<pre class="brush: js">function create(){
+ // ...
+ initBricks();
+}
+</pre>
+
+<p><font><font>现在到函数本身。</font></font><code>initBricks()</code><font><font>在我们的游戏代码末尾</font><font>添加</font><font>功能,就在关闭&lt;/ script&gt;标签之前,如下所示。</font><font>首先我们已经包括了这个  </font></font><code>brickInfo</code><font><font>对象,因为这很快就会派上用场:</font></font></p>
+
+<pre class="brush: js">function initBricks() {
+ brickInfo = {
+ width: 50,
+ height: 20,
+ count: {
+ row: 7,
+ col: 3
+ },
+ offset: {
+ top: 50,
+ left: 60
+ },
+ padding: 10
+ };
+}
+</pre>
+
+<p><font><font>这个</font></font><code>brickInfo</code><font><font>对象将包含我们需要的所有信息:单个砖的宽度和高度,我们将在屏幕上看到的砖的行数和列数,顶部和左边的偏移量(画布上我们将开始绘制的位置)砖块)和每一列和砖块之间的填充。</font></font></p>
+
+<p><font><font>现在,让我们开始创建砖块 - 首先添加一个空组来包含砖块,在</font></font><code>initBricks()</code><font><font>函数</font><font>底部添加以下行</font><font>:</font></font></p>
+
+<pre class="brush: js">bricks = game.add.group();
+</pre>
+
+<p>我们可以循环遍历行和列,以便在每次迭代中创建新的砖块 - 在上一行代码下面添加以下嵌套循环:</p>
+
+<pre class="brush: js">for(c=0; c&lt;brickInfo.count.col; c++) {
+ for(r=0; r&lt;brickInfo.count.row; r++) {
+ // create new brick and add it to the group
+ }
+}
+</pre>
+
+<p><font><font>这样我们将创建我们需要的确切数量的砖,并将它们全部包含在一个组中。</font><font>现在我们需要在嵌套循环结构中添加一些代码来绘制每个砖块。</font><font>填写内容如下图所示:</font></font></p>
+
+<pre class="brush: js">for(c=0; c&lt;brickInfo.count.col; c++) {
+ for(r=0; r&lt;brickInfo.count.row; r++) {
+ var brickX = 0;
+ var brickY = 0;
+ newBrick = game.add.sprite(brickX, brickY, 'brick');
+ game.physics.enable(newBrick, Phaser.Physics.ARCADE);
+ newBrick.body.immovable = true;
+ newBrick.anchor.set(0.5);
+ bricks.add(newBrick);
+ }
+}
+</pre>
+
+<p><font><font>在这里,我们循环遍历行和列,创建新的砖块并将其放在屏幕上。</font><font>新创建的砖块为Arcade物理引擎启用,它的身体被设置为不可移动(所以当球被击中时它不会移动),我们还将锚点放在中间并添加砖到集团。</font></font></p>
+
+<p><font><font>目前的问题是,我们在一个地方绘制所有的砖,坐标(0,0)。</font><font>我们需要做的是将每个砖块绘制在自己的x和y位置。</font><font>更新</font></font><code>brickX</code><font><font>和</font></font><code>brickY</code><font><font>行如下:</font></font></p>
+
+<pre class="brush: js">var brickX = (r*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
+var brickY = (c*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;
+</pre>
+
+<p><font><font>每个</font></font><code>brickX</code><font><font>位置都是</font></font><code>brickInfo.width</code><font><font>加</font></font><code>brickInfo.padding</code><font><font>号乘以行号</font></font><code>r</code><font><font>,加上</font></font><code>brickInfo.offset.left</code><font><font>; </font><font>用于所述逻辑</font></font><code>brickY</code><font><font>是不同之处在于它使用的值列号相同</font></font><code>c</code><font><font>,</font></font><code>brickInfo.height</code><font><font>和</font></font><code>brickInfo.offset.top</code><font><font>。</font><font>现在每个砖都可以放置在正确的位置,每个砖块之间填充,并从左侧和顶部画布边缘偏移绘制。</font></font></p>
+
+<h2 id="检查initBricks()代码"><font><font>检查initBricks()代码</font></font></h2>
+
+<p><font><font>这是功能的完整代码</font></font><code>initBricks()</code><font><font>:</font></font></p>
+
+<pre class="brush: js">function initBricks() {
+ brickInfo = {
+ width: 50,
+ height: 20,
+ count: {
+ row: 7,
+ col: 3
+ },
+ offset: {
+ top: 50,
+ left: 60
+ },
+ padding: 10
+ }
+ bricks = game.add.group();
+ for(c=0; c&lt;brickInfo.count.col; c++) {
+ for(r=0; r&lt;brickInfo.count.row; r++) {
+ var brickX = (r*(brickInfo.width+brickInfo.padding))+brickInfo.offset.left;
+ var brickY = (c*(brickInfo.height+brickInfo.padding))+brickInfo.offset.top;
+ newBrick = game.add.sprite(brickX, brickY, 'brick');
+ game.physics.enable(newBrick, Phaser.Physics.ARCADE);
+ newBrick.body.immovable = true;
+ newBrick.anchor.set(0.5);
+ bricks.add(newBrick);
+ }
+ }
+}
+</pre>
+
+<p><font><font>如果您现在重新加载</font></font><code>index.html</code><font><font>,您应该看到在屏幕上打印的砖块彼此相距甚远。</font></font></p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p><font><font>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</font></font></p>
+
+<p> </p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/cck2b9e8/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>有些东西丢失了 </font><font>球不经停,经过砖块 - 我们需要适当的</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Collision_detection"><font><font>碰撞检测</font></font></a><font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Game_over", "Games/Workflows/2D_Breakout_game_Phaser/Collision_detection")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/buttons/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/buttons/index.html
new file mode 100644
index 0000000000..2b29b39714
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/buttons/index.html
@@ -0,0 +1,104 @@
+---
+title: Buttons
+slug: Games/Tutorials/2D_breakout_game_Phaser/Buttons
+tags:
+ - 2D
+ - Beginner
+ - Buttons
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Buttons
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens", "Games/Workflows/2D_Breakout_game_Phaser/Randomizing_gameplay")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第15步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson15.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson15.html</font></a><font>完成本课程后找到源代码</font></font></p>
+</div>
+
+<p><font>而不是立即开始游戏,我们可以通过添加他们可以按的开始按钮将该决定留给玩家。</font><font>我们来调查如何做到这一点。</font></p>
+
+<h2 id="新变量"><font><font>新变量</font></font></h2>
+
+<p><font>我们需要一个变量来存储表示游戏当前是否正在播放的布尔值,另一个代表我们的按钮。</font><font>将以下行添加到其他变量定义之下:</font></p>
+
+<pre class="brush: js">var playing = false;
+var startButton;
+</pre>
+
+<h2 id="加载按钮spritesheet"><font><font>加载按钮spritesheet</font></font></h2>
+
+<p><font><font>我们可以加载按钮spritesheet与我们加载球的摆动动画相同的方式。</font><font>将以下内容添加到</font></font><code>preload()</code><font><font>函数</font><font>底部</font><font>:</font></font></p>
+
+<pre class="brush: js">game.load.spritesheet('button', 'img/button.png', 120, 40);
+</pre>
+
+<p><font><font>单个按钮框架宽120像素,高40像素。</font></font></p>
+
+<p><font><font>您还需要</font></font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/img/button.png"><font><font>从Github抓取按钮spritesheet</font></font></a><font><font>,并将其保存在您的</font></font><code>/img</code><font><font>目录中。</font></font></p>
+
+<h2 id="将按钮添加到游戏中"><font><font>将按钮添加到游戏中</font></font></h2>
+
+<p><font><font>使用该</font></font><code>add.button</code><font><font>方法</font><font>可以将新的按钮添加到游戏中</font><font>。</font><font>将以下行添加到</font></font><code>create()</code><font><font>函数</font><font>的底部</font><font>:</font></font></p>
+
+<pre class="brush: js">startButton = game.add.button(game.world.width*0.5, game.world.height*0.5, 'button', startGame, this, 1, 0, 2);
+startButton.anchor.set(0.5);
+</pre>
+
+<p><font><font>该</font></font><code>button()</code><font><font>方法的参数如下:</font></font></p>
+
+<ul>
+ <li><font><font>按钮的x和y坐标</font></font></li>
+ <li><font><font>要显示按钮的图形资产的名称</font></font></li>
+ <li><font><font>按下按钮时将执行的回调函数</font></font></li>
+ <li><code>this</code><font><font>指定执行上下文的</font><font>引用</font></font></li>
+ <li><font><font>将用于</font></font><em><font><font>过度</font></font></em><font><font>,</font></font><em><font><font>超出</font></font></em><font><font>和</font></font><em><font><font>向下</font></font></em><font><font>事件</font><font>的框架</font><font>。</font></font></li>
+</ul>
+
+<div class="note">
+<p><strong><font><font>注意</font></font></strong><font><font>:超越事件与悬停相同,当指针从按钮中移出时,当按下按钮时,向下移动。</font></font></p>
+</div>
+
+<p><font><font>现在我们需要定义</font></font><code>startGame()</code><font><font>上面代码中引用</font><font>的</font><font>函数:</font></font></p>
+
+<pre class="brush: js">function startGame() {
+ startButton.destroy();
+ ball.body.velocity.set(150, -150);
+ playing = true;
+}
+</pre>
+
+<p><font><font>当按下按钮时,我们删除按钮,设置球的初始速度并将</font></font><code>playing</code><font><font>变量</font><font>设置</font><font>为</font></font><code>true</code><font><font>。</font></font></p>
+
+<p><font><font>最后对于这一部分,回到你的</font></font><code>create()</code><font><font>函数,找到</font></font><code>ball.body.velocity.set(150, -150);</code><font><font>一行,并删除它。</font><font>你只需要按下按钮时移动球,而不是之前!</font></font></p>
+
+<h2 id="在游戏开始之前仍然保持桨"><font><font>在游戏开始之前仍然保持桨</font></font></h2>
+
+<p><font><font>它按预期工作,但是当游戏尚未开始时,我们仍然可以移动桨,这看起来有点愚蠢。</font><font>为了阻止这一点,我们可以利用</font></font><code>playing</code><font><font>变量,使得桨只有在游戏开始时才能移动。</font><font>要做到这一点,调整</font></font><code>update()</code><font><font>功能如下所示:</font></font></p>
+
+<pre class="brush: js">function update() {
+ game.physics.arcade.collide(ball, paddle, ballHitPaddle);
+ game.physics.arcade.collide(ball, bricks, ballHitBrick);
+ if(playing) {
+ paddle.x = game.input.x || game.world.width*0.5;
+ }
+}
+</pre>
+
+<p>这样一来,在所有的装载和准备之后,但在实际游戏开始之前,桨是不可移动的。</p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/1rpj71k4/","","400")}}</p>
+
+<h2 id="下一步"><font><font>下一步</font></font></h2>
+
+<p><font><font>在本系列文章中我们将做的最后一件事情是,通过添加一些</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Randomizing_gameplay"><font><font>随机化</font></font></a><font><font>的方式,球从球上弹起来,</font><font>使游戏更有趣</font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens", "Games/Workflows/2D_Breakout_game_Phaser/Randomizing_gameplay")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html
new file mode 100644
index 0000000000..1977d93fb9
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/collision_detection/index.html
@@ -0,0 +1,59 @@
+---
+title: Collision detection
+slug: Games/Tutorials/2D_breakout_game_Phaser/Collision_detection
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - collision detection
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Collision_detection
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_Phaser/The_score")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第10步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson10.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson10.html</font></a><font>完成本课程后找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>现在接下来的挑战 - 球和砖块之间的碰撞检测。</font><font>幸运的是,我们可以使用物理引擎来检查单个对象(如球和桨)之间的碰撞,也可以检测对象和组之间的碰撞。</font></p>
+
+<h2 id="砖球碰撞检测"><font><font>砖/球碰撞检测</font></font></h2>
+
+<p><font><font>物理引擎使一切都变得更容易 - 我们只需要添加两个简单的代码。</font><font>首先,在你的</font></font><code>update()</code><font><font>函数中</font><font>添加一行</font><font>,检查球和砖之间的碰撞检测,如下所示:</font></font></p>
+
+<pre class="brush: js">function update() {
+ game.physics.arcade.collide(ball, paddle);
+ game.physics.arcade.collide(ball, bricks, ballHitBrick);
+ paddle.x = game.input.x || game.world.width*0.5;
+}
+</pre>
+
+<p><font><font>球的位置是根据组中所有砖的位置计算的。</font><font>第三个可选参数是发生冲突时执行的功能</font></font><code>ballHitBrick()</code><font><font>。</font><font>创建这个新功能作为代码的底部,就在结束</font></font><code>&lt;/script&gt;</code><font><font>标签</font><font>之前</font><font>,如下所示:</font></font></p>
+
+<pre class="brush: js">function ballHitBrick(ball, brick) {
+ brick.kill();
+}
+</pre>
+
+<p><font><font>就是这样!</font><font>重新加载你的代码,你应该看到新的碰撞检测工作正常。</font></font></p>
+
+<p><font><font>感谢Phaser,有两个参数传递给函数 - 第一个是球,我们在碰撞方法中明确定义,第二个是球碰撞的砖组中的单个砖。</font><font>在功能内部,我们从屏幕上删除所讨论的砖块,只需运行其</font></font><code>kill()</code><font><font>上</font><font>的</font><font>方法即可。</font></font></p>
+
+<p><font><font>您将期望在使用</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection"><font><font>纯JavaScript</font></font></a><font><font>时编写更多自己的计算机来实现碰撞检测</font><font>。</font><font>这是使用框架的好处 - 您可以为Phaser留下大量无聊的代码,并专注于制作游戏中最有趣和最有趣的部分。</font></font></p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/wwneakwf/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>我们可以打砖块并删除它们,这已经是游戏的一个很好的补充。</font><font>结果,更好地计算被毁砖增加</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/The_score"><font><font>得分</font></font></a><font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_Phaser/The_score")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html
new file mode 100644
index 0000000000..81143d4c14
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/extra_lives/index.html
@@ -0,0 +1,124 @@
+---
+title: Extra lives
+slug: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - lives
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Extra_lives
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Win_the_game", "Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第13步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson13.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson13.html</font></a><font>完成本课程后找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>我们可以通过增加生活使游戏更愉快。</font><font>在这篇文章中,我们将实施一个生活系统,以便玩家可以继续玩,直到他们失去了三个生命,而不仅仅是一个人。</font></p>
+
+<h2 id="新变量"><font><font>新变量</font></font></h2>
+
+<p>在代码中的现有添加下面添加以下新变量:</p>
+
+<pre class="brush: js">var lives = 3;
+var livesText;
+var lifeLostText;
+</pre>
+
+<p>这些分别将存储生命数,显示剩余生命数的文本标签,以及当玩家失去生命之后将在屏幕上显示的文本标签。</p>
+
+<h2 id="定义新的文本标签"><font><font>定义新的文本标签</font></font></h2>
+
+<p><font><font>定义文本看起来像我们已经在</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/The_score"><font><font>分数</font></font></a><font><font>课上</font><font>已经做</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/The_score"><font>的</font></a><font>。</font></font><code>scoreText</code><font><font>在</font></font><code>create()</code><font><font>函数</font><font>内</font><font>的现有</font><font>定义</font><font>下方添加以下行</font><font>:</font></font></p>
+
+<pre class="brush: js">livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, { font: '18px Arial', fill: '#0095DD' });
+livesText.anchor.set(1,0);
+lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', { font: '18px Arial', fill: '#0095DD' });
+lifeLostText.anchor.set(0.5);
+lifeLostText.visible = false;
+</pre>
+
+<p><font><font>在</font></font><code>livesText</code><font><font>与</font></font><code>lifeLostText</code><font><font>物体看起来非常相似的</font></font><code>scoreText</code><font><font>一个-它们定义在屏幕上的位置,显示实际文本和字体样式。</font><font>前者被锚定在其右上边缘上,与屏幕正确对齐,后者位于中心位置,两者均使用</font></font><code>anchor.set()</code><font><font>。</font></font></p>
+
+<p><font><font>该</font></font><code>lifeLostText</code><font><font>会表示,只有当生命消失,因此其知名度初始设置为</font></font><code>false</code><font><font>。</font></font></p>
+
+<h3 id="使我们的文字造型干燥"><font><font>使我们的文字造型干燥</font></font></h3>
+
+<p><font><font>正如你可能已经注意到,我们使用相同的造型为三种文本:</font></font><code>scoreText</code><font><font>,</font></font><code>livesText</code><font><font>和</font></font><code>lifeLostText</code><font><font>。</font><font>如果我们想要更改字体大小或颜色,我们必须在多个地方进行。</font><font>为了使我们更容易维护,将来我们可以创建一个单独的变量来保存我们的样式,让我们</font></font><code>textStyle</code><font><font>将其</font><font>调用</font><font>并放在文本定义之前:</font></font></p>
+
+<pre class="brush: js">textStyle = { font: '18px Arial', fill: '#0095DD' };
+</pre>
+
+<p>现在我们可以在使用文本标签的时候使用这个变量 - 更新你的代码,使文本样式的多个实例被替换为变量:</p>
+
+<pre class="brush: js">scoreText = game.add.text(5, 5, 'Points: 0', textStyle);
+livesText = game.add.text(game.world.width-5, 5, 'Lives: '+lives, textStyle);
+livesText.anchor.set(1,0);
+lifeLostText = game.add.text(game.world.width*0.5, game.world.height*0.5, 'Life lost, click to continue', textStyle);
+lifeLostText.anchor.set(0.5);
+lifeLostText.visible = false;
+</pre>
+
+<p>这样一来,改变一个变量中的字体将会将更改应用于每个使用的地方。</p>
+
+<h2 id="生活处理代码"><font><font>生活处理代码</font></font></h2>
+
+<p><font><font>为了在我们的游戏中实现生活,让我们先改变球对</font></font><code>onOutOfBounds</code><font><font>事件的影响。</font><font>而不是执行匿名函数并立即显示警报:</font></font></p>
+
+<pre class="brush: js"><s>ball.events.onOutOfBounds.add(function(){
+ alert('Game over!');
+ location.reload();
+}, this);</s>
+</pre>
+
+<p><font><font>我们将分配一个所谓的新功能</font></font><code>ballLeaveScreen</code><font><font>; </font><font>删除以前的事件处理程序(如上所示),并将其替换为以下行:</font></font></p>
+
+<pre class="brush: js">ball.events.onOutOfBounds.add(ballLeaveScreen, this);
+</pre>
+
+<p><font><font>我们想减少每次球离开帆布的人数。</font></font><code>ballLeaveScreen()</code><font><font>在代码末尾</font><font>添加</font><font>函数定义:</font></font></p>
+
+<pre class="brush: js">function ballLeaveScreen() {
+ lives--;
+ if(lives) {
+ livesText.setText('Lives: '+lives);
+ lifeLostText.visible = true;
+ ball.reset(game.world.width*0.5, game.world.height-25);
+ paddle.reset(game.world.width*0.5, game.world.height-5);
+ game.input.onDown.addOnce(function(){
+ lifeLostText.visible = false;
+ ball.body.velocity.set(150, -150);
+ }, this);
+ }
+ else {
+ alert('You lost, game over!');
+ location.reload();
+ }
+}
+</pre>
+
+<p><font><font>而不是立即打印警报,当你失去了一生,我们首先从当前的数字减去一个生命,并检查它是否是一个非零值。</font><font>如果是,那么玩家还是有一些生命剩下,可以继续玩 - 他们会看到生命中的消息,球和桨的位置将被重置在屏幕上和下一个输入(点击或触摸),消息将被隐藏球将再次开始移动。</font></font></p>
+
+<p><font><font>当可用生活数量达到零时,游戏结束,并显示游戏过期警报消息。</font></font></p>
+
+<h2 id="事件">事件</h2>
+
+<p><font><font>您可能已经注意到了</font></font><code>add()</code><font><font>,并</font></font><code>addOnce()</code><font><font>在上面的两个代码块的方法调用,并想知道它们的区别。</font><font>不同之处在于,该</font></font><code>add()</code><font><font>方法绑定给定的函数,并使其在每次事件发生时执行,同时</font></font><code>addOnce()</code><font><font>当您希望绑定函数只执行一次,然后解除绑定时有用,因此不会再次执行。</font><font>在我们的例子中,每个</font></font><code>outOfBounds</code><font><font>事件</font></font><code>ballLeaveScreen</code><font><font>都将被执行,但当球离开屏幕时,我们只想从屏幕上删除一次消息。</font></font></p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/yk1c5n0b/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>生活让游戏更加宽容 - 如果你失去一个生命,你还剩下两个,可以继续玩。</font><font>现在让我们通过添加</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens"><font><font>动画和补间来</font></font></a><font><font>扩展游戏的外观和感觉</font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Win_the_game", "Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/game_over/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/game_over/index.html
new file mode 100644
index 0000000000..d91bcc5e3b
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/game_over/index.html
@@ -0,0 +1,53 @@
+---
+title: Game over
+slug: Games/Tutorials/2D_breakout_game_Phaser/Game_over
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - game over
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Game_over
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls", "Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第8步</font></font></strong><font><font>。</font><font>在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson08.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson08.html</font></a><font>完成本课后,您可以找到源代码</font><font>。</font></font></p>
+</div>
+
+<p>为了使游戏更有趣,我们可以引入失去的能力 - 如果在到达屏幕底部边缘之前没有击球,那么这个游戏将会结束。</p>
+
+<h2 id="如何输"><font><font>如何输</font></font></h2>
+
+<p><font><font>为了提供丢失的能力,我们将禁用球与屏幕底部的碰撞。</font><font>在</font></font><code>create()</code><font><font>函数</font><font>内添加下面的代码</font><font>; </font><font>刚刚定义球的属性就好了:</font></font></p>
+
+<pre class="brush: js">game.physics.arcade.checkCollision.down = false;
+</pre>
+
+<p><font>这将使三个墙壁(顶部,左侧和右侧)弹回球,但是第四个(底部)将消失,如果桨错过,则球从屏幕上脱落。</font><font>我们需要一种方法来检测并相应地采取行动。</font><font>在以前的新的下方添加以下行:</font></p>
+
+<pre class="brush: js">ball.checkWorldBounds = true;
+ball.events.onOutOfBounds.add(function(){
+ alert('Game over!');
+ location.reload();
+}, this);
+</pre>
+
+<p><font><font>添加这些行将使得球检查世界(在我们的例子中是画布)边界并执行绑定到</font></font><code>onOutOfBounds</code><font><font>事件</font><font>的函数</font><font>。</font><font>当您点击生成的警报时,页面将被重新加载,以便您可以再次播放。</font></font></p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/436bckb7/","","400")}}</p>
+
+<h2 id="下一步"><font><font>下一步</font></font></h2>
+
+<p><font><font>现在的基本游戏就是让我们通过引入砖块来更有趣的是 - 现在是</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field"><font><font>建造砖块</font></font></a><font><font>的时候了</font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls", "Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/index.html
new file mode 100644
index 0000000000..9f283f7774
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/index.html
@@ -0,0 +1,57 @@
+---
+title: 使用Phaser开发2D breakout game
+slug: Games/Tutorials/2D_breakout_game_Phaser
+tags:
+ - Phaser
+ - 教程
+ - 游戏
+translation_of: Games/Tutorials/2D_breakout_game_Phaser
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{Next("Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework")}}</p>
+
+<p class="summary">在这个手把手的教程中,我们将使用Phaser框架制作一个使用JavaScript构建简单的MDN消除游戏。</p>
+
+<p>教程的每一步骤都会有可供修改的样品来玩,所以你可以看到开发的每一步中间步骤。 您将学到如何使用Phaser框架来实现基础游戏机制的基本知识,诸如渲染和移动图像,碰撞检测,控制机制,框架特定的帮助器功能,动画和补间,以及获胜和失败状态等。</p>
+
+<p>为了充分理解这一系列的文章,您应该确保已有基本的中级JavaScript知识。学完本教程,您将有能力用Phaser构建简单的Web游戏。</p>
+
+<p><img alt="Gameplay screen from the game MDN Breakout created with Phaser where you can use your paddle to bounce the ball and destroy the brick field, with keeping the points and lives." src="https://mdn.mozillademos.org/files/11323/mdn-breakout-phaser.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p>
+
+<h2 id="教学清单">教学清单</h2>
+
+<p>所有的课程 — 以及我们接下来将一起做的各个版本的 <a href="https://end3r.github.io/Gamedev-Phaser-Content-Kit/demos/lesson16.html">MDN Breakout game</a>  都能在 <a href="https://end3r.github.io/Gamedev-Phaser-Content-Kit/demos/">GitHub</a>上找到</p>
+
+<ol>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework">初始化框架</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Scaling">缩放</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen">加载资源并在屏幕上打印</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Move_the_ball">移动小球</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Physics">物理</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Bounce_off_the_walls">从墙上弹开</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Player_paddle_and_controls">弹块和控制</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Game_over">游戏结束</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Build_the_brick_field">建立砖块</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Collision_detection">碰撞检测</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/The_score">得分</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Win_the_game">胜利</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Extra_lives">额外生命</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Animations_and_tweens">动画与补间</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Buttons">按钮</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Randomizing_gameplay">随机游戏</a></li>
+</ol>
+
+<p>学习路线的小提示 — 最好先熟悉使用原生JavaScript进行网页游戏开发,这样可以打下坚实的基础.如果你还不熟悉原生javascript开发,我们建议你先过一遍这个系列, <a href="/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript">使用原生Javascript开发MDN消除游戏</a>.</p>
+
+<p>在那之后,你就能随意挑选框架并用在你的项目中;我们选择了Phaser这个稳定优越的框架,它有着好的支持和社区环境以及大量优秀的插件. 框架加速了开发并能帮你管理无趣的部分,让你专注于有意思的事务. 然而, 框架也有不好的地方, 所以当一些意想不到的事情发生了或者想实现一些框架没有提供的功能时,你就将需要原生的JavaScript知识了.</p>
+
+<div class="note">
+<p><strong>注意</strong>: 本系列文章可用作实际游戏开发的材料。 如果您想要使用Phaser讨论游戏开发,您还可以使用基于本教程的 <a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit">Gamedev Phaser内容套件</a>.</p>
+</div>
+
+<h2 id="Next_steps">Next steps</h2>
+
+<p>好了,那我们就开始吧!前往系列第一部分 — <a href="/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework">初始化框架</a>.</p>
+
+<p>{{Next("Games/Workflows/2D_Breakout_game_Phaser/Initialize_the_framework")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html
new file mode 100644
index 0000000000..ed6ef03718
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/initialize_the_framework/index.html
@@ -0,0 +1,90 @@
+---
+title: Initialize the framework
+slug: Games/Tutorials/2D_breakout_game_Phaser/Initialize_the_framework
+tags:
+ - Canvas
+ - HTML
+ - JavaScript
+ - Phaser
+ - 二维
+ - 入门
+ - 教程
+ - 游戏
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Initialize_the_framework
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/zh-CN/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_Phaser", "Games/Tutorials/2D_Breakout_game_Phaser/Scaling")}}</p>
+
+<div class="summary">
+<p>这是<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser教程</a>系列的第一课. 在课程完成之后,你可以在<a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson01.html">Gamedev-Phaser-Content-Kit/demos/lesson01.html</a>找到源码.</p>
+</div>
+
+<p><span class="seoSummary">在我们开始写游戏的功能之前,我们需要创建一个用来内部渲染游戏的基础架构.使用HTML就能做到 — Parser框架将生成所需的 {{htmlelement("canvas")}} 元素.</span></p>
+
+<h2 id="游戏的HTML">游戏的HTML</h2>
+
+<p>HTML文档结构非常的简单,这个游戏将整个被渲染在框架生成的{{htmlelement("canvas")}} 元素上. 拿起你最爱的编辑器,挑一个好目录,创建一个HTML文档,存成index.html,然后写下下面的代码:</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+ &lt;meta charset="utf-8" /&gt;
+ &lt;title&gt;Gamedev Phaser Workshop - lesson 01: Initialize the framework&lt;/title&gt;
+ &lt;style&gt;* { padding: 0; margin: 0; }&lt;/style&gt;
+ &lt;script src="js/phaser.min.js"&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+ var game = new Phaser.Game(480, 320, Phaser.AUTO, null, {
+ preload: preload, create: create, update: update
+ });
+ function preload() {}
+ function create() {}
+ function update() {}
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<h2 id="下载Phaser">下载Phaser</h2>
+
+<p>下面我们将下载Phaser的代码,并应用到我们的HTML文档中.</p>
+
+<ol>
+ <li>进入 <a href="http://phaser.io/download/stable">Phaser 下载页面</a>.</li>
+ <li>选择最适合你的下载项 — 我们建议选择min.js,因为它最小,而且你不太可能想去看它的源码</li>
+ <li>将Phaser的源码存到一个和index.html同级的 /js 的目录下</li>
+ <li>在上面第一个 {{htmlelement("script")}} 标签里写下phaser的路径.</li>
+</ol>
+
+<h2 id="捋一捋我们干了些啥">捋一捋我们干了些啥</h2>
+
+<p>这个时候我们在 {{htmlelement("header")}} 里定义了 {{htmlelement("charset")}} ,{{htmlelement("title")}} 和一些基础的css来重置默认的margin和padding. 我们也用 {{htmlelement("script")}} 标签向页面引入了 Phaser 源码。{{htmlelement("body ")}} 里也有一个 {{htmlelement("script")}} 标签,我们将在里面写 JavaScript 代码来渲染和控制游戏。</p>
+
+<p>{{htmlelement("canvas")}} 元素是由框架自动生成的。我们是通过 <code>Phaser.Game </code>创建一个对象并赋给了 game 变量来完成初始化的。参数的含义是:</p>
+
+<ul>
+ <li>width 和 height 设置了 {{htmlelement("canvas")}} 宽高.</li>
+ <li>渲染方式。有三个选项分别是 <code>AUTO<font face="Open Sans, arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">,</span></font></code><code>CANVAS</code> 和 <code>WEBGL</code>。我们可以指定使用 Canvas 还是 WebGL 来渲染,如果使用了 Auto 则优先使用 WebGL,如果浏览器不支持则会选择 Canvas。</li>
+ <li>{{htmlelement("canvas")}} 的 id。如果该参数有值,则使用该值作为 canvas 标签的 id,我们传入 null,则 phaser 会决定 canvas 的 id 值。</li>
+ <li>第四个参数指定了 phaser 的三个生命周期所对应的函数。我们使用相同的名字来让程序更清晰
+ <ul>
+ <li><code>preload</code> 进行资源的加载。</li>
+ <li><code>create</code> 会在资源加载完成后执行一次。</li>
+ <li><code>update</code> 会一直循环执行来处理每一帧动画。</li>
+ </ul>
+ </li>
+</ul>
+
+<h2 id="完整示例">完整示例</h2>
+
+<p>以下是第一章的完整代码,可以直接在 JSFiddle 中运行:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/h6cwzv2b/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p>现在我们已经完成了一个简单的 HTML 页面,并且学习了如何安装 Phaser, 让我们继续学习第二章: <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Scaling">scaling</a>.</p>
+
+<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_Phaser", "Games/Tutorials/2D_Breakout_game_Phaser/Scaling")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html
new file mode 100644
index 0000000000..135bcee403
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/load_the_assets_and_print_them_on_screen/index.html
@@ -0,0 +1,71 @@
+---
+title: Load the assets and print them on screen
+slug: >-
+ Games/Tutorials/2D_breakout_game_Phaser/Load_the_assets_and_print_them_on_screen
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Sprites
+ - Tutorial
+translation_of: >-
+ Games/Tutorials/2D_breakout_game_Phaser/Load_the_assets_and_print_them_on_screen
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Scaling", "Games/Workflows/2D_Breakout_game_Phaser/Move the ball")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第三步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson03.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson03.html</font></a><font>完成本课程后找到源代码</font></font></p>
+</div>
+
+<p><font>我们的游戏将围绕屏幕滚动,弹出一个桨,摧毁砖块赚取积分 - 熟悉吗?</font><font>在本文中,我们将介绍如何将sprite添加到我们的gameworld中。</font></p>
+
+<h2 id="有一个球"><font><font>有一个球</font></font></h2>
+
+<p><font><font>我们开始创建一个JavaScript变量来表示我们的球 - 在游戏初始化代码(我们的</font></font><code>var game...</code><font><font>块)和</font></font><code>preload()</code><font><font>函数</font><font>之间添加以下行</font><font>:</font></font></p>
+
+<pre class="brush: js">var ball;
+</pre>
+
+<div class="note">
+<p><strong><font><font>注意</font></font></strong><font><font>:为了本教程,我们将使用全局变量。</font><strong><font>本教程的目的是教导Phaser特定的游戏开发方法,而不是主观的最佳方法。</font></strong></font></p>
+</div>
+
+<h2 id="加载球精灵"><font><font>加载球精灵</font></font></h2>
+
+<p><font><font>使用Phaser加载图像并将其打印在我们的画布上比使用纯JavaScript容易得多。</font><font>要加载资产,我们将使用</font></font><code>game</code><font><font>由Phaser创建</font><font>的</font><font>对象,执行其</font></font><code>load.image()</code><font><font>方法。</font><font>在</font></font><code>preload()</code><font><font>函数的底部</font><font>添加以下新行</font><font>:</font></font></p>
+
+<pre class="brush: js">function preload() {
+ // ...
+ game.load.image('ball', 'img/ball.png');
+}
+</pre>
+
+<p><font><font>第一个参数是我们要提供资产的名称 - 这将在我们的游戏代码中使用,例如我们的</font></font><code>ball</code><font><font>变量名称,所以我们需要确保它是一样的。</font><font>第二个参数是图形资源的相对路径。</font><font>在我们的情况下,我们将加载我们的球的图像(请注意,文件名不一定是一致的,但我们建议,因为它使一切更容易遵循。)</font></font></p>
+
+<p><font><font>当然,要加载图像,它需要在我们的代码目录中可用。</font></font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/img/ball.png"><font><font>从Github抓住球图像</font></font></a><font><font>,并将其保存</font></font><code>/img</code><font><font>在与</font></font><code>index.html</code><font><font>文件</font><font>相同位置</font><font>的</font><font>目录中</font><font>。</font></font></p>
+
+<p><font><font>现在,要在屏幕上显示,我们将使用另一种Phaser方法</font></font><code>add.sprite()</code><font><font>:</font><font>在</font></font><code>create()</code><font><font>函数</font><font>内添加以下新的代码行</font><font>,如图所示:</font></font></p>
+
+<pre class="brush: js">function create() {
+ ball = game.add.sprite(50, 50, 'ball');
+}
+</pre>
+
+<p><font><font>这将添加球到游戏,并将其呈现在屏幕上。</font><font>前两个参数是要添加的画布的x和y坐标,第三个是我们之前定义的资产的名称。</font><font>就是这样 - 如果你加载你的</font></font><code>index.html</code><font><font>文件,你会看到已经加载并在画布上渲染的图像!</font></font></p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/98xrv9x5/","","400")}}</p>
+
+<h2 id="下一步"><font><font>下一步</font></font></h2>
+
+<p><font><font>打出球很容易; </font><font>接下来我们将尝试</font><font>在屏幕上</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Move_the_ball"><font><font>移动球</font></font></a><font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Scaling", "Games/Workflows/2D_Breakout_game_Phaser/Move the ball")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html
new file mode 100644
index 0000000000..331d02cfab
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/move_the_ball/index.html
@@ -0,0 +1,49 @@
+---
+title: Move the ball
+slug: Games/Tutorials/2D_breakout_game_Phaser/Move_the_ball
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - moving
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Move_the_ball
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Workflows/2D_Breakout_game_Phaser/Physics")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第4步</font></font></strong><font><font>。</font><font>在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson04.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson04.html</font></a><font>完成本课后,您可以找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>我们在屏幕上打印了我们的蓝色球,但它什么都不做,这样做会很酷。</font><font>本文介绍如何做到这一点。</font></p>
+
+<h2 id="在每个框架上更新球的位置"><font><font>在每个框架上更新球的位置</font></font></h2>
+
+<p><font><font>记住</font></font><code>update()</code><font><font>功能及其定义?</font><font>其中的代码在每个框架上执行,所以它是一个完美的地方,将代码更新球的位置在屏幕上。</font><font>在里面添加以下新行代码</font></font><code>update()</code><font><font>,如下所示:</font></font></p>
+
+<pre class="brush: js">function update() {
+ ball.x += 1;
+ ball.y += 1;
+}
+</pre>
+
+<p><font><font>上面的代码</font><font>在每个框架上为表示画布上的球坐标的属性</font></font><code>x</code><font><font>和</font></font><code>y</code><font><font>属性</font><font>添加</font><font>了一个。</font><font>重新加载index.html,你应该看到球在屏幕上滚动。</font></font></p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/g1cfp0vv/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>下一步是添加一些基本的碰撞检测,所以我们的球可以从墙壁反弹。</font><font>这将需要几行代码 - 一个比我们迄今为止看到的更复杂的步骤,特别是如果我们也想添加桨和砖碰撞 - 但是幸运的是Phaser使我们比我们想要使用纯粹的方法更容易做到这一点JavaScript的。</font></font></p>
+
+<p><font><font>无论如何,在我们做所有的事情之前,我们将首先介绍Phaser的</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Physics"><font><font>物理</font></font></a><font><font>引擎,并做一些设置工作。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen", "Games/Workflows/2D_Breakout_game_Phaser/Physics")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/physics/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/physics/index.html
new file mode 100644
index 0000000000..4f908a9bc2
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/physics/index.html
@@ -0,0 +1,99 @@
+---
+title: Physics
+slug: Games/Tutorials/2D_breakout_game_Phaser/Physics
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - physics
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Physics
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Move_the_ball", "Games/Workflows/2D_Breakout_game_Phaser/Bounce_off_the_walls")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第5步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson05.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson05.html</font></a><font>完成本课程后找到源代码</font></font></p>
+</div>
+
+<p><font>为了在我们的游戏中的对象之间进行正确的碰撞检测,我们将需要物理学; </font><font>本文将向您介绍Phaser中的可用内容,以及演示典型的简单设置。</font></p>
+
+<h2 id="添加物理效果"><font><font>添加物理效果</font></font></h2>
+
+<p><font><font>Phaser与三个不同的物理引擎(Arcade Physics,P2和Ninja Physics)捆绑在一起,第四个选项Box2D可作为商业插件使用。</font><font>对于像我们这样的简单游戏,我们可以使用Arcade Physics引擎。</font><font>我们不需要任何重的几何计算 - 毕竟只是一个球从墙壁和砖块弹起来。</font></font></p>
+
+<p><font><font>首先,让我们在游戏中初始化Arcade Physics引擎。</font></font><code>physics.startSystem()</code><font><font>在</font></font><code>create</code><font><font>函数</font><font>开头</font><font>添加</font><font>方法</font><font>(使其成为函数内的第一行),如下所示:</font></font></p>
+
+<pre class="brush: js">game.physics.startSystem(Phaser.Physics.ARCADE);
+</pre>
+
+<p><font><font>接下来,我们需要为物理系统启用我们的球 - 默认情况下,Phaser对象物理不启用。</font><font>在</font></font><code>create()</code><font><font>函数</font><font>底部添加以下行</font><font>:</font></font></p>
+
+<pre class="brush: js">game.physics.enable(ball, Phaser.Physics.ARCADE);
+</pre>
+
+<p><font><font>接下来,如果我们要在屏幕上移动我们的球,我们可以设置</font></font><code>velocity</code><font><font>它</font></font><code>body</code><font><font>。</font><font>再次添加以下行</font></font><code>create()</code><font><font>:</font></font></p>
+
+<pre class="brush: js">ball.body.velocity.set(150, 150);
+</pre>
+
+<h2 id="删除我们以前的更新说明"><font><font>删除我们以前的更新说明</font></font></h2>
+
+<p><font><font>记得删除添加值的我们的老方法</font></font><code>x</code><font><font>,并</font></font><code>y</code><font><font>从</font></font><code>update()</code><font><font>功能:</font></font></p>
+
+<pre class="brush: js">function update() {
+<s> ball.x += 1;</s>
+<s> ball.y += 1;</s>
+}
+</pre>
+
+<p>我们正在使用物理引擎正确处理。</p>
+
+<h2 id="最终代码检查"><font><font>最终代码检查</font></font></h2>
+
+<p>最新的代码应该如下所示:</p>
+
+<pre class="brush: js">var ball;
+
+function preload() {
+ game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
+ game.scale.pageAlignHorizontally = true;
+ game.scale.pageAlignVertically = true;
+ game.stage.backgroundColor = '#eee';
+ game.load.image('ball', 'img/ball.png');
+}
+
+function create() {
+ game.physics.startSystem(Phaser.Physics.ARCADE);
+ ball = game.add.sprite(50, 50, 'ball');
+ game.physics.enable(ball, Phaser.Physics.ARCADE);
+ ball.body.velocity.set(150, 150);
+}
+
+function update() {
+}
+</pre>
+
+<p><font><font>尝试重新加载</font></font><code>index.html</code><font><font>- 球应该在给定的方向上不断移动。</font><font>目前,物理引擎的重力和摩擦力设定为零。</font><font>增加重力将导致球落下,同时摩擦力最终会停止球。</font></font></p>
+
+<h2 id="物理效果趣味"><font><font>物理效果趣味</font></font></h2>
+
+<p><font><font>你可以用物理学来做更多的事情,例如添加</font></font><code>ball.body.gravity.y = 100;</code><font><font>你将设置球的垂直重力。</font><font>因此,它将向上发射,但是由于重力的作用而下降。</font></font></p>
+
+<p><font><font>这种功能只是冰山一角 - 有各种功能和变量可以帮助您操纵物理对象。</font><font>查看官方</font></font><a href="http://phaser.io/docs#physics"><font><font>物理文档,</font></font></a><font><font>并使用</font></font><a href="http://phaser.io/examples/v2/category/arcade-physics"><font><font>Arcade</font></font></a><font><font>和</font></font><a href="http://phaser.io/examples/v2/category/p2-physics"><font><font>P2</font></font></a><font><font>物理系统</font><font>查看大量示例</font><font>。</font></font></p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/bjto9nj8/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>现在我们可以转到下一课,看看如何让球</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Bounce_off_the_walls"><font><font>从墙上弹起</font></font></a><font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Move_the_ball", "Games/Workflows/2D_Breakout_game_Phaser/Bounce_off_the_walls")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html
new file mode 100644
index 0000000000..07ee9e7ee7
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/player_paddle_and_controls/index.html
@@ -0,0 +1,122 @@
+---
+title: Player paddle and controls
+slug: Games/Tutorials/2D_breakout_game_Phaser/Player_paddle_and_controls
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Player_paddle_and_controls
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Bounce_off_the_walls", "Games/Workflows/2D_Breakout_game_Phaser/Game_over")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第7步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson07.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson07.html</font></a><font>完成本课程后找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>我们有球从墙上移动并弹跳,但它很快变得无聊 - 没有互动!</font><font>我们需要一种介绍游戏的方法,所以在这篇文章中,我们将创建一个桨来移动并击中球。</font></p>
+
+<h2 id="渲染桨"><font><font>渲染桨</font></font></h2>
+
+<p>从框架的角度看,桨非常类似于球 - 我们需要添加一个变量来表示它,加载相关的图像资源,然后做出魔法。</p>
+
+<h3 id="装载桨"><font><font>装载桨</font></font></h3>
+
+<p><font><font>首先,添加</font></font><code>paddle</code><font><font>我们将在我们的游戏中使用的</font></font><code>ball</code><font><font>变量</font><font>,就在</font><font>变量之后:</font></font></p>
+
+<pre class="brush: js">var paddle;
+</pre>
+
+<p><font><font>然后,在该</font></font><code>preload</code><font><font>功能中,</font></font><code>paddle</code><font><font>通过添加以下新</font></font><code>load.image()</code><font><font>调用来</font><font>加载</font><font>图像</font><font>:</font></font></p>
+
+<pre class="brush: js">function preload() {
+ // ...
+ game.load.image('ball', 'img/ball.png');
+ game.load.image('paddle', 'img/paddle.png');
+}
+</pre>
+
+<h3 id="添加桨图形"><font><font>添加桨图形</font></font></h3>
+
+<p><font><font>所以我们不要忘记,在这一点上,你应该</font><font>从Github </font><font>抓住这个</font></font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/img/paddle.png"><font><font>图形</font></font></a><font><font>,并保存在你的</font></font><code>/img</code><font><font>文件夹中。</font></font></p>
+
+<h3 id="渲染桨用物理引擎"><font><font>渲染桨用物理引擎</font></font></h3>
+
+<p><font><font>接下来,我们将通过</font></font><code>add.sprite()</code><font><font>在</font></font><code>create()</code><font><font>函数中添加</font><font>以下</font><font>调用</font><font>来初始化我们的桨,将其</font><font>添加到底部:</font></font></p>
+
+<pre class="brush: js">paddle = game.add.sprite(game.world.width*0.5, game.world.height-5, 'paddle');
+</pre>
+
+<p><font><font>我们可以使用</font></font><code>world.width</code><font><font>和</font></font><code>world.height</code><font><font>值来将桨定位到我们想要的位置:</font></font><code>game.world.width*0.5</code><font><font>将在屏幕中间。</font><font>在我们这个例子中,世界和画布是一样的,但是对于其他类型的游戏,例如侧滚滚,这个世界会变大,你可以修改它来创造有趣的效果。</font></font></p>
+
+<p><font><font>你会注意到,如果你</font></font><code>index.html</code><font><font>在这一点上</font><font>重新加载</font><font>,那么桨是目前不完全在中间的。</font><font>为什么?</font><font>因为计算位置的锚总是从对象的左上角开始。</font><font>我们可以改变它,使锚在桨的宽度的中间和它的高度的底部,所以更容易将其定位在底部边缘。</font><font>添加以下新行以下的行:</font></font></p>
+
+<pre class="brush: js">paddle.anchor.set(0.5,1);
+</pre>
+
+<p><font><font>桨现在位于我们想要的地方。</font><font>现在,为了使它与球碰撞,我们必须为桨提供物理效果。</font><font>继续添加以下新行,再次在</font></font><code>create()</code><font><font>函数</font><font>的底部</font><font>:</font></font></p>
+
+<pre class="brush: js">game.physics.enable(paddle, Phaser.Physics.ARCADE);
+</pre>
+
+<p><font><font>现在,魔法可以开始发生 - 该框架可以在每个框架上检查碰撞检测。</font><font>要启用桨和球之间的碰撞检测,请将</font></font><code>collide()</code><font><font>方法</font><font>添加</font><font>到如下</font></font><code>update()</code><font><font>功能中:</font></font></p>
+
+<pre class="brush: js">function update() {
+ game.physics.arcade.collide(ball, paddle);
+}
+</pre>
+
+<p><font><font>第一个参数是我们感兴趣的对象之一 - 球 - 第二个是另一个,桨。</font><font>这有效,但不如我们预期的那样 - 当球击中桨时,桨从屏幕上掉下来!</font><font>我们想要的就是球从跳板上跳起来,而桨子停在同一个地方。</font><font>我们可以将</font></font><code>body</code><font><font>桨</font><font>设置成</font></font><code>immovable</code><font><font>球,所以当球击中它时不会移动。</font><font>为此,请在</font></font><code>create()</code><font><font>函数</font><font>底部添加以下行</font><font>:</font></font></p>
+
+<pre class="brush: js">paddle.body.immovable = true;
+</pre>
+
+<p>现在它按预期工作。</p>
+
+<h2 id="控制桨"><font><font>控制桨</font></font></h2>
+
+<p><font><font>接下来的问题是我们不能移动桨。</font><font>要做到这一点,我们可以使用系统的默认输入(鼠标或触摸,取决于平台),并将桨位置设置到位置的</font></font><code>input</code><font><font>位置。</font><font>将以下新行添加到</font></font><code>update()</code><font><font>函数中,如下所示:</font></font></p>
+
+<pre class="brush: js">function update() {
+ game.physics.arcade.collide(ball, paddle);
+ paddle.x = game.input.x;
+}
+</pre>
+
+<p><font><font>现在在每个新的一帧上,桨的</font></font><code>x</code><font><font>位置将根据输入的</font></font><code>x</code><font><font>位置进行</font><font>调整</font><font>,但是当我们开始游戏时,桨的位置不在中间。</font><font>这是因为输入位置尚未定义。</font><font>要修复,我们可以将默认位置(如果输入位置尚未定义)设置为屏幕中间。</font><font>更新上一行如下:</font></font></p>
+
+<pre class="brush: js">paddle.x = game.input.x || game.world.width*0.5;
+</pre>
+
+<p><font><font>如果您还没有这样做,请重新加载</font></font><code>index.html</code><font><font>并尝试!</font></font></p>
+
+<h2 id="定位球"><font><font>定位球</font></font></h2>
+
+<p><font><font>我们有桨按预期工作,所以我们把球放在上面。</font><font>它非常类似于定位桨 - 我们需要将其放置在屏幕中间水平和垂直的底部,与底部有一点偏移。</font><font>要按照我们想要的方式放置它,我们将把锚定位到球的正中间。</font><font>找到现有的</font><font>行,并将其替换为以下两行:</font></font><code>ball = game.add.</code><code>sprite( ... )</code></p>
+
+<pre class="brush: js">ball = game.add.sprite(game.world.width*0.5, game.world.height-25, 'ball');
+ball.anchor.set(0.5);</pre>
+
+<p><font><font>速度保持不变 - 我们只是将第二个参数的值从150改为-150,所以球将通过向上移动而不是下降来开始游戏。</font><font>查找现有</font></font><code>ball.body.velocity.set( ... )</code><font><font>行并将其更新为以下内容:</font></font></p>
+
+<pre class="brush: js">ball.body.velocity.set(150, -150);
+</pre>
+
+<p>现在球将从桨的中间开始。</p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/ogqza0ye/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>我们可以移动桨,并将球反弹,但是如果球从屏幕的底部边缘反弹,那又有什么意义?</font><font>我们来介绍丢失的可能性 - 也称为</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Game_over"><font><font>游戏</font></font></a><font><font>逻辑。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Bounce_off_the_walls", "Games/Workflows/2D_Breakout_game_Phaser/Game_over")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/randomizing_gameplay/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/randomizing_gameplay/index.html
new file mode 100644
index 0000000000..8642ed4eb7
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/randomizing_gameplay/index.html
@@ -0,0 +1,61 @@
+---
+title: Randomizing gameplay
+slug: Games/Tutorials/2D_breakout_game_Phaser/Randomizing_gameplay
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Randomizing_gameplay
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{Previous("Games/Workflows/2D_Breakout_game_Phaser/Buttons")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16中的</font><font>第</font></font><strong><font><font>16步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson16.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson16.html</font></a><font>完成本课程后找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>我们的游戏似乎已经完成了,但是如果你看起来足够近,你会发现球在整个游戏中都以相同的角度从桨上弹起。</font><font>这意味着每个游戏都非常相似。</font><font>为了解决这个问题,提高可玩性,我们应该使反弹角度更加随机,在本文中我们将介绍一下如何。</font></p>
+
+<h2 id="让篮板更随机"><font><font>让篮板更随机</font></font></h2>
+
+<p><font><font>我们可以根据撞击桨的确切位置来改变球的速度,通过</font><font>使用沿着下方的线路运行功能</font><font>来修改</font></font><code>x</code><font><font>速度</font></font><code>ballHitPaddle()</code><font><font>。</font><font>现在添加这一行到您的代码,并尝试。</font></font></p>
+
+<pre class="brush: js">function ballHitPaddle(ball, paddle) {
+ ball.animations.play('wobble');
+ ball.body.velocity.x = -1*5*(paddle.x-ball.x);
+}</pre>
+
+<p><font>这有点魔法 - 新的速度越高,桨的中心和球撞到的地方之间的距离就越大。</font><font>此外,方向(左或右)由该值确定 - 如果球击中桨的左侧,则其将向左反弹,而击球右侧将向右反弹。</font><font>最终这样做是因为对某些值进行了一些实验,您可以进行自己的实验,看看会发生什么。</font><font>这当然不是完全随机的,但它确实使游戏玩法变得更加不可预测,因此更有趣。</font></p>
+
+<h2 id="比较你的代码"><font><font>比较你的代码</font></font></h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/3yds5ege/","","400")}}</p>
+
+<h2 id="概要"><font><font>概要</font></font></h2>
+
+<p><font>你已经完成了所有的课程 - 恭喜你!</font><font>在这一点上,您将了解到Phaser的基础知识和简单2D游戏背后的逻辑。</font></p>
+
+<h3 id="练习跟随"><font><font>练习跟随</font></font></h3>
+
+<p><font><font>你可以在游戏中做更多的事情 - 添加任何你觉得最好的东西,使它更有趣和有趣。</font><font>Phaser提供的无数有用的方法的基本介绍。</font><font>以下是关于如何扩展我们的小游戏的一些建议,让您开始:</font></font></p>
+
+<ul>
+ <li><font><font>添加第二个球或桨。</font></font></li>
+ <li><font><font>改变每次命中背景的颜色。</font></font></li>
+ <li><font><font>更改图像并使用自己的图像。</font></font></li>
+ <li><font><font>如果砖块被迅速摧毁,并排排列(或您选择的其他奖金),则可获得额外的奖励积分。</font></font></li>
+ <li><font><font>创建不同砖块布局的水平。</font></font></li>
+</ul>
+
+<p><font><font>一定要检查越来越多的</font></font><a href="http://examples.phaser.io/"><font><font>示例</font></font></a><font><font>列表</font><font>和</font></font><a href="http://docs.phaser.io/"><font><font>官方文档</font></font></a><font><font>,</font><font>如果您需要任何帮助</font><font>,请访问</font></font><a href="http://www.html5gamedevs.com/forum/14-phaser/"><font><font>HTML5 Gamedevs论坛</font></font></a><font><font>。</font></font></p>
+
+<p><font><font>您也可以返回</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_breakout_game_Phaser"><font><font>本教程系列的索引页</font></font></a><font><font>。</font></font></p>
+
+<p>{{Previous("Games/Workflows/2D_Breakout_game_Phaser/Buttons")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/scaling/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/scaling/index.html
new file mode 100644
index 0000000000..063f95aba9
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/scaling/index.html
@@ -0,0 +1,64 @@
+---
+title: Scaling
+slug: Games/Tutorials/2D_breakout_game_Phaser/Scaling
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Scaling
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/zh-CN/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_Phaser/Initialize_the_framework", "Games/Tutorials/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen")}}</p>
+
+<div class="summary">
+<p>这是<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser">Gamedev Phaser教程</a>系列的第二课. 在课程完成之后,你可以在<a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson01.html">Gamedev-Phaser-Content-Kit/demos/lesson02.html</a>找到源码.</p>
+</div>
+
+<p><font>缩放是指游戏画布如何在不同的屏幕尺寸上进行显示。</font><font>我们可以在预加载阶段自动使游戏规模适合任何屏幕尺寸,之后就可以不用再担心屏幕尺寸的问题了。</font></p>
+
+<h2 id="Phaser中scale对象">Phaser中scale对象</h2>
+
+<p><font><font>Phaser中</font><font>有一个特殊的</font><font>对象:</font></font><code>scale</code>,<font><font>它包含一些特别的方法和属性。</font><font>让我们来更改一下上一节中创建的的</font></font><code>preload()</code>函数<font><font>:</font></font></p>
+
+<pre class="brush: js">function preload() {
+ game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
+ game.scale.pageAlignHorizontally = true;
+ game.scale.pageAlignVertically = true;
+}
+</pre>
+
+<p><code>scaleMode</code><font><font> 有几个不同的选项来指定 Canvas 应该如何缩放:</font></font></p>
+
+<ul>
+ <li><code>NO_SCALE</code> — 不进行任何缩放。</li>
+ <li><code>EXACT_FIT</code> — 拉伸,填充屏幕,不保留长宽比。</li>
+ <li><code>SHOW_ALL</code> — 等比缩放,填充屏幕,保留长宽比,剩余空间用黑色填充<font>。</font></li>
+ <li><code>RESIZE</code> — 动态,每次都会根据屏幕生成画布,所以你需要在游戏运行时动态的放置游戏元素。这是一种进阶的模式<font>。</font></li>
+ <li><code>USER_SCALE</code> — 自定义<font>,允许您自己计算大小和比例。这也是一种进阶的模式。</font></li>
+</ul>
+
+<p><code>preload()</code><font><font>中的其他两行代码</font></font><font><font>负责水平和垂直居中画布,所以它始终以屏幕为中心,无论大小如何。</font></font></p>
+
+<h2 id="设置背景颜色"><font><font>设置背景颜色</font></font></h2>
+
+<p><font><font>我们还可以给画布设置背景颜色来替代磨人的黑色背景。</font><font>通过更改</font></font><code>stage</code><font><font>对象的</font></font><code>backgroundColor</code><font><font>属性来添加,我们可以使用CSS颜色定义语法进行设置。</font><font>我们在刚才的代码下面添加以下代码:</font></font></p>
+
+<pre class="brush: js">game.stage.backgroundColor = '#eee';
+</pre>
+
+<h2 id="完整的代码">完整的代码</h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/6a64vecL/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>现在我们设置了我们游戏的缩放比例,让我们继续第三课,并设计出如何</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen"><font><font>加载资源并将其显示在屏幕上</font></font></a><font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_Phaser/Initialize_the_framework", "Games/Tutorials/2D_Breakout_game_Phaser/Load_the_assets_and_print_them_on_screen")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/the_score/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/the_score/index.html
new file mode 100644
index 0000000000..f71ded071f
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/the_score/index.html
@@ -0,0 +1,76 @@
+---
+title: The score
+slug: Games/Tutorials/2D_breakout_game_Phaser/The_score
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - scoring
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/The_score
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Collision_detection", "Games/Workflows/2D_Breakout_game_Phaser/Win_the_game")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第11步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson11.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson11.html</font></a><font>完成本课程后找到源代码</font><font>。</font></font></p>
+</div>
+
+<p><font>得分也可以使游戏更有趣 - 你可以尝试击败自己的高分,或者你的朋友。</font><font>在这篇文章中,我们将为我们的游戏添加一个评分系统。</font></p>
+
+<p><font><font>我们将使用一个单独的变量来存储分数和Phaser的</font></font><code>text()</code><font><font>方法将其打印到屏幕上。</font></font></p>
+
+<h2 id="新变量">新变量</h2>
+
+<p><font><font>在以前定义的之后添加两个新变量:</font></font></p>
+
+<pre class="brush: js">// ...
+var scoreText;
+var score = 0;
+</pre>
+
+<h2 id="将得分文字添加到游戏显示"><font><font>将得分文字添加到游戏显示</font></font></h2>
+
+<p><font><font>现在在</font></font><code>create()</code><font><font>函数</font><font>末尾添加这一行</font><font>:</font></font></p>
+
+<pre class="brush: js">scoreText = game.add.text(5, 5, 'Points: 0', { font: '18px Arial', fill: '#0095DD' });
+</pre>
+
+<p><font><font>该</font></font><code>text()</code><font><font>方法可以采用四个参数:</font></font></p>
+
+<ul>
+ <li><font><font>x和y坐标来绘制文本。</font></font></li>
+ <li><font><font>将呈现的实际文本。</font></font></li>
+ <li><font><font>用于呈现文本的字体样式。</font></font></li>
+</ul>
+
+<p><font><font>最后一个参数与CSS样式非常相似。</font><font>在我们的例子中,乐谱文字将为蓝色,大小为18像素,并使用Arial字体。</font></font></p>
+
+<h2 id="当砖块被破坏时更新分数"><font><font>当砖块被破坏时更新分数</font></font></h2>
+
+<p><font><font>每当球击中砖块时,我们将增加点数,更新</font></font><code>scoreText</code><font><font>显示当前得分。</font><font>这可以使用</font></font><code>setText()</code><font><font>方法 - 添加以下两行新</font></font><code>ballHitBrick()</code><font><font>功能:</font></font></p>
+
+<pre class="brush: js">function ballHitBrick(ball, brick) {
+ brick.kill();
+ score += 10;
+ scoreText.setText('Points: '+score);
+}
+</pre>
+
+<p><font><font>这是现在 - 重新加载你的,</font></font><code>index.html</code><font><font>并检查得分更新每个砖击。</font></font></p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/n8o6rhrf/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>我们现在有一个得分系统,但是如果你不能赢得,那么玩和保持分数是多少?</font><font>让我们看看我们如何能够增加胜利的状态,让我们</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Win_the_game"><font><font>赢得比赛</font></font></a><font><font>。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/Collision_detection", "Games/Workflows/2D_Breakout_game_Phaser/Win_the_game")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html
new file mode 100644
index 0000000000..acdcc8fba9
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_phaser/win_the_game/index.html
@@ -0,0 +1,59 @@
+---
+title: Win the game
+slug: Games/Tutorials/2D_breakout_game_Phaser/Win_the_game
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Phaser
+ - Tutorial
+ - winning
+translation_of: Games/Tutorials/2D_breakout_game_Phaser/Win_the_game
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/The_score", "Games/Workflows/2D_Breakout_game_Phaser/Extra_lives")}}</p>
+
+<div class="summary">
+<p><font><font>这是</font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser"><font>Gamedev Phaser教程</font></a><font> 16 </font><font>的</font></font><strong><font><font>第12步</font></font></strong><font><font>。</font><font>您可以在</font><a href="https://github.com/end3r/Gamedev-Phaser-Content-Kit/blob/gh-pages/demos/lesson12.html"><font>Gamedev-Phaser-Content-Kit / demos / lesson12.html</font></a><font>完成本课程后找到源代码</font><font>。</font></font></p>
+</div>
+
+<p>在我们的游戏中实现获胜是相当容易的:如果你碰巧摧毁所有的砖块,那么你赢了。</p>
+
+<h2 id="如何取胜?"><font><font>如何取胜?</font></font></h2>
+
+<p><font><font>将以下新代码添加到您的</font></font><code>ballHitBrick()</code><font><font>函数中:</font></font></p>
+
+<pre class="brush: js">function ballHitBrick(ball, brick) {
+ brick.kill();
+ score += 10;
+ scoreText.setText('Points: '+score);
+
+  var count_alive = 0;
+    for (i = 0; i &lt; bricks.children.length; i++) {
+     if (bricks.children[i].alive == true) {
+        count_alive++;
+     }
+    }
+    if (count_alive == 0) {
+     alert('You won the game, congratulations!');
+     location.reload();
+    }
+}
+</pre>
+
+<p><font><font>我们循环使用组中的砖块</font></font><code>bricks.children</code><font><font>,检查每个砖块的</font></font><code>.alive() </code><font><font>方法</font><font>的活力</font><font>。</font><font>如果没有更多的砖块活着,那么我们会显示一个获胜的消息,一旦警报被关闭,重新启动游戏。</font></font></p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>您可以在下面的现场演示中查看本课程的完成代码,并使用它来更好地了解它的工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/u8waa4Lx/1/","","400")}}</p>
+
+<h2 id="下一步">下一步</h2>
+
+<p><font><font>失败和获胜都是实施的,所以我们的游戏的核心游戏就完成了。</font><font>现在让我们添加一些额外的东西-我们会给玩家将3个</font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_Phaser/Extra_lives"><font><font>生活</font></font></a><font><font>的,而不是一个。</font></font></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_Phaser/The_score", "Games/Workflows/2D_Breakout_game_Phaser/Extra_lives")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.html
new file mode 100644
index 0000000000..afbfbc1908
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.html
@@ -0,0 +1,99 @@
+---
+title: 反弹的墙壁
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls")}}</p>
+
+<div class="summary">
+<p>本篇是 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a> 10节教程中的第三节。如果你完成了本篇教程之后,你可以从 <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson03.html">Gamedev-Canvas-workshop/lesson3.html</a> 看到源码。</p>
+</div>
+
+<p><span class="seoSummary">看到我们的球动起来很惊讶吧,但是它很快就从屏幕上消失了,当然我们是可以控制它的。我们会实现一些非常简单的碰撞检测(详细后面解释),使球在画布的四周反弹回来。</span></p>
+
+<h2 id="简单的碰撞">简单的碰撞</h2>
+
+<p>我们将检查球体是否与边缘接触,如果有接触我们将相应的改变它的运动方向。</p>
+
+<p>为了运算方便我们定义一个名为 ballRadius 的变量,来存储球的半径。向代码中添加一下内容:</p>
+
+<pre class="brush: js">var ballRadius = 10;</pre>
+
+<p>现在更新绘制球的 drawBall() 函数:</p>
+
+<pre class="brush: js">ctx.arc(x, y, ballRadius, 0, Math.PI*2);</pre>
+
+<h3 id="从顶部和底部弹起">从顶部和底部弹起</h3>
+
+<p>有四面墙壁可以让它反弹回来,我们先来看上面的那面墙。我们需要判断球运动的每一帧,球体是否与画布的顶部边缘接触。如果有接触,我们将会改变球体的运动方向,使它向相反的方向移动,并保证它在画布的可见范围之内。记住坐标系统的左上角,让我们开始并加以下代码:</p>
+
+<pre class="brush: js">if(y + dy &lt; 0) {
+ dy = -dy;
+}</pre>
+
+<p>如果球的纵坐标(y轴)值小于零,我们将在球体原有的运动方向上逆转。如果球体向上移动的速度是2像素/帧,现在就是向上移动速度是-2像素。这相当于此时向下移动的速度是2像素/帧。</p>
+
+<p>上面的代码将处理球与画布顶部边缘的反射,现在让我们思考一下底部边缘如何处理:</p>
+
+<pre class="brush: js">if(y + dy &gt; canvas.height) {
+ dy = -dy;
+}</pre>
+
+<p>如果球的y位置大于<code>canvas</code>的高度(记住,我们从左上角计算y值,所以顶部边缘从0开始,底部边缘在480像素),然后通过像以前那样反转y轴运动而离开底部边缘。</p>
+
+<p>我们可以将这两句冗长的代码合二为一:</p>
+
+<pre class="brush: js">if(y + dy &gt; canvas.height || y + dy &lt; 0) {
+ dy = -dy;
+}</pre>
+
+<p>如果其中一个判断为 <code>true</code>, 则反转球的运动。</p>
+
+<h3 id="从左边和右边反弹">从左边和右边反弹</h3>
+
+<p>我们有顶部和底部的边缘,所以我们来考虑一下左边和右边的边缘。 实际上非常相似,你所要做的就是颠倒<code>x</code>而不是<code>y</code>:</p>
+
+<pre class="brush: js">if(x + dx &gt; canvas.width || x + dx &lt; 0) {
+ dx = -dx;
+}
+
+if(y + dy &gt; canvas.height || y + dy &lt; 0) {
+ dy = -dy;
+}</pre>
+
+<p>你应该把上面的代码块插入到draw()函数中,就在大括号之前。</p>
+
+<h3 id="球部分消失在墙上!">球部分消失在墙上!</h3>
+
+<p>测试你的代码,你会看到我们的球碰到任一边缘都会反弹!然而,我们还发现了一个问题,当球碰撞到边缘,反弹之前:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/10432/ball-in-wall.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p>
+
+<p>这是因为我们正在计算墙和球的中心碰撞点,而我们应该围绕它的周长来做。 如果碰到墙壁,球应该会弹起来,而不是陷入墙壁一半时,所以让我们来调整一下我们的判断条件。 更新你之前添加的代码:</p>
+
+<pre class="brush: js">if(x + dx &gt; canvas.width-ballRadius || x + dx &lt; ballRadius) {
+ dx = -dx;
+}
+if(y + dy &gt; canvas.height-ballRadius || y + dy &lt; ballRadius) {
+ dy = -dy;
+}</pre>
+
+<p>当球的中心到墙的边缘之间的距离与球的半径完全相同时,它将改变运动的方向。</p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>让我们再次检查这个部分的代码与你之间有何差异:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/redj37dc/","","370")}}</p>
+
+<div class="note">
+<p><strong>练习</strong>: 尝试修改你的代码,在每次碰到墙壁时都要把球的颜色改成随机的颜色。</p>
+</div>
+
+<h2 id="下一步">下一步</h2>
+
+<p>现在我们已经到了我们的球正在移动和留在游戏板上的阶段。 在第四章中,我们将看看如何实现一个可控制的paddle - 参见<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Paddle_and_keyboard_controls">paddle和键盘控制</a>。</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html
new file mode 100644
index 0000000000..e91072bc68
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/build_the_brick_field/index.html
@@ -0,0 +1,106 @@
+---
+title: Build the brick field
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Build_the_brick_field
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Build_the_brick_field
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection")}}</p>
+
+<div class="summary">
+<p>这是 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>教程10节的第6节。您可以在完成本课程后在这里<a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson06.html">Gamedev-Canvas-workshop/lesson6.html</a>找到源代码。</p>
+</div>
+
+<p><span class="seoSummary">在修改游戏机制后,我们可以输了 — 这样这游戏看起来终于像是一个游戏了,这真是太好了。但是,如果你总是让球与墙、板碰撞的话,很快就会感到无聊的。 好游戏需要的是让球消灭砖,这就是我们即将要做的!</span></p>
+
+<h2 id="设置砖变量">设置砖变量</h2>
+
+<p>本课题的总体目标是使用一个二维数组嵌套的循环,给出砖的几行代码。首先我们需要设置一些变量定义的砖,如宽度和高度信息, 行和列,等。在之前的变量声明处加入以下几行代码。</p>
+
+<pre class="brush: js">var brickRowCount = 3;
+var brickColumnCount = 5;
+var brickWidth = 75;
+var brickHeight = 20;
+var brickPadding = 10;
+var brickOffsetTop = 30;
+var brickOffsetLeft = 30;</pre>
+
+<p>在这里,我们定义了砖的行数和列,宽度和高度,砖块之间的填充物,这样它们就不会互相接触;有一个上、左偏移量,所以它们不会从画布的边缘开始绘制。 </p>
+
+<p>我们将在一个二维数组容纳我们所有的砖。它将包含砖列(c),砖行(R),每一个包含一个对象,其中包含x和y位置,让每个砖显示在屏幕上。在变量下面添加以下代码:</p>
+
+<pre class="brush: js">var bricks = [];
+for(c=0; c&lt;brickColumnCount; c++) {
+ bricks[c] = [];
+ for(r=0; r&lt;brickRowCount; r++) {
+ bricks[c][r] = { x: 0, y: 0 };
+ }
+}</pre>
+
+<p>上面的代码将通过行和列的循环和创造新砖。注意,砖块对象稍后也将用于碰撞检测。</p>
+
+<h2 id="画砖的逻辑">画砖的逻辑</h2>
+
+<p>现在让我们创建一个函数来遍历数组中的所有砖块并在屏幕上绘制它们。. 代码如下:</p>
+
+<pre class="brush: js">function drawBricks() {
+ for(c=0; c&lt;brickColumnCount; c++) {
+ for(r=0; r&lt;brickRowCount; r++) {
+ bricks[c][r].x = 0;
+ bricks[c][r].y = 0;
+ ctx.beginPath();
+ ctx.rect(0, 0, brickWidth, brickHeight);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ }
+ }
+}</pre>
+
+<p>再次,我们遍历的行和列,给每一块砖的位置设置<code>X</code>和<code>Y</code>,我们也画布上画砖,---<code>brickwidth</code> X <code>brickheight</code> 。问题是我们都画在一个地方坐标<code>(0,0)</code>处。我们需要做的是增加一些计算,计算每个循环迭代后的砖块的x和y位置:</p>
+
+<pre class="brush: js">var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
+var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;</pre>
+
+<p>每个<code>brickX</code>位置是<code> brickWidth + brickPadding</code>,乘以列数<code>C</code>,再加上<code>brickOffsetLeft</code>;对于砖<code>brickY</code>的逻辑相同,除了名称不同,使用行数<code>R</code>,<code>brickHeight</code>,和<code>brickOffsetTop</code>。现在,每一块砖都可以放在正确的地方,排成一排,每一块砖之间都有填充物,从左上角和顶部的帆布边缘偏移。</p>
+
+<p>在设置<code>brickX</code>和<code>brickY</code>作为对应砖的坐标之后,形成了 <code>drawBricks()</code>函数的最终版本。将以下代码加在<code>drawPaddle()</code>函数后面:</p>
+
+<pre class="brush: js">function drawBricks() {
+ for(c=0; c&lt;brickColumnCount; c++) {
+ for(r=0; r&lt;brickRowCount; r++) {
+ var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
+ var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
+ bricks[c][r].x = brickX;
+ bricks[c][r].y = brickY;
+ ctx.beginPath();
+ ctx.rect(brickX, brickY, brickWidth, brickHeight);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ }
+ }
+}</pre>
+
+<h2 id="到了展现真正画砖的时候了">到了展现真正画砖的时候了</h2>
+
+<p>最后一件事就是在<code>draw()</code>中调用<code>drawBricks()</code>, 位置最好在函数开始处,在清除画布和画球之间。直接将下面代码加在<code>drawBall()</code> 处:</p>
+
+<pre class="brush: js">drawBricks();
+</pre>
+
+<h2 id="比较你的代码"> 比较你的代码</h2>
+
+<p>这样,游戏变得更有趣了 :</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/kundan333/myd4vbwg/2/","","320")}}</p>
+
+<div class="note">
+<p>练习:尝试在行或列上改变砖块数量,或者它们的位置。</p>
+</div>
+
+<h2 id="下一节">下一节</h2>
+
+<p>现在,我们有砖啦!但是球根本就没有和它们互动 —— 接下来的第七章我们将让球和砖产生碰撞: <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Collision_detection">碰撞检测</a>。</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html
new file mode 100644
index 0000000000..fe3769ee79
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/collision_detection/index.html
@@ -0,0 +1,126 @@
+---
+title: 撞击处理
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}</p>
+
+<div class="summary">
+<p>本篇为<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>10节教程中的<strong>第7节。</strong>在你完成这篇课程之后,你可以在<a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson07.html">Gamedev-Canvas-workshop/lesson7.html</a>.找到我们的源代码。</p>
+</div>
+
+<p><span class="seoSummary">我们已经在屏幕上画出了砖块,但游戏仍然没有那么有趣,因为球通过它们。我们需要考虑增加碰撞检测,这样球就可以弹击砖块并打破它们。</span></p>
+
+<p>当然,这是我们的决定如何实现的,但是计算球是否触及矩形是很困难的,因为在画布中没有辅助函数。为了这个教程,我们将尽可能地做到这一点。我们将检查球的中心是否与任何给定的砖块碰撞。这不会每次都给出一个完美的结果,而且有很多更复杂的方法来进行碰撞检测,但是这对指导你的基本概念很有效。</p>
+
+<h2 id="撞击侦测函数"><strong>撞击侦测函数</strong></h2>
+
+<p>踢掉这一切,我们想创建一个碰撞检测功能,将循环通过所有砖块,并比较每一个砖的位置与球的坐标,因为每个帧绘制。为了更好地理解代码,我们将定义用于在碰撞检测的每个循环中存储砖块对象的B变量:</p>
+
+<pre class="brush: js">function collisionDetection() {
+ for(c=0; c&lt;brickColumnCount; c++) {
+ for(r=0; r&lt;brickRowCount; r++) {
+ var b = bricks[c][r];
+ // calculations
+ }
+ }
+}</pre>
+
+<p>如果球的中心在我们的一块砖块的坐标内,我们将改变球的方向。对于球的中心在砖块内,以下四个陈述都必须是正确的:</p>
+
+<ul>
+ <li>球的X位置大于砖的X位置。</li>
+ <li>球的X位置小于砖的X位置加上它的宽度。</li>
+ <li>球的Y位置大于砖的Y位置。</li>
+ <li>球的Y位置小于砖块的Y位置加上它的高度。</li>
+</ul>
+
+<p>让我们在代码中写下:</p>
+
+<pre class="brush: js">function collisionDetection() {
+ for(c=0; c&lt;brickColumnCount; c++) {
+ for(r=0; r&lt;brickRowCount; r++) {
+ var b = bricks[c][r];
+ if(x &gt; b.x &amp;&amp; x &lt; b.x+brickWidth &amp;&amp; y &gt; b.y &amp;&amp; y &lt; b.y+brickHeight) {
+ dy = -dy;
+ }
+ }
+ }
+}</pre>
+
+<p>将上面的块添加到代码中,在 <code>keyUpHandler()</code> 函数下面。</p>
+
+<h2 id="让砖块在被撞击之后消失">让砖块在被撞击之后消失</h2>
+
+<p>上述代码将按需要工作,球改变其方向。问题是砖块留在原地。我们必须想出一个办法来摆脱那些我们已经用球打中的砖。我们可以通过添加一个额外的参数来指示我们是否想在屏幕上画每个砖块。在初始化砖块的代码的一部分中,让我们为每个砖块对象添加一个状态属性。更新代码的下面部分,如突出显示的行所示:</p>
+
+<pre class="brush: js; highlight:[5]">var bricks = [];
+for(c=0; c&lt;brickColumnCount; c++) {
+ bricks[c] = [];
+ for(r=0; r&lt;brickRowCount; r++) {
+ bricks[c][r] = { x: 0, y: 0, status: 1 };
+ }
+}</pre>
+
+<p>接下来,我们将在绘制之前在 <code>drawBricks()</code> 中检查每个砖块的 <code>status</code>属性的值-如果 <code>status</code>是 <code>1</code>,然后画它,但是如果它是 <code>0</code>,那么它被球击中,我们不再希望它在屏幕上。更新您的 <code>drawBricks()</code> 函数如下:</p>
+
+<pre class="brush: js; highlight:[4,5,6,7,8,9,10,11,12,13,14]">function drawBricks() {
+ for(c=0; c&lt;brickColumnCount; c++) {
+ for(r=0; r&lt;brickRowCount; r++) {
+ if(bricks[c][r].status == 1) {
+ var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
+ var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
+ bricks[c][r].x = brickX;
+ bricks[c][r].y = brickY;
+ ctx.beginPath();
+ ctx.rect(brickX, brickY, brickWidth, brickHeight);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ }
+ }
+ }
+}</pre>
+
+<h2 id="跟踪并更新在撞击侦测函数中的状态">跟踪并更新在撞击侦测函数中的状态</h2>
+
+<p>现在我们需要将砖块 <code>status</code> 属性包含在 <code>collisionDetection()</code>函数中:如果砖块是活动的(它的状态是 <code>1</code>),我们将检查碰撞是否发生;如果发生碰撞,我们将给定砖块的状态设置为 <code>0</code>,这样它就不会被绘制在屏幕上。更新您的 <code>collisionDetection()</code> 函数,如下所示:</p>
+
+<pre class="brush: js; highlight:[5,6,7,8,9,10]">function collisionDetection() {
+ for(c=0; c&lt;brickColumnCount; c++) {
+ for(r=0; r&lt;brickRowCount; r++) {
+ var b = bricks[c][r];
+ if(b.status == 1) {
+ if(x &gt; b.x &amp;&amp; x &lt; b.x+brickWidth &amp;&amp; y &gt; b.y &amp;&amp; y &lt; b.y+brickHeight) {
+ dy = -dy;
+ b.status = 0;
+ }
+ }
+ }
+ }
+}</pre>
+
+<h2 id="调用我们的撞击侦测函数">调用我们的撞击侦测函数</h2>
+
+<p>最后要做的是向 <code>collisionDetection()</code> 函数添加一个调用到我们的主要<code>draw()</code> 函数。将下面的行添加到 <code>draw()</code> 函数中,就在<code>drawPaddle()</code> 调用的下面:</p>
+
+<pre class="brush: js">collisionDetection();
+</pre>
+
+<h2 id="对比你的代码">对比你的代码</h2>
+
+<p>现在,在每一帧,每一块砖上都检查了球的碰撞检测。现在我们可以毁掉砖头:-!</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/kundan333/myd4vbwg/5/","","320")}}</p>
+
+<div class="note">
+<p>练习:当球碰到砖头时,改变球的颜色。</p>
+</div>
+
+<h2 id="下一节">下一节</h2>
+
+<p>我们现在肯定到了,继续前进吧!在第八章中,我们将探讨如何跟踪得分和获胜。<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Track_the_score_and_win">Track the score and win</a>.</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html
new file mode 100644
index 0000000000..59b0b70392
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/create_the_canvas_and_draw_on_it/index.html
@@ -0,0 +1,114 @@
+---
+title: 创建、绘制画布
+slug: >-
+ Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it
+translation_of: >-
+ Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball")}}</p>
+
+<div class="summary">
+<p>本篇是 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a> 10节教程中的第一节。如果你完成了本篇教程之后,你可以从 <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson01.html">Gamedev-Canvas-workshop/lesson1.html</a> 看到源码。</p>
+</div>
+
+<p><span class="seoSummary">在我们开始编写游戏功能之前,我们可以通过HTML的canvas标签创建支撑游戏的基本结构。</span></p>
+
+<h2 id="页面部分">页面部分</h2>
+
+<p>HTML文档的结构是非常简单的,我们的游戏将完全呈现在这个HTML的canvas标签中。你可以选择一款你最喜欢的文本编辑器,创建一个HTML文件,保存到你理想的位置,名称为index.html。并添加以下代码:</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+ &lt;meta charset="utf-8" /&gt;
+ &lt;title&gt;Gamedev Canvas Workshop&lt;/title&gt;
+ &lt;style&gt;
+ * { padding: 0; margin: 0; }
+ canvas { background: #eee; display: block; margin: 0 auto; }
+ &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+&lt;canvas id="myCanvas" width="480" height="320"&gt;&lt;/canvas&gt;
+
+&lt;script&gt;
+ // JavaScript code goes here
+&lt;/script&gt;
+
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>在 <span style="color: #990055;">head</span> 标签中我们需要定义字符集(charset),标题(title)和一些基本的样式。在 <span style="color: #990055;">body </span>标签中包含<span style="color: #990055;"> canvas </span>标签和 <span style="color: #990055;">javascript</span> 标签,我们将在 <span style="color: #990055;">javascript </span>标签中使用 JavaScript 代码来控制 <span style="color: #990055;">canvas</span> 标签中的内容展现。在 <span style="color: #990055;">canvas</span> 标签有一个名为 myCanvas 的 Id,根据这个属性我们可以很容易的获取到这个元素并设置他的宽为 480 像素,高为 320 像素。 之后我们会将所有的 JavaScript 代码全部写到 <span style="color: #990055;">javascript</span> 标签中(&lt;script&gt;...&lt;/script&gt;)。</p>
+
+<h2 id="画布的基本属性">画布的基本属性</h2>
+
+<p>要想在 <span style="color: #990055;">canvas</span> 标签中呈现图像内容,我们必须在 JavaScript 代码中获取到这个元素。在 <span style="color: #990055;">javascript </span>标签中添加以下代码;</p>
+
+<pre class="brush: js">var canvas = document.getElementById("myCanvas");
+var ctx = canvas.getContext("2d");</pre>
+
+<p>在这里我们可以声明一个变量保存 <span style="color: #990055;">canvas</span> 标签,然后我们需要创建变量 ctx, 这个变量可用来存储 2d 的渲染上下文,我们实际上就用它在 <span style="color: #990055;">canvas</span> 标签上绘制内容。 </p>
+
+<p>让我们来看一个例子,打印在画布上的红色正方形。添加以下代码到你的 JavaScript 里,然后在浏览器中打开 index.html 来看看效果。</p>
+
+<pre class="brush: js">ctx.beginPath();
+ctx.rect(20, 40, 50, 50);
+ctx.fillStyle = "#FF0000";
+ctx.fill();
+ctx.closePath();</pre>
+
+<p>把全部指令放到 <span style="color: #0077aa;">ctx.beginPath()</span> 方法 和 <span style="color: #0077aa;">ctx.closePath() </span>方法之间。我们使用 <span style="color: #0077aa;">ctx.rect()</span> 方法创建了一个矩形。这个方法的第一组参数(20,40)是确定这个矩形的左上角在画布上的坐标,第二组参数(50, 50)是指定矩形的宽度和高度。例子中矩形左上角的 x 坐标为20像素,y 坐标为40像素;宽和高各为50像素,这样画出一个完美的正方形。<span style="color: #0077aa;">ctx.fillStyle </span>属性是用于填充绘画的颜色,这里填充的颜色为红色。<span style="color: #0077aa;">ctx.fill()</span> 方法是填充路径的内容区域生成实心的图形。</p>
+
+<p>我们不局限于绘制矩形 — 下面这段代码会绘制出一个绿色的圆;尝试添加到 JavaScript 代码的底部,保存并刷新:</p>
+
+<pre><code>ctx.beginPath();
+ctx.arc(240, 160, 20, 0, Math.PI*2, false);
+ctx.fillStyle = "green";
+ctx.fill();
+ctx.closePath();</code></pre>
+
+<p>正如你所见,我们再一次使用了 <span style="color: #0077aa;">ctx.beginPath()</span> 方法 和 <span style="color: #0077aa;">ctx.closePath() </span>方法;在这两个方法中间,最重要的部分是 <span style="color: #0077aa;">ctx.arc() </span>方法。它需要六个参数:</p>
+
+<ul>
+ <li><code>圆心的 x</code> 和 <code>y</code> 轴坐标</li>
+ <li>半径</li>
+ <li>起始角度,结束角度。以弧度计(弧的圆形的三点钟位置是 0 度)</li>
+ <li>规定应该逆时针还是顺时针绘图。false = 顺时针,true = 逆时针。(可选)</li>
+</ul>
+
+<p><span style="color: #0077aa;">ctx.fillStyle</span> 属性的值看起来和之前不大一样。这是因为它与 CSS 一样,颜色可以指定为十六进制值也可以指定为 rgba() 函数,或者任何其他可用的颜色值函数。</p>
+
+<p>当然我们也可以不使用 <span style="color: #0077aa;">ctx.fill()</span> 函数来填充图形和颜色,用 <span style="color: #0077aa;">ctx.stroke() </span>函数来绘制定义图形的路径。试着将这段代码添加到您的JavaScript:</p>
+
+<pre class="brush: js">ctx.beginPath();
+ctx.rect(160, 10, 100, 40);
+ctx.strokeStyle = "rgba(0, 0, 255, 0.5)";
+ctx.stroke();
+ctx.closePath();</pre>
+
+<p>上面的代码绘制出一个蓝色边框的空心矩形。由于 <span style="color: #0077aa;">rgba() </span> 函数的特性,边框为蓝色半透明的状态。</p>
+
+<h2 id="比对你的代码">比对你的代码</h2>
+
+<p>以上是第一节的全部代码,可以运行在JSFiddle(在线JS代码调试工具)上:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/x62h15e2/","","370")}}</p>
+
+<div class="note">
+<p>练习:尝试改变给定几何图形的大小和颜色。</p>
+</div>
+
+<h2 id="下一节">下一节</h2>
+
+<p>现在我们已经创建了基本的HTML和关于画布的基本知识。我们继续第二节,如何让球在游戏中动起来 — <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Move_the_ball">让球动起来</a>。</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball")}}</p>
+
+<p>
+ <audio style="display: none;"> </audio>
+</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/game_over/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/game_over/index.html
new file mode 100644
index 0000000000..5256e9b632
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/game_over/index.html
@@ -0,0 +1,81 @@
+---
+title: 游戏结束
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field")}}</p>
+
+<div class="summary">
+<p>这是 <a href="/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>教程的第五章。您可以在完成本课程后在这里<a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson05.html">Gamedev-Canvas-workshop/lesson5.html</a>找到源代码。</p>
+</div>
+
+<p><span class="seoSummary">看球从墙上反弹,并能够移动球盘是很有趣的。但除此之外,游戏什么都不做,也没有任何进展或最终目标。 从游戏的角度来看,我们需要一个game over。 失败的逻辑很简单。 如果你的球拍错过了球,并且球到达屏幕的底部边缘,那么游戏就结束了。</span></p>
+
+<h2 id="实现游戏失败">实现游戏失败</h2>
+
+<p>让我们在代码中实现,下面是第三章里的一段代码,让球从墙上反弹:</p>
+
+<pre class="brush: js notranslate">if(x + dx &gt; canvas.width-ballRadius || x + dx &lt; ballRadius) {
+ dx = -dx;
+}
+
+if(y + dy &gt; canvas.height-ballRadius || y + dy &lt; ballRadius) {
+ dy = -dy;
+}</pre>
+
+<p>我们不需要让球从四面墙上反弹,应该只允许三个 - 左,上,右。 击中底部墙将结束游戏。 我们将编辑第二个if代码块,这是一个if else块,当球碰撞到画布的底部边缘时,它会触发我们的“游戏结束”状态。 现在我们将保持简单,显示一条警告消息,并通过重新加载页面重新开始游戏。</p>
+
+<p>第一步,把您最开始使用的 <code>setInterval()</code> 函数</p>
+
+<pre class="brush: js notranslate">setInterval(draw, 10);</pre>
+
+<p>替换成:</p>
+
+<pre class="brush: js notranslate">var interval = setInterval(draw, 10);</pre>
+
+<p>然后将第二个if块替换为以下内容:</p>
+
+<pre class="brush: js notranslate">if(y + dy &lt; ballRadius) {
+ dy = -dy;
+} else if(y + dy &gt; canvas.height-ballRadius) {
+ alert("GAME OVER");
+ document.location.reload();
+}</pre>
+
+<h2 id="让球拍接住球">让球拍接住球</h2>
+
+<p>本课中最后要做的是在球和球拍之间创建一些碰撞检测,以便它可以反弹并返回到游戏区域。 最简单的方法是检查球的中心是否在球拍的左边和右边之间。 再次更新您修改的代码的最后一位(第二个if块),如下所示:</p>
+
+<pre class="brush: js notranslate">if(y + dy &lt; ballRadius) {
+ dy = -dy;
+} else if(y + dy &gt; canvas.height-ballRadius) {
+ if(x &gt; paddleX &amp;&amp; x &lt; paddleX + paddleWidth) {
+ dy = -dy;
+ }
+ else {
+ alert("GAME OVER");
+ document.location.reload();
+ }
+}</pre>
+
+<p>如果球击中画布的底部边缘,我们需要检查它是否碰到球拍。 如果是的话,就像你所期望的那样反弹。 如果没有,那么游戏就像以前一样结束。</p>
+
+<h2 id="代码对比">代码对比</h2>
+
+<p>这里是完整例子,对比一下代码吧!</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/z4zy79fo/","","320")}}</p>
+
+<div class="note">
+<p><strong>练习</strong>: 当球碰到球拍时,让球移动得更快</p>
+</div>
+
+<h2 id="下一步">下一步</h2>
+
+<p>到目前为止,我们的表现相当不错,游戏变得更有趣,并且现在你可以输了! 但它仍然缺少一些东西。 让我们继续前进到第六章 - <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Build_the_brick_field">建造砖块</a> - 并创造一些砖块来消灭它们。</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/index.html
new file mode 100644
index 0000000000..68a7f25df9
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/index.html
@@ -0,0 +1,60 @@
+---
+title: 2D breakout game using pure JavaScript
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - NeedsTranslation
+ - TopicStub
+ - Tutorial
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{Next("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it")}}</p>
+
+<p class="summary">在这里我们将完全使用JavaScript语言基于HTML5的canvas标签,一步一步的绘制一个简单的MDN消除游戏。</p>
+
+<p>过程中的每一步都会有例子可供体验,让你更清晰的了解他的制作过程。你将学习到如何使用canvas标签的基本语法去实现简单游戏的渲染、动画、碰撞、控制胜负。</p>
+
+<p>为了更快速高效的学习本系列教程,你需要掌握 <a href="/en-US/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript</a> 的一些基础知识。学习完本教程之后你就可以创建自己的网页小游戏了。</p>
+
+<p><img alt="Gameplay screen from the game MDN Breakout where you can use your paddle to bounce the ball and destroy the brick field, with keeping the score and lives." src="https://mdn.mozillademos.org/files/10383/mdn-breakout-gameplay.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p>
+
+<h2 id="教程详情">教程详情</h2>
+
+<p> </p>
+
+<p>全部教程 — <a href="http://breakout.enclavegames.com/lesson10.html">MDN 消除小游戏</a> 的各个版本我们正一起管理并托管到 <a href="https://github.com/end3r/Canvas-gamedev-workshop">GitHub</a> 上:</p>
+
+<ol>
+ <li><a href="https://developer.mozilla.org/zh-CN/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it">创建、绘制画布</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball">让球动起来</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls">反弹的墙</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls">键盘操作</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over">游戏结束</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field">创建砖块</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection">撞击处理</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win">统计得分、获得胜利</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls">鼠标控制</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up">完成</a></li>
+</ol>
+
+<p>对于实现一个网页游戏而言,最好的方式是从纯 JavaScirpt 着手,那样可以让我们建立更坚实的基础。之后你可以在你的项目中选择你喜欢的框架。框架也只是用JavaScript语言实现的工具;如果你想要在项目中使用框架,你必须先了解语言本身。框架可以帮你提高开发效率并生成一些基础的内容;但是如果没有达到你的预期,你只能慢慢调试或者使用原生JavaScript去实现解决方案。 </p>
+
+<div class="note">
+<p><span style="font-size: 14px;"><strong>说明</strong></span>: 如果你对使用第三方游戏资源库开发2d网页游戏感兴趣,可以参考本系列教程的 <a href="/en-US/docs/Games/Workflows/2D_breakout_game_Phaser">2D breakout game using Phaser</a>.</p>
+</div>
+
+<div class="note">
+<p><span style="font-size: 14px;"><strong>说明</strong></span>: 本系列教程可以用作游戏开发工作室的素材资源。如果你想探讨普通的游戏开发,你可以利用<a href="https://github.com/end3r/Gamedev-Canvas-Content-Kit">Gamedev Canvas Content Kit</a>以及本教程的内容。</p>
+</div>
+
+<h2 id="下一步">下一步</h2>
+
+<p>好,让我们开始吧。第一步 — <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it">创建、绘制画布</a></p>
+
+<p>{{Next("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it")}} </p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html
new file mode 100644
index 0000000000..e035a28838
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/move_the_ball/index.html
@@ -0,0 +1,143 @@
+---
+title: 让球动起来
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball
+tags:
+ - 2D
+ - Beginner
+ - Canvas
+ - Games
+ - JavaScript
+ - Loop
+ - Tutorial
+ - movement
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<div>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}</div>
+
+<div class="summary">
+<p>本篇是 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a> 10节教程中的第二节。如果你完成了本篇教程之后,你可以从 <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson02.html">Gamedev-Canvas-workshop/lesson2.html</a> 看到源码。</p>
+</div>
+
+<p><span class="seoSummary">从上一节中你已经知道如何去绘制一个球。现在让我们使它动起来。从技术上讲,我们将在画布上绘制一个球,之后让它消失,然后在一个稍微不用的位置上再绘制一个一样的球。就想电影里的每一帧动起来的感觉。</span></p>
+
+<p>我们需要定义一个绘图函数,每次使用一组不同的变量改变球体的位置;循环调用以保持画布上每一帧不断更新。你可以使用JavaScript时间函数 {{domxref("WindowTimers.setInterval()", "setInterval()")}} 或者 {{domxref("window.requestAnimationFrame()")}}。 </p>
+
+<p>在你的HTML文件只保留前两行,删除其他所有的JavaScript代码并在 draw() 函数中添加以下内容保证每10毫秒执行一次 draw() 函数:</p>
+
+<pre class="brush: js">function draw() {
+ // drawing code
+}
+setInterval(draw, 10);</pre>
+
+<p>得益于 <code>setInterval</code> 的无限性,使得 <code>draw()</code> 函数将每10毫秒就会被调用,除非我们停止它。现在,我们来绘制小球吧,在 <code>draw()</code> 函数中添加以下内容:</p>
+
+<pre class="brush: js">ctx.beginPath();
+ctx.arc(50, 50, 10, 0, Math.PI*2);
+ctx.fillStyle = "#0095DD";
+ctx.fill();
+ctx.closePath();
+</pre>
+
+<p>现在,尝试更新你的代码,球会在每一帧画面被绘制</p>
+
+<h2 id="让球动起来">让球动起来</h2>
+
+<p>你不会注意到球正在不停地被重新刷,因为它没有移动。让我们改变这种情况。首先,我们不再使用固定位置(50,50),而是用x和y的变量来定义画布底部的起始点,然后使用这些变量来定义圆被绘制的位置。</p>
+
+<p><font><font>首先,在</font></font><code>draw()</code><font><font>函数</font><font>上方添加以下两行</font><font>,以定义</font></font><code>x</code><font><font>和</font></font><code>y</code><font><font>:</font></font></p>
+
+<pre class="brush: js">var x = canvas.width/2;
+var y = canvas.height-30;
+</pre>
+
+<p><font><font>接下来更新</font></font> <code>draw()</code> <font><font>函数,在 </font></font><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc" title="Canvas 2D API的CanvasRenderingContext2D.arc()方法将以弧度为中心的(x,y)位置的弧线添加一个圆弧,半径r从startAngle开始,并以endAngle的顺时针方向(默认为顺时针方向)终止, 。">arc()</a> </code><font><font>方法中使用 <code>x</code> 和 <code>y</code> 变量,如下面高亮行所示:</font></font></p>
+
+<pre class="brush: js; highlight:[3]">function draw() {
+ ctx.beginPath();
+ ctx.arc(x, y, 10, 0, Math.PI*2);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+}
+</pre>
+
+<p>现在到了最重要的部分:我们想要在每一帧都被绘制出来之后,给 <code>x</code> 和 <code>y</code> 添加一个较小的值,让它看起来像是在移动。让我们将这些值定义为 <code>dx</code> 和 <code>dy</code>,并将它们的值分别设为 <code>2</code> 和 <code>-2</code>。在你的 x 和 y 变量声明下方添加以下内容:</p>
+
+<pre class="brush: js">var dx = 2;
+var dy = -2;
+</pre>
+
+<p>最后要做的是在每一帧上更新 <code>x</code> 和 <code>y</code>,在每一次更新中,把球画在新的位置上。将下面的两条新线添加到你的 <code>draw()</code> 函数:</p>
+
+<pre class="brush: js; highlight:[7,8]">function draw() {
+ ctx.beginPath();
+ ctx.arc(x, y, 10, 0, Math.PI*2);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ x += dx;
+ y += dy;
+}</pre>
+
+<p>再次保存代码,并在浏览器中尝试。很好,尽管看起来球在后面留下了痕迹:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/10430/ball-trail.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p>
+
+<h2 id="在每一帧更新之前清空画布">在每一帧更新之前清空画布</h2>
+
+<p>球移动时留下了轨迹,因为我们在每一帧上都画了一个新的圆,而没有去掉之前的一个圆。不要担心,因为有一个方法来清空画布的内容:<code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clearRect" title="Canvas 2D API的CanvasRenderingContext2D.clearRect()方法将由起点(x,y)和大小(宽,高)定义的矩形中的所有像素设置为透明黑色,擦除任何先前绘制的内容。">clearRect()</a></code>。该方法有四个参数:矩形左上角的 <code>x</code> 和 <code>y</code> 坐标,以及矩形的右下角的 <code>x</code> 和 <code>y</code> 坐标。这个矩形覆盖的整个区域里,之前所画的任何内容将被清除。</p>
+
+<p>将下列高亮显示行添加到 <code>draw()</code> 函数:</p>
+
+<pre class="brush: js; highlight:[2]">function draw() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.beginPath();
+ ctx.arc(x, y, 10, 0, Math.PI*2);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ x += dx;
+ y += dy;
+}
+</pre>
+
+<p>保存您的代码并再次尝试,这次你将看到球移动后没有留下轨迹。每隔10毫秒,画布就会被清除,蓝色的圆圈(我们的球)将被绘制在一个给定的位置上,而 <code>x</code> 和 <code>y</code> 的值将在下一个帧被更新。</p>
+
+<h2 id="保持代码整洁">保持代码整洁</h2>
+
+<p>在接下来的几篇文章中,我们将在 <code>draw()</code> 函数中添加越来越多的命令,因此尽可能保持简单和整洁是很好的。让我们从把绘制球的代码移至一个单独的函数。</p>
+
+<p>用以下两个函数替换现有的 <code>draw()</code> 函数:</p>
+
+<pre class="brush: js">function drawBall() {
+ ctx.beginPath();
+ ctx.arc(x, y, 10, 0, Math.PI*2);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+}
+
+function draw() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ drawBall();
+ x += dx;
+ y += dy;
+}</pre>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>您可以在下面的实时演示中查看本文的代码,并使用它来更好地了解其工作原理:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/3x5foxb1/","","415")}}</p>
+
+<div class="summary">
+<p>练习:尝试改变移动球的速度,或者移动球的方向。</p>
+</div>
+
+<h2 id="下一步"><font><font>下一步</font></font></h2>
+
+<p><font><font>我们已经画了我们的球,并将其移动,但它仍然消失在画布的边缘。</font><font>在第三章中,我们将探讨如何使其 </font></font><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Bounce_off_the_walls">从墙壁上反弹</a>.</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/paddle_and_keyboard_controls/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/paddle_and_keyboard_controls/index.html
new file mode 100644
index 0000000000..6cd024799d
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/paddle_and_keyboard_controls/index.html
@@ -0,0 +1,122 @@
+---
+title: 球板及键盘控制
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over")}}</p>
+
+<div class="summary">
+<p>这是<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>中的第四章。完成本课程后,你可以在<a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson04.html">Gamedev-Canvas-workshop/lesson4.html</a>找到源码.</p>
+</div>
+
+<p>你可以看到球自由的、无限次的在墙壁上反弹,但是没有和我们发生任何交互。如果我们没有对它的控制操作,这仍然不是一个游戏。下面,我们新增一些用户操作:一个可以控制球的球板。</p>
+
+<h2 id="定义一个球板去接球">定义一个球板去接球</h2>
+
+<p>我们需要添加一个球板去接球:为此需要先定义一些变量。在你的代码的顶部的其它变量下方添加下列代码:</p>
+
+<pre class="brush: js">var paddleHeight = 10;
+var paddleWidth = 75;
+var paddleX = (canvas.width-paddleWidth)/2;</pre>
+
+<p>然后定义球拍的长和宽,以及为了之后的处理同时定义x轴上的初始位置。新建一个方法来在页面上描绘球板。把下列代码添加到你的<code>drawBall()方法里去</code>:</p>
+
+<pre class="brush: js">function drawPaddle() {
+ ctx.beginPath();
+ ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+}</pre>
+
+<h2 id="允许用户控制球板">允许用户控制球板</h2>
+
+<p>我们可以如愿的描绘出球板,也需让它听从用户的控制。是时候实现用键盘控制它了。我们需要:</p>
+
+<ul>
+ <li>两个变量以保存左右方向键是否被按下的信息。</li>
+ <li>两个事件监控器来捕捉按键的按下和松开动作。我们需要运行一些代码以在按键被按下时可以控制球拍的移动</li>
+ <li>两个用于处理按键被按下或松开后的事件处理方法</li>
+ <li>实现左右移动球拍</li>
+</ul>
+
+<p>按键可以使用boolean变量来初始定义。在你的其它变量附近添加下列代码:</p>
+
+<pre class="brush: js">var rightPressed = false;
+var leftPressed = false;</pre>
+
+<p>这两个变量的默认值都是false,因为在开始时按键没有被按下。为了监听按键的按下动作,我们需要添加两个监听器。把下列代码添加到底部的<code>setInterval()的上一列去:</code></p>
+
+<pre class="brush: js">document.addEventListener("keydown", keyDownHandler, false);
+document.addEventListener("keyup", keyUpHandler, false);</pre>
+
+<p>当你按下任何键盘上的按键,按下事件被激活时<code>keyDownHandler()方法会被调用。对于松开时的处理也是类似的:当松开按键时keyUpHandler()方法会被调用。把下列代码添加到addEventListener()下方</code>:</p>
+
+<pre class="brush: js">function keyDownHandler(e) {
+ if(e.keyCode == 39) {
+ rightPressed = true;
+ }
+ else if(e.keyCode == 37) {
+ leftPressed = true;
+ }
+}
+
+function keyUpHandler(e) {
+ if(e.keyCode == 39) {
+ rightPressed = false;
+ }
+ else if(e.keyCode == 37) {
+ leftPressed = false;
+ }
+}</pre>
+
+<p>当按下一个按键,这个信息会被储存在一个变量中。每种情况下的相关变量都设置为<code>true</code>。 当松开按键时,对应变量被设置回<code>false</code>。</p>
+
+<p>两个函数都以一个事件作为参数,由<code>e</code>(event)变量表示。 从这里你可以得到有用的信息:keyCode属性是被按下的键的信息。 例如,keyCode为37是左箭头键,而39是右箭头键。 如果按下左键,那么leftPressed变量设置为true,当松开时,leftPressed变量设置为false。右键同理。</p>
+
+<h3 id="球拍移动逻辑">球拍移动逻辑</h3>
+
+<p>我们现在有用于存储按键,事件监听器和相关功能的信息的变量。 现在我们将看到实际的代码来使用这些变量,并在屏幕上移动球拍。 在draw()函数内部,我们将检查每一帧被渲染的同时是否按下左或右键。 我们的代码如下:</p>
+
+<pre class="brush: js">if(rightPressed) {
+ paddleX += 7;
+}
+else if(leftPressed) {
+ paddleX -= 7;
+}</pre>
+
+<p>如果按一下左键,球拍将向左移动7个像素,如果按一下右键,球拍将向右移动7个像素。 目前这个功能可以正常工作,但是如果我们按任意一个键的时间太长,球拍就会从画布的边缘消失。 我们可以通过改变代码来改善这种情况,并且只能在画布的边界内移动球拍,如下所示:</p>
+
+<pre class="brush: js">if(rightPressed &amp;&amp; paddleX &lt; canvas.width-paddleWidth) {
+ paddleX += 7;
+}
+else if(leftPressed &amp;&amp; paddleX &gt; 0) {
+ paddleX -= 7;
+}</pre>
+
+<p>我们使用在<code>Canvas</code>左侧的0和右侧的<code>canvas.width-paddleWidth</code>之间的<code>paddleX</code>位置移动,这会让球拍按预期的要求移动。</p>
+
+<p>将上面的代码块添加到底部的<code>draw()</code>函数中,在右大括号的上方。</p>
+
+<p>现在唯一要做的就是在<code>draw()</code>函数内调用<code>drawPaddle()</code>函数,将其实际渲染在屏幕上。 在<code>draw()</code>函数内添加下面一行,就在调用<code>drawBall()</code>的那一行的下面:</p>
+
+<pre class="brush: js">drawPaddle();
+</pre>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>以下是我们的示例代码,以便与您进行比较:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/tgn3zscj/","","320")}}</p>
+
+<div class="note">
+<p><strong>练习</strong>: 让球拍变快变慢,或者改变它的大小。</p>
+</div>
+
+<h2 id="下一步">下一步</h2>
+
+<p>现在我们有一些类似于游戏的东西。 唯一的麻烦就是无论如何你都可以继续用球拍击球。 这一切都将在第五章中改变,<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Game_over">游戏结束</a>时,我们会为游戏添加一个最后的状态。</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/track_the_score_and_win/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/track_the_score_and_win/index.html
new file mode 100644
index 0000000000..fc39385f02
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/track_the_score_and_win/index.html
@@ -0,0 +1,92 @@
+---
+title: 跟踪得分和获胜
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}</p>
+
+<div class="summary">
+<p>本篇为<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>10节教程中的<strong>第8节。</strong>在你完成这篇课程之后,你可以在<a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson08.html">Gamedev-Canvas-workshop/lesson8.html</a>找到我们的源代码。</p>
+</div>
+
+<p><span class="seoSummary">破坏砖块真的很酷,但更酷的是,游戏可以给每个用户击破的砖块奖励分数,并保持总分。</span></p>
+
+<h2 id="计算分数">计算分数</h2>
+
+<p>如果你能在整个游戏中看到你的分数,最终你会给你的朋友留下深刻印象。你需要一个变量来记录分数。在变量的其余部分之后,将下面的内容添加到JavaScript中:</p>
+
+<pre class="brush: js">var score = 0;</pre>
+
+<p>您还需要一个 <code>drawScore()</code> 函数来创建和更新分数显示。在 <code>collisionDetection()</code> 函数之后添加以下内容:</p>
+
+<pre class="brush: js">function drawScore() {
+ ctx.font = "16px Arial";
+ ctx.fillStyle = "#0095DD";
+ ctx.fillText("Score: "+score, 8, 20);
+}</pre>
+
+<p>在画布上绘制文本类似于绘制形状。字体定义看起来与CSS中的字体定义完全一样——可以在{{domxref("CanvasRenderingContext2D.font","font()")}} 方法中设置大小和字体类型。然后使用{{domxref("CanvasRenderingContext2D.fillStyle()","fillStyle()")}} 来设置字体的颜色,{{domxref("CanvasRenderingContext2D.fillText","fillText()")}} 来设置将放置在画布上的实际文本,和其放置位置。第一个参数是文本本身——上面的代码显示当前点的数量——最后两个参数是文本将放置在画布上的坐标。</p>
+
+<p>若要在每次击中砖块时评分,则在 <code>collisionDetection()</code>中添加计分规则,以在每次检测到碰撞时增加得分变量的值。将下面突出显示的行添加到代码中:</p>
+
+<pre class="brush: js; highlight:[9]">function collisionDetection() {
+ for(var c=0; c&lt;brickColumnCount; c++) {
+ for(var r=0; r&lt;brickRowCount; r++) {
+ var b = bricks[c][r];
+ if(b.status == 1) {
+ if(x &gt; b.x &amp;&amp; x &lt; b.x+brickWidth &amp;&amp; y &gt; b.y &amp;&amp; y &lt; b.y+brickHeight) {
+ dy = -dy;
+ b.status = 0;
+ score++;
+ }
+ }
+ }
+ }
+}</pre>
+
+<p>从 <code>draw()</code> 函数调用 <code>drawScore()</code> ,使每一个新帧的分数都保持最新,在 <code>draw()</code>中添加下面的行,在 <code>drawPaddle()</code> 下面调用:</p>
+
+<pre class="brush: js">drawScore();</pre>
+
+<h2 id="当所有砖块被破坏时显示获胜消息">当所有砖块被破坏时显示获胜消息</h2>
+
+<p>收集这些点很有效,但是你不会永远添加它们-当所有的砖头都被破坏的时候呢?毕竟这是游戏的主要目的,所以如果收集到所有可用的点,你应该显示一个获胜的消息。将下面突出显示的部分添加到 <code>collisionDetection()</code> 函数中:</p>
+
+<pre class="brush: js; highlight:[10,11,12,13]">function collisionDetection() {
+ for(var c=0; c&lt;brickColumnCount; c++) {
+ for(var r=0; r&lt;brickRowCount; r++) {
+ var b = bricks[c][r];
+ if(b.status == 1) {
+ if(x &gt; b.x &amp;&amp; x &lt; b.x+brickWidth &amp;&amp; y &gt; b.y &amp;&amp; y &lt; b.y+brickHeight) {
+ dy = -dy;
+ b.status = 0;
+ score++;
+ if(score == brickRowCount*brickColumnCount) {
+ alert("YOU WIN, CONGRATULATIONS!");
+ document.location.reload();
+ }
+ }
+ }
+ }
+ }
+}</pre>
+
+<p>谢谢你做的这些,你的用户可以真正赢得游戏时,他们也摧毁了所有的砖块。当用户来到游戏还有一点非常重要,用户一旦点击了警告按钮, <code>document.location.reload()</code>函数将重新加载页面并重新启动游戏。</p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>最新的代码是这样(和工程),如果你想比较和对比它与你写的:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/2m74vr9r/1/","","395")}}</p>
+
+<div class="note">
+<p><strong>练习:在每一个砖头击破后添加更多的分数,打印出收集到的点数在游戏结束警告框中。</strong></p>
+</div>
+
+<h2 id="下一节">下一节</h2>
+
+<p>游戏到这一步看起来相当不错。在下一课中,您将通过添加鼠标控件来扩大游戏的吸引力:<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Mouse_controls">Mouse controls</a>.。</p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/收尾工作/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/收尾工作/index.html
new file mode 100644
index 0000000000..baa5a514fc
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/收尾工作/index.html
@@ -0,0 +1,113 @@
+---
+title: 收尾工作
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作
+tags:
+ - Canvas
+ - JavaScript
+ - requestAnimationFrame
+ - 入门
+ - 教程
+ - 游戏
+ - 生命
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}</p>
+
+<div class="summary">
+<p>本篇为 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial </a>10节教程中的<strong>第10节也是最后一节。</strong>完成这篇课程后,你可以在 <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson10.html">Gamedev-Canvas-workshop/lesson10.html</a> 找到我们的源代码。</p>
+</div>
+
+<p><span class="seoSummary">不管我们做什么游戏,它总是存在优化的空间。例如,我们可以为玩家多提供几条命,让他们能在发生一两次失误的情况下顺利完成游戏。或者,我们也可以在渲染代码上下工夫。</span></p>
+
+<h2 id="加入生命机制">加入生命机制</h2>
+
+<p>在游戏中实现生命机制的思路很直接。让我们先新增一个变量,用来存储其生命值。把下面这行代码和我们声明其它变量的代码放在一起:</p>
+
+<pre class="brush: js">var lives = 3;</pre>
+
+<p>在 canvas 上绘制生命值计数的做法几乎和绘制分数一样——把下面的函数添加到<code>drawScore()</code> 函数后面:</p>
+
+<pre class="brush: js">function drawLives() {
+ ctx.font = "16px Arial";
+ ctx.fillStyle = "#0095DD";
+ ctx.fillText("Lives: "+lives, canvas.width-65, 20);
+}</pre>
+
+<p>当玩家失误时,我们不立即结束游戏,而是减少生命计数,直到为零。在玩家用掉一条命后,我们也可以重置小球和球板位置。那么,在函数 <code>draw()</code> 中将下面三行:</p>
+
+<pre class="brush: js">alert("GAME OVER");
+document.location.reload();
+clearInterval(interval); // Needed for Chrome to end game
+</pre>
+
+
+
+
+
+<p>替换为下面的代码,注意到我们加入了一点点逻辑控制:</p>
+
+<pre class="brush: js">lives--;
+if(!lives) {
+ alert("GAME OVER");
+ document.location.reload();
+ clearInterval(interval); // Needed for Chrome to end game
+}
+else {
+ x = canvas.width/2;
+ y = canvas.height-30;
+ dx = 2;
+ dy = -2;
+ paddleX = (canvas.width-paddleWidth)/2;
+}</pre>
+
+<p>现在,当小球碰到屏幕底边时,我们让变量<code>lives</code> 的值减一。如果生命用尽,游戏就宣告结束;否则就重置小球与球板的位置,以及小球的速度。</p>
+
+<h3 id="渲染生命值">渲染生命值</h3>
+
+<p>现在只需在 <code>draw()</code> 函数内调用<code>drawLives()</code> 即可。让我们把它加到<code>drawScore()</code> 的下一行:</p>
+
+<pre class="brush: js">drawLives();
+</pre>
+
+<h2 id="用_requestAnimationFrame_优化渲染">用 requestAnimationFrame() 优化渲染</h2>
+
+<p>现在让我们处理一些与游戏机制无关,但与画面渲染相关的东西。和我们目前使用{{domxref("windowTimers.setInterval()", "setInterval()")}} 实现的固定帧率渲染相比,{{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} 能让浏览器更好地渲染画面。让我们把下面这行代码:</p>
+
+<pre class="brush: js">var interval = setInterval(draw, 10);</pre>
+
+<p>替换为:</p>
+
+<pre class="brush: js">draw();</pre>
+
+<p>再把代码中的每一处</p>
+
+<pre class="brush: js">clearInterval(interval); // Needed for Chrome to end game
+</pre>
+
+<p>删除。然后,在 <code>draw()</code> 函数的最下方(右花括号之前)加入下面这行代码。 它的作用是使 <code>draw()</code> 函数递归调用自身:</p>
+
+<pre class="brush: js">requestAnimationFrame(draw);</pre>
+
+<p>现在 <code>draw()</code> 函数在 <code>requestAnimationFrame()</code> 的循环中被反复调用,之先前做法最大的不同是,我们将帧率的控制权交给浏览器,而不是固定的 10 毫秒。浏览器会在适当的时机同步帧率,并且只在必要的时候才刷新渲染的图形。这使得我们的动画比之前的 <code>setInterval()</code> 方法更加流畅且高效.</p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>我们的游戏的最终版本已经完成!以上。</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/raymondjplante/dfh2tpu1/","","395")}}</p>
+
+<div class="note">
+<p><strong>练习:</strong>试着改变生命的数目和球从球板上反弹的角度。</p>
+</div>
+
+<h2 id="游戏结束——暂时看来!">游戏结束——暂时看来!</h2>
+
+<p>祝贺你——你完成了本教程的所有小节!现在,你应该已经掌握 canvas 操纵的基础和 2D 游戏背后的逻辑了。是时候去学习一些框架,继续你的游戏开发之旅了!你可以看看本系列的姊妹篇:<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_breakout_game_Phaser">用 Phaser 制作 2D 打砖块游戏</a> 或者 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/HTML5_Gamedev_Phaser_Device_Orientation">Cyber Orb built in Phaser</a> 。或者,你也可以在 <a href="https://developer.mozilla.org/en/docs/Games">MDN 游戏区</a> 中获得灵感和更多知识。</p>
+
+<p>你也可以回到<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">本教程的目录页</a>。祝编程愉快!</p>
+
+<p>{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}</p>
diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/鼠标控制/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/鼠标控制/index.html
new file mode 100644
index 0000000000..cb90cb8773
--- /dev/null
+++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/鼠标控制/index.html
@@ -0,0 +1,61 @@
+---
+title: 鼠标控制
+slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制
+tags:
+ - Canvas
+ - JavaScript
+ - 入门
+ - 操作控制
+ - 教程
+ - 游戏
+ - 鼠标
+translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up")}}</p>
+
+<div class="summary">
+<p>本篇为 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a> 10节教程中的<strong>第9节</strong>。在你完成这篇课程之后,你可以在 <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson09.html">Gamedev-Canvas-workshop/lesson9.html</a> 找到我们的源代码。</p>
+</div>
+
+<p><span class="seoSummary">这个游戏实际已经完成,现在让我们着手去润色。我们已经添加过键盘控制,而加入鼠标控制也同样简单。</span></p>
+
+<h2 id="监听鼠标移动">监听鼠标移动</h2>
+
+<p>监听鼠标移动甚至比监听按键更简单:只需监听 {{event("mousemove")}} 这个事件即可。把下面这行代码和其它事件监听代码放在一起,在 <code>keyup event</code> 的下一行:</p>
+
+<pre class="brush: js">document.addEventListener("mousemove", mouseMoveHandler, false);</pre>
+
+<h2 id="将球板移动绑定到鼠标移动">将球板移动绑定到鼠标移动</h2>
+
+<p>我们可以根据鼠标光标位置来更新球板位置——下面这个函数正是做这件事的。把这个函数加到你的代码中,接在你刚刚加入的那行后面:</p>
+
+<pre class="brush: js">function mouseMoveHandler(e) {
+ var relativeX = e.clientX - canvas.offsetLeft;
+ if(relativeX &gt; 0 &amp;&amp; relativeX &lt; canvas.width) {
+ paddleX = relativeX - paddleWidth/2;
+ }
+}</pre>
+
+<p>在这个函数中,我们首先计算 <code>relativeX</code> 的值,它等于鼠标在视窗中的水平位置 (<code>e.clientX</code>) 减去 canvas 元素左边框到视窗左边框的距离 (<code>canvas.offsetLeft</code>) —— 这就得到了 canvas 元素左边框到鼠标的距离。若这个值大于零,且小于 canvas 的宽度,说明鼠标指针落在 canvas 边界内,这时就把 <code>paddleX</code> (等于球板左边缘的坐标)设为 <code>relativeX</code> 减速去球板宽度的一半。这样就确保位移是相对于球板中心进行的。</p>
+
+<p>现在球板将跟随鼠标指针。不过由于我们将球板移动限制在 canvas 大小范围内,它不会从两边完全消失。</p>
+
+<h2 id="比较你的代码">比较你的代码</h2>
+
+<p>以下是我们的示例代码,以便与您进行比较:</p>
+
+<p>{{JSFiddleEmbed("https://jsfiddle.net/raymondjplante/vt7y5hcp/","","395")}}</p>
+
+<div class="summary">
+<p>练习:调整球板移动的范围,使得整个球板总是可见,而不是在移动到边缘时被遮住一半。</p>
+</div>
+
+<h2 id="下一步">下一步</h2>
+
+<p>现在我们已经拥有一个完整的游戏。我们的系列教程将以一些细节上的调整作为<a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Finishing_up">结束。</a></p>
+
+<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up")}}</p>
diff --git a/files/zh-cn/games/tutorials/html5_gamedev_phaser_device_orientation/index.html b/files/zh-cn/games/tutorials/html5_gamedev_phaser_device_orientation/index.html
new file mode 100644
index 0000000000..e5af242f12
--- /dev/null
+++ b/files/zh-cn/games/tutorials/html5_gamedev_phaser_device_orientation/index.html
@@ -0,0 +1,449 @@
+---
+title: 2D maze game with device orientation
+slug: Games/Tutorials/HTML5_Gamedev_Phaser_Device_Orientation
+translation_of: Games/Tutorials/HTML5_Gamedev_Phaser_Device_Orientation
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<div class="summary">
+<p>在本教程中,我们将介绍构建 HTML5 移动游戏的过程。 本游戏使用 <a href="https://developer.mozilla.org/en-US/Apps/Build/gather_and_modify_data/responding_to_device_orientation_changes">Device Orientation</a> 和 <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API/Vibration">Vibration </a><strong>APIs</strong> 来增强游戏玩法,并使用 <a class="external external-icon" href="http://phaser.io/">Phaser</a> 框架构建。 为了充分理解本教程建议您先学习基础的JavaScript 知识。</p>
+</div>
+
+<h2 id="Example_game">Example game</h2>
+
+<p>在本教程结束时,您将有一个功能齐全的游戏demo:<a href="http://orb.enclavegames.com/">Cyber Orb </a>。如下所示:</p>
+
+<p><img alt="A 2D game board featuring a small yellow ball. There is a large black hole for the ball to escape down, and a number of barriers blocking the ball from escaping." src="https://mdn.mozillademos.org/files/10297/cyber-orb.png" style="display: block; height: 450px; margin: 0px auto; width: 300px;"></p>
+
+<h2 id="Phaser_framework">Phaser framework</h2>
+
+<p><a href="http://phaser.io/">Phaser</a> 是构建桌面和移动 HTML5 游戏的框架。它非常新,但由于热情的社区参与开发过程它同时也是快速增长的。您能够在<a href="https://github.com/photonstorm/phaser"> GitHub </a>查看它的开放源代码,阅读<a href="http://docs.phaser.io/"> 在线文档</a> 并浏览大量 <a href="http://examples.phaser.io/">示例 </a>。Phaser 框架为您提供了一组工具,这些工具将加快开发速度,并帮助处理完成游戏所需的一般任务,因此您可以专注于游戏创意本身。</p>
+
+<h2 id="Starting_with_the_project">Starting with the project</h2>
+
+<p>您能够在GitHub看到它的源代码 <a href="https://github.com/EnclaveGames/Cyber-Orb">Cyber Orb</a>。文件夹结构非常简单:起点是 <code>index.html</code>。 我们在该文件中初始化框架并设置 html 元素 {{htmlelement("canvas")}} 以呈现游戏。</p>
+
+<p><img alt="Screenshot of the GitHub repository with the Cyber Orb game code, listing the folders and the files in the main structure." src="https://mdn.mozillademos.org/files/10357/cyber-orb-github.png" style="height: 423px; width: 620px;"></p>
+
+
+
+<p>您可以在您最喜爱的浏览器中打开index文件以启动并尝试游戏。目录中还有三个文件夹:</p>
+
+<ul>
+ <li><code>img</code>: 我们将在游戏中使用的所有图片。</li>
+ <li><code>src</code>:定义了游戏中所有源代码的 JavaScript文件。</li>
+ <li><code>audio:</code> 在游戏中使用的声音文件。</li>
+</ul>
+
+<h2 id="Setting_up_the_Canvas">Setting up the Canvas</h2>
+
+<p>We will be rendering our game on Canvas, but we won't do it manually — this will be taken care of by the framework. Let’s set it up: our starting point is the <code>index.html</code> file with the following content. You can create this yourself if you want to follow along:</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+ &lt;meta charset="utf-8" /&gt;
+ &lt;title&gt;Cyber Orb demo&lt;/title&gt;
+ &lt;style&gt; body { margin: 0; background: #333; } &lt;/style&gt;
+ &lt;script src="src/phaser-arcade-physics.2.2.2.min.js"&gt;&lt;/script&gt;
+ &lt;script src="src/Boot.js"&gt;&lt;/script&gt;
+ &lt;script src="src/Preloader.js"&gt;&lt;/script&gt;
+ &lt;script src="src/MainMenu.js"&gt;&lt;/script&gt;
+ &lt;script src="src/Howto.js"&gt;&lt;/script&gt;
+ &lt;script src="src/Game.js"&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+(function() {
+ var game = new Phaser.Game(320, 480, Phaser.CANVAS, 'game');
+ game.state.add('Boot', Ball.Boot);
+ game.state.add('Preloader', Ball.Preloader);
+ game.state.add('MainMenu', Ball.MainMenu);
+ game.state.add('Howto', Ball.Howto);
+ game.state.add('Game', Ball.Game);
+ game.state.start('Boot');
+})();
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>So far we have a simple HTML website with some basic content in the <code>&lt;head&gt;</code> section: charset, title, CSS styling and the inclusion of the JavaScript files. The <code>&lt;body&gt;</code> contains initialization of the Phaser framework and the definitions of the game states.</p>
+
+<pre class="brush: js">var game = new Phaser.Game(320, 480, Phaser.CANVAS, 'game');</pre>
+
+<p>The line above will initialize the Phaser instance — the arguments are the width of the Canvas, height of the Canvas, rendering method (we're using <code>CANVAS</code>, but there are also <code>WEBGL</code> and <code>AUTO</code> options available) and the optional ID of the DOM container we want to put the Canvas in. If there's nothing specified in that last argument or the element is not found, the Canvas will be added to the &lt;body&gt; tag. Without the framework, to add the Canvas element to the page, you would have to write something like this inside the &lt;body&gt; tag:</p>
+
+<pre class="brush: html">&lt;canvas id='game' width='320' height='480'&gt;&lt;/canvas&gt;</pre>
+
+<p>The important thing to remember is that the framework is setting up helpful methods to speed up a lot of things like image manipulation or assets management, which would be a lot harder to do manually.</p>
+
+<div class="note">
+<p><strong>Note</strong>: You can read the <a href="http://gamedevelopment.tutsplus.com/tutorials/getting-started-with-phaser-building-monster-wants-candy--cms-21723">Building Monster Wants Candy</a> article for the in-depth introduction to the basic Phaser-specific functions and methods.</p>
+</div>
+
+<p>Back to game states: the line below is adding a new state called <code>Boot</code> to the game:</p>
+
+<pre class="brush: html">game.state.add('Boot', Ball.Boot);</pre>
+
+<p>The first value is the name of the state and the second one is the object we want to assign to it. The <code>start</code> method is starting the given state and making it active. Let's see what the states are actually.</p>
+
+<h2 id="Managing_game_states">Managing game states</h2>
+
+<p>The states in Phaser are separate parts of the game logic; in our case we’re loading them from independent JavaScript files for better maintainability. The basic states used in this game are: <code>Boot</code>, <code>Preloader</code>, <code>MainMenu</code>, <code>Howto</code> and <code>Game</code>. <code>Boot</code> will take care of initializing a few settings, <code>Preloader</code> will load all of the assets like graphics and audio, <code>MainMenu</code> is the menu with the start button, <code>Howto</code> shows the "how to play" instructions and the <code>Game</code> state lets you actually play the game. Let's quickly go though the content of those states.</p>
+
+<h3 id="Boot.js">Boot.js</h3>
+
+<p>The <code>Boot</code> state is the first one in the game.</p>
+
+<pre class="brush: js">var Ball = {
+ _WIDTH: 320,
+ _HEIGHT: 480
+};
+Ball.Boot = function(game) {};
+Ball.Boot.prototype = {
+ preload: function() {
+ this.load.image('preloaderBg', 'img/loading-bg.png');
+ this.load.image('preloaderBar', 'img/loading-bar.png');
+ },
+ create: function() {
+ this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
+ this.game.scale.pageAlignHorizontally = true;
+ this.game.scale.pageAlignVertically = true;
+ this.game.state.start('Preloader');
+ }
+};</pre>
+
+<p>The main <code>Ball</code> object is defined and we're adding two variables called <code>_WIDTH</code> and <code>_HEIGHT</code> that are the width and the height of the game Canvas — they will help us position the elements on the screen. We're loading two images first that will be used later in the <code>Preload</code> state to show the progress of loading all the other assets. The <code>create</code> function holds some basic configuration: we're setting up the scaling and alignment of the Canvas, and moving on to the <code>Preload</code> state when everything's ready.</p>
+
+<h3 id="Preloader.js">Preloader.js</h3>
+
+<p>The <code>Preloader</code> state takes care of loading all the assets:</p>
+
+<pre class="brush: js">Ball.Preloader = function(game) {};
+Ball.Preloader.prototype = {
+ preload: function() {
+ this.preloadBg = this.add.sprite((Ball._WIDTH-297)*0.5, (Ball._HEIGHT-145)*0.5, 'preloaderBg');
+ this.preloadBar = this.add.sprite((Ball._WIDTH-158)*0.5, (Ball._HEIGHT-50)*0.5, 'preloaderBar');
+ this.load.setPreloadSprite(this.preloadBar);
+
+ this.load.image('ball', 'img/ball.png');
+ // ...
+ this.load.spritesheet('button-start', 'img/button-start.png', 146, 51);
+ // ...
+ this.load.audio('audio-bounce', ['audio/bounce.ogg', 'audio/bounce.mp3', 'audio/bounce.m4a']);
+ },
+ create: function() {
+ this.game.state.start('MainMenu');
+ }
+};</pre>
+
+<p>There are single images, spritesheets and audio files loaded by the framework. In this state the <code>preloadBar</code> is showing the progress on the screen. That progress of the loaded assets is visualized by the framework with the use of one image. With every asset loaded you can see more of the <code>preloadBar</code> image: from 0% to 100%, updated on every frame. After all the assets are loaded, the <code>MainMenu</code> state is launched.</p>
+
+<h3 id="MainMenu.js">MainMenu.js</h3>
+
+<p>The <code>MainMenu</code> state shows the main menu of the game, where you can start playing by clicking the button.</p>
+
+<pre class="brush: js">Ball.MainMenu = function(game) {};
+Ball.MainMenu.prototype = {
+ create: function() {
+ this.add.sprite(0, 0, 'screen-mainmenu');
+ this.gameTitle = this.add.sprite(Ball._WIDTH*0.5, 40, 'title');
+ this.gameTitle.anchor.set(0.5,0);
+ this.startButton = this.add.button(Ball._WIDTH*0.5, 200, 'button-start', this.startGame, this, 2, 0, 1);
+ this.startButton.anchor.set(0.5,0);
+ this.startButton.input.useHandCursor = true;
+ },
+ startGame: function() {
+ this.game.state.start('Howto');
+ }
+};</pre>
+
+<p>To create a new button there's <code>add.button</code> method with the following list of optional arguments:</p>
+
+<ul>
+ <li>Top absolute position on Canvas in pixels.</li>
+ <li>Left absolute position on Canvas in pixels.</li>
+ <li>Name of the image asset the button is using.</li>
+ <li>Function that will be executed when someone clicks the button.</li>
+ <li>The execution context.</li>
+ <li>Frame from the image asset used as the button's "hover" state.</li>
+ <li>Frame from the image asset used as the button's "normal" or "out" state.</li>
+ <li>Frame from the image asset used as the button's "click" or "down" state.</li>
+</ul>
+
+<p>The <code>anchor.set</code> is setting up the anchor point on the button for which all the calculations of the position are applied. In our case it's anchored half the way from the left edge and at the start of the top edge, so it can be easily horizontally centered on the screen without the need to know its width.</p>
+
+<p>When the start button is pressed, instead of jumping directly into the action the game will show the screen with the information on how to play the game.</p>
+
+<h3 id="Howto.js">Howto.js</h3>
+
+<pre class="brush: js">Ball.Howto = function(game) {
+};
+Ball.Howto.prototype = {
+ create: function() {
+ this.buttonContinue = this.add.button(0, 0, 'screen-howtoplay', this.startGame, this);
+ },
+ startGame: function() {
+ this.game.state.start('Game');
+ }
+};</pre>
+
+<p>The <code>Howto</code> state shows the gameplay instructions on the screen before starting the game. After clicking the screen the actual game is launched.</p>
+
+<h3 id="Game.js">Game.js</h3>
+
+<p>The <code>Game</code> state from the <code>Game.js</code> file is where all the magic happens. All the initialization is in the <code>create()</code> function (launched once at the beginning of the game). After that some functionality will require further code to control — we will write our own functions to handle more complicated tasks. In particular, take note of the <code>update()</code> function (executed at every frame), which updates things such as the ball position.</p>
+
+<pre class="brush: js">Ball.Game = function(game) {};
+Ball.Game.prototype = {
+ create: function() {},
+ initLevels: function() {},
+ showLevel: function(level) {},
+ updateCounter: function() {},
+ managePause: function() {},
+ manageAudio: function() {},
+ update: function() {},
+ wallCollision: function() {},
+ handleOrientation: function(e) {},
+ finishLevel: function() {}
+};</pre>
+
+<p>The <code>create</code> and <code>update</code> functions are framework-specific, while others will be our own creations:</p>
+
+<ul>
+ <li><code>initLevels</code> initializes the level data.</li>
+ <li><code>showLevel</code> prints the level data on the screen.</li>
+ <li><code>updateCounter</code> updates the time spent playing each level and records the total time spent playing the game..</li>
+ <li><code>managePause</code> pauses and resumes the game.</li>
+ <li><code>manageAudio</code> turns the audio on and off.</li>
+ <li><code>wallCollision</code> is executed when the ball hits the walls or other objects.</li>
+ <li><code>handleOrientation</code> is the function bound to the event responsible for the Device Orientation API, providing the motion controls when the game is running on a mobile device with appropriate hardware.</li>
+ <li><code>finishLevel</code> loads a new level when the current level is completed, or finished the game if the final level is completed.</li>
+</ul>
+
+<h4 id="Adding_the_ball_and_its_motion_mechanics">Adding the ball and its motion mechanics</h4>
+
+<p>First, let’s go to the <code>create()</code> function, initialize the ball object itself and assign a few properties to it:</p>
+
+<pre class="brush: js">this.ball = this.add.sprite(this.ballStartPos.x, this.ballStartPos.y, 'ball');
+this.ball.anchor.set(0.5);
+this.physics.enable(this.ball, Phaser.Physics.ARCADE);
+this.ball.body.setSize(18, 18);
+this.ball.body.bounce.set(0.3, 0.3);</pre>
+
+<p>Here we’re adding a sprite at the given place on the screen and using the <code>'ball'</code> image from the loaded graphic assets. We’re also setting the anchor for any physics calculations to the middle of the ball, enabling the Arcade physics engine (which handles all the physics for the ball movement), and setting the size of the body for the collision detection. The <code>bounce</code> property is used to set the bounciness of the ball when it hits the obstacles.</p>
+
+<h4 id="Controlling_the_ball">Controlling the ball</h4>
+
+<p>It’s cool to have the ball ready to be thrown around in the play area, but it’s also important to be able to actually move it! Now we will add the ability to control the ball with the keyboard on the desktop devices, and then we will move to the implementation of the Device Orientation API. Let’s focus on the keyboard first by adding the following to the <code>create()</code> function :</p>
+
+<pre class="brush: js">this.keys = this.game.input.keyboard.createCursorKeys();</pre>
+
+<p>As you can see there’s a special Phaser function called <code>createCursorKeys()</code>, which will give us an object with event handlers for the four arrow keys to play with: up, down, left and right.</p>
+
+<p>Next we will add the following code to the <code>update()</code> function, so it will be fired on every frame. The <code>this.keys</code> object will be checked against player input, so the ball can react accordingly with the predefined force:</p>
+
+<pre class="brush: js">if(this.keys.left.isDown) {
+ this.ball.body.velocity.x -= this.movementForce;
+}
+else if(this.keys.right.isDown) {
+ this.ball.body.velocity.x += this.movementForce;
+}
+if(this.keys.up.isDown) {
+ this.ball.body.velocity.y -= this.movementForce;
+}
+else if(this.keys.down.isDown) {
+ this.ball.body.velocity.y += this.movementForce;
+}</pre>
+
+<p>That way we can check which key is pressed at the given frame and apply the defined force to the ball, thus increase the velocity in the proper direction.</p>
+
+<h4 id="Implementing_the_Device_Orientation_API">Implementing the Device Orientation API</h4>
+
+<p>Probably the most interesting part of the game is its usage of the <strong>Device Orientation API</strong> for control on mobile devices. Thanks to this you can play the game by tilting the device in the direction you want the ball to roll. Here’s the code from the <code>create()</code> function responsible for this:</p>
+
+<pre class="brush: js">window.addEventListener("deviceorientation", this.handleOrientation, true);</pre>
+
+<p>We’re adding an event listener to the <code>"deviceorientation"</code> event and binding the <code>handleOrientation</code> function which looks like this:</p>
+
+<pre class="brush: js">handleOrientation: function(e) {
+ var x = e.gamma;
+ var y = e.beta;
+ Ball._player.body.velocity.x += x;
+ Ball._player.body.velocity.y += y;
+},</pre>
+
+<p>The more you tilt the device, the more force is applied to the ball, therefore the faster it moves (the velocity is higher).</p>
+
+<p><img alt="An explanation of the X, Y and Z axes of a Flame mobile device with the Cyber Orb game demo on the screen." src="https://mdn.mozillademos.org/files/10369/cyber-orb-flame-orientation.png" style="height: 480px; width: 620px;"></p>
+
+<div class="note">
+<p><strong>Note</strong>: To find more out about implementing device orientation and what raw code would look like, read <a href="/en-US/Apps/Build/gather_and_modify_data/responding_to_device_orientation_changes">Keep it level: responding to device orientation changes</a>.</p>
+</div>
+
+<h4 id="Adding_the_hole">Adding the hole</h4>
+
+<p>The main objective in the game is to move the ball from the starting position to the ending position: a hole in the ground. Implementation looks very similar to the part where we created the ball, and it's also added in the <code>create()</code> function of our <code>Game</code> state:</p>
+
+<pre class="brush: js">this.hole = this.add.sprite(Ball._WIDTH*0.5, 90, 'hole');
+this.physics.enable(this.hole, Phaser.Physics.ARCADE);
+this.hole.anchor.set(0.5);
+this.hole.body.setSize(2, 2);</pre>
+
+<p>The difference is that our hole’s body will not move when we hit it with the ball and will have the collision detection calculated (which will be discussed later on in this article).</p>
+
+<h4 id="Building_the_block_labyrinth">Building the block labyrinth</h4>
+
+<p>To make the game harder and more interesting we will add some obstacles between the ball and the exit. We could use a level editor, but for the sake of this tutorial let's create something on our own.</p>
+
+<p>To hold the block information we'll use a level data array: for each block we'll store the top and left absolute positions in pixels (<code>x</code> and <code>y</code>) and the type of the block — horizontal or vertical (<code>t</code> with the <code>'w'</code> value meaning width and <code>'h'</code> meaning height). Then, to load the level we'll parse the data and show the blocks specific for that level. In the <code>initLevels</code> function we have:</p>
+
+<pre class="brush: js">this.levelData = [
+ [
+ { x: 96, y: 224, t: 'w' }
+ ],
+ [
+ { x: 72, y: 320, t: 'w' },
+ { x: 200, y: 320, t: 'h' },
+ { x: 72, y: 150, t: 'w' }
+ ],
+ // ...
+];</pre>
+
+<p>Every array element holds a collection of blocks with an <code>x</code> and <code>y</code> position and <code>t</code> value for each. After <code>levelData</code>, but still in the <code>initLevels</code> function, we're adding the blocks into an array in the <code>for</code> loop using some of the framework-specific methods:</p>
+
+<pre class="brush: js">for(var i=0; i&lt;this.maxLevels; i++) {
+ var newLevel = this.add.group();
+ newLevel.enableBody = true;
+ newLevel.physicsBodyType = Phaser.Physics.ARCADE;
+ for(var e=0; e&lt;this.levelData[i].length; e++) {
+ var item = this.levelData[i][e];
+ newLevel.create(item.x, item.y, 'element-'+item.t);
+ }
+ newLevel.setAll('body.immovable', true);
+ newLevel.visible = false;
+ this.levels.push(newLevel);
+}</pre>
+
+<p>First, <code>add.group()</code> is used to create a new group of items. Then the <code>ARCADE</code> body type is set for that group to enable physics calculations. The <code>newLevel.create</code> method creates new items in the group with starting left and top positions, and its own image. If you don't want to loop through the list of items again to add a property to every single one explicitly, you can use <code>setAll</code> on a group to apply it to all the items in that group.</p>
+
+<p>The objects are stored in the <code>this.levels</code> array, which is by default invisible. To load specific levels, we make sure the previous levels are hidden, and show the current one:</p>
+
+<pre class="brush: js">showLevel: function(level) {
+ var lvl = level | this.level;
+ if(this.levels[lvl-2]) {
+ this.levels[lvl-2].visible = false;
+ }
+ this.levels[lvl-1].visible = true;
+}</pre>
+
+<p>Thanks to that the game gives the player a challenge - now he have to roll the ball across the play area and guide it through the labyrinth built from the blocks. It's just an example of loading the levels, and there are only 5 of them just to showcase the idea, but you can work on expanding that on your own.</p>
+
+<h4 id="Collision_detection">Collision detection</h4>
+
+<p>At this point we've got the ball that is controlled by the player, the hole to reach and the obstacles blocking the way. There’s a problem though — our game doesn’t have any collision detection yet, so nothing happens when the ball hits the blocks — it just goes through. Let’s fix it! The good news is that the framework will take care of calculating the collision detection, we only have to specify the colliding objects in the <code>update()</code> function:</p>
+
+<pre class="brush: js">this.physics.arcade.collide(this.ball, this.borderGroup, this.wallCollision, null, this);
+this.physics.arcade.collide(this.ball, this.levels[this.level-1], this.wallCollision, null, this);</pre>
+
+<p>This will tell the framework to execute the <code>wallCollision</code> function when the ball hits any of the walls. We can use the <code>wallCollision</code> function to add any functionality we want like playing the bounce sound and implementing the <strong>Vibration API</strong>.</p>
+
+<h4 id="Adding_the_sound">Adding the sound</h4>
+
+<p>Among the preloaded assets there was an audio track (in various formats for browser compatibility), which we can use now. It has to be defined in the <code>create()</code> function first:</p>
+
+<pre class="brush: js">this.bounceSound = this.game.add.audio('audio-bounce');</pre>
+
+<p>If the status of the audio is <code>true</code> (so the sounds in the game are enabled), we can play it in the <code>wallCollision</code> function:</p>
+
+<pre class="brush: js">if(this.audioStatus) {
+ this.bounceSound.play();
+}</pre>
+
+<p>That's all — loading and playing the sounds is easy with Phaser.</p>
+
+<h4 id="Implementing_the_Vibration_API">Implementing the Vibration API</h4>
+
+<p>When collision detection works as expected let's add some special effects with the help from the Vibration API.</p>
+
+<p><img alt="A visualization of the vibrations of a Flame mobile device with the Cyber Orb game demo on the screen." src="https://mdn.mozillademos.org/files/10371/cyber-orb-flame-vibration.png" style="height: 480px; width: 620px;"></p>
+
+<p>The best way to use it in our case is to vibrate the phone every time the ball hits the walls — inside the <code>wallCollision</code> function:</p>
+
+<pre class="brush: js">if("vibrate" in window.navigator) {
+ window.navigator.vibrate(100);
+}</pre>
+
+<p>If the <code>vibrate</code> method is supported by the browser and available in the <code>window.navigator</code> object, vibrate the phone for 100 miliseconds. That's it!</p>
+
+<h4 id="Adding_the_elapsed_time">Adding the elapsed time</h4>
+
+<p>To improve replayability and give players the option to compete with each other we will store the elapsed time — players can then try to improve on their best game completion time. To implement this we have to create a variable for storing the actual number of seconds elapsed from the start of the game, and to show it for the player in the game. Let’s define the variables in the <code>create</code> function first:</p>
+
+<pre class="brush: js">this.timer = 0; // time elapsed in the current level
+this.totalTimer = 0; // time elapsed in the whole game</pre>
+
+<p>Then, right after that, we can initialize the necessary text objects to display this information to the user:</p>
+
+<pre class="brush: js">this.timerText = this.game.add.text(15, 15, "Time: "+this.timer, this.fontBig);
+this.totalTimeText = this.game.add.text(120, 30, "Total time: "+this.totalTimer, this.fontSmall);</pre>
+
+<p>We’re defining the top and left positions of the text, the content that will be shown and the styling applied to the text. We have this printed out on the screen, but it would be good to update the values every second:</p>
+
+<pre class="brush: js">this.time.events.loop(Phaser.Timer.SECOND, this.updateCounter, this);</pre>
+
+<p>This loop, also in the <code>create</code> function, will execute the <code>updateCounter</code> function every single second from the beginning of the game, so we can apply the changes accordingly. This is how the complete <code>updateCounter</code> function looks:</p>
+
+<pre class="brush: js">updateCounter: function() {
+ this.timer++;
+ this.timerText.setText("Time: "+this.timer);
+ this.totalTimeText.setText("Total time: "+(this.totalTimer+this.timer));
+},</pre>
+
+<p>As you can see we’re incrementing the <code>this.timer</code> variable and updating the content of the text objects with the current values on each iteration, so the player sees the elapsed time.</p>
+
+<h4 id="Finishing_the_level_and_the_game">Finishing the level and the game</h4>
+
+<p>The ball is rolling on the screen, the timer is working and we have the hole created that we have to reach. Now let’s set up the possibility to actually finish the level! The following line in the <code>update()</code> function adds a listener that fires when the ball gets to the hole.</p>
+
+<pre class="brush: js">this.physics.arcade.overlap(this.ball, this.hole, this.finishLevel, null, this);</pre>
+
+<p>This works similarly to the <code>collide</code> method explained earlier. When the ball overlaps with the hole (instead of colliding), the <code>finishLevel</code> function is executed:</p>
+
+<pre class="brush: js">finishLevel: function() {
+ if(this.level &gt;= this.maxLevels) {
+ this.totalTimer += this.timer;
+ alert('Congratulations, game completed!\nTotal time of play: '+this.totalTimer+' seconds!');
+ this.game.state.start('MainMenu');
+ }
+ else {
+ alert('Congratulations, level '+this.level+' completed!');
+ this.totalTimer += this.timer;
+ this.timer = 0;
+ this.level++;
+ this.timerText.setText("Time: "+this.timer);
+ this.totalTimeText.setText("Total time: "+this.totalTimer);
+ this.levelText.setText("Level: "+this.level+" / "+this.maxLevels);
+ this.ball.body.x = this.ballStartPos.x;
+ this.ball.body.y = this.ballStartPos.y;
+ this.ball.body.velocity.x = 0;
+ this.ball.body.velocity.y = 0;
+ this.showLevel();
+ }
+},</pre>
+
+<p>If the current level is equal to the maximum number of levels (in this case 5), then the game is finished — you'll get a congratulations message along with the number of seconds elapsed through the whole game, and a button to press that takes you to the main menu.</p>
+
+<p>If the current level is lower than 5, all the neccesary variables are reset and the next level is loaded.</p>
+
+<h2 id="Ideas_for_new_features">Ideas for new features</h2>
+
+<p>This is merely a working demo of a game that could have lots of additional features. We can for example add power-ups to collect along the way that will make our ball roll faster, stop the timer for a few seconds or give the ball special powers to go through obstacles. There’s also room for the traps which will slow the ball down or make it more difficult to reach the hole. You can create more levels of increasing difficulty. You can even implement achievements, leaderboards and medals for different actions in the game. There are endless possibilities — they only depend on your imagination.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>I hope this tutorial will help you dive into 2D game development and inspire you to create awesome games on your own. You can play the demo game <a href="http://orb.enclavegames.com/">Cyber Orb</a> and check out its <a href="https://github.com/EnclaveGames/Cyber-Orb">source code on GitHub</a>.</p>
+
+<p>HTML5 gives us raw tools, the frameworks built on top of it are getting faster and better, so now is a great time get into web game development. In this tutorial we used Phaser, but there are a number of <a href="http://html5devstarter.enclavegames.com/#frameworks">other frameworks</a> worth considering too like <a href="http://impactjs.com/">ImpactJS</a>, <a href="https://www.scirra.com/construct2">Construct 2</a> or <a href="http://playcanvas.com/">PlayCanvas</a> — it depends on your preferences, coding skills (or lack thereof), project scale, requirements and other aspects. You should check them all out and decide which one suits your needs best.</p>
diff --git a/files/zh-cn/games/tutorials/index.html b/files/zh-cn/games/tutorials/index.html
new file mode 100644
index 0000000000..63b38fa324
--- /dev/null
+++ b/files/zh-cn/games/tutorials/index.html
@@ -0,0 +1,25 @@
+---
+title: Tutorials
+slug: Games/Tutorials
+tags:
+ - Canvas
+ - Games
+ - JavaScript
+ - NeedsTranslation
+ - TopicStub
+ - Web
+ - Workflows
+translation_of: Games/Tutorials
+---
+<div>{{GamesSidebar}}</div><div>{{IncludeSubnav("/en-US/docs/Games")}}</div>
+
+<p>This page contains multiple tutorial series that highlight different workflows for effectively creating different types of web games.</p>
+
+<dl>
+ <dt><a href="/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript">2D breakout game using pure JavaScript</a></dt>
+ <dd>In this step-by-step tutorial you'll implement a simple breakout clone using pure JavaScript. Along the way you will learn the basics of using the {{htmlelement("canvas")}} element to implement fundamental game mechanics like rendering and moving images, collision detection, control machanisms, and winning and losing states.</dd>
+ <dt><a href="/en-US/docs/Games/Workflows/2D_breakout_game_Phaser">2D breakout game using Phaser</a></dt>
+ <dd>In this step-by-step tutorial you'll implement the same breakout clone as the previous tutorial series, except that this time you'll do it using the<a class="external external-icon" href="http://phaser.io/">Phaser</a> HTML5 game framework. This idea here is to teach some of the fundamentals (and advantages) of working with frameworks, along with fundamental game mechanics.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/HTML5_Gamedev_Phaser_Device_Orientation">2D maze game with device orientation</a></dt>
+ <dd>This tutorial shows how to create a 2D maze game using HTML5, incorporating fundamentals such as collision detection and sprite placement on a {{htmlelement("canvas")}}. This is a mobile game that uses the <a href="/en-US/Apps/Build/gather_and_modify_data/responding_to_device_orientation_changes">Device Orientation</a> and <a href="/en-US/docs/Web/Guide/API/Vibration">Vibration</a><strong> APIs</strong> to enhance the gameplay and is built using the <a href="http://phaser.io/">Phaser</a> framework.</dd>
+</dl>
diff --git a/files/zh-cn/games/简介/index.html b/files/zh-cn/games/简介/index.html
new file mode 100644
index 0000000000..67ffed62c0
--- /dev/null
+++ b/files/zh-cn/games/简介/index.html
@@ -0,0 +1,118 @@
+---
+title: Web 游戏开发简介
+slug: Games/简介
+tags:
+ - 指引
+ - 游戏
+ - 移动端
+translation_of: Games/Introduction
+---
+<div>{{GamesSidebar}}</div>
+
+<div>{{IncludeSubnav("/zh-CN/docs/Games")}}</div>
+
+<p>现代的web已经高速发展成为一个可行可靠的平台,它不仅能够用来创建高质量的酷炫游戏,同时也能够用来发布和传播这些游戏。</p>
+
+<p>采用现代网页技术和较新的浏览器,完全有可能做出令人印象深刻的顶级页面游戏。它能够制作的游戏种类可以和桌面端以及原生系统相当。我们这里所说的,并不是很久之前就采用Flash®制作出的简单卡牌游戏或者多人社交游戏。而是牛逼的3D 动作射击游戏,RPG 游戏等等。得益于 <a href="/zh-CN/docs/JavaScript" title="/zh-CN/docs/JavaScript">JavaScript</a> 实时编译技术性能的大幅提升,以及新开放的 API。在制作运行在浏览器(或者是基于类似 <a href="/zh-CN/docs/Mozilla/Firefox_OS" title="/zh-CN/docs/Mozilla/Firefox_OS">Firefox OS</a> 的 <a href="/zh-CN/docs/HTML/HTML5" title="/zh-CN/docs/HTML/HTML5">HTML5</a>技术支持的设备)上的游戏时,我们不用妥协。</p>
+
+
+
+<h2 id="HTML5游戏平台">HTML5游戏平台</h2>
+
+<p>你可以真正地为你的游戏考虑下 Web 来作为更好的目标平台。我们总是喜欢说,"the Web is the platform."  让我们浏览下 Web 平台的核心部分:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">功能</th>
+ <th scope="col">技术</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>音频</strong></td>
+ <td><a href="/zh-CN/docs/Web/API/Web_Audio_API" title="/zh-CN/docs/Web/API/Web_Audio_API">Web Audio API</a></td>
+ </tr>
+ <tr>
+ <td><strong>图形</strong></td>
+ <td><a href="/zh-CN/docs/WebGL" title="/zh-CN/docs/WebGL">WebGL</a> (<a href="http://www.khronos.org/opengles/" title="http://www.khronos.org/opengles/">OpenGL ES</a> 2.0)</td>
+ </tr>
+ <tr>
+ <td><strong>输入</strong></td>
+ <td><a href="/zh-CN/docs/DOM/Touch_events" title="/zh-CN/docs/DOM/Touch_events">Touch events</a>, <a href="/zh-CN/docs/Web/API/Gamepad_API/Using_the_Gamepad_API" title="/zh-CN/docs/Web/API/Gamepad_API/Using_the_Gamepad_API">Gamepad API</a>, 设备传感器, <a href="/zh-CN/docs/WebRTC" title="/zh-CN/docs/WebRTC">WebRTC</a>, <a href="/zh-CN/docs/Web/API/Fullscreen_API" title="/zh-CN/docs/Web/API/Fullscreen_API">Full Screen API</a>, <a href="/zh-CN/docs/API/Pointer_Lock_API" title="/zh-CN/docs/API/Pointer_Lock_API">Pointer Lock API</a></td>
+ </tr>
+ <tr>
+ <td><strong>语言</strong></td>
+ <td><a href="/zh-CN/docs/JavaScript" title="/zh-CN/docs/JavaScript">JavaScript</a> (或是 C/C++ 使用 <a href="https://github.com/kripken/emscripten/wiki" title="https://github.com/kripken/emscripten/wiki">Emscripten</a> 来编译成 JavaScript)</td>
+ </tr>
+ <tr>
+ <td>
+ <p><strong>网络</strong></p>
+ </td>
+ <td><a href="/zh-CN/docs/WebRTC" title="/zh-CN/docs/WebRTC">WebRTC</a> 和/或 <a href="/zh-CN/docs/Web/API/WebSockets_API" title="/zh-CN/docs/Web/API/WebSockets_API">WebSockets</a></td>
+ </tr>
+ <tr>
+ <td><strong>存储</strong></td>
+ <td><a href="/zh-CN/docs/IndexedDB" title="/zh-CN/docs/IndexedDB">IndexedDB</a> 或是 "云(存储)"</td>
+ </tr>
+ <tr>
+ <td><strong>Web</strong></td>
+ <td><a href="/zh-CN/docs/HTML" title="/zh-CN/docs/HTML">HTML</a>, <a href="/zh-CN/docs/CSS" title="/zh-CN/docs/CSS">CSS</a>, <a href="/zh-CN/docs/SVG" title="/zh-CN/docs/SVG">SVG</a>, <a href="/zh-CN/docs/Mozilla/Projects/Social_API" title="/zh-CN/docs/Mozilla/Projects/Social_API">Social API</a> (还有其他很多很多东西!)</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="商业案例">商业案例</h2>
+
+<p>作为一名游戏开发者,无论你是独立的个人还是大型游戏工作室,你想知道你的下一个游戏项目瞄准 Web 是有意义的 。让我们看看 Web 是如何帮到你的 。</p>
+
+<ol>
+ <li>
+ <div>Web 触手可及;它无处不在。如今可以看到,用 HTML5 构建的游戏运行在智能手机,平板,个人电脑和智能电视。</div>
+ </li>
+ <li>提高营销和曝光度。你不限于在某商店推广你的游戏。相反,你可以像其他媒体一样在 Web 宣传和推广你的游戏,利用网络的固有性和共享性接触新客户。</li>
+ <li>你可以掌握最重要的事项:支付。你不必交付超过收入的 30% 给他人,仅仅就因为你的游戏在他们的生态系统。相反,你可以管理任何你想要的和使用任何你喜欢的付款处理服务。</li>
+ <li>拥有更多控制权的是,只要你愿意,你可以随时更新游戏。 不必着急等待审核通过,仅当其他公司的某某人决定你的关键 bug 修复是否会在今天或明天交付。</li>
+ <li>掌握你的数据分析! 不必依靠别人作出所有决定,你需要什么分析,你可以收集自己的 -- 或选择你最喜欢的第三方平台, 来收集有关你的销售和游戏产生的信息。</li>
+ <li>你可以用你的方式更密切地管理你的客户关系。 再也不用苦苦等待只能通过应用商店有限的机制来过滤客户的反馈。用你想要的方式与客户交流, 没有中间人。</li>
+ <li>你的玩家可以随时随地玩你的游戏。因为 Web 是无处不在的,你的顾客可以在手机,平板,家庭手提,个人电脑或其他设备上关注游戏动态。</li>
+</ol>
+
+<h2 id="针对游戏开发者的Web技术">针对游戏开发者的Web技术</h2>
+
+<p>技术同行们, 让我们发掘出所有关于Web的APIs,将它们呈现给所有的游戏开发者们。下面是一个比较完整的列表,可以一窥Web究竟能够做些什么:</p>
+
+<div class="twocolumns">
+<dl>
+ <dt><a href="/zh-CN/docs/Web/API/Fullscreen_API" title="/zh-CN/docs/Web/API/Fullscreen_API">Full Screen API</a></dt>
+ <dd>这个简单的API能够让你的游戏占据整个屏幕,从而使玩家沉浸在动作中</dd>
+ <dt><a href="/zh-CN/docs/Web/API/Gamepad_API/Using_the_Gamepad_API" title="/zh-CN/docs/Web/API/Gamepad_API/Using_the_Gamepad_API">Gamepad API</a></dt>
+ <dd>如果你想你的用户能够使用游戏手柄或其他游戏控制器来控制游戏,你需要这个API</dd>
+ <dt><a href="/zh-CN/docs/HTML" title="/zh-CN/docs/HTML">HTML</a> and <a href="/zh-CN/docs/CSS" title="/zh-CN/docs/CSS">CSS</a></dt>
+ <dd>二者合璧,可以构建,设计并对你的游戏界面布局,HTML有一个提供2D图形的元素,即{{HTMLElement("canvas")}}</dd>
+ <dt><a href="/zh-CN/docs/HTML/Element/audio" title="/zh-CN/docs/HTML/Element/audio">HTML audio</a></dt>
+ <dd> {{HTMLElement("audio")}} 元素可以用来播放一些简单的音效和音乐。如果你想要更多的参与,可以学习<a href="/zh-CN/docs/Web/API/Web_Audio_API" title="/zh-CN/docs/Web/API/Web_Audio_API">Web Audio API</a> 来深入了解音频处理的力量!</dd>
+ <dt><a href="/zh-CN/docs/IndexedDB" title="/zh-CN/docs/IndexedDB">IndexedDB</a></dt>
+ <dd>一个强大的数据存储API,用来在电脑或者设备上保存用户自己的数据。一个很好的方法用来保存游戏的状态和其它最近的信息,这样在需要的时候不用每次重新下载。也可以用来让你的游戏即使用户没有链接到网络也能继续玩 (例如在飞机上的数小时)。</dd>
+ <dt><a href="/zh-CN/docs/JavaScript" title="/zh-CN/docs/JavaScript">JavaScript</a></dt>
+ <dd>JavaScript是网络上使用的编程语言,在现代浏览器中正在快速发展,而且一直在快速发展。 使用它的力量为您的游戏编写代码,或者使用<a href="https://github.com/kripken/emscripten/wiki">Emscripten</a>或<a href="http://asmjs.org/spec/latest/">Asm.js</a>等技术轻松移植您现有的游戏。</dd>
+ <dt><a href="/zh-CN/docs/API/Pointer_Lock_API" title="/zh-CN/docs/API/Pointer_Lock_API">Pointer Lock API</a></dt>
+ <dd>指针锁定API允许您在游戏界面中锁定鼠标或其他指针设备,以便您不用绝对定位光标就可以获得坐标变化值,从而准确地判断用户正在做什么,并且还可以防止用户意外地进入另一块屏幕或别的什么地方,从而导致误操作。</dd>
+ <dt><a href="/zh-CN/docs/SVG" title="/zh-CN/docs/SVG">SVG</a> (可缩放矢量图形)</dt>
+ <dd>无论用户显示器的大小或分辨率如何,都可以构建平滑缩放的矢量图形。</dd>
+ <dt><a href="/zh-CN/docs/JavaScript/Typed_arrays" title="/zh-CN/docs/JavaScript/Typed_arrays">Typed Arrays</a></dt>
+ <dd>JavaScript中的类型数组可以让您访问原始二进制数据;这使您可以操纵GL纹理,游戏数据或其他任何东西,即使它不是原生JavaScript数据格式。</dd>
+ <dt><a href="/zh-CN/docs/Web/API/Web_Audio_API" title="/zh-CN/docs/Web/API/Web_Audio_API">Web Audio API</a></dt>
+ <dd>这个API用于控制JavaScript代码中的音频的回放,合成和处理,使您可以创建出色的音效,以及实时播放和操作音乐。</dd>
+ <dt><a href="/zh-CN/docs/WebGL" title="/zh-CN/docs/WebGL">WebGL</a></dt>
+ <dd>允许您从Web内容创建高性能,硬件加速的3D(和2D)图形。 这是一个Web支持的<a href="https://www.khronos.org/opengles/">OpenGL ES</a> 2.0实现。</dd>
+ <dt><a href="/zh-CN/docs/WebRTC" title="/zh-CN/docs/WebRTC">WebRTC</a></dt>
+ <dd>WebRTC(实时通信)API使您能够控制音频和视频数据,包括远程会议以及两个用户之间来回传输其他应用程序数据。 希望你的玩家能够在殴打怪物的同时互相交流? 这是你的API,快使用它吧。</dd>
+ <dt><a href="/zh-CN/docs/Web/API/WebSockets_API" title="/zh-CN/docs/Web/API/WebSockets_API">WebSockets</a></dt>
+ <dd>WebSocket API使您可以将您的应用程序或站点连接到服务器,实时传输数据。 构建完美的多人游戏动作,聊天服务等必备。</dd>
+ <dt><a href="/zh-CN/docs/DOM/Using_web_workers" title="/zh-CN/docs/DOM/Using_web_workers">Web Workers</a></dt>
+ <dd>Workers API 能够让您生成运行JavaScript代码的后台线程,以充分利用现代的多核CPU。</dd>
+ <dt><a href="/zh-CN/docs/DOM/XMLHttpRequest" title="/zh-CN/docs/DOM/XMLHttpRequest">XMLHttpRequest</a> 和 <a href="/zh-CN/docs/Web/API/File_and_Directory_Entries_API" title="/zh-CN/docs/DOM/File_API">File API</a></dt>
+ <dd>XMLHttpRequest和File API的组合使您可以从Web服务器发送和接收任何类型的数据。比如下载新的游戏关卡,文件,以及传递非实时游戏状态信息等。</dd>
+</dl>
+</div>