Game stuck on first frame when triggered by onclick event - javascript

I'm making a game in a webpage using the html canvas element, and I have put all of the code for my game inside of a function called playPong(), and when the code is not stored inside of a function, it works perfectly fine, but when the function is called from the onclick event, all of the elements of the game show, but nothing happens. This is my code.
<canvas id='my' width = '640' height = '480'></canvas>
<script>
function playPong() {
var canvas = document.getElementById("my");
var ctx = canvas.getContext("2d");
function paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedModifier = 0;
this.hasCollidedWith = function(ball) {
var paddleLeftWall = this.x;
var paddleRightWall = this.x + this.width;
var paddleTopWall = this.y;
var paddleBottomWall = this.y + this.height;
if (ball.x > paddleLeftWall &&
ball.x < paddleRightWall &&
ball.y > paddleTopWall &&
ball.y < paddleBottomWall) {
return true;
}
return false;
};
this.move = function(keyCode) {
var nextY = this.y;
if (keyCode == 40) {
nextY += 5;
this.speedModifer = 1.5;
} else if (keyCode == 38) {
nextY += -5;
this.speedModifier = 1.5;
} else {
this.speedModifier = 0;
}
nextY = nextY < 0 ? 0 : nextY;
nextY = nextY + this.height > 480 ? 480 - this.height : nextY;
this.y = nextY;
};
}
var player = new paddle(5, 200, 25, 100);
var ai = new paddle(610, 200, 25, 100);
var ball = {
x: 320,
y: 240,
radius: 7,
xSpeed: 2,
ySpeed: 0,
playerscore: 0,
aiscore: 0,
reverseX: function() {
this.xSpeed *= -1;
},
reverseY: function() {
this.ySpeed *= -1;
},
reset: function() {
alert('The score is now ' + this.playerscore + ' to ' + this.aiscore);
this.x = 20;
this.y = 24;
this.xSpeed = 2;
this.ySpeed = 0;
},
isBouncing: function() {
return ball.ySpeed != 0;
},
modifyXSpeedBy: function(modification) {
modification = this.xSpeed < 0 ? modification * -1 : modification;
var nextValue = this.xSpeed + modification;
nextValue = Math.abs(nextValue) > 9 ? 9 : nextValue;
this.xSpeed = nextValue;
},
modifyYSpeedBy: function(modification) {
modification = this.ySpeed < 0 ? modification * -1 : modification;
this.ySpeed += modification;
}
};
function tick() {
updateGame();
draw()
window.setTimeout("tick()", 1000 / 60);
}
function updateGame() {
ball.x += ball.xSpeed;
ball.y += ball.ySpeed;
if (ball.x < 0) {
ball.reset();
ball.aiscore = ball.aiscore + 1;
}
if (ball.x > 640) {
ball.reset();
ball.playerscore = ball.playerscore + 1
}
if (ball.y <= 0 || ball.y >= 480) {
ball.reverseY();
}
var collidedWithPlayer = player.hasCollidedWith(ball);
var collidedWithAi = ai.hasCollidedWith(ball);
if (collidedWithPlayer || collidedWithAi) {
ball.reverseX();
ball.modifyXSpeedBy(0.25);
var speedUpValue = collidedWithPlayer ? player.speedModifier : ai.speedModifier;
ball.modifyYSpeedBy(speedUpValue);
}
for (var keyCode in heldDown) {
player.move(keyCode);
}
var aiMiddle = ai.y + (ai.height / 2);
if (aiMiddle < ball.y) {
ai.move(40);
}
if (aiMiddle > ball.y) {
ai.move(38);
}
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 640, 480);
renderPaddle(player);
renderPaddle(ai);
renderBall(ball);
}
function renderPaddle(paddle) {
ctx.fillStyle = "blue";
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
function renderBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "pink";
ctx.fill();
}
var heldDown = {};
window.addEventListener("keydown", function(keyInfo) {
heldDown[event.keyCode] = true;
}, false);
window.addEventListener("keyup", function(keyInfo) {
delete heldDown[event.keyCode];
}, false);
tick();
}
</script>
<script>
function getOff(){
alert ("you've been on for five minutes now. Time to take a break.");
setTimeout(function(){ alert("it's been 10 minutes now. Get back to work.");
close();
var body = document.getElementById('hide5')
body.style.display = 'none'
},300000);
}
setInterval (getOff, 300000)
}
</script>
<button onclick = 'playPong()'> Play pong </button>

