【问题标题】:p5.js collision between array elementsp5.j​​s 数组元素之间的冲突
【发布时间】:2018-09-10 20:50:01
【问题描述】:

我正在学习 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 函数内部,因此它会连续执行。谁能帮帮我?

提前谢谢你!

【问题讨论】:

    标签: javascript arrays collections detection p5.js


    【解决方案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';
      }
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"&gt;&lt;/script&gt;

    要检测两个元素数组之间的冲突,您可以使用嵌套的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;
      }
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"&gt;&lt;/script&gt;

    【讨论】:

    • 检查碰撞已经在绘制循环中。我的问题是我有一个array 的子弹和一个敌人。所以我必须检查它们中的每一个。因为玩家射出的子弹比数组的元素多。
    猜你喜欢
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 2019-07-09
    • 1970-01-01
    相关资源
    最近更新 更多