recursal/MDN huggingface dataset:
Build the brick field
=====================

* « 上一页 (en-US)
* 下一页 » (en-US)

这是 Gamedev Canvas tutorial (en-US)教程 10 节的第 6 节。你可以在完成本课程后在这里Gamedev-Canvas-workshop/lesson6.html找到源代码。

在修改游戏机制后，我们可以输了 — 这样这游戏看起来终于像是一个游戏了，这真是太好了。但是，如果你总是让球与墙、板碰撞的话，很快就会感到无聊的。好游戏需要的是让球消灭砖，这就是我们即将要做的！

设置砖变量
-----

本课题的总体目标是使用一个二维数组嵌套的循环，给出砖的几行代码。首先我们需要设置一些变量定义的砖，如宽度和高度信息，行和列，等。在之前的变量声明处加入以下几行代码。


```js
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
```


在这里，我们定义了砖的行数和列，宽度和高度，砖块之间的填充物，这样它们就不会互相接触；有一个上、左偏移量，所以它们不会从画布的边缘开始绘制。

我们将在一个二维数组容纳我们所有的砖。它将包含砖列（c），砖行（R），每一个包含一个对象，其中包含 x 和 y 位置，让每个砖显示在屏幕上。在变量下面添加以下代码：


```js
var bricks = [];
for (c = 0; c < brickColumnCount; c++) {
  bricks[c] = [];
  for (r = 0; r < brickRowCount; r++) {
    bricks[c][r] = { x: 0, y: 0 };
  }
}
```


上面的代码将通过行和列的循环和创造新砖。注意，砖块对象稍后也将用于碰撞检测。

画砖的逻辑
-----

现在让我们创建一个函数来遍历数组中的所有砖块并在屏幕上绘制它们。. 代码如下：


```js
function drawBricks() {
  for (c = 0; c < brickColumnCount; c++) {
    for (r = 0; r < 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();
    }
  }
}
```


再次，我们遍历的行和列，给每一块砖的位置设置`X`和`Y`，我们也画布上画砖，---`brickwidth` X `brickheight` 。问题是我们都画在一个地方坐标`（0,0）`处。我们需要做的是增加一些计算，计算每个循环迭代后的砖块的 x 和 y 位置：


```js
var brickX = c \* (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = r \* (brickHeight + brickPadding) + brickOffsetTop;
```


每个`brickX`位置是 `brickWidth + brickPadding`，乘以列数`C`，再加上`brickOffsetLeft`；对于砖`brickY`的逻辑相同，除了名称不同，使用行数`R`，`brickHeight`，和`brickOffsetTop`。现在，每一块砖都可以放在正确的地方，排成一排，每一块砖之间都有填充物，从左上角和顶部的帆布边缘偏移。

在设置`brickX`和`brickY`作为对应砖的坐标之后，形成了 `drawBricks()`函数的最终版本。将以下代码加在`drawPaddle()`函数后面：


```js
function drawBricks() {
  for (c = 0; c < brickColumnCount; c++) {
    for (r = 0; r < 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();
    }
  }
}
```

到了展现真正画砖的时候了
------------

最后一件事就是在`draw()`中调用`drawBricks()`, 位置最好在函数开始处，在清除画布和画球之间。直接将下面代码加在`drawBall()` 处：


```js
drawBricks();
```

比较你的代码
------

这样，游戏变得更有趣了 :

**备注：** 练习：尝试在行或列上改变砖块数量，或者它们的位置。

下一节
---

现在，我们有砖啦！但是球根本就没有和它们互动——接下来的第七章我们将让球和砖产生碰撞：碰撞检测 (en-US)。

* « 上一页 (en-US)
* 下一页 » (en-US)
Web 中的 3D 游戏
============

为了 web 上丰富的游戏体验，一个好武器是 webGL，它可以在 HTML `<canvas>` 元素上渲染。WebGL 基本上是 Web 的 OpenGL ES 2.0 版本——作为一个 JavaScript API，它提供了能构建丰富的交互式动画和游戏的工具。你可以使用硬件加速的 JavaScript 生成和呈现动态 3D 图像。

文档和浏览器支持
--------

WebGL 项目的文档和规范由 Khronos Group 维护，而非大部分 Web API 采用的 W3C。它很好地支持了现代浏览器甚至是移动手机，由此你无需担心太多。主流浏览器均支持 WebGL，你需要关注的仅仅是在你使用的设备上进行优化。

WebGL 2.0（基于 OpenGL ES 3.0）将在不久的将来发布，它将带来许多改进，并将帮助开发人员使用当前强大的硬件为现代 web 构建游戏。

对基本 3D 理论的解释
------------

三维理论的基本原理围绕三维空间中的图形展开，并使用坐标系来计算它们的位置。请参阅我们的解释基本 3D 理论文章，了解你需要的所有信息。

进阶概念
----

使用 WebGL，可以做更多事情。应该深入学习一些高级概念，如着色器、碰撞检测或最新的热门话题：Web 虚拟现实。

