今天初步学了一下 Babylon.js,参考新手教程把项目架子搭了起来。

随后在文档里寻找了一番,找到了可以画圆柱体的 API(MeshBuilder.CreateCylinder)。厉害的是,它不光可以画圆柱体,还能画圆锥体。这俩一组装,不就是火箭吗?于是就试着捣鼓了一下,算是把一个简单的火箭画了出来。

效果如下:

简单的火箭模型

下次试试画一个喷射的火焰效果,加在火箭底部,就更有感觉了😁。

完整代码如下:


import "@babylonjs/core/Debug/debugLayer";
import "@babylonjs/inspector";
import "@babylonjs/loaders/glTF";
import { Engine, Scene, ArcRotateCamera, Vector3, HemisphericLight, Mesh, MeshBuilder } from "@babylonjs/core";

class App {
  constructor() {
    // create the canvas html element and attach it to the webpage
    var canvas = document.createElement("canvas");
    canvas.style.width = "100%";
    canvas.style.height = "100%";
    canvas.id = "gameCanvas";
    document.body.appendChild(canvas);

    // initialize babylon scene and engine
    var engine = new Engine(canvas, true);
    var scene = new Scene(engine);

    // 镜头
    var camera: ArcRotateCamera = new ArcRotateCamera(
      "Camera",
      Math.PI / 2,
      Math.PI / 2,
      20,
      Vector3.Zero(),
      scene
    );
    camera.attachControl(canvas, true);

    // 光源
    var light1: HemisphericLight = new HemisphericLight(
      "light1",
      new Vector3(10, 5, 5),
      scene
    );

    // 主火箭
    this._createRocket('main', 10, 2, 0, 0, 0)
    // 辅助推进器——体积较小的火箭
    this._createRocket('r1', 4, 1, 1.5, -3, 0)
    // 一边一个
    this._createRocket('r2', 4, 1, -1.5, -3, 0)

    // hide/show the Inspector
    // 快捷键唤起 Babylon.js 的调试工具,非常有用,可以让你看到每个实体占据的立体空间,便于计算和调整坐标。
    window.addEventListener("keydown", (ev) => {
      // Shift+Ctrl+Alt+I
      if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.keyCode === 73) {
        if (scene.debugLayer.isVisible()) {
          scene.debugLayer.hide();
        } else {
          scene.debugLayer.show();
        }
      }
    });

    // run the main render loop
    engine.runRenderLoop(() => {
      scene.render();
    });
  }

  /**
   * 封装了一个绘制火箭的方法。
   * 火箭由三个部分组成:箭头、箭体、箭尾(就是底部喷火的地方,不知道术语叫什么,暂时先叫它箭尾吧)
   */
  private _createRocket(
    // 实体名称
    name: string,
    // 箭体高度
    height: number,
    // 箭体直径
    diameter: number,
    // 箭体的坐标
    x: number,
    y: number,
    z: number,
  ) {
    // 箭体是一个圆柱体
    const cylinder = MeshBuilder.CreateCylinder(name + "Cylinder", {
      height,
      diameter,
    });
    cylinder.position.x = x
    cylinder.position.y = y
    cylinder.position.z = z

    // 箭头是一个圆锥体,直径与箭体相同,高度是箭体的 1/5
    const headHeight = height / 5
    const coneHead = MeshBuilder.CreateCylinder(name + 'ConeHead', {
      height: headHeight,
      diameterTop: 0,
      diameterBottom: diameter,
    })
    coneHead.position.x = x
    // 箭头与箭体刚好衔接在一起
    coneHead.position.y = y + (headHeight + height) / 2
    coneHead.position.z = z

    // 箭尾是一个顶面较小,底面较大的圆柱体(还算是圆柱体吗?),有点像烟囱
    const tailHeight = height / 10
    const coneTail = MeshBuilder.CreateCylinder(name + 'ConeTail', {
      height: tailHeight,
      diameterTop: diameter * 0.5,
      diameterBottom: diameter * 0.8,
    })
    coneTail.position.x = x
    // 箭尾一半嵌在箭体里,一半在箭体外面
    coneTail.position.y = y - height / 2
    coneTail.position.z = z
  }
}
new App();

调试工具的效果如下: 调试工具

调试过程中遇到的一个问题是,有时候从其他页面或者从编辑器切换到调试页面,电脑显示器会黑屏几秒再恢复。

Next