默认情况下,我的画布矩形应该从左向右移动。当按下键时,它应该开始向下移动。
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>
&#13;
使用上面的代码,您至少可以注意到两个问题:
如何解决这些问题?
答案 0 :(得分:2)
查看你打电话的地方
requestAnimationFrame(function() {
draw(x_move, y_move);
});
您现在递归调用draw()
。
现在,每次拨打draw()
时,都会一遍又一遍地调用它。当你从keydown事件中调用它时,你会经常调用它2倍,然后在第二次按它时经常调用3倍等等。
我并不完全清楚你的目标是什么,但是如果你想通过按下来调整方块的轨迹,你可以这样做:
document.addEventListener('keydown', function(event) {
//console.log(event.keyCode);
if (event.keyCode == 40) {
adjustDownwardTrajectory();
}
});
并让adjustDownwardTrajectory()
改变一些向下的轨道变量,以便:
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;
}
答案 1 :(得分:1)
我相信这就是你想做的事情(而且你很亲密!)。我希望这是你正在寻找的行为。
相关要点:将None
和x_move
包装在具有这些功能的闭包中可能是一个好主意,这样您就可以避免在其他部分中意外更改它们。该程序。这样,您实现的用于更改方形方向的函数将具有对这些变量的私有访问权限。
y_move
&#13;
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;
}
});
&#13;
canvas {
background-color: red;
}
&#13;
答案 2 :(得分:0)
keyboardEvent.keyCode
是折旧财产。您应该使用keyboardEvent.code
或keyboardEvent.key
他们提供的命名密钥比管理密钥代码更容易管理。
您可以使用fillRect
而不是rect
,并且不需要使用beginPath
和fill
。您不需要使用closePath
只有在想要关闭形状时使用它(即从最后一个点到第一个点添加一条线)rect
已经关闭
您可以直接将回调设置为requestAnimationFrame
将相关数据分组在一起是值得的。在这种情况下,正方形有一个位置x
,y
和一个在对象中更好的增量位置(x_move
,y_move
)。您有相关数据的好线索是当您发现自己为一组变量添加相同的名称时。对象还可以包括draw
和update
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";
}
}