### 着色器

值得一提的是着色器，其本身有很多值得探讨的地方。着色器使用一种特殊的 OpenGL 着色语言——GLSL，其语法类似于 C 语言，由图形管道直接执行。着色器可分为顶点着色器和片段着色器（或像素着色器），前者将形状位置转换为真实的 3D 绘图坐标，后者则计算渲染颜色和其他属性。你一定要看看 GLSL 着色器这篇文章，了解更多关于它们的信息。

### 碰撞检测

很难想象没有碰撞检测的游戏会是什么样子——我们总是需要计算出物体什么时候碰撞到另外一个物体。我们有相关信息可供你学习：

* 2D 碰撞检测
* 3D 碰撞检测
### WebXR

虚拟现实的概念并不新鲜，但由于 Meta Quest、WebXR API（目前处于试验阶段）等硬件的进步，它正风靡网络，用于从 XR 硬件捕捉信息并将其提供给 JavaScript 应用程序使用。更多信息，请阅读 WebXR——Web 虚拟和增强现实 (en-US)。

还有一篇用 A-Frame 构建基本演示 (en-US)的文章，向你展示了使用 A-Frame 框架构建 3D 环境的虚拟现实是多么的简单。

库和框架的兴起
-------

编码原生 WebGL 是相当复杂的，从长远来看，随着项目更进一步，你会希望掌握它（请参阅我们的 WebGL 文档以开始学习）。在实际项目中，你可能也会使用框架来加快开发速度，并帮助你管理正在进行的项目。在 3D 游戏中使用框架还有助于优化性能，因为所使用的工具可以解决很多问题，这样就可以专注于构建游戏本身。

最流行的 JavaScript 3D 库是 Three.js，这是一个多用途工具，它使常见的 3D 技术更易于实现。还有其他一些流行的游戏开发库和框架也值得一看。A-Frame、PlayCanvas 和 Babylon.js 是其中最知名的几个，它们拥有丰富的文档、在线编辑器和活跃的社区。

### 使用 A-Frame 搭建一个基础演示

A-Frame 是一个用于搭建 3D 和 VR 体验的 Web 框架。在内部，它是一个具有已声明的实体组件模式的 three.js 框架，也就是说我们只需借助 HTML 即可搭建场景。请参阅使用 A-Frame 构建基本演示 (en-US)子页面来了解创建演示的步骤。

### 使用 Babylon.js 搭建一个基础演示

Babylon.js 是最受开发者欢迎的 3D 游戏引擎之一。与其他任何 3D 库一样，它提供了内置函数，帮助你更快地实现常见的 3D 功能。请参阅 使用 Babylon.js 构建基本演示 (en-US)子页，其中包括建立一个开发环境，构建必要的 HTML，以及编写 JavaScript 代码。

### 使用 PlayCanvas 搭建一个基础演示

PlayCanvas 是一个流行的 GitHub 开源 3D WebGL 游戏引擎，有在线编辑器和良好的文档。更多详细信息 请参阅使用 PlayCanvas 构建基本演示 (en-US) ，文章将进一步介绍如何使用 PlayCanvas 库和在线编辑器搭建演示。

### 使用 Three.js 搭建一个基础演示

与其他库一样，Three.js 也能带来巨大优势：无需编写数百行 WebGL 代码来构建任何有趣的内容，而是可以使用内置的辅助函数来更轻松、更快速地完成工作。请参阅使用 Three.js 构建基本演示子页面，了解创建演示的逐步过程。

### 其他工具

Unity 和虚幻引擎可以将你的游戏通过 asm.js (en-US) 输出到 WebGL，因此你可以自由地使用这些工具与技术来构建可被输出到 Web 上的游戏。

![三个三维几何图形的插图：灰色环形体、蓝色立方体和黄色圆柱体。](/zh-CN/docs/Games/Techniques/3D_on_the_web/shapes.png)

下一步
---

通过这篇文章，我们刚刚了解了当前可用技术所能实现的功能。使用 WebGL 以及在其基础上构建的库和框架，你可以在网络上构建身临其境、美观且快速的 3D 游戏。

### 源代码

你可以在 GitHub 上找到该系列的所有源代码演示。

### API

* Canvas API
* WebGL API
* WebVR API
### 框架

* Three.js
* PlayCanvas
* Babylon.js
* A-Frame
### 教程

* 使用 Three.js 构建基本演示
* 使用 PlayCanvas 构建基本演示 (en-US)
* 使用 Babylon.js 构建基本演示 (en-US)
* 使用 A-Frame 构建基本演示 (en-US)
实现游戏控制机制
========

作为游戏开发平台，HTML5 的主要优势之一是能够在各种平台和设备上运行。简化跨设备差异带来了多重挑战，尤其是在为不同环境提供适当控件时。在本系列文章中，我们将向你展示如何构建一款可以使用触摸屏智能手机、鼠标和键盘以及游戏手柄等不常用机制进行游玩的游戏。

案例分析
----

