feat: 新的ui系统

This commit is contained in:
unanmed 2023-10-29 22:13:37 +08:00
parent 57498ea72e
commit 669ad11c82
10 changed files with 182 additions and 59 deletions

View File

@ -2317,7 +2317,7 @@ control.prototype._doSL_load = function (id, callback) {
1 1
)[0]; )[0];
if (!main.replayChecking) { if (!main.replayChecking) {
mota.plugin.ui.startOpened.value = false; mota.ui.fixed.open('start');
} }
if (core.isPlaying() && !core.status.gameOver) { if (core.isPlaying() && !core.status.gameOver) {
core.control.autosave(0); core.control.autosave(0);
@ -2334,7 +2334,7 @@ control.prototype._doSL_load = function (id, callback) {
null, null,
function (data) { function (data) {
if (!main.replayChecking && data) { if (!main.replayChecking && data) {
mota.plugin.ui.startOpened.value = false; mota.ui.fixed.closeByName('start');
} }
if (id == 'autoSave' && data != null) { if (id == 'autoSave' && data != null) {
core.saves.autosave.data = data; core.saves.autosave.data = data;

View File

@ -26,7 +26,7 @@ events.prototype.startGame = function (hard, seed, route, callback) {
hard = hard || ''; hard = hard || '';
core.dom.gameGroup.style.display = 'block'; core.dom.gameGroup.style.display = 'block';
if (!main.replayChecking) { if (!main.replayChecking) {
mota.plugin.ui.startOpened.value = false; mota.ui.fixed.closeByName('start');
} }
if (main.mode != 'play') return; if (main.mode != 'play') return;

View File

@ -1,14 +1,43 @@
<template> <template>
<div id="ui"> <!-- <div id="ui">
<template v-for="com of uiStack"> <template v-for="com of uiStack">
<component :is="com"></component> <component :is="com"></component>
</template> </template>
</div> -->
<div id="ui-new">
<div id="ui-main">
<div id="ui-list">
<div class="ui-one" v-for="ui of mainUi.stack">
<template>
<component
:is="ui.ui.component"
v-on="ui.vOn ?? {}"
v-bind="ui.vBind ?? {}"
></component>
</template>
</div>
</div>
</div>
<div id="ui-fixed">
<template v-for="ui of fixedUi.stack">
<component
:is="ui.ui.component"
v-on="ui.vOn ?? {}"
v-bind="ui.vBind ?? {}"
></component>
</template>
</div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import { onMounted } from 'vue';
import { uiStack } from './plugin/uiController'; import { mainUi, fixedUi } from './core/main/init/ui';
import { hook } from '@/core/main/game';
onMounted(() => {
hook.emit('mounted');
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -20,10 +49,64 @@ import { uiStack } from './plugin/uiController';
overflow: hidden; overflow: hidden;
} }
#ui-new {
width: 0;
height: 0;
left: 0;
top: 0;
position: fixed;
overflow: visible;
display: block;
}
#ui-main {
width: 100vw;
height: 100vh;
display: none;
justify-content: center;
left: 0;
top: 0;
position: fixed;
}
#ui-list {
width: 90%;
height: 90%;
overflow: hidden;
position: relative;
left: 0;
top: 0;
}
.ui-one {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
display: flex;
justify-content: center;
}
#ui-fixed {
position: fixed;
width: 0;
height: 0;
overflow: visible;
left: 0;
top: 0;
display: none;
}
@media screen and (max-width: 600px) { @media screen and (max-width: 600px) {
#ui { #ui {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
#ui-list {
width: 100%;
height: 100%;
}
} }
</style> </style>

View File

@ -1,18 +1,18 @@
<template> <template>
<div id="non-ui"> <!-- <div id="non-ui">
<Start v-if="startOpened"></Start> <Start v-if="startOpened"></Start>
<StatusBar v-if="showStatusBar"></StatusBar> <StatusBar v-if="showStatusBar"></StatusBar>
<MarkedEnemy v-if="showMarkedEnemy && showStatusBar"></MarkedEnemy> <MarkedEnemy v-if="showMarkedEnemy && showStatusBar"></MarkedEnemy>
<!-- <Studied <Studied
v-if="showStudiedSkill && showStatusBar && showStudied" v-if="showStudiedSkill && showStatusBar && showStudied"
></Studied> --> ></Studied>
<Fixed v-if="showStatusBar && useFixed"></Fixed> <Fixed v-if="showStatusBar && useFixed"></Fixed>
<Chapter v-if="chapterShowed" :chapter="chapterContent"></Chapter> <Chapter v-if="chapterShowed" :chapter="chapterContent"></Chapter>
<CompleteAchievement <CompleteAchievement
v-if="showComplete" v-if="showComplete"
:complete="completeAchi" :complete="completeAchi"
></CompleteAchievement> ></CompleteAchievement>
</div> </div> -->
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>

View File

@ -217,6 +217,23 @@ export class UiController extends Focus<IndexedGameUi> {
this.spliceIndex(ui); this.spliceIndex(ui);
} }
/**
* id关闭所有同id的uiui后的所有ui都关闭掉
* @param id ui的id
*/
closeByName(id: string) {
console.log(id);
if (!this.equal) {
const ui = this.stack.findIndex(v => v.ui.id === id);
this.spliceIndex(ui);
} else {
let ui;
while ((ui = this.stack.findIndex(v => v.ui.id === id)) !== -1) {
this.spliceIndex(ui);
}
}
}
/** /**
* ui * ui
* @param id ui的id * @param id ui的id

View File

@ -1,7 +1,10 @@
import { EmitableEvent, EventEmitter } from '../common/eventEmitter'; import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
export interface GameEvent extends EmitableEvent { export interface GameEvent extends EmitableEvent {
/** Emitted in events.prototype.resetGame. */
reset: () => void; reset: () => void;
/** Emitted in src/App.vue setup. */
mounted: () => void;
} }
export const hook = new EventEmitter<GameEvent>(); export const hook = new EventEmitter<GameEvent>();

