ui控制器

This commit is contained in:
unanmed 2023-08-13 19:51:52 +08:00
parent 31a8e2d502
commit 50fd24fbe0
4 changed files with 169 additions and 8 deletions

View File

@ -90,6 +90,11 @@ dam4.png ---- 存档 59
[] 优化路径显示,瞬移可以闪一下再熄灭 [] 优化路径显示,瞬移可以闪一下再熄灭
[] 勇士身上显示攻防血 [] 勇士身上显示攻防血
[] 优化地图拖动 [] 优化地图拖动
[] 楼层转换假如随机小贴士 [] 楼层转换加入随机小贴士
[] ui 中如果元素发生改变,那么做出背景亮一下再熄灭的效果 [] ui 中如果元素发生改变,那么做出背景亮一下再熄灭的效果
[] 双击怪物手册拐点可以直接在拖动条上定位 [] 双击怪物手册拐点可以直接在拖动条上定位
[] 重构技能树结构
[] 技能树允许自动升级
[] 重构装备系统
[] 野外地图加入平行光
[] 弹幕系统

145
src/core/main/custom/ui.ts Normal file
View File

@ -0,0 +1,145 @@
import { Component, reactive } from 'vue';
import { EmitableEvent, EventEmitter } from '../../common/eventEmitter';
import { KeyCode } from '../../../plugin/keyCodes';
import { Hotkey } from './hotkey';
interface FocusEvent<T> extends EmitableEvent {
focus: (before: T | null, after: T) => void;
unfocus: (before: T | null) => void;
add: (item: T) => void;
pop: (item: T | null) => void;
register: (item: T[]) => void;
splice: (spliced: T[]) => void;
}
export class Focus<T = any> extends EventEmitter<FocusEvent<T>> {
targets: Set<T> = new Set();
/** 显示列表 */
stack: T[];
focused: T | null = null;
constructor(react?: boolean) {
super();
this.stack = react ? reactive([]) : [];
}
/**
*
* @param target
* @param add
*/
focus(target: T, add: boolean = false) {
if (target === this.focused) return;
const before = this.focused;
if (!this.stack.includes(target)) {
if (add) {
this.add(target);
this.focused = target;
} else {
console.warn(
`聚焦于一个不存在的目标,同时没有传入自动追加的参数`,
`聚焦目标:${target}`
);
return;
}
} else {
this.focused = target;
}
this.emit('focus', before, this.focused);
}
/**
*
*/
unfocus() {
const before = this.focused;
this.focused = null;
this.emit('unfocus', before);
}
/**
*
* @param item
*/
add(item: T) {
if (!this.targets.has(item)) {
console.warn(`向显示列表里面添加了不在物品集合里面的物品`);
return;
}
this.stack.push(item);
this.emit('add', item);
}
/**
*
*/
pop() {
const item = this.stack.pop() ?? null;
this.emit('pop', item);
return item;
}
/**
*
* @param item
*/
splice(item: T) {
const index = this.stack.indexOf(item);
if (index === -1) {
this.emit('splice', []);
return;
}
this.emit('splice', this.stack.splice(index));
}
/**
*
* @param item
*/
register(...item: T[]) {
item.forEach(v => {
this.targets.add(v);
});
this.emit('register', item);
}
}
interface GameUiEvent extends EmitableEvent {
close: () => void;
open: () => void;
}
export class GameUi extends EventEmitter<GameUiEvent> {
static uiList: GameUi[] = [];
component: Component;
hotkey?: Hotkey;
constructor(component: Component, hotkey?: Hotkey) {
super();
this.component = component;
this.hotkey = hotkey;
GameUi.uiList.push(this);
}
}
export class UiController extends Focus<GameUi> {
constructor() {
super(true);
this.on('splice', spliced => {
spliced.forEach(v => {
v.emit('close');
});
});
this.on('add', item => item.emit('open'));
}
/**
*
* @param key KeyCode
* @param e
*/
emitKey(key: KeyCode, e: KeyboardEvent) {
this.focused?.hotkey?.emitKey(key, e);
}
}

View File