我们将使用 Captain Rogers: Battle at Andromeda 演示版作为示例。

![Captain Rogers: Battle at Andromeda——包含 Enclave Games 和 Blackmoon Design 徽标、罗杰的太空船和游戏名称的游戏封面。](/zh-CN/docs/Games/Techniques/Control_mechanisms/captainrogers2-cover.png)

Captain Rogers 是使用 Phaser 框架开发的游戏，该框架是目前 JavaScript 中最流行的简单 2D 游戏开发工具，但在使用纯 JavaScript 或其他框架构建游戏时，重复使用这些文章中包含的知识应该相当容易。如果你想了解 Phaser 的入门知识，请查看使用 Phaser 开发 2D 打砖块游戏教程。

在接下来的文章中，我们将展示如何为 Rogers 船长实现各种不同的控制机制，以支持不同的平台——从手机上的触摸、桌面上的键盘/鼠标/游戏板，到更多非常规的控制机制，如电视遥控器、对着笔记本电脑大喊或挥手，或者捏香蕉。

设置环境
----

让我们先快速浏览一下游戏的文件夹结构、JavaScript 文件和游戏中的状态，这样就能知道在哪里发生了什么。游戏的文件夹看起来是这样的：

![Captain Rogers: Battle at Andromeda——游戏项目的文件夹结构，其中包含 JavaScript 源代码、图像和字体。](/zh-CN/docs/Games/Techniques/Control_mechanisms/captainrogers2-folderstructure.png)

正如你所看到的，这里有用于存放图片、JavaScript 文件、字体和音效的文件夹。`src` 文件夹包含 JavaScript 文件，这些文件被分为不同的状态：`Boot.js`、`Preloader.js`、`MainMenu.js` 和 `Game.js`。第一个状态初始化 Phaser，第二个状态预加载所有资源，第三个状态控制欢迎玩家的主菜单，第四个状态控制实际游戏。

每个状态都有自己的默认方法：`preload()`、`create()` 和 `update()`。第一个方法用于预载所需资源，`create()` 在状态启动后执行，而 `update()` 则在每一帧上执行。

例如，你可以在 `create()` 函数中定义一个按钮：


```js
create() {
  // …
  const buttonEnclave = this.add.button(10, 10, 'logo-enclave', this.clickEnclave, this);
  // …
}
```


它将在游戏开始时创建一次，并在点击时执行分配给它的 `this.clickEnclave()` 动作，但你也可以在 `update()` 函数中使用鼠标指针值来执行动作：


```js
update() {
  // …
  if (this.game.input.mousePointer.isDown) {
      // 做些什么
  }
  // …
}
```


当鼠标按钮被按下时，它就会被执行，并且在游戏的每一帧都会根据输入的 `isDown` 布尔变量进行检查。

这应该能让你对项目结构有一些了解。我们将主要使用 `MainMenu.js` 和 `Game.js` 文件，并将在以后的文章中更详细地解释 `create()` 和 `update()` 方法中的代码。

纯 JavaScript 演示
---------------

另外还有一个小型在线演示，其完整源代码可在 GitHub 上获取，其中文章中描述的控制机制的基本支持是用纯 JavaScript 实现的。下面的文章将对其进行解释，但你已经可以用它来玩了，也可以出于学习目的随意使用这些代码。

其他文章
----

JavaScript 是移动游戏的最佳选择，因为 HTML 具有真正的多平台特性；以下所有文章都将重点放在为不同控制机制提供接口的 API 上：

1. 移动触控——第一篇文章将以触控为开篇，因为移动优先的方式非常流行。
2. 桌面鼠标和键盘控制 (en-US)——当在台式机/笔记本电脑上进行游戏时，提供键盘和鼠标控制对于为游戏提供可接受的无障碍程度至关重要。
3. 桌面游戏手柄控制 (en-US)——游戏手柄 API 允许在桌面/笔记本电脑上使用游戏手柄控制网络应用程序，以获得游戏机的感觉。
4. 非常规控制 (en-US)——最后一篇文章展示了一些非常规的控制机制，从实验性的到略显疯狂的，你可能不会相信这些机制可以用来玩游戏。
2D 碰撞检测
=======

2D 游戏中的碰撞检测算法依赖于可碰撞物体的形状（例如：矩形与矩形、矩形与圆形、圆形与圆形）。通常情况下，你使用的简单通用形状，会被称为“碰撞盒（hitbox）”的实体所覆盖，尽管发生的碰撞并不是像素那样完美契合，但它看起来也足够好，而且可跨多个实体执行碰撞。本文提供了一系列较为通用的 2D 游戏中碰撞检测技术。

轴对齐包围盒
------

碰撞检测的一种较简单的形式是在轴线对齐的两个矩形之间进行碰撞检测（这意味着没有旋转）。该算法的工作原理是确保两个矩形的 4 条边之间没有间隙。任何间隙都意味着不存在碰撞。
```

<div id="cr-stage"></div>
<p>用箭头键移动矩形。绿色表示碰撞，蓝色表示无碰撞。</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script>
```



