不了解addEventListener行为

时间:2018-12-01 18:57:10

标签: javascript

我已经用JavaScript编写了这段代码:

window.onload = function() {
  var keyboard = new Keyboard();

  var gameCanvas = document.getElementById("gameCanvas").getContext("2d");
  var player = new Player(gameCanvas, keyboard);
  player.Init();

  setInterval(function() {
    gameCanvas.clearRect(0, 0, 1200, 300);
    player.Update();
  }, 20);
}

class Player {
  constructor(canvas, keyboard) {
    this._canvas = canvas;
    this._keyboard = keyboard;
    this._x = 100;
    this._y = 75;
    this._dx = 1;
    this.dy = 1;
  }

  Init() {
    this.Draw();
  }


  Update() {
    if (this._keyboard.GetIsArrowLeftDown())
      this._x -= this._dx;
    if (this._keyboard.GetIsArrowRightDown())
      this._x += this._dx;
    if (this._keyboard.GetIsArrowUpDown())
      this._y -= this._dy;
    if (this._keyboard.GetIsArrowDownDown())
      this._y += this._dy;

    this.Draw();
  }

  Draw() {
    this._canvas.beginPath();
    this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
    this._canvas.closePath();
    this._canvas.strokeStyle = "black";
    this._canvas.stroke();
    this._canvas.beginPath();
    this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
    this._canvas.closePath();
    this._canvas.fillStyle = "red";
    this._canvas.fill();
  }
}

class Keyboard {
  constructor() {
    this.isArrowLeftDown = false;
    this.isArrowRightDown = false;
    this.isArrowUpDown = false;
    this.isArrowDownDown = false;

    window.addEventListener("keyup", keyboard.OnKeyUpEvent);
    window.addEventListener("keydown", keyboard.OnKeyDownEvent);
  }

  OnKeyUpEvent(event) {
    if (event.defaultPrevented) {
      return;
    }

    var key = event.key || event.keyCode;

    if (key == "ArrowLeft")
      this.isArrowLeftDown = false;
    if (key == "ArrowRight")
      this.isArrowRightDown = false;
    if (key == "ArrowUp")
      this.isArrowUpDown = false;
    if (key == "ArrowDown")
      this.isArrowDownDown = false;
  }

  OnKeyDownEvent(event) {
    if (event.defaultPrevented) {
      return;
    }

    var key = event.key || event.keyCode;

    if (key == "ArrowLeft")
      this.isArrowLeftDown = true;
    if (key == "ArrowRight")
      this.isArrowRightDown = true;
    if (key == "ArrowUp")
      this.isArrowUpDown = true;
    if (key == "ArrowDown")
      this.isArrowDownDown = true;
  }

  GetIsArrowLeftDown() {
    return this.isArrowLeftDown;
  }

  GetIsArrowRightDown() {
    return this.isArrowRightDown;
  }

  GetIsArrowUpDown() {
    return this.isArrowUpDown;
  }

  GetIsArrowDownDown() {
    return this.isArrowDownDown;
  }
}

我有一个Keyboard对象,它可以记住用户按下的键。

Player是吸引自己的对象。

我希望当我向左按下时,图形会移到屏幕的左侧。但是它没有按预期工作。

当我被keyboard对象读取时,我的player对象似乎没有好的属性值。

我想念什么?

1 个答案:

答案 0 :(得分:2)

一些问题:

  • Player构造函数中,您将1分配给dy属性,但稍后将其引用为_dy,因此应在此处添加下划线。

  • Keyboard构造函数中,您使用keyboard,但这是未定义的;您打算this

  • 在这些相同的行中,您传递对OnKeyUpEventOnKeyDownEvent方法的引用。但是,在调用它们时,它们不会传递this的当前值,因此您应该bind(this)才能实现。

这是更正的代码:

window.onload = function() {
  var keyboard = new Keyboard();

  var gameCanvas = document.getElementById("gameCanvas").getContext("2d");
  var player = new Player(gameCanvas, keyboard);
  player.Init();

  setInterval(function() {
    gameCanvas.clearRect(0, 0, 1200, 300);
    player.Update();
  }, 20);
}

class Player {
  constructor(canvas, keyboard) {
    this._canvas = canvas;
    this._keyboard = keyboard;
    this._x = 100;
    this._y = 75;
    this._dx = 1;
    this._dy = 1; /// add the underscore
  }

  Init() {
    this.Draw();
  }


  Update() {
    if (this._keyboard.GetIsArrowLeftDown())
      this._x -= this._dx;
    if (this._keyboard.GetIsArrowRightDown())
      this._x += this._dx;
    if (this._keyboard.GetIsArrowUpDown())
      this._y -= this._dy;
    if (this._keyboard.GetIsArrowDownDown())
      this._y += this._dy;

    this.Draw();
  }

  Draw() {
    this._canvas.beginPath();
    this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
    this._canvas.closePath();
    this._canvas.strokeStyle = "black";
    this._canvas.stroke();
    this._canvas.beginPath();
    this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
    this._canvas.closePath();
    this._canvas.fillStyle = "red";
    this._canvas.fill();
  }
}

class Keyboard {
  constructor() {
    this.isArrowLeftDown = false;
    this.isArrowRightDown = false;
    this.isArrowUpDown = false;
    this.isArrowDownDown = false;

    window.addEventListener("keyup", this.OnKeyUpEvent.bind(this)); // use this and bind
    window.addEventListener("keydown", this.OnKeyDownEvent.bind(this));
  }

  OnKeyUpEvent(event) {
    if (event.defaultPrevented) {
      return;
    }

    var key = event.key || event.keyCode;

    if (key == "ArrowLeft")
      this.isArrowLeftDown = false;
    if (key == "ArrowRight")
      this.isArrowRightDown = false;
    if (key == "ArrowUp")
      this.isArrowUpDown = false;
    if (key == "ArrowDown")
      this.isArrowDownDown = false;
  }

  OnKeyDownEvent(event) {
    if (event.defaultPrevented) {
      return;
    }

    var key = event.key || event.keyCode;

    if (key == "ArrowLeft")
      this.isArrowLeftDown = true;
    if (key == "ArrowRight")
      this.isArrowRightDown = true;
    if (key == "ArrowUp")
      this.isArrowUpDown = true;
    if (key == "ArrowDown")
      this.isArrowDownDown = true;
  }

  GetIsArrowLeftDown() {
    return this.isArrowLeftDown;
  }

  GetIsArrowRightDown() {
    return this.isArrowRightDown;
  }

  GetIsArrowUpDown() {
    return this.isArrowUpDown;
  }

  GetIsArrowDownDown() {
    return this.isArrowDownDown;
  }
}
<canvas id="gameCanvas"></canvas>

注意:您可以检测到此类错误,因为它们已在控制台中报告。