本文给大家介绍如何为 JS 游戏引擎添加 DOM UI,下图里的手机、日志面板、控制面板均用 DOM 实现,而非使用 Canvas 绘制:

需求描述
通常我们整个游戏场景的核心视图是基于 Canvas 绘制的,我们将那些不是用 Canvas 绘制的、直接由 DOM 构成的视图定义为 DOM UI。
DOM UI 是游戏场景 UI 层的一种实现方式,游戏场景 UI 层用于容纳不属于游戏世界的元素,比如一个箱子是属于游戏世界的,但一份游戏说明并不属于游戏世界,或者说游戏世界中的角色“看”不到这份游戏说明,因为它是设计给用户看的。
我们当然可以使用 Canvas 实现游戏场景的 UI 层,但使用 DOM 会更好,主要考虑两点:
- 开发效率更高:一方面写 HTML/CSS/JS 比调用 Canvas 绘制 API 要简单许多;另一方面,我们还能使用丰富的前端框架进一步提高写 HTML/CSS/JS 的效率。可以想象,要开发上面效果图里的手机,使用 Canvas 绘制 API 会相当复杂。
- 实现效果更好:一方面是在处理用户输入事件时,DOM 的事件机制性能可能会更好,如果使用 Canvas,则需要通过监听 Canvas 的事件再查找目标元素,这个查找过程可能会使用到遍历,而遍历的耗时正相关于游戏场景内的元素数量;另一方面在缩放页面时,DOM 视图不会变模糊,而 Canvas 是基于像素的,在放大页面的情况下,画布内容会变模糊,为了保证其不变模糊,往往需要调整画布的分辨率,但这也增加了复杂度。
那么该如何让当前的 JS 游戏引擎支持添加上面提到的这种 DOM UI 呢?
需求分析
很自然地,我们需要解决两个关键问题:
- 如何使用 DOM UI?具体点,它是一种资源吗?和 Model (ECSM 架构)有什么关系?
- 如何开发 DOM UI?具体点,要用原生的 HTML/CSS/JS 还是基于框架?
方案设计
定义形式
DOM UI 的组成就是 HTML/CSS/JS,所以它的实际存在形式就是 HTML/CSS/JS,可以是内容字符串,也可以是文件:
// index.template
<div id='phone' class='phone'>phone</div>
// index.css
.phone {
color: blue }
// index.js
const phone = document.getElementById('phone');
我们把 DOM UI 当做一种静态资源,就像是一张图片,可以为 Model 所引用:
public/
|--models/
|--Customer/
|--index.js
|--avatar.png
|--dom/ // ===> 这个目录下用于存储 DOM UI 资源
|--Phone/ // ===> 这里定义了一个手机组件
|--index.template
|--index.css
|--index.js
引用方式
在 Model 里该如何引用 DOM UI 呢?我们基于 ECSM 架构,定义了一种 DOM Component,用来存储 DOM UI 相关的数据:

最低0.47元/天 解锁文章
510

被折叠的 条评论
为什么被折叠?



