JavaScript中的Pong游戏碰撞问题

7

你好,我想制作一个乒乓球游戏。 但我的碰撞方法不起作用,我看不出自己做错了什么。 球穿过了玩家。 对我来说,碰撞方法看起来不错。

 if (player.left < ball.right && player.right > ball.left &&
            player.top < ball.bottom && player.bottom > ball.top) {
            ball.vel.x = -ball.vel.x;
        }

class Vec {
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
}

class Rect {
  constructor(w, h) {
    this.pos = new Vec;
    this.size = new Vec(w, h)
  }
  get left() {
    return this.pos.x - this.size.x / 2;
  }
  get right() {
    return this.pos.x - this.size.x / 2;
  }
  get top() {
    return this.pos.y - this.size.y / 2;
  }
  get bottom() {
    return this.pos.y - this.size.y / 2;
  }
}
class Ball extends Rect {
  constructor() {
    super(10, 10);
    this.vel = new Vec;
  }
}
class Player extends Rect {
  constructor() {
    super(20, 100);
    this.score = 0;
  }
}
class Pong {
  constructor(canvas) {
    this._canvas = canvas;
    this._context = canvas.getContext('2d');

    this.ball = new Ball;
    this.ball.pos.x = 100;
    this.ball.pos.y = 50;

    this.ball.vel.x = 100;
    this.ball.vel.y = 100;

    this.players = [
      new Player,
      new Player,
    ];

    this.players[0].pos.x = 40;
    this.players[1].pos.x = this._canvas.width - 40;
    this.players.forEach(player => {
      player.pos.y = this._canvas.height / 2;
    })


    let lastTime;
    const callback = (millis) => {
      if (lastTime) {
        this.update((millis - lastTime) / 1000);
      }
      lastTime = millis;
      requestAnimationFrame(callback);
    };
    callback();
  }
  collide(player, ball) {
    if (player.left < ball.right && player.right > ball.left &&
      player.top < ball.bottom && player.bottom > ball.top) {
      ball.vel.x = -ball.vel.x;
    }
  }
  draw() {

    this._context.fillStyle = '#000';
    this._context.fillRect(0, 0, this._canvas.width, this._canvas.height);

    this.drawRect(this.ball);
    this.players.forEach(player => this.drawRect(player));
  }
  drawRect(rect) {
    this._context.fillStyle = '#fff';
    this._context.fillRect(rect.left, rect.top, rect.size.x, rect.size.y);
  }
  update(dt) {
    this.ball.pos.x += this.ball.vel.x * dt;
    this.ball.pos.y += this.ball.vel.y * dt;

    if (this.ball.left < 0 || this.ball.right > this._canvas.width) {
      this.ball.vel.x = -this.ball.vel.x;
    }
    if (this.ball.top < 0 || this.ball.bottom > this._canvas.height) {
      this.ball.vel.y = -this.ball.vel.y;
    }
    this.players[1].pos.y = this.ball.pos.y;

    this.players.forEach(player => this.collide(player, this.ball));

    this.draw();
  }

}
const canvas = document.getElementById('pong');
const pong = new Pong(canvas);

canvas.addEventListener('mousemove', event => {
  pong.players[0].pos.y = event.offsetY;
})
<body>
  <canvas id="pong" width="600" height="400"></canvas>
</body>


可能是Javascript:碰撞检测的重复问题。 - Jeto
1
player.top < ball.bottom && player.bottom > ball.top - I think this should be player.bottom < ball.top && player.top > ball.bottom - Robin Zigmond
1个回答

2

似乎可以使用标准的矩形与矩形碰撞来解决问题,例如:

最初的回答
if ( player.pos.x < ball.pos.x + ball.size.x &&
      player.pos.x + player.size.x > ball.pos.x &&
      player.pos.y < ball.pos.y + ball.size.y &&
      player.size.y + player.pos.y > ball.pos.y ) {
      ball.vel.x = -ball.vel.x;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接