0

I'm coding a Breakout game with Javascript. I took the MDN tutorial and another tutorial and I'm trying to modify the original with a OOP approach. Until now, everything works fine except for the collision detection with the paddle. Which is not happening. Why is that? Here's my code. Can somebody help? Thanks!

var canvas = document.getElementById('game');
var theLoop;
var paddleSpeed = 4;

//OBJECTS
//Game
function Game() {
  this.width = canvas.width;
  this.height = canvas.height;
  this.ctx = canvas.getContext('2d');
  this.ctx.fillStyle = "white";
  this.p = new Paddle(0, 130);
  this.p.x = (this.width - this.p.width) / 2;
  this.keys = new Keylistener();
  this.ball = new Ball();
  this.ball.x = this.width / 2;
  this.ball.y = 125;
  this.ball.vy = Math.floor(Math.random() * 12 - 6);  
  this.ball.vx = 7 - Math.abs(this.ball.vy);
}

Game.prototype.draw = function() {
  this.ctx.clearRect(0, 0, this.width, this.height);
  this.p.draw(this.ctx);
  this.ball.draw(this.ctx);
};

Game.prototype.update = function() {
  if (this.paused) return;
  this.ball.update();
  //Right Paddle's Directions
  if (this.keys.isPressed(37)) { // LEFT
    this.p.x = Math.max(0, this.p.x - paddleSpeed);
  } else if (this.keys.isPressed(39)) { // RIGHT
        
    this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
  }


  if (this.ball.x < this.ball.ballRadius || this.ball.x > this.width - this.ball.ballRadius) { //LEFT & RIGHT
    this.ball.vx = -this.ball.vx;
  }
  if (this.ball.y < this.ball.ballRadius) { //TOP
    this.ball.vy = -this.ball.vy;
  } else if (this.ball.y > this.height - this.ball.ballRadius) {
    if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
      this.ball.vy = -this.ball.vy;
      console.log('hit');
    } else {
      //      console.log(this.ball.x);
    }
  }
};

/////Paddle
function Paddle(x, y) {
  this.x = x;
  this.y = y;
  this.width = 30;
  this.height = 5;
  this.score = 0;
}

Paddle.prototype.draw = function(p) {
  p.fillRect(this.x, this.y, this.width, this.height);
};

///KEY LISTENER
function Keylistener() {
  this.pressedKeys = [];
  this.keydown = function(e) {
    this.pressedKeys[e.keyCode] = true;
  };
  this.keyup = function(e) {
    this.pressedKeys[e.keyCode] = false;
  };
  document.addEventListener("keydown", this.keydown.bind(this));
  document.addEventListener("keyup", this.keyup.bind(this));
}

Keylistener.prototype.isPressed = function(key) {
  return this.pressedKeys[key] ? true : false;
};

Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
  document.addEventListener("keypress", function(e) {
    if (e.keyCode == keyCode) callback(e);
  });
};

///BALL
function Ball() {
  this.x = 0;
  this.y = 0;
  this.vx = 0;
  this.vy = 0;
  this.ballRadius = 5;
}

Ball.prototype.update = function() {
  this.x += this.vx;
  this.y += this.vy;
};

Ball.prototype.draw = function(p) {
  p.beginPath();
  p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
  p.fill();
  p.closePath();
};


//Initialize the game
var game = new Game();

//the Main Engine
function mainLoop() {
  theLoop = setInterval(function() {
    game.update();
    game.draw();
  }, 33.3333);
}

//calling the Main Engine
mainLoop();
#game {
  width: 800px;
  height: 400px;
  background-color: #353535;
}
<canvas id="game"></canvas>
CoderPi
  • 12,985
  • 4
  • 34
  • 62
Marco Mazzai
  • 95
  • 2
  • 16

2 Answers2

0

Your problem is this section right here.

