Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pong game collision in javascript

Tags:

javascript

Hi I try to make a pong game. but my collide method doesn't work I can't see what i'm doing wrong. The ball pass through the player. The collide method seems good to me

 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>
like image 907
sonia maklouf Avatar asked Feb 24 '19 13:02

sonia maklouf


1 Answers

It seems to work with a standard rectangle on rectangle collision, such as this :

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;
    }
like image 170
Stev Avatar answered Nov 11 '22 10:11

Stev