If you want to start game by button. You can create function playPong() to cover just tick() code line.
Like below.
<canvas id='my' width = '640' height = '480'></canvas>
<script>
var canvas = document.getElementById("my");
var ctx = canvas.getContext("2d");
function paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedModifier = 0;
this.hasCollidedWith = function(ball) {
var paddleLeftWall = this.x;
var paddleRightWall = this.x + this.width;
var paddleTopWall = this.y;
var paddleBottomWall = this.y + this.height;
if (ball.x > paddleLeftWall &&
ball.x < paddleRightWall &&
ball.y > paddleTopWall &&
ball.y < paddleBottomWall) {
return true;
}
return false;
};
this.move = function(keyCode) {
var nextY = this.y;
if (keyCode == 40) {
nextY += 5;
this.speedModifer = 1.5;
} else if (keyCode == 38) {
nextY += -5;
this.speedModifier = 1.5;
} else {
this.speedModifier = 0;
}
nextY = nextY < 0 ? 0 : nextY;
nextY = nextY + this.height > 480 ? 480 - this.height : nextY;
this.y = nextY;
};
}
var player = new paddle(5, 200, 25, 100);
var ai = new paddle(610, 200, 25, 100);
var ball = {
x: 320,
y: 240,
radius: 7,
xSpeed: 2,
ySpeed: 0,
playerscore: 0,
aiscore: 0,
reverseX: function() {
this.xSpeed *= -1;
},
reverseY: function() {
this.ySpeed *= -1;
},
reset: function() {
alert('The score is now ' + this.playerscore + ' to ' + this.aiscore);
this.x = 20;
this.y = 24;
this.xSpeed = 2;
this.ySpeed = 0;
},
isBouncing: function() {
return ball.ySpeed != 0;
},
modifyXSpeedBy: function(modification) {
modification = this.xSpeed < 0 ? modification * -1 : modification;
var nextValue = this.xSpeed + modification;
nextValue = Math.abs(nextValue) > 9 ? 9 : nextValue;
this.xSpeed = nextValue;
},
modifyYSpeedBy: function(modification) {
modification = this.ySpeed < 0 ? modification * -1 : modification;
this.ySpeed += modification;
}
};
function tick() {
updateGame();
draw()
window.setTimeout("tick()", 1000 / 60);
}
function updateGame() {
ball.x += ball.xSpeed;
ball.y += ball.ySpeed;
if (ball.x < 0) {
ball.reset();
ball.aiscore = ball.aiscore + 1;
}
if (ball.x > 640) {
ball.reset();
ball.playerscore = ball.playerscore + 1
}
if (ball.y <= 0 || ball.y >= 480) {
ball.reverseY();
}
var collidedWithPlayer = player.hasCollidedWith(ball);
var collidedWithAi = ai.hasCollidedWith(ball);
if (collidedWithPlayer || collidedWithAi) {
ball.reverseX();
ball.modifyXSpeedBy(0.25);
var speedUpValue = collidedWithPlayer ? player.speedModifier : ai.speedModifier;
ball.modifyYSpeedBy(speedUpValue);
}
for (var keyCode in heldDown) {
player.move(keyCode);
}
var aiMiddle = ai.y + (ai.height / 2);
if (aiMiddle < ball.y) {
ai.move(40);
}
if (aiMiddle > ball.y) {
ai.move(38);
}
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 640, 480);
renderPaddle(player);
renderPaddle(ai);
renderBall(ball);
}
function renderPaddle(paddle) {
ctx.fillStyle = "blue";
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
function renderBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "pink";
ctx.fill();
}
var heldDown = {};
window.addEventListener("keydown", function(keyInfo) {
heldDown[event.keyCode] = true;
}, false);
window.addEventListener("keyup", function(keyInfo) {
delete heldDown[event.keyCode];
}, false);
function playPong(){
tick();
}
</script>
<script>
function getOff(){
alert ("you've been on for five minutes now. Time to take a break.");
setTimeout(function(){ alert("it's been 10 minutes now. Get back to work.");
close();
var body = document.getElementById('hide5')
body.style.display = 'none'
},300000);
}
setInterval (getOff, 300000)
}
</script>
<button onclick = 'playPong()'> Play pong </button>

Related

problems with resizing sprites

