2015 年 12 月

第 30 卷,第 13 期

游戏开发 - Babylon.js: 构建 Web 基本游戏

作者 Raanan Weber

Babylon.js 是一款基于 WebGL 的 3D 引擎,主要以游戏开发和易用性为主。作为 3D 引擎,它包含的工具可用于创建和显示网格,以及在空间中设置纹理,并能添加光源和照相机。由于是以游戏为主,因此 Babylon.js 还具有常规 3D 引擎不需要的一些额外功能。它提供了对碰撞检测、场景重力、面向游戏的照相机(例如,跟踪移动对象的跟随照相机),以及对 Oculus Rift 和其他虚拟现实 (VR) 设备的本地支持。它具有物理引擎插件系统、本地音频支持、基于用户输入的操作管理器等。在本教程中,我将介绍所有这些功能。

关于本教程

在本教程中,我将开发一个简单的保龄球游戏。我将创建一个保龄球球道,添加 10 个保龄球瓶和一个保龄球,并提供掷球功能。我的游戏当然不会发布,但我会用它来向您展示如何使用 Babylon.js 提供的工具开发游戏。在开发期间,我会刻意避免使用任何外部工具。我将只使用 JavaScript 代码创建对象、照相机、纹理等。

在本教程中,我将使用最新的稳定版本 Babylon.js 2.1。David Catuhe 和 Babylon 开发团队正在尝试尽可能保持框架的后向兼容性,因此,我只能假设本教程适用于今后发布的版本(至少在下一主要版本发布之前)。我使用的是 Visual Studio 2015 Community Edition,但您也可以根据需要使用任意 IDE。

本教程分为两个部分。在本文中,我将概述 Babylon.js 的构建基块。我将创建网格、设置纹理、添加照相机和光源,并启用简单的用户交互。在第二部分中,我将添加碰撞和物理特性、音频、用户操作和特殊的照相机类型,从而展现 Babylon.js 的真正闪光之处。

入门: 新建 Babylon.js 项目

简单的 Babylon.js 项目是一个静态网站。由于我使用的是 Visual Studio,因此我将使用嵌入 Visual Studio 的本地 IIS 服务器来托管这些静态文件。Visual Studio 没有静态网站模板,所以需要采用不同的方法。

首先,新建一个空白解决方案。打开 Visual Studio,然后转到“文件 | 新建 | 项目”。选择左窗格中的“其他项目类型”,然后选择“空白解决方案”(如图 1 所示)。为解决方案命名(我命名的是“BabylonBowling”),然后单击“确定”。

在 Visual Studio 中新建空白解决方案
图 1:在 Visual Studio 中新建空白解决方案

若要新建静态网站,您首先需要新建一个托管目录。右键单击空解决方案,然后单击“在文件资源管理器中打开文件夹”(如图 2 所示)。

在文件资源管理器中打开解决方案文件夹
图 2:在文件资源管理器中打开解决方案文件夹

为 BabylonBowling 项目新建一个目录,然后关闭文件资源管理器。

右键单击解决方案,然后选择“添加 | 现有网站”。选择新创建的文件夹(务必选择刚创建的文件夹,而不是解决方案的文件夹),然后单击“打开”。此时,您应该有一个空白网站作为此解决方案的唯一项目了。

创建项目后,您需要添加框架和框架依赖项。有几种方法可以做到这一点。最简单的方法是使用 NuGet 包管理器。

右键单击项目,然后选择“管理 NuGet 包”。单击搜索字段(键盘快捷方式为 Ctrl+E),然后键入 babylon。此时,您会看到一个窗口(如图 3 所示)。选择“BabylonJS”。请确保选定版本是 2.1(或最新的稳定版本),然后单击“安装”。在弹出的“预览”窗口(若有)中,单击“确定”,然后 Babylon.js 会安装至您的空项目中(包括演示场景)。

使用 NuGet 包管理器添加 Babylon.js
图 3:使用 NuGet 包管理器添加 Babylon.js

