gpt4 book ai didi

javascript - requestanimationframe drawing with for loop 问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:25:38 27 4
gpt4 key购买 nike

我正在开发一款俄罗斯方 block 游戏 - 仍然 - 并且正在尝试使用 requestAnimationFrame 在黑板上绘制我的 T block 。

这就是问题所在。 requestAnimationFrame 绘制了 2 次,然后停止绘制,即使 for 循环仍在运行。也就是说,两次之后,我只看到黑色背景。当我注释掉黑色背景时,作品显示/动画效果很好。

我真的不知道为什么会这样。

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 累积的(参见“更多示例”)。相反,使用 20*x20*y对于 block 20x20。

    编辑 基于further test ,看起来这是最重要的变化。

  • 重命名 piece未用作所有变量,player中的字段名称, 和参数 colorPiece

  • 移动ctx创作成update() (现在称为 doUpdate() )根据 this fiddle example .通过ctx作为其他函数的参数。

  • 移动红色fillStyle循环外的赋值,因为你只需要做一次,然后你可以在不改变它的情况下绘制所有的矩形。

  • 在循环中:

    for(var y = 0; y < thePiece.length; ++y) {
    for(var x = 0; x < thePiece[y].length; ++x) { ... } }

    保留 xy in the local scope , 使用 var .

    当您准备好跨越一行时,即 thePiece[y].length ,即行的长度。使用 thePiece.length T 的非正方形元素会被破坏.

  • 添加了一个 <p id="log"/>和一个 javascript framenum这样我就可以看到 doUpdate()确实被调用了。

如果您还没有,请确保在测试时打开控制台,以便您可以看到错误消息。如果drawCanvas导致错误,它将阻止 requestAnimationFrame从被再次调用。我想这就是为什么 the fiddle I linked above电话 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();

关于javascript - requestanimationframe drawing with for loop 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44852846/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com