I need to resize my spritesheet so it fits the correct dimensions of my game object. I have been looking around the internet and I found that this -ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);- is what i think i need to use. however, i do not know how or where to implement this in my code. i know how it works but i dont know where to put it or where in my code to put it. i use almost completely javascript
var myGamePiece;
var myObstacle;
var object1;
var objects;
var box;
function startGame() {
//creation of objects
wall = new component(30, 100, "black", 300, 200);
myGamePiece = new component(30, 30, "red", 240, 135);
myObstacle = new component(100, 100, "green", 200, 100);
object1 = new component(30, 30, "enemy.png", 340, 125, "image");
box = new component(30, 30, "box.png", 177, 145, "image");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
window.addEventListener('keydown', function (e) {
myGameArea.key = e.keyCode;
})
window.addEventListener('keyup', function (e) {
myGameArea.key = false;
})
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
collide : function() {
object1.x += 1;
object1.y += 1;
},
//what to do when pushing box
boxleft : function() {
box.x -= 1;
x -= 1;
}
}
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.sx = x;
this.sy = y;
this.swidth = width;
this.sheight = height;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width,
this.height
);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
//code for gray square
this.crashWith = function(object1) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = object1.x;
var otherright = object1.x + (object1.width);
var othertop = object1.y;
var otherbottom = object1.y + (object1.height);
var crash = true;
if ((mybottom < othertop) ||
(mytop > otherbottom) ||
(myright < otherleft) ||
(myleft > otherright)) {
crash = false;
}
return crash;
}
//code to push box
this.pushboxWith = function(box) {
const myleft = this.x;
const myright = this.x + (this.width);
const mytop = this.y;
const mybottom = this.y + (this.height);
const boxleft = box.x-2;
const boxright = box.x + (box.width)+2;
const boxtop = box.y+2;
const boxbottom = box.y + (box.height)-2;
var pushboxleft = true;
var pushboxright = true;
//test if pushing box
if ((myleft < boxright) && (mybottom >= boxtop) && (mytop <= boxbottom) && (myleft > boxleft)) {
pushboxleft = true;
} else {
pushboxleft = false;
}
return pushboxleft;
}
}
function updateGameArea() {
if (myGamePiece.crashWith(object1)) {
myGameArea.collide();
} else if (myGamePiece.pushboxWith(box)) {
myGameArea.boxleft();
} else {
myGameArea.clear();
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
//keyboard controls. moves everything but the player
if (myGameArea.key && myGameArea.key == 37) {
myObstacle.x += 2;
object1.x += 2;
box.x += 2;
wall.x += 2;
}
if (myGameArea.key && myGameArea.key == 39) {
myObstacle.x += -2;
object1.x += -2;
box.x += -2;
wall.x += -2;
}
if (myGameArea.key && myGameArea.key == 38) {
myObstacle.y += 2;
object1.y += 2;
box.y += 2;
wall.y += 2
}
if (myGameArea.key && myGameArea.key == 40) {
myObstacle.y += -2;
object1.y += -2;
box.y += -2;
wall.y += -2
}
//other square movement. disabled to isolate code.
/*
if (object1.x < myGamePiece.x) {
object1.x += 1;
}
if (object1.x > myGamePiece.x) {
object1.x += -1;
}
if (object1.y < myGamePiece.y) {
object1.y += 1;
}
if (object1.y > myGamePiece.y) {
object1.y += -1;
}
*/
/* object order: the object that is higher on the list
will be on top of objects lower on the list
*/
myObstacle.update();
myGamePiece.newPos();
myGamePiece.update();
wall.update();
object1.update();
box.update();
//end of list
}
}
i do use some html
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
border:1px solid #d3d3d3;
background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">
<script src="main.js"></script>
</body>
</html>
if you need to test my code you can find it here- https://eeeegame-2.octopuscat.repl.co/

Pausing javascript game using style.display in if statements not working