else if (this.ball.y > this.height - this.ball.ballRadius) {
    if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {

You aren't trying to register a hit with the paddle unless the ball is at the bottom of the screen. You need to be checking if the ball intersects with the paddle before you hit the bottom of the screen.

var paddleLeft = this.p.x;
var paddleRight = paddleLeft + this.p.width;
var paddleTop = this.p.y;
var ballLeft = this.ball.x;
var ballRight = ballLeft + this.ball.ballRadius;
var ballBottom = this.ball.y + this.ball.ballRadius;
var xCollision = (ballLeft <= paddleRight && ballRight >= paddleLeft);
var yCollision = (ballBottom >= paddleTop);
if (this.ball.y < this.ball.ballRadius) { //TOP
  this.ball.vy = -this.ball.vy;
} else if (xCollision && yCollision) {
  this.ball.vy = -this.ball.vy;
  console.log('hit');
}

Here it is running in your game.

var canvas = document.getElementById('game');
var theLoop;
var paddleSpeed = 4;

//OBJECTS
//Game
function Game() {
  this.width = canvas.width;
  this.height = canvas.height;
  this.ctx = canvas.getContext('2d');
  this.ctx.fillStyle = "white";
  this.p = new Paddle(0, 220);
  this.p.x = (this.width - this.p.width) / 2;
  this.keys = new Keylistener();
  this.ball = new Ball();
  this.ball.x = this.width / 2;
  this.ball.y = 125;
  this.ball.vy = Math.floor(Math.random() * 12 - 6);  
  this.ball.vx = 7 - Math.abs(this.ball.vy);
}

Game.prototype.draw = function() {
  this.ctx.clearRect(0, 0, this.width, this.height);
  this.p.draw(this.ctx);
  this.ball.draw(this.ctx);
};

Game.prototype.update = function() {
  if (this.paused) return;
  this.ball.update();
  //Right Paddle's Directions
  if (this.keys.isPressed(37)) { // LEFT
    this.p.x = Math.max(0, this.p.x - paddleSpeed);
  } else if (this.keys.isPressed(39)) { // RIGHT
        
    this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
  }

  var leftBallCollision = this.ball.x < this.ball.ballRadius;
  var rightBallCollision = this.ball.x > this.width - this.ball.ballRadius;
  if (leftBallCollision || rightBallCollision) { //LEFT & RIGHT
    this.ball.vx = -this.ball.vx;
  }
  
  var paddleLeft = this.p.x;
  var paddleRight = paddleLeft + this.p.width;
  var paddleTop = this.p.y;
  var ballLeft = this.ball.x;
  var ballRight = ballLeft + this.ball.ballRadius;
  var ballBottom = this.ball.y + this.ball.ballRadius;
  var xCollision = (ballLeft <= paddleRight && ballRight >= paddleLeft);
  var yCollision = (ballBottom >= paddleTop);
  if (this.ball.y < this.ball.ballRadius) { //TOP
    this.ball.vy = -this.ball.vy;
  } else if (xCollision && yCollision) {
    this.ball.vy = -this.ball.vy;
    console.log('hit');
  }
};

/////Paddle
function Paddle(x, y) {
  this.x = x;
  this.y = y;
  this.width = 30;
  this.height = 5;
  this.score = 0;
}

Paddle.prototype.draw = function(p) {
  p.fillRect(this.x, this.y, this.width, this.height);
};

///KEY LISTENER
function Keylistener() {
  this.pressedKeys = [];
  this.keydown = function(e) {
    this.pressedKeys[e.keyCode] = true;
  };
  this.keyup = function(e) {
    this.pressedKeys[e.keyCode] = false;
  };
  document.addEventListener("keydown", this.keydown.bind(this));
  document.addEventListener("keyup", this.keyup.bind(this));
}

Keylistener.prototype.isPressed = function(key) {
  return this.pressedKeys[key] ? true : false;
};

Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
  document.addEventListener("keypress", function(e) {
    if (e.keyCode == keyCode) callback(e);
  });
};

///BALL
function Ball() {
  this.x = 0;
  this.y = 0;
  this.vx = 0;
  this.vy = 0;
  this.ballRadius = 5;
}

Ball.prototype.update = function() {
  this.x += this.vx;
  this.y += this.vy;
};

Ball.prototype.draw = function(p) {
  p.beginPath();
  p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
  p.fill();
  p.closePath();
};


//Initialize the game
var game = new Game();

//the Main Engine
function mainLoop() {
  theLoop = setInterval(function() {
    game.update();
    game.draw();
  }, 33.3333);
}

//calling the Main Engine
mainLoop();
#game {
  background-color: #353535;
}
<canvas id="game" width="320" height="240"></canvas>
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
0

