fix: fix region align & shuffle
This commit is contained in:
+2
-2
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user