mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-10-31 12:12:58 +08:00 
			
		
		
		
	ui控制器
This commit is contained in:
		
							parent
							
								
									31a8e2d502
								
							
						
					
					
						commit
						50fd24fbe0
					
				
							
								
								
									
										7
									
								
								idea.md
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								idea.md
									
									
									
									
									
								
							| @ -90,6 +90,11 @@ dam4.png ---- 存档 59 | ||||
| [] 优化路径显示,瞬移可以闪一下再熄灭 | ||||
| [] 勇士身上显示攻防血 | ||||
| [] 优化地图拖动 | ||||
| [] 楼层转换假如随机小贴士 | ||||
| [] 楼层转换加入随机小贴士 | ||||
| [] ui 中如果元素发生改变,那么做出背景亮一下再熄灭的效果 | ||||
| [] 双击怪物手册拐点可以直接在拖动条上定位 | ||||
| [] 重构技能树结构 | ||||
| [] 技能树允许自动升级 | ||||
| [] 重构装备系统 | ||||
| [] 野外地图加入平行光 | ||||
| [] 弹幕系统 | ||||
|  | ||||
							
								
								
									
										145
									
								
								src/core/main/custom/ui.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/core/main/custom/ui.ts
									
									
									
									
									
										Normal 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); | ||||
|     } | ||||
| } | ||||
| @ -3,7 +3,6 @@ import { EmitableEvent, EventEmitter } from '../common/eventEmitter'; | ||||
| import { transition } from '../../plugin/uiController'; | ||||
| import { loading } from '../loader/load'; | ||||
| import { hook } from './game'; | ||||
| import { isMobile } from '../../plugin/use'; | ||||
| import { GameStorage } from './storage'; | ||||
| import { triggerFullscreen } from '../../plugin/utils'; | ||||
| 
 | ||||
| @ -352,7 +351,6 @@ mainSetting | ||||
|         new MotaSetting() | ||||
|             .register('fullscreen', '全屏游戏', false) | ||||
|             .register('halo', '光环显示', true) | ||||
|             .register('frag', '打怪特效', true) | ||||
|             .register('itemDetail', '宝石血瓶显伤', true) | ||||
|             .register('transition', '界面动画', false) | ||||
|             .register('antiAlias', '抗锯齿', false) | ||||
| @ -376,10 +374,17 @@ mainSetting | ||||
|     ) | ||||
|     .register( | ||||
|         'utils', | ||||
|         '功能设置', | ||||
|         '系统设置', | ||||
|         new MotaSetting() | ||||
|             .register('betterLoad', '优化加载', true) | ||||
|             .register('autoScale', '自动放缩', true) | ||||
|     ) | ||||
|     .register( | ||||
|         'fx', | ||||
|         '特效设置', | ||||
|         new MotaSetting() | ||||
|             .register('paraLight', '野外阴影', true) | ||||
|             .register('frag', '打怪特效', true) | ||||
|     ); | ||||
| 
 | ||||
| interface SettingStorage { | ||||
| @ -394,6 +399,7 @@ interface SettingStorage { | ||||
|     fixed: boolean; | ||||
|     betterLoad: boolean; | ||||
|     autoScale: boolean; | ||||
|     paraLight: boolean; | ||||
| } | ||||
| 
 | ||||
| const storage = new GameStorage<SettingStorage>( | ||||
| @ -404,7 +410,6 @@ loading.once('coreInit', () => { | ||||
|     mainSetting.reset({ | ||||
|         'screen.fullscreen': !!document.fullscreenElement, | ||||
|         'screen.halo': !!storage.getValue('showHalo', true), | ||||
|         'screen.frag': !!storage.getValue('frag', true), | ||||
|         'screen.itemDetail': !!storage.getValue('itemDetail', true), | ||||
|         'screen.transition': !!storage.getValue('transition', false), | ||||
|         'screen.antiAlias': !!storage.getValue('antiAlias', false), | ||||
| @ -413,7 +418,9 @@ loading.once('coreInit', () => { | ||||
|         'screen.criticalGem': !!storage.getValue('criticalGem', false), | ||||
|         'action.fixed': !!storage.getValue('fixed', 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) | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
|  | ||||
| @ -5,7 +5,6 @@ | ||||
|             "请按下方的按钮打开。进入或退出全屏后请存读档一下,以解决一部分绘制问题。" | ||||
|         ], | ||||
|         "halo": ["开启后,会在地图上显示范围光环。"], | ||||
|         "frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"], | ||||
|         "itemDetail": ["是否在地图上显示宝石血瓶装备等增加的属性值"], | ||||
|         "transition": [ | ||||
|             "是否展示当一个ui界面,如怪物手册等的打开与关闭时的动画。当此项开启时,", | ||||
| @ -14,7 +13,6 @@ | ||||
|         "antiAlias": [ | ||||
|             "是否开启抗锯齿。开启后,画面会变得不那么锐利,观感更加舒适;关闭后,可以更好地展现出像素感,同时部分像素错误也不会出现。" | ||||
|         ], | ||||
| 
 | ||||
|         "fontSize": [ | ||||
|             "在各种 ui 界面中显示的文字大小,范围为 8 - 28。注意,字体过大可能会引起 ui 布局发生错误" | ||||
|         ], | ||||
| @ -57,5 +55,11 @@ | ||||
|             "<br>", | ||||
|             "2. 如果缩放后游戏画面高度高于页面高度的95%,那么缩小一个缩放比例,否则保持最大比例" | ||||
|         ] | ||||
|     }, | ||||
|     "fx": { | ||||
|         "paraLight": [ | ||||
|             "是否开启野外的平行光阴影,在野外将会显示平行光阴影,模拟太阳光,拥有不错的视觉效果" | ||||
|         ], | ||||
|         "frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"] | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user