mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-02-28 17:37:07 +08:00
完善ui控制器
This commit is contained in:
parent
41e0037bed
commit
be2a22e574
8
idea.md
8
idea.md
@ -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
|
||||||
|
[] 怪物脚下加入阴影
|
||||||
|
[] 着色器特效
|
||||||
|
@ -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');
|
||||||
|
@ -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> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭一个ui,注意在其之后的ui都会同时关闭掉
|
* 关闭一个ui,注意如果不是平等模式,在其之后的ui都会同时关闭掉
|
||||||
* @param id 要关闭的ui的id
|
* @param id 要关闭的ui的id
|
||||||
*/
|
*/
|
||||||
close(id: string) {
|
close(id: string) {
|
||||||
|
@ -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)
|
||||||
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user