mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 20:59:37 +08:00
feat: 按键触发方式
This commit is contained in:
parent
b0f9e9d17d
commit
fdd4563f45
@ -5,7 +5,6 @@ import { GameStorage } from './main/storage';
|
|||||||
import './main/init/';
|
import './main/init/';
|
||||||
import './main/custom/toolbar';
|
import './main/custom/toolbar';
|
||||||
import { fixedUi, mainUi } from './main/init/ui';
|
import { fixedUi, mainUi } from './main/init/ui';
|
||||||
import { gameKey } from './main/init/hotkey';
|
|
||||||
import {
|
import {
|
||||||
MotaSetting,
|
MotaSetting,
|
||||||
SettingDisplayer,
|
SettingDisplayer,
|
||||||
@ -22,7 +21,8 @@ import {
|
|||||||
Hotkey,
|
Hotkey,
|
||||||
checkAssist,
|
checkAssist,
|
||||||
isAssist,
|
isAssist,
|
||||||
unwarpBinary
|
unwarpBinary,
|
||||||
|
gameKey
|
||||||
} from './main/custom/hotkey';
|
} from './main/custom/hotkey';
|
||||||
import { Keyboard, generateKeyboardEvent } from './main/custom/keyboard';
|
import { Keyboard, generateKeyboardEvent } from './main/custom/keyboard';
|
||||||
import './main/layout';
|
import './main/layout';
|
||||||
|
@ -1,22 +1,27 @@
|
|||||||
import { KeyCode } from '@/plugin/keyCodes';
|
import { KeyCode } from '@/plugin/keyCodes';
|
||||||
import { deleteWith, generateBinary, keycode, spliceBy } from '@/plugin/utils';
|
import { deleteWith, generateBinary, keycode, spliceBy } from '@/plugin/utils';
|
||||||
import { EventEmitter } from '../../common/eventEmitter';
|
import { EventEmitter } from 'eventemitter3';
|
||||||
|
import { isNil } from 'lodash-es';
|
||||||
|
|
||||||
// todo: 按下时触发,长按(单次/连续)触发,按下连续触发,按下节流触发,按下加速节流触发
|
// todo: 按下时触发,长按(单次/连续)触发,按下连续触发,按下节流触发,按下加速节流触发
|
||||||
|
|
||||||
interface HotkeyEvent {
|
interface HotkeyEvent {
|
||||||
set: (id: string, key: KeyCode, assist: number) => void;
|
set: [id: string, key: KeyCode, assist: number];
|
||||||
emit: (key: KeyCode, assist: number, type: KeyEmitType) => void;
|
emit: [key: KeyCode, assist: number, type: KeyEmitType];
|
||||||
|
press: [key: KeyCode];
|
||||||
|
release: [key: KeyCode];
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyEmitType =
|
type KeyEmitType =
|
||||||
| 'down'
|
|
||||||
| 'up'
|
| 'up'
|
||||||
|
| 'down'
|
||||||
| 'down-repeat'
|
| 'down-repeat'
|
||||||
| 'down-throttle'
|
| 'down-throttle'
|
||||||
| 'down-accelerate'
|
// todo: | 'down-accelerate'
|
||||||
| 'down-timeout';
|
| 'down-timeout';
|
||||||
|
|
||||||
|
type KeyEventType = 'up' | 'down';
|
||||||
|
|
||||||
interface AssistHoykey {
|
interface AssistHoykey {
|
||||||
ctrl: boolean;
|
ctrl: boolean;
|
||||||
shift: boolean;
|
shift: boolean;
|
||||||
@ -27,17 +32,17 @@ interface RegisterHotkeyData extends Partial<AssistHoykey> {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
defaults: KeyCode;
|
defaults: KeyCode;
|
||||||
type?: KeyEmitType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HotkeyData extends Required<RegisterHotkeyData> {
|
interface HotkeyData extends Required<RegisterHotkeyData> {
|
||||||
key: KeyCode;
|
key: KeyCode;
|
||||||
func: Map<symbol, HotkeyFunc>;
|
emits: Map<symbol, HotkeyEmitData>;
|
||||||
group?: string;
|
group?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id 此处的id包含数字后缀
|
* @param id 此处的id包含数字后缀
|
||||||
|
* @returns 返回 `@void` 时,表示此次触发没有包含副作用,不会致使 `preventDefault` 被执行
|
||||||
*/
|
*/
|
||||||
type HotkeyFunc = (
|
type HotkeyFunc = (
|
||||||
id: string,
|
id: string,
|
||||||
@ -45,6 +50,12 @@ type HotkeyFunc = (
|
|||||||
ev: KeyboardEvent
|
ev: KeyboardEvent
|
||||||
) => void | '@void';
|
) => void | '@void';
|
||||||
|
|
||||||
|
interface HotkeyEmitData {
|
||||||
|
func: HotkeyFunc;
|
||||||
|
onUp?: HotkeyFunc;
|
||||||
|
config?: HotkeyEmitConfig;
|
||||||
|
}
|
||||||
|
|
||||||
export interface HotkeyJSON {
|
export interface HotkeyJSON {
|
||||||
key: KeyCode;
|
key: KeyCode;
|
||||||
assist: number;
|
assist: number;
|
||||||
@ -64,8 +75,6 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
name: string;
|
name: string;
|
||||||
data: Record<string, HotkeyData> = {};
|
data: Record<string, HotkeyData> = {};
|
||||||
keyMap: Map<KeyCode, HotkeyData[]> = new Map();
|
keyMap: Map<KeyCode, HotkeyData[]> = new Map();
|
||||||
/** 每个指令的配置信息 */
|
|
||||||
configData: Map<string, HotkeyEmitConfig> = new Map();
|
|
||||||
/** id to name */
|
/** id to name */
|
||||||
groupName: Record<string, string> = {
|
groupName: Record<string, string> = {
|
||||||
none: '未分类按键'
|
none: '未分类按键'
|
||||||
@ -81,6 +90,13 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
private scopeStack: symbol[] = [];
|
private scopeStack: symbol[] = [];
|
||||||
private grouping: string = 'none';
|
private grouping: string = 'none';
|
||||||
|
|
||||||
|
/** 当前正在按下的按键 */
|
||||||
|
private pressed: Set<KeyCode> = new Set();
|
||||||
|
/** 按键按下时的时间 */
|
||||||
|
private pressTime: Map<KeyCode, number> = new Map();
|
||||||
|
/** 按键节流时间 */
|
||||||
|
private throttleMap: Map<KeyCode, number> = new Map();
|
||||||
|
|
||||||
constructor(id: string, name: string) {
|
constructor(id: string, name: string) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@ -98,9 +114,8 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
shift: !!data.shift,
|
shift: !!data.shift,
|
||||||
alt: !!data.alt,
|
alt: !!data.alt,
|
||||||
key: data.defaults,
|
key: data.defaults,
|
||||||
func: new Map(),
|
emits: new Map(),
|
||||||
group: this.grouping,
|
group: this.grouping
|
||||||
type: data.type ?? 'up'
|
|
||||||
};
|
};
|
||||||
this.ensureMap(d.key);
|
this.ensureMap(d.key);
|
||||||
if (d.id in this.data) {
|
if (d.id in this.data) {
|
||||||
@ -117,7 +132,7 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
* 实现一个按键按下时的操作
|
* 实现一个按键按下时的操作
|
||||||
* @param id 要实现的按键id,可以不包含数字后缀
|
* @param id 要实现的按键id,可以不包含数字后缀
|
||||||
* @param func 按键按下时执行的函数
|
* @param func 按键按下时执行的函数
|
||||||
* @param config 按键触发配置,默认为按键抬起时触发
|
* @param config 按键的配置信息
|
||||||
*/
|
*/
|
||||||
realize(id: string, func: HotkeyFunc, config?: HotkeyEmitConfig) {
|
realize(id: string, func: HotkeyFunc, config?: HotkeyEmitConfig) {
|
||||||
const toSet = Object.values(this.data).filter(v => {
|
const toSet = Object.values(this.data).filter(v => {
|
||||||
@ -129,12 +144,24 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
throw new Error(`Realize nonexistent key '${id}'.`);
|
throw new Error(`Realize nonexistent key '${id}'.`);
|
||||||
}
|
}
|
||||||
for (const key of toSet) {
|
for (const key of toSet) {
|
||||||
if (!key.func.has(this.scope)) {
|
const data = key.emits.get(this.scope);
|
||||||
throw new Error(
|
if (!data) {
|
||||||
`Cannot access using scope. Call use before calling realize.`
|
key.emits.set(this.scope, { func, config });
|
||||||
);
|
} else {
|
||||||
|
// 同时注册抬起和按下
|
||||||
|
const dataType = data.config?.type ?? 'up';
|
||||||
|
const configType = config?.type ?? 'up';
|
||||||
|
if (dataType === 'up' && configType !== 'up') {
|
||||||
|
data.onUp = func;
|
||||||
|
data.config ??= { type: configType };
|
||||||
|
data.config.type = configType;
|
||||||
|
} else if (dataType !== 'up' && configType === 'up') {
|
||||||
|
data.onUp = func;
|
||||||
|
} else {
|
||||||
|
data.config = config;
|
||||||
|
data.func = func;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
key.func.set(this.scope, func);
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -148,9 +175,6 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
this.scopeStack.push(symbol);
|
this.scopeStack.push(symbol);
|
||||||
this.scope = symbol;
|
this.scope = symbol;
|
||||||
this.conditionMap.set(symbol, () => true);
|
this.conditionMap.set(symbol, () => true);
|
||||||
for (const key of Object.values(this.data)) {
|
|
||||||
key.func.set(symbol, () => '@void');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,7 +183,7 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
*/
|
*/
|
||||||
dispose(symbol: symbol = this.scopeStack.at(-1) ?? Symbol()) {
|
dispose(symbol: symbol = this.scopeStack.at(-1) ?? Symbol()) {
|
||||||
for (const key of Object.values(this.data)) {
|
for (const key of Object.values(this.data)) {
|
||||||
key.func.delete(symbol);
|
key.emits.delete(symbol);
|
||||||
}
|
}
|
||||||
spliceBy(this.scopeStack, symbol);
|
spliceBy(this.scopeStack, symbol);
|
||||||
this.scope = this.scopeStack.at(-1) ?? Symbol();
|
this.scope = this.scopeStack.at(-1) ?? Symbol();
|
||||||
@ -196,31 +220,106 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
emitKey(
|
emitKey(
|
||||||
key: KeyCode,
|
key: KeyCode,
|
||||||
assist: number,
|
assist: number,
|
||||||
type: KeyEmitType,
|
type: KeyEventType,
|
||||||
ev: KeyboardEvent
|
ev: KeyboardEvent
|
||||||
): boolean {
|
): boolean {
|
||||||
|
// 检查全局启用情况
|
||||||
if (!this.enabled) return false;
|
if (!this.enabled) return false;
|
||||||
const when = this.conditionMap.get(this.scope)!;
|
const when = this.conditionMap.get(this.scope)!;
|
||||||
if (!when()) return false;
|
if (!when()) return false;
|
||||||
const toEmit = this.keyMap.get(key);
|
const toEmit = this.keyMap.get(key);
|
||||||
if (!toEmit) return false;
|
if (!toEmit) return false;
|
||||||
|
|
||||||
|
// 进行按键初始处理
|
||||||
const { ctrl, shift, alt } = unwarpBinary(assist);
|
const { ctrl, shift, alt } = unwarpBinary(assist);
|
||||||
|
|
||||||
|
// 真正开始触发按键
|
||||||
let emitted = false;
|
let emitted = false;
|
||||||
toEmit.forEach(v => {
|
toEmit.forEach(v => {
|
||||||
if (type !== v.type) return;
|
|
||||||
if (ctrl === v.ctrl && shift === v.shift && alt === v.alt) {
|
if (ctrl === v.ctrl && shift === v.shift && alt === v.alt) {
|
||||||
const func = v.func.get(this.scope);
|
const data = v.emits.get(this.scope);
|
||||||
if (!func) {
|
if (!data) return;
|
||||||
throw new Error(`Emit unknown scope keys.`);
|
if (type === 'up' && data.onUp) {
|
||||||
|
data.onUp(v.id, key, ev);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const res = func(v.id, key, ev);
|
if (!this.canEmit(v.id, key, type, data)) return;
|
||||||
|
const res = data.func(v.id, key, ev);
|
||||||
if (res !== '@void') emitted = true;
|
if (res !== '@void') emitted = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.emit('emit', key, assist, type);
|
this.emit('emit', key, assist, type);
|
||||||
|
|
||||||
|
if (type === 'down') this.checkPress(key);
|
||||||
|
else this.checkPressEnd(key);
|
||||||
|
|
||||||
return emitted;
|
return emitted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查按键按下情况,如果没有按下则添加
|
||||||
|
* @param keyCode 按下的按键
|
||||||
|
*/
|
||||||
|
private checkPress(keyCode: KeyCode) {
|
||||||
|
if (this.pressed.has(keyCode)) return;
|
||||||
|
this.pressed.add(keyCode);
|
||||||
|
this.pressTime.set(keyCode, Date.now());
|
||||||
|
this.emit('press', keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当按键松开时,移除相应的按下配置
|
||||||
|
* @param keyCode 松开的按键
|
||||||
|
*/
|
||||||
|
private checkPressEnd(keyCode: KeyCode) {
|
||||||
|
if (!this.pressed.has(keyCode)) return;
|
||||||
|
this.pressed.delete(keyCode);
|
||||||
|
this.pressTime.delete(keyCode);
|
||||||
|
this.emit('release', keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查一个按键是否可以被触发
|
||||||
|
* @param id 触发的按键id
|
||||||
|
* @param keyCode 按键码
|
||||||
|
*/
|
||||||
|
private canEmit(
|
||||||
|
_id: string,
|
||||||
|
keyCode: KeyCode,
|
||||||
|
type: KeyEventType,
|
||||||
|
data: HotkeyEmitData
|
||||||
|
) {
|
||||||
|
const config = data?.config;
|
||||||
|
// 这时默认为抬起触发,始终可触发
|
||||||
|
if (type === 'up') {
|
||||||
|
if (!config || config.type === 'up') return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
if (!config) return false;
|
||||||
|
// 按下单次触发
|
||||||
|
if (config.type === 'down') return !this.pressed.has(keyCode);
|
||||||
|
// 按下重复触发
|
||||||
|
if (config.type === 'down-repeat') return true;
|
||||||
|
if (config.type === 'down-timeout') {
|
||||||
|
const time = this.pressTime.get(keyCode);
|
||||||
|
if (isNil(time) || isNil(config.timeout)) return false;
|
||||||
|
return Date.now() - time >= config.timeout;
|
||||||
|
}
|
||||||
|
if (config.type === 'down-throttle') {
|
||||||
|
const thorttleTime = this.throttleMap.get(keyCode);
|
||||||
|
if (isNil(config.throttle)) return false;
|
||||||
|
if (isNil(thorttleTime)) {
|
||||||
|
this.throttleMap.set(keyCode, Date.now());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Date.now() - thorttleTime >= config.throttle) {
|
||||||
|
this.throttleMap.set(keyCode, Date.now());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按键分组,执行后 register 的按键将会加入此分组
|
* 按键分组,执行后 register 的按键将会加入此分组
|
||||||
* @param id 组的id
|
* @param id 组的id
|
||||||
@ -290,22 +389,6 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo
|
|
||||||
/**
|
|
||||||
* 热键控制器,用于控制按下时触发等操作
|
|
||||||
*/
|
|
||||||
export class HotkeyController {
|
|
||||||
/** 所有按下的按键 */
|
|
||||||
private pressed: Set<KeyCode> = new Set();
|
|
||||||
|
|
||||||
/** 当前控制器管理的热键实例 */
|
|
||||||
hotkey: Hotkey;
|
|
||||||
|
|
||||||
constructor(hotkey: Hotkey) {
|
|
||||||
this.hotkey = hotkey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function unwarpBinary(bin: number): AssistHoykey {
|
export function unwarpBinary(bin: number): AssistHoykey {
|
||||||
return {
|
return {
|
||||||
ctrl: !!(bin & (1 << 0)),
|
ctrl: !!(bin & (1 << 0)),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { EventEmitter, Listener } from '@/core/common/eventEmitter';
|
import { EventEmitter, Listener } from '@/core/common/eventEmitter';
|
||||||
import { KeyCode } from '@/plugin/keyCodes';
|
import { KeyCode } from '@/plugin/keyCodes';
|
||||||
import { gameKey } from '../init/hotkey';
|
import { gameKey } from './hotkey';
|
||||||
import { unwarpBinary } from './hotkey';
|
import { unwarpBinary } from './hotkey';
|
||||||
import { deleteWith, flipBinary } from '@/plugin/utils';
|
import { deleteWith, flipBinary } from '@/plugin/utils';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
@ -15,25 +15,21 @@ gameKey
|
|||||||
.group('game', '游戏按键')
|
.group('game', '游戏按键')
|
||||||
.register({
|
.register({
|
||||||
id: 'moveUp',
|
id: 'moveUp',
|
||||||
type: 'down',
|
|
||||||
name: '上移',
|
name: '上移',
|
||||||
defaults: KeyCode.UpArrow
|
defaults: KeyCode.UpArrow
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: 'moveDown',
|
id: 'moveDown',
|
||||||
type: 'down',
|
|
||||||
name: '下移',
|
name: '下移',
|
||||||
defaults: KeyCode.DownArrow
|
defaults: KeyCode.DownArrow
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: 'moveLeft',
|
id: 'moveLeft',
|
||||||
type: 'down',
|
|
||||||
name: '左移',
|
name: '左移',
|
||||||
defaults: KeyCode.LeftArrow
|
defaults: KeyCode.LeftArrow
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: 'moveRight',
|
id: 'moveRight',
|
||||||
type: 'down',
|
|
||||||
name: '右移',
|
name: '右移',
|
||||||
defaults: KeyCode.RightArrow
|
defaults: KeyCode.RightArrow
|
||||||
})
|
})
|
||||||
@ -293,78 +289,66 @@ 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', '怪物手册')
|
||||||
.register({
|
.register({
|
||||||
id: '@book_up',
|
id: '@book_up',
|
||||||
name: '上移光标',
|
name: '上移光标',
|
||||||
defaults: KeyCode.UpArrow,
|
defaults: KeyCode.UpArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@book_down',
|
id: '@book_down',
|
||||||
name: '下移光标',
|
name: '下移光标',
|
||||||
defaults: KeyCode.DownArrow,
|
defaults: KeyCode.DownArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@book_pageDown_1',
|
id: '@book_pageDown_1',
|
||||||
name: '下移5个怪物_1',
|
name: '下移5个怪物_1',
|
||||||
defaults: KeyCode.RightArrow,
|
defaults: KeyCode.RightArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@book_pageDown_2',
|
id: '@book_pageDown_2',
|
||||||
name: '下移5个怪物_2',
|
name: '下移5个怪物_2',
|
||||||
defaults: KeyCode.PageDown,
|
defaults: KeyCode.PageDown
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@book_pageUp_1',
|
id: '@book_pageUp_1',
|
||||||
name: '上移5个怪物_1',
|
name: '上移5个怪物_1',
|
||||||
defaults: KeyCode.LeftArrow,
|
defaults: KeyCode.LeftArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@book_pageUp_2',
|
id: '@book_pageUp_2',
|
||||||
name: '上移5个怪物_2',
|
name: '上移5个怪物_2',
|
||||||
defaults: KeyCode.PageUp,
|
defaults: KeyCode.PageUp
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
// --------------------
|
// --------------------
|
||||||
.group('@ui_toolbox', '道具栏')
|
.group('@ui_toolbox', '道具栏')
|
||||||
.register({
|
.register({
|
||||||
id: '@toolbox_right',
|
id: '@toolbox_right',
|
||||||
name: '光标右移',
|
name: '光标右移',
|
||||||
defaults: KeyCode.RightArrow,
|
defaults: KeyCode.RightArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@toolbox_left',
|
id: '@toolbox_left',
|
||||||
name: '光标左移',
|
name: '光标左移',
|
||||||
defaults: KeyCode.LeftArrow,
|
defaults: KeyCode.LeftArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@toolbox_up',
|
id: '@toolbox_up',
|
||||||
name: '光标上移',
|
name: '光标上移',
|
||||||
defaults: KeyCode.UpArrow,
|
defaults: KeyCode.UpArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@toolbox_down',
|
id: '@toolbox_down',
|
||||||
name: '光标下移',
|
name: '光标下移',
|
||||||
defaults: KeyCode.DownArrow,
|
defaults: KeyCode.DownArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
// --------------------
|
// --------------------
|
||||||
.group('@ui_shop', '商店')
|
.group('@ui_shop', '商店')
|
||||||
@ -381,14 +365,12 @@ gameKey
|
|||||||
.register({
|
.register({
|
||||||
id: '@shop_add',
|
id: '@shop_add',
|
||||||
name: '增加购买量',
|
name: '增加购买量',
|
||||||
defaults: KeyCode.RightArrow,
|
defaults: KeyCode.RightArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
.register({
|
.register({
|
||||||
id: '@shop_min',
|
id: '@shop_min',
|
||||||
name: '减少购买量',
|
name: '减少购买量',
|
||||||
defaults: KeyCode.LeftArrow,
|
defaults: KeyCode.LeftArrow
|
||||||
type: 'down'
|
|
||||||
})
|
})
|
||||||
// --------------------
|
// --------------------
|
||||||
.group('@ui_fly', '楼层传送')
|
.group('@ui_fly', '楼层传送')
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
import './fixed';
|
import './fixed';
|
||||||
import './keyboard';
|
import './keyboard';
|
||||||
|
import './hotkey';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { SettingComponent, SettingComponentProps } from '../setting';
|
import type { SettingComponent, SettingComponentProps } from '../setting';
|
||||||
import { Button, InputNumber, Radio } from 'ant-design-vue';
|
import { Button, InputNumber, Radio } from 'ant-design-vue';
|
||||||
import { mainUi } from './ui';
|
import { mainUi } from './ui';
|
||||||
import { gameKey } from './hotkey';
|
import { gameKey } from '../custom/hotkey';
|
||||||
|
|
||||||
interface Components {
|
interface Components {
|
||||||
Default: SettingComponent;
|
Default: SettingComponent;
|
||||||
|
@ -17,7 +17,7 @@ import {
|
|||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
import { MotaSettingItem, mainSetting } from '../setting';
|
import { MotaSettingItem, mainSetting } from '../setting';
|
||||||
import Minimap from '@/components/minimap.vue';
|
import Minimap from '@/components/minimap.vue';
|
||||||
import { gameKey } from './hotkey';
|
import { gameKey } from '../custom/hotkey';
|
||||||
import { FunctionalComponent, StyleValue, h } from 'vue';
|
import { FunctionalComponent, StyleValue, h } from 'vue';
|
||||||
import { mainUi } from './ui';
|
import { mainUi } from './ui';
|
||||||
import { isMobile } from '@/plugin/use';
|
import { isMobile } from '@/plugin/use';
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import type { RenderAdapter } from '@/core/render/adapter';
|
import type { RenderAdapter } from '@/core/render/adapter';
|
||||||
import type { HeroRenderer } from '@/core/render/preset/hero';
|
import type { HeroRenderer } from '@/core/render/preset/hero';
|
||||||
import { backDir } from './utils';
|
|
||||||
|
|
||||||
interface Adapters {
|
interface Adapters {
|
||||||
'hero-adapter'?: RenderAdapter<HeroRenderer>;
|
'hero-adapter'?: RenderAdapter<HeroRenderer>;
|
||||||
@ -9,7 +8,7 @@ interface Adapters {
|
|||||||
const adapters: Adapters = {};
|
const adapters: Adapters = {};
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
if (!main.replayChecking) {
|
if (!main.replayChecking && main.mode === 'play') {
|
||||||
const Adapter = Mota.require('module', 'Render').RenderAdapter;
|
const Adapter = Mota.require('module', 'Render').RenderAdapter;
|
||||||
const hero = Adapter.get<HeroRenderer>('hero-adapter');
|
const hero = Adapter.get<HeroRenderer>('hero-adapter');
|
||||||
|
|
||||||
|
@ -151,34 +151,50 @@ function checkScroll() {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
gameKey.use(props.ui.symbol);
|
gameKey.use(props.ui.symbol);
|
||||||
gameKey
|
gameKey
|
||||||
.realize('@book_up', () => {
|
.realize(
|
||||||
if (selected.value > 0) {
|
'@book_up',
|
||||||
selected.value--;
|
() => {
|
||||||
}
|
if (selected.value > 0) {
|
||||||
checkScroll();
|
selected.value--;
|
||||||
})
|
}
|
||||||
.realize('@book_down', () => {
|
checkScroll();
|
||||||
if (selected.value < enemy.length - 1) {
|
},
|
||||||
selected.value++;
|
{ type: 'down-repeat' }
|
||||||
}
|
)
|
||||||
checkScroll();
|
.realize(
|
||||||
})
|
'@book_down',
|
||||||
.realize('@book_pageDown', () => {
|
() => {
|
||||||
if (selected.value <= 4) {
|
if (selected.value < enemy.length - 1) {
|
||||||
selected.value = 0;
|
selected.value++;
|
||||||
} else {
|
}
|
||||||
selected.value -= 5;
|
checkScroll();
|
||||||
}
|
},
|
||||||
checkScroll();
|
{ type: 'down-repeat' }
|
||||||
})
|
)
|
||||||
.realize('@book_pageUp', () => {
|
.realize(
|
||||||
if (selected.value >= enemy.length - 5) {
|
'@book_pageDown',
|
||||||
selected.value = enemy.length - 1;
|
() => {
|
||||||
} else {
|
if (selected.value <= 4) {
|
||||||
selected.value += 5;
|
selected.value = 0;
|
||||||
}
|
} else {
|
||||||
checkScroll();
|
selected.value -= 5;
|
||||||
})
|
}
|
||||||
|
checkScroll();
|
||||||
|
},
|
||||||
|
{ type: 'down-repeat' }
|
||||||
|
)
|
||||||
|
.realize(
|
||||||
|
'@book_pageUp',
|
||||||
|
() => {
|
||||||
|
if (selected.value >= enemy.length - 5) {
|
||||||
|
selected.value = enemy.length - 1;
|
||||||
|
} else {
|
||||||
|
selected.value += 5;
|
||||||
|
}
|
||||||
|
checkScroll();
|
||||||
|
},
|
||||||
|
{ type: 'down-repeat' }
|
||||||
|
)
|
||||||
.realize('exit', () => {
|
.realize('exit', () => {
|
||||||
exit();
|
exit();
|
||||||
})
|
})
|
||||||
|
@ -289,12 +289,20 @@ gameKey
|
|||||||
selected.value++;
|
selected.value++;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.realize('@shop_add', () => {
|
.realize(
|
||||||
count.value++;
|
'@shop_add',
|
||||||
})
|
() => {
|
||||||
.realize('@shop_min', () => {
|
count.value++;
|
||||||
count.value--;
|
},
|
||||||
})
|
{ type: 'down-repeat' }
|
||||||
|
)
|
||||||
|
.realize(
|
||||||
|
'@shop_min',
|
||||||
|
() => {
|
||||||
|
count.value--;
|
||||||
|
},
|
||||||
|
{ type: 'down-repeat' }
|
||||||
|
)
|
||||||
.realize('exit', () => {
|
.realize('exit', () => {
|
||||||
exit();
|
exit();
|
||||||
})
|
})
|
||||||
|
@ -192,20 +192,28 @@ function movein(button: HTMLElement, i: number) {
|
|||||||
|
|
||||||
gameKey.use(props.ui.symbol);
|
gameKey.use(props.ui.symbol);
|
||||||
gameKey
|
gameKey
|
||||||
.realize('@start_up', () => {
|
.realize(
|
||||||
const i = toshow.indexOf(selected.value);
|
'@start_up',
|
||||||
const next = toshow[i + 1];
|
() => {
|
||||||
if (!next) return;
|
const i = toshow.indexOf(selected.value);
|
||||||
selected.value = next;
|
const next = toshow[i + 1];
|
||||||
setCursor(buttons[toshow.length - i - 2], toshow.length - i - 2);
|
if (!next) return;
|
||||||
})
|
selected.value = next;
|
||||||
.realize('@start_down', () => {
|
setCursor(buttons[toshow.length - i - 2], toshow.length - i - 2);
|
||||||
const i = toshow.indexOf(selected.value);
|
},
|
||||||
const next = toshow[i - 1];
|
{ type: 'down-repeat' }
|
||||||
if (!next) return;
|
)
|
||||||
selected.value = next;
|
.realize(
|
||||||
setCursor(buttons[toshow.length - i], toshow.length - i);
|
'@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);
|
||||||
|
},
|
||||||
|
{ type: 'down-repeat' }
|
||||||
|
)
|
||||||
.realize('confirm', () => {
|
.realize('confirm', () => {
|
||||||
clickStartButton(selected.value);
|
clickStartButton(selected.value);
|
||||||
});
|
});
|
||||||
|
@ -205,35 +205,51 @@ async function toEquip() {
|
|||||||
|
|
||||||
gameKey.use(props.ui.symbol);
|
gameKey.use(props.ui.symbol);
|
||||||
gameKey
|
gameKey
|
||||||
.realize('@toolbox_right', () => {
|
.realize(
|
||||||
const constants = items.constants.length;
|
'@toolbox_right',
|
||||||
if (mode.value === 'tools') {
|
() => {
|
||||||
if (index.value >= constants) {
|
const constants = items.constants.length;
|
||||||
index.value = constants - 1;
|
if (mode.value === 'tools') {
|
||||||
|
if (index.value >= constants) {
|
||||||
|
index.value = constants - 1;
|
||||||
|
}
|
||||||
|
mode.value = 'constants';
|
||||||
}
|
}
|
||||||
mode.value = 'constants';
|
},
|
||||||
}
|
{ type: 'down-repeat' }
|
||||||
})
|
)
|
||||||
.realize('@toolbox_left', () => {
|
.realize(
|
||||||
const constants = items.tools.length;
|
'@toolbox_left',
|
||||||
if (mode.value === 'constants') {
|
() => {
|
||||||
if (index.value >= constants) {
|
const constants = items.tools.length;
|
||||||
index.value = constants - 1;
|
if (mode.value === 'constants') {
|
||||||
|
if (index.value >= constants) {
|
||||||
|
index.value = constants - 1;
|
||||||
|
}
|
||||||
|
mode.value = 'tools';
|
||||||
}
|
}
|
||||||
mode.value = 'tools';
|
},
|
||||||
}
|
{ type: 'down-repeat' }
|
||||||
})
|
)
|
||||||
.realize('@toolbox_up', () => {
|
.realize(
|
||||||
if (index.value > 0) {
|
'@toolbox_up',
|
||||||
index.value--;
|
() => {
|
||||||
}
|
if (index.value > 0) {
|
||||||
})
|
index.value--;
|
||||||
.realize('@toolbox_down', () => {
|
}
|
||||||
const total = items[mode.value].length;
|
},
|
||||||
if (index.value < total - 1) {
|
{ type: 'down-repeat' }
|
||||||
index.value++;
|
)
|
||||||
}
|
.realize(
|
||||||
})
|
'@toolbox_down',
|
||||||
|
() => {
|
||||||
|
const total = items[mode.value].length;
|
||||||
|
if (index.value < total - 1) {
|
||||||
|
index.value++;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ type: 'down-repeat' }
|
||||||
|
)
|
||||||
.realize('exit', () => {
|
.realize('exit', () => {
|
||||||
exit();
|
exit();
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user