javascript - AI跟随并避免与障碍物碰撞

标签 javascript algorithm math artificial-intelligence path-finding

我正在制作一个基于极坐标的 AI 导航系统。目的是将 actor 移动到一个位置,同时远离其路径上可能存在的障碍。

代码大部分时间都运行良好,但经过测试后,我发现了这一点:当玩家、障碍物和 Actor 都在 X 或 Y 方向或对 Angular 线上完全对齐时, Actor 会卡在障碍物中。当玩家“拥抱”一堵墙时,这一点最为明显,因为 Actor 的运动矢量被墙剪裁,使它们对齐。

单击代码段中的按钮以查看我在说什么。

有什么办法可以避免这种情况吗?

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

let playerX = 100;
let playerY = 200;

let obstacleX = 200;
let obstacleY = 200;

let actorX = 300;
let actorY = 201;


function loop() {
    // Wall clipping
    if (actorX > 490) {
        actorX = 490;
    } else if (actorX < 10) {
        actorX = 10;
    }

    if (actorY > 490) {
        actorY = 490;
    } else if (actorY < 10) {
        actorY = 10;
    }

    // Vector between player and actor
    let vectorPlayerX = playerX - actorX;
    let vectorPlayerY = playerY - actorY;

    // Vector between obstacle and actor
    let vectorObstacleX = obstacleX - actorX;
    let vectorObstacleY = obstacleY - actorY;

    // Where to move, defaults to player's position
    const anglePlayer = Math.atan2(vectorPlayerY, vectorPlayerX);
    let moveAngle = anglePlayer;

    // If near obstacle, adjust course and try to avoid it
    if (Math.sqrt(vectorObstacleX * vectorObstacleX + vectorObstacleY * vectorObstacleY) < 50) {
        const angleObstacle = Math.atan2(vectorObstacleY, vectorObstacleX);
        moveAngle += anglePlayer - angleObstacle;
    }

    // Move the vector to desired location
    actorX += Math.cos(moveAngle);
    actorY += Math.sin(moveAngle);

    //Drawing
    ctx.clearRect(0, 0, 500, 500);

    ctx.beginPath();
    ctx.fillStyle = "gray";
    ctx.arc(actorX, actorY, 10, 0, Math.PI * 2, true);
    ctx.fill();

    ctx.beginPath();
    ctx.fillStyle = "orange";
    ctx.arc(obstacleX, obstacleY, 10, 0, Math.PI * 2, true);
    ctx.fill();

    ctx.beginPath();
    ctx.fillStyle = "blue";
    ctx.arc(playerX, playerY, 10, 0, Math.PI * 2, true);
    ctx.fill();

    requestAnimationFrame(loop);
}

requestAnimationFrame(loop);


function nonAligned() {
    playerX = 100;
    playerY = 200;

    obstacleX = 200;
    obstacleY = 200;

    actorX = 300;
    actorY = 201;
}

function alignedY() {
    playerX = 100;
    playerY = 490;

    obstacleX = 200;
    obstacleY = 490;

    actorX = 300;
    actorY = 490;
}

function alignedBoth() {
    playerX = 200;
    playerY = 200;

    obstacleX = 300;
    obstacleY = 300;

    actorX = 400;
    actorY = 400;
}
#options {
    position: fixed;
    top: 5px;
    left: 5px;
}
<!DOCTYPE html>
<html>
<body>
    <canvas id="canvas" width="500" height="500"></canvas>
<div id="options">
    <button onclick="nonAligned()">Spawn non-aligned</button>
    <button onclick="alignedY()">Spawn Y aligned</button>
    <button onclick="alignedBoth()">Spawn diagonally aligned</button>
</div>
</body>
</html>

最佳答案

如果玩家和障碍物的 Angular 相同,那么我们继续类(class),因为变量相互抵消。

    moveAngle += anglePlayer - angleObstacle;

如果 anglePlayer 是 117,angleObstacle 是 117,你的 moveAngle 是 117,你得到

   117 + 117 -117 = 117 ...

你可能想要这样的东西(伪代码)

    moveAngle += anglePlayer + random(90)-45;

或者如果碰到障碍物向左或向右移动

    moveAngle += anglePlayer - 90;
    if (random(2)==1 moveAngle += 180

关于javascript - AI跟随并避免与障碍物碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53057291/

相关文章:

javascript - ReactJs 换时间视频html5

javascript - 当属性不存在时忽略 for 循环中的大小写

algorithm - Mergesort 运行时间 BigO

math - 如何选择指向任何凸多边形内部的法向量(2d)?

java - 如何在c++/java中生成一组遵循一定分布的值?

javascript - 使用 "image"类型下拉框和 vbscript

c - C 中的大数减法

c++ - 3d 迷宫递归方法 - C++

javascript - 找到两点之间 Angular 最快方法

javascript - 无法使用谷歌图表适应模式窗口