UNPKG

mm_os

Version:

MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。

467 lines (413 loc) 10.9 kB
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;