feat: 自定义状态栏的显示

This commit is contained in:
unanmed 2023-12-18 17:10:28 +08:00
parent 56ff2098f7
commit 72d74ec7a6
5 changed files with 108 additions and 24 deletions

View File

@ -9,6 +9,7 @@ import { fixedUi, mainUi } from './main/init/ui';
import { GameStorage } from './main/storage'; import { GameStorage } from './main/storage';
import { resolvePlugin } from './plugin'; import { resolvePlugin } from './plugin';
import './main/init/'; import './main/init/';
import './main/custom/toolbar';
interface AncTePlugin { interface AncTePlugin {
pop: ReturnType<typeof import('../plugin/pop').default>; pop: ReturnType<typeof import('../plugin/pop').default>;

View File

@ -1,10 +1,12 @@
import { EmitableEvent, EventEmitter } from '@/core/common/eventEmitter'; import { EmitableEvent, EventEmitter } from '@/core/common/eventEmitter';
import { KeyCode } from '@/plugin/keyCodes'; import { KeyCode } from '@/plugin/keyCodes';
import { flipBinary, has } from '@/plugin/utils'; import { flipBinary, has } from '@/plugin/utils';
import { FunctionalComponent, reactive } from 'vue'; import { FunctionalComponent, nextTick, reactive } from 'vue';
import { createToolbarComponents } from '../init/toolbar'; import { createToolbarComponents } from '../init/toolbar';
import { gameKey } from '../init/hotkey'; import { gameKey } from '../init/hotkey';
import { unwarpBinary } from './hotkey'; import { unwarpBinary } from './hotkey';
import { fixedUi } from '../init/ui';
import { hook } from '../game';
interface CustomToolbarEvent extends EmitableEvent { interface CustomToolbarEvent extends EmitableEvent {
add: (item: ValueOf<ToolbarItemMap>) => void; add: (item: ValueOf<ToolbarItemMap>) => void;
@ -77,13 +79,14 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
x: number = 300; x: number = 300;
y: number = 300; y: number = 300;
width: number = 300; width: number = 300;
height: number = 100; height: number = 70;
// ----- other // ----- other
assistKey: number = 0; assistKey: number = 0;
constructor(id: string) { constructor(id: string) {
super(); super();
this.id = id; this.id = id;
this.show();
CustomToolbar.list.push(this); CustomToolbar.list.push(this);
} }
@ -134,13 +137,12 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
*/ */
emitTool(id: string) { emitTool(id: string) {
const item = this.items.find(v => v.id === id); const item = this.items.find(v => v.id === id);
if (!item) return; if (!item) return this;
this.emit(id); this.emit(id);
if (item.type === 'hotkey') { if (item.type === 'hotkey') {
// 按键 // 按键
const { ctrl, shift, alt } = unwarpBinary( const assist = item.assist | this.assistKey;
item.assist | this.assistKey const { ctrl, shift, alt } = unwarpBinary(assist);
);
const ev = new KeyboardEvent('keyup', { const ev = new KeyboardEvent('keyup', {
ctrlKey: ctrl, ctrlKey: ctrl,
shiftKey: shift, shiftKey: shift,
@ -148,7 +150,7 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
}); });
// todo: Advanced KeyboardEvent simulate // todo: Advanced KeyboardEvent simulate
gameKey.emitKey(item.key, item.assist, 'up', ev); gameKey.emitKey(item.key, assist, 'up', ev);
} else if (item.type === 'item') { } else if (item.type === 'item') {
// 道具 // 道具
core.tryUseItem(item.item); core.tryUseItem(item.item);
@ -162,6 +164,15 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
this.assistKey = flipBinary(this.assistKey, 2); this.assistKey = flipBinary(this.assistKey, 2);
} }
} }
return this;
}
refresh() {
const items = this.items.splice(0);
nextTick(() => {
this.items.push(...items);
});
// this.items.push(...this.items.splice(0));
} }
setPos(x?: number, y?: number) { setPos(x?: number, y?: number) {
@ -174,7 +185,31 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
has(height) && (this.height = height); has(height) && (this.height = height);
} }
show() {
fixedUi.open('toolbar', { bar: this });
}
static get(id: string) { static get(id: string) {
return this.list.find(v => v.id === id); return this.list.find(v => v.id === id);
} }
} }
hook.once('reset', () => {
const toolbar = new CustomToolbar('test');
toolbar.add<'hotkey'>({
id: 'test1',
type: 'hotkey',
assist: 0,
key: KeyCode.KeyX
});
toolbar.add<'assistKey'>({
id: 'test2',
type: 'assistKey',
assist: KeyCode.Ctrl
});
toolbar.add<'item'>({
id: 'test3',
type: 'item',
item: 'book'
});
});

