mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-06-28 05:07:59 +08:00
feat: 存档自适应数量
This commit is contained in:
parent
98a0e13aee
commit
2d301cf0d0
@ -20,6 +20,8 @@ export interface PageProps extends DefaultProps {
|
|||||||
pages: number;
|
pages: number;
|
||||||
/** 页码组件的定位 */
|
/** 页码组件的定位 */
|
||||||
loc: ElementLocator;
|
loc: ElementLocator;
|
||||||
|
/** 当前页码 */
|
||||||
|
page?: number;
|
||||||
/** 页码的字体 */
|
/** 页码的字体 */
|
||||||
font?: Font;
|
font?: Font;
|
||||||
/** 只有一页的时候,是否隐藏页码 */
|
/** 只有一页的时候,是否隐藏页码 */
|
||||||
@ -28,6 +30,8 @@ export interface PageProps extends DefaultProps {
|
|||||||
|
|
||||||
export type PageEmits = {
|
export type PageEmits = {
|
||||||
pageChange: (page: number) => void;
|
pageChange: (page: number) => void;
|
||||||
|
|
||||||
|
'update:page': (page: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface PageExpose {
|
export interface PageExpose {
|
||||||
@ -54,8 +58,8 @@ type PageSlots = SlotsType<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
const pageProps = {
|
const pageProps = {
|
||||||
props: ['pages', 'loc', 'font', 'hideIfSingle'],
|
props: ['pages', 'loc', 'page', 'font', 'hideIfSingle'],
|
||||||
emits: ['pageChange']
|
emits: ['pageChange', 'update:page']
|
||||||
} satisfies SetupComponentOptions<
|
} satisfies SetupComponentOptions<
|
||||||
PageProps,
|
PageProps,
|
||||||
PageEmits,
|
PageEmits,
|
||||||
@ -85,7 +89,7 @@ export const Page = defineComponent<
|
|||||||
keyof PageEmits,
|
keyof PageEmits,
|
||||||
PageSlots
|
PageSlots
|
||||||
>((props, { slots, expose, emit }) => {
|
>((props, { slots, expose, emit }) => {
|
||||||
const nowPage = ref(0);
|
const nowPage = ref(props.page ?? 0);
|
||||||
|
|
||||||
// 五个元素的位置
|
// 五个元素的位置
|
||||||
const leftLoc = ref<ElementLocator>([]);
|
const leftLoc = ref<ElementLocator>([]);
|
||||||
@ -182,6 +186,7 @@ export const Page = defineComponent<
|
|||||||
if (nowPage.value !== target) {
|
if (nowPage.value !== target) {
|
||||||
nowPage.value = target;
|
nowPage.value = target;
|
||||||
emit('pageChange', target);
|
emit('pageChange', target);
|
||||||
|
emit('update:page', target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,6 +74,6 @@ export const Thumbnail = defineComponent<ThumbnailProps>(props => {
|
|||||||
watch(props, update);
|
watch(props, update);
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<sprite ref={spriteRef} loc={props.loc} render={drawThumbnail} />
|
<sprite noanti ref={spriteRef} loc={props.loc} render={drawThumbnail} />
|
||||||
);
|
);
|
||||||
}, thumbnailProps);
|
}, thumbnailProps);
|
||||||
|
@ -7,22 +7,29 @@ import {
|
|||||||
SetupComponentOptions,
|
SetupComponentOptions,
|
||||||
UIComponentProps
|
UIComponentProps
|
||||||
} from '@motajs/system-ui';
|
} from '@motajs/system-ui';
|
||||||
import { defineComponent, ref, computed, onMounted } from 'vue';
|
import {
|
||||||
|
defineComponent,
|
||||||
|
ref,
|
||||||
|
computed,
|
||||||
|
onMounted,
|
||||||
|
shallowReactive
|
||||||
|
} from 'vue';
|
||||||
import { 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 } from '../shared';
|
||||||
import { getSave, SaveData } from '../utils';
|
import { getSave, SaveData } from '../utils';
|
||||||
import { Thumbnail } from '../components/thumbnail';
|
import { Thumbnail } from '../components/thumbnail';
|
||||||
|
import { adjustGrid, IGridLayoutData } from '../utils/layout';
|
||||||
|
|
||||||
export interface SaveProps extends UIComponentProps, DefaultProps {
|
export interface SaveProps extends UIComponentProps, DefaultProps {
|
||||||
loc: ElementLocator;
|
loc: ElementLocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SaveBtnProps extends DefaultProps {
|
export interface SaveItemProps extends DefaultProps {
|
||||||
loc: ElementLocator;
|
loc: ElementLocator;
|
||||||
index: number;
|
index: number;
|
||||||
isSelected: boolean;
|
selected: boolean;
|
||||||
isDelete: boolean;
|
inDelete: boolean;
|
||||||
data: SaveData | null;
|
data: SaveData | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,26 +42,45 @@ export type SaveEmits = {
|
|||||||
exit: () => void;
|
exit: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SaveBtnEmits = {
|
|
||||||
/** 读取数据 */
|
|
||||||
updateData: (isValid: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveProps = {
|
const saveProps = {
|
||||||
props: ['loc', 'controller', 'instance'],
|
props: ['loc', 'controller', 'instance'],
|
||||||
emits: ['delete', 'emit', 'exit']
|
emits: ['delete', 'emit', 'exit']
|
||||||
} satisfies SetupComponentOptions<SaveProps, SaveEmits, keyof SaveEmits>;
|
} satisfies SetupComponentOptions<SaveProps, SaveEmits, keyof SaveEmits>;
|
||||||
|
|
||||||
const saveBtnProps = {
|
const saveBtnProps = {
|
||||||
props: ['loc', 'index', 'isSelected', 'isDelete', 'data']
|
props: ['loc', 'index', 'selected', 'inDelete', 'data']
|
||||||
} satisfies SetupComponentOptions<SaveBtnProps>;
|
} satisfies SetupComponentOptions<SaveItemProps>;
|
||||||
|
|
||||||
export const SaveBtn = defineComponent<SaveBtnProps>(props => {
|
export const SaveItem = defineComponent<SaveItemProps>(props => {
|
||||||
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 statusFont = new Font('normal', 14);
|
||||||
|
|
||||||
|
const w = computed(() => props.loc[2] ?? 200);
|
||||||
|
const lineWidth = computed(() => (props.selected ? 4 : 2));
|
||||||
|
const imgLoc = computed<ElementLocator>(() => {
|
||||||
|
const size = w.value - 4;
|
||||||
|
return [2, 24, size, size];
|
||||||
|
});
|
||||||
|
|
||||||
|
const name = computed(() => {
|
||||||
|
return props.index === -1 ? '自动存档' : `存档${props.index}`;
|
||||||
|
});
|
||||||
|
const statusText = computed(() => {
|
||||||
|
if (!props.data) return '';
|
||||||
|
else {
|
||||||
|
const hero = props.data.data.hero;
|
||||||
|
return `${hero.hp}/${hero.atk}/${hero.def}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const strokeStyle = computed(() => {
|
||||||
|
if (props.selected) return props.inDelete ? 'red' : 'gold';
|
||||||
|
else return 'white';
|
||||||
|
});
|
||||||
|
|
||||||
|
const floorId = computed(() => props.data?.data.floorId ?? 'empty');
|
||||||
const mapBlocks = computed(() => {
|
const mapBlocks = computed(() => {
|
||||||
if (props.data === null || props.data === undefined) return void 0;
|
if (!props.data) return [];
|
||||||
else {
|
else {
|
||||||
const currData = props.data.data;
|
const currData = props.data.data;
|
||||||
const map = core.maps.loadMap(currData.maps, currData.floorId);
|
const map = core.maps.loadMap(currData.maps, currData.floorId);
|
||||||
@ -62,54 +88,42 @@ export const SaveBtn = defineComponent<SaveBtnProps>(props => {
|
|||||||
return map.blocks;
|
return map.blocks;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const name = computed(() =>
|
|
||||||
props.index === -1 ? '自动存档' : `存档${props.index + 1}`
|
|
||||||
);
|
|
||||||
const statusText = computed(() => {
|
|
||||||
if (props.data === null || props.data === undefined) return '';
|
|
||||||
else {
|
|
||||||
const hero = props.data.data.hero;
|
|
||||||
return `${hero.hp}/${hero.atk}/${hero.def}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const strokeStyle = computed(() => {
|
|
||||||
if (props.isSelected) return props.isDelete ? 'red' : 'gold';
|
|
||||||
else return 'white';
|
|
||||||
});
|
|
||||||
const lineWidth = computed(() => (props.isSelected ? 2 : 1));
|
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<container loc={props.loc}>
|
<container loc={props.loc}>
|
||||||
<text
|
<text
|
||||||
text={name.value}
|
text={name.value}
|
||||||
font={font}
|
font={font}
|
||||||
loc={[w / 2, 20, void 0, void 0, 0.5, 1]}
|
loc={[w.value / 2, 20]}
|
||||||
|
anc={[0.5, 1]}
|
||||||
/>
|
/>
|
||||||
<g-rect
|
<g-rect
|
||||||
loc={[lineWidth.value, 24, w - 2 * lineWidth.value, w]}
|
loc={imgLoc.value}
|
||||||
fill
|
strokeAndFill
|
||||||
stroke
|
|
||||||
fillStyle="gray"
|
fillStyle="gray"
|
||||||
strokeStyle={strokeStyle.value}
|
strokeStyle={strokeStyle.value}
|
||||||
lineWidth={lineWidth.value}
|
lineWidth={lineWidth.value}
|
||||||
lineJoin="miter"
|
lineJoin="miter"
|
||||||
|
cursor="pointer"
|
||||||
/>
|
/>
|
||||||
<Thumbnail
|
<Thumbnail
|
||||||
hidden={props.data === null}
|
hidden={!props.data}
|
||||||
loc={[3, 26, w - 6, w - 4]}
|
loc={imgLoc.value}
|
||||||
padStyle="gray"
|
padStyle="gray"
|
||||||
floorId={props.data?.data.floorId || 'MT0'}
|
floorId={floorId.value}
|
||||||
map={mapBlocks.value}
|
map={mapBlocks.value}
|
||||||
hero={props.data?.data.hero as HeroStatus}
|
hero={props.data?.data.hero}
|
||||||
all
|
all
|
||||||
noHD
|
noHD
|
||||||
size={w / MAP_WIDTH}
|
size={(w.value - 4) / MAP_WIDTH}
|
||||||
|
noevent
|
||||||
/>
|
/>
|
||||||
<text
|
<text
|
||||||
text={statusText.value}
|
text={statusText.value}
|
||||||
fillStyle="yellow"
|
fillStyle="yellow"
|
||||||
font={statusFont}
|
font={statusFont}
|
||||||
loc={[w / 2, w + 28, void 0, void 0, 0.5, 0]}
|
loc={[w.value / 2, w.value + 28]}
|
||||||
|
anc={[0.5, 0]}
|
||||||
/>
|
/>
|
||||||
</container>
|
</container>
|
||||||
);
|
);
|
||||||
@ -117,62 +131,108 @@ 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 }) => {
|
||||||
const row = 2;
|
const itemSize = 150;
|
||||||
const column = 3;
|
const itemHeight = itemSize + 40;
|
||||||
/** 除自动存档外,每一页容纳的存档数量 */
|
const interval = 30;
|
||||||
const pageCap = row * column - 1;
|
|
||||||
const font = new Font('normal', 18);
|
const font = new Font('normal', 18);
|
||||||
const pageFont = new Font('normal', 14);
|
const pageFont = new Font('normal', 14);
|
||||||
|
|
||||||
const isDelete = ref(false);
|
/** 当前页上被选中的存档的posIndex */
|
||||||
|
const selected = ref(0);
|
||||||
|
const now = ref(0);
|
||||||
|
const inDelete = ref(false);
|
||||||
const pageRef = ref<PageExpose>();
|
const pageRef = ref<PageExpose>();
|
||||||
|
|
||||||
/** posIndex 存档在当前页的序号 范围为0到pageCap-1 */
|
const saveData: Record<number, SaveData | null> = shallowReactive({});
|
||||||
|
|
||||||
|
const width = computed(() => props.loc[2] ?? 200);
|
||||||
|
const height = computed(() => props.loc[3] ?? 200);
|
||||||
|
|
||||||
|
const grid = computed<IGridLayoutData>(() =>
|
||||||
|
adjustGrid(
|
||||||
|
width.value,
|
||||||
|
height.value - 30,
|
||||||
|
itemSize,
|
||||||
|
itemHeight,
|
||||||
|
interval
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const contentLoc = computed<ElementLocator>(() => {
|
||||||
|
const cx = width.value / 2;
|
||||||
|
const cy = (height.value - 30) / 2;
|
||||||
|
return [cx, cy, grid.value.width, grid.value.height, 0.5, 0.5];
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteLoc = computed<ElementLocator>(() => {
|
||||||
|
const pad = (width.value - grid.value.width) / 2;
|
||||||
|
return [pad, height.value - 13, void 0, void 0, 0, 1];
|
||||||
|
});
|
||||||
|
|
||||||
|
const exitLoc = computed<ElementLocator>(() => {
|
||||||
|
const pad = (width.value - grid.value.width) / 2;
|
||||||
|
const right = width.value - pad;
|
||||||
|
return [right, height.value - 13, void 0, void 0, 1, 1];
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取存档在当前页的序号,范围为 0 到 pageCap-1。
|
||||||
|
*/
|
||||||
const getPosIndex = (index: number) => {
|
const getPosIndex = (index: number) => {
|
||||||
if (index === -1) return 0;
|
if (index === -1) return 0;
|
||||||
return index - pageCap * (pageRef.value?.now() || 0) + 1;
|
return index % (grid.value.count - 1);
|
||||||
};
|
|
||||||
/** index 存档的总序号 从0开始 用于数据交互 */
|
|
||||||
const getIndex = (posIndex: number, page: number) => {
|
|
||||||
return page * pageCap + posIndex - 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 存档数据的列表 */
|
/**
|
||||||
const dataList = ref<(SaveData | null)[]>(
|
* 获取存档的总序号,从 0 开始,用于数据交互。
|
||||||
Array(pageCap + 1).fill(null)
|
*/
|
||||||
);
|
const getIndex = (posIndex: number, page: number) => {
|
||||||
const updateDataList = (page: number) => {
|
return page * grid.value.count + posIndex - 1;
|
||||||
dataList.value.forEach((_ele, i) => {
|
};
|
||||||
getSave(getIndex(i, page)).then(saveValue => {
|
|
||||||
dataList.value[i] = saveValue;
|
const updateDataList = async (page: number) => {
|
||||||
});
|
const promises: Promise<SaveData | null>[] = [];
|
||||||
|
for (let i = 0; i < grid.value.count; i++) {
|
||||||
|
const index = getIndex(i, page);
|
||||||
|
promises.push(getSave(index));
|
||||||
|
}
|
||||||
|
const data = await Promise.all(promises);
|
||||||
|
|
||||||
|
data.forEach((v, i) => {
|
||||||
|
if (v) {
|
||||||
|
saveData[i] = v;
|
||||||
|
} else {
|
||||||
|
saveData[i] = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const hasData = (posIndex: number) => {
|
|
||||||
return dataList.value[posIndex] !== null;
|
const exist = (index: number) => {
|
||||||
|
return saveData[index] !== null;
|
||||||
};
|
};
|
||||||
const getData = (posIndex: number) => dataList.value[posIndex];
|
|
||||||
const deleteData = (posIndex: number) => {
|
const deleteData = (index: number) => {
|
||||||
dataList.value[posIndex] = null;
|
saveData[index] = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const currPage = pageRef.value?.now() || 0;
|
updateDataList(now.value);
|
||||||
updateDataList(currPage);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 当前页上被选中的存档的posIndex */
|
|
||||||
const pickIndex = ref(1);
|
|
||||||
|
|
||||||
const emitSave = (index: number) => {
|
const emitSave = (index: number) => {
|
||||||
const posIndex = getPosIndex(index);
|
const posIndex = getPosIndex(index);
|
||||||
if (isDelete.value) {
|
if (inDelete.value) {
|
||||||
emit('delete', index, hasData(posIndex));
|
emit('delete', index, exist(posIndex));
|
||||||
deleteData(posIndex);
|
deleteData(posIndex);
|
||||||
} else {
|
} else {
|
||||||
emit('emit', index, hasData(posIndex));
|
emit('emit', index, exist(posIndex));
|
||||||
|
}
|
||||||
|
if (index === -1) {
|
||||||
|
selected.value = 0;
|
||||||
|
} else {
|
||||||
|
selected.value = (index % (grid.value.count - 1)) + 1;
|
||||||
}
|
}
|
||||||
pickIndex.value = (index % pageCap) + 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const wheel = (ev: IWheelEvent) => {
|
const wheel = (ev: IWheelEvent) => {
|
||||||
@ -185,7 +245,7 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const toggleDelete = () => {
|
const toggleDelete = () => {
|
||||||
isDelete.value = !isDelete.value;
|
inDelete.value = !inDelete.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const exit = () => {
|
const exit = () => {
|
||||||
@ -194,11 +254,14 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// #region 按键实现
|
// #region 按键实现
|
||||||
|
|
||||||
const [key] = useKey();
|
const [key] = useKey();
|
||||||
key.realize('confirm', () => {
|
key.realize('confirm', () => {
|
||||||
const currPage = pageRef.value?.now();
|
if (selected.value === 0) {
|
||||||
if (currPage === void 0) return;
|
emitSave(-1);
|
||||||
emitSave(pageCap * currPage + pickIndex.value);
|
} else {
|
||||||
|
emitSave((grid.value.count - 1) * now.value + selected.value);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.realize('exit', exit)
|
.realize('exit', exit)
|
||||||
.realize('@save_exit', exit)
|
.realize('@save_exit', exit)
|
||||||
@ -220,14 +283,16 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
'@save_up',
|
'@save_up',
|
||||||
() => {
|
() => {
|
||||||
if (!pageRef.value) return;
|
if (!pageRef.value) return;
|
||||||
const now = pageRef.value.now();
|
const cols = grid.value.cols;
|
||||||
if (pickIndex.value >= row) {
|
const count = grid.value.count;
|
||||||
pickIndex.value -= column;
|
if (selected.value >= cols) {
|
||||||
|
selected.value -= cols;
|
||||||
} else {
|
} else {
|
||||||
if (now === 0) {
|
if (now.value === 0) {
|
||||||
pickIndex.value = 0;
|
selected.value = 0;
|
||||||
} else {
|
} else {
|
||||||
pickIndex.value += pageCap + 1 - column;
|
const selectedCol = selected.value % cols;
|
||||||
|
selected.value = count - (cols - selectedCol);
|
||||||
pageRef.value?.movePage(-1);
|
pageRef.value?.movePage(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,10 +302,13 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
.realize(
|
.realize(
|
||||||
'@save_down',
|
'@save_down',
|
||||||
() => {
|
() => {
|
||||||
if (pickIndex.value <= pageCap - row) {
|
const cols = grid.value.cols;
|
||||||
pickIndex.value += column;
|
const count = grid.value.count;
|
||||||
|
if (selected.value < count - cols) {
|
||||||
|
selected.value += cols;
|
||||||
} else {
|
} else {
|
||||||
pickIndex.value += column - pageCap - 1;
|
const selectedCol = selected.value % cols;
|
||||||
|
selected.value = selectedCol;
|
||||||
pageRef.value?.movePage(1);
|
pageRef.value?.movePage(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -250,12 +318,12 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
'@save_left',
|
'@save_left',
|
||||||
() => {
|
() => {
|
||||||
if (!pageRef.value) return;
|
if (!pageRef.value) return;
|
||||||
const now = pageRef.value.now();
|
const count = grid.value.count;
|
||||||
if (pickIndex.value > 0) {
|
if (selected.value > 0) {
|
||||||
pickIndex.value--;
|
selected.value--;
|
||||||
} else {
|
} else {
|
||||||
if (now > 0) {
|
if (now.value > 0) {
|
||||||
pickIndex.value = pageCap;
|
selected.value = count;
|
||||||
pageRef.value?.movePage(-1);
|
pageRef.value?.movePage(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,99 +333,62 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
.realize(
|
.realize(
|
||||||
'@save_right',
|
'@save_right',
|
||||||
() => {
|
() => {
|
||||||
if (pickIndex.value < pageCap) {
|
const count = grid.value.count;
|
||||||
pickIndex.value++;
|
if (selected.value < count) {
|
||||||
|
selected.value++;
|
||||||
} else {
|
} else {
|
||||||
pickIndex.value = 0;
|
selected.value = 0;
|
||||||
pageRef.value?.movePage(1);
|
pageRef.value?.movePage(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ type: 'down-repeat' }
|
{ type: 'down-repeat' }
|
||||||
);
|
);
|
||||||
// #endregion
|
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<container loc={props.loc} zIndex={10}>
|
<container loc={props.loc} zIndex={10}>
|
||||||
<Page
|
<Page
|
||||||
loc={[0, 0, MAP_WIDTH, MAP_HEIGHT - 10]}
|
ref={pageRef}
|
||||||
|
loc={[0, 0, width.value, height.value - 10]}
|
||||||
pages={1000}
|
pages={1000}
|
||||||
|
font={pageFont}
|
||||||
|
v-model:page={now.value}
|
||||||
onWheel={wheel}
|
onWheel={wheel}
|
||||||
onPageChange={updateDataList}
|
onPageChange={updateDataList}
|
||||||
ref={pageRef}
|
|
||||||
font={pageFont}
|
|
||||||
>
|
>
|
||||||
{(page: number) => (
|
{(page: number) => (
|
||||||
<container loc={[0, 0, MAP_WIDTH, MAP_HEIGHT]}>
|
<container loc={contentLoc.value}>
|
||||||
<SaveBtn
|
{grid.value.locs.map((v, i) => {
|
||||||
loc={[30, 50, 120, 170]}
|
const count = grid.value.count;
|
||||||
index={-1}
|
const rawIndex = (count - 1) * page + i;
|
||||||
isSelected={pickIndex.value === 0}
|
const index = i === 0 ? -1 : rawIndex;
|
||||||
isDelete={isDelete.value}
|
return (
|
||||||
onClick={() => emitSave(-1)}
|
<SaveItem
|
||||||
cursor="pointer"
|
loc={v}
|
||||||
data={getData(0)}
|
index={index}
|
||||||
/>
|
selected={selected.value === i}
|
||||||
<SaveBtn
|
inDelete={inDelete.value}
|
||||||
loc={[180, 50, 120, 170]}
|
data={saveData[i]}
|
||||||
index={page * pageCap}
|
onClick={() => emitSave(index)}
|
||||||
isSelected={pickIndex.value === 1}
|
onEnter={() => (selected.value = i)}
|
||||||
isDelete={isDelete.value}
|
|
||||||
onClick={() => emitSave(page * pageCap)}
|
|
||||||
cursor="pointer"
|
|
||||||
data={getData(1)}
|
|
||||||
/>
|
|
||||||
<SaveBtn
|
|
||||||
loc={[330, 50, 120, 170]}
|
|
||||||
index={page * pageCap + 1}
|
|
||||||
isSelected={pickIndex.value === 2}
|
|
||||||
isDelete={isDelete.value}
|
|
||||||
onClick={() => emitSave(page * pageCap + 1)}
|
|
||||||
cursor="pointer"
|
|
||||||
data={getData(2)}
|
|
||||||
/>
|
|
||||||
<SaveBtn
|
|
||||||
loc={[30, 230, 120, 170]}
|
|
||||||
index={page * pageCap + 2}
|
|
||||||
isSelected={pickIndex.value === 3}
|
|
||||||
isDelete={isDelete.value}
|
|
||||||
onClick={() => emitSave(page * pageCap + 2)}
|
|
||||||
cursor="pointer"
|
|
||||||
data={getData(3)}
|
|
||||||
/>
|
|
||||||
<SaveBtn
|
|
||||||
loc={[180, 230, 120, 170]}
|
|
||||||
index={page * pageCap + 3}
|
|
||||||
isSelected={pickIndex.value === 4}
|
|
||||||
isDelete={isDelete.value}
|
|
||||||
onClick={() => emitSave(page * pageCap + 3)}
|
|
||||||
cursor="pointer"
|
|
||||||
data={getData(4)}
|
|
||||||
/>
|
|
||||||
<SaveBtn
|
|
||||||
loc={[330, 230, 120, 170]}
|
|
||||||
index={page * pageCap + 4}
|
|
||||||
isSelected={pickIndex.value === 5}
|
|
||||||
isDelete={isDelete.value}
|
|
||||||
onClick={() => emitSave(page * pageCap + 4)}
|
|
||||||
cursor="pointer"
|
|
||||||
data={getData(5)}
|
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</container>
|
</container>
|
||||||
)}
|
)}
|
||||||
</Page>
|
</Page>
|
||||||
<text
|
<text
|
||||||
text="删除模式"
|
text="删除模式"
|
||||||
|
loc={deleteLoc.value}
|
||||||
font={font}
|
font={font}
|
||||||
loc={[30, 450, void 0, void 0, 0, 0]}
|
|
||||||
zIndex={10}
|
zIndex={10}
|
||||||
fillStyle={isDelete.value ? 'red' : 'white'}
|
fillStyle={inDelete.value ? 'red' : 'white'}
|
||||||
onClick={toggleDelete}
|
onClick={toggleDelete}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
/>
|
/>
|
||||||
<text
|
<text
|
||||||
text="返回游戏"
|
text="返回游戏"
|
||||||
|
loc={exitLoc.value}
|
||||||
font={font}
|
font={font}
|
||||||
loc={[450, 450, void 0, void 0, 1, 0]}
|
|
||||||
zIndex={10}
|
zIndex={10}
|
||||||
onClick={exit}
|
onClick={exit}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
@ -387,9 +418,9 @@ export type SaveValidationFunction = (
|
|||||||
* 使用示例:
|
* 使用示例:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const index = await selectSave(props.controller, [0, 0, 416, 416]);
|
* const index = await selectSave(props.controller, [0, 0, 416, 416]);
|
||||||
* if (index === -2) {
|
* if (index === -1) {
|
||||||
* // 如果用户未选择存档,而是关闭了存档。
|
* // 如果用户未选择存档,而是关闭了存档。
|
||||||
* } else if (index === -1) {
|
* } else if (index === 0) {
|
||||||
* // 用户选择了自动存档。
|
* // 用户选择了自动存档。
|
||||||
* } else {
|
* } else {
|
||||||
* // 用户选择了一个存档。
|
* // 用户选择了一个存档。
|
||||||
@ -462,7 +493,6 @@ export async function saveSave(
|
|||||||
};
|
};
|
||||||
const index = await selectSave(controller, loc, validate, props);
|
const index = await selectSave(controller, loc, validate, props);
|
||||||
if (index === -2) return false;
|
if (index === -2) return false;
|
||||||
// 由于样板存档编号从1开始,这里需要+1
|
|
||||||
core.doSL(index + 1, 'save');
|
core.doSL(index + 1, 'save');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
59
packages-user/client-modules/src/render/utils/layout.ts
Normal file
59
packages-user/client-modules/src/render/utils/layout.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { ElementLocator } from '@motajs/render-core';
|
||||||
|
|
||||||
|
export interface IGridLayoutData {
|
||||||
|
/** 有多少列 */
|
||||||
|
readonly cols: number;
|
||||||
|
/** 有多少行 */
|
||||||
|
readonly rows: number;
|
||||||
|
/** 去除余留部分后的宽度 */
|
||||||
|
readonly width: number;
|
||||||
|
/** 去除预留部分后的高度 */
|
||||||
|
readonly height: number;
|
||||||
|
/** 元素总数量 */
|
||||||
|
readonly count: number;
|
||||||
|
/** 每个元素的定位,按照从左到右,从左上下的顺序排列,包含所有六个元素 */
|
||||||
|
readonly locs: readonly ElementLocator[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网格布局
|
||||||
|
* @param width 总宽度
|
||||||
|
* @param height 总高度
|
||||||
|
* @param itemWidth 每个元素的宽度
|
||||||
|
* @param itemHeight 每个元素的高度
|
||||||
|
* @param intervalX 元素的横向间隔
|
||||||
|
* @param intervalY 元素的纵向间隔,不填时等于横向间隔
|
||||||
|
* @returns 网格布局信息
|
||||||
|
*/
|
||||||
|
export function adjustGrid(
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
itemWidth: number,
|
||||||
|
itemHeight: number,
|
||||||
|
intervalX: number,
|
||||||
|
intervalY: number = intervalX
|
||||||
|
): IGridLayoutData {
|
||||||
|
const cols = Math.floor((width + intervalX) / (itemWidth + intervalX));
|
||||||
|
const rows = Math.floor((height + intervalY) / (itemHeight + intervalY));
|
||||||
|
const rawWidth = (itemWidth + intervalX) * cols - intervalX;
|
||||||
|
const rawHeight = (itemHeight + intervalY) * rows - intervalY;
|
||||||
|
|
||||||
|
const locs: ElementLocator[] = [];
|
||||||
|
|
||||||
|
for (let y = 0; y < rows; y++) {
|
||||||
|
const iy = (intervalY + itemHeight) * y;
|
||||||
|
for (let x = 0; x < cols; x++) {
|
||||||
|
const ix = (intervalX + itemWidth) * x;
|
||||||
|
locs.push([ix, iy, itemWidth, itemHeight, 0, 0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
cols,
|
||||||
|
rows,
|
||||||
|
count: cols * rows,
|
||||||
|
width: rawWidth,
|
||||||
|
height: rawHeight,
|
||||||
|
locs
|
||||||
|
};
|
||||||
|
}
|
@ -25,7 +25,7 @@ export function getSave(index: number) {
|
|||||||
const content = {
|
const content = {
|
||||||
name: core.firstData.name,
|
name: core.firstData.name,
|
||||||
version: core.firstData.version,
|
version: core.firstData.version,
|
||||||
data: data
|
data: data instanceof Array ? data[0] : data
|
||||||
};
|
};
|
||||||
res(content);
|
res(content);
|
||||||
});
|
});
|
||||||
|
4
src/types/declaration/util.d.ts
vendored
4
src/types/declaration/util.d.ts
vendored
@ -821,7 +821,7 @@ interface Animate {
|
|||||||
pitch: any;
|
pitch: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Save = DeepReadonly<{
|
type Save = {
|
||||||
/**
|
/**
|
||||||
* 存档所在的楼层id
|
* 存档所在的楼层id
|
||||||
*/
|
*/
|
||||||
@ -866,7 +866,7 @@ type Save = DeepReadonly<{
|
|||||||
* 存档时间
|
* 存档时间
|
||||||
*/
|
*/
|
||||||
time: number;
|
time: number;
|
||||||
}>;
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 深度只读一个对象,使其所有属性都只读
|
* 深度只读一个对象,使其所有属性都只读
|
||||||
|
Loading…
Reference in New Issue
Block a user