为什么当发生非常具体的事情时 ctx.resetTransform() 不起作用?它也没有给出任何错误

问题描述 投票:0回答:1

我正在编写一个 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>

javascript arrays object oop html5-canvas
1个回答
-1
投票

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>
© www.soinside.com 2019 - 2024. All rights reserved.