requestanimationframe drawing with for loop 问题
requestanimationframe drawing with for loop issue
我正在开发俄罗斯方块游戏 - 仍然 - 并且正在尝试使用 requestAnimationFrame 在黑板上绘制我的 T 块。
这就是问题所在。 requestAnimationFrame 绘制了 2 次,然后停止绘制,即使 for 循环仍然是 运行。也就是说,两次之后,我只看到黑色背景。当我注释掉黑色背景时,该作品显示 up/animates 就好了。
我真的很困惑为什么会这样。
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
const T = [
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
]
var piece = T[0];
const player = {
position: {x: 5, y: -1},
piece: piece,
}
function colorPiece(piece, offset) {
for(y = 0; y < piece.length; y++) {
for(x = 0; x < piece.length; x++) {
if (piece[y][x] !== 0) {
ctx.fillStyle = "red";
ctx.fillRect(x + offset.x, y + offset.y, 1, 1);
}
}
}
}
function drawCanvas() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.scale(20, 20);
colorPiece(player.piece, player.position);
}
function update() {
drawCanvas();
requestAnimationFrame(update);
}
update();
OK - 工作版本,fiddle here。一些变化。最大的是:
不要使用 canvas.scale()
,因为它是按 this 累积的(参见 "More Examples")。相反,对 20x20 块使用 20*x
和 20*y
。
编辑 基于 further test,看起来这是最重要的更改。
重命名,使piece
不用作变量的全部,player
中的字段名,colorPiece
[=41=的参数]
根据 this fiddle example 将 ctx
创作移动到 update()
(现在称为 doUpdate()
)。将 ctx
作为参数传递给其他函数。
将红色的fillStyle
赋值移出循环,因为你只需要做一次,然后你就可以在不改变它的情况下绘制所有的矩形。
在循环中:
for(var y = 0; y < thePiece.length; ++y) {
for(var x = 0; x < thePiece[y].length; ++x) { ... } }
保留 x
和 y
in the local scope,使用 var
。
当您准备好跨越一行时,即 thePiece[y].length
,即行的长度。使用 thePiece.length
会破坏 T
.
的非正方形元素
添加了一个 <p id="log"/>
和一个 javascript framenum
这样我就可以看到 doUpdate()
确实被调用了。
如果还没有,请确保在测试时打开控制台,以便查看错误消息。如果 drawCanvas
导致错误,它将阻止 requestAnimationFrame
再次被调用。我认为这就是为什么 the fiddle I linked above 在帧绘制函数的 beginning 而不是 end 调用 requestAnimationFrame
的原因。
希望对您有所帮助!
代码
const T = [
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
]
const player = {
position: {x: 5, y: -1},
piece: T[0]
}
function colorPiece(ctx, thePiece, offset) {
ctx.fillStyle = "red";
for(var y = 0; y < thePiece.length; ++y) {
for(var x = 0; x < thePiece[y].length; ++x) {
if (thePiece[y][x] !== 0) {
ctx.fillRect(20*(x + offset.x), 20*(y + offset.y), 20, 20);
}
}
}
}
function drawCanvas(ctx) {
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
colorPiece(ctx, player.piece, player.position);
}
var framenum=0;
function doUpdate(timestamp) {
document.getElementById("log").innerHTML = framenum.toString();
++framenum;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
drawCanvas(ctx);
window.requestAnimationFrame(doUpdate);
}
doUpdate();
我正在开发俄罗斯方块游戏 - 仍然 - 并且正在尝试使用 requestAnimationFrame 在黑板上绘制我的 T 块。
这就是问题所在。 requestAnimationFrame 绘制了 2 次,然后停止绘制,即使 for 循环仍然是 运行。也就是说,两次之后,我只看到黑色背景。当我注释掉黑色背景时,该作品显示 up/animates 就好了。
我真的很困惑为什么会这样。
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
const T = [
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
]
var piece = T[0];
const player = {
position: {x: 5, y: -1},
piece: piece,
}
function colorPiece(piece, offset) {
for(y = 0; y < piece.length; y++) {
for(x = 0; x < piece.length; x++) {
if (piece[y][x] !== 0) {
ctx.fillStyle = "red";
ctx.fillRect(x + offset.x, y + offset.y, 1, 1);
}
}
}
}
function drawCanvas() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.scale(20, 20);
colorPiece(player.piece, player.position);
}
function update() {
drawCanvas();
requestAnimationFrame(update);
}
update();
OK - 工作版本,fiddle here。一些变化。最大的是:
不要使用
canvas.scale()
,因为它是按 this 累积的(参见 "More Examples")。相反,对 20x20 块使用20*x
和20*y
。编辑 基于 further test,看起来这是最重要的更改。
重命名,使
piece
不用作变量的全部,player
中的字段名,colorPiece
[=41=的参数]根据 this fiddle example 将
ctx
创作移动到update()
(现在称为doUpdate()
)。将ctx
作为参数传递给其他函数。将红色的
fillStyle
赋值移出循环,因为你只需要做一次,然后你就可以在不改变它的情况下绘制所有的矩形。在循环中:
for(var y = 0; y < thePiece.length; ++y) { for(var x = 0; x < thePiece[y].length; ++x) { ... } }
保留
x
和y
in the local scope,使用var
。当您准备好跨越一行时,即
thePiece[y].length
,即行的长度。使用thePiece.length
会破坏T
. 的非正方形元素
添加了一个
<p id="log"/>
和一个 javascriptframenum
这样我就可以看到doUpdate()
确实被调用了。
如果还没有,请确保在测试时打开控制台,以便查看错误消息。如果 drawCanvas
导致错误,它将阻止 requestAnimationFrame
再次被调用。我认为这就是为什么 the fiddle I linked above 在帧绘制函数的 beginning 而不是 end 调用 requestAnimationFrame
的原因。
希望对您有所帮助!
代码
const T = [
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
]
const player = {
position: {x: 5, y: -1},
piece: T[0]
}
function colorPiece(ctx, thePiece, offset) {
ctx.fillStyle = "red";
for(var y = 0; y < thePiece.length; ++y) {
for(var x = 0; x < thePiece[y].length; ++x) {
if (thePiece[y][x] !== 0) {
ctx.fillRect(20*(x + offset.x), 20*(y + offset.y), 20, 20);
}
}
}
}
function drawCanvas(ctx) {
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
colorPiece(ctx, player.piece, player.position);
}
var framenum=0;
function doUpdate(timestamp) {
document.getElementById("log").innerHTML = framenum.toString();
++framenum;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
drawCanvas(ctx);
window.requestAnimationFrame(doUpdate);
}
doUpdate();