我正在编写一个 OOP 2d 画布游戏,我发现我的代码出现了一些奇怪的行为。当在工作区“e”内时,有两个或多个相同的对象,但没有其他对象,
ctx.resetTransform
不知何故不起作用,但当我在控制台中创建不同类型的新对象时,即。 e.create('bullet')
,错误消失了。有谁知道这是为什么吗?
var c = document.querySelector("canvas");
ctx = c.getContext("2d", {alpha: false});
const objs = {
flower: {
name: "flower",
rot: 45,
vel: {x: 0, y: 0},
pos: {x: 50, y: 100},
size: {x: 100, y: 100},
sprite: [
[0.4, 0.5, 0.2, 0.5, "green"],
[0.3, 0.1, 0.4, 0.4, "pink"],
],
},
bullet: {
name: "bullet",
rot: 0,
vel: {x: 0, y: 0},
pos: {x: 50, y: 100},
size: {x: 5, y: 10},
sprite: [[0, 0, 1, 1, "black"]],
},
};
var e = [];
e.create = function (cr) {
crr = structuredClone(objs[cr]);
e[e.length] = crr;
return crr;
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function render() {
ctx.clearRect(0, 0, c.width, c.height);
for (i = 0; i < e.length; i++) {
var obj = e[i];
for (ii = 0; ii < obj.sprite.length; ii++) {
ctx.resetTransform();
ctx.translate(
obj.pos.x + obj.size.x,
obj.pos.y + obj.size.y
);
ctx.rotate((obj.rot / 180) * Math.PI);
ctx.translate(
-(obj.pos.x + obj.size.x),
-(obj.pos.y + obj.size.y)
);
ctx.fillStyle = obj.sprite[ii][4];
ctx.fillRect(
obj.pos.x +
obj.sprite[ii][0] * obj.size.x -
obj.size.x / 2,
obj.pos.y +
obj.sprite[ii][1] * obj.size.y -
obj.size.y / 2,
obj.sprite[ii][2] * obj.size.x,
obj.sprite[ii][3] * obj.size.y
);
}
}
}
setInterval(() => {
render();
}, 50);
setInterval(() => {
e[0].pos.x = Math.random() * c.width;
}, 50);
e.create("flower");
e.create("flower");
<canvas height="1080" width="1920"></canvas>
2D 画布游戏中的
ctx.resetTransform()
问题似乎很不寻常。通常,无论工作区中的对象如何,此函数都应将当前变换重置为单位矩阵。但是,根据您的描述,似乎存在特定行为,具体取决于您的 e
数组的状态或组成。
<canvas height="1080" width="1920"></canvas>
<script>
var c = document.querySelector("canvas");
var ctx = c.getContext("2d", {alpha: false});
const objs = {
flower: {
name: "flower",
rot: 45,
vel: {x: 0, y: 0},
pos: {x: 50, y: 100},
size: {x: 100, y: 100},
sprite: [
[0.4, 0.5, 0.2, 0.5, "green"],
[0.3, 0.1, 0.4, 0.4, "pink"],
],
},
bullet: {
name: "bullet",
rot: 0,
vel: {x: 0, y: 0},
pos: {x: 50, y: 100},
size: {x: 5, y: 10},
sprite: [[0, 0, 1, 1, "black"]],
},
};
var e = [];
e.create = function (cr) {
var crr = structuredClone(objs[cr]);
e.push(crr);
return crr;
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function render() {
console.log('Render start');
ctx.clearRect(0, 0, c.width, c.height);
e.forEach(obj => {
obj.sprite.forEach(sprite => {
ctx.resetTransform();
ctx.translate(obj.pos.x + obj.size.x, obj.pos.y + obj.size.y);
ctx.rotate((obj.rot / 180) * Math.PI);
ctx.translate(-(obj.pos.x + obj.size.x), -(obj.pos.y + obj.size.y));
ctx.fillStyle = sprite[4];
ctx.fillRect(
obj.pos.x + sprite[0] * obj.size.x - obj.size.x / 2,
obj.pos.y + sprite[1] * obj.size.y - obj.size.y / 2,
sprite[2] * obj.size.x,
sprite[3] * obj.size.y
);
});
});
console.log('Render end');
}
setInterval(() => {
render();
}, 50);
setInterval(() => {
e[0].pos.x = Math.random() * c.width;
}, 50);
e.create("flower");
e.create("flower");
</script>