一个方块占8个数字 这样子 我做出了固定形状的 但是两种不同的就会出现重叠 我想在这范围内不重叠 求助求助!!
每个节点上面加个白色背景底 大小一致 直接展示背景不就ok了
我需要随机每次都不是同一个位置

像这样 但是我现在写出来的还是有概率会重叠
直接让gpt帮你写快一点
假定全是竖着放的,然后整齐地从上到下从左到右排列,接下来就每个方块随机一个位置交换坐标吧,能交换就交换,交换不了就保持原地,交换成功后再随机地横放,能横就横,横不了就不横。不是很严谨的逻辑,但有一定随机性且不会重叠。
更严谨一点的话,可以每次交换前先遍历所有可以交换的位置,然后从所有可交换的位置里随一个位置。
大晚上睡不着,顺带做了个实现。随手写的,边界处理等不一定严谨,不要介意哈。
const config = {
width: 14,
height: 14
}
class Block {
x: number;
y: number;
type: "horizontal" | "vertical";
constructor(posx: number, posy: number, type: "horizontal" | "vertical") {
this.x = posx;
this.y = posy;
this.type = type;
}
get width() {
return this.type === "horizontal" ? 4 : 2;
}
get height() {
return this.type === "horizontal" ? 2 : 4;
}
}
function CheckOutOfRange(block: Block) {
if (block.type === "horizontal") {
return !(block.x + 4 <= config.width && block.y + 2 <= config.height);
} else {
return !(block.x + 2 <= config.width && block.y + 4 <= config.height);
}
}
function CheckCollision(rect1: Block, rect2: Block) {
var maxX: number, maxY: number, minX: number, minY: number
maxX = rect1.x + rect1.width >= rect2.x + rect2.width ? rect1.x + rect1.width : rect2.x + rect2.width
maxY = rect1.y + rect1.height >= rect2.y + rect2.height ? rect1.y + rect1.height : rect2.y + rect2.height
minX = rect1.x <= rect2.x ? rect1.x : rect2.x
minY = rect1.y <= rect2.y ? rect1.y : rect2.y
if (maxX - minX <= rect1.width + rect2.width && maxY - minY <= rect1.height + rect2.height) {
return true
} else {
return false
}
}
function CheckValid(oldList: Block[], newItem: Block): boolean {
if (CheckOutOfRange(newItem)) {
return false;
}
return oldList.every((oldItem) => {
return !CheckCollision(oldItem, newItem);
})
}
function generate() {
let origin: Block[] = [];
//手动设置几个原始方块,也可以自动生成,合法就行
origin.push(new Block(0, 0, "vertical"));
origin.push(new Block(2, 0, "vertical"));
origin.push(new Block(4, 0, "vertical"));
origin.push(new Block(6, 0, "vertical"));
origin.push(new Block(8, 0, "vertical"));
for (let idx = 0; idx < origin.length; idx++) {
let all: Block[] = [];//计算所有合法的位置
for (let i = 0; i < config.width; ++i) {
for (let j = 0; j < config.height; ++j) {
let tempA = new Block(i, j, "vertical");
if (CheckValid(origin, tempA)) {
all.push(tempA)
}
let tempB = new Block(i, j, "horizontal");
if (CheckValid(origin, tempB)) {
all.push(tempB)
}
}
}
if (all.length > 0) {
let random = all[Math.floor(Math.random() * all.length)];
origin[idx] = random;//随机选一个交换
}
}
//打印结果
let grid = {};
for (let i = 0; i < config.width; ++i) {
let temp = {}
for (let j = 0; j < config.height; ++j) {
temp[j] = false;
}
grid[i] = temp;
}
for (let idx = 0; idx < origin.length; idx++) {
let item = origin[idx];
for (let i = 0; i < item.width; ++i) {
for (let j = 0; j < item.height; ++j) {
grid[item.x + i][item.y + j] = true;
}
}
}
console.log(origin)
console.log(grid)
}

1赞
感谢! 我现在的写法是这样的
const nodeCount = 12;
const nodeAreaWidth = 910;
const nodeAreaHeight = 910;
const gridSize = 65.5; // 网格大小设为节点的最小尺寸
const gridWidth = Math.floor(nodeAreaWidth / gridSize);
const gridHeight = Math.floor(nodeAreaHeight / gridSize);
// 创建一个二维数组来表示网格
let grid = new Array(gridHeight).fill(0).map(() => new Array(gridWidth).fill(0));
function isOverlap(x: number, y: number, width: number, height: number): boolean {
if (x + width > gridWidth || y + height > gridHeight) {
return true;
}
for (let i = y; i < y + height; i++) {
for (let j = x; j < x + width; j++) {
if (grid[i][j] === 1) {
return true;
}
}
}
return false;
}
function placeNode(x: number, y: number, width: number, height: number) {
if (x + width > gridWidth || y + height > gridHeight) {
return;
}
for (let i = y; i < y + height; i++) {
for (let j = x; j < x + width; j++) {
grid[i][j] = 1;
}
}
}
class Node {
x: number;
y: number;
width: number;
height: number;
constructor(x: number, y: number, width: number, height: number) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
function getRandomSize(): { width: number, height: number } {
const sizes = [
{ width: 260, height: 130 },
{ width: 130, height: 260 }
];
return sizes[Math.floor(Math.random() * sizes.length)];
}
let positions = [];
for (let i = 0; i < gridHeight; i++) {
for (let j = 0; j < gridWidth; j++) {
positions.push({ x: j, y: i });
}
}
function generateNodes(): Node[] {
const nodes: Node[] = [];
while (nodes.length < nodeCount && positions.length > 0) {
const { width, height } = getRandomSize();
const gridWidth = Math.ceil(width / gridSize);
const gridHeight = Math.ceil(height / gridSize);
let pos;
let index;
do {
index = Math.floor(Math.random() * positions.length);
pos = positions[index];
positions.splice(index, 1);
} while (isOverlap(pos.x, pos.y, gridWidth, gridHeight) && positions.length > 0);
if (positions.length > 0 || !isOverlap(pos.x, pos.y, gridWidth, gridHeight)) {
placeNode(pos.x, pos.y, gridWidth, gridHeight);
nodes.push(new Node(pos.x * gridSize, pos.y * gridSize, width, height));
}
}
return nodes;
}
const nodes = generateNodes();
if (nodes.length != nodeCount) {
return false
}
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].width == 260) {
this.Item = instantiate(this.itemL);
} else {
this.Item = instantiate(this.itemT);
}
this.Item.setPosition(nodes[i].x, nodes[i].y);
generateNode.addChild(this.Item);
this.suzu.push(this.Item)
}
let bool = this.CheckOverlap(this.suzu)
this.suzu = [];
if (!bool) {
generateNode.removeAllChildren();
}
return bool
}
//判断节点是否相交
IsIntersect(node1: Node, node2: Node): boolean {
const rect1 = node1.getComponent(UITransform).getBoundingBox();
const rect2 = node2.getComponent(UITransform).getBoundingBox();
return rect1.intersects(rect2);
}
//判断多个节点是否相交
CheckOverlap(nodes: Node[]): boolean {
for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
if (this.IsIntersect(nodes[i], nodes[j])) {
return false;
}
}
}
return true;
} 因为生成出来的还是有概率重叠 所以判断有重叠就重新生成 有点笨的处理方式 但也能用