如何在规定大小的范围内生成多个260x130或者130x260大小的方块!!!求助

image 一个方块占8个数字 这样子 我做出了固定形状的 但是两种不同的就会出现重叠 我想在这范围内不重叠 求助求助!!

每个节点上面加个白色背景底 大小一致 直接展示背景不就ok了

我需要随机每次都不是同一个位置

image
像这样 但是我现在写出来的还是有概率会重叠

直接让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)
}

微信截图_20240125031844 微信截图_20240125031651

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;

}  因为生成出来的还是有概率重叠  所以判断有重叠就重新生成 有点笨的处理方式 但也能用