如果您将 npm 用作包管理器,则可以使用下列命令安装 Babylon.js:

npm install babylonjs

在安装包后,您应该会在脚本文件夹中看到下列文件:

  • babylon.js:Babylon.js 的简化版本
  • babylon.max.js:Babylon.js 的调试版本
  • Oimo.js:Oimo JS 物理引擎,本教程的第二部分中将会用到
  • poly2tri.js:可选的三边转换库 (github.com/r3mi/poly2tri.js)
  • hand-minified.js:指针事件填充代码;在使用 npm 时缺失,因此使用下列命令进行安装:
npm install handjs

NuGet 安装程序也会创建 index.html 文件和 index.js 文件。

NuGet 包中的错误会在 web.config 中添加不需要的行。请双击此文件,并删除图 4 中突出显示的行(在我的解决方案中,为第 9 行),直至修复完成。

从 web.config 中删除突出显示的行
图 4:从 web.config 中删除突出显示的行

您现在可以测试项目了。使用 Ctrl+Shift+W 或通过单击顶部导航栏的“运行”按钮,在您的默认浏览器中打开项目。如果您看到图 5 中显示的 3D 宇宙飞船,则表明您的项目已准备就绪。

Babylon 默认宇宙飞船
图 5:Babylon 默认宇宙飞船

如果您使用的是其他 IDE,只需按 Babylon.js 文档页中的“创建基本场景”教程执行操作,即可达到当前状态。如果您没有使用 NuGet,我仍然建议您使用 npm 安装依赖项。有关此教程,请访问 bit.ly/1MXT6WP

若要从头开始,请删除 index.js 中的 createScene 函数。

构建基块

我首先将介绍的两个元素是引擎和场景。

引擎是负责与低级 WebGL API 通信的对象(WebGL 1 以 OpenGL ES2 为基础,语法非常相似)。引擎提供了更易于理解的较高级 API,这样您就不必编写低级 WebGL 代码了。这对开发者来说也是透明的。除了初始项目设置之外,我根本不会直接使用引擎。虽然使用此引擎可以完成特定的较低级功能,但我不会涉及这一点。

引擎需要两个参数才能初始化。第一个参数是用于绘制的画布。画布是 index.html 中已有的 HTML 元素。第二个参数是抗锯齿状态(开或关)。

打开当前的空白 index.js,然后添加下列代码行:

function init() {
  var engine = initEngine();
}
function initEngine() {
  // Get the canvas element from index.html
  var canvas = document.getElementById("renderCanvas");
  // Initialize the BABYLON 3D engine
  var engine = new BABYLON.Engine(canvas, true);
  return engine;
}

在开发期间,我将使用 init 函数为每一步添加新功能。我创建的每个元素都会有自己的函数。

为了更好地了解场景代表什么,请将场景看成是包含不同网页的网站。一个网页中包含文本、图像、事件监听器以及呈现一个网页所需的其他所有资源。加载不同的网页就是加载不同的资源。

如同一个网页,场景包含显示一个 3D“网页”所需的资源。 此场景可能非常大,包含大量资源(网格、照相机、光、用户操作等)。不过,若要从一个网页移到另一个网页,我建议使用新场景。场景也负责呈现它自己的资源,并将所需的信息传达给引擎。保龄球游戏只需要一个场景。不过,如果我计划添加新等级或奖分游戏,那么我会使用新场景创建它们。

若要初始化场景,只需要我创建的引擎。在 index.js 中添加以下代码:

function createScene(engine) {
  var scene = new BABYLON.Scene(engine);
  // Register a render loop to repeatedly render the scene
  engine.runRenderLoop(function () {
      scene.render();
  });
}

首先,我将创建场景对象。接下来的代码行是我与引擎的唯一交互。它们会指示引擎,每当呈现循环运行时,呈现此特定场景。

将以下代码行添加到 init 函数的末尾,以真正创建场景:

