diff --git a/public/libs/control.js b/public/libs/control.js index a4afba9..0e6a9ca 100644 --- a/public/libs/control.js +++ b/public/libs/control.js @@ -1325,6 +1325,8 @@ control.prototype.startReplay = function (list) { this._replay_drawProgress(); core.updateStatusBar(false, true); core.drawTip('开始播放'); + Mota.require('var', 'hook').emit('replayStatus', false); + Mota.require('class', 'CustomToolbar').setDefaultTool(true); this.replay(); }; @@ -1340,6 +1342,7 @@ control.prototype.pauseReplay = function () { core.status.replay.pausing = true; core.updateStatusBar(false, true); core.drawTip('暂停播放'); + Mota.require('var', 'hook').emit('replayStatus', false); }; ////// 恢复播放 ////// @@ -1353,6 +1356,7 @@ control.prototype.resumeReplay = function () { core.updateStatusBar(false, true); core.drawTip('恢复播放'); core.replay(); + Mota.require('var', 'hook').emit('replayStatus', true); }; ////// 单步播放 ////// @@ -1417,6 +1421,8 @@ control.prototype.stopReplay = function (force) { core.deleteCanvas('replay'); core.updateStatusBar(false, true); core.drawTip('停止播放并恢复游戏'); + Mota.require('var', 'hook').emit('replayStatus', true); + Mota.require('class', 'CustomToolbar').setDefaultTool(false); }; ////// 回退 ////// @@ -1453,6 +1459,7 @@ control.prototype.rewindReplay = function () { core.control._replay_drawProgress(); core.updateStatusBar(false, true); core.drawTip('成功回退到上一个节点'); + Mota.require('class', 'CustomToolbar').setDefaultTool(true); }); }; @@ -1686,6 +1693,7 @@ control.prototype._replay_error = function (action, callback) { if (core.status.replay.save.length > 0) { core.status.replay.replaying = true; core.status.replay.pausing = true; + Mota.require('var', 'hook').emit('replayStatus', false); core.rewindReplay(); } else { core.playSound('操作失败'); diff --git a/public/libs/events.js b/public/libs/events.js index c9a0dda..7b4d94f 100644 --- a/public/libs/events.js +++ b/public/libs/events.js @@ -4492,19 +4492,27 @@ events.prototype._checkLvUp_check = function () { ////// 尝试使用道具 ////// events.prototype.tryUseItem = function (itemId, noRoute, callback) { - if (itemId == 'book') { - core.ui.closePanel(); - core.openBook(false); + if (itemId === 'book') { + if (core.isReplaying()) { + core.control._replay_book(); + } else { + core.ui.closePanel(); + core.openBook(false); + callback?.(); + } + return; + } + if (core.isReplaying()) { callback?.(); return; } - if (itemId == 'fly') { + if (itemId === 'fly') { core.ui.closePanel(); core.useFly(false); callback?.(); return; } - if (itemId == 'centerFly') { + if (itemId === 'centerFly') { core.ui.closePanel(); core.ui._drawCenterFly(); callback?.(); diff --git a/public/project/functions.js b/public/project/functions.js index 419f9c2..a9eb14f 100644 --- a/public/project/functions.js +++ b/public/project/functions.js @@ -77,6 +77,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = { delete flags[v]; }); } + + Mota.require('class', 'CustomToolbar').setDefaultTool(false); }, win: function (reason, norank, noexit) { // 游戏获胜事件 diff --git a/src/core/main/custom/toolbar.ts b/src/core/main/custom/toolbar.ts index cfb09c8..56ba076 100644 --- a/src/core/main/custom/toolbar.ts +++ b/src/core/main/custom/toolbar.ts @@ -127,6 +127,48 @@ const misc: Misc = { } }; +const playingDefaultTool: MiscToolbar = { + id: '@defaults_misc', + type: 'misc', + folded: false, + noDefaultAction: true, + items: [ + 'book', + 'fly', + 'save', + 'load', + 'toolbox', + 'equipbox', + 'shop', + 'virtualKey', + 'setting', + 'undo', + 'redo', + 'viewMap', + 'danmaku', + 'minimap' + ] +}; +const replayingDefaultTool: MiscToolbar = { + id: '@defaults_misc', + type: 'misc', + folded: false, + noDefaultAction: true, + items: [ + 'startReplay', + 'stopReplay', + 'rewindReplay', + 'stepReplay', + 'book', + 'speedDownReplay', + 'speedUpReplay', + 'save', + 'viewMap', + 'danmaku', + 'minimap' + ] +}; + export class CustomToolbar extends EventEmitter { static num: number = 0; static list: CustomToolbar[] = shallowReactive([]); @@ -369,6 +411,44 @@ export class CustomToolbar extends EventEmitter { static closeAll() { this.list.forEach(v => v.closeAll()); } + + /** + * 设置默认工具栏的内容 + */ + static setDefaultTool(replaying: boolean) { + const mainStorage = GameStorage.for(GameStorage.fromGame('main')); + mainStorage.read(); + let defaultsTool = CustomToolbar.list.find(v => v.id === '@defaults'); + const hasDefaults = !!defaultsTool; + if (!defaultsTool) { + defaultsTool = new CustomToolbar('@defaults', true); + } + defaultsTool.closeAll(); + defaultsTool.items.splice(0); + defaultsTool.add(replaying ? replayingDefaultTool : playingDefaultTool); + if (!mainStorage.getValue('played', false)) { + mainStorage.setValue('played', true); + + // 计算位置,显示在游戏画面下方 + if (!hasDefaults) { + const game = core.dom.gameDraw; + const bottom = game.offsetTop + game.offsetHeight; + const left = game.offsetLeft; + const width = game.offsetWidth; + + if (isMobile) { + // 手机端显示在最下方 + defaultsTool.setPos(16, bottom); + defaultsTool.setSize(window.innerWidth - 32, 85); + } else { + // 电脑显示在屏幕右方 + defaultsTool.setPos(left, bottom); + defaultsTool.setSize(width, 70); + } + } + } + defaultsTool.show(); + } } Mota.require('var', 'loading').once('coreInit', () => { @@ -387,57 +467,6 @@ Mota.require('var', 'hook').on('reset', () => { }); Mota.require('var', 'hook').once('reset', () => { - const mainStorage = GameStorage.for(GameStorage.fromGame('main')); - mainStorage.read(); - if (!mainStorage.getValue('played', false)) { - mainStorage.setValue('played', true); - let defaultsTool = CustomToolbar.list.find(v => v.id === '@defaults'); - const hasDefaults = !!defaultsTool; - if (!defaultsTool) { - defaultsTool = new CustomToolbar('@defaults', true); - } - defaultsTool.closeAll(); - defaultsTool.items = reactive([]); - defaultsTool.add({ - id: '@defaults_misc', - type: 'misc', - folded: false, - noDefaultAction: true, - items: [ - 'book', - 'fly', - 'save', - 'load', - 'toolbox', - 'equipbox', - 'shop', - 'virtualKey', - 'setting', - 'undo', - 'redo', - 'danmaku', - 'minimap' - ] - }); - // 计算位置,显示在游戏画面下方 - if (!hasDefaults) { - const game = core.dom.gameDraw; - const bottom = game.offsetTop + game.offsetHeight; - const left = game.offsetLeft; - const width = game.offsetWidth; - - if (isMobile) { - // 手机端显示在最下方 - defaultsTool.setPos(16, bottom); - defaultsTool.setSize(window.innerWidth - 32, 85); - } else { - // 电脑显示在屏幕右方 - defaultsTool.setPos(left, bottom); - defaultsTool.setSize(width, 70); - } - } - - defaultsTool.show(); - CustomToolbar.save(); - } + CustomToolbar.setDefaultTool(false); + CustomToolbar.save(); }); diff --git a/src/core/main/init/toolbar.tsx b/src/core/main/init/toolbar.tsx index 40bf42a..1d6519d 100644 --- a/src/core/main/init/toolbar.tsx +++ b/src/core/main/init/toolbar.tsx @@ -18,18 +18,24 @@ import { import { MotaSettingItem, mainSetting } from '../setting'; import Minimap from '@/components/minimap.vue'; import { gameKey } from '../custom/hotkey'; -import { FunctionalComponent, StyleValue, h } from 'vue'; +import { FunctionalComponent, StyleValue, h, ref } from 'vue'; import { mainUi } from './ui'; import { isMobile } from '@/plugin/use'; import { + BackwardFilled, BackwardOutlined, + BorderOuterOutlined, + CaretRightOutlined, EllipsisOutlined, FolderOpenOutlined, + ForwardOutlined, LayoutOutlined, MessageOutlined, + PauseOutlined, RetweetOutlined, RollbackOutlined, - SwapOutlined + StepBackwardOutlined, + StepForwardOutlined } from '@ant-design/icons-vue'; import { generateKeyboardEvent } from '../custom/keyboard'; @@ -758,6 +764,10 @@ Mota.require('var', 'hook').once('reset', () => { const scale = mainSetting.getSetting('ui.toolbarScale') as Readonly< MotaSettingItem >; + const replaying = ref(false); + Mota.require('var', 'hook').on('replayStatus', re => { + replaying.value = re; + }); CustomToolbar.misc.register('danmaku', '发弹幕', openDanmakuPoster, () => h(MessageOutlined) @@ -869,7 +879,11 @@ Mota.require('var', 'hook').once('reset', () => { 'save', '存档', () => { - core.save(true); + if (core.isReplaying()) { + core.control._replay_SL(); + } else { + core.save(true); + } }, () => ( { }, () => h(LayoutOutlined) ); + CustomToolbar.misc.register( + 'startReplay', + '播放录像', + () => { + core.triggerReplay(); + }, + () => ( + + {replaying.value ? : } + + ) + ); + CustomToolbar.misc.register( + 'stopReplay', + '停止录像', + () => { + core.stopReplay(); + }, + () => ( + + + + ) + ); + CustomToolbar.misc.register( + 'rewindReplay', + '回退录像', + () => { + core.rewindReplay(); + }, + () => + ); + CustomToolbar.misc.register( + 'stepReplay', + '单步前进录像', + () => { + core.stepReplay(); + }, + () => + ); + CustomToolbar.misc.register( + 'speedDownReplay', + '录像减速', + () => { + core.speedDownReplay(); + }, + () => + ); + CustomToolbar.misc.register( + 'speedUpReplay', + '录像加速', + () => { + core.speedUpReplay(); + }, + () => + ); + CustomToolbar.misc.register( + 'viewMap', + '浏览地图', + () => { + if (core.isReplaying()) { + core.control._replay_viewMap(); + } else { + if ( + core.isPlaying() && + !core.isMoving() && + !core.status.lockControl + ) { + core.ui._drawViewMaps(); + } + } + }, + () => + ); CustomToolbar.misc.bindActivable('minimap', true, () => minimapTool); }); diff --git a/src/core/render/shader.ts b/src/core/render/shader.ts index c30b88b..8abe6b8 100644 --- a/src/core/render/shader.ts +++ b/src/core/render/shader.ts @@ -77,393 +77,6 @@ export class Shader extends GL2 { ): void {} } -// export class Shader extends Container { -// /** 是否支持此组件 */ -// static readonly support: boolean = isWebGL2Supported(); - -// // 会用到的一些常量 -// // 着色器版本 -// readonly VERSION_ES_100: ShaderVersion.ES_100 = 0; -// readonly VERSION_ES_300: ShaderVersion.ES_300 = 1; -// // uniform 类型 -// readonly UNIFORM_1f: UniformType.Uniform1f = UniformType.Uniform1f; -// readonly UNIFORM_1fv: UniformType.Uniform1fv = UniformType.Uniform1fv; -// readonly UNIFORM_1i: UniformType.Uniform1i = UniformType.Uniform1i; -// readonly UNIFORM_1iv: UniformType.Uniform1iv = UniformType.Uniform1iv; -// readonly UNIFORM_1ui: UniformType.Uniform1ui = UniformType.Uniform1ui; -// readonly UNIFORM_1uiv: UniformType.Uniform1uiv = UniformType.Uniform1uiv; -// readonly UNIFORM_2f: UniformType.Uniform2f = UniformType.Uniform2f; -// readonly UNIFORM_2fv: UniformType.Uniform2fv = UniformType.Uniform2fv; -// readonly UNIFORM_2i: UniformType.Uniform2i = UniformType.Uniform2i; -// readonly UNIFORM_2iv: UniformType.Uniform2iv = UniformType.Uniform2iv; -// readonly UNIFORM_2ui: UniformType.Uniform2ui = UniformType.Uniform2ui; -// readonly UNIFORM_2uiv: UniformType.Uniform2uiv = UniformType.Uniform2uiv; -// readonly UNIFORM_3f: UniformType.Uniform3f = UniformType.Uniform3f; -// readonly UNIFORM_3fv: UniformType.Uniform3fv = UniformType.Uniform3fv; -// readonly UNIFORM_3i: UniformType.Uniform3i = UniformType.Uniform3i; -// readonly UNIFORM_3iv: UniformType.Uniform3iv = UniformType.Uniform3iv; -// readonly UNIFORM_3ui: UniformType.Uniform3ui = UniformType.Uniform3ui; -// readonly UNIFORM_3uiv: UniformType.Uniform3uiv = UniformType.Uniform3uiv; -// readonly UNIFORM_4f: UniformType.Uniform4f = UniformType.Uniform4f; -// readonly UNIFORM_4fv: UniformType.Uniform4fv = UniformType.Uniform4fv; -// readonly UNIFORM_4i: UniformType.Uniform4i = UniformType.Uniform4i; -// readonly UNIFORM_4iv: UniformType.Uniform4iv = UniformType.Uniform4iv; -// readonly UNIFORM_4ui: UniformType.Uniform4ui = UniformType.Uniform4ui; -// readonly UNIFORM_4uiv: UniformType.Uniform4uiv = UniformType.Uniform4uiv; -// // uniform matrix 类型 -// readonly U_MATRIX_2x2: UniformMatrix.UMatrix2x2 = UniformMatrix.UMatrix2x2; -// readonly U_MATRIX_2x3: UniformMatrix.UMatrix2x3 = UniformMatrix.UMatrix2x3; -// readonly U_MATRIX_2x4: UniformMatrix.UMatrix2x4 = UniformMatrix.UMatrix2x4; -// readonly U_MATRIX_3x2: UniformMatrix.UMatrix3x2 = UniformMatrix.UMatrix3x2; -// readonly U_MATRIX_3x3: UniformMatrix.UMatrix3x3 = UniformMatrix.UMatrix3x3; -// readonly U_MATRIX_3x4: UniformMatrix.UMatrix3x4 = UniformMatrix.UMatrix3x4; -// readonly U_MATRIX_4x2: UniformMatrix.UMatrix4x2 = UniformMatrix.UMatrix4x2; -// readonly U_MATRIX_4x3: UniformMatrix.UMatrix4x3 = UniformMatrix.UMatrix4x3; -// readonly U_MATRIX_4x4: UniformMatrix.UMatrix4x4 = UniformMatrix.UMatrix4x4; -// // attribute 类型 -// readonly ATTRIB_1f: AttribType.Attrib1f = AttribType.Attrib1f; -// readonly ATTRIB_1fv: AttribType.Attrib1fv = AttribType.Attrib1fv; -// readonly ATTRIB_2f: AttribType.Attrib2f = AttribType.Attrib2f; -// readonly ATTRIB_2fv: AttribType.Attrib2fv = AttribType.Attrib2fv; -// readonly ATTRIB_3f: AttribType.Attrib3f = AttribType.Attrib3f; -// readonly ATTRIB_3fv: AttribType.Attrib3fv = AttribType.Attrib3fv; -// readonly ATTRIB_4f: AttribType.Attrib4f = AttribType.Attrib4f; -// readonly ATTRIB_4fv: AttribType.Attrib4fv = AttribType.Attrib4fv; -// readonly ATTRIB_I4i: AttribType.AttribI4i = AttribType.AttribI4i; -// readonly ATTRIB_I4iv: AttribType.AttribI4iv = AttribType.AttribI4iv; -// readonly ATTRIB_I4ui: AttribType.AttribI4ui = AttribType.AttribI4ui; -// readonly ATTRIB_I4uiv: AttribType.AttribI4uiv = AttribType.AttribI4uiv; -// // 渲染模式 -// readonly DRAW_ARRAYS = RenderMode.Arrays; -// readonly DRAW_ELEMENTS = RenderMode.Elements; -// readonly DRAW_ARRAYS_INSTANCED = RenderMode.ArraysInstanced; -// readonly DRAW_ELEMENTS_INSTANCED = RenderMode.ElementsInstanced; -// // 其他常量 -// readonly MAX_TEXTURE_COUNT: number = 0; - -// canvas: HTMLCanvasElement; -// gl: WebGL2RenderingContext; - -// /** 是否需要重新渲染着色器 */ -// private shaderRenderDirty: boolean = true; - -// /** webgl使用的程序 */ -// private program: ShaderProgram | null = null; - -// /** 当前渲染实例的所有着色器程序 */ -// private programs: Set = new Set(); -// /** framebuffer 映射 */ -// private framebufferMap: Map = new Map(); - -// constructor(type: RenderItemPosition = 'static') { -// super(type, !Shader.support); - -// this.canvas = document.createElement('canvas'); -// this.gl = this.canvas.getContext('webgl2')!; -// if (!Shader.support) { -// this.canvas.width = 0; -// this.canvas.height = 0; -// } else { -// const num = this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS); -// if (typeof num === 'number') { -// this.MAX_TEXTURE_COUNT = num; -// } -// } - -// this.init(); -// } - -// protected render( -// canvas: MotaOffscreenCanvas2D, -// transform: Transform -// ): void { -// if (!Shader.support || !this.program || !this.program.modified) { -// super.render(canvas, transform); -// } else { -// const compile = this.program.requestCompile(); -// if (compile) { -// this.gl.useProgram(this.program.program); -// } - -// if (this.cacheDirty) { -// const { ctx } = this.cache; -// ctx.clearRect(0, 0, canvas.width, canvas.height); -// ctx.save(); -// super.render(this.cache, transform); -// ctx.restore(); -// this.cacheDirty = false; -// } - -// if (this.shaderRenderDirty) { -// this.drawScene(); -// this.shaderRenderDirty = false; -// } - -// canvas.ctx.drawImage(this.canvas, 0, 0, this.width, this.height); -// } -// } - -// setHD(hd: boolean): void { -// super.setHD(hd); -// this.sizeGL(this.width, this.height); -// } - -// size(width: number, height: number): void { -// super.size(width, height); -// this.sizeGL(width, height); -// } - -// private sizeGL(width: number, height: number) { -// const ratio = this.highResolution ? devicePixelRatio : 1; -// const scale = ratio * core.domStyle.scale; -// this.canvas.width = width * scale; -// this.canvas.height = height * scale; -// this.shaderRenderDirty = true; -// } - -// update(item?: RenderItem): void { -// super.update(item); -// this.shaderRenderDirty = true; -// } - -// drawScene() { -// const gl = this.gl; -// const program = this.program; -// if (!gl || !program) return; -// const useDefault = program.defaultReady; -// const dr = useDefault ? this.defaultReady() : true; -// const ready = dr && program.ready(); -// if (!ready) return; -// const indices = program.usingIndices; -// const param = program.getDrawParams(program.renderMode); -// if (!param) return; - -// // 清空画布 -// gl.viewport(0, 0, this.canvas.width, this.canvas.height); -// gl.clearColor(0, 0, 0, 0); -// gl.clearDepth(1); -// gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - -// const pre = this.preDraw(gl, program, param, indices); -// if (!pre) { -// this.postDraw(gl, program, param, indices); -// return; -// } - -// this.draw(gl, program, param, indices); - -// this.postDraw(gl, program, param, indices); -// } - -// draw( -// gl: WebGL2RenderingContext, -// program: ShaderProgram, -// param: DrawParamsMap[keyof DrawParamsMap], -// indices: IShaderIndices | null -// ) { -// switch (program.renderMode) { -// case RenderMode.Arrays: { -// const { mode, first, count } = param as DrawArraysParam; -// gl.drawArrays(mode, first, count); -// } -// case RenderMode.Elements: { -// if (!indices) return; -// const { mode, count, type, offset } = -// param as DrawElementsParam; -// gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices.data); -// gl.drawElements(mode, count, type, offset); -// } -// case RenderMode.ArraysInstanced: { -// const { mode, first, count, instanceCount } = -// param as DrawArraysInstancedParam; -// gl.drawArraysInstanced(mode, first, count, instanceCount); -// } -// case RenderMode.ElementsInstanced: { -// if (!indices) return; -// const { -// mode, -// count, -// type, -// offset, -// instanceCount: ins -// } = param as DrawElementsInstancedParam; -// gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices.data); -// gl.drawElementsInstanced(mode, count, type, offset, ins); -// } -// } -// } - -// /** -// * 在本着色器内部渲染之前执行的渲染,如果返回false,则表示不进行内部渲染,但依然会执行 {@link postDraw}。 -// * 继承本类,并复写此方法即可实现前置渲染功能 -// */ -// protected preDraw( -// gl: WebGL2RenderingContext, -// program: ShaderProgram, -// param: DrawParamsMap[keyof DrawParamsMap], -// indices: IShaderIndices | null -// ): boolean { -// return true; -// } - -// /** -// * 在本着色器内部渲染之后执行的渲染,即使preDraw返回false,本函数也会执行 -// * 继承本类,并复写此方法即可实现后置渲染功能 -// */ -// protected postDraw( -// gl: WebGL2RenderingContext, -// program: ShaderProgram, -// param: DrawParamsMap[keyof DrawParamsMap], -// indices: IShaderIndices | null -// ) {} - -// /** -// * 默认的准备函数 -// * @returns 是否准备成功 -// */ -// protected defaultReady(): boolean { -// const program = this.program; -// if (!program) return false; -// const tex = program.getTexture('u_sampler'); -// if (!tex) return false; -// const canvas = this.cache.canvas; -// if (tex.width === canvas.width && tex.height === canvas.height) { -// tex.sub(canvas, 0, 0, canvas.width, canvas.height); -// } else { -// tex.set(canvas); -// } -// return true; -// } - -// /** -// * 将画面渲染至帧缓冲 -// * @param name 帧缓冲名称 -// * @param texture 渲染至的纹理 -// * @param clear 是否先清空画布再渲染 -// */ -// framebuffer( -// name: string, -// texture: IShaderTexture2D, -// clear: boolean = true -// ) { -// const gl = this.gl; -// const buffer = this.framebufferMap.get(name); -// const program = this.program; -// if (!gl || !buffer || !program) return; -// const indices = program.usingIndices; -// if (!indices) return; -// const param = program.getDrawParams(program.renderMode); -// if (!param) return; - -// const tex = texture.texture; -// gl.bindTexture(gl.TEXTURE_2D, tex); -// gl.bindFramebuffer(gl.FRAMEBUFFER, buffer); -// if (clear) { -// gl.viewport(0, 0, this.canvas.width, this.canvas.height); -// gl.clearColor(0, 0, 0, 0); -// gl.clearDepth(1); -// gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); -// } -// gl.framebufferTexture2D( -// gl.FRAMEBUFFER, -// gl.COLOR_ATTACHMENT0, -// gl.TEXTURE_2D, -// tex, -// 0 -// ); -// this.draw(gl, program, param, indices); -// gl.bindFramebuffer(gl.FRAMEBUFFER, null); -// gl.bindTexture(gl.TEXTURE_2D, null); -// } - -// /** -// * 创建一个帧缓冲对象 -// * @param name 帧缓冲名称 -// * @returns 是否创建成功 -// */ -// createFramebuffer(name: string): boolean { -// const gl = this.gl; -// if (!gl) return false; -// const buffer = gl.createFramebuffer(); -// if (!buffer) return false; -// this.framebufferMap.set(name, buffer); -// return true; -// } - -// /** -// * 删除一个帧缓冲对象 -// * @param name 帧缓冲名称 -// * @returns 是否删除成功 -// */ -// deleteFramebuffer(name: string): boolean { -// const gl = this.gl; -// if (!gl) return false; -// const buffer = this.framebufferMap.get(name); -// if (!buffer) return false; -// gl.deleteFramebuffer(buffer); -// return this.framebufferMap.delete(name); -// } - -// /** -// * 切换着色器程序 -// * @param program 着色器程序 -// */ -// useProgram(program: ShaderProgram) { -// if (!this.gl) return; -// if (program.element !== this) { -// logger.error(17); -// return; -// } -// if (this.program !== program) { -// this.program?.unload(); -// this.program = program; -// this.gl.useProgram(program.program); -// program.load(); -// } -// this.shaderRenderDirty = true; -// } - -// /** -// * 创建一个着色器程序 -// * @param vs 顶点着色器,可选 -// * @param fs 片元着色器,可选 -// */ -// createProgram(vs?: string, fs?: string) { -// const program = new ShaderProgram(this, vs, fs); -// this.programs.add(program); -// return program; -// } - -// /** -// * 删除一个着色器程序 -// * @param program 要删除的着色器程序 -// */ -// deleteProgram(program: ShaderProgram) { -// if (program.element !== this) { -// logger.error(18); -// return; -// } -// program.destroy(); -// this.programs.delete(program); -// } - -// destroy(): void { -// this.programs.forEach(v => v.destroy()); -// super.destroy(); -// } - -// // ----- 初始化部分 - -// private init() { -// const gl = this.gl; -// if (!gl) return; -// gl.enable(gl.DEPTH_TEST); -// gl.enable(gl.BLEND); -// gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); -// gl.depthFunc(gl.LEQUAL); -// } -// } - export class ShaderProgram extends GL2Program { protected readonly prefix: IGL2ProgramPrefix = SHADER_PREFIX; @@ -474,17 +87,6 @@ export class ShaderProgram extends GL2Program { if (!vs && !fs) { this.modified = false; } - this.setReady(() => { - const tex = this.getTexture('u_sampler'); - if (!tex) return false; - const c = this.element.canvas; - if (tex.width === c.width && tex.height === c.height) { - tex.sub(c, 0, 0, c.width, c.height); - } else { - tex.set(c); - } - return true; - }); } protected override compile() { diff --git a/src/game/game.ts b/src/game/game.ts index 74627d8..fc1dbb0 100644 --- a/src/game/game.ts +++ b/src/game/game.ts @@ -101,6 +101,8 @@ export interface GameEvent { y: number, floorId: FloorIds ]; + /** Emitted in lib/control.js */ + replayStatus: [replaying: boolean]; } export const hook = new EventEmitter(); diff --git a/src/types/control.d.ts b/src/types/control.d.ts index 86264f5..b17836f 100644 --- a/src/types/control.d.ts +++ b/src/types/control.d.ts @@ -1163,6 +1163,8 @@ interface Control { frame?: number ): void; _moveAction_popAutomaticRoute(): void; + _replay_SL(): void; + _replay_viewMap(): void; } declare const control: new () => Control;