```js
Crafty.init(200, 200);

const dim1 = { x: 5, y: 5, w: 50, h: 50 };
const dim2 = { x: 20, y: 10, w: 60, h: 40 };

const rect1 = Crafty.e("2D, Canvas, Color").attr(dim1).color("red");

const rect2 = Crafty.e("2D, Canvas, Color, Keyboard, Fourway")
  .fourway(2)
  .attr(dim2)
  .color("blue");

rect2.bind("EnterFrame", function () {
  if (
    rect1.x < rect2.x + rect2.w &&
    rect1.x + rect1.w > rect2.x &&
    rect1.y < rect2.y + rect2.h &&
    rect1.y + rect1.h > rect2.y
  ) {
    // 检测到碰撞发生！
    this.color("green");
  } else {
    // 没有碰撞
    this.color("blue");
  }
});
```


**备注：** 另一个不使用 Canvas 或外部库的示例。

圆形碰撞
----

碰撞测试的另一种形状是两个圆形间的碰撞，该算法是通过获取两个圆心点，并确定圆心距离小于两个圆形的半径和实现的。
```

<div id="cr-stage"></div>
<p>用箭头键移动圆形。绿色表示碰撞，蓝色表示无碰撞。</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.5.4/crafty-min.js"></script>
```


```
#cr-stage {
  position: static !important;
  height: 200px !important;
}
```



```js
Crafty.init(200, 200);

const dim1 = { x: 5, y: 5 };
const dim2 = { x: 20, y: 20 };

Crafty.c("Circle", {
  circle(radius, color) {
    this.radius = radius;
    this.w = this.h = radius \* 2;
    this.color = color || "#000000";

    this.bind("Move", Crafty.DrawManager.drawAll);
    return this;
  },

  draw() {
    const ctx = Crafty.canvas.context;
    ctx.save();
    ctx.fillStyle = this.color;
    ctx.beginPath();
    ctx.arc(
      this.x + this.radius,
      this.y + this.radius,
      this.radius,
      0,
      Math.PI \* 2,
    );
    ctx.closePath();
    ctx.fill();
    ctx.restore();
  },
});

const circle1 = Crafty.e("2D, Canvas, Circle").attr(dim1).circle(15, "red");

const circle2 = Crafty.e("2D, Canvas, Circle, Fourway")
  .fourway(2)
  .attr(dim2)
  .circle(20, "blue");

circle2.bind("EnterFrame", function () {
  const dx = circle1.x - circle2.x;
  const dy = circle1.y - circle2.y;
  const distance = Math.sqrt(dx \* dx + dy \* dy);

  const colliding = distance < circle1.radius + circle2.radius;
  this.color = colliding ? "green" : "blue";
});
```


**备注：** 另一个不使用 Canvas 或外部库的示例

分离轴定理
-----

这是一种碰撞算法，可以检测任意两个*凸*多边形之间的碰撞。它的实现比上述方法更复杂，但功能更强大。这种算法的复杂性意味着我们需要考虑性能优化，这将在下一节中介绍。

实现分离轴定理（SAT）不在本页讨论范围之内，请参阅下面推荐的教程：

1. 分离轴定理（SAT）解释
2. 碰撞检测与响应
3. 使用分离轴定理进行碰撞检测
4. SAT（分离轴定理）
5. 分离轴定理
碰撞性能
----

虽然其中一些碰撞检测算法计算起来非常简单，但要测试*每一个*实体与其他实体之间的碰撞可能会浪费很多周期。通常游戏会将碰撞分为两个阶段，即宽周期和窄周期。

### 宽周期

宽周期应该得到一个*可能*发生碰撞的实体列表。这可以通过一个空间数据结构来实现，它能让你大致了解实体存在的位置及其周围的情况。空间数据结构的一些例子包括四叉树、R 树或空间哈希图。

### 窄周期

如果要检查的实体数量不多，就需要使用窄周期算法（如上文列出的算法）来确定是否存在碰撞。
asm.js 的异步脚本
============

每个中型或大型游戏都应编译asm.js (en-US)代码作为异步脚本的一部分，以便浏览器能够最大限度地灵活地优化编译过程。在 Gecko 中，异步编译允许 JavaScript 引擎在游戏加载时缓存主线程的 asm.js，并缓存生成的机器代码，这样游戏就不需要在随后的加载中编译（从 Firefox 28 开始）。要查看差异，请切换`javascript.options.parallel_parsing` in `about:config`.

异步执行
----

获取异步编译非常简单：编写 JavaScript 时，只需使用 `async` 属性即可：


```js
<script async src="file.js"></script>
```


或者，通过脚本来做同样的事情：


```js
const script = document.createElement("script");
script.src = "file.js";
document.body.appendChild(script);
```


（从脚本中创建的脚本默认为异步。）默认的 HTML shell Emscripten 生成后者。

什么时候用 async 或者不用？
-----------------

