为什么AI在移动时会振动
Why is the AI vibrating when it moves
let playerX;
let playerY;
let playerSize = 15;
let playerSpeed = (playerSize / Math.pow(playerSize, 1.44)) * 10;
let Newcelltimer = 0;
let cell = []
let zoom = 1;
let n = 0;
let Xgrid = 600;
let Ygrid = 600;
let cpu = [];
let x = 0;
let y = 10;
let OffSetX = [];
let OffSetY = [];
let CPUteam = 2;
function setup() {
smooth();
frameRate(999)
createCanvas(600, 450);
playerX = 500;
playerY = 100;
}
function draw() {
let cellDist = [];
let cpuDist = [];
background(220);
push();
//Changes the FOV depending on your size
let Newzoom = 10 / playerSize
let newnewZoom = 1.3 * lerp(0.9, 10 / playerSize, 0.5)
Newzoom = lerp(zoom, Newzoom, 0.3)
translate(Xgrid / 2, Ygrid / 2 - 50);
scale(newnewZoom)
translate(-playerX, -playerY);
// Player's speed
playerSpeed = round((playerSize / Math.pow(playerSize, 1.44)) * 10000) / 1000
Newcelltimer++;
//Adds in new cells
if (Newcelltimer % 40 == 0) {
cell.push(ceil(random(0 - Xgrid, 2 * Xgrid)),
ceil(random(0 - Ygrid, 2 * Ygrid)))
}
//Adds in new AI's
if (Newcelltimer % 200 == 0) {
cpu.push(ceil(random(-Xgrid, 2 * Xgrid)), ceil(random(-Ygrid, 2 * Ygrid)), 20, CPUteam)
OffSetX.push(ceil(random(0, 1000000)))
OffSetY.push(ceil(random(1000000, 2000000)))
CPUteam++;
}
//Creates AI when you start playing
if (Newcelltimer == 1 || Newcelltimer == 2) {
cpu.push(ceil(random(-Xgrid, 2 * Xgrid)), ceil(random(-Ygrid, 2 * Ygrid)), 20, CPUteam)
OffSetX.push(ceil(random(0, 1000000)))
OffSetY.push(ceil(random(1000000, 2000000)))
cell.push(ceil(random(0 - Xgrid, 2 * Xgrid)),
ceil(random(0 - Ygrid, 2 * Ygrid)))
CPUteam++;
}
//Checks if cell is eaten
for (let i = 0; i < cell.length / 2; i++) {
let d = int(dist(cell[i * 2], cell[i * 2 + 1], playerX, playerY))
if (d <= playerSize / 2) {
playerSize += 5;
cell.splice(i * 2, 2)
celliseaten = true;
}
else{
fill(0,255,255,180);
circle(i*2,i*2+1,8);
}
}
//The cells disappear after a bit
if (Newcelltimer % 200 == 0) {
cell.splice(0, 2)
}
//Everything to do with the AI system
for (let j = 0; j < (cpu.length / 4); j++) {
let cpuDist = [];
let distance = int(dist(cpu[j * 4], cpu[j * 4 + 1], playerX, playerY)) //Distance between AI and player
if (distance <= playerSize / 2 && cpu[j * 4 + 2] < playerSize) {
playerSize += floor(cpu[j * 4 + 2]);
cpu.splice(j * 4, 4)
}
else if(distance<=cpu[j*4+2]/2&&cpu[j*4+2]<playerSize)
{
//You lose
}
//Checks if AI ate AI
for (let m = 0; m < cpu.length / 4; m++) {
//Makes sure the AI's isn't the AI in the "j" loop
if (m != j) {
//Checks if the Ai's are on the same team
if (cpu[j * 4 + 3] % 2 != cpu[m * 4 + 3] % 2) {
distant = dist(cpu[m * 4], cpu[m * 4 + 1], cpu[j * 4], cpu[j * 4 + 1])
let higher = (cpu[m * 4 + 2] > cpu[j * 4 + 2]) ? cpu[m * 4 + 2] : cpu[j * 4 + 2];
if (higher > distant) {
if (cpu[m * 4 + 2] > cpu[j * 4 + 2]) {
cpu[m * 4 + 2] += cpu[j * 4 + 2]
cpu.splice(j * 4, 4)
} else {
cpu[j * 4 + 2] += cpu[m * 4 + 2]
cpu.splice(m * 4, 4)
} //Else
} //If
//If AI didn't eat another AI, return the distance
else {
cpuDist.push(distant);
} //Else
} //If
} //If
} //For
let ClosestCpu = min(cpuDist);
let ClosestCpupos;
//Index value of the closest cpu (NOT WORKINGS)
for (var q = 0; q < cpu.length / 4; q++) {
if (ClosestCpu == int(dist(cpu[q * 4], cpu[q * 4 + 1], cpu[j * 4], cpu[j * 4 + 1]))) {
ClosestCpupos = q;
break;
}
}
//Checks if AI ate cell
for (let n = 0; n < cell.length / 2; n++) {
let dis = int(dist(cell[n * 2], cell[n * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]))
if (dis <= cpu[j * 4 + 2] / 2) {
cpu[j * 4 + 2] += 5;
cell.splice(n * 2, 2)
} else {
//If it didn't eat the cell, does the same idea with the AI from before
cellDist.push(dis)
}
}
let ClosestCell = min(cellDist);
let ClosestCellpos;
for (let r = 0; r < cell.length / 2; r++) {
if (ClosestCell == int(dist(cell[r * 2], cell[r * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]))) {
ClosestCellpos = r;
break;
}
}
//AI sppeed
let amp = round((cpu[j * 4 + 2] / Math.pow(cpu[j * 4 + 2], 1.44)) * 70000) / 7000;
if (dist(playerX, playerY, cpu[j * 4], cpu[j * 4 + 1]) < 150 && playerSize > cpu[j * 4 + 2]) {
let distXpos = cpu[j * 4]-playerX;
let distYpos = cpu[j * 4 + 1]-playerY;
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] += distXpos * amp;
cpu[j * 4 + 1] += distYpos * amp;
} else if (dist(playerX, playerY, cpu[j * 4], cpu[j * 4 + 1]) < 150 && playerSize < cpu[j * 4 + 2]) {
let distXpos = cpu[j * 4]-playerX;
let distYpos = cpu[j * 4 + 1]-playerY;
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] -= distXpos * amp;
cpu[j * 4 + 1] -= distYpos * amp;
}
else if (dist(cpu[ClosestCpupos * 4], cpu[ClosestCpupos * 4 + 1], cpu[j * 4], cpu[j * 4 + 1]) < 150 && cpu[j * 4 + 2] > cpu[ClosestCpupos * 4 + 2]) {
let distXpos = cpu[ClosestCpupos * 4] - cpu[j * 4];
let distYpos = cpu[ClosestCpupos * 4 + 1] - cpu[j * 4 + 1];
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] += distXpos * amp;
cpu[j * 4 + 1] += distYpos * amp;
} else if (dist(cpu[ClosestCpupos * 4], cpu[ClosestCpupos * 4 + 1], cpu[j * 4], cpu[j * 4 + 1]) < 150 && cpu[j * 4 + 2] > cpu[ClosestCpupos * 4 + 2]) {
let distXpos = cpu[ClosestCpupos * 4] - cpu[j * 4];
let distYpos = cpu[ClosestCpupos * 4 + 1] - cpu[j * 4 + 1];
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] -= distXpos * amp;
cpu[j * 4 + 1] -= distYpos * amp;
} else if (dist(cell[ClosestCellpos * 2], cell[ClosestCellpos * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]) < 150) {
let distXpos = cell[ClosestCellpos * 2] - cpu[j * 4];
let distYpos = cell[ClosestCellpos * 2 + 1] - cpu[j * 4 + 1];
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] += distXpos * amp;
cpu[j * 4 + 1] += distYpos * amp;
} else {
x += 0.003;
y += 0.003;
let offsetX = map(noise(x + OffSetX[j]), 0, 1, -1, 1) * amp;
let offsetY = map(noise(y + OffSetY[j]), 0, 1, -1, 1) * amp;
cpu[j * 4] += offsetX;
cpu[j * 4 + 1] += offsetY;
}
if (cpu[j * 4 + 3] % 2 == 0) {
fill(0, 0, 255)
circle(cpu[j * 4], cpu[j * 4 + 1], cpu[j * 4 + 2]);
} else {
fill(255, 0, 0)
circle(cpu[j * 4], cpu[j * 4 + 1], cpu[j * 4 + 2])
} // Else
} //Cpu for
//Draws player
fill(255, 255, 0)
circle(playerX, playerY, playerSize)
pop();
}
问题是玩家在追AI的时候,AI在运行ning的时候,AI在运行ning的时候在震动。此外, closestCpupos 由于某种原因未定义,这不是我的问题,我稍后会修复或问另一个问题,后者可能就是这种情况。我已经输入了很多代码,所以我对大多数内容都发表了评论。问题可能出在 for(var j = 0;j<cpu.length/4;j++)
循环中的某处。也不确定这段代码是否会 运行 在 snipper 中,我可能删除了一些不会在代码段工具中 运行 的东西,并且代码有太多的嵌套循环。
- https://editor.p5js.org/Meowmeow/sketches/XTH-hArn6 完整程序,未删除任何内容
- 如果AI追逐玩家,它不会振动
- AI chase AI 不工作,这将在另一个问题中问到
- 问题可能出在CPU for 循环
- 该数组令人困惑,可能应该是一个二维数组,但要尝试解释它:一维数组在 4 的“组”中,第一个数字是 X 位置,第二个是 2 Y 位置,第三个是大小,第四个是蓝色团队或红色团队(如果第 4 个值 %2 为 0,则为蓝色,否则为 1)。所以 CPU 的数组可能看起来像
[100,150,25,3,250,600,15,4]
然后你会做一个 for 循环,从 0 开始,到 length/4,然后你绘制 AI,第一个 AI 会在100,150,尺寸 25,蓝队。第二个 AI 是 200,600,大小 26,团队 Red
这是因为 AI 比玩家移动得更快、更有效率。假设 CPU 每帧移动 3 个像素,玩家移动 1 个像素。现在考虑以下内容:
- CPU 距离玩家 149 像素,因此它向远离玩家的方向移动 3 个像素,而玩家向 CPU
方向移动 1 个像素
- 下一帧:CPU 距离 151 像素,因此它恢复到正常行为。
- 下一帧:玩家靠得近了,恢复到被追赶状态
- 重复
这种状态之间的交替是导致您看到的振动的原因。你如何解决这个问题?一种解决方案是给每个 CPU 一个布尔值以供追逐。当 CPU 距离玩家 150 以内时,您可以将其设置为 true,然后在距离玩家 200 时将其设置回 false。这样,它就不会振荡,因为它需要移动 50 个像素才能改变行为。为此,您需要将 j * 4
的所有实例更改为 j * 5
并为 cpu[j * 5 + 4]
提供初始布尔值。这是我的测试解决方案:
if (cpu[j * 5 + 4]) {//if currently running away
//continue running away if smallerthan player and still within 200
cpu[j * 5 + 4] = dist(cpu[j * 5], cpu[j * 5 + 1], playerX, playerY) < 200 &&
playerSize > cpu[j * 5 + 2];
} else {//if not currently running away
//start running away if smaller than player and within 150
cpu[j * 5 + 4] = dist(cpu[j * 5], cpu[j * 5 + 1], playerX, playerY) < 150 &&
playerSize > cpu[j * 5 + 2];
}
if (cpu[j * 5 + 4]) {
//your running away code...
}//...
我高度鼓励您使用classes。如果你为你的 CPU 制作一个 class,你可以为你想做的每件事制作一个方法。然后你可以有一个 CPU 数组并遍历它,做你需要它做的所有事情。它只是让代码更有条理。
let playerX;
let playerY;
let playerSize = 15;
let playerSpeed = (playerSize / Math.pow(playerSize, 1.44)) * 10;
let Newcelltimer = 0;
let cell = []
let zoom = 1;
let n = 0;
let Xgrid = 600;
let Ygrid = 600;
let cpu = [];
let x = 0;
let y = 10;
let OffSetX = [];
let OffSetY = [];
let CPUteam = 2;
function setup() {
smooth();
frameRate(999)
createCanvas(600, 450);
playerX = 500;
playerY = 100;
}
function draw() {
let cellDist = [];
let cpuDist = [];
background(220);
push();
//Changes the FOV depending on your size
let Newzoom = 10 / playerSize
let newnewZoom = 1.3 * lerp(0.9, 10 / playerSize, 0.5)
Newzoom = lerp(zoom, Newzoom, 0.3)
translate(Xgrid / 2, Ygrid / 2 - 50);
scale(newnewZoom)
translate(-playerX, -playerY);
// Player's speed
playerSpeed = round((playerSize / Math.pow(playerSize, 1.44)) * 10000) / 1000
Newcelltimer++;
//Adds in new cells
if (Newcelltimer % 40 == 0) {
cell.push(ceil(random(0 - Xgrid, 2 * Xgrid)),
ceil(random(0 - Ygrid, 2 * Ygrid)))
}
//Adds in new AI's
if (Newcelltimer % 200 == 0) {
cpu.push(ceil(random(-Xgrid, 2 * Xgrid)), ceil(random(-Ygrid, 2 * Ygrid)), 20, CPUteam)
OffSetX.push(ceil(random(0, 1000000)))
OffSetY.push(ceil(random(1000000, 2000000)))
CPUteam++;
}
//Creates AI when you start playing
if (Newcelltimer == 1 || Newcelltimer == 2) {
cpu.push(ceil(random(-Xgrid, 2 * Xgrid)), ceil(random(-Ygrid, 2 * Ygrid)), 20, CPUteam)
OffSetX.push(ceil(random(0, 1000000)))
OffSetY.push(ceil(random(1000000, 2000000)))
cell.push(ceil(random(0 - Xgrid, 2 * Xgrid)),
ceil(random(0 - Ygrid, 2 * Ygrid)))
CPUteam++;
}
//Checks if cell is eaten
for (let i = 0; i < cell.length / 2; i++) {
let d = int(dist(cell[i * 2], cell[i * 2 + 1], playerX, playerY))
if (d <= playerSize / 2) {
playerSize += 5;
cell.splice(i * 2, 2)
celliseaten = true;
}
else{
fill(0,255,255,180);
circle(i*2,i*2+1,8);
}
}
//The cells disappear after a bit
if (Newcelltimer % 200 == 0) {
cell.splice(0, 2)
}
//Everything to do with the AI system
for (let j = 0; j < (cpu.length / 4); j++) {
let cpuDist = [];
let distance = int(dist(cpu[j * 4], cpu[j * 4 + 1], playerX, playerY)) //Distance between AI and player
if (distance <= playerSize / 2 && cpu[j * 4 + 2] < playerSize) {
playerSize += floor(cpu[j * 4 + 2]);
cpu.splice(j * 4, 4)
}
else if(distance<=cpu[j*4+2]/2&&cpu[j*4+2]<playerSize)
{
//You lose
}
//Checks if AI ate AI
for (let m = 0; m < cpu.length / 4; m++) {
//Makes sure the AI's isn't the AI in the "j" loop
if (m != j) {
//Checks if the Ai's are on the same team
if (cpu[j * 4 + 3] % 2 != cpu[m * 4 + 3] % 2) {
distant = dist(cpu[m * 4], cpu[m * 4 + 1], cpu[j * 4], cpu[j * 4 + 1])
let higher = (cpu[m * 4 + 2] > cpu[j * 4 + 2]) ? cpu[m * 4 + 2] : cpu[j * 4 + 2];
if (higher > distant) {
if (cpu[m * 4 + 2] > cpu[j * 4 + 2]) {
cpu[m * 4 + 2] += cpu[j * 4 + 2]
cpu.splice(j * 4, 4)
} else {
cpu[j * 4 + 2] += cpu[m * 4 + 2]
cpu.splice(m * 4, 4)
} //Else
} //If
//If AI didn't eat another AI, return the distance
else {
cpuDist.push(distant);
} //Else
} //If
} //If
} //For
let ClosestCpu = min(cpuDist);
let ClosestCpupos;
//Index value of the closest cpu (NOT WORKINGS)
for (var q = 0; q < cpu.length / 4; q++) {
if (ClosestCpu == int(dist(cpu[q * 4], cpu[q * 4 + 1], cpu[j * 4], cpu[j * 4 + 1]))) {
ClosestCpupos = q;
break;
}
}
//Checks if AI ate cell
for (let n = 0; n < cell.length / 2; n++) {
let dis = int(dist(cell[n * 2], cell[n * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]))
if (dis <= cpu[j * 4 + 2] / 2) {
cpu[j * 4 + 2] += 5;
cell.splice(n * 2, 2)
} else {
//If it didn't eat the cell, does the same idea with the AI from before
cellDist.push(dis)
}
}
let ClosestCell = min(cellDist);
let ClosestCellpos;
for (let r = 0; r < cell.length / 2; r++) {
if (ClosestCell == int(dist(cell[r * 2], cell[r * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]))) {
ClosestCellpos = r;
break;
}
}
//AI sppeed
let amp = round((cpu[j * 4 + 2] / Math.pow(cpu[j * 4 + 2], 1.44)) * 70000) / 7000;
if (dist(playerX, playerY, cpu[j * 4], cpu[j * 4 + 1]) < 150 && playerSize > cpu[j * 4 + 2]) {
let distXpos = cpu[j * 4]-playerX;
let distYpos = cpu[j * 4 + 1]-playerY;
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] += distXpos * amp;
cpu[j * 4 + 1] += distYpos * amp;
} else if (dist(playerX, playerY, cpu[j * 4], cpu[j * 4 + 1]) < 150 && playerSize < cpu[j * 4 + 2]) {
let distXpos = cpu[j * 4]-playerX;
let distYpos = cpu[j * 4 + 1]-playerY;
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] -= distXpos * amp;
cpu[j * 4 + 1] -= distYpos * amp;
}
else if (dist(cpu[ClosestCpupos * 4], cpu[ClosestCpupos * 4 + 1], cpu[j * 4], cpu[j * 4 + 1]) < 150 && cpu[j * 4 + 2] > cpu[ClosestCpupos * 4 + 2]) {
let distXpos = cpu[ClosestCpupos * 4] - cpu[j * 4];
let distYpos = cpu[ClosestCpupos * 4 + 1] - cpu[j * 4 + 1];
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] += distXpos * amp;
cpu[j * 4 + 1] += distYpos * amp;
} else if (dist(cpu[ClosestCpupos * 4], cpu[ClosestCpupos * 4 + 1], cpu[j * 4], cpu[j * 4 + 1]) < 150 && cpu[j * 4 + 2] > cpu[ClosestCpupos * 4 + 2]) {
let distXpos = cpu[ClosestCpupos * 4] - cpu[j * 4];
let distYpos = cpu[ClosestCpupos * 4 + 1] - cpu[j * 4 + 1];
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] -= distXpos * amp;
cpu[j * 4 + 1] -= distYpos * amp;
} else if (dist(cell[ClosestCellpos * 2], cell[ClosestCellpos * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]) < 150) {
let distXpos = cell[ClosestCellpos * 2] - cpu[j * 4];
let distYpos = cell[ClosestCellpos * 2 + 1] - cpu[j * 4 + 1];
let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
let MultVal = 150/abs(higherVal);
distXpos*=MultVal;
distYpos*=MultVal;
distXpos = map(distXpos, -150, 150, -1, 1);
distYpos = map(distYpos, -150, 150, -1, 1);
cpu[j * 4] += distXpos * amp;
cpu[j * 4 + 1] += distYpos * amp;
} else {
x += 0.003;
y += 0.003;
let offsetX = map(noise(x + OffSetX[j]), 0, 1, -1, 1) * amp;
let offsetY = map(noise(y + OffSetY[j]), 0, 1, -1, 1) * amp;
cpu[j * 4] += offsetX;
cpu[j * 4 + 1] += offsetY;
}
if (cpu[j * 4 + 3] % 2 == 0) {
fill(0, 0, 255)
circle(cpu[j * 4], cpu[j * 4 + 1], cpu[j * 4 + 2]);
} else {
fill(255, 0, 0)
circle(cpu[j * 4], cpu[j * 4 + 1], cpu[j * 4 + 2])
} // Else
} //Cpu for
//Draws player
fill(255, 255, 0)
circle(playerX, playerY, playerSize)
pop();
}
问题是玩家在追AI的时候,AI在运行ning的时候,AI在运行ning的时候在震动。此外, closestCpupos 由于某种原因未定义,这不是我的问题,我稍后会修复或问另一个问题,后者可能就是这种情况。我已经输入了很多代码,所以我对大多数内容都发表了评论。问题可能出在 for(var j = 0;j<cpu.length/4;j++)
循环中的某处。也不确定这段代码是否会 运行 在 snipper 中,我可能删除了一些不会在代码段工具中 运行 的东西,并且代码有太多的嵌套循环。
- https://editor.p5js.org/Meowmeow/sketches/XTH-hArn6 完整程序,未删除任何内容
- 如果AI追逐玩家,它不会振动
- AI chase AI 不工作,这将在另一个问题中问到
- 问题可能出在CPU for 循环
- 该数组令人困惑,可能应该是一个二维数组,但要尝试解释它:一维数组在 4 的“组”中,第一个数字是 X 位置,第二个是 2 Y 位置,第三个是大小,第四个是蓝色团队或红色团队(如果第 4 个值 %2 为 0,则为蓝色,否则为 1)。所以 CPU 的数组可能看起来像
[100,150,25,3,250,600,15,4]
然后你会做一个 for 循环,从 0 开始,到 length/4,然后你绘制 AI,第一个 AI 会在100,150,尺寸 25,蓝队。第二个 AI 是 200,600,大小 26,团队 Red
这是因为 AI 比玩家移动得更快、更有效率。假设 CPU 每帧移动 3 个像素,玩家移动 1 个像素。现在考虑以下内容:
- CPU 距离玩家 149 像素,因此它向远离玩家的方向移动 3 个像素,而玩家向 CPU 方向移动 1 个像素
- 下一帧:CPU 距离 151 像素,因此它恢复到正常行为。
- 下一帧:玩家靠得近了,恢复到被追赶状态
- 重复
这种状态之间的交替是导致您看到的振动的原因。你如何解决这个问题?一种解决方案是给每个 CPU 一个布尔值以供追逐。当 CPU 距离玩家 150 以内时,您可以将其设置为 true,然后在距离玩家 200 时将其设置回 false。这样,它就不会振荡,因为它需要移动 50 个像素才能改变行为。为此,您需要将 j * 4
的所有实例更改为 j * 5
并为 cpu[j * 5 + 4]
提供初始布尔值。这是我的测试解决方案:
if (cpu[j * 5 + 4]) {//if currently running away
//continue running away if smallerthan player and still within 200
cpu[j * 5 + 4] = dist(cpu[j * 5], cpu[j * 5 + 1], playerX, playerY) < 200 &&
playerSize > cpu[j * 5 + 2];
} else {//if not currently running away
//start running away if smaller than player and within 150
cpu[j * 5 + 4] = dist(cpu[j * 5], cpu[j * 5 + 1], playerX, playerY) < 150 &&
playerSize > cpu[j * 5 + 2];
}
if (cpu[j * 5 + 4]) {
//your running away code...
}//...
我高度鼓励您使用classes。如果你为你的 CPU 制作一个 class,你可以为你想做的每件事制作一个方法。然后你可以有一个 CPU 数组并遍历它,做你需要它做的所有事情。它只是让代码更有条理。