var scene = createScene(engine);

在继续前,我还需要执行两项操作。当您重设浏览器窗口大小时,画布也会重设大小。引擎还必须重设其内部宽度和高度,以使场景比例正确。就在返回引擎前,向 initEngine 函数添加下列代码行;声明会使场景比例正确。

// Watch for browser/canvas resize events
window.addEventListener("resize", function () {
  engine.resize();
});

第二项操作是,将 index.html 更改为使用新的 init 函数。打开 index.html,然后查找包含 createScene 调用的脚本标记。将 createScene 更改为 init,然后保存 index.html 并关闭。

此场景的调试层极为高级,可方便您调试正在呈现的场景。它显示正在呈现的网格数以及当前的每秒帧数 (FPS)。借助它,您可以关闭纹理和阴影等功能,并能轻松找到丢失的网格。开启调试层非常简单:

scene.debugLayer.show();

开启后,您便能自行调试场景。

此时,我已有引擎和场景,我可以开始添加照相机、光源和网格来创建我的保龄球馆场景了。

相机

Babylon.js 提供很多类型的照相机,每个都有自己的特定用途。在为游戏选择照相机之前,让我们先回顾一下最常见的类型:

  • 自由照相机是一种由第一人称拍摄的照相机。使用键盘上的箭头键,可以自由地在整个场景中移动它,并能使用鼠标设置方向。还可以视需要选择启用重力和碰撞检测。
  • 弧形旋转照相机用于围绕特定的目标旋转。使用鼠标、键盘或触摸事件,用户可以全方位地查看对象。
  • 触控照相机是一种使用触摸事件作为输入的自由照相机。它适合所有的移动平台。
  • 跟随照相机自动跟踪特定目标。

Babylon.js 对 WebVR 和设备方向照相机提供本地支持。也就是说,您很容易就可以将此类设备列为 Oculus Rift 或 Google Cardboard。

第 2.1 版中引入的新概念让每种类型的照相机都支持 3D。也就是说,每种类型的照相机都可以设置为适应 Oculus Rift 式立体视图和红蓝眼镜(3D 立体)。图 6 展示了使用非立体照相机呈现的宇宙飞船场景,图 7 展示了使用立体照相机呈现的场景。

非 3D 立体照相机
图 6:非 3D 立体照相机

立体照相机
图 7:立体照相机

对于我的保龄球游戏,我将使用两种类型的照相机。第一种是玩家的主要照相机,用于设置保龄球的掷出位置。这就体现了自由照相机的确切用途。我还想添加不同的视图,即当球在球道中时,我想跟随它直到其撞击到保龄球瓶。

首先,我将添加自由照相机。createFreeCamera 函数将场景视作一个变量:

function createFreeCamera(scene) {
  var camera = new BABYLON.FreeCamera(
    "player camera", BABYLON.Vector3.Zero(), scene);
  return camera;
}

我在场景的 0,0,0 位置处创建了照相机位置。稍后,我将把此函数扩展(必要时)为进一步配置照相机。

当然,别忘了最后将它添加到 init 函数中:

...
// Create the main player camera
var camera = createFreeCamera(scene);
// Attach the control from the canvas' user input
camera.attachControl(engine.getRenderingCanvas());
// Set the camera to be the main active camera
scene.activeCamera = camera;

attachControl 函数注册特定照相机所需的本地 JavaScript 事件监听器(如鼠标、触摸或键盘输入的事件监听器)。设置场景的活动照相机可以指示场景,此照相机应该用于呈现。

在启用掷球后,我将在第二部分中添加第二种照相机。

创建球道

保龄球球道是一种相对简单的几何结构。我将先设置一些常量作为保龄球球道的实际尺寸(以米为单位)。我以米为单位是因为使用的是物理引擎(我将在本文的第二部分中予以解释)。

您可以在项目文件中看到常量。为了计算这些值,我参考了网上关于保龄球球道的可用信息。

