使用原生js加DFS算法实现简单的推箱子小游戏

1.HTML部分

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>

<body>
    <header style="width: 100%; height: 80px; 
    line-height: 80px; color: #000000; text-align: center; font-size: 30px;">休闲推箱子</header>
    <div
        style="display: flex; width: 40%; height: 50px; margin: 0 auto; flex-wrap: nowrap; justify-content: space-around;">
        <div style="flex: 0 1 15%;" class="left"><img src="./img/图层 4.png" alt="" width="100%"></div>
        <p class="text" style="flex: 1; color: rgb(57, 55, 53); text-align: center; line-height: 50px;">第1关移动次数0</p>
        <div style="flex: 0 1 15%;" class="right"><img src="./img/图层 5.png" alt="" width="100%"></div>
    </div>
    <div class="henbox">
        <table class="box" style="z-index: 3;">

        </table>
    </div>
    <div style="width: 60%; height: 50px;  margin: 10px auto;">
        <div style="display: flex; width: 100%; height: 50px; justify-content: space-around;">
            <div style="flex:0 1 10%;" class="Reboot"><img src="./img/图层 2.png" alt="" width="100%"></div>
            <div style="flex:0 1 20%; text-align: center; line-height: 50px; 
            border-radius: 50px; background-color: rgb(192, 180, 8);
            color: #fbfbfb; cursor: pointer;" class="AIfun">开挂通关
            </div>
            <div style="flex:0 1 10%;" class="Withdraw"><img src="./img/图层 3.png" alt="" width="100%"></div>
        </div>
    </div>
</body>
<script src="./index.js"></script>

</html>

2.CSS部分

* {
    margin: 0;
    padding: 0;
}

body {
    /* background-color: black; */
/* background-image: linear-gradient(to bottom, #b98c1e, #be9822, #c2a427, #c5b02d, #c8bc34, #cac236, #cbc838, #ccce3a, #cecf36, #cfd032, #d1d02d, #d3d128); */
}

.henbox {
    width: 100%;
    height: auto;
}

.box {
    width: 500px;
    height: 500px;
    margin: 0 auto;
    /* background-image: url(./img/map.png);
    background-size: cover;
    background-repeat: repeat-y; */
    border-collapse: collapse;
    padding: 0;
}

.box tr {
    width: 100%;
    height: 50px;
    background-color: transparent;
}

.box tr td {
    width: 10%;
    height: 50px;
    /* border: 1px solid black; */
    margin: 0;
    padding: 0;
    background-image: none;
    background-size: 100% 100%;
    background-repeat: no-repeat;
    /* background-size: cover; */
}
/* .left{
  
}
.right{

} */

3.JS源码