@ -3,7 +3,6 @@ import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
import { transition } from '../../plugin/uiController'; import { transition } from '../../plugin/uiController';
import { loading } from '../loader/load'; import { loading } from '../loader/load';
import { hook } from './game'; import { hook } from './game';
import { isMobile } from '../../plugin/use';
import { GameStorage } from './storage'; import { GameStorage } from './storage';
import { triggerFullscreen } from '../../plugin/utils'; import { triggerFullscreen } from '../../plugin/utils';
@ -352,7 +351,6 @@ mainSetting
new MotaSetting() new MotaSetting()
.register('fullscreen', '全屏游戏', false) .register('fullscreen', '全屏游戏', false)
.register('halo', '光环显示', true) .register('halo', '光环显示', true)
.register('frag', '打怪特效', true)
.register('itemDetail', '宝石血瓶显伤', true) .register('itemDetail', '宝石血瓶显伤', true)
.register('transition', '界面动画', false) .register('transition', '界面动画', false)
.register('antiAlias', '抗锯齿', false) .register('antiAlias', '抗锯齿', false)
@ -376,10 +374,17 @@ mainSetting
) )
.register( .register(
'utils', 'utils',
'功能设置', '系统设置',
new MotaSetting() new MotaSetting()
.register('betterLoad', '优化加载', true) .register('betterLoad', '优化加载', true)
.register('autoScale', '自动放缩', true) .register('autoScale', '自动放缩', true)
)
.register(
'fx',
'特效设置',
new MotaSetting()
.register('paraLight', '野外阴影', true)
.register('frag', '打怪特效', true)
); );
interface SettingStorage { interface SettingStorage {
@ -394,6 +399,7 @@ interface SettingStorage {
fixed: boolean; fixed: boolean;
betterLoad: boolean; betterLoad: boolean;
autoScale: boolean; autoScale: boolean;
paraLight: boolean;
} }
const storage = new GameStorage<SettingStorage>( const storage = new GameStorage<SettingStorage>(
@ -404,7 +410,6 @@ loading.once('coreInit', () => {
mainSetting.reset({ mainSetting.reset({
'screen.fullscreen': !!document.fullscreenElement, 'screen.fullscreen': !!document.fullscreenElement,
'screen.halo': !!storage.getValue('showHalo', true), 'screen.halo': !!storage.getValue('showHalo', true),
'screen.frag': !!storage.getValue('frag', true),
'screen.itemDetail': !!storage.getValue('itemDetail', true), 'screen.itemDetail': !!storage.getValue('itemDetail', true),
'screen.transition': !!storage.getValue('transition', false), 'screen.transition': !!storage.getValue('transition', false),
'screen.antiAlias': !!storage.getValue('antiAlias', false), 'screen.antiAlias': !!storage.getValue('antiAlias', false),
@ -413,7 +418,9 @@ loading.once('coreInit', () => {
'screen.criticalGem': !!storage.getValue('criticalGem', false), 'screen.criticalGem': !!storage.getValue('criticalGem', false),
'action.fixed': !!storage.getValue('fixed', true), 'action.fixed': !!storage.getValue('fixed', true),
'utils.betterLoad': !!storage.getValue('betterLoad', true), 'utils.betterLoad': !!storage.getValue('betterLoad', true),
'utils.autoScale': !!storage.getValue('autoScale', true) 'utils.autoScale': !!storage.getValue('autoScale', true),
'fx.paraLight': !!storage.getValue('paraLight', true),
'fx.frag': !!storage.getValue('frag', true)
}); });
}); });

View File

@ -5,7 +5,6 @@
"请按下方的按钮打开。进入或退出全屏后请存读档一下,以解决一部分绘制问题。" "请按下方的按钮打开。进入或退出全屏后请存读档一下,以解决一部分绘制问题。"
], ],
"halo": ["开启后,会在地图上显示范围光环。"], "halo": ["开启后,会在地图上显示范围光环。"],
"frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"],
"itemDetail": ["是否在地图上显示宝石血瓶装备等增加的属性值"], "itemDetail": ["是否在地图上显示宝石血瓶装备等增加的属性值"],
"transition": [ "transition": [
"是否展示当一个ui界面如怪物手册等的打开与关闭时的动画。当此项开启时", "是否展示当一个ui界面如怪物手册等的打开与关闭时的动画。当此项开启时",
@ -14,7 +13,6 @@
"antiAlias": [ "antiAlias": [
"是否开启抗锯齿。开启后,画面会变得不那么锐利,观感更加舒适;关闭后,可以更好地展现出像素感,同时部分像素错误也不会出现。" "是否开启抗锯齿。开启后,画面会变得不那么锐利,观感更加舒适;关闭后,可以更好地展现出像素感,同时部分像素错误也不会出现。"
], ],
"fontSize": [ "fontSize": [
"在各种 ui 界面中显示的文字大小,范围为 8 - 28。注意字体过大可能会引起 ui 布局发生错误" "在各种 ui 界面中显示的文字大小,范围为 8 - 28。注意字体过大可能会引起 ui 布局发生错误"
], ],
@ -57,5 +55,11 @@
"<br>", "<br>",
"2. 如果缩放后游戏画面高度高于页面高度的95%,那么缩小一个缩放比例,否则保持最大比例" "2. 如果缩放后游戏画面高度高于页面高度的95%,那么缩小一个缩放比例,否则保持最大比例"
] ]
},
"fx": {
"paraLight": [
"是否开启野外的平行光阴影,在野外将会显示平行光阴影,模拟太阳光,拥有不错的视觉效果"
],
"frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"]
} }
} }