From 1673eb7a4bf6bc4a938820276292f1b7a160c1d5 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Wed, 9 Aug 2023 12:27:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E9=94=AE=E5=88=86=E7=BB=84=E4=B8=8E?= =?UTF-8?q?=E8=BE=85=E5=8A=A9=E9=94=AE=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- idea.md | 6 ++ src/core/index.ts | 5 +- src/core/main/custom/hotkey.ts | 167 ++++++++++++++++++++++----------- src/plugin/utils.ts | 10 ++ 4 files changed, 131 insertions(+), 57 deletions(-) diff --git a/idea.md b/idea.md index 7458cd9..f6939f9 100644 --- a/idea.md +++ b/idea.md @@ -87,3 +87,9 @@ dam4.png ---- 存档 59 [] 优化资源分离,音乐放到 bgm 目录下 [] 一次性道具拾取与清怪 [] 重构数据统计 +[] 优化路径显示,瞬移可以闪一下再熄灭 +[] 勇士身上显示攻防血 +[] 优化地图拖动 +[] 楼层转换假如随机小贴士 +[] ui 中如果元素发生改变,那么做出背景亮一下再熄灭的效果 +[] 双击怪物手册拐点可以直接在拖动条上定位 diff --git a/src/core/index.ts b/src/core/index.ts index a2c823c..60856fe 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -4,6 +4,7 @@ import { EventEmitter } from './common/eventEmitter'; import { loading, readyAllResource } from './loader/load'; import { ResourceStore, ResourceType } from './loader/resource'; import { GameEvent, hook } from './main/game'; +import { GameStorage } from './main/storage'; import { resolvePlugin } from './plugin'; interface AncTePlugin { @@ -41,6 +42,7 @@ export interface AncTe { plugin: AncTePlugin; game: { hook: EventEmitter; + storage: GameStorage[]; }; } @@ -53,7 +55,8 @@ function ready() { // @ts-ignore plugin: {}, game: { - hook + hook, + storage: GameStorage.list } }; diff --git a/src/core/main/custom/hotkey.ts b/src/core/main/custom/hotkey.ts index 71d5e6d..d55743e 100644 --- a/src/core/main/custom/hotkey.ts +++ b/src/core/main/custom/hotkey.ts @@ -1,5 +1,5 @@ import { KeyCode } from '../../../plugin/keyCodes'; -import { deleteWith } from '../../../plugin/utils'; +import { deleteWith, generateBinary, has } from '../../../plugin/utils'; import { EmitableEvent, EventEmitter } from '../../common/eventEmitter'; import { GameStorage } from '../storage'; @@ -16,13 +16,22 @@ interface HotkeyData { ctrl?: boolean; alt?: boolean; shift?: boolean; + group?: string; func: (code: KeyCode, e: KeyboardEvent) => any; } +interface GroupInfo { + name: string; + includes: string[]; +} + +type RegisterData = Omit; + export class Hotkey extends EventEmitter { keyMap: Map = new Map(); list: Record = {}; storage: GameStorage>; + groups: Record = {}; constructor(id: string) { super(); @@ -33,9 +42,10 @@ export class Hotkey extends EventEmitter { * 注册一个按键操作 * @param data 按键信息 */ - register(id: string, data: Omit) { + register(id: string, name: string, data: RegisterData) { const key = { id, + name, key: this.storage.getValue(id, data.defaults), ...data }; @@ -75,7 +85,48 @@ export class Hotkey extends EventEmitter { */ emitKey(key: KeyCode, e: KeyboardEvent): any[] { this.emit('emit', key, e); - return this.getData(key).map(v => v.func(key, e)); + return this.getData(key).map(v => { + const assist = generateBinary([e.ctrlKey, e.altKey, e.shiftKey]); + const need = generateBinary([!!v.ctrl, !!v.alt, !!v.shift]); + if (assist & need) { + v.func(key, e); + } + }); + } + + /** + * 按键分组 + * @param id 组id + * @param name 组名称 + * @param ids 组包含的内容 + */ + group(id: string, name: string, ids: string[]) { + this.groups[id] = { + name, + includes: ids + }; + ids.forEach(v => { + const data = this.list[v]; + if (has(data.group)) { + deleteWith(this.groups[data.group].includes, v); + } + data.group = id; + }); + return this; + } + + /** + * 将剩余的按键组成一个组合 + * @param id 组合id + * @param name 组合的名称 + */ + groupRest(id: string, name: string) { + const rest = Object.values(this.list) + .filter(v => !has(v.group)) + .map(v => v.id); + + this.group(id, name, rest); + return this; } private ensureKey(key: KeyCode) { @@ -89,133 +140,137 @@ export class Hotkey extends EventEmitter { export const hotkey = new Hotkey('gameKey'); hotkey - .register('book', { - name: '怪物手册', + .register('book', '怪物手册', { defaults: KeyCode.KeyX, func: () => {} }) - .register('save', { - name: '存档界面', + .register('save', '存档界面', { defaults: KeyCode.KeyS, func: () => {} }) - .register('load', { - name: '读档界面', + .register('load', '读档界面', { defaults: KeyCode.KeyD, func: () => {} }) - .register('undo1', { - name: '撤回', + .register('undo1', '撤回', { defaults: KeyCode.KeyA, func: () => {} }) - .register('undo2', { - name: '撤回', + .register('undo2', '撤回 手机端', { defaults: KeyCode.Digit5, func: () => {} }) - .register('redo1', { - name: '重做', + .register('redo1', '重做', { defaults: KeyCode.KeyW, func: () => {} }) - .register('redo2', { - name: '重做', + .register('redo2', '重做 手机端', { defaults: KeyCode.Digit6, func: () => {} }) - .register('toolbox', { - name: '道具栏', + .register('toolbox', '道具栏', { defaults: KeyCode.KeyT, func: () => {} }) - .register('equipbox', { - name: '装备栏', + .register('equipbox', '装备栏', { defaults: KeyCode.KeyQ, func: () => {} }) - .register('fly', { - name: '楼层传送', + .register('fly', '楼层传送', { defaults: KeyCode.KeyG, func: () => {} }) - .register('turn', { - name: '勇士转向', + .register('turn', '勇士转向', { defaults: KeyCode.KeyZ, func: () => {} }) - .register('getNext1', { - name: '轻按', + .register('getNext1', '轻按', { defaults: KeyCode.Space, func: () => {} }) - .register('getNext2', { - name: '轻按', + .register('getNext2', '轻按 手机端', { defaults: KeyCode.Digit7, func: () => {} }) - .register('menu', { - name: '菜单', + .register('menu', '菜单', { defaults: KeyCode.Escape, func: () => {} }) - .register('replay', { - name: '录像回放', + .register('replay', '录像回放', { defaults: KeyCode.KeyR, func: () => {} }) - .register('restart', { - name: '开始菜单', + .register('restart', '开始菜单', { defaults: KeyCode.KeyN, func: () => {} }) - .register('shop', { - name: '快捷商店', + .register('shop', '快捷商店', { defaults: KeyCode.KeyV, func: () => {} }) - .register('statistics', { - name: '数据统计', + .register('statistics', '数据统计', { defaults: KeyCode.KeyB, func: () => {} }) - .register('viewMap1', { - name: '浏览地图', + .register('viewMap1', '浏览地图', { defaults: KeyCode.PageUp, func: () => {} }) - .register('viewMap2', { - name: '浏览地图', + .register('viewMap2', '浏览地图', { defaults: KeyCode.PageDown, func: () => {} }) - .register('comment', { - name: '评论区', + .register('comment', '评论区', { defaults: KeyCode.KeyP, func: () => {} }) - .register('mark', { - name: '标记怪物', + .register('mark', '标记怪物', { defaults: KeyCode.KeyM, func: () => {} }) - .register('skillTree', { - name: '技能树', + .register('skillTree', '技能树', { defaults: KeyCode.KeyJ, func: () => {} }) - .register('desc', { - name: '百科全书', + .register('desc', '百科全书', { defaults: KeyCode.KeyH, func: () => {} }) - .register('special', { - name: '鼠标位置怪物属性', + .register('special', '鼠标位置怪物属性', { defaults: KeyCode.KeyE, func: () => {} }) - .register('critical', { - name: '鼠标位置怪物临界', + .register('critical', '鼠标位置怪物临界', { defaults: KeyCode.KeyC, func: () => {} - }); + }) + .group('action', '游戏操作', [ + 'save', + 'load', + 'undo1', + 'undo2', + 'redo1', + 'redo2', + 'turn', + 'getNext1', + 'getNext2', + 'mark' + ]) + .group('view', '快捷查看', [ + 'book', + 'toolbox', + 'equipbox', + 'fly', + 'menu', + 'replay', + 'shop', + 'statistics', + 'viewMap1', + 'viewMap2', + 'skillTree', + 'desc', + 'special', + 'critical' + ]) + .group('system', '系统按键', ['comment']) + .groupRest('unClassed', '未分类按键'); diff --git a/src/plugin/utils.ts b/src/plugin/utils.ts index e460bb9..941f9a6 100644 --- a/src/plugin/utils.ts +++ b/src/plugin/utils.ts @@ -286,3 +286,13 @@ export async function triggerFullscreen(full: boolean) { }); } } + +export function generateBinary(arr: boolean[]) { + let num = 0; + arr.forEach((v, i) => { + if (v) { + num += 1 << i; + } + }); + return num; +}