两种常见的情况下是脚本是**非**异步的（由HTML 规范定义）


```js
<script async>code();</script>
```


以及


```js
const script = document.createElement("script");
script.textContent = "code()";
document.body.appendChild(script);
```


两者都被视为“内联”脚本，阻塞其余所有任务，进行编译，编译完成后立即执行。

如果你的代码是一个 JS 字符串呢？你应该使用带有对象 URL（object URL）的 Blob 对象，而不是使用 `eval` 或 `innerHTML`，这两者都会触发同步编译：


```js
const blob = new Blob([codeString]);
const script = document.createElement("script");
const url = URL.createObjectURL(blob);
script.onload = script.onerror = () => URL.revokeObjectURL(url);
script.src = url;
document.body.appendChild(script);
```


使用`src`而不是`innerHTML，则该`脚本是异步的。
附加组件
====

附加组件允许开发者们去扩展和修改 Firefox 的功能。开发者们能使用标准的 Web 技术「JavaScript，HTML 以及 CSS」再加上一些专用的 JavaScript APIs 来开发附加组件。

除此之外，附加组件还能：

* 改变指定网站的外观或者内容
* 修改 Firefox 的用户界面
* 给 Firefox 加上新功能

有几种附件组件类型，但最常见类型是扩展。

开发扩展
----

在过去，有几种工具集用于开发 Firefox 扩展，但是到 2017 年 11 月底，扩展必须使用 WebExtensions APIs 构建。其余工具集「包括 overlay add-ons、bootstrapped add-ons 和 Add-on SDK」将会同时被废弃。

使用 Firefox WebExtensions APIs 编写的扩展设计为跨浏览器兼容。在大多数情况下它也能在 Chrome，Edge 和 Opera 中运行，几乎没有任何变化。它们也完全兼容多进程 Firefox。你可以查看目前在 Firefox 和其他浏览器中支持的 APIs。

### 扩展工坊

Firefox 扩展工坊可以帮助你为 Firefox 开发扩展，并为你的用户提供简单而强大的方式来定制他们的浏览体验。你会找到：

* Firefox 扩展特征概述
* 开发和测试工具及其流程
* 如何在 addons.mozilla.org 上发布扩展或自己分发扩展
* 如何管理已发布的扩展
* 对于企业用户，开发和使用扩展的指南
* 如何为 Firefox 开发主题
* Firefox 开发者社区
### Android 版 Firefox 的扩展

2020 年，Mozilla 将发布一款新的 Android 版 Firefox。这款新的 Android 高性能浏览器是使用 Mozilla 的移动浏览器引擎 GeckoView 从头开始重新构建的。我们目前正在 GeckoView 上添加对 WebExtensionsAPI 的支持。

### 迁移现有扩展

如果你正在维护一个旧式扩展，比如 XUL overlay、bootstrapped，或者基于 Add-on SDK 的扩展，我们建议你将其移植到 WebExtension APIs。这里有一些Firefox 扩展工坊中的移植资源。

有关过渡支持的更多内容，请访问我们的wiki 页面。

发布附加组件
------

Addons.mozilla.org，俗称「AMO」，是 Mozilla 官方的官方站点，方便开发者发布扩展组件和用户查找。通过上传附加组件到 AMO，你可以加入我们的用户和开发者社区，为你的附加组件找到订阅者。

你不一定需要在 AMO 上发布你的附加组件，但你的附加组件必须要经过 Mozilla 签名，否则用户不能安装它。

有关发布附加组件过程的概述，请参阅签署和分发你的加载项。

其他类型的附加组件
---------

通常，当人们谈起附加组件时是指扩展工具，但是这里也有一些其他类型的附加组件允许用户定制 Firefox. 这些附加组件包括：

* 用户字典 是可以进行各种语言的拼写检查的插件；
* 语言包 让你有更多可用的语言用于 Firefox 的界面。
联系我们
----

查看联系我们页面，了解有关如何获得帮助、时刻关注关于附加组件的最新消息以及向我们提供反馈的详细信息。
Firefox
=======

Firefox（非正式中文名称“火狐”）是 Mozilla 的流行 Web 浏览器，适用于多种平台，包括 Windows、MacOS、Linux 等桌面版，以及所有的 Android 和 iOS 移动设备。得益于对最新的 Web 标准的广泛兼容性和强有力的开发工具，Firefox 是 Web 开发者和终端用户的绝佳选择。

Firefox 是一个开源项目，许多代码都是由庞大的志愿者社区贡献的。在此你可以了解如何为 Firefox 项目做贡献，你也可以找到关于构建 Firefox 附加组件、使用 Firefox 开发者工具以及其他主题的信息的链接。

了解如何为 Firefox 创建附加组件、如何开发和构建 Firefox 本身，并了解 Firefox 的内部以及其他子项目如何运作。

主要资源
----

Firefox 开发者指南

我们的开发者指南提供了关于获取 Firefox 源代码，在 Linux、macOS 和 Windows 上构建源代码，如何找到解决方法，以及如何为项目做贡献的详细说明。

