使用XOR绘制JavaScript/HTML5以删除旧的精灵

arm*_*ive 3 javascript html5 drawing canvas xor

我正在为一个小游戏构建引擎,现在我刚刚得到一个红色圆圈,两个小眼睛作为主角.我有keyPress检测运动的功能,并且有效,但我想使用很久以前在QBASIC中使用的东西来移除角色并在新位置重绘:XOR

基本上,在按键上会发生这种情况:

if (code == 39) {
    mainChar.drawChar();
    mainChar.x += 1;
    mainChar.leftEye.x += 1;
    mainChar.rightEye.x += 1;
    mainChar.drawChar();
}
Run Code Online (Sandbox Code Playgroud)

我想在相同的空间上绘制角色,然后再次调整位置和绘图将删除第一个实例并绘制一个新实例.这是我的drawChar方法的片段:

  context.beginPath();
  context.arc(mainChar.x, mainChar.y, mainChar.radius, 0, 2 * Math.PI, false);
  context.closePath();
  context.fillStyle = 'red';
  context.fill();
  context.globalCompositeOperation = "xor";
Run Code Online (Sandbox Code Playgroud)

这是'有点'的工作,并且通过'排序',我的意思是它并没有完全抹掉第一张图.第一次调用还没有转移(并且在加载时调用了字符)所以我认为XOR会完全擦除图像,因为它们的坐标和一切都是相同的?

我是偏离基础,实施稍微错误的东西,还是有更好的方法来做到这一点?

mar*_*rkE 5

您是否注意到您圈子中未被删除的部分非常锯齿状?

这是因为画布最初用抗锯齿绘制了你的圆圈,以便在视觉上平滑圆圈的圆度.

当您对同一个圆进行异或时,画布不会擦除它最初创建的抗锯齿像素.

斜线也会发生同样的情况.

底线... XOR将无法工作,直到浏览器让我们关闭抗锯齿.已经向权力提出了这个选项.

在此之前,您可能会更改drawChar,以便"擦除"比您最初绘制的略大的圆圈.

drawChar(50,"red");
drawChar(51,"white");

function drawChar(r,fill){
  ctx.beginPath();
  ctx.arc(100,100,r, 0, 2 * Math.PI, false);
  ctx.closePath();
  ctx.fillStyle = fill;
  ctx.fill();
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,我记得很久以前用 GDI 进行异或运算——它既简单又有效。我想这就是“进步”!帆布是一种不同的动物。您可能会发现擦除/重绘整个场景最适合除性能最密集的项目之外的所有项目。为了获得最佳性能,您可以重绘部分画布或使用第二个隐藏的“缓冲区”画布来保存您的下一帧。然后只需将缓冲区绘制到显示画布上,然后通过绘制缓冲区重新开始整个过程​​。 (2认同)
  • 顺便说一句,您可以有 2 个重叠的画布。你的背景画布将在你的“动画”画布下。这样,您可以擦除动画画布上的圆圈,而无需重新绘制任何背景。 (2认同)
  • 我也很惊讶 XOR 不像 1980 年那样有效!但另一方面,现在绘图速度如此之快,可能人们认为不需要它。 (2认同)