fix: fix region align & shuffle

This commit is contained in:
hyper
2026-04-01 17:48:40 +08:00
parent 284251ddf2
commit 729f15c2bf
3 changed files with 114 additions and 70 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ export type Part = Entity & {
// current region
region: EntityAccessor<Region>;
// current position in region
// current position in region, expect to be the same length as region's axes
position: number[];
}
@@ -30,4 +30,4 @@ export function flipTo(part: Part, side: number) {
export function roll(part: Part, rng: RNG) {
part.side = rng.nextInt(part.sides);
}
}
+17 -24
View File
@@ -3,7 +3,7 @@ import {Part} from "./part";
import {RNG} from "../utils/rng";
export type Region = Entity & {
// aligning axes of the region
// aligning axes of the region, expect a part's position to have a matching number of elements
axes: RegionAxis[];
// current children; expect no overlapped positions
@@ -26,33 +26,30 @@ export type RegionAxis = {
* @param region
*/
export function applyAlign(region: Region){
for (const axis of region.axes) {
if (region.children.length === 0) continue;
if (region.children.length === 0) return;
// 对每个 axis 分别处理
for (let axisIndex = 0; axisIndex < region.axes.length; axisIndex++) {
const axis = region.axes[axisIndex];
if (!axis.align) continue;
// 获取当前轴向上的所有位置
const positions = region.children.map(accessor => accessor.value.position);
// 根据当前轴的位置排序 children
region.children.sort((a, b) => {
const posA = a.value.position[0] ?? 0;
const posB = b.value.position[0] ?? 0;
const posA = a.value.position[axisIndex] ?? 0;
const posB = b.value.position[axisIndex] ?? 0;
return posA - posB;
});
if (axis.align === 'start' && axis.min !== undefined) {
// 从 min 开始紧凑排列
region.children.forEach((accessor, index) => {
const currentPos = accessor.value.position.slice();
currentPos[0] = axis.min! + index;
accessor.value.position = currentPos;
accessor.value.position[axisIndex] = axis.min! + index;
});
} else if (axis.align === 'end' && axis.max !== undefined) {
// 从 max 开始向前紧凑排列
const count = region.children.length;
region.children.forEach((accessor, index) => {
const currentPos = accessor.value.position.slice();
currentPos[0] = axis.max! - (count - 1 - index);
accessor.value.position = currentPos;
accessor.value.position[axisIndex] = axis.max! - (count - 1 - index);
});
} else if (axis.align === 'center') {
// 居中排列
@@ -61,13 +58,11 @@ export function applyAlign(region: Region){
const max = axis.max ?? count - 1;
const range = max - min;
const center = min + range / 2;
region.children.forEach((accessor, index) => {
const currentPos = accessor.value.position.slice();
// 计算相对于中心的偏移
const offset = index - (count - 1) / 2;
currentPos[0] = center + offset;
accessor.value.position = currentPos;
accessor.value.position[axisIndex] = center + offset;
});
}
}
@@ -85,11 +80,9 @@ export function shuffle(region: Region, rng: RNG){
const children = [...region.children];
for (let i = children.length - 1; i > 0; i--) {
const j = rng.nextInt(i + 1);
// 交换位置
const posI = children[i].value.position.slice();
const posJ = children[j].value.position.slice();
children[i].value.position = posJ;
children[j].value.position = posI;
// 交换两个 part 的整个 position 数组
const temp = children[i].value.position;
children[i].value.position = children[j].value.position;
children[j].value.position = temp;
}
}