View File

@ -19,6 +19,7 @@ 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';
import { hook } from '../game';
export const exitKey = new Hotkey('exitKey'); export const exitKey = new Hotkey('exitKey');
exitKey exitKey
@ -48,8 +49,7 @@ mainUi.register(
new GameUi('fixedDetail', FixedDetail, exitKey), new GameUi('fixedDetail', FixedDetail, exitKey),
new GameUi('shop', Shop, exitKey), new GameUi('shop', Shop, exitKey),
new GameUi('achievement', Achievement, exitKey), new GameUi('achievement', Achievement, exitKey),
new GameUi('bgm', Bgm, exitKey), new GameUi('bgm', Bgm, exitKey)
new GameUi('start', Start)
// todo: 把游戏主 div 加入到 mainUi 里面 // todo: 把游戏主 div 加入到 mainUi 里面
); );
@ -59,7 +59,37 @@ fixedUi.register(
new GameUi('markedEnemy', Mark), new GameUi('markedEnemy', Mark),
new GameUi('fixed', Fixed), new GameUi('fixed', Fixed),
new GameUi('chapter', Chapter), new GameUi('chapter', Chapter),
new GameUi('completeAchi', CompleteAchi) new GameUi('completeAchi', CompleteAchi),
new GameUi('start', Start)
); );
mainUi.focusByNum(mainUi.open('start')); hook.once('mounted', () => {
mainUi.on('start', () => {
const ui = document.getElementById('ui-main');
if (ui) {
ui.style.display = 'flex';
}
});
mainUi.on('end', () => {
const ui = document.getElementById('ui-main');
if (ui) {
ui.style.display = 'none';
}
});
fixedUi.on('start', () => {
console.log(1);
const ui = document.getElementById('ui-fixed');
if (ui) {
ui.style.display = 'block';
}
});
fixedUi.on('end', () => {
console.log(1);
const ui = document.getElementById('ui-fixed');
if (ui) {
ui.style.display = 'none';
}
});
mainUi.focusByNum(fixedUi.open('start'));
});

View File

@ -6,7 +6,7 @@ import 'ant-design-vue/dist/antd.dark.css';
import './core/index'; import './core/index';
createApp(App).mount('#root'); createApp(App).mount('#root');
createApp(App2).mount('#root2'); // createApp(App2).mount('#root2');
main.init('play'); main.init('play');
main.listen(); main.listen();

View File

@ -40,41 +40,41 @@ let app: HTMLDivElement;
/** ui声明列表 */ /** ui声明列表 */
const UI_LIST: [Ref<boolean>, Component][] = [ const UI_LIST: [Ref<boolean>, Component][] = [
[bookOpened, Book], // [bookOpened, Book],
[toolOpened, Toolbox], // [toolOpened, Toolbox],
[equipOpened, Equipbox], // [equipOpened, Equipbox],
[settingsOpened, Settings], // [settingsOpened, Settings],
[descOpened, Desc], // [descOpened, Desc],
[skillOpened, Skill], // [skillOpened, Skill],
[skillTreeOpened, SkillTree], // [skillTreeOpened, SkillTree],
[flyOpened, Fly], // [flyOpened, Fly],
[fixedDetailOpened, FixedDetail], // [fixedDetailOpened, FixedDetail],
[shopOpened, Shop], // [shopOpened, Shop],
[achievementOpened, Achievement], // [achievementOpened, Achievement],
[bgmOpened, Bgm] // [bgmOpened, Bgm]
]; ];
/** ui栈 */ /** ui栈 */
export const uiStack = shallowReactive<Component[]>([]); export const uiStack = shallowReactive<Component[]>([]);
export default function init() { export default function init() {
app = document.getElementById('root') as HTMLDivElement; // app = document.getElementById('root') as HTMLDivElement;
UI_LIST.forEach(([ref, com]) => { // UI_LIST.forEach(([ref, com]) => {
watch(ref, n => { // watch(ref, n => {
if (n === true) { // if (n === true) {
uiStack.push(markRaw(com)); // uiStack.push(markRaw(com));
showApp(); // showApp();
} else { // } else {
const index = uiStack.findIndex(v => v === com); // const index = uiStack.findIndex(v => v === com);
if (index === -1) return; // if (index === -1) return;
if (uiStack.length === 1) { // if (uiStack.length === 1) {
hideApp(index); // hideApp(index);
} else { // } else {
uiStack.splice(index, 1); // uiStack.splice(index, 1);
} // }
} // }
}); // });
}); // });
return { return {
uiStack, uiStack,
transition, transition,

View File

@ -1,22 +1,12 @@
// 部分全局css特效 // 部分全局css特效
#root { #root {
position: absolute; position: fixed;
display: none; display: block;
width: 100%; width: 0;
height: 100%; height: 0;
z-index: 1000; z-index: 1000;
justify-content: center; overflow: visible;
align-items: center;
overflow: hidden;
transition: all 0.6s linear;
opacity: 0;
background-color: #000d;
font-size: 16px;
backdrop-filter: blur(2px) grayscale(50%);
}
#root2 {
font-size: 16px; font-size: 16px;
} }