Compare commits

...

3 Commits

Author SHA1 Message Date
AncTe
27d59acdfe
Merge 583df29f38 into 820dc5bf4c 2025-06-20 10:52:59 +00:00
583df29f38 chore: UI 改成全覆盖 2025-06-20 18:52:41 +08:00
9826866c94 fix: 存档界面按键报错 2025-06-20 17:38:23 +08:00
8 changed files with 121 additions and 83 deletions

View File

@ -9,6 +9,7 @@ import { createLoopMap } from './loopMap';
import { createGameCanvas } from './legacy/gameCanvas'; import { createGameCanvas } from './legacy/gameCanvas';
import { createElements } from './elements'; import { createElements } from './elements';
import { mainRenderer } from './renderer'; import { mainRenderer } from './renderer';
import { createUI } from './ui';
export function createGameRenderer() { export function createGameRenderer() {
const App = defineComponent(_props => { const App = defineComponent(_props => {
@ -37,6 +38,7 @@ export function createGameRenderer() {
} }
export function createRender() { export function createRender() {
createUI();
createGameCanvas(); createGameCanvas();
createItemDetail(); createItemDetail();
createLoopMap(); createLoopMap();

View File

@ -1,3 +0,0 @@
import { UIController } from '@motajs/system-ui';
export const mainUIController = new UIController('main-ui');

View File

@ -0,0 +1,33 @@
import { DefaultProps } from '@motajs/render-vue';
import {
GameUI,
SetupComponentOptions,
UIComponentProps,
UIController
} from '@motajs/system-ui';
import { defineComponent } from 'vue';
import { MAIN_HEIGHT, MAIN_WIDTH } from '../shared';
export const mainUIController = new UIController('main-ui');
export interface MainBackgroundProps extends DefaultProps, UIComponentProps {}
const mainBackgroundProps = {
props: ['controller', 'instance']
} satisfies SetupComponentOptions<MainBackgroundProps>;
export const MainBackground = defineComponent<MainBackgroundProps>(() => {
return () => (
<g-rect
loc={[0, 0, MAIN_WIDTH, MAIN_HEIGHT]}
fill
fillStyle="rgba(0, 0, 0, 0.8)"
/>
);
}, mainBackgroundProps);
export const MainBackgroundUI = new GameUI('main-background', MainBackground);
export function createMainController() {
mainUIController.setBackground(MainBackgroundUI, {});
}

View File

@ -1,3 +1,9 @@
import { createMainController } from './controller';
export function createUI() {
createMainController();
}
export * from './controller'; export * from './controller';
export * from './main'; export * from './main';
export * from './save'; export * from './save';

View File

@ -8,7 +8,7 @@ import {
UIComponentProps UIComponentProps
} from '@motajs/system-ui'; } from '@motajs/system-ui';
import { defineComponent, ref, computed } from 'vue'; import { defineComponent, ref, computed } from 'vue';
import { Background, Page, PageExpose } from '../components'; import { Page, PageExpose } from '../components';
import { useKey } from '../use'; import { useKey } from '../use';
import { MAP_WIDTH, MAP_HEIGHT } from '../shared'; import { MAP_WIDTH, MAP_HEIGHT } from '../shared';
@ -44,6 +44,7 @@ const saveBtnProps = {
export const SaveBtn = defineComponent<SaveBtnProps>(props => { export const SaveBtn = defineComponent<SaveBtnProps>(props => {
const w = props.loc[2] ?? 200; const w = props.loc[2] ?? 200;
const font = new Font('normal', 18); const font = new Font('normal', 18);
const statusFont = new Font('normal', 14);
const text = computed(() => const text = computed(() =>
props.index === -1 ? '自动存档' : `存档${props.index + 1}` props.index === -1 ? '自动存档' : `存档${props.index + 1}`
); );
@ -57,21 +58,22 @@ export const SaveBtn = defineComponent<SaveBtnProps>(props => {
<text <text
text={text.value} text={text.value}
font={font} font={font}
loc={[w / 2, 0, void 0, void 0, 0.5, 0]} loc={[w / 2, 20, void 0, void 0, 0.5, 1]}
/> />
<g-rect <g-rect
loc={[lineWidth.value, 20, w - 2 * lineWidth.value, w]} loc={[lineWidth.value, 24, w - 2 * lineWidth.value, w]}
fill fill
stroke stroke
fillStyle="gray" fillStyle="gray"
strokeStyle={strokeStyle.value} strokeStyle={strokeStyle.value}
lineWidth={lineWidth.value} lineWidth={lineWidth.value}
lineJoin="miter"
/> />
<text <text
text="placeholder" text="placeholder"
fillStyle="yellow" fillStyle="yellow"
font={font} font={statusFont}
loc={[w / 2, w + 20, void 0, void 0, 0.5, 0]} loc={[w / 2, w + 28, void 0, void 0, 0.5, 0]}
/> />
</container> </container>
); );
@ -79,17 +81,12 @@ export const SaveBtn = defineComponent<SaveBtnProps>(props => {
export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>( export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
(props, { emit }) => { (props, { emit }) => {
// 这些注释写完之后删了
// 这里是 UI 部分,不负责任何存读档操作,这些在特定场景下传入 onEmit 来实现
// 缩略图暂用 container 元素替代,点击时触发 onEmit
// onEmit 事件在点击存档或按键确认时触发
// 存读档执行函数在 ../../utils/saves.ts
const row = 2; const row = 2;
const column = 3; const column = 3;
/** 除自动存档外,每一页容纳的存档数量 */ /** 除自动存档外,每一页容纳的存档数量 */
const pageCap = row * column - 1; const pageCap = row * column - 1;
const font = new Font('normal', 18); const font = new Font('normal', 18);
const pageFont = new Font('normal', 14);
const isDelete = ref(false); const isDelete = ref(false);
const pageRef = ref<PageExpose>(); const pageRef = ref<PageExpose>();
@ -120,7 +117,6 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
props.controller.close(props.instance); props.controller.close(props.instance);
}; };
// 参考 ../../action/hotkey.ts 中的按键定义
const [key] = useKey(); const [key] = useKey();
key.realize('confirm', () => { key.realize('confirm', () => {
const currPage = pageRef.value?.now(); const currPage = pageRef.value?.now();
@ -146,10 +142,17 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
.realize( .realize(
'@save_up', '@save_up',
() => { () => {
if (pickIndex.value >= row) pickIndex.value -= column; if (!pageRef.value) return;
else { const now = pageRef.value.now();
pickIndex.value += pageCap + 1 - column; if (pickIndex.value >= row) {
pageRef.value?.movePage(-1); pickIndex.value -= column;
} else {
if (now === 0) {
pickIndex.value = 0;
} else {
pickIndex.value += pageCap + 1 - column;
pageRef.value?.movePage(-1);
}
} }
}, },
{ type: 'down-repeat' } { type: 'down-repeat' }
@ -169,10 +172,15 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
.realize( .realize(
'@save_left', '@save_left',
() => { () => {
if (pickIndex.value > 0) pickIndex.value--; if (!pageRef.value) return;
else { const now = pageRef.value.now();
pickIndex.value = pageCap; if (pickIndex.value > 0) {
pageRef.value?.movePage(-1); pickIndex.value--;
} else {
if (now > 0) {
pickIndex.value = pageCap;
pageRef.value?.movePage(-1);
}
} }
}, },
{ type: 'down-repeat' } { type: 'down-repeat' }
@ -188,16 +196,15 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
}, },
{ type: 'down-repeat' } { type: 'down-repeat' }
); );
// 其他按键自定义,需要新开一个 save 的 group
return () => ( return () => (
<container loc={props.loc}> <container loc={props.loc} zIndex={10}>
<Background loc={[0, 0, MAP_WIDTH, MAP_HEIGHT]} color="black" />
<Page <Page
loc={[0, 0, MAP_WIDTH, MAP_HEIGHT - 10]} loc={[0, 0, MAP_WIDTH, MAP_HEIGHT - 10]}
pages={1000} pages={1000}
onWheel={wheel} onWheel={wheel}
ref={pageRef} ref={pageRef}
font={pageFont}
> >
{(page: number) => ( {(page: number) => (
<container loc={[0, 0, MAP_WIDTH, MAP_HEIGHT]}> <container loc={[0, 0, MAP_WIDTH, MAP_HEIGHT]}>
@ -259,6 +266,7 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
zIndex={10} zIndex={10}
fillStyle={isDelete.value ? 'red' : 'white'} fillStyle={isDelete.value ? 'red' : 'white'}
onClick={toggleDelete} onClick={toggleDelete}
cursor="pointer"
/> />
<text <text
text="返回游戏" text="返回游戏"
@ -266,6 +274,7 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
loc={[450, 450, void 0, void 0, 1, 0]} loc={[450, 450, void 0, void 0, 1, 0]}
zIndex={10} zIndex={10}
onClick={exit} onClick={exit}
cursor="pointer"
/> />
</container> </container>
); );

View File

@ -21,9 +21,9 @@ import { KeyCode } from '@motajs/client-base';
import { Progress } from '../components/misc'; import { Progress } from '../components/misc';
import { generateBinary } from '@motajs/legacy-common'; import { generateBinary } from '@motajs/legacy-common';
import { SetupComponentOptions } from '@motajs/system-ui'; import { SetupComponentOptions } from '@motajs/system-ui';
import { selectSave } from './save'; import { SaveUI } from './save';
import { mainUIController } from '@user/client-modules'; import { mainUIController } from '@user/client-modules';
import { STATUS_BAR_WIDTH, MAP_WIDTH, MAP_HEIGHT } from '../shared'; import { MAIN_WIDTH, MAIN_HEIGHT } from '../shared';
interface ToolbarProps extends DefaultProps { interface ToolbarProps extends DefaultProps {
loc?: ElementLocator; loc?: ElementLocator;
@ -88,19 +88,7 @@ export const PlayingToolbar = defineComponent<
const tool = () => core.openToolbox(true); const tool = () => core.openToolbox(true);
const fly = () => core.useFly(true); const fly = () => core.useFly(true);
const save = async () => { const save = async () => {
const index = await selectSave(mainUIController, [ mainUIController.open(SaveUI, { loc: [0, 0, MAIN_WIDTH, MAIN_HEIGHT] });
STATUS_BAR_WIDTH,
0,
MAP_WIDTH,
MAP_HEIGHT
]);
if (index === -2) {
// 如果用户未选择存档,而是关闭了存档。
console.log('用户关闭了存档界面。');
} else {
// 用户选择了一个存档。
console.log('用户选择在存档位' + index + '保存。');
}
}; };
const load = () => core.load(true); const load = () => core.load(true);
const equip = () => core.openEquipbox(true); const equip = () => core.openEquipbox(true);

View File

@ -3,28 +3,23 @@ import { getConfirm, waitbox } from '../render';
import { IUIMountable } from '@motajs/system-ui'; import { IUIMountable } from '@motajs/system-ui';
import { SyncSaveFromServerResponse } from '@motajs/client-base'; import { SyncSaveFromServerResponse } from '@motajs/client-base';
export function getAllSavesData() { export interface SaveData {
return new Promise<string>(res => { name: string;
core.getAllSaves(saves => { version: string;
if (!saves) { data: Save;
res('');
return;
}
const content = {
name: core.firstData.name,
version: core.firstData.version,
data: saves
};
res(compressToBase64(JSON.stringify(content)));
});
});
} }
export function getSaveData(index: number) { export interface SaveDataArray {
return new Promise<string>(res => { name: string;
version: string;
data: Save[];
}
export function getSave(index: number) {
return new Promise<SaveData | null>(res => {
core.getSave(index, data => { core.getSave(index, data => {
if (!data) { if (!data) {
res(''); res(null);
return; return;
} }
const content = { const content = {
@ -32,11 +27,40 @@ export function getSaveData(index: number) {
version: core.firstData.version, version: core.firstData.version,
data: data data: data
}; };
res(compressToBase64(JSON.stringify(content))); res(content);
}); });
}); });
} }
export function getAllSaves() {
return new Promise<SaveDataArray | null>(res => {
core.getAllSaves(saves => {
if (!saves) {
res(null);
return;
}
const content = {
name: core.firstData.name,
version: core.firstData.version,
data: saves
};
res(content);
});
});
}
export async function getSaveData(index: number) {
const data = await getSave(index);
if (!data) return '';
return compressToBase64(JSON.stringify(data));
}
export async function getAllSavesData() {
const data = await getAllSaves();
if (!data) return '';
return compressToBase64(JSON.stringify(data));
}
//#region 服务器加载 //#region 服务器加载
const enum FromServerResponse { const enum FromServerResponse {
@ -169,24 +193,3 @@ export async function syncFromServer(
); );
} }
} }
//#region 存读档操作
export const enum LoadMode {
Load,
ReplayFrom,
ContinueReplayFrom,
ContinueReplayTo
}
/**
*
* @param index
*/
export function saveTo(index: number) {}
/**
*
* @param index
*/
export function loadFrom(index: number, mode: LoadMode) {}

View File

@ -232,10 +232,10 @@ export class Hotkey extends EventEmitter<HotkeyEvent> {
): boolean { ): boolean {
// 检查全局启用情况 // 检查全局启用情况
if (!this.enabled) return false; if (!this.enabled) return false;
const when = this.conditionMap.get(this.scope)!; const when = this.conditionMap.get(this.scope);
if (type === 'up') this.checkPressEnd(key); if (type === 'up') this.checkPressEnd(key);
else if (type === 'down') this.checkPress(key); else if (type === 'down') this.checkPress(key);
if (!when()) return false; if (when && !when()) return false;
const toEmit = this.keyMap.get(key); const toEmit = this.keyMap.get(key);
if (!toEmit) return false; if (!toEmit) return false;