简体   繁体   中英

Resetting a class parameter upon new instance of that class: JS ES6

I am working on creating a game that redraws the canvas every time the player goes to a new "room". While most of the functionality is there, I am having some trouble with the player... although the rest of my room-drawing class Room gets reset and reinitialized with no reference to the previous room, the player square carries across to the next screen and stays in the same place.

My User class:

class User {
   constructor(user, x, y, ctx) {
     for (let metric in user) { this[metric] = user[metric]; }
     this.initialX = x;
     this.initialY = y;
     this.ctx = ctx;
     this.move = this.move.bind(this);
     //// various other constructor things...
   }
   //// various other methods
   move(e) {
      //// motion description
      if (this.y - 5 <= 0 {
          init(theRoom.connectingRooms[0], this.x, 550) ///// should create a new box at the last player-x position and y-position 550
          }
       }
    }

My Room class:

class Room {
    constructor(canv, room, player) {
    for (let key in canv) { this[key] = canv[key]; }
    for (let attr in room) { this[attr] = room[attr]; } 
    this.drawWalls();
    this.player = player; /// adding player to room
  } /// end of constructor
////methods, nothing that affects player
}

Initializer:

let init = function init(room, x, y) {
  canv = document.getElementById('canvas');
  canvas = new CanvasState(canv); 
  player = new User(user, x, y, canvas.ctx); //// it's remembering the last player I set instead of removing the old one & creating a new one
  theRoom = new Room(canvas, room, player);
  window.addEventListener('keydown', theRoom.player.move);
  window.addEventListener('keyup', theRoom.typeInput);
};

You can see this on CodePen here . The relevant lines are 10, 53, 185, & 232.

I'm pretty new to JS and very new to the canvas element, so I'm sure I'm making a rookie mistake in here somewhere, but I can't seem to spot it.

Before overwriting the player variable with the new one, you need to remove the key handlers from window . Those are still referencing the methods of the old player object, which consequently is drawn every time you move it.

You can use

function init(room, x, y) {
  canv = document.getElementById('canvas');
  canvas = new CanvasState(canv);

  if (player != null)
    window.removeEventListener('keydown', player.move);
  player = new User(user, x, y, canvas.ctx);
  window.addEventListener('keydown', player.move);

  if (theRoom != null)
    window.removeEventListener('keyup', theRoom.typeInput);
  theRoom = new Room(canvas, room, player);
  window.addEventListener('keyup', theRoom.typeInput);
}

Another approach would be to register only one callback that invokes the respective method of the current object (so that you don't need to .bind them as well):

function init(room, x, y) {
  canv = document.getElementById('canvas');
  canvas = new CanvasState(canv);
  player = new User(user, x, y, canvas.ctx);
  theRoom = new Room(canvas, room, player);
}

window.onload = function() {
  init(castleCourtyard, 350, 100);
  window.addEventListener('keyup', e => theRoom.typeInput(e));
  window.addEventListener('keydown', e => player.move(e));
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM