簡體   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