在设置这些常量后,我就可以开始创建构成保龄球球道的网格了。图 8 展示了我的 (2D) 规划。我将先创建网格。然后,我会设置网格纹理(即指定材料)。

保龄球球道场景的 2D 规划
图 8:保龄球球道场景的 2D 规划

首先,我将为场景创建全场地板:

function createFloor(scene) {
  var floor = BABYLON.Mesh.CreateGround("floor", 100, 100, 1, scene, false);
  return floor;
}

这会创建一块简单的 100x100 米地板。使用 Babylon.js 内部函数创建的所有网格都集中位于场景的 0,0,0 位置处。有三个重要的变量用于转换网格并在场景中正确定位网格:

  • mesh.position 是网格在空间中的位置的矢量
  • mesh.scaling 是网格在每个轴中的比例系数
  • mesh.rotation 是每个轴的旋转欧拉角(以弧度为单位);如果您更愿意使用四元(我知道我是这样),则可以改用 mesh.rotationQuaternion

在向 init 函数添加函数并启动场景后,我注意到一个有趣的现象,即我根本看不到我所添加的地板! 原因是照相机和地板两者均创建于空间的同一点 (0,0,0)。由于地面是完全平坦的,因此只有从高空(或低空)审视才会在屏幕上看到它。回到 createCamera 函数中的照相机初始化,我将第二个变量(照相机的初始位置)更改为一个新矢量。现在,照相机离地面有 1.7 个单位(在此示例中,单位为米):

var camera = new BABYLON.FreeCamera(
  "cam", new BABYLON.Vector3(0,1.7,0), scene);

如果您现在启动场景,则会看到地板拉伸超过屏幕的一半(如图 9 所示)。

向场景添加地板
图 9:向场景添加地板

尝试使用箭头和鼠标进行移动,以掌握如何控制自由照相机。

您会注意到地板是全黑的。就缺少光! 我将添加新的函数 createLight(稍后我将会扩展)。

function createLight(scene) {
  var light = new BABYLON.DirectionalLight(
    "dir01", new BABYLON.Vector3(-0.5, -1, -0.5), scene);
  // Set a position in order to enable shadows later
  light.position = new BABYLON.Vector3(20, 40, 20);
  return light;
}

别忘了将以下代码行添加到 init 函数中:

var light = createLight(scene);

Babylon.js 提供四种类型的光:

  • 半球光: 环境光,用地面颜色(正面向下的像素)、天空颜色(正面向上的像素)和反射颜色预定义。
  • 点光: 从一个点向所有方向发射的光(如阳光)。
  • 投射光: 从名称我们就可以看出,这是从一个点以特定发射半径向特定方向发射的光。此类光可以产生阴影。
  • 定向光: 从任意位置向特定方向发射的光。虽然阳光可以为点光,但定向光可以更好地模拟阳光。此类光也可以产生阴影,我的示例中使用的就是这种光。

现在,地板将变成白色。Babylon.js 向尚未分配材料的每个网格分配默认的白色材料。

球道本身就是一个盒子,“躺”在我刚刚创建的地板上:

function createLane(scene) {
  var lane = BABYLON.Mesh.CreateBox("lane", 1, scene, false);
  lane.scaling = new BABYLON.Vector3(
    laneWidth, laneHeight, totalLaneLength);
  lane.position.y = laneHeight / 2; // New position due to mesh centering
  lane.position.z = totalLaneLength / 2;
  return lane;
}

再强调一次,别忘了将此函数添加到 init 中。

您可以看到我是如何使用缩放参数的。我创建了一个大小为 1x1x1 的盒子,然后将它的缩放设置更改为适应我预定义的常量。

使用同样的技术,我创建了两个盒子,它们将用作我球道两边的球槽(若以错误的方向掷出,则球会落入此槽)。您可以自己尝试创建看看,也可以查看随附的项目,看我是如何创建的。

保龄球瓶和球

