2017-04-02 45 views
1

默認情況下,我的畫布的矩形應從左向右移動。當按下鍵時,它應該開始向下移動。畫布:按下按鍵時的奇怪行爲

var canvas = document.getElementById('canvas'), 
 
    ctx = canvas.getContext('2d'), 
 
    x = 0, 
 
    y = 0; 
 

 
function draw(x_move, y_move) { 
 
    requestAnimationFrame(function() { 
 
    draw(x_move, y_move); 
 
    }); 
 
    ctx.beginPath(); 
 
    ctx.rect(x, y, 20, 20); 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
    ctx.fillStyle = "#ffffff"; 
 
    ctx.fill(); 
 
    ctx.closePath(); 
 
    x = x + x_move; 
 
    y = y + y_move; 
 
} 
 

 
draw(1, 0); 
 

 
document.addEventListener('keydown', function(event) { 
 
    //console.log(event.keyCode); 
 
    if (event.keyCode == 40) { 
 
    draw(0, 1); 
 
    } 
 
});
canvas { background-color: red; }
<canvas id="canvas" width="600" height="400"></canvas>

使用上面的代碼,你可能至少發現兩個問題:

  1. 當按下鍵不放,矩形向下移動,而且還使向右移動。
  2. 當您多次按下向下鍵時,速度會增加。

我該如何解決這些問題?

+0

在功能形式的行爲修改的keydown和KeyUp事件國家重點對象,並有抽獎功能檢查國家重點對象的狀態。不要在代碼中的任何地方多次調用draw()。 – Chris

回答

1

我相信這是你想做什麼(和你接近!)。我希望這是你正在尋找的行爲。

一個相關的點:這可能是包裹x_movey_move了在關閉這些功能,使您避免意外改變它們在程序的其它部分是一個好主意。這樣,您爲改變方塊方向而實施的功能將可以私人訪問這些變量。

var canvas = document.getElementById('canvas'), 
 
    ctx = canvas.getContext('2d'), 
 
    x = 0, 
 
    y = 0; 
 

 
var x_move = 1; 
 
var y_move = 0; 
 

 
function draw() { 
 
    requestAnimationFrame(function() { 
 
    draw(); 
 
    }); 
 

 
    ctx.beginPath(); 
 
    ctx.rect(x, y, 20, 20); 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
    ctx.fillStyle = "#ffffff"; 
 
    ctx.fill(); 
 
    ctx.closePath(); 
 
    x = x + x_move; 
 
    y = y + y_move; 
 
} 
 

 
draw(); 
 

 
document.addEventListener('keydown', function(event) { 
 
    //console.log(event.keyCode); 
 
    if (event.keyCode == 40) { 
 
    x_move = 0; 
 
    y_move = 1; 
 
    } 
 
});
canvas { 
 
    background-color: red; 
 
}
<canvas id="canvas" width="600" height="400"></canvas>

+0

謝謝,這是一個簡單的解決方案,它效果很好! –

2

看到你打電話

requestAnimationFrame(function() { 
    draw(x_move, y_move); 
    }); 

您現在遞歸調用draw()

現在每次撥打電話draw()時,都會一遍又一遍地打來電話。而當你從keydown事件中調用它時,你經常稱它爲2x,然後在第二次按下它時爲3倍,等等。

我並不完全清楚你的目標是在這裏,但如果你想僅僅通過按下調整方形的軌跡,你可以做這樣的事情:

document.addEventListener('keydown', function(event) { 
    //console.log(event.keyCode); 
    if (event.keyCode == 40) { 
    adjustDownwardTrajectory(); 
    } 
}); 

,並有adjustDownwardTrajectory()改變一些downwardTrajectory變量這樣的:

function draw(x_move, y_move) { 
    requestAnimationFrame(function() { 
    draw(x_move, y_move); 
    }); 
    ctx.beginPath(); 
    ctx.rect(x, y, 20, 20); 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    ctx.fillStyle = "#ffffff"; 
    ctx.fill(); 
    ctx.closePath(); 
    x = x + x_move; 
    y = y + y_move + downwardTrajectory; 
} 
+0

謝謝,很高興知道這件事! –

0

keyboardEvent.keyCode是一個貶值的財產。您應該使用keyboardEvent.codekeyboardEvent.key他們提供了一個命名密鑰,比試圖記憶密鑰更容易管理。

您可以使用fillRect而不是rect,而且您不需要使用beginPathfill。你不需要使用closePath,如果你想關閉一個形狀(即從最後一個點到第一個點加一條線),你只能使用它。rect已經關閉了

你可以直接設置回調作爲參數​​

它支付將相關數據組合在一起。在這種情況下,廣場的位置爲x,y和位置較好的三角形位置(x_move,y_move)。你有相關數據的一個很好的線索是當你發現你自己給一組變量添加了相同的名字時。對象也可以包括像drawupdate

const canvas = document.getElementById('canvas'); 
const ctx = canvas.getContext('2d'); 

// list of named keys to record state of 
const keys = { 
    ArrowDown: false, 
}; 
// create key event listeners 
document.addEventListener('keydown', keyEvent); 
document.addEventListener('keyup', keyEvent); 

// define the square 
const square = { 
    x : 0, // position 
    y : 0, 
    dx : 0, // delta pos 
    dy : 0, 
    draw() { // function to render the square 
     ctx.fillStyle = "#ffffff"; 
     ctx.fillRect(this.x, this.y, 20, 20); 
    }, 
    update() { // function to update square 
     if(keys.ArrowDown){ 
      this.dx = 0; 
      this.dy = 1; 
     }else { 
      this.dx = 1; 
      this.dy = 0; 
     } 
     this.x += this.dx; 
     this.y += this.dy; 
    } 
} 

// main animation update function called once per frame 1/60th second 
function update() { 
    requestAnimationFrame(update); 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    square.update(); 
    square.draw(); 
} 

// key event records named key state (false up, true down) 
function keyEvent (event) { 
    if(keys[event.code] !== undefined){ 
     keys[event.code] = event.type === "keydown"; 
    } 
}