今天初步学了一下 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();
调试工具的效果如下:
调试过程中遇到的一个问题是,有时候从其他页面或者从编辑器切换到调试页面,电脑显示器会黑屏几秒再恢复。