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 { createElements } from './elements';
import { mainRenderer } from './renderer';
import { createUI } from './ui';
export function createGameRenderer() {
const App = defineComponent(_props => {
@ -37,6 +38,7 @@ export function createGameRenderer() {
}
export function createRender() {
createUI();
createGameCanvas();
createItemDetail();
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 './main';
export * from './save';

View File

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

View File

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

View File

@ -3,28 +3,23 @@ import { getConfirm, waitbox } from '../render';
import { IUIMountable } from '@motajs/system-ui';
import { SyncSaveFromServerResponse } from '@motajs/client-base';
export function getAllSavesData() {
return new Promise<string>(res => {
core.getAllSaves(saves => {
if (!saves) {
res('');
return;
}
const content = {
name: core.firstData.name,
version: core.firstData.version,
data: saves
};
res(compressToBase64(JSON.stringify(content)));
});
});
export interface SaveData {
name: string;
version: string;
data: Save;
}
export function getSaveData(index: number) {
return new Promise<string>(res => {
export interface SaveDataArray {
name: string;
version: string;
data: Save[];
}
export function getSave(index: number) {
return new Promise<SaveData | null>(res => {
core.getSave(index, data => {
if (!data) {
res('');
res(null);
return;
}
const content = {
@ -32,11 +27,40 @@ export function getSaveData(index: number) {
version: core.firstData.version,
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 服务器加载
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 {
// 检查全局启用情况
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);
else if (type === 'down') this.checkPress(key);
if (!when()) return false;
if (when && !when()) return false;
const toEmit = this.keyMap.get(key);
if (!toEmit) return false;