完善ui控制器

This commit is contained in:
unanmed 2023-08-22 00:02:18 +08:00
parent 41e0037bed
commit be2a22e574
4 changed files with 101 additions and 29 deletions

View File

@ -21,7 +21,7 @@
### 机制 ### 机制
[] 苍蓝之殿 1: 利用点光源,照到的位置与没照到的位置内容不同,玩家可以选择是否装备手电筒 [] 苍蓝之殿 1:
[] 苍蓝之殿 2: [] 苍蓝之殿 2:
[] 苍蓝之殿 3: [] 苍蓝之殿 3:
[] 苍蓝之殿 4: [] 苍蓝之殿 4:
@ -72,7 +72,7 @@ dam4.png ---- 存档 59
[] 区域名称显示特效3D 粒子特效 [] 区域名称显示特效3D 粒子特效
[] 单独的工具栏,可以自定义按键 [] 单独的工具栏,可以自定义按键
[] 完全 ts 化 [] 完全 ts 化
[] 平行光 [] 平行光(待定)
[] 视角控制系统 [] 视角控制系统
[x] 重构设置界面 [x] 重构设置界面
[] 优化开头动画 [] 优化开头动画
@ -96,5 +96,7 @@ dam4.png ---- 存档 59
[] 重构技能树结构 [] 重构技能树结构
[] 技能树允许自动升级 [] 技能树允许自动升级
[] 重构装备系统 [] 重构装备系统
[] 野外地图加入平行光
[] 弹幕系统 [] 弹幕系统
[] 优化各种 ui
[] 怪物脚下加入阴影
[] 着色器特效

View File