Firefox 附加组件指南

附件组件指南提供了开发和部署 Firefox 扩展的信息。

面向开发者的发布说明

在面向开发者的发布说明中了解每一个 Firefox 版本为网站与附加组件开发者带来的新功能。

Firefox 更新通道
------------

Firefox 通过 5 个**更新通道**进行发布。

### Firefox Nightly

每天晚上，我们都使用 mozilla-central 中的最新代码构建 Firefox。这些版本适用于开发者或想要尝试最新的、处于活跃开发中的特性的使用者。

下载 Firefox Nightly

### Firefox 开发者版

这是一个为开发者量身定做的 Firefox 版本。Firefox 开发者版拥有所有已经达到测试版（beta）的最新的开发者工具。我们还为开发者添加了一些额外的、仅在这个更新通道提供的特性。它使用自己的路径和配置文件，因此它可以与标准版或 Beta 版 Firefox 一起运行。

下载 Firefox 开发者版

### Firefox Beta

每隔四个星期，我们就会选取足够稳定的特性，创建一个新的 Firefox Beta 版本。Firefox Beta 版是为 Firefox 爱好者提供的，用于测试注定会成为下一个 Firefox 标准版本的内容。

下载 Firefox Beta

### Firefox

当在 Beta 频道中稳定四周之后，我们便发布 Firefox 的新版本，将新特性推送至数亿用户。

下载 Firefox

### Firefox 延长支持版（ESR）

Firefox 延长支持版是在较长周期提供支持的桌面版 Firefox，适用于学校、大学、商业机构等组织以及需要延长支持用以进行大规模部署的用户。

下载 Firefox 延长支持版

内容
--

Firefox 中的实验性特性本页列出了 Firefox 的实验性和部分实现的特性，包括针对提议的或前沿的网络平台标准的特性，以及这些特性的版本信息、是否“默认”激活这些特性，以及可用于激活或停用这些特性的偏好设置。这样，就可以在特性发布前对其进行测试。

与 Firefox 开发者相关的发行说明本页提供每个 Firefox 的版本的“与 Firefox 开发者相关的发行说明”文章的链接。这些日志文章可以让你查看每个 Firefox 版本增加了哪些功能和修复的错误。

参见
--

* 邮件列表
* 发布时间表
与 Firefox 开发者相关的发行说明
====================

本页提供每个 Firefox 的版本的“与 Firefox 开发者相关的发行说明”文章的链接。这些日志文章可以让你查看每个 Firefox 版本增加了哪些功能和修复的错误。

1. 致 Firefox 3 开发者
2. Firefox 121 的开发者说明
3. Firefox 120 的开发者说明
4. Firefox 119 的开发者说明
5. Firefox 78 的开发者说明
6. Firefox 65 for developers
7. Firefox 59 for developers
8. Firefox 41 for developers
9. Firefox 33 for developers
10. Firefox 32 for developers
11. Firefox 31 for developers
12. Firefox 27 for developers
13. Firefox 26 for developers
14. Firefox 25 for developers
15. Firefox 24 for developers
16. Firefox 22 for developers
17. Firefox 21 for developers
18. Firefox 20 for developers
19. Firefox 19 for developers
20. Firefox 18 for developers
21. Firefox 14 for developers
Firefox 25 for developers
=========================

Web 开发者需要注意的变化
--------------

### CSS

* 新增了 `background-attachment` 属性值 `local` (Firefox bug 483446).
* 新增了一个 Mozilla 私有的媒体查询属性：`-moz-os-version`, 目前该属性只支持 Windows (Firefox bug 810399).
* 实现了新的 `-moz-osx-font-smoothing` (en-US) CSS 属性 (Firefox bug 857142)
### HTML

* 实现了 `<iframe>` 元素的 `srcdoc` 属性，可以用 HTML 代码来定义 `<iframe>` 元素的文档内容 (Firefox bug 802895).
* `HTMLCanvasElement.toBlob` 方法，当第二个参数指定为 `"image/jpeg"` 时，会接受第三个参数，用来指定 jpeg 图片质量。(Firefox bug 891884).
### JavaScript

下面都是 ECMAScript 6 (Harmony) 中的新特性！

* 实现了 `Array.of()` 方法 (Firefox bug 866849).
* 实现了 `Number.parseInt()` 和 `Number.parseFloat()` 方法 (Firefox bug 886949).
* 实现了 `Map.prototype.forEach()` 和 `Set.prototype.forEach()` 方法 (Firefox bug 866847)
* 实现了更多的数学函数：`Math.log10()`, `Math.log2()`, `Math.log1p()`, `Math.expm1()`, `Math.cosh()`, `Math.sinh()`, `Math.tanh()`, `Math.acosh()`, `Math.asinh()`, `Math.atanh()`, `Math.hypot()`, `Math.trunc()`, `Math.sign()` 以及 `Math.cbrt()` (Firefox bug 894026).
* 实现了八进制整数字面量写法 (比如`0o777`) 和二进制整数字面量写法 (比如`0b111`) (Firefox bug 717379).
* 实现了 ECMAScript 国际化 API——ECMA 402（Firefox bug 853301）
### DOM