现在就差保龄球瓶和球了。为了创建保龄球瓶,我将使用圆柱体,只需将一个圆柱体倍增多次即可(确切地说,是 10 次)。在 Babylon.js 中,我们将这样倍增的对象称为实例。实例就是网格的精确副本(在空间中的转换除外)。也就是说,不能更改实例的几何图形和纹理,但可以更改实例的位置、缩放和旋转。我个人从未在场景中使用过原始对象;如果我想要 10 个保龄球瓶,我将会创建 1 个保龄球瓶并禁用它,然后在 10 个预定义位置上创建 10 个保龄球瓶实例:

function createPins(scene) {
  // Create the main pin
  var mainPin = BABYLON.Mesh.CreateCylinder(
    "pin", pinHeight, pinDiameter / 2, pinDiameter, 6, 1, scene);
  // Disable it so it won't show
  mainPin.setEnabled(false);
  return pinPositions.map(function (positionInSpace, idx) {
    var pin = new BABYLON.InstancedMesh("pin-" + idx, mainPin);
    pin.position = positionInSpace;
    return pin;
  });
}

此函数中缺少的变量可以在项目文件中找到,包括 pinPositions(包含所有 10 个保龄球瓶的全局位置的数组)。

现在就差保龄球了。保龄球是一种简单的球体,上有 3 个方便手指插入的孔。为了创建此球体,我将使用 Babylon.js 提供的 CreateSphere 函数:

var sphere = BABYLON.Mesh.CreateSphere("sphere", 12, 0.22, scene);

现在,我需要钻孔。为此,我将使用已集成到 Babylon.js 中的构造实体几何 (CSG) 功能。借助此功能,我可以向现有网格添加网格或从中去掉网格,或者可以向另一个几何体添加几何体或从中去掉几何体(如果能这样,就更好了)。也就是说,如果两个网格相交,我可以从中“去掉”一个网格,获得另一个经过更改的网格。在我的示例中,我想在一个球体中创建三个圆孔。圆柱体就完全适合。

首先,我将创建用于第一个孔的圆柱体:

var cylinder = BABYLON.Mesh.CreateCylinder(
  "cylinder", 0.15, 0.02, 0.02, 8, 1, scene, false);

接下来,我将把圆柱体的位置更改为与球体相交:

cylinder.position.y += 0.15;

然后,我将创建 CSG 对象,并使用它们从球体中去掉圆柱体:

var sphereCSG = BABYLON.CSG.FromMesh(sphere);
var cylinderCSG = BABYLON.CSG.FromMesh(cylinder);
sphereCSG.subtractInPlace(cylinderCSG);
var ball = sphereCSG.toMesh("test", sphere.material, scene, false);

图 10 展示了球体和圆柱体,紧靠着的是使用 CSG 创建的保龄球。

创建保龄球
图 10:创建保龄球

图 11babylonjs-playground.com/#BIG0J 上的园地均展示了从头开始创建保龄球的全部代码。

图 11:使用 CSG 创建保龄球

// The original sphere, from which the ball will be made
var sphere = BABYLON.Mesh.CreateSphere("sphere", 10.0, 10.0, scene);
sphere.material = new BABYLON.StandardMaterial("sphereMat", scene);
// Create pivot-parent-boxes to rotate the cylinders correctly
var box1 = BABYLON.Mesh.CreateBox("parentBox", 1, scene);
var box2 = box1.clone("parentBox");
var box3 = box1.clone("parentBox");
// Set rotation to each parent box
box2.rotate(BABYLON.Axis.X, 0.3);
box3.rotate(BABYLON.Axis.Z, 0.3);
box1.rotate(new BABYLON.Vector3(0.5, 0, 0.5), -0.2);
[box1, box2, box3].forEach(function (boxMesh) {
// Compute the world matrix so the CSG will get the rotation correctly
  boxMesh.computeWorldMatrix(true);
  // Make the boxes invisible
  boxMesh.isVisible = false;
});
// Create the 3 cylinders
var cylinder1 = BABYLON.Mesh.CreateCylinder(
  "cylinder", 4, 1, 1, 30, 1, scene, false);