@ -135,11 +135,12 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
* @param hotkey * @param hotkey
* @param cover id的按键 * @param cover id的按键
*/ */
extend(hotkey: Hotkey, cover: boolean) { extend(hotkey: Hotkey, cover: boolean = false) {
Object.values(hotkey.list).forEach(v => { Object.values(hotkey.list).forEach(v => {
if (v.id in this.list && !cover) return; if (v.id in this.list && !cover) return;
this.register(v.id, v.name, v); this.register(v.id, v.name, v);
}); });
return this;
} }
private ensureKey(key: KeyCode) { private ensureKey(key: KeyCode) {
@ -177,7 +178,7 @@ hotkey
core.doSL('autoSave', 'load'); core.doSL('autoSave', 'load');
} }
}) })
.register('redo', '撤销回退', { .register('redo', '恢复', {
defaults: KeyCode.KeyW, defaults: KeyCode.KeyW,
func: () => { func: () => {
core.doSL('autoSave', 'reload'); core.doSL('autoSave', 'reload');

View File

@ -1,4 +1,4 @@
import { Component, shallowReactive } from 'vue'; import { Component, h, shallowReactive } from 'vue';
import { EmitableEvent, EventEmitter } from '../../common/eventEmitter'; import { EmitableEvent, EventEmitter } from '../../common/eventEmitter';
import { KeyCode } from '../../../plugin/keyCodes'; import { KeyCode } from '../../../plugin/keyCodes';
import { Hotkey } from './hotkey'; import { Hotkey } from './hotkey';
@ -19,9 +19,13 @@ export class Focus<T = any> extends EventEmitter<FocusEvent<T>> {
stack: T[]; stack: T[];
focused: T | null = null; focused: T | null = null;
constructor(react?: boolean) { /** ui是否平等在平等时关闭ui不再会将其之后的ui全部删除而是保留 */
readonly equal: boolean;
constructor(react: boolean = false, equal: boolean = false) {
super(); super();
this.stack = react ? shallowReactive([]) : []; this.stack = react ? shallowReactive([]) : [];
this.equal = equal;
} }
/** /**
@ -79,12 +83,15 @@ export class Focus<T = any> extends EventEmitter<FocusEvent<T>> {
*/ */
pop() { pop() {
const item = this.stack.pop() ?? null; const item = this.stack.pop() ?? null;
const last = this.stack.at(-1) ?? null;
if (!last) this.unfocus();
else this.focus(last);
this.emit('pop', item); this.emit('pop', item);
return item; return item;
} }
/** /**
* * ui平等ui全部删除
* @param item * @param item
*/ */
splice(item: T) { splice(item: T) {
@ -93,7 +100,13 @@ export class Focus<T = any> extends EventEmitter<FocusEvent<T>> {
this.emit('splice', []); this.emit('splice', []);
return; return;
} }
this.emit('splice', this.stack.splice(index)); const last = this.stack.at(-1) ?? null;
if (!last) this.unfocus();
else this.focus(last);
this.emit(
'splice',
this.stack.splice(index, this.equal ? 1 : Infinity)
);
} }
/** /**
@ -133,6 +146,9 @@ export class GameUi extends EventEmitter<GameUiEvent> {
hotkey?: Hotkey; hotkey?: Hotkey;
id: string; id: string;
vBind: any = {};
vOn: Record<string, (...params: any[]) => any> = {};
constructor(id: string, component: Component, hotkey?: Hotkey) { constructor(id: string, component: Component, hotkey?: Hotkey) {
super(); super();
this.component = component; this.component = component;
@ -140,17 +156,53 @@ export class GameUi extends EventEmitter<GameUiEvent> {
this.id = id; this.id = id;
GameUi.uiList.push(this); GameUi.uiList.push(this);
} }
/**
* vue v-bind
* @param data
*/
vbind(data: any) {
this.vBind = data;
}
/**
* ui组件所触发的某种事件
* @param event
* @param fn
*/
von(event: string, fn: (...params: any[]) => any) {
this.vOn[event] = fn;
}
/**
* ui组件所触发的某种事件
* @param event
*/
voff(event: string) {
delete this.vOn[event];
}
} }
export class UiController extends Focus<GameUi> { export class UiController extends Focus<GameUi> {
constructor() { static list: UiController[] = [];
super(true);
constructor(equal?: boolean) {
super(true, equal);
UiController.list.push(this);
this.on('splice', spliced => { this.on('splice', spliced => {
spliced.forEach(v => { spliced.forEach(v => {
v.emit('close'); v.emit('close');
if (this.stack.length === 0) {
this.emit('end');
}
}); });
}); });
this.on('add', item => item.emit('open')); this.on('add', item => {
if (this.stack.length === 1) {
this.emit('start');
}
item.emit('open');
});
} }
/** /**
@ -171,7 +223,7 @@ export class UiController extends Focus<GameUi> {
} }
/** /**
* uiui都会同时关闭掉 * uiui都会同时关闭掉
* @param id ui的id * @param id ui的id
*/ */
close(id: string) { close(id: string) {

View File

@ -10,26 +10,16 @@ import FixedDetail from '../../../ui/fixedDetail.vue';
import Shop from '../../../ui/shop.vue'; import Shop from '../../../ui/shop.vue';
import Achievement from '../../../ui/achievement.vue'; import Achievement from '../../../ui/achievement.vue';
import Bgm from '../../../ui/bgmList.vue'; import Bgm from '../../../ui/bgmList.vue';
import StatusBar from '../../../ui/statusBar.vue';
import Mark from '../../../ui/markedEnemy.vue';
import Fixed from '../../../ui/fixed.vue';
import Chapter from '../../../ui/chapter.vue';
import CompleteAchi from '../../../ui/completeAchievement.vue';
import Start from '../../../ui/start.vue';
import { GameUi, UiController } from '../custom/ui'; import { GameUi, UiController } from '../custom/ui';
import { Hotkey } from '../custom/hotkey'; import { Hotkey } from '../custom/hotkey';
import { KeyCode } from '../../../plugin/keyCodes'; import { KeyCode } from '../../../plugin/keyCodes';
export const mainUi = new UiController();
mainUi.register(
new GameUi('book', Book),
new GameUi('toolbox', Toolbox),
new GameUi('equipbox', Equipbox),
new GameUi('settings', Settings),
new GameUi('desc', Desc),
new GameUi('skill', Skill),
new GameUi('skillTree', SkillTree),
new GameUi('fly', Fly),
new GameUi('fixedDetail', FixedDetail),
new GameUi('shop', Shop),
new GameUi('achievement', Achievement),
new GameUi('bgm', Bgm)
);
export const exitKey = new Hotkey('exitKey'); export const exitKey = new Hotkey('exitKey');
exitKey exitKey
.register('exit1', '退出', { .register('exit1', '退出', {
@ -44,3 +34,30 @@ exitKey
if (mainUi.focused) mainUi.splice(mainUi.focused); if (mainUi.focused) mainUi.splice(mainUi.focused);
} }
}); });
export const mainUi = new UiController();
mainUi.register(
new GameUi('book', Book, exitKey),
new GameUi('toolbox', Toolbox, exitKey),
new GameUi('equipbox', Equipbox, exitKey),
new GameUi('settings', Settings, exitKey),
new GameUi('desc', Desc, exitKey),
new GameUi('skill', Skill, exitKey),
new GameUi('skillTree', SkillTree, exitKey),
new GameUi('fly', Fly, exitKey),
new GameUi('fixedDetail', FixedDetail, exitKey),
new GameUi('shop', Shop, exitKey),
new GameUi('achievement', Achievement, exitKey),
new GameUi('bgm', Bgm, exitKey),
new GameUi('start', Start)
// todo: 把游戏主 div 加入到 mainUi 里面
);
export const fixedUi = new UiController(true);
fixedUi.register(
new GameUi('statusBar', StatusBar),
new GameUi('markedEnemy', Mark),
new GameUi('fixed', Fixed),
new GameUi('chapter', Chapter),
new GameUi('completeAchi', CompleteAchi)
);