p5.j​​s数组元素之间的冲突

时间:2018-04-01 11:46:17

标签: javascript arrays collections detection p5.js

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

在右侧,我们有玩家,中间是子弹(用阵列处理),左侧是敌人(阵列)。敌人和子弹都有自己的对象。 这是产生敌人和子弹的代码:

对于子弹

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函数内部,因此会连续执行。任何人都可以帮助我吗?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

您可以检查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>