繁体   English   中英

context.clearRect() 没有按预期工作

[英]context.clearRect() doesn't work as expected

所以我这里有一个迷宫,当用户在迷宫中更改 rowNum/colNum 时就会出现问题。 当用户更改其中任何一个时,它会调用

ctx.clearRect(0, 0, canvas.width, canvas.height)

这清除了整个 canvas 但是当用户再次开始移动播放器时,之前清除的播放器 canvas 出现在此 canvas 中。 看这里

clearRect()清除了 canvas 但我不知道为什么player仍然留在那里与之交互。

代码框链接

这是我的代码为绘制player所做的简短描述 -

main.js

let customGrid = document.querySelector("#rows,#columns");

customGrid.forEach(elem =>  elem.addEventListener("change", e => {

    // detect changed element
    if (e.target.id === "row")
        customGrid[0].value = parseInt(e.target.value);
    else
        customGrid[1].value = parseInt(e.target.value);

    ctx.clearRect(0, 0, canvas.width, canvas.width);

    // setting myMaze to new instance of Maze
    myMaze = new Maze(ctx, 600, customGrid[0].value, customGrid[1].value);
    myMaze.setup();
    myMaze.drawMap();
    })
);

接下来, myMaze.drawMap()包含 -

//set player
this.player = new Player(this.ctx, this.goal, this.cellWidth, this.cellHeight);
this.player.setPlayer(this);

从这里setPlayer调用-

setPlayer(myMaze) {
    ....
    this.drawPlayer();
    this.listenMoves(myMaze);
}
listenMoves(myMaze) {
    window.addEventListener("keydown", function handler(e) {
        myMaze.player.move(e.keyCode, myMaze);

        let reachedCol = myMaze.player.colNum === myMaze.goal.colNum ? true : false;
        let reachedRow = myMaze.player.rowNum === myMaze.goal.rowNum ? true : false;

        if (reachedRow && reachedCol) {
            alert("reached!");
            window.removeEventListener("keydown", handler);
        }
    });
}
move(input, myMaze) {

    let current = myMaze.grid[this.rowNum][this.colNum];
    let walls = current.walls;

    switch(input) {

        case 37:
            if(!walls.leftWall) {
                this.colNum -= 1;  
            } break;

        case 38:
            if(!walls.topWall)  {
                this.rowNum -= 1;  
            } break;
            
        case 39:
            if(!walls.rightWall)  {
                this.colNum += 1;  
            } break;

        case 40:
            if(!walls.bottomWall)   {
                this.rowNum += 1;
            }
    }
        
    this.ctx.clearRect(current.xCord, current.yCord, current.width, current.height);
    current.drawCell();
    this.drawPlayer();
}

我会将事件侦听器移至main.js 由于 Maze 有提到 Player,所以应该可以。 我假设你有一个迷宫的全局变量( myMaze )。

let myMaze;
let reched = false;

window.addEventListener("keydown", function handler(e) {
  if (!myMaze || reched) {
    return;
  }

  myMaze.player.move(e.keyCode, myMaze);
  myMaze.player.handleMove();

  let reachedCol = myMaze.player.colNum === myMaze.goal.colNum ? true : false;
  let reachedRow = myMaze.player.rowNum === myMaze.goal.rowNum ? true : false;

  if (reachedRow && reachedCol) {
    alert("reached!");
    reched = true;
  }
});

如果您想将事件处理程序保留为 Player 的方法,您可以执行以下操作。 并在网格大小发生变化时调用unListenMoves()

class Player {
  constructor(ctx, goal, cellWidth, cellHeight, myMaze) {
    // keep the Maze instance as a Player's prop for the later use
    this.myMaze = myMaze;

    // we need to bind this here, not in listenMoves
    this.handleMove = this.handleMove.bind(this);
  }

  listenMoves() {
    window.addEventListener("keydown", this.handleMove);
  }

  unListenMoves() {
    window.removeEventListener("keydown", this.handleMove);
  }

  handleMove(e) {
    const myMaze = this.myMaze;
    myMaze.player.move(e.keyCode, myMaze);

    let reachedCol = myMaze.player.colNum === myMaze.goal.colNum ? true : false;
    let reachedRow = myMaze.player.rowNum === myMaze.goal.rowNum ? true : false;

    if (reachedRow && reachedCol) {
      alert("reached!");
      window.removeEventListener("keydown", this.handleMove);
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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