refactor: 所有ui的按键操作

This commit is contained in:
unanmed 2023-11-18 22:24:07 +08:00
parent 02088aae00
commit 253445eb6e
9 changed files with 191 additions and 226 deletions

View File

@ -88,13 +88,21 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
* @param func * @param func
*/ */
realize(id: string, func: HotkeyFunc) { realize(id: string, func: HotkeyFunc) {
const key = this.data[id]; const toSet = Object.values(this.data).filter(v => {
if (!key.func.has(this.scope)) { return v.id === id || v.id.split('_').slice(0, -1).join('_') === id;
throw new Error( });
`Cannot access using scope. Call use before calling realize.` 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<HotkeyEvent> {
key.func.delete(symbol); key.func.delete(symbol);
} }
spliceBy(this.scopeStack, 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<HotkeyEvent> {
group(id: string, name: string) { group(id: string, name: string) {
this.grouping = id; this.grouping = id;
this.groupName[id] = name; this.groupName[id] = name;
this.groups[id] ??= [];
return this; return this;
} }

View File

@ -160,12 +160,14 @@ gameKey
.register({ .register({
id: '@start_up', id: '@start_up',
name: '上移光标', name: '上移光标',
defaults: KeyCode.UpArrow defaults: KeyCode.UpArrow,
type: 'down'
}) })
.register({ .register({
id: '@start_down', id: '@start_down',
name: '下移光标', name: '下移光标',
defaults: KeyCode.DownArrow defaults: KeyCode.DownArrow,
type: 'down'
}) })
// -------------------- // --------------------
.group('@ui_book', '怪物手册') .group('@ui_book', '怪物手册')
@ -226,7 +228,7 @@ gameKey
type: 'down' type: 'down'
}) })
.register({ .register({
id: '@toolbox_right', id: '@toolbox_down',
name: '光标下移', name: '光标下移',
defaults: KeyCode.DownArrow, defaults: KeyCode.DownArrow,
type: 'down' type: 'down'

View File

@ -1,38 +1,21 @@
import * as UI from '@ui/.'; import * as UI from '@ui/.';
import { GameUi, UiController } from '../custom/ui'; import { GameUi, UiController } from '../custom/ui';
import { Hotkey } from '../custom/hotkey';
import { KeyCode } from '@/plugin/keyCodes';
import { hook } from '../game'; 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(); export const mainUi = new UiController();
mainUi.register( mainUi.register(
new GameUi('book', UI.Book, exitKey), new GameUi('book', UI.Book),
new GameUi('toolbox', UI.Toolbox, exitKey), new GameUi('toolbox', UI.Toolbox),
new GameUi('equipbox', UI.Equipbox, exitKey), new GameUi('equipbox', UI.Equipbox),
new GameUi('settings', UI.Settings, exitKey), new GameUi('settings', UI.Settings),
new GameUi('desc', UI.Desc, exitKey), new GameUi('desc', UI.Desc),
new GameUi('skill', UI.Skill, exitKey), new GameUi('skill', UI.Skill),
new GameUi('skillTree', UI.SkillTree, exitKey), new GameUi('skillTree', UI.SkillTree),
new GameUi('fly', UI.Fly, exitKey), new GameUi('fly', UI.Fly),
new GameUi('fixedDetail', UI.FixedDetail, exitKey), new GameUi('fixedDetail', UI.FixedDetail),
new GameUi('shop', UI.Shop, exitKey), new GameUi('shop', UI.Shop),
new GameUi('achievement', UI.Achievement, exitKey), new GameUi('achievement', UI.Achievement),
new GameUi('bgm', UI.BgmList, exitKey) new GameUi('bgm', UI.BgmList)
// todo: 把游戏主 div 加入到 mainUi 里面 // todo: 把游戏主 div 加入到 mainUi 里面
); );
mainUi.showAll(); mainUi.showAll();

View File

@ -49,6 +49,7 @@ import { KeyCode } from '../plugin/keyCodes';
import { ToShowEnemy, detailInfo } from '../plugin/ui/book'; import { ToShowEnemy, detailInfo } from '../plugin/ui/book';
import { getDetailedEnemy } from '../plugin/ui/fixed'; import { getDetailedEnemy } from '../plugin/ui/fixed';
import { GameUi } from '@/core/main/custom/ui'; import { GameUi } from '@/core/main/custom/ui';
import { gameKey } from '@/core/main/init/hotkey';
const props = defineProps<{ const props = defineProps<{
num: number; num: number;
@ -141,70 +142,46 @@ function checkScroll() {
} }
} }
/** //
* 键盘松开时 gameKey.use(props.ui.symbol);
*/ gameKey
function keyup(e: KeyboardEvent) { .realize('@book_up', () => {
const c = keycode(e.keyCode); if (selected.value > 0) {
if (c === KeyCode.KeyX || c === KeyCode.Escape) { 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(); exit();
} })
if ( .realize('confirm', () => {
(c === KeyCode.Enter || c === KeyCode.KeyC || c === KeyCode.Space) &&
!detail.value
) {
select(toShow[selected.value], selected.value); select(toShow[selected.value], selected.value);
} });
}
/** onUnmounted(() => {
* 键盘按下时 gameKey.dispose(props.ui.symbol);
*/
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);
}); });
</script> </script>