View File

@ -4,7 +4,6 @@ import type {
CustomToolbarProps CustomToolbarProps
} from '../custom/toolbar'; } from '../custom/toolbar';
import BoxAnimate from '@/components/boxAnimate.vue'; import BoxAnimate from '@/components/boxAnimate.vue';
import { onUnmounted, ref } from 'vue';
import { checkAssist } from '../custom/hotkey'; import { checkAssist } from '../custom/hotkey';
interface Components { interface Components {
@ -31,7 +30,7 @@ function DefaultTool(props: CustomToolbarProps) {
function KeyTool(props: CustomToolbarProps<'hotkey'>) { function KeyTool(props: CustomToolbarProps<'hotkey'>) {
const { item, toolbar } = props; const { item, toolbar } = props;
return ( return (
<span onClick={() => toolbar.emitTool(item.id)}> <span class="button-text" onClick={() => toolbar.emitTool(item.id)}>
{KeyCodeUtils.toString(item.key)} {KeyCodeUtils.toString(item.key)}
</span> </span>
); );
@ -40,30 +39,30 @@ function KeyTool(props: CustomToolbarProps<'hotkey'>) {
function ItemTool(props: CustomToolbarProps<'item'>) { function ItemTool(props: CustomToolbarProps<'item'>) {
const { item, toolbar } = props; const { item, toolbar } = props;
return ( return (
<div onClick={() => toolbar.emitTool(item.id)}> <div
<BoxAnimate id={item.item}></BoxAnimate> style="display: flex; justify-content: center; width: 50px"
onClick={() => toolbar.emitTool(item.id)}
>
<BoxAnimate
noborder={true}
width={50}
height={50}
id={item.item}
></BoxAnimate>
</div> </div>
); );
} }
function AssistKeyTool(props: CustomToolbarProps<'assistKey'>) { function AssistKeyTool(props: CustomToolbarProps<'assistKey'>) {
const { item, toolbar } = props; const { item, toolbar } = props;
const pressed = ref(checkAssist(toolbar.assistKey, item.assist)); const pressed = checkAssist(toolbar.assistKey, item.assist);
const listen = () => {
pressed.value = checkAssist(toolbar.assistKey, item.assist);
};
toolbar.on('emit', listen);
onUnmounted(() => {
toolbar.off('emit', listen);
});
return ( return (
<span <span
class="button-text" class="button-text"
// @ts-ignore // @ts-ignore
active={pressed.value} active={pressed}
onClick={() => toolbar.emitTool(item.id)} onClick={() => toolbar.emitTool(item.id).refresh()}
> >
{KeyCodeUtils.toString(item.assist)} {KeyCodeUtils.toString(item.assist)}
</span> </span>

View File

@ -336,6 +336,6 @@ export function getStatusLabel(name: string) {
export function flipBinary(num: number, col: number) { export function flipBinary(num: number, col: number) {
const n = 1 << col; const n = 1 << col;
if (num & col) return num & ~n; if (num & n) return num & ~n;
else return num | n; else return num | n;
} }

View File

@ -1,5 +1,6 @@
<template> <template>
<Box <Box
class="toolbar-container"
:dragable="true" :dragable="true"
:resizable="true" :resizable="true"
v-model:left="box.x" v-model:left="box.x"
@ -8,7 +9,11 @@
v-model:width="box.width" v-model:width="box.width"
> >
<div class="toolbar"> <div class="toolbar">
<div v-for="item of bar.items"> <div
class="toolbar-item"
v-for="item of bar.items"
@click.stop="click"
>
<component <component
:is="(item.com as any)" :is="(item.com as any)"
:item="item" :item="item"
@ -52,11 +57,55 @@ watch(box, ({ x, y, width, height }) => {
bar.width = width; bar.width = width;
bar.height = height; bar.height = height;
}); });
function click() {
// pass
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.toolbar-container {
background-color: #0009;
padding: 5px;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap;
align-items: center;
font-size: 150%;
}
.toolbar-item {
display: flex;
margin: 5px;
min-width: 50px;
height: 50px;
cursor: pointer;
background-color: #222;
border: 1px solid #ddd8;
justify-content: center;
align-items: center;
transition: all 0.1s linear;
}
.toolbar-item::v-deep(> *) {
height: 50px;
min-width: 50px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
text-overflow: clip;
text-wrap: nowrap;
}
.toolbar-item:hover {
background-color: #444;
}
.toolbar-item:active {
background-color: #333;
} }
</style> </style>