2017-04-02 25 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"; 
    } 
}