p5.js 数组元素之间的碰撞

p5.js collision between array elements

我正在学习 p5.js,但我遇到了一个我还无法解决的问题。 所以我正在制作这个小游戏,你必须在其中射击敌人并躲避他们的技能。这是看起来的样子:

右边是玩家,中间是子弹(用数组处理),左边是敌人(数组)。敌人和子弹都有自己的对象。 这是生成敌人和子弹的代码:

为了子弹

function shoot() {
    x = p.x + 6.5;
    y = p.y + 12.5;
    bullets.push(new Bullet(x, y));
}

敌人:

function spawnEnemies() {
    let x = 650;
    let y = 30;

    for (let i = 0; i < 14; i++) {
        enemies.push(new Enemy(x, y));
        y += 40
    }
}

我想做的是在子弹到达目标时检测碰撞。我是这样尝试的:

// check hit
for (let i = 0; i < bullets.length; i++){
    for (let j = 0; j < enemies.length; j++){
        let d = dist(bullets[i].x, bullets[i].y, enemies[j].x, enemies[j].y)
        if (d < 1){
            console.log('hit');
        }
    }
}

check hit 代码在 p5 的 draw 函数中,因此它被连续执行。谁能帮帮我?

提前致谢!

您可以检查 draw 循环内的碰撞。使用圆圈很简单,您只需检查距离是否小于两个元素半径之和 DEMO

dist < circleOne.radius + circleTwo.radius

但是因为你有正方形,所以它有点困难,因为 size != diagonal 所以代码看起来像这样。 DEMO

if (Math.abs(this.position.x - player.position.x) < this.size/2 + player.size/2 && Math.abs(this.position.y - player.position.y) < this.size/2 + player.size/2) collision = true; 

这里我也使用 p5.Vector 作为位置,但你不必,只需使用 dist 而不是 p5.Vector.dist

const targets = [];
let player = null;
let canvas = null;

function setup() {
  canvas = createCanvas(400, 400);
  player = new Player(0, 0, 30, 'green');

  for (var i = 0; i < 10; i++) {
    const w = random(width);
    const h = random(height);
    const size = random(5, 40);
    targets.push(new Target(w, h, size, 'blue'));
  }

  canvas.mouseMoved(function() {
    player.position.x = mouseX;
    player.position.y = mouseY;
  })
}

function draw() {
  background(220);
  player.show()
  targets.forEach(target => {
    target.show();
    target.hit(player)
  })
}

class Element {
  constructor(x, y, size, color) {
    this.x = x;
    this.y = y;
    this.size = size;
    this.color = color;
    this.position = new p5.Vector(this.x, this.y);
  }

  show() {
    fill(this.color);
    rectMode(CENTER)
    rect(this.position.x, this.position.y, this.size, this.size)
  }
}

class Player extends Element {}
class Target extends Element {
  hit(player) {
    let collision = false;

    if (Math.abs(this.position.x - player.position.x) < this.size / 2 + player.size / 2 && Math.abs(this.position.y - player.position.y) < this.size / 2 + player.size / 2) collision = true;
    else collision = false;
    if (collision) this.color = 'red';
    else this.color = 'blue';
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>

要检测两个元素数组之间的冲突,您可以使用嵌套 for 循环,因为您需要检查第一个数组中的任何元素是否与第二个数组中的任何元素发生冲突。

const targets = [];
const bullets = [];
let canvas = null;

function setup() {
  canvas = createCanvas(400, 400);

  for (var i = 0; i < 10; i++) {
    const w = random(width);
    const h = random(height);
    const size = random(5, 50);
    targets.push(new Target(w, h, size, 'blue'));
  }

  for (var j = 0; j < 30; j++) {
    const w = random(width);
    const h = random(height);
    const size = random(5, 20);
    bullets.push(new Bullet(w, h, size, 'green'));
  }
}

function draw() {
  background(220);
  bullets.forEach(bullet => {
    bullet.show();
    bullet.move();
  });

  for (var i = 0; i < targets.length; i++) {
    for (var j = 0; j < bullets.length; j++) {
      const hit = targets[i].hit(bullets[j]);
      if (hit) {
        targets[i].color = 'red';
        break;
      } else targets[i].color = 'blue'
    }
  }

  targets.forEach(target => target.show());
}

class Element {
  constructor(x, y, size, color) {
    this.x = x;
    this.y = y;
    this.size = size;
    this.color = color;
    this.position = new p5.Vector(this.x, this.y);
  }

  show() {
    const c = color(this.color);
    c.setAlpha(150);
    fill(c);
    rectMode(CENTER)
    rect(this.position.x, this.position.y, this.size, this.size)
  }
}

class Bullet extends Element {
  move() {
    this.position.add(p5.Vector.random2D())
  }
}
class Target extends Element {
  hit(player) {
    if (Math.abs(this.position.x - player.position.x) < this.size / 2 + player.size / 2 && Math.abs(this.position.y - player.position.y) < this.size / 2 + player.size / 2) return true;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>