mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
467 lines (413 loc) • 10.9 kB
JavaScript
const {
Drive
} = require('mm_machine');
/**
* 场景基类
* 负责管理游戏场景中的实体和图层,处理场景生命周期
* 场景是Entity实例的容器,管理实体的生命周期
*/
class Scene extends Drive {
static config = {
// 场景名称
name: 'default',
// 场景描述
desc: '',
// 场景优先级
priority: 0,
// 是否激活场景
active: true
};
/**
* 构造函数
* @param {object} config 配置参数
* @param {object} parent 父场景对象
*/
constructor(config, parent) {
super({ ...Scene.config, ...config || {} }, parent);
// 系统实例集合,主要调用场景系统SceneSystem
this._system = {};
// 图层映射集合
this._layers = {};
// 地图实例集合
this.map = {};
// /**
// * 地图集合
// * @type {object} 地图对象
// */
// this.maps = new Map();
// // 实体集合
// this._entities = new Map();
}
}
/**
* 预设
*/
Scene.prototype._preset = function () {
// 是否激活场景
this.active = this.config.active;
};
/**
* 获取模板目录
* @returns {string} 模板目录
*/
Scene.prototype.getTplDir = function () {
return __dirname;
};
/**
* 初始化核心
* @override
* @param {object} system 系统对象
* @param {object} eventer 事件对象
* @param {object} logger 日志对象
* @returns {Promise<void>}
*/
Scene.prototype._initCore = async function (system, eventer, logger) {
// 初始化依赖项
if (logger) {
this.setLogger(logger);
}
if (eventer) {
this.getEventer = function () {
return eventer;
};
}
if (system) {
this._system = system;
}
// 初始化场景
await this._loadSources();
// 初始化地图
await this._initMap();
// 初始化实体
await this._initEntities();
// 触发场景加载事件
this.emitEvent('scene_load', {
scene_id: this.scene_id,
scene_name: this.config.name,
timestamp: Date.now()
});
};
/**
* 初始化地图
* @private
*/
Scene.prototype._initMap = async function () {
// 子类应重写此方法初始化地图
};
/**
* 加载场景资源
* @private
* @returns {Promise<void>}
*/
Scene.prototype._loadSources = async function () {
// 子类应重写此方法加载场景所需资源
};
/**
* 添加实体到场景
* @param {object} entity 实体对象
* @returns {boolean} 添加是否成功
*/
Scene.prototype.addEntity = function (entity) {
// 参数校验
if (!entity || typeof entity !== 'object') {
this.log('error', '实体必须是非空对象');
return false;
}
// 检查实体是否已存在
if (this._entities.has(entity.entity_id)) {
return true; // 已存在,返回成功
}
// 添加实体
this._entities.set(entity.entity_id, entity);
// 设置实体的场景引用
if (entity.setScene && typeof entity.setScene === 'function') {
entity.setScene(this);
}
this.log('info', `实体 [${entity.entity_id}] 添加到场景`);
return true;
};
/**
* 从场景移除实体
* @param {object|string} entity 实体对象或实体ID
* @returns {boolean} 移除是否成功
*/
Scene.prototype.delEntity = function (entity) {
// 参数校验
if (!entity) {
this.log('error', '实体参数不能为空');
return false;
}
// 如果是ID,直接从Map中移除
if (typeof entity === 'string') {
if (!this._entities.has(entity)) {
return false; // 实体不存在
}
this._entities.delete(entity);
this.log('info', `实体 [${entity}] 从场景移除`);
return true;
}
// 如果是对象,使用实体ID移除
if (!entity.entity_id || !this._entities.has(entity.entity_id)) {
return false; // 实体不存在于场景中
}
this._entities.delete(entity.entity_id);
this.log('info', `实体 [${entity.entity_id}] 从场景移除`);
return true;
};
/**
* 根据ID或属性查找实体
* @param {string | number | object} query 查询条件
* @returns {object|null} 找到的实体或null
*/
Scene.prototype.findEntity = function (query) {
if (!query) {
return null;
}
if (typeof query === 'string' || typeof query === 'number') {
return this._findById(query);
}
if (query.prototype && typeof query === 'function') {
return this._findByType(query);
}
if (typeof query === 'object') {
return this._findByProps(query);
}
return null;
};
/**
* 根据ID查找实体
* @param {string | number} id 实体ID
* @returns {object|null} 找到的实体或null
*/
Scene.prototype._findById = function (id) {
return this._entities.get(id) || null;
};
/**
* 根据构造函数类型查找实体
* @param {Function} type 构造函数
* @returns {object|null} 找到的实体或null
*/
Scene.prototype._findByType = function (type) {
for (let entity of this._entities.values()) {
if (entity instanceof type) {
return entity;
}
}
return null;
};
/**
* 根据属性对象查找实体
* @param {object} props 属性对象
* @returns {object|null} 找到的实体或null
*/
Scene.prototype._findByProps = function (props) {
for (let entity of this._entities.values()) {
if (this._matchProps(entity, props)) {
return entity;
}
}
return null;
};
/**
* 检查实体属性是否匹配
* @param {object} entity 实体
* @param {object} props 属性对象
* @returns {boolean} 是否匹配
*/
Scene.prototype._matchProps = function (entity, props) {
for (let key in props) {
if (entity[key] !== props[key]) {
return false;
}
}
return true;
};
/**
* 查找符合条件的所有实体
* @param {object} query 查询条件
* @returns {Array} 符合条件的实体数组
*/
Scene.prototype.findEntities = function (query = {}) {
if (!query || typeof query !== 'object') {
return [...this._entities.values()];
}
let result = [];
for (let entity of this._entities.values()) {
let match = true;
for (let key in query) {
if (entity[key] !== query[key]) {
match = false;
break;
}
}
if (match) {
result.push(entity);
}
}
return result;
};
/**
* 添加图层
* @param {string} name 图层名称
* @param {object} layer 图层对象
* @returns {boolean} 添加是否成功
*/
Scene.prototype.addLayer = function (name, layer) {
// 参数校验
if (!name || typeof name !== 'string') {
this.log('error', '图层名称必须是非空字符串');
return false;
}
if (!layer || typeof layer !== 'object') {
this.log('error', '图层对象必须是非空对象');
return false;
}
// 添加图层
this._layers[name] = layer;
return true;
};
/**
* 获取图层
* @param {string} name 图层名称
* @returns {object | null} 图层对象或null
*/
Scene.prototype.getLayer = function (name) {
if (!name || typeof name !== 'string') {
this.log('error', '图层名称必须是非空字符串');
return null;
}
return this._layers[name] || null;
};
/**
* 更新场景
* @param {number} delta 时间间隔(毫秒)
*/
Scene.prototype.set = function (delta) {
// 如果场景不活跃,不更新
if (!this.active) {
return;
}
// 更新所有实体
for (let entity of this._entities.values()) {
try {
if (entity.update && typeof entity.update === 'function') {
entity.update(delta);
}
} catch (error) {
this.log('error', '更新实体时出错:', error);
// 可以选择移除出错的实体
// this.delEntity(entity);
}
}
};
/**
* 渲染场景
*/
Scene.prototype.render = function () {
// 如果场景不活跃,不渲染
if (!this.active) {
return;
}
// 渲染所有图层
Object.values(this._layers).forEach(layer => {
try {
if (layer.render && typeof layer.render === 'function') {
layer.render();
}
} catch (error) {
this.log('error', '渲染图层时出错:', error);
}
});
};
/**
* 清理场景资源
* @override
*/
Scene.prototype._destroy = function () {
try {
// 触发场景卸载事件
this.emitEvent('scene_unload', {
scene_id: this.scene_id,
scene_name: this.config.name,
timestamp: Date.now()
});
// 清理所有实体
for (let entity of this.map._entities.values()) {
try {
if (entity.destroy && typeof entity.destroy === 'function') {
entity.destroy();
}
} catch (error) {
this.log('error', '销毁实体时出错:', error);
}
}
// 清空引用
this.map._entities = null;
} catch (error) {
this.log('error', '场景销毁失败:', error);
}
};
/**
* 实体进入场景
* @param {object} entity 实体对象
* @returns {boolean} 是否成功进入
*/
Scene.prototype.enter = async function (entity) {
// 参数校验
if (!entity || typeof entity !== 'object') {
throw new TypeError('实体对象必须是非空对象');
}
// 添加实体到场景
this._entities.set(entity.entity_id, entity);
// 触发实体进入场景事件(如果事件总线存在)
this.emitEvent('entity_enter_scene', {
scene_id: this.scene_id,
scene_name: this.config.name,
entity_id: entity.entity_id,
timestamp: Date.now()
});
return true;
};
/**
* 实体离开场景
* @param {object} entity 实体对象
* @returns {boolean} 是否成功离开
*/
Scene.prototype.leave = async function (entity) {
// 参数校验
if (!entity || typeof entity !== 'object') {
throw new TypeError('实体对象必须是非空对象');
}
// 从场景移除实体
if (!entity.entity_id || !this._entities.has(entity.entity_id)) {
throw new Error('实体不在场景中');
}
this._entities.delete(entity.entity_id);
// 触发实体离开场景事件(如果事件总线存在)
this.emitEvent('entity_leave_scene', {
scene_id: this.scene_id,
scene_name: this.config.name,
entity_id: entity.entity_id,
timestamp: Date.now()
});
return true;
};
/**
* 更新场景
* @param {number} delta 时间间隔(毫秒)
*/
Scene.prototype.update = function (delta) {
// 如果场景不活跃,不更新
if (!this.isRunning()) {
return;
}
// 触发场景更新事件
this.emitEvent('scene_update', {
scene_id: this.scene_id,
scene_name: this.config.name,
delta: delta,
timestamp: Date.now()
});
};
// 导出模块
exports.Scene = Scene;