* 在 Windows 上新增了 `KeyboardEvent.key` 属性对几个与 IME 有关的键盘按键的支持 (Firefox bug 865565), 查看 各按键对应的 key 属性列表 了解详情。
* Metrofox 的键盘事件和桌面版实现统一 (Firefox bug 843236).
* 如果使用 preventDefault() 阻止了 keydown 事件的默认行为，则后续的 keypress 事件就不会触发 (en-US) (Firefox bug 501496)
* 实现了 `HTMLIFrameElement` 接口的 `srcDoc` 属性，可以用 HTML 代码来定义 `<iframe>` 元素的文档内容 (Firefox bug 802895).
* 实现了 `HTMLTableElement` 接口的 `createTBody()` 方法，可以用来获取 (创建) 表格的 `<tbody>` 子元素 (Firefox bug 813034).
* `Range.collapse` 方法的 `toStart` 参数变为可选，且默认值为 `false` (Firefox bug 891340).
* 按照最新 DOM 规范，`window.Future()` 改名为 `window.Promise()`(Firefox bug 884279).
* 实现了 document.firstElementChild, document.lastElementChild, document.children, document.childElementCount 以及 DocumentFragment 的 `parentNode` 等属性 (Firefox bug 895974).
* `navigator.geolocation` 属性更新以符合最新规范。它永远不会返回 `null`。当 `geo.enabled` 偏好设置为 `false` 时，它会返回 `undefined` (Firefox bug 884921).
* `ImageData` API 在 `Worker` 内也可用 (Firefox bug 845545).
### MathML

### SVG

参见
--

* Firefox 25 网站兼容性
### 更早版本

* Firefox 24 for developers
* Firefox 23 for developers (en-US)
* Firefox 22 for developers
* Firefox 21 for developers
* Firefox 20 for developers
* Firefox 19 for developers
* Firefox 18 for developers
* Firefox 17 for developers (en-US)
* Firefox 16 for developers (en-US)
* Firefox 15 for developers (en-US)
* Firefox 14 for developers
* Firefox 13 for developers (en-US)
* Firefox 12 for developers (en-US)
* Firefox 11 for developers (en-US)
* Firefox 10 for developers (en-US)
* Firefox 9 for developers (en-US)
* Firefox 8 for developers (en-US)
* Firefox 7 for developers (en-US)
* Firefox 6 for developers (en-US)
* Firefox 5 for developers (en-US)
* Firefox 4 for developers (en-US)
* Firefox 3.6 for developers (en-US)
* Firefox 3.5 for developers (en-US)
* Firefox 3 for developers
* Firefox 2 for developers (en-US)
* Firefox 1.5 for developers (en-US)
Firefox 31 for developers
=========================

Web 开发者需要关注的变化

### Developer Tools

*No change.*

### CSS

* CSS 变量的语法从旧的 "var-" 前缀更新为新的 "--" 前缀。（Firefox bug 985838）
* Unwanted white space for multiple of 10,000 in Korean counte.(Firefox bug 985186)
### HTML

*No change.*

### JavaScript

实现了如下 ECMAScript 6 新特性：

* `Array` 方法：`Array.prototype.fill()` (Firefox bug 911147)
* `Math` 函数：`Math.clz32()` (Firefox bug 925123)
* `String` 方法：`String.prototype.normalize()` (Firefox bug 918987).
### Interfaces/APIs/DOM

* Constructor of `KeyboardEvent` has been implemented (Firefox bug 930893).
* `KeyboardEvent.initKeyboardEvent()` has been implemented (Firefox bug 930893).
* `KeyboardEvent.isComposing` attribute has been implemented (Firefox bug 993234).
* `InputEvent` interface has been implemented (Firefox bug 993253).
* `InputEvent.isComposing` attribute has been implemented (Firefox bug 993253).
### MathML

*No change.*

### SVG

*No change.*

### Audio/Video

*No change.*

Security
--------

*No change.*

Changes for add-on and Mozilla developers
-----------------------------------------

*No change.*

See also
--------

* Site Compatibility for Firefox 31
### Older versions

* Firefox 30 for developers (en-US)
* Firefox 29 for developers (en-US)
* Firefox 28 for developers (en-US)
* Firefox 27 for developers
* Firefox 26 for developers
* Firefox 25 for developers
* Firefox 24 for developers
* Firefox 23 for developers (en-US)
* Firefox 22 for developers
* Firefox 21 for developers
* Firefox 20 for developers
* Firefox 19 for developers
* Firefox 18 for developers
* Firefox 17 for developers (en-US)
* Firefox 16 for developers (en-US)
* Firefox 15 for developers (en-US)
* Firefox 14 for developers
* Firefox 13 for developers (en-US)
* Firefox 12 for developers (en-US)
* Firefox 11 for developers (en-US)
* Firefox 10 for developers (en-US)
* Firefox 9 for developers (en-US)
* Firefox 8 for developers (en-US)
* Firefox 7 for developers (en-US)
* Firefox 6 for developers (en-US)
* Firefox 5 for developers (en-US)
* Firefox 4 for developers (en-US)
* Firefox 3.6 for developers (en-US)
* Firefox 3.5 for developers (en-US)
* Firefox 3 for developers
* Firefox 2 for developers (en-US)
* Firefox 1.5 for developers (en-US)
Firefox 18 for developers
=========================

