I'm currently learning some JavaScript for my web and I'm building a simple pong game. This is my main file (a canvas with its context, 4 objects that make the game and an animation function to update and draw them):
const canvas = document.getElementById("game_canvas");
const ctx = canvas.getContext("2d");
canvas.width = 600;
canvas.height = canvas.width/2;
const table = new Table(canvas.width, canvas.height);
const ball = new Ball(canvas.width/2, canvas.height/2, canvas.width/200);
const pad1 = new Pad( canvas.width/20, canvas.height/2, canvas.width/100, canvas.height/5, true);
const pad2 = new Pad(canvas.width*19/20, canvas.height/2, canvas.width/100, canvas.height/5);
animate();
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
result = ball.update(canvas.width, canvas.height, pad1, pad2);
pad1.update(canvas.height);
pad2.update(canvas.height);
ball.draw(ctx);
pad1.draw(ctx);
pad2.draw(ctx);
table.draw(ctx);
requestID = requestAnimationFrame(animate);
switch (result) {
case 1:
cancelAnimationFrame(requestID);
confirm("You lost!");
break;
case 2:
cancelAnimationFrame(requestID);
confirm("You won!");
break;
}
}
This works perfectly. The problem comes because I would like to let the player star over when the game ends, my solution is to put all of the definitions inside a function star_game()
and pass the objects as arguments to the animate function:
start_game();
function start_game() {
const canvas = document.getElementById("game_canvas");
const ctx = canvas.getContext("2d");
canvas.width = 600;
canvas.height = canvas.width/2;
const table = new Table(canvas.width, canvas.height);
const ball = new Ball(canvas.width/2, canvas.height/2, canvas.width/200);
const pad1 = new Pad( canvas.width/20, canvas.height/2, canvas.width/100, canvas.height/5, true);
const pad2 = new Pad(canvas.width*19/20, canvas.height/2, canvas.width/100, canvas.height/5);
animate(canvas, ctx, table, ball, pad1, pad2);
}
function animate(canvas, ctx, table, ball, pad1, pad2) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
result = ball.update(canvas.width, canvas.height, pad1, pad2);
pad1.update(canvas.height);
pad2.update(canvas.height);
ball.draw(ctx);
pad1.draw(ctx);
pad2.draw(ctx);
table.draw(ctx);
requestID = requestAnimationFrame(animate);
switch (result) {
case 1:
cancelAnimationFrame(requestID);
var again = confirm("You lost, play again?");
break;
case 2:
cancelAnimationFrame(requestID);
var again = confirm("You won, play again?");
break;
}
if (again) start_game();
}
Now, for some reason I do not understand, I get this error:
Uncaught TypeError: Cannot read properties of undefined (reading 'clearRect') at animate
And this happens with all of the objects.
I tried logging the ctx object in the console at the begining of the animate()
function and something even weirder happens, the object is printed as normal and then as undefined:
What's going on?
CodePudding user response:
I don't see you passing any arguments to animate here:
requestAnimationFrame(animate)
You meant:
requestAnimationFrame(() => animate(canvas, ctx, table, ball, pad1, pad2))