cylinder1.position.y += 4;
cylinder1.parent = box1;
var cylinder2 = cylinder1.clone("cylinder", box2);
var cylinder3 = cylinder1.clone("cylinder", box3);
// Create the sphere's CSG object
var sphereCSG = BABYLON.CSG.FromMesh(sphere);
// Subtract all cylinders from the sphere's CSG object
[cylinder1, cylinder2, cylinder3].forEach(function (cylinderMesh) {
  sphereCSG.subtractInPlace(BABYLON.CSG.FromMesh(cylinderMesh));
});
// Create a new mesh from the sphere CSG
var ball = sphereCSG.toMesh("bowling ball", sphere.material, scene, false);

纹理

我创建的全部网格均分配有默认的白色材料。为了使场景更具吸引力,我应该添加其他材料。标准 Babylon.js 材料(默认着色器)有很多定义,我不会在此进行介绍。(若要详细了解默认 Babylon.js 着色器,您可以试用 materialeditor.raananweber.com 上的 BabylonJS 材料编辑器。) 不过,我将介绍我是如何设置球道和保龄球的纹理的。

为了设置保龄球的纹理,我将使用另一项精彩的 Babylon.js 功能,即过程化纹理。过程化纹理不是使用 2D 图像的标准纹理,而是以编程方式创建的纹理(由 GPU(而不是 CPU)生成),能够对场景的效果产生积极影响。Babylon 提供多种类型的过程化纹理(木质、砖块、火、云、草等)。我将要使用的是大理石纹理。

在创建保龄球的网格后,添加以下代码行会让保龄球变成绿色的大理石球(如图 12 所示):

var marbleMaterial = new BABYLON.StandardMaterial("ball", scene);
var marbleTexture = new BABYLON.MarbleProceduralTexture(
  "marble", 512, scene);
marbleTexture.numberOfTilesHeight = 2;
marbleTexture.numberOfTilesWidth = 2;
marbleMaterial.ambientTexture = marbleTexture;
// Set the diffuse color to the wanted ball's color (green)
marbleMaterial.diffuseColor = BABYLON.Color3.Green();
ball.material = marbleMaterial;

应用于保龄球的大理石纹理
图 12:应用于保龄球的大理石纹理

可以使用标准材料的漫射纹理,向球道添加木质纹理。不过,这不是我要谈论球道材料的原因所在。如果您看过真实的保龄球球道,则会注意到球道上面有多组点和一组箭头或三角形。为了模拟这样的球道,我可以创建一个非常大的纹理,其上包含所有这些元素,但这样做可能会影响性能(由于纹理非常大)或降低图像质量。

我也可以使用贴花纸,这是 Babylon.js 2.1 中引入的一项新功能。借助贴花纸,您可以在已设置纹理的网格之上“绘制”图形。例如,贴花纸可用于模拟墙上的枪孔,或在保龄球球道上添加装饰(如我的示例所示)。由于贴花纸是网格,因此使用标准材料设置纹理。图 13 展示了我是如何添加边线的,图 14 展示了在我添加贴花纸后保龄球球道的外观,以及在我将过程化纹理(砖块和草)用作材料后地板和球槽的外观。

图 13:添加边线贴花纸

// Set the decal's position
var foulLinePosition = new BABYLON.Vector3(0, laneHeight, foulLaneDistance);
var decalSize = new BABYLON.Vector3(1,1,1);
// Create the decal (name, the mesh to add it to, position, up vector and the size)
var foulLine = BABYLON.Mesh.CreateDecal("foulLine", lane, foulLinePosition, BABYLON.Vector3.Up(), decalSize);
// Set the rendering group so it will render after the lane
foulLine.renderingGroupId = 1;
// Set the material
var foulMaterial = new BABYLON.StandardMaterial("foulMat", scene);
foulMaterial.diffuseTexture =
  new BABYLON.Texture("Assets/dots2-w-line.png", scene);