Firefox 18 已于 2013 年 1 月 8 日发布。

WEB 开发者需要注意的变化
--------------

### HTML

* 实现了`<ol>`元素上的`reversed`属性 (Firefox bug 601912).
* 实现了`<link>`元素上的`crossorigin`属性 (Firefox bug 786564).
### CSS

* `min-width` 和 `min-height` 属性使用 `auto` 关键字作为初始值 (This has an effect only on flex items as it resolves to `0`, the previous initial value, for other items). (Firefox bug 763689)
* The cascade has been updated: now author `!important` rules override CSS animations (en-US). (Firefox bug 783714)
* `background`简写属性可以包含 CSS3 中的`background-size`属性了。(Firefox bug 570326)
* 初步实现了 Flexbox.默认禁用状态，可以通过设置`layout.css.flexbox.enabled`选项激活该特性.(Firefox bug 666041)
### DOM

* 实现了 `navigator.mozPay` 属性（Firefox bug 767818）
* 实现了 `window.devicePixelRatio` 属性。（Firefox bug 564815）
* 在 MacOS 上实现了`window.navigator.battery` 属性。（Firefox bug 696045）
* 删除了 `MozBlobBuilder`。开发者应该使用 `Blob` 构造函数来创建 `Blob` 对象。（Firefox bug 744907）
* `visibilitychange`事件和页面可见性 API (en-US)取消前缀Firefox bug 812086).
* 实现了 `TextDecoder` 和 `TextEncoder`。（Firefox bug 764234）
* `HTMLMediaElement.src` 被分成了两个属性：一个是标准的 `src` 属性，返回普通的字符串 `DOMString`,另一个是带前缀的`mozSrcObject`属性，返回 media streams (en-US)（Firefox bug 792665）。
### JavaScript

* 实现了 EcmaScript 6 中的直接代理(Firefox bug 703537).警告：该实现包含了一些已知的 bug，以及未根据最新规范草案实现某些特性。不要在生产环境中使用它。
* 实现了 ECMAScript 6 中的字符串方法`contains()`.
### WebGL

### SVG

### MathML

### XUL

### 网络

* HTTP 请求头`Accept-Language` 可以使用两位数字的质量因子（"q-values"）（Firefox bug 672448）。
* HTTP 响应头支持了`X-FRAME-OPTIONS` (en-US)中的`ALLOW-FROM`语法 (Firefox bug 690168).
### 开发者工具

附加组件和 Mozilla 开发者需要注意的变化
------------------------

### 接口变更

`nsIStreamListener`

`onDataAvailable()`方法的第四个参数 (aOffset) 类型改为无符号长整型。(Firefox bug 784912)

`nsIUploadChannel`

`setUploadStream()` 支持了超过 2GB 大小的 content-length (Firefox bug 790617)

`nsIEditor`

删除了 `addEditorObserver()`，使用 `setEditorObserver()` 来替代，`removeEditorObserver()` 不再需要一个 `nsIEditorObserver` 参数（Firefox bug 785091）

`nsIHttpProtocolHandler`

`http-on-modify-request` observers are no longer guaranteed to be called synchronously during
 `nsIChannel.asyncOpen()`. For observers that need to be called during `asyncOpen`(), the new `http-on-opening-request` observer topic has been added. (Firefox bug 800799)


#### 新增接口

#### 移除接口

下面的接口已经被移除。

* `nsIEditorObserver`
参见
--

* Firefox 18 发行说明
* Aurora 18: HiDPI & Touch Events (Mozilla Hacks)
* Firefox 18 网站兼容性
* Firefox 18 附加组件兼容性
### 更早版本

* Firefox 17 for developers (en-US)
* Firefox 16 for developers (en-US)
* Firefox 15 for developers (en-US)
* Firefox 14 for developers
* Firefox 13 for developers (en-US)
* Firefox 12 for developers (en-US)
* Firefox 11 for developers (en-US)
* Firefox 10 for developers (en-US)
* Firefox 9 for developers (en-US)
* Firefox 8 for developers (en-US)
* Firefox 7 for developers (en-US)
* Firefox 6 for developers (en-US)
* Firefox 5 for developers (en-US)
* Firefox 4 for developers (en-US)
* Firefox 3.6 for developers (en-US)
* Firefox 3.5 for developers (en-US)
* Firefox 3 for developers
* Firefox 2 for developers (en-US)
* Firefox 1.5 for developers (en-US)