"TypeError: Cannot read property 'cvs' of undefined" of a `this` statement in a class when it is initialized

63 views Asked by At

So, I have the class "genGameObject" which, as it states, is used to generate a Game Object, and then draw content inside that gameObject.

I thought it would be a spelling mistake or something small, but I cant find anything (If someone sees something, PLEASE tell me, I am mostly blind so I could've missed it.)

Its saying that the this.cvs at line 11 (this.cvs.width = 400;) is undefined and I cant read it. (well more like its saying "this" is undefined, and I cant call a property of an undefined object. Its a class, how is the "this" undefined?)

So, I have the current code:

(I tried making a Minimal Reproducible example but it caused a different error similar to this one that just didnt make sense)

class genGameObject {
  // Constructor, obviously
  constructor(sel) {
    this.cvs = document.querySelector(sel) || canvas;
    this.ctx = this.cvs.getContext("2d");
    this.gameState = "unStarted";
  }

  // Main Game Initialization
  gameLoop() {
    this.cvs.width = 400;
    this.cvs.height = 400;

    this.ctx.fillStyle = "#64004C";
    this.ctx.fillRect(0, 0, this.cvs.width, this.cvs.height);

    this.drawMap();
    this.drawPlayer();

    window.requestAnimationFrame(this.gameLoop);
  }

  // Draw Map
  loadMapData(arr) {
    this.mapLoaded = JSON.parse(arr);
  }

  drawMap() {

  }

  // Draw Coins / Entities / Powerups

  // Draw Physics Simulations

  // Draw Player
  drawPlayer() {
    if (this.gameState == "unStarted") {
      this.playerX = this.mapLoaded.player.x;
      this.playerY = this.mapLoaded.player.y;
    } else {
      this.ctx.beginPath();
      this.ctx.fillStyle = "#D41E3C";
      this.ctx.arc(this.playerX, this.playerY, 20, 0, 2 * Math.PI);
      this.ctx.fill();
    }
  }
}

const gCont = new genGameObject(".gameObject");

const mapArray = {
  player: {
    x: "10",
    y: "10"
  },
  coins: [

  ]
};

gCont.loadMapData(JSON.stringify(mapArray));

gCont.gameLoop();
.gameObject {
  box-sizing: border-box;
  border: 1px solid black;
}
<link rel="stylesheet" href="rsc/index.css">

<canvas class="gameObject"></canvas>

<script src="rsc/index.js"></script>

1

There are 1 answers

0
Mister SirCode On

Not a Javascript specialist, but I don't see how window.requestAnimationFrame(this.gameLoop); would pass "this" to gameLoop

Also got some info from: How to use requestAnimationFrame inside a Class object

After that comment from Mat, I figured out that the this statement scope of my requestAnimationFrame was incorrect.

I've been scoping it with this.gameLoop as to call the loop itself, completely ignoring that I havent been binding this back into itself.

so..

window.requestAnimationFrame(this.gameLoop.bind(this));

Should go into the class