对象

时间:2018-08-21 23:15:16

标签: javascript html canvas

我有点困惑。因此,我在JS,HTML5 canvas和Firebase中构建了JavaScript游戏。我遇到的奇怪的事情是,当我玩游戏时,因为它将信息发送到后端没有问题。但是,如果刷新,就好像以前的分数仍然存在,因此当信息发送时,它会发送两次。如果我再次刷新,则为3倍等。在图像中,您可以看到以前的回合中存在名称和得分。

Backend showing repetition

发送信息的代码块是

  showInput() {
    document.getElementById("inputName").type = "text";
    document.getElementById("inputName").addEventListener("keyup", e => {
      e.preventDefault();
      if (e.keyCode === 13) {
        const scores = firebase.database().ref("scores/");
        let name = document.getElementById("inputName").value;
        let score = this.score;
        let highScore = { name, score };
        scores.push(highScore);

        document.getElementById("inputName").type = "hidden";
        this.showLeaderBoard();
      }
    });
  }

但这很奇怪,因为创建了新游戏。例如,其中的信息表示分数this.score = 0并表明了这一点。有人可以解释为什么以前的分数仍然存在吗?

感谢您的所有帮助和解释。

**删除监听器**

  showInput() {
    document.getElementById("inputName").type = "text";
    document.getElementById("inputName").addEventListener("keyup", e => {
      console.log("event added");
      e.preventDefault();
      if (e.keyCode === 13) {
        const scores = firebase.database().ref("scores/");
        let name = document.getElementById("inputName").value;
        let score = this.score;
        let highScore = { name, score };
        scores.push(highScore);

        document.getElementById("inputName").type = "hidden";
        this.showLeaderBoard();
      }
    });

    document.getElementById("inputName").removeEventListener("keyup", e => {
      console.log("event removed");
      e.preventDefault();
      if (e.keyCode === 13) {
        const scores = firebase.database().ref("scores/");
        let name = document.getElementById("inputName").value;
        let score = this.score;
        let highScore = { name, score };
        scores.push(highScore);

        document.getElementById("inputName").type = "hidden";
        this.showLeaderBoard();
      }
    });
  }

**重置功能**

    const Game = require("./game");
const Background = require("./background");
var GameInstance = null;

document.addEventListener("DOMContentLoaded", () => {
  let preGame = () => {
    const canvasStart = document.getElementById("start");
    if (canvasStart.getContext) {
      const ctxStart = canvasStart.getContext("2d");

      ctxStart.font = "30px games";
      ctxStart.fillStyle = "red";
      ctxStart.fillText(
        "Press R to Start!",
        canvasStart.width / 2 - 110,
        canvasStart.height / 2
      );
    }
  };

  document.getElementById("inputName").addEventListener("keyup", e => {
    e.preventDefault();
    if (e.keyCode === 13 && GameInstance) {
      const scores = firebase.database().ref("scores/");
      let name = document.getElementById("inputName").value;
      let score = GameInstance.score;
      let highScore = { name, score };
      scores.push(highScore);

      document.getElementById("inputName").type = "hidden";
      GameInstance.showLeaderBoard();
    }
  });

  preGame();
  document.addEventListener("keypress", e => {
    if (
      e.key === "r" &&
      document.getElementById("inputName").type === "hidden"
    ) {
      let score = 0;
      const canvasStart = document.getElementById("start");
      if (canvasStart.getContext) {
        const ctxStart = canvasStart.getContext("2d");
        ctxStart.clearRect(0, 0, canvasStart.width, canvasStart.height);
      }
      const canvas = document.getElementById("canvas");
      const canvasEnemy = document.getElementById("enemy");
      const canvasScore = document.getElementById("scoreBoard");
      const canvasGameOver = document.getElementById("gameOver");
      if (canvas.getContext) {
        const ctx = canvas.getContext("2d");
        const ctxEnemy = canvasEnemy.getContext("2d");
        const ctxScore = canvasScore.getContext("2d");
        const ctxGameOver = canvasGameOver.getContext("2d");
        GameInstance = new Game(
          ctx,
          canvas,
          ctxEnemy,
          canvasEnemy,
          ctxScore,
          canvasScore,
          ctxGameOver,
          canvasGameOver,
          score
        ).start();
      }
    }
  });

1 个答案:

答案 0 :(得分:0)

您的代码需要稍作重构,因为它现在正在引起一些非常严重的问题:

  • 游戏的每个实例都会为输入创建自己的事件监听器。每个新实例都会发送越来越多的请求。
  • 您认为已销毁的实例仍然有效。它们被困在多个事件侦听器创建的闭包中。那是一次重大的内存泄漏。

showInput函数中删除事件侦听器。只定义一次。它应该只检查当前游戏实例,并在输入发生时将其分数发送到服务器:

var gameInstance = null;

document.getElementById("inputName").addEventListener("keyup", function(e) {
  e.preventDefault();
  if (e.keyCode === 13 && gameInstance) {                             // check if there is a game instance
    const scores = firebase.database().ref("scores/");
    let name = this.value;                                            // this is the input now
    let score = gameInstance.score;                                   // use gameInstance
    let highScore = { name, score };
    scores.push(highScore);

    this.type = "hidden";                                             // here too
    gameInstance.showLeaderBoard();                                   // ...
  }
});

document.addEventListener("keypress", e => {
  // ...
  gameInstance = new Game(/* ... */);                                 // don't forget to store the gameInstance so the event listener will have access to it
  // ...
});

showInput应该看起来像这样:

showInput() {
  document.getElementById("inputName").type = "text";
}

这只是按原样显示输入。