foulMaterial.diffuseTexture.hasAlpha = true;
foulLine.material = foulMaterial;
// If the action manager wasn't initialized, create a new one
scene.actionManager = new BABYLON.ActionManager(scene);
// Register an action to generate a new color each time I press "c"
scene.actionManager.registerAction(new BABYLON.ExecuteCodeAction({
  trigger: BABYLON.ActionManager.OnKeyUpTrigger, parameter: "c" },
  // The function to execute every time "c" is pressed"
  function () {
    ball.material.diffuseColor =
      new BABYLON.Color3(Math.random(), Math.random(), Math.random());
  }
));

添加了贴花纸的球道
图 14:添加了贴花纸的球道

用户输入 - Babylon.js 操作管理器

作为功能齐全的游戏引擎,Babylon.js 提供了一种与用户输入进行交互的简单方式。假设我想使用 C 键更改保龄球的颜色。每次按下 C,我都想为保龄球设置一种随机颜色:

// If the action manager wasn't initialized, create a new one
scene.actionManager = new BABYLON.ActionManager(scene);
// Register an action to generate a new color each time I press C
scene.actionManager.registerAction(
  new BABYLON.ExecuteCodeAction({ trigger:
  BABYLON.ActionManager.OnKeyUpTrigger, parameter: "c" },
  // The function to execute every time C is pressed
  function () {
    ball.material.diffuseColor =
      new BABYLON.Color3(Math.random(), Math.random(), Math.random());
  }
));

Babylon.js 操作管理器是一款功能强大的工具,可用于根据触发器控制操作。触发器可以是鼠标移动或单击、网格相交或键盘输入。有很多触发器和操作可供选择。请访问 Babylon.js 教程站点 (bit.ly/1MEkNRo),了解全部触发器和操作。

我将使用操作管理器控制保龄球并重置场景。我将在本教程的第 2 部分中添加这些操作。

使用外部资源

我已使用 Babylon.js 的内部函数创建了所需的网格。大多数情况下,这是不够的。Babylon.js 提供了很多网格(从球体和盒子到复杂的带状物),但创建复杂的模型是很难的,如人、Web 版 Doom 中的武器或 Space Invaders 克隆中的宇宙飞船。

Babylon.js 为很多知名的 3D 工具(如 Blender 和 3D-Studio)提供了导出程序插件。您也可以从出色的 Clara.io 中导出您的模型,然后下载 .babylon 文件。

Babylon.js 使用自己的文件格式,这种格式可以包含整个场景,包括网格、照相机、光、动画、几何体和其他信息。因此,如果您愿意,可以将 Blender 仅用于模拟整个场景。您还可以导入单个网格。

不过,这并不在本教程的范围之内。对于本文,我只想展示如何只使用 Babylon.js 创建简单的游戏。

下一步是什么?

我已跳过 Babylon.js 中集成的许多功能。它具有大量功能,我强烈建议您查看园地 (babylonjs-playground.com)、文档页 (doc.babylonjs.com) 和 Babylon.js 主页 (babylonjs.com),看看如何开创无限可能。如果您觉得本教程的任何部分比较难懂,请联系我或十分活跃的 Babylon.js HTML5 游戏开发论坛 (bit.ly/1GmUyzq) 上的任何一位 Babylon.js 大神。

在下一篇文章中,我将创建实际的游戏,即添加物理特性和碰撞检测、掷球功能、音频等。


Raanan Weber既是一名 IT 顾问、完整堆栈开发者,也是一名丈夫和父亲。空闲时,他为 Babylon.js 和其他开放源代码项目献计献策。您可以阅读他的博客 (blog.raananweber.com)。

衷心感谢以下 Microsoft 技术专家对本文的审阅: David Catuhe