// 10x10的二维数组表示地图,0表示空地,1表示障碍物 2为角色 3为箱子 4为终点
let map5 = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 0, 0, 4, 0, 1, 4, 1],
    [1, 0, 3, 0, 0, 3, 0, 0, 0, 1],
    [1, 0, 0, 0, 1, 0, 1, 0, 0, 1],
    [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
    [1, 2, 0, 0, 3, 0, 0, 0, 0, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 3, 0, 1, 0, 1],
    [1, 4, 0, 0, 1, 0, 0, 0, 4, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
let map4 = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 0, 0, 3, 0, 0, 0, 4, 1],
    [1, 0, 1, 0, 1, 0, 1, 0, 1, 1],
    [1, 4, 0, 0, 0, 0, 3, 0, 0, 1],
    [1, 0, 3, 0, 0, 2, 0, 0, 0, 1],
    [1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
    [1, 0, 4, 0, 3, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 1, 0, 4, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
let map3 = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 0, 0, 1, 0, 0, 0, 1],
    [1, 0, 3, 0, 0, 0, 0, 3, 0, 1],
    [1, 0, 1, 0, 0, 1, 1, 0, 1, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
    [1, 0, 4, 0, 2, 0, 0, 3, 0, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 4, 0, 1, 0, 1],
    [1, 1, 0, 0, 4, 0, 0, 0, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
let map2 = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 0, 1, 0, 1, 4, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 1],
    [1, 0, 3, 0, 2, 0, 0, 0, 1],
    [1, 0, 3, 0, 0, 0, 0, 0, 1],
    [1, 0, 1, 1, 1, 3, 0, 0, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 1],
    [1, 0, 4, 0, 4, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
];
let map = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 0, 0, 1, 0, 1, 0, 1],
    [1, 0, 0, 0, 3, 0, 2, 0, 0, 1],
    [1, 0, 1, 0, 1, 1, 1, 0, 1, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
    [1, 0, 3, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 4, 0, 1, 0, 1],
    [1, 0, 0, 0, 4, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
let arraysetmap = [map, map2, map3, map4, map5]
//获取文本DOM
const textwenben = document.querySelector('.text')
//存储DOM
let array = [];
//存储角色位置
let strat = ''
//用于存储箱子所在位置
let modulebox = []
//存储箱子位置的副本
let clonedModulebox = []
//存储终点位置
let end = []
//存储游戏角色走过的路径与箱子的位置
let startRegister = []

const boxy = [0, 0, 1, -1]
const boxx = [1, -1, 0, 0]
//存储第几关
let asderight = 0
//记录步数
let numberset = 0
//记录总路径
let totialpath = []
//记录角色推完箱子后的位置
let startpostion = []
geuzi(map)
//格子生成
function geuzi(map) {
    //记录总路径
    totialpath = []
    //记录角色推完箱子后的位置
    startpostion = []
    array = []
    strat = ''
    modulebox = []
    clonedModulebox = []
    end = []
    startRegister = []
    numberset = 0
    text()
    const box = document.querySelector(".box");
    box.innerHTML = " "
    for (let row = 0; row < map.length; row++) {
        const tr = document.createElement("tr");
        let rowArray = [];
        for (let col = 0; col < map[row].length; col++) { // 这里修正了错误
            let td = document.createElement("td");
            if (map[row][col] === 1) {
                td.style.backgroundImage = "url('./img/墙.png')";
            }
            if (map[row][col] === 2) {
                //存储角色初始位置
                strat = { x: col, y: row }
                setTimeout(() => {
                    startRegister.push({ x: col, y: row, img: './img/向下1.png', Postionbox: clonedModulebox })
                }, 10);
                td.style.backgroundImage = "url('./img/向下1.png')";
            }
            if (map[row][col] === 3) {
                modulebox.push({ x: col, y: row })
                clonedModulebox.push({ x: col, y: row })
                td.style.backgroundImage = "url('./img/箱子.png')";
            }
            if (map[row][col] === 4) {
                end.push({ x: col, y: row })
                td.style.backgroundImage = "url('./img/终点.png')";
            }
            tr.appendChild(td);
            rowArray.push(td);
        }
        // 添加到数组和表格
        array.push(rowArray);
        box.appendChild(tr);
    }
}
function text() {
    textwenben.innerHTML = `第${asderight + 1}关移动次数${numberset}`
}
// 监听键盘按下事件
const CallbackFunction = document.addEventListener('keydown', function (event) {
    const key = event.key.toLowerCase(); // 获取按下的键并转换为小写
    // 判断按下的键是否为ADWS中的一个,并进行相应操作
    switch (key) {
        case 'a':
            // 处理按下A键的逻辑
            array[strat.y][strat.x].style.backgroundImage = "url('./img/左1.png')";
            if (!(strat.x <= 0 || map[strat.y][strat.x - 1] === 1) && boxHenZi(strat.y, strat.x - 1, 'left')) {
                array[strat.y][strat.x].style.backgroundImage = "none";
                greener(strat.y, strat.x)
                strat.x -= 1
                numberset++
                text()
                startRegister.push({ x: strat.x, y: strat.y, img: './img/左1.png', Postionbox: clonedModulebox })
                array[strat.y][strat.x].style.backgroundImage = "url('./img/左1.png')";
            }
            break;
        case 'd':
            // 处理按下D键的逻辑
            array[strat.y][strat.x].style.backgroundImage = "url('./img/右1.png')";
            if (!(strat.x > map[0].length || map[strat.y][strat.x + 1] === 1) && boxHenZi(strat.y, strat.x + 1, 'right')) {
                array[strat.y][strat.x].style.backgroundImage = "none";
                greener(strat.y, strat.x)
                strat.x += 1
                numberset++
                text()
                startRegister.push({ x: strat.x, y: strat.y, img: './img/右1.png', Postionbox: clonedModulebox })
                array[strat.y][strat.x].style.backgroundImage = "url('./img/右1.png')";
            }
            break;
        case 'w':
            // 处理按下W键的逻辑
            array[strat.y][strat.x].style.backgroundImage = "url('./img/向上1.png')";
            if (!(strat.y <= 0 || map[strat.y - 1][strat.x] === 1) && boxHenZi(strat.y - 1, strat.x, 'top')) {
                array[strat.y][strat.x].style.backgroundImage = "none";
                greener(strat.y, strat.x)
                strat.y -= 1
                numberset++
                text()
                startRegister.push({ x: strat.x, y: strat.y, img: './img/向上1.png', Postionbox: clonedModulebox })
                array[strat.y][strat.x].style.backgroundImage = "url('./img/向上1.png')";

            }
            break;
        case 's':
            // 处理按下S键的逻辑
            array[strat.y][strat.x].style.backgroundImage = "url('./img/向下1.png')";
            if (!(strat.y > map[0].length || map[strat.y + 1][strat.x] === 1) && boxHenZi(strat.y + 1, strat.x, 'buttom')) {
                array[strat.y][strat.x].style.backgroundImage = "none";
                greener(strat.y, strat.x)
                strat.y += 1
                numberset++
                text()
                startRegister.push({ x: strat.x, y: strat.y, img: './img/向下1.png', Postionbox: clonedModulebox })
                array[strat.y][strat.x].style.backgroundImage = "url('./img/向下1.png')";

            }
            break;
        default:
            // 其他按键的处理逻辑
            break;
    }
});
//箱子与角色是否将要重合
function boxHenZi(starty, startx, fangxiang) {
    for (let index = 0; index < modulebox.length; index++) {
        if (modulebox[index].y === starty && modulebox[index].x === startx) {
            return movebox(modulebox[index].y, modulebox[index].x, fangxiang, index)
        }
    }
    return true
}
//更新盒子副本数据
function boxcopy() {
    clonedModulebox = []
    clonedModulebox = modulebox.map(box => ({ ...box }));
}
//控制箱子移动
function movebox(moduleboxy, moduleboxx, fangxiang, num) {
    if (fangxiang === 'top') {
        if (!(moduleboxy - 1 <= 0 || map[moduleboxy - 1][moduleboxx] === 1)) {
            //改变坐标
            modulebox[num].y -= 1

            if (twobox(modulebox)) {
                modulebox[num].y += 1
                // alert(modulebox[num].y)
                return false
            }

            writer(modulebox[num].y, modulebox[num].x, moduleboxy, moduleboxx, num)
            boxcopy()
            win()
            return true
        } else {
            return false
        }
    } else if (fangxiang === 'buttom') {
        if (!(moduleboxy + 1 > map[0].length || map[moduleboxy + 1][moduleboxx] === 1)) {
            modulebox[num].y += 1
            if (twobox(modulebox)) {
                modulebox[num].y -= 1
                return false
            }
            writer(modulebox[num].y, modulebox[num].x, moduleboxy, moduleboxx, num)
            boxcopy()
            win()
            return true
        } else {
            return false
        }
    } else if (fangxiang === 'left') {
        if (!(moduleboxx - 1 <= 0 || map[moduleboxy][moduleboxx - 1] === 1)) {
            modulebox[num].x -= 1
            if (twobox(modulebox)) {
                modulebox[num].x += 1
                return false
            }
            writer(modulebox[num].y, modulebox[num].x, moduleboxy, moduleboxx, num)
            boxcopy()
            win()
            return true
        } else {
            return false
        }
    } else if (fangxiang === 'right') {
        if (!(moduleboxx + 1 > map[0].length || map[moduleboxy][moduleboxx + 1] === 1)) {
            modulebox[num].x += 1
            if (twobox(modulebox)) {
                modulebox[num].x -= 1
                return false
            }
            writer(modulebox[num].y, modulebox[num].x, moduleboxy, moduleboxx, num)
            boxcopy()
            win()
            return true
        } else {
            return false
        }
    }
}
function writer(zby, zbx, zbying, zbxing, num) {
    array[zbying][zbxing].style.backgroundImage = "none";
    array[zby][zbx].style.backgroundImage = "url('./img/箱子.png')";
    modulebox[num].y = zby
    modulebox[num].x = zbx
}
//渲染角色经过终点后恢复终点
function greener(zby, zbx) {
    end.forEach((item) => {
        if (zby === item.y && zbx === item.x) {
            if (array[zby][zbx].style.backgroundImage === "url('./img/箱子.png')") {
                array[zby][zbx].style.backgroundImage === "url('./img/箱子.png')"
            } else {
                array[zby][zbx].style.backgroundImage = "url('./img/终点.png')";
            }
        } else {

        }
    })
}
//判断两个箱子是否重合
function twobox(arrayx) {
    const serialized = arrayx.map(obj => JSON.stringify(obj));
    //判断坐标是否重复,重复true,不重复
    return new Set(serialized).size !== serialized.length;
}2
//判断是否胜利
function win() {
    let panduan = false
    for (let index = 0; index < modulebox.length; index++) {
        for (let ind = 0; ind < end.length; ind++) {
            if (modulebox[index].y === end[ind].y && modulebox[index].x === end[ind].x) {
                break
            }
            if (ind === end.length - 1) {
                panduan = true
            }
        }
        if (panduan) {
            break
        }
        if (index === modulebox.length - 1) {
            setTimeout(() => {
                alert("你赢了")
                if (asderight === arraysetmap.length - 1) {
                    asderight = -1
                }
                asderight++
                text()
                map = arraysetmap[asderight]
                geuzi(map)
            }, 100);
            break
        }
    }
}

document.querySelector(".right").addEventListener("click", (e) => {
    if (asderight === arraysetmap.length - 1) {
        asderight = -1
    }
    asderight++
    text()
    map = arraysetmap[asderight]
    geuzi(map)
})
document.querySelector(".left").addEventListener("click", (e) => {
    if (asderight === 0) {
        asderight = arraysetmap.length
    }
    asderight--
    text()
    map = arraysetmap[asderight]
    geuzi(map)
})
//判断撤回
document.querySelector(".Withdraw").addEventListener("click", (e) => {
    if (numberset > 0) {
        for (let index = 0; index < end.length; index++) {
            if (end[index].y === startRegister[numberset].y && end[index].x === startRegister[numberset].x) {
                array[startRegister[numberset].y][startRegister[numberset].x].style.backgroundImage = "url('./img/终点.png')";
                break;
            }
            if (index === end.length - 1) {
                array[startRegister[numberset].y][startRegister[numberset].x].style.backgroundImage = "none";
            }
        }
        //判断箱子是否需要撤回
        modulebox.forEach((item, indexx) => {
            if (startRegister[numberset].Postionbox[indexx].x === item.x && startRegister[numberset].Postionbox[indexx].y === item.y) {
                for (let index = 0; index < end.length; index++) {
                    //终点恢复
                    if (end[index].y === item.y && end[index].x === item.x) {
                        array[item.y][item.x].style.backgroundImage = "url('./img/终点.png')";
                        break
                    }
                    if (index === end.length - 1) {
                        array[item.y][item.x].style.backgroundImage = "none";
                    }
                }
                // array[item.y][item.x].style.backgroundImage = "none";
                modulebox[indexx].x = startRegister[numberset - 1].Postionbox[indexx].x
                modulebox[indexx].y = startRegister[numberset - 1].Postionbox[indexx].y
                boxcopy()
                array[modulebox[indexx].y][modulebox[indexx].x].style.backgroundImage = "url('./img/箱子.png')";
            }
        })
        numberset -= 1
        console.log(numberset);
        console.log(startRegister);
        array[startRegister[numberset].y][startRegister[numberset].x].style.backgroundImage = `url(${startRegister[numberset].img})`;
        strat.y = startRegister[numberset].y
        strat.x = startRegister[numberset].x
        startRegister.pop()
        text()
    } else {
        console.log("速度呼唤", startRegister);
    }
})
document.querySelector(".Reboot").addEventListener("click", (e) => {
    geuzi(arraysetmap[asderight])
})

function textcs(wenziendx, wenziendy) {
    console.log("这是", wenziendx, wenziendy);
    let wemap = BFS2(strat.x, strat.y, wenziendx, wenziendy)
    console.log(wemap);
    let index = 0
    let time = setInterval(() => {
        juese(wemap[index + 1].x, wemap[index + 1].y, wemap[index].x, wemap[index].y)
        index++
        if (index + 1 === wemap.length) {
            // namebox()
            console.log(wemap);
            clearInterval(time)
        }
    }, 500);
}

//用于渲染角色移动轨迹
function juese(startx, starty, startxing, startying) {
    const pahtwe = BFS(startx, starty, startxing, startying)
    if (pahtwe.length > 0) {
        juesemove(startx, starty, startxing, startying)
    } else {
        juesemove(startx, starty, startxing, startying)
    }
}
function juesemove(startx, starty, startxing, startying) {
    array[startying][startxing].style.backgroundImage = "none";
    greener(startying, startxing)
    const left = startx - startxing
    const top = starty - startying
    strat.x = startx
    strat.y = starty
    if (left > 0) {
        array[starty][startx].style.backgroundImage = "url('./img/右1.png')";
    }
    if (left < 0) {
        array[starty][startx].style.backgroundImage = "url('./img/左1.png')";
    }
    if (top > 0) {
        array[starty][startx].style.backgroundImage = "url('./img/向下1.png')";
    }
    if (top < 0) {
        array[starty][startx].style.backgroundImage = "url('./img/向上1.png')";
    }
}
// BFS函数返回最短路径经过的坐标数组(广度优先搜索)
function BFS(startX, startY, endX, endY) {
    const queue = [];
    const visited = [];
    const path = [];
    //存储盒子被推走的路线
    const pathbox = []
    for (let i = 0; i < map.length; i++) {
        visited[i] = [];
        for (let j = 0; j < map[i].length; j++) {
            visited[i][j] = false;
        }
    }
    //添加起始坐标boxx:modulebox[0].x, boxy: modulebox[0].y
    queue.push({ x: startX, y: startY, distance: 0, reversex: startX, reversey: startY });
    visited[startY][startX] = true;

    const dx = [-1, 1, 0, 0];
    const dy = [0, 0, -1, 1];

    while (queue.length > 0) {
        const current = queue.shift();
        const { x, y, distance } = current;

        if (x === endX && y === endY) {
            // 找到终点时,将路径坐标保存到 path 数组中并返回
            let currentNode = current;
            while (currentNode) {
                path.unshift({ x: currentNode.x, y: currentNode.y, reversex: currentNode.reversex, reversey: currentNode.reversey });
                currentNode = currentNode.parent;
            }
            return path;
        }
        for (let i = 0; i < 4; i++) {
            const nx = x + dx[i];
            const ny = y + dy[i];
            const curryx = x - dx[i];
            const curryy = y - dy[i];
            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && map[ny][nx] !== 1 && !visited[ny][nx] && map[ny][nx] !== 3 && !(ny === strat.y && nx === strat.x) &&
                curryx >= 0 && curryx < 10 && curryy >= 0 && curryy < 10 && map[curryy][curryx] !== 1) {
                //parent用于保存该路径上一级父节点的坐标
                queue.push({ x: nx, y: ny, distance: distance + 1, parent: current, reversex: curryx, reversey: curryy });
                visited[ny][nx] = true;
            }
        }
    }
    return []; // 无法到达终点
}
function BFSbox(nx, ny) {
    modulebox.forEach((item, index) => {
        if (item.x === nx && item.y === ny) {
            return false
        }
    })
    return true
}
function BFS2(startX, startY, endX, endY) {
    const queue = [];
    const visited = [];
    const path = [];
    //存储盒子被推走的路线
    const pathbox = []
    for (let i = 0; i < map.length; i++) {
        visited[i] = [];
        for (let j = 0; j < map[i].length; j++) {
            visited[i][j] = false;
        }
    }
    //添加起始坐标boxx:modulebox[0].x, boxy: modulebox[0].y
    queue.push({ x: startX, y: startY, distance: 0 });
    visited[startY][startX] = true;

    const dx = [-1, 1, 0, 0];
    const dy = [0, 0, -1, 1];

    while (queue.length > 0) {
        const current = queue.shift();
        const { x, y, distance } = current;

        if (x === endX && y === endY) {
            // 找到终点时,将路径坐标保存到 path 数组中并返回
            let currentNode = current;
            while (currentNode) {
                path.unshift({ x: currentNode.x, y: currentNode.y });
                currentNode = currentNode.parent;
            }
            return path;
        }
        for (let i = 0; i < 4; i++) {
            const nx = x + dx[i];
            const ny = y + dy[i];
            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && map[ny][nx] !== 1 && !visited[ny][nx] && (map[ny][nx] !== 3 || (nx === endX && ny === endY))) {
                //parent用于保存该路径上一级父节点的坐标
                queue.push({ x: nx, y: ny, distance: distance + 1, parent: current });
                visited[ny][nx] = true;
            }
        }
    }
    return []; // 无法到达终点
}
function BFS3(startX, startY, endX, endY) {
    const queue = [];
    const visited = [];
    const path = [];
    //存储盒子被推走的路线
    const pathbox = []
    for (let i = 0; i < map.length; i++) {
        visited[i] = [];
        for (let j = 0; j < map[i].length; j++) {
            visited[i][j] = false;
        }
    }
    //添加起始坐标boxx:modulebox[0].x, boxy: modulebox[0].y
    queue.push({ x: startX, y: startY, distance: 0, reversex: startX, reversey: startY });
    visited[startY][startX] = true;

    const dx = [-1, 1, 0, 0];
    const dy = [0, 0, -1, 1];

    while (queue.length > 0) {
        const current = queue.shift();
        const { x, y, distance } = current;

        if (x === endX && y === endY) {
            // 找到终点时,将路径坐标保存到 path 数组中并返回
            let currentNode = current;
            while (currentNode) {
                path.unshift({ x: currentNode.x, y: currentNode.y, reversex: currentNode.reversex, reversey: currentNode.reversey });
                currentNode = currentNode.parent;
            }
            return path;
        }
        for (let i = 0; i < 4; i++) {
            const nx = x + dx[i];
            const ny = y + dy[i];
            const curryx = x - dx[i];
            const curryy = y - dy[i];
            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && map[ny][nx] !== 1 && !visited[ny][nx] && map[ny][nx] !== 3 && !(ny === strat.y && nx === strat.x) &&
                curryx >= 0 && curryx < 10 && curryy >= 0 && curryy < 10 && map[curryy][curryx] !== 1) {
                //parent用于保存该路径上一级父节点的坐标
                queue.push({ x: nx, y: ny, distance: distance + 1, parent: current, reversex: x, reversey: y });
                visited[ny][nx] = true;
            }
        }
    }
    return []; // 无法到达终点
}

function AIkongzi(params1, params2) {
    return BFS3(params1.x, params1.y, params2.x, params2.y);
}

//开始使用广度优先搜索算法,寻找最短路径
document.querySelector(".AIfun").addEventListener("click", (e) => {
    // let pathboxx = BFS(modulebox[1].x, modulebox[1].y, end[1].x, end[1].y)
    // let wemap = BFS2(strat.x, strat.y, pathboxx[1].reversex, pathboxx[1].reversey)
    // textcs(pathboxx[1].reversex, pathboxx[1].reversey)
    // console.log(pathboxx[pathboxx.length - 1].reversex, pathboxx[pathboxx.length - 1].reversey);
    for (let index = 0; index < end.length; index++) {
        //获取角色应该到达什么地方推动坐标
        if (index === 0) {
            let pathboxx = BFS(modulebox[index].x, modulebox[index].y, end[index].x, end[index].y)
            let wemap = BFS2(strat.x, strat.y, pathboxx[1].reversex, pathboxx[1].reversey)
            startpostion.push(wemap)
        }
        //获取箱子到终点路径信息
        console.log(modulebox[index], end[index]);
        let pathboxx2 = AIkongzi(modulebox[index], end[index])
        //获取角色应该到达什么地方推动坐标
        if (index > 0) {
            let pathboxx = BFS(modulebox[index].x, modulebox[index].y, end[index].x, end[index].y)
            console.log(pathboxx);
            console.log(pathboxx2);
            let wemap = BFS2(pathboxx2[pathboxx2.length - 1].reversex, pathboxx2[pathboxx2.length - 1].reversey, pathboxx[1].reversex, pathboxx[1].reversey)
            startpostion.push(wemap)
        }
        totialpath.push(pathboxx2)
    }
    console.log(totialpath);
    console.log(startpostion);
    namebox()
})

//盒子自动到达终点
function namebox() {
    let index = 0
    let index2 = 0
    let index3 = 0
    let num = 1
    let num2 = 1
    let time = setInterval(() => {
        if (!(index % 2)) {
            juese(startpostion[index3][num2].x, startpostion[index3][num2].y, startpostion[index3][num2 - 1].x, startpostion[index3][num2 - 1].y)
            num2++
        } else {
            nameboxmove(totialpath[index2][num].reversey, totialpath[index2][num].reversex, strat.y, strat.x, totialpath[index2][num].y, totialpath[index2][num].x, totialpath[index2][num - 1].y, totialpath[index2][num - 1].x, index2)
            num++
        }
        if (num === totialpath[index2].length) {
            index++
            if (index2 < totialpath.length - 1) {
                index2++
            }
            num = 1
            num2 = 1
        }
        if (num2 === startpostion[index3].length) {
            index++
            if (index3 < startpostion.length - 1) {
                index3++
            }
            num = 1
            num2 = 1
        }
        if (index === totialpath.length + startpostion.length) {
            win()
            clearInterval(time)
        }
    }, 500);
}
function nameboxmove(starty, startx, startying, startxing, boxxy, boxxx, boxxying, boxxxing, num) {
    array[boxxying][boxxxing].style.backgroundImage = "none";
    array[boxxy][boxxx].style.backgroundImage = "url('./img/箱子.png')";
    modulebox[num].y = boxxy
    modulebox[num].x = boxxx

    array[startying][startxing].style.backgroundImage = "none";
    greener(startying, startxing)
    const left = startx - startxing
    const top = starty - startying
    strat.x = startx
    strat.y = starty
    if (left > 0) {
        array[starty][startx].style.backgroundImage = "url('./img/右1.png')";
    }
    if (left < 0) {
        array[starty][startx].style.backgroundImage = "url('./img/左1.png')";
    }
    if (top > 0) {
        array[starty][startx].style.backgroundImage = "url('./img/向下1.png')";
    }
    if (top < 0) {
        array[starty][startx].style.backgroundImage = "url('./img/向上1.png')";
    }
}

第一次发布作品,若有不对,还望各位大佬见谅,欢迎评论区讨论

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值