I'm working on a javascript game and trying to add some code to the button that toggles the visibility of the games and acts as a pause button so that it will stop running and not keep shoving scoring alerts down your throat if you have it hidden, and all of the code that I've written has failed miserably. Here it is, hope someone can help me fix it.
<div id = 'games'>
<!-- I only put this canvas in a div because there will be more games here soon. -->
<canvas id='my' width = '640' height = '480'></canvas>
</div>
<script>
var canvas = document.getElementById("my");
var ctx = canvas.getContext("2d");
function paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedModifier = 0;
this.hasCollidedWith = function(ball) {
var paddleLeftWall = this.x;
var paddleRightWall = this.x + this.width;
var paddleTopWall = this.y;
var paddleBottomWall = this.y + this.height;
if (ball.x > paddleLeftWall &&
ball.x < paddleRightWall &&
ball.y > paddleTopWall &&
ball.y < paddleBottomWall) {
return true;
}
return false;
};
this.move = function(keyCode) {
var nextY = this.y;
if (keyCode == 40) {
nextY += 5;
this.speedModifer = 1.5;
} else if (keyCode == 38) {
nextY += -5;
this.speedModifier = 1.5;
} else {
this.speedModifier = 0;
}
nextY = nextY < 0 ? 0 : nextY;
nextY = nextY + this.height > 480 ? 480 - this.height : nextY;
this.y = nextY;
};
}
var player = new paddle(5, 200, 25, 100);
var ai = new paddle(610, 200, 25, 100);
var ball = {
x: 320,
y: 240,
radius: 7,
xSpeed: 2,
ySpeed: 0,
playerscore: 0,
aiscore: 0,
reverseX: function() {
this.xSpeed *= -1;
},
reverseY: function() {
this.ySpeed *= -1;
},
reset: function() {
alert('The score is now ' + this.playerscore + ' to ' + this.aiscore);
this.x = 20;
this.y = 24;
this.xSpeed = 2;
this.ySpeed = 0;
},
isBouncing: function() {
return ball.ySpeed != 0;
},
modifyXSpeedBy: function(modification) {
modification = this.xSpeed < 0 ? modification * -1 : modification;
var nextValue = this.xSpeed + modification;
nextValue = Math.abs(nextValue) > 9 ? 9 : nextValue;
this.xSpeed = nextValue;
},
modifyYSpeedBy: function(modification) {
modification = this.ySpeed < 0 ? modification * -1 : modification;
this.ySpeed += modification;
}
};
function tick() {
updateGame();
draw()
window.setTimeout("tick()", 1000 / 60);
}
function updateGame() {
ball.x += ball.xSpeed;
ball.y += ball.ySpeed;
if (ball.x < 0) {
ball.reset();
ball.aiscore = ball.aiscore + 1;
}
if (ball.x > 640) {
ball.reset();
ball.playerscore = ball.playerscore + 1
}
if (ball.y <= 0 || ball.y >= 480) {
ball.reverseY();
}
var collidedWithPlayer = player.hasCollidedWith(ball);
var collidedWithAi = ai.hasCollidedWith(ball);
if (collidedWithPlayer || collidedWithAi) {
ball.reverseX();
ball.modifyXSpeedBy(0.25);
var speedUpValue = collidedWithPlayer ? player.speedModifier : ai.speedModifier;
ball.modifyYSpeedBy(speedUpValue);
}
for (var keyCode in heldDown) {
player.move(keyCode);
}
var aiMiddle = ai.y + (ai.height / 2);
if (aiMiddle < ball.y) {
ai.move(40);
}
if (aiMiddle > ball.y) {
ai.move(38);
}
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 640, 480);
renderPaddle(player);
renderPaddle(ai);
renderBall(ball);
}
function renderPaddle(paddle) {
ctx.fillStyle = "blue";
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
function renderBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "pink";
ctx.fill();
}
var heldDown = {};
window.addEventListener("keydown", function(keyInfo) {
heldDown[event.keyCode] = true;
}, false);
window.addEventListener("keyup", function(keyInfo) {
delete heldDown[event.keyCode];
}, false);
function playPong(){
if (canvas.style.display == 'none'){canvas.style.display = 'block';}
else {canvas.style.display == 'none';}
if (canvas.style.display === 'block')
{
tick()};
}
</script>
<script>
function hide() {
var games = document.getElementById('games')
if (games.style.display === 'block')
games.style.display = 'none';
else{games.style.display = 'block';}
}
function show(){
var canvas = document.getElementById('my')
canvas.style.display = 'block';
}
</script>
<button onclick = 'hide()'> Hide or show the games</button>
<button onclick = 'playPong();show()'> Play pong </button>
I would try not using the visibility of the canvas as the deciding factor in the if statement and instead maybe trying something like this-
<div id='games'>
<canvas id='my' width='640' height='480'></canvas>
</div>
<script>
var paused = false
function PausePlay() {
if (paused === false) {
paused = true;
} else {
paused = false;
}
}
var canvas = document.getElementById("my");
var ctx = canvas.getContext("2d");
function paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedModifier = 0;
this.hasCollidedWith = function(ball) {
var paddleLeftWall = this.x;
var paddleRightWall = this.x + this.width;
var paddleTopWall = this.y;
var paddleBottomWall = this.y + this.height;
if (ball.x > paddleLeftWall &&
ball.x < paddleRightWall &&
ball.y > paddleTopWall &&
ball.y < paddleBottomWall) {
return true;
}
return false;
};
this.move = function(keyCode) {
var nextY = this.y;
if (keyCode == 40) {
nextY += 5;
this.speedModifer = 1.5;
} else if (keyCode == 38) {
nextY += -5;
this.speedModifier = 1.5;
} else {
this.speedModifier = 0;
}
nextY = nextY < 0 ? 0 : nextY;
nextY = nextY + this.height > 480 ? 480 - this.height : nextY;
this.y = nextY;
};
}
var player = new paddle(5, 200, 25, 100);
var ai = new paddle(610, 200, 25, 100);
var ball = {
x: 320,
y: 240,
radius: 7,
xSpeed: 2,
ySpeed: 0,
playerscore: 0,
aiscore: 0,
reverseX: function() {
this.xSpeed *= -1;
},
reverseY: function() {
this.ySpeed *= -1;
},
reset: function() {
alert('The score is now ' + this.playerscore + ' to ' + this.aiscore);
this.x = 20;
this.y = 24;
this.xSpeed = 2;
this.ySpeed = 0;
},
isBouncing: function() {
return ball.ySpeed != 0;
},
modifyXSpeedBy: function(modification) {
modification = this.xSpeed < 0 ? modification * -1 : modification;
var nextValue = this.xSpeed + modification;
nextValue = Math.abs(nextValue) > 9 ? 9 : nextValue;
this.xSpeed = nextValue;
},
modifyYSpeedBy: function(modification) {
modification = this.ySpeed < 0 ? modification * -1 : modification;
this.ySpeed += modification;
}
};
function tick() {
updateGame();
draw()
window.setTimeout("tick()", 1000 / 60);
}
function updateGame() {
if (paused === false) {
ball.x += ball.xSpeed;
ball.y += ball.ySpeed;
if (ball.x < 0) {
ball.reset();
ball.aiscore = ball.aiscore + 1;
}
if (ball.x > 640) {
ball.reset();
ball.playerscore = ball.playerscore + 1
}
if (ball.y <= 0 || ball.y >= 480) {
ball.reverseY();
}
var collidedWithPlayer = player.hasCollidedWith(ball);
var collidedWithAi = ai.hasCollidedWith(ball);
if (collidedWithPlayer || collidedWithAi) {
ball.reverseX();
ball.modifyXSpeedBy(0.25);
var speedUpValue = collidedWithPlayer ? player.speedModifier : ai.speedModifier;
ball.modifyYSpeedBy(speedUpValue);
}
for (var keyCode in heldDown) {
player.move(keyCode);
}
var aiMiddle = ai.y + (ai.height / 2);
if (aiMiddle < ball.y) {
ai.move(40);
}
if (aiMiddle > ball.y) {
ai.move(38);
}
}
}
function draw() {
if (paused === false) {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 640, 480);
renderPaddle(player);
renderPaddle(ai);
renderBall(ball);
}
}
function renderPaddle(paddle) {
ctx.fillStyle = "blue";
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
function renderBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "pink";
ctx.fill();
}
var heldDown = {};
window.addEventListener("keydown", function(keyInfo) {
heldDown[event.keyCode] = true;
}, false);
window.addEventListener("keyup", function(keyInfo) {
delete heldDown[event.keyCode];
}, false);
function playPong() {
tick()
}
</script>
<script>
function getOff() {
alert("you've been on for five minutes now. Time to take a break.");
setTimeout(function() {
alert("it's been 10 minutes now. Get back to work.");
close();
var body = document.getElementById('hide5')
body.style.display = 'none'
}, 300000);
}
setInterval(getOff, 300000)
}
</script>
<script>
function hide() {
var games = document.getElementById('games')
if (games.style.display === 'block')
games.style.display = 'none';
else {
games.style.display = 'block';
}
}
function show() {
var canvas = document.getElementById('my')
canvas.style.display = 'block';
}
</script>
<button onclick='hide()'> Hide or show the games</button>
<button onclick='PausePlay()'> Pause games </button>
<button onclick='playPong()'> Play pong </button>

