【问题标题】:How to render a seamless tiling sprite using bunch of tiles rendered left and right如何使用左右渲染的一堆瓷砖来渲染无缝平铺精灵
【发布时间】:2020-03-31 00:18:32
【问题描述】:

我有一堆想要并排渲染的精灵。

let sprites = [sprite1, sprite2, sprite3];

sprites.forEach((_, i) => {
    _.position.set(i * _.width, 0);
});

我想沿由tileX 变量控制的x 轴移动这些精灵。

sprites.forEach((_, i) => {
    _.position.set(tileX + i * _.width, 0);
});

棘手的部分是当精灵到达屏幕的左边缘或右边缘时,我想将它移动到相反的边缘以便再次渲染。

【问题讨论】:

  • 我只想指出,使用_ 作为变量名是conventionally 完成的,“这个参数被忽略了,但我必须在这里放一个。”这对手头的问题并不重要,但我建议将_ 重命名为s 或其他名称,因为您实际上正在使用它。 :)
  • 在 Scala 中有一个符号 _.useThisVariable

标签: javascript


【解决方案1】:

假设您不希望精灵在左侧和右侧弹出,那么您需要使用 (displayAreaWidth + spriteWidth) 修改位置,如果精灵不在右侧,则减去该数量

不是 100% 清楚你想要做什么,但如果你只使用x % displayWidth,那么精灵就会出现在左边。他们需要从左边开始 -width。

  sprites.forEach((_, i) => {
      const scrollWidth = ctx.canvas.width + _.width;
      let x = (tileX + i * _.width) % scrollWidth;
      if (x < 0) x += scrollWidth;
      if (x > ctx.canvas.width) x -= scrollWidth;
      _.position.set(x, 0);
  });

const ctx = document.querySelector('canvas').getContext('2d');
const sprites = [...Array(16).keys()].map(i => {
  return {
    id: String.fromCharCode(i + 65),
    color: `hsl(${i / 26 * 360}, 100%, 50%)`,
    width: 20,
    height: 20,  
    position: {
      x: 0,
      y: 0,
      set(x, y) {
        this.x = x;
        this.y = y;
      },
    },
  };
});

requestAnimationFrame(animate);

function animate(time) {
  time *= 0.001;
  
  update(time);
  render();
  requestAnimationFrame(animate);
}

function update(time) {
  tileX = Math.sin(time) * 100;
  sprites.forEach((_, i) => {
      const scrollWidth = ctx.canvas.width + _.width;
      let x = (tileX + i * _.width) % scrollWidth;
      if (x < 0) x += scrollWidth;
      if (x > ctx.canvas.width) x -= scrollWidth;
      _.position.set(x, 0);
  });
}

function render() {
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  
  ctx.font = '28px sans-serif';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  
  for (const sprite of sprites) {
    ctx.fillStyle = sprite.color;
    ctx.fillRect(sprite.position.x, sprite.position.y, sprite.width, sprite.height);
    ctx.fillStyle = 'black';
    ctx.fillText(
        sprite.id,
        sprite.position.x + sprite.width / 2, 
        sprite.position.y + sprite.height / 2);
  }
}
canvas { border: 1px solid black; }
&lt;canvas&gt;&lt;/canvas&gt;

【讨论】:

    【解决方案2】:

    首先您需要找到画布或屏幕的大小,例如canvas.clientWidth。然后使用运算符%(模块)查找位置。正如你所说,它可以到达屏幕的左侧,我认为这个数字可能是负数。在这种情况下,您需要添加到屏幕宽度。

    var screenWidth = canvas.clientWidth;
    var positionX = (tileX + i * _.width) % screenWidth;
    if (positionX < 0) positionX += screenWidth;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-06
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多