javascript - 如何在 JS 的画布中更好地移动没有 clearRect() 的框?
问题描述
每个人。我打算在 JS 中开发一个类似 Piano Tiles 的游戏。我遇到的问题是我需要让几个可能出现在不同时间的图块移动,它让我不能使用 clearRect() 然后绘制下一个位置的图块,如果我这样做,我的多个图块会闪烁(因为当A瓷砖调用clearRect,B瓷砖将消失,这是不应该发生的)
我想出的解决方案是不使用 clearRect()清除整个屏幕,我只是清除我不想要的 Rectangle ,然后 fillRect (它的填充样式与我的背景颜色相同)再次填充这个小空矩形。
我的解决方案几乎可以达到我的目的,但我的代码中仍然存在一些缺陷。当我的黑色瓷砖移动时,仍然会出现一些微小的灰色矩形(并且很快就会消失)。
我想知道有没有更好的方法可以移动多个框(或矩形)?
PS:我的背景使用渐变,所以它可能使我的问题更加棘手。
以下是我的代码:
myTiles存储两个瓦片,paintWindow 函数针对绘制背景,我的解决方案是写在move() 函数中
var c = document.getElementById("piano");
var context = c.getContext("2d");
startGame();
function startGame(){
paintWindow();
myTiles = [];
myTiles[0] = new Block(0);
myTiles[1] = new Block(1);
}
function paintWindow(){
my_gradient = context.createLinearGradient(0,0,0,600);
my_gradient.addColorStop(0,"rgba(65,234,246,0.6)");
my_gradient.addColorStop(1,"rgba(254,74,251,0.5)");
context.fillStyle = my_gradient;
context.fillRect(0,0,300,600);
context.beginPath();
context.moveTo(72,0);
context.lineTo(72,600);
context.strokeStyle = "white";
context.stroke();
context.beginPath();
context.moveTo(148,0);
context.lineTo(148,600);
context.strokeStyle = "white";
context.stroke();
context.beginPath();
context.moveTo(226,0);
context.lineTo(226,600);
context.strokeStyle = "white";
context.stroke();
context.beginPath();
context.moveTo(0,470);
context.lineTo(300,470);
context.strokeStyle = "white";
context.stroke();
}
function Block(index){
this.index = index;
this.appearPos = Math.floor(Math.random()*4);
this.width = 70;
this.height = 120;
this.color = "black";
switch(this.appearPos){
case 0:
this.x = 0;
this.y = 0;
break;
case 1:
this.x = 75;
this.y = 0;
break;
case 2:
this.x = 152;
this.y = 0;
break;
case 3:
this.x = 228;
this.y = 0;
break;
}
context.fillStyle = this.color;
context.fillRect(this.x,this.y,this.width,this.height);
this.interval = setInterval(move,10,this.index);
}
function move(index){
//context.clearRect(0,0,300,600);
//paintWindow();
myTiles[index].y += 1;
context.fillStyle = "black";
context.fillRect(myTiles[index].x,myTiles[index].y,70,120);
context.clearRect(myTiles[index].x,myTiles[index].y-2,70,2);
context.fillStyle = my_gradient;
context.fillRect(myTiles[index].x,myTiles[index].y-2,70,2);
}
解决方案
我建议您不要为每个新块创建一个新间隔,而是创建一个间隔,您可以在其中一次更新所有块。这可能看起来像这样:
setInterval(moveAll,10);
function moveAll(){
context.clearRect(0,0,c.width,c.height);
for (var i=0;i<myTiles.length;i++){
move(i);
}
}
如果由于某种原因不能这样做,您还可以在单独的画布中绘制图块,以便在清除图块时保留背景:
<div>
<canvas id="background" style="position:absolute;left:0;top:0;">
<canvas id="tiles" style="position:absolute;left:0;top:0;">
</div>
这样,第二个画布将显示在第一个画布上,但背景仍然在它后面透明的地方可见。
推荐阅读
- pyspark - Spark优化编码
- javascript - 我有这两个吨位计算器。第一个工作得很好。我该如何修复第二个?我的 Javascript 有问题吗?
- angular - APP_INITIALIZER 不返回
- java - 如何创建相同对象的副本(例如标签)?
- filter - 使用 ffmpeg 将所有帧聚合为一张图像
- dart - 在 Dart 中使用 PointyCastle 进行 SHA-384/PSS 签名验证
- node.js - 当我尝试从 firebase 导出 db 时编译节点模块失败
- r - 用前一行的值替换 NA 或用 R 中的向量循环进行变异
- discord.py - 禁止命令角色层次结构中的 discord.py 错误
- r - 没有私有端点的安全 ACI - 使用管道工和 R 的 docker 映像