首页 > 解决方案 > HTLM5 Canvas:删除旋转精灵之间的间隙

问题描述

所以我正在制作一个基于瓷砖的小宇宙飞船游戏,我遇到了一个问题,当瓷砖精灵随着船的旋转而旋转时,瓷砖之间似乎有小间隙。我对此进行了研究,发现抗锯齿可能与它有关,但使用后ctx.imageSmoothingEnabled= false;我仍然看不到任何变化。

在这里它看起来应该是,当一切都处于 90 度角时,它看起来很好:

精灵之间没有间隙的宇宙飞船

另一个例子,船在 90 度角看起来很好

但是,当船旋转时:

精灵之间的间隙

这是用于可视化瓷砖边框的“网格”示例:

平铺网格

目前,我使用的系统将较大的 2x2 瓦片精灵“拆分”为 4 个 1x1 瓦片。我可以将其更改为渲染整个 2x2 瓷砖,并且主要解决这个问题,因为它不太明显,但我想知道是否有一个解决方案不会有间隙。

标签: javascripthtmlcanvassprite

解决方案


您可以简单地在离屏画布上渲染一次,然后旋转这个完整的图像,而不是每次都合成它。

// the main context
const ctx = canvas.getContext('2d');
// an off-screen canvas
const ship = document.createElement('canvas');
const ship_renderer = ship.getContext('2d');
ship.height = ship.width = 150; 
const sprites = new Image();
sprites.onload = begin;
sprites.src = 'https://i.stack.imgur.com/scISJ.png';
let angle = 0;


function begin() {
  drawShip(ship_renderer); // render once complete
  anim(); // rotate
}

// draw our sprites on given context
function drawShip(renderer) {
  for(let y=0; y<6; y++) {
    for(let x=0; x<6; x++) {
      renderer.drawImage(sprites,
        (x + y * 6) * 25, 0, 25, 25,
        x * 25, y * 25, 25, 25
      );
    }
  }
}

function anim() {
  ctx.clearRect(0,0,canvas.width, canvas.height);
  angle += Math.PI / 180;
  
  // draw our complete image on the left
  ctx.setTransform(1,0,0,1,75,75);
  ctx.rotate(angle);
  ctx.translate(-75, -75);
  ctx.drawImage(ship, 0, 0);

  // draw like OP on the right
  ctx.setTransform(1,0,0,1,225,75);
  ctx.rotate(angle);
  ctx.translate(-75, -75);
  drawShip(ctx);
  
  ctx.setTransform(1,0,0,1,0,0);
  requestAnimationFrame(anim);
}
canvas{
  background: black;
}
<canvas id="canvas"></canvas>


推荐阅读