Home > Enterprise >  Object turns into undefined when passed to function as argument and method is called JavaScript
Object turns into undefined when passed to function as argument and method is called JavaScript

Time:09-23

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:

logged ctx object followed by 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))
  • Related