JavaScript p5.js 游戏中的敌人侦测和炮塔 animation/control

Enemy detection and turret animation/control in a JavaScript p5.js game

我正在使用 JavaScript 和 p5.js 库制作塔防游戏。我的敌人沿着一条路走,他们的位置总是存储在一个列表中。我有一个底座和一把枪,枪围绕底座旋转(作为 1 个单位)并且应该指向最近的敌人。我有一个功能可以让我把枪指向敌人 pointEnemy 但是,我无法获得正确的条件使其指向范围内最近的敌人。我需要 enemyxenemyy 的正确参数。我目前正在生成 100 个敌人,它们一直在移动,它们的位置存储在 globalenemy1position 中。感谢您的帮助,谢谢。


所需代码


一些重要变量

var numberOfEnemy1 = 100
let classenemy1 = new Enemy1(numberOfEnemy1);
var globalenemy1position = [];   
var isFireTowerPressed = false;
var FireTowerPos = [];    // Position of all FireTowers => [x,y]
var FireTowerRange = 300;
var FireTowerAngle = 0;

我的敌人Class

class Enemy1
{
    constructor(number_of_enemies)
    {
        this.number_of_enemies = number_of_enemies;
        this.enemy_position = [];
        this.enemy1speed = 4;

    }
    enemy1_spawn()
    {
        let randomx = random(-300, -100);
        for(var i=0; i<this.number_of_enemies; i++)
        {
            var positionx = randomx;
            var positiony = 100;

            this.enemy_position.push([positionx + (-i*50), positiony]);
            globalenemy1position.push([positionx + (-i*50), positiony]);
            image(enemy1, this.enemy_position[i][0], this.enemy_position[i][1]);
        }

    }

    enemy1_move()
    {
        for(var i = 0; i < this.enemy_position.length; i++)
        {
            image(enemy1, this.enemy_position[i][0], this.enemy_position[i][1]);

            if (this.enemy_position[i][0] >= 200 && this.enemy_position[i][1] <= 450 && this.enemy_position[i][0] < 599)
            {
                this.enemy_position[i][1] += this.enemy1speed;
                globalenemy1position[i][1] += this.enemy1speed;
            }   

            else if (this.enemy_position[i][1] >= 100 && this.enemy_position[i][0] >= 600)
            {
                this.enemy_position[i][1] -= this.enemy1speed;
                globalenemy1position[i][1] -= this.enemy1speed;
            }

            else if (this.enemy_position[i][0] >= 750)
            {
                this.enemy_position[i][0] = 750;
                lives --;
                this.enemy_position.shift();
                globalenemy1position.shift();
            }   

            else
            {
                this.enemy_position[i][0] += this.enemy1speed;
                globalenemy1position[i][0] += this.enemy1speed;
            }

        }
    }
}

绘制函数 - 重绘每一帧

function draw() 
{

    background(60, 238, 161);
    [...]
    classenemy1.enemy1_move();
    rect(750, 70, 50, 100);
    ShowLives();
    if (isFireTowerPressed == true) 
    {
        image(firetowerbaseImg, mouseX - 28, mouseY - 28);
        noFill();
        stroke(0,0,0);
        strokeWeight(1);
        circle(mouseX, mouseY, 300);
    }
    for (var i = 0; i < FireTowerPos.length; i++) 
    {
        image(firetowerbaseImg, FireTowerPos[i][0], FireTowerPos[i][1]);

        if (globalenemy1position.length >= 1)
        {
            var gunx = FireTowerPos[i][0] +28;
            var guny = FireTowerPos[i][1]+25;
            var gunrange = FireTowerPos[i][3];

            for (j=0; j<globalenemy1position.length; j++)
            {

                // Need help with this statement here
                pointEnemy(globalenemy1position[j][0], globalenemy1position[j][1], gunx, guny, FireTowerPos[i][2], FireTowerPos[i][3]);
                
            }
        }
        else
        {
            image(firetowerturretImg, FireTowerPos[i][0], FireTowerPos[i][1]-20);
        }
    }
}

使枪指向敌人的功能 - 我需要 enemyx 和 enemyy 的正确值

function pointEnemy(enemyx, enemyy, gunx, guny, gunangle, gunrange)
{
    const isWithinRange = dist(enemyx, enemyy, gunx, guny) < gunrange;
    if(isWithinRange)
    {
        gunangle = atan2(enemyy - guny, enemyx - gunx) + radians(90);
    }
        push();
        translate(gunx, guny);
        // rect(-25, -20, 50, 40) // Draw the gun base
        // ellipse(0, 0, gun.range*2) // display the gun range
        rotate(gunangle);
        image(firetowerturretImg, -28, -45); // Set the offset of the gun sprite and draw the gun
        pop();
}

这里有一张图片可以帮助形象化问题

如你所见,目前我只是遍历所有敌人并给出他们的位置,所以它基本上指向附近的每个敌人。


更新


1

我尝试了 @user3386109 给出的方法,但是没能实现,如果可能的话我希望 turret/gun 指向敌人直到它离开范围而不是总是指向最近的敌人。它应该从最近的开始,然后一直指向它,直到它离开或敌人死亡(位置从列表中删除),以先到者为准。然后该函数应再次重新启动并继续该过程。

这个过程就是对塔的完整瞄准。将其添加到绘图中,它会搜索敌人。

for (var i = 0; i < FireTowerPos.length; i++) 
{
    // image(firetowerbaseImg, FireTowerPos[i][0], FireTowerPos[i][1]);
    // pointEnemy(mouseX, mouseY, FireTowerPos[i][0] +28, FireTowerPos[i][1]+25, FireTowerPos[i][2], FireTowerPos[i][3]);
    image(firetowerbaseImg, FireTowerPos[i][0], FireTowerPos[i][1]);

    var enemiesInRange = [];
    let firetowerx = FireTowerPos[i][0];
    let firetowery = FireTowerPos[i][1];
    for (var j = 0; j < globalenemy1position.length; j++) 
    {
        var checkDist = dist(globalenemy1position[j][0], globalenemy1position[j][1], firetowerx, firetowery);
        let thisenemyx = globalenemy1position[j][0];
        let thisenemyy = globalenemy1position[j][1];

        if (checkDist < FireTowerRange) 
        {
            enemiesInRange.push([thisenemyx, thisenemyy]);
            pointEnemy(enemiesInRange[0][0], enemiesInRange[0][1], FireTowerPos[i][0] +28, FireTowerPos[i][1]+25, FireTowerPos[i][2], FireTowerPos[i][3]);

        }
        else
        {
            enemiesInRange.shift();
        }
    }
}