From 253445eb6efeec667839c2b708d4d139f720f531 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Sat, 18 Nov 2023 22:24:07 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=89=80=E6=9C=89ui=E7=9A=84?= =?UTF-8?q?=E6=8C=89=E9=94=AE=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/main/custom/hotkey.ts | 23 +++++--- src/core/main/init/hotkey.ts | 8 +-- src/core/main/init/ui.ts | 41 +++++--------- src/ui/book.vue | 99 +++++++++++++--------------------- src/ui/bookDetail.vue | 23 ++++---- src/ui/fly.vue | 67 ++++++++++++++--------- src/ui/shop.vue | 47 +++++++--------- src/ui/start.vue | 45 ++++++++-------- src/ui/toolbox.vue | 64 ++++++++++------------ 9 files changed, 191 insertions(+), 226 deletions(-) diff --git a/src/core/main/custom/hotkey.ts b/src/core/main/custom/hotkey.ts index 05b6595..6bec68b 100644 --- a/src/core/main/custom/hotkey.ts +++ b/src/core/main/custom/hotkey.ts @@ -88,13 +88,21 @@ export class Hotkey extends EventEmitter { * @param func 按键按下时执行的函数 */ realize(id: string, func: HotkeyFunc) { - const key = this.data[id]; - if (!key.func.has(this.scope)) { - throw new Error( - `Cannot access using scope. Call use before calling realize.` - ); + const toSet = Object.values(this.data).filter(v => { + return v.id === id || v.id.split('_').slice(0, -1).join('_') === id; + }); + if (toSet.length === 0) { + throw new Error(`Realize nonexistent key '${id}'.`); } - key.func.set(this.scope, func); + for (const key of toSet) { + if (!key.func.has(this.scope)) { + throw new Error( + `Cannot access using scope. Call use before calling realize.` + ); + } + key.func.set(this.scope, func); + } + return this; } /** @@ -119,7 +127,7 @@ export class Hotkey extends EventEmitter { key.func.delete(symbol); } spliceBy(this.scopeStack, symbol); - this.scope = this.scopeStack.pop() ?? Symbol(); + this.scope = this.scopeStack.at(-1) ?? Symbol(); } /** @@ -177,6 +185,7 @@ export class Hotkey extends EventEmitter { group(id: string, name: string) { this.grouping = id; this.groupName[id] = name; + this.groups[id] ??= []; return this; } diff --git a/src/core/main/init/hotkey.ts b/src/core/main/init/hotkey.ts index dc16483..96e96b6 100644 --- a/src/core/main/init/hotkey.ts +++ b/src/core/main/init/hotkey.ts @@ -160,12 +160,14 @@ gameKey .register({ id: '@start_up', name: '上移光标', - defaults: KeyCode.UpArrow + defaults: KeyCode.UpArrow, + type: 'down' }) .register({ id: '@start_down', name: '下移光标', - defaults: KeyCode.DownArrow + defaults: KeyCode.DownArrow, + type: 'down' }) // -------------------- .group('@ui_book', '怪物手册') @@ -226,7 +228,7 @@ gameKey type: 'down' }) .register({ - id: '@toolbox_right', + id: '@toolbox_down', name: '光标下移', defaults: KeyCode.DownArrow, type: 'down' diff --git a/src/core/main/init/ui.ts b/src/core/main/init/ui.ts index 6e2b19e..2a4b7a1 100644 --- a/src/core/main/init/ui.ts +++ b/src/core/main/init/ui.ts @@ -1,38 +1,21 @@ import * as UI from '@ui/.'; import { GameUi, UiController } from '../custom/ui'; -import { Hotkey } from '../custom/hotkey'; -import { KeyCode } from '@/plugin/keyCodes'; import { hook } from '../game'; -export const exitKey = new Hotkey('exitKey'); -exitKey - .register('exit1', '退出', { - defaults: KeyCode.KeyX, - func: () => { - if (mainUi.focused) mainUi.splice(mainUi.focused); - } - }) - .register('exit2', '退出', { - defaults: KeyCode.Escape, - func: () => { - if (mainUi.focused) mainUi.splice(mainUi.focused); - } - }); - export const mainUi = new UiController(); mainUi.register( - new GameUi('book', UI.Book, exitKey), - new GameUi('toolbox', UI.Toolbox, exitKey), - new GameUi('equipbox', UI.Equipbox, exitKey), - new GameUi('settings', UI.Settings, exitKey), - new GameUi('desc', UI.Desc, exitKey), - new GameUi('skill', UI.Skill, exitKey), - new GameUi('skillTree', UI.SkillTree, exitKey), - new GameUi('fly', UI.Fly, exitKey), - new GameUi('fixedDetail', UI.FixedDetail, exitKey), - new GameUi('shop', UI.Shop, exitKey), - new GameUi('achievement', UI.Achievement, exitKey), - new GameUi('bgm', UI.BgmList, exitKey) + new GameUi('book', UI.Book), + new GameUi('toolbox', UI.Toolbox), + new GameUi('equipbox', UI.Equipbox), + new GameUi('settings', UI.Settings), + new GameUi('desc', UI.Desc), + new GameUi('skill', UI.Skill), + new GameUi('skillTree', UI.SkillTree), + new GameUi('fly', UI.Fly), + new GameUi('fixedDetail', UI.FixedDetail), + new GameUi('shop', UI.Shop), + new GameUi('achievement', UI.Achievement), + new GameUi('bgm', UI.BgmList) // todo: 把游戏主 div 加入到 mainUi 里面 ); mainUi.showAll(); diff --git a/src/ui/book.vue b/src/ui/book.vue index 617b2aa..ee5aa44 100644 --- a/src/ui/book.vue +++ b/src/ui/book.vue @@ -49,6 +49,7 @@ import { KeyCode } from '../plugin/keyCodes'; import { ToShowEnemy, detailInfo } from '../plugin/ui/book'; import { getDetailedEnemy } from '../plugin/ui/fixed'; import { GameUi } from '@/core/main/custom/ui'; +import { gameKey } from '@/core/main/init/hotkey'; const props = defineProps<{ num: number; @@ -141,70 +142,46 @@ function checkScroll() { } } -/** - * 键盘松开时 - */ -function keyup(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (c === KeyCode.KeyX || c === KeyCode.Escape) { +// 按键控制 +gameKey.use(props.ui.symbol); +gameKey + .realize('@book_up', () => { + if (selected.value > 0) { + selected.value--; + } + checkScroll(); + }) + .realize('@book_down', () => { + if (selected.value < enemy.length - 1) { + selected.value++; + } + checkScroll(); + }) + .realize('@book_pageDown', () => { + if (selected.value <= 4) { + selected.value = 0; + } else { + selected.value -= 5; + } + checkScroll(); + }) + .realize('@book_pageUp', () => { + if (selected.value >= enemy.length - 5) { + selected.value = enemy.length - 1; + } else { + selected.value += 5; + } + checkScroll(); + }) + .realize('exit', () => { exit(); - } - if ( - (c === KeyCode.Enter || c === KeyCode.KeyC || c === KeyCode.Space) && - !detail.value - ) { + }) + .realize('confirm', () => { select(toShow[selected.value], selected.value); - } -} + }); -/** - * 键盘按下时 - */ -function keydown(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (!detail.value) { - if (c === KeyCode.DownArrow) { - if (selected.value < enemy.length - 1) { - selected.value++; - } - checkScroll(); - } - if (c === KeyCode.UpArrow) { - if (selected.value > 0) { - selected.value--; - } - checkScroll(); - } - // 一次移动5个怪物 - if (c === KeyCode.LeftArrow || c === KeyCode.PageUp) { - if (selected.value <= 4) { - selected.value = 0; - } else { - selected.value -= 5; - } - checkScroll(); - } - if (c === KeyCode.RightArrow || c === KeyCode.PageDown) { - if (selected.value >= enemy.length - 5) { - selected.value = enemy.length - 1; - } else { - selected.value += 5; - } - checkScroll(); - } - } -} - -onMounted(async () => { - // if (mota.plugin.ui.transition.value) await sleep(600); - await sleep(50); - document.addEventListener('keyup', keyup); - document.addEventListener('keydown', keydown); -}); - -onUnmounted(async () => { - document.removeEventListener('keyup', keyup); - document.removeEventListener('keydown', keydown); +onUnmounted(() => { + gameKey.dispose(props.ui.symbol); }); diff --git a/src/ui/bookDetail.vue b/src/ui/bookDetail.vue index ad7f1b9..9378cc5 100644 --- a/src/ui/bookDetail.vue +++ b/src/ui/bookDetail.vue @@ -81,6 +81,7 @@ import { keycode } from '../plugin/utils'; import { sleep } from 'mutate-animate'; import EnemyTarget from '../panel/enemyTarget.vue'; import { detailInfo } from '../plugin/ui/book'; +import { gameKey } from '@/core/main/init/hotkey'; const props = defineProps<{ fromBook?: boolean; @@ -90,6 +91,7 @@ const props = defineProps<{ const enemy = detailInfo.enemy; const top = ref(detailInfo.pos); const panel = ref(props.defaultPanel ?? 'special'); +const symbol = Symbol(); let detail: HTMLDivElement; @@ -108,17 +110,14 @@ function close() { emits('close'); } -function key(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (c === KeyCode.Enter || c === KeyCode.Space || c === KeyCode.KeyC) { +gameKey.use(symbol); +gameKey + .realize('exit', () => { close(); - } - if (!props.fromBook) { - if (c === KeyCode.KeyX || c === KeyCode.Escape) { - close(); - } - } -} + }) + .realize('confirm', () => { + close(); + }); onMounted(async () => { top.value = 0; @@ -148,12 +147,10 @@ onMounted(async () => { moved = false; } ); - - document.addEventListener('keyup', key); }); onUnmounted(() => { - document.removeEventListener('keyup', key); + gameKey.dispose(symbol); }); diff --git a/src/ui/fly.vue b/src/ui/fly.vue index 48e3313..6445db5 100644 --- a/src/ui/fly.vue +++ b/src/ui/fly.vue @@ -96,9 +96,12 @@ import { debounce } from 'lodash-es'; import { downloadCanvasImage, keycode, tip } from '../plugin/utils'; import { sleep } from 'mutate-animate'; import { KeyCode } from '../plugin/keyCodes'; +import { GameUi } from '@/core/main/custom/ui'; +import { gameKey } from '@/core/main/init/hotkey'; const props = defineProps<{ num: number; + ui: GameUi; }>(); type Loc2 = [number, number, number, number]; @@ -520,28 +523,44 @@ function locateMap(id: FloorIds) { // -------------------- 键盘事件 -function keyup(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (c === KeyCode.Enter || c === KeyCode.Space || c === KeyCode.KeyC) fly(); - if (c === KeyCode.Escape || c === KeyCode.KeyX || c === KeyCode.KeyG) { +gameKey.use(props.ui.symbol); +gameKey + .realize('@fly_left', () => { + if (!tradition.value) changeFloorByDir('left'); + }) + .realize('@fly_right', () => { + if (!tradition.value) changeFloorByDir('right'); + }) + .realize('@fly_up', () => { + if (!tradition.value) changeFloorByDir('up'); + }) + .realize('@fly_down', () => { + if (!tradition.value) changeFloorByDir('down'); + }) + .realize('@fly_last', () => { + if (!tradition.value) changeFloorByDelta(-1); + }) + .realize('@fly_next', () => { + if (!tradition.value) changeFloorByDelta(1); + }) + .realize('@fly_down_t', () => { + if (tradition.value) changeFloorByDelta(-1); + }) + .realize('@fly_up_t', () => { + if (tradition.value) changeFloorByDelta(1); + }) + .realize('@fly_left_t', () => { + if (tradition.value) changeFloorByDelta(-10); + }) + .realize('@fly_right_t', () => { + if (tradition.value) changeFloorByDelta(10); + }) + .realize('exit', () => { exit(); - } - if (!tradition.value) { - if (c === KeyCode.LeftArrow) changeFloorByDir('left'); - if (c === KeyCode.RightArrow) changeFloorByDir('right'); - if (c === KeyCode.UpArrow) changeFloorByDir('up'); - if (c === KeyCode.DownArrow) changeFloorByDir('down'); - if (c === KeyCode.PageUp) changeFloorByDelta(1); - if (c === KeyCode.PageDown) changeFloorByDelta(-1); - } else { - if (c === KeyCode.UpArrow) changeFloorByDelta(1); - if (c === KeyCode.DownArrow) changeFloorByDelta(-1); - if (c === KeyCode.LeftArrow) changeFloorByDelta(-10); - if (c === KeyCode.RightArrow) changeFloorByDelta(10); - if (c === KeyCode.PageUp) changeFloorByDelta(10); - if (c === KeyCode.PageDown) changeFloorByDelta(-10); - } -} + }) + .realize('confirm', () => { + fly(); + }); // -------------------- 触摸事件 @@ -613,10 +632,6 @@ onMounted(async () => { resize(delta); }); - await sleep(50); - // if (mota.plugin.ui.transition.value) await sleep(600); - - document.addEventListener('keyup', keyup); map.addEventListener('touchstart', touchdown); map.addEventListener('touchend', touchup); map.addEventListener('touchmove', touchmove); @@ -624,7 +639,7 @@ onMounted(async () => { onUnmounted(() => { cancelGlobalDrag(drag); - document.removeEventListener('keyup', keyup); + gameKey.dispose(props.ui.symbol); }); diff --git a/src/ui/shop.vue b/src/ui/shop.vue index d74221c..0db0cec 100644 --- a/src/ui/shop.vue +++ b/src/ui/shop.vue @@ -175,9 +175,12 @@ import { isMobile } from '../plugin/use'; import BoxAnimate from '../components/boxAnimate.vue'; import { KeyCode } from '../plugin/keyCodes'; import { sleep } from 'mutate-animate'; +import { GameUi } from '@/core/main/custom/ui'; +import { gameKey } from '@/core/main/init/hotkey'; const props = defineProps<{ num: number; + ui: GameUi; shopId: string; }>(); @@ -276,35 +279,30 @@ function confirm() { update.value = !update.value; } -function keyup(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (c === KeyCode.KeyX || c === KeyCode.Escape || c === KeyCode.KeyV) { - exit(); - } - if (c === KeyCode.UpArrow) { +gameKey.use(props.ui.symbol); +gameKey + .realize('@shop_up', () => { if (selected.value >= 1) { selected.value--; } - } - if (c === KeyCode.DownArrow) { + }) + .realize('@shop_down', () => { if (selected.value <= choices.length - 2) { selected.value++; } - } - if (c === KeyCode.KeyC || c === KeyCode.Space || c === KeyCode.Enter) { - confirm(); - } -} - -function keydown(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (c === KeyCode.LeftArrow) { + }) + .realize('@shop_add', () => { count.value--; - } - if (c === KeyCode.RightArrow) { + }) + .realize('@shop_min', () => { count.value++; - } -} + }) + .realize('exit', () => { + exit(); + }) + .realize('confirm', () => { + confirm(); + }); function exit() { if (bought) core.status.route.push('closeShop'); @@ -312,16 +310,11 @@ function exit() { } onMounted(async () => { - await sleep(50); - // if (mota.plugin.ui.transition.value) await sleep(600); - document.addEventListener('keyup', keyup); - document.addEventListener('keydown', keydown); core.status.route.push(`openShop:${id}`); }); onUnmounted(() => { - document.removeEventListener('keyup', keyup); - document.removeEventListener('keydown', keydown); + gameKey.dispose(props.ui.symbol); }); diff --git a/src/ui/start.vue b/src/ui/start.vue index a323263..44b8389 100644 --- a/src/ui/start.vue +++ b/src/ui/start.vue @@ -70,6 +70,13 @@ import { KeyCode } from '../plugin/keyCodes'; import { triggerFullscreen } from '../plugin/utils'; import { loading } from '../core/loader/load'; import { isMobile } from '../plugin/use'; +import { GameUi } from '@/core/main/custom/ui'; +import { gameKey } from '@/core/main/init/hotkey'; + +const props = defineProps<{ + num: number; + ui: GameUi; +}>(); let startdiv: HTMLDivElement; let start: HTMLDivElement; @@ -179,29 +186,25 @@ function movein(button: HTMLElement, i: number) { selected.value = button.id; } -function keydown(e: KeyboardEvent) { - const c = keycode(e.keyCode); - const i = toshow.indexOf(selected.value); - if (c === KeyCode.DownArrow) { - const next = toshow[i - 1]; - if (!next) return; - selected.value = next; - setCursor(buttons[toshow.length - i], toshow.length - i); - } - if (c === KeyCode.UpArrow) { +gameKey.use(props.ui.symbol); +gameKey + .realize('@start_up', () => { + const i = toshow.indexOf(selected.value); const next = toshow[i + 1]; if (!next) return; selected.value = next; setCursor(buttons[toshow.length - i - 2], toshow.length - i - 2); - } -} - -function keyup(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (c === KeyCode.Enter || c === KeyCode.Space || c === KeyCode.KeyC) { + }) + .realize('@start_down', () => { + const i = toshow.indexOf(selected.value); + const next = toshow[i - 1]; + if (!next) return; + selected.value = next; + setCursor(buttons[toshow.length - i], toshow.length - i); + }) + .realize('confirm', () => { clickStartButton(selected.value); - } -} + }); function bgm() { core.triggerBgm(); @@ -310,9 +313,6 @@ onMounted(async () => { soundChecked.value = core.musicStatus.bgmStatus; - await sleep(50); - document.addEventListener('keydown', keydown); - document.addEventListener('keyup', keyup); start.style.opacity = '1'; if (played) { text.value = text2; @@ -327,8 +327,7 @@ onMounted(async () => { onUnmounted(() => { window.removeEventListener('resize', resize); - document.removeEventListener('keydown', keydown); - document.removeEventListener('keyup', keyup); + gameKey.dispose(props.ui.symbol); }); diff --git a/src/ui/toolbox.vue b/src/ui/toolbox.vue index 1b76a4d..7495e04 100644 --- a/src/ui/toolbox.vue +++ b/src/ui/toolbox.vue @@ -117,9 +117,12 @@ import { type, keycode, has } from '../plugin/utils'; import { hyper, sleep } from 'mutate-animate'; import { message } from 'ant-design-vue'; import { KeyCode } from '../plugin/keyCodes'; +import { GameUi } from '@/core/main/custom/ui'; +import { gameKey } from '@/core/main/init/hotkey'; const props = defineProps<{ num: number; + ui: GameUi; }>(); type ItemMode = 'tools' | 'constants'; @@ -196,30 +199,9 @@ async function toEquip() { mota.ui.main.open('equipbox'); } -function keyup(e: KeyboardEvent) { - const c = keycode(e.keyCode); - if (c === KeyCode.Escape || c === KeyCode.KeyX || c === KeyCode.KeyT) { - exit(); - } - if (c === KeyCode.Enter || c === KeyCode.KeyC) { - use(selected.value); - } -} - -function keydown(e: KeyboardEvent) { - const c = keycode(e.keyCode); - const total = items[mode.value].length; - if (c === KeyCode.DownArrow) { - if (index.value < total - 1) { - index.value++; - } - } - if (c === KeyCode.UpArrow) { - if (index.value > 0) { - index.value--; - } - } - if (c === KeyCode.RightArrow) { +gameKey.use(props.ui.symbol); +gameKey + .realize('@toolbox_right', () => { const constants = items.constants.length; if (mode.value === 'tools') { if (index.value >= constants) { @@ -227,8 +209,8 @@ function keydown(e: KeyboardEvent) { } mode.value = 'constants'; } - } - if (c === KeyCode.LeftArrow) { + }) + .realize('@toolbox_left', () => { const constants = items.tools.length; if (mode.value === 'constants') { if (index.value >= constants) { @@ -236,19 +218,27 @@ function keydown(e: KeyboardEvent) { } mode.value = 'tools'; } - } -} - -onMounted(async () => { - // if (mota.plugin.ui.transition.value) await sleep(600); - await sleep(50); - document.addEventListener('keyup', keyup); - document.addEventListener('keydown', keydown); -}); + }) + .realize('@toolbox_up', () => { + if (index.value > 0) { + index.value--; + } + }) + .realize('@toolbox_down', () => { + const total = items[mode.value].length; + if (index.value < total - 1) { + index.value++; + } + }) + .realize('exit', () => { + exit(); + }) + .realize('confirm', () => { + use(selected.value); + }); onUnmounted(() => { - document.removeEventListener('keyup', keyup); - document.removeEventListener('keydown', keydown); + gameKey.dispose(props.ui.symbol); });