how can I detect collision in a 2D tile game map

I made this basic game where I drew a map and a player, the player can move anywhere but how can I make so that it wont move when its on the tile[1] in the map?
also when I try to check if the player.x is greater than 50 it could go left it works but than if I click 2 keys at once it goes through
const context = document.querySelector("canvas").getContext("2d");
var rgb = 'rgb(' + Math.random()*256 + ',' + Math.random()*256 + ',' + Math.random()*256 + ','+Math.random() + ')';
document.onload = Loop();
var width = 1500;
var height = 800;
function Loop(){
var width = 1500;
var height = 800;
context.canvas.height = height;
context.canvas.width = width;
this.interval = setInterval(Update, 1000/100);
}
const Player = function(x, y, w, h, color) {
this.x = x; this.y = y; this.w = w; this.h = h;
this.speedY = 0; this.speedX = 0;
this.Draw = function(){
context.fillStyle = this.color;
context.fillRect(this.x, this.y, this.w, this.h);
};
this.Move = function(){
this.x += this.speedX;
this.y += this.speedY;
};
};<code>
var player = new Player(100,100,50, 50, rgb);
var Key = {};
function Update(){
context.clearRect(0, 0, width, height);
Map();
player.Draw();
player.Move();
onkeydown = onkeyup = function(e){
player.speedX = 0;
player.speedY = 0;
e = e || event;
Key[e.keyCode] = e.type == 'keydown';
if(Key[37] || Key[65]) {player.speedX -= 2}
if(Key[38] || Key[87]) {player.speedY -= 2}
if(Key[39] || Key[68]) {player.speedX += 2}
if(Key[40] || Key[83]) {player.speedY += 2}
if(Key[32]) {player.color = 'rgb(' + Math.random()*256 + ',' + Math.random()*256 + ',' + Math.random()*256 + ','+Math.random()*1 + ')';}
};
}
var map = [
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1
];
var row = 5;
var column = 5;
function Map(){
for(let y = -1; y < column; y++){
for(let x = -1; x < row; x++){
switch(map[((y*row) + x)]) {
case 0: context.fillStyle = player.color;
break;
case 1: context.fillStyle = "#ffffff";
break;
default: context.fillStyle = "#000000";
}
context.fillRect(x*50, y*50, 50, 50);
}
}
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
display: block;
margin: auto;
border: solid 1px white;
border-radius: 10px;
}
script {
display: none;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
void function() {
"use strict";
// Classes
function Camera(x,y) {
this.x = x || 0.0;
this.y = y || 0.0;
}
Camera.prototype = {
set: function(x,y) {
this.x = x || 0.0;
this.y = y || 0.0;
},
pan: function(x,y) {
this.x += x || 0.0;
this.y += y || 0.0;
}
};
var nextID = 0;
function Tile(colour) {
this.id = nextID++;
this.colour = colour || "black";
}
function Map(width,height) {
this.width = width || 1;
this.height = height || 1;
this.map = [];
this.map.length = this.height;
for (var y = 0; y < this.height; ++y) {
this.map[y] = [];
this.map[y].length = width;
for (var x = 0; x < this.width; ++x) {
this.map[y][x] = Math.random() < 0.2 ?
this.TILE_WALL:
this.TILE_GRASS;
}
this.map[y][0] = this.TILE_WALL;
this.map[y][this.width - 1] = this.TILE_WALL;
}
for (var x = 0; x < this.width; ++x) {
this.map[0][x] = this.TILE_WALL;
this.map[this.height - 1][x] = this.TILE_WALL;
}
}
Map.prototype = {
TILE_WIDTH: 32.0,
TILE_HEIGHT: 32.0,
INV_TILE_WIDTH: 0.0,
INV_TILE_HEIGHT: 0.0,
TILE_AIR: new Tile("#00000000"),
TILE_GRASS: new Tile("#00AA00FF"),
TILE_WALL: new Tile("#555555FF"),
set: function(x,y,tile) {
this.map[y][x] = tile;
},
scaleX: function(x) {
return (x * this.INV_TILE_WIDTH) | 0;
},
scaleY: function(y) {
return (y * this.INV_TILE_HEIGHT) | 0;
},
isColliding: function(x,y) {
return x > -1 && x < this.width
&& y > -1 && y < this.height
&& this.map[y][x].id > 1;
},
render: function(ctx,camera) {
for (var y = 0; y < this.height; ++y) {
for (var x = 0; x < this.width; ++x) {
var tile = this.map[y][x];
var _x = x * this.TILE_WIDTH - camera.x;
var _y = y * this.TILE_HEIGHT - camera.y;
ctx.fillStyle = tile.colour;
ctx.fillRect(_x,_y,this.TILE_WIDTH - 1,this.TILE_HEIGHT - 1);
}
}
}
};
Map.prototype.INV_TILE_WIDTH = 1.0 / Map.prototype.TILE_WIDTH;
Map.prototype.INV_TILE_HEIGHT = 1.0 / Map.prototype.TILE_HEIGHT;
function Player(x,y) {
this.x = x || 0.0;
this.y = y || 0.0;
this.dx = 0.0;
this.dy = 0.0;
this.isUp = false;
this.isDown = false;
this.isLeft = false;
this.isRight = false;
}
Player.prototype = {
WIDTH: 20.0,
HEIGHT: 20.0,
ACCELERATION: 1.0,
DEACCELERATION: 0.5,
MAX_SPEED: 3.0,
tick: function(map) {
// Movement
if (this.isUp) {
this.dy -= this.ACCELERATION;
if (this.dy < -this.MAX_SPEED) {
this.dy = -this.MAX_SPEED;
}
} else if (this.dy < 0.0) {
this.dy += this.DEACCELERATION;
if (this.dy > 0.0) {
this.dy = 0.0;
}
}
if (this.isDown) {
this.dy += this.ACCELERATION;
if (this.dy > this.MAX_SPEED) {
this.dy = this.MAX_SPEED;
}
} else if (this.dy > 0.0) {
this.dy -= this.DEACCELERATION;
if (this.dy < 0.0) {
this.dy = 0.0;
}
}
if (this.isLeft) {
this.dx -= this.ACCELERATION;
if (this.dx < -this.MAX_SPEED) {
this.dx = -this.MAX_SPEED;
}
} else if (this.dx < 0.0) {
this.dx += this.DEACCELERATION;
if (this.dx > 0.0) {
this.dx = 0.0;
}
}
if (this.isRight) {
this.dx += this.ACCELERATION;
if (this.dx > this.MAX_SPEED) {
this.dx = this.MAX_SPEED;
}
} else if (this.dx > 0.0) {
this.dx -= this.DEACCELERATION;
if (this.dx < 0.0) {
this.dx = 0.0;
}
}
// Collision
if (this.dx !== 0.0) {
var minY = map.scaleY(this.y);
var maxY = map.scaleY(this.y + this.HEIGHT);
var minX = 0;
var maxX = 0;
if (this.dx < 0.0) {
minX = map.scaleX(this.x + this.dx);
maxX = map.scaleX(this.x);
} else {
minX = map.scaleX(this.x + this.WIDTH);
maxX = map.scaleX(this.x + this.WIDTH + this.dx);
}
loop:
for (var y = minY; y <= maxY; ++y) {
for (var x = minX; x <= maxX; ++x) {
if (map.isColliding(x,y)) {
this.x = this.dx < 0.0 ?
(x + 1) * map.TILE_WIDTH:
x * map.TILE_WIDTH - this.WIDTH - 1;
this.dx = 0.0;
break loop;
}
}
}
}
if (this.dy !== 0.0) {
var minX = map.scaleX(this.x);
var maxX = map.scaleX(this.x + this.WIDTH);
var minY = 0;
var maxY = 0;
if (this.dy < 0.0) {
minY = map.scaleY(this.y + this.dy);
maxY = map.scaleY(this.y);
} else {
minY = map.scaleY(this.y + this.HEIGHT);
maxY = map.scaleY(this.y + this.HEIGHT + this.dy);
}
loop:
for (var y = minY; y <= maxY; ++y) {
for (var x = minX; x <= maxX; ++x) {
if (map.isColliding(x,y)) {
this.y = this.dy < 0.0 ?
(y + 1) * map.TILE_HEIGHT:
y * map.TILE_HEIGHT - this.HEIGHT - 1;
this.dy = 0.0;
break loop;
}
}
}
}
this.x += this.dx;
this.y += this.dy;
},
render: function(ctx,camera) {
camera.set(this.x,this.y);
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
ctx.fillStyle = "darkred";
ctx.beginPath();
ctx.rect(this.x - camera.x,this.y - camera.y,this.WIDTH,this.HEIGHT);
ctx.fill();
ctx.stroke();
}
};
// Variables
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var ctx = null;
var camera = null;
var map = null;
var player = null;
// Functions
function onKeyDown(e) {
switch(e.key.toUpperCase()) {
case "W": player.isUp = true; break;
case "S": player.isDown = true; break;
case "A": player.isLeft = true; break;
case "D": player.isRight = true; break;
}
}
function onKeyUp(e) {
switch(e.key.toUpperCase()) {
case "W": player.isUp = false; break;
case "S": player.isDown = false; break;
case "A": player.isLeft = false; break;
case "D": player.isRight = false; break;
}
}
function loop() {
// Tick
player.tick(map);
// Render
ctx.fillStyle = "gray";
ctx.fillRect(-canvasWidth >> 1,-canvasHeight >> 1,canvasWidth,canvasHeight);
map.render(ctx,camera);
player.render(ctx,camera);
//
requestAnimationFrame(loop);
}
// Entry point (first to execute)
onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
ctx.translate(canvasWidth >> 1,canvasHeight >> 1);
camera = new Camera(0.0,0.0);
map = new Map(10,10);
player = new Player(40.0,40.0);
map.set(1,1,map.TILE_GRASS);
addEventListener("keydown",onKeyDown);
addEventListener("keyup",onKeyUp);
loop();
}
}();
</script>
</body>
</html>
Firstly, looking at your code, there are some things that are missing which is required to implement basic collision detection and those are:
The player's current direction that he/she is moving in. This is important because it allows the function determining the collision detection to distinguish which side it is checking for the collision (Up, down, left, or right) since a player can only collide with one side at a time.
The tile's position and size. This is also very important because like the first point, there is only one side of the tile that the player can collide with and knowing the size and position can determine if it is a collision or not based on the players size and position.
Also, since you mentioned it is a basic game, the implementation below is a basic collision detection. If you were to make a more complex and bigger game, you should try looking into quad trees for more efficient collision detection:
https://gamedevelopment.tutsplus.com/tutorials/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space--gamedev-374
Now this is the function for detecting collision, for the sake of readability and shortness, p will represent the player object and t would represent the tile object. This function returns whether or not the player is colliding with a tile based on their direction of movement.
function isColliding(p, t){
if (p.direction == 'up') {
return p.y +(p.height/2)-p.speedY< t.y + t.height && p.y > t.y
&& p.x + p.width > t.x && p.x < t.x + t.width;
}
if (p.direction == 'down') {
return p.y + (p.height/2)+p.speedY > t.y && p.y < t.y
&& p.x + p.width > t.x && p.x < t.x + t.width;
}
if (p.direction == 'right') {
return p.x + p.width+p.speedX > t.x && p.x < t.x
&& p.y +(p.height/2)> t.y && p.y + p.height < t.y +t.height+ (p.height / 2);
}
if (p.direction == 'left') {
return p.x -p.speedX< t.x + t.width && p.x > t.x
&& p.y +(p.height/2)> t.y && p.y + p.height < t.y +t.height+ (p.height / 2);
}
return false;
}
You would probably want to put this in the player move function to constantly detect for tiles as it is moving. To do that, you'd want to modify your keydown detection so that with each different keydown, it would update the player's direction, here's a simple example:
document.onkeydown = function(event){
if (event.keyCode == 87)
player.up = true;
else if (event.keyCode == 65)
player.left = true;
else if (event.keyCode == 83)
player.down = true;
else if (event.keyCode == 68)
player.right = true;
}
and another simple example for every time the player moves (user presses a keydown):
const Player= function(/*Param stuff*/){
/*Property stuff*/
//tileArray is the array (or object, your choice) of all the current tiles in the map
this.move=function(tileArray){
//Go through all tiles to see if player is colliding with any of them
for(var t in tileArray){
if(this.up){
if(isColliding(this, tileArray[t]){
//functionality for when player collides
}else{
//functionality for when player doesn't collide
}
}
//check if player is going down, left, etc
}
}
}
These are just examples of how to implement the detection. You should use it as a reference to implement it relatively to how your code function because I didn't write it based on what you posted.
PS.
Make sure to also convert the directions to false after the user stops pressing the key.

Pong game my ball keep going above colisions

i have a simple pong game where i can shot the ball and check for colisions at the moment. I had the colisions with X and Y working, but since i added angles to the ball trajectory the colisions at X coordinate sometimes fail, dunno why. So this is what i have at the moment, the colisions checking is handled by the ballMovementHandler function.
var canvas;
var ctx;
var player;
var ball;
var gameStarted;
var flagY;
var flagX;
var angle;
function init() {
canvas = document.getElementById('myCanvas')
if (canvas.getContext) {
ctx = canvas.getContext('2d')
setCanvasSize(ctx)
player = new Player()
ball = new Ball()
attachKeyboardListeners()
reset();
animate();
}
}
function reset() {
flagX = -1;
flagY = -1;
angle = 90;
gameStarted = false
player = new Player();
ball = new Ball();
}
function animate () {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawIce()
player.drawPlayer();
ball.drawBall();
playerMovementeHandler()
if(gameStarted) {
ballMovementHandler();
}
window.requestAnimationFrame(animate);
}
function playerMovementeHandler() {
if(player.left === true) {
if(player.x > 0) {
player.movePlayer(-SPEED);
if(!gameStarted) {
ball.moveBallWithPlayer(-SPEED);
}
}
}
if(player.right === true) {
if(player.x + player.width < ctx.canvas.width) {
player.movePlayer(SPEED);
if(!gameStarted) {
ball.moveBallWithPlayer(SPEED);
}
}
}
}
function ballMovementHandler() {
if(ball.y - ball.radius <= 0) {
flagY = 1;
}
if(ball.y + ball.radius === player.y) {
if(ball.x + ball.radius >= player.x && ball.x < player.x + player.width) {
angle = playerAngleHandler()
flagY = -1;
}
else {
reset();
}
}
if(ball.x - ball.radius <= 0) {
flagX = 1;
}
if(ball.x + ball.radius >= ctx.canvas.width) {
flagX = -1;
}
radians = angle * Math.PI/ 180;
ball.moveBallY(Math.sin(radians) * ball.speed * flagY);
ball.moveBallX(Math.cos(radians) * ball.speed * flagX);
}
function playerAngleHandler() {
var angle = 90;
if(ball.x + ball.radius <= player.x + 25) {
angle = 35;
} else if(ball.x + ball.radius >= player.x + player.width - 25) {
angle = 135;
} else if(ball.x + ball.radius >= player.x + player.width - 50) {
angle = 120
} else if(ball.x + ball.radius <= player.x + 50 ) {
angle = 50;
} else if(ball.x + ball.radius <= player.x + 75) {
angle = 75;
} else if( ball.x + ball.radius >= player.x + player.width - 75 ) {
angle = 100;
}
return angle;
}
function drawIce() {
ctx.fillStyle = 'rgb(134,214,216)'
ctx.fillRect(0,ctx.canvas.height - Y_OFFSET + player.height + 10, ctx.canvas.width, Y_OFFSET)
}
function setCanvasSize() {
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
}
function keyboardEvent(keyCode, keyStatus) {
switch(keyCode) {
case 37:
player.left = keyStatus;
break;
case 39:
player.right = keyStatus;
break;
case 32:
gameStarted = true;
break;
}
}
function attachKeyboardListeners() {
document.addEventListener('keydown', function(e) {
keyboardEvent(e.keyCode, true)
})
document.addEventListener('keyup', function(e) {
keyboardEvent(e.keyCode, false)
})
}
init();
ball.js
// defines player configuration behaviour
const BALL_POSITION_Y = 100;
const RADIUS = 12;
const BALL_SPEED = 10;
function Ball(x = ctx.canvas.width/2, y = ctx.canvas.height - Y_OFFSET - RADIUS, radius = RADIUS, color = 'rgb(100,149,237)', speed = BALL_SPEED) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.speed = speed;
this.drawBall = function() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
ctx.fill();
}
// for inital game started
this.moveBallWithPlayer = function(deltaX) {
this.x += deltaX;
}
this.moveBallY = function(flag) {
this.y = this.y + flag;
}
this.moveBallX = function(flag) {
this.x = this.x + flag;
}
}
player.js
// defines player configuration behaviour
const PLAYER_WIDTH = 200;
const Y_OFFSET = 100;
const PLAYER_HEIGHT = 30;
const SPEED = 6;
function Player(x = ctx.canvas.width/2 - PLAYER_WIDTH/2, y = ctx.canvas.height - Y_OFFSET, width = PLAYER_WIDTH, height = PLAYER_HEIGHT, color = 'rgba(0,0,0)') {
this.left = false;
this.right = false;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.movePlayer = function(deltaX) {
this.x += deltaX;
}
this.drawPlayer = function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}

breakout collision detection

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>
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>
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>

Categories

Resources