var canvas = document.getElementById('game');
var theLoop;
var paddleSpeed = 4;

//OBJECTS
//Game
function Game() {
  this.width = canvas.width;
  this.height = canvas.height;
  this.ctx = canvas.getContext('2d');
  this.ctx.fillStyle = "white";
  this.p = new Paddle(0, 130);
  this.p.x = (this.width - this.p.width) / 2;
  this.keys = new Keylistener();
  this.ball = new Ball();
  this.ball.x = this.width / 2;
  this.ball.y = 125;
  this.ball.vy = Math.floor(Math.random() * 12 - 6);  
  this.ball.vx = 7 - Math.abs(this.ball.vy);
}

Game.prototype.draw = function() {
  this.ctx.clearRect(0, 0, this.width, this.height);
  this.p.draw(this.ctx);
  this.ball.draw(this.ctx);
};

Game.prototype.update = function() {
  if (this.paused) return;
  this.ball.update();
  //Right Paddle's Directions
  if (this.keys.isPressed(37)) { // LEFT
    this.p.x = Math.max(0, this.p.x - paddleSpeed);
  } else if (this.keys.isPressed(39)) { // RIGHT
        
    this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
  }


  if (this.ball.x < this.ball.ballRadius || this.ball.x > this.width - this.ball.ballRadius) { //LEFT & RIGHT
    this.ball.vx = -this.ball.vx;
  }
  if (this.ball.y < this.ball.ballRadius) { //TOP
    this.ball.vy = -this.ball.vy;
  } else if (this.ball.y > this.p.y - this.ball.ballRadius && 
            this.ball.y < this.p.y + this.p.height + this.ball.ballRadius) {

   if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
      this.ball.vy = -this.ball.vy;
      console.log('hit');
    } else {
      //      console.log(this.ball.x);
    }
  }
};

/////Paddle
function Paddle(x, y) {
  this.x = x;
  this.y = y;
  this.width = 30;
  this.height = 5;
  this.score = 0;
}

Paddle.prototype.draw = function(p) {
  p.fillRect(this.x, this.y, this.width, this.height);
};

///KEY LISTENER
function Keylistener() {
  this.pressedKeys = [];
  this.keydown = function(e) {
    this.pressedKeys[e.keyCode] = true;
  };
  this.keyup = function(e) {
    this.pressedKeys[e.keyCode] = false;
  };
  document.addEventListener("keydown", this.keydown.bind(this));
  document.addEventListener("keyup", this.keyup.bind(this));
}

Keylistener.prototype.isPressed = function(key) {
  return this.pressedKeys[key] ? true : false;
};

Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
  document.addEventListener("keypress", function(e) {
    if (e.keyCode == keyCode) callback(e);
  });
};

///BALL
function Ball() {
  this.x = 0;
  this.y = 0;
  this.vx = 0;
  this.vy = 0;
  this.ballRadius = 5;
}

Ball.prototype.update = function() {
  this.x += this.vx;
  this.y += this.vy;
};

Ball.prototype.draw = function(p) {
  p.beginPath();
  p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
  p.fill();
  p.closePath();
};


//Initialize the game
var game = new Game();

//the Main Engine
function mainLoop() {
  theLoop = setInterval(function() {
    game.update();
    game.draw();
  }, 33.3333);
}

//calling the Main Engine
mainLoop();
#game {
  width: 800px;
  height: 400px;
  background-color: #353535;
}
<canvas id="game"></canvas>
CoderPi
  • 12,985
  • 4
  • 34
  • 62