View File

@ -81,6 +81,7 @@ import { keycode } from '../plugin/utils';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
import EnemyTarget from '../panel/enemyTarget.vue'; import EnemyTarget from '../panel/enemyTarget.vue';
import { detailInfo } from '../plugin/ui/book'; import { detailInfo } from '../plugin/ui/book';
import { gameKey } from '@/core/main/init/hotkey';
const props = defineProps<{ const props = defineProps<{
fromBook?: boolean; fromBook?: boolean;
@ -90,6 +91,7 @@ const props = defineProps<{
const enemy = detailInfo.enemy; const enemy = detailInfo.enemy;
const top = ref(detailInfo.pos); const top = ref(detailInfo.pos);
const panel = ref<string>(props.defaultPanel ?? 'special'); const panel = ref<string>(props.defaultPanel ?? 'special');
const symbol = Symbol();
let detail: HTMLDivElement; let detail: HTMLDivElement;
@ -108,17 +110,14 @@ function close() {
emits('close'); emits('close');
} }
function key(e: KeyboardEvent) { gameKey.use(symbol);
const c = keycode(e.keyCode); gameKey
if (c === KeyCode.Enter || c === KeyCode.Space || c === KeyCode.KeyC) { .realize('exit', () => {
close(); close();
} })
if (!props.fromBook) { .realize('confirm', () => {
if (c === KeyCode.KeyX || c === KeyCode.Escape) { close();
close(); });
}
}
}
onMounted(async () => { onMounted(async () => {
top.value = 0; top.value = 0;
@ -148,12 +147,10 @@ onMounted(async () => {
moved = false; moved = false;
} }
); );
document.addEventListener('keyup', key);
}); });
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener('keyup', key); gameKey.dispose(symbol);
}); });
</script> </script>

View File

@ -96,9 +96,12 @@ import { debounce } from 'lodash-es';
import { downloadCanvasImage, keycode, tip } from '../plugin/utils'; import { downloadCanvasImage, keycode, tip } from '../plugin/utils';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
import { GameUi } from '@/core/main/custom/ui';
import { gameKey } from '@/core/main/init/hotkey';
const props = defineProps<{ const props = defineProps<{
num: number; num: number;
ui: GameUi;
}>(); }>();
type Loc2 = [number, number, number, number]; type Loc2 = [number, number, number, number];
@ -520,28 +523,44 @@ function locateMap(id: FloorIds) {
// -------------------- // --------------------
function keyup(e: KeyboardEvent) { gameKey.use(props.ui.symbol);
const c = keycode(e.keyCode); gameKey
if (c === KeyCode.Enter || c === KeyCode.Space || c === KeyCode.KeyC) fly(); .realize('@fly_left', () => {
if (c === KeyCode.Escape || c === KeyCode.KeyX || c === KeyCode.KeyG) { 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(); exit();
} })
if (!tradition.value) { .realize('confirm', () => {
if (c === KeyCode.LeftArrow) changeFloorByDir('left'); fly();
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);
}
}
// -------------------- // --------------------
@ -613,10 +632,6 @@ onMounted(async () => {
resize(delta); resize(delta);
}); });
await sleep(50);
// if (mota.plugin.ui.transition.value) await sleep(600);
document.addEventListener('keyup', keyup);
map.addEventListener('touchstart', touchdown); map.addEventListener('touchstart', touchdown);
map.addEventListener('touchend', touchup); map.addEventListener('touchend', touchup);
map.addEventListener('touchmove', touchmove); map.addEventListener('touchmove', touchmove);
@ -624,7 +639,7 @@ onMounted(async () => {
onUnmounted(() => { onUnmounted(() => {
cancelGlobalDrag(drag); cancelGlobalDrag(drag);
document.removeEventListener('keyup', keyup); gameKey.dispose(props.ui.symbol);
}); });
</script> </script>

View File

@ -175,9 +175,12 @@ import { isMobile } from '../plugin/use';
import BoxAnimate from '../components/boxAnimate.vue'; import BoxAnimate from '../components/boxAnimate.vue';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
import { GameUi } from '@/core/main/custom/ui';
import { gameKey } from '@/core/main/init/hotkey';
const props = defineProps<{ const props = defineProps<{
num: number; num: number;
ui: GameUi;
shopId: string; shopId: string;
}>(); }>();
@ -276,35 +279,30 @@ function confirm() {
update.value = !update.value; update.value = !update.value;
} }
function keyup(e: KeyboardEvent) { gameKey.use(props.ui.symbol);
const c = keycode(e.keyCode); gameKey
if (c === KeyCode.KeyX || c === KeyCode.Escape || c === KeyCode.KeyV) { .realize('@shop_up', () => {
exit();
}
if (c === KeyCode.UpArrow) {
if (selected.value >= 1) { if (selected.value >= 1) {
selected.value--; selected.value--;
} }
} })
if (c === KeyCode.DownArrow) { .realize('@shop_down', () => {
if (selected.value <= choices.length - 2) { if (selected.value <= choices.length - 2) {
selected.value++; selected.value++;
} }
} })
if (c === KeyCode.KeyC || c === KeyCode.Space || c === KeyCode.Enter) { .realize('@shop_add', () => {
confirm();
}
}
function keydown(e: KeyboardEvent) {
const c = keycode(e.keyCode);
if (c === KeyCode.LeftArrow) {
count.value--; count.value--;
} })
if (c === KeyCode.RightArrow) { .realize('@shop_min', () => {
count.value++; count.value++;
} })
} .realize('exit', () => {
exit();
})
.realize('confirm', () => {
confirm();
});
function exit() { function exit() {
if (bought) core.status.route.push('closeShop'); if (bought) core.status.route.push('closeShop');
@ -312,16 +310,11 @@ function exit() {
} }
onMounted(async () => { 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}`); core.status.route.push(`openShop:${id}`);
}); });
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener('keyup', keyup); gameKey.dispose(props.ui.symbol);
document.removeEventListener('keydown', keydown);
}); });
</script> </script>

View File

@ -70,6 +70,13 @@ import { KeyCode } from '../plugin/keyCodes';
import { triggerFullscreen } from '../plugin/utils'; import { triggerFullscreen } from '../plugin/utils';
import { loading } from '../core/loader/load'; import { loading } from '../core/loader/load';
import { isMobile } from '../plugin/use'; 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 startdiv: HTMLDivElement;
let start: HTMLDivElement; let start: HTMLDivElement;
@ -179,29 +186,25 @@ function movein(button: HTMLElement, i: number) {
selected.value = button.id; selected.value = button.id;
} }
function keydown(e: KeyboardEvent) { gameKey.use(props.ui.symbol);
const c = keycode(e.keyCode); gameKey
const i = toshow.indexOf(selected.value); .realize('@start_up', () => {
if (c === KeyCode.DownArrow) { 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);
}
if (c === KeyCode.UpArrow) {
const next = toshow[i + 1]; const next = toshow[i + 1];
if (!next) return; if (!next) return;
selected.value = next; selected.value = next;
setCursor(buttons[toshow.length - i - 2], toshow.length - i - 2); setCursor(buttons[toshow.length - i - 2], toshow.length - i - 2);
} })
} .realize('@start_down', () => {
const i = toshow.indexOf(selected.value);
function keyup(e: KeyboardEvent) { const next = toshow[i - 1];
const c = keycode(e.keyCode); if (!next) return;
if (c === KeyCode.Enter || c === KeyCode.Space || c === KeyCode.KeyC) { selected.value = next;
setCursor(buttons[toshow.length - i], toshow.length - i);
})
.realize('confirm', () => {
clickStartButton(selected.value); clickStartButton(selected.value);
} });
}
function bgm() { function bgm() {
core.triggerBgm(); core.triggerBgm();
@ -310,9 +313,6 @@ onMounted(async () => {
soundChecked.value = core.musicStatus.bgmStatus; soundChecked.value = core.musicStatus.bgmStatus;
await sleep(50);
document.addEventListener('keydown', keydown);
document.addEventListener('keyup', keyup);
start.style.opacity = '1'; start.style.opacity = '1';
if (played) { if (played) {
text.value = text2; text.value = text2;
@ -327,8 +327,7 @@ onMounted(async () => {
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('resize', resize); window.removeEventListener('resize', resize);
document.removeEventListener('keydown', keydown); gameKey.dispose(props.ui.symbol);
document.removeEventListener('keyup', keyup);
}); });
</script> </script>

View File

@ -117,9 +117,12 @@ import { type, keycode, has } from '../plugin/utils';
import { hyper, sleep } from 'mutate-animate'; import { hyper, sleep } from 'mutate-animate';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
import { GameUi } from '@/core/main/custom/ui';
import { gameKey } from '@/core/main/init/hotkey';
const props = defineProps<{ const props = defineProps<{
num: number; num: number;
ui: GameUi;
}>(); }>();
type ItemMode = 'tools' | 'constants'; type ItemMode = 'tools' | 'constants';
@ -196,30 +199,9 @@ async function toEquip() {
mota.ui.main.open('equipbox'); mota.ui.main.open('equipbox');
} }
function keyup(e: KeyboardEvent) { gameKey.use(props.ui.symbol);
const c = keycode(e.keyCode); gameKey
if (c === KeyCode.Escape || c === KeyCode.KeyX || c === KeyCode.KeyT) { .realize('@toolbox_right', () => {
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) {
const constants = items.constants.length; const constants = items.constants.length;
if (mode.value === 'tools') { if (mode.value === 'tools') {
if (index.value >= constants) { if (index.value >= constants) {
@ -227,8 +209,8 @@ function keydown(e: KeyboardEvent) {
} }
mode.value = 'constants'; mode.value = 'constants';
} }
} })
if (c === KeyCode.LeftArrow) { .realize('@toolbox_left', () => {
const constants = items.tools.length; const constants = items.tools.length;
if (mode.value === 'constants') { if (mode.value === 'constants') {
if (index.value >= constants) { if (index.value >= constants) {
@ -236,19 +218,27 @@ function keydown(e: KeyboardEvent) {
} }
mode.value = 'tools'; mode.value = 'tools';
} }
} })
} .realize('@toolbox_up', () => {
if (index.value > 0) {
onMounted(async () => { index.value--;
// if (mota.plugin.ui.transition.value) await sleep(600); }
await sleep(50); })
document.addEventListener('keyup', keyup); .realize('@toolbox_down', () => {
document.addEventListener('keydown', keydown); const total = items[mode.value].length;
}); if (index.value < total - 1) {
index.value++;
}
})
.realize('exit', () => {
exit();
})
.realize('confirm', () => {
use(selected.value);
});
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener('keyup', keyup); gameKey.dispose(props.ui.symbol);
document.removeEventListener('keydown', keydown);
}); });
</script> </script>