Javascript 为什么清除画布元素并将其放回会使其出现故障?

Javascript 为什么清除画布元素并将其放回会使其出现故障?,javascript,html,css,html5-canvas,Javascript,Html,Css,Html5 Canvas,这是我发布的最后一个问题的一个问题,但是当我清除画布时,对象就会出现故障。它消失了,然后又出现了。但为什么会出现故障呢?我将间隔设置为0毫秒,但它只是弹出然后出现 这里发生了一个小故障: 可能就是这个装置。我使用笔记本电脑和电脑。Windows7电脑很旧,chromebook也很差 const c=document.getElementById('c') const ctx=c.getContext('2d') c、 高度=窗内高度 c、 宽度=window.innerWidth 让block

这是我发布的最后一个问题的一个问题,但是当我清除画布时,对象就会出现故障。它消失了,然后又出现了。但为什么会出现故障呢?我将间隔设置为0毫秒,但它只是弹出然后出现

这里发生了一个小故障:

可能就是这个装置。我使用笔记本电脑和电脑。Windows7电脑很旧,chromebook也很差

const c=document.getElementById('c')
const ctx=c.getContext('2d')
c、 高度=窗内高度
c、 宽度=window.innerWidth
让blockInfo={
h:15,//定义高度和宽度以便可以更改。(注意:高度和宽度不必是相同的值)
w:15
}
让renderObjects=false//保留,以防发生冲突
让玩家={
速度:0.125,
x:2,
y:2,
身高:1,,
宽度:1
}
函数clearObjects(){
//清除所有
ctx.clearRect(0,0,c.宽度,c.高度)
}
函数renderObjects(){
//渲染块
ctx.fillStyle='#00b02f'
ctx.fillRect(5*blockInfo.w,5*blockInfo.h,blockInfo.w,blockInfo.h)
//渲染播放器
ctx.fillStyle='#000000'
ctx.fillRect(player.x*blockInfo.w,player.y*blockInfo.h,player.width*blockInfo.w,player.height*blockInfo.h)
}
功能按钮(e){
设w=e
if(renderObjects==true){
clearObjects()
如果(w==39){
player.x+=player.speed
}否则如果(w==37){
player.x-=player.speed
}否则如果(w==38){
player.y-=player.speed
}否则如果(w==40){
player.y+=player.speed
}
}
}
setInterval(函数(){
RenderObjects=false
renderObjects()
renderObjects=true
},0)
正文{
保证金:0;
溢出:隐藏;
}

答复

使用,而不是
setInterval
。即使您为
setInterval
指定了0,它实际上仍然会在再次调用回调之前等待一些最小延迟。这与您的设备无关<代码>请求动画帧特别适用于。。。动画

const c=document.getElementById('c');
const ctx=c.getContext('2d');
c、 高度=窗内高度;
c、 宽度=window.innerWidth;
让blockInfo={
h:15,//定义高度和宽度以便可以更改。(注意:高度和宽度不必是相同的值)
w:15
};
让renderObjects=false;//保持警惕,以防你会受伤
让玩家={
速度:0.125,
x:2,
y:2,
身高:1,,
宽度:1
};
函数clearObjects(){
//清除所有
ctx.clearRect(0,0,c.宽度,c.高度);
}
函数renderObjects(){
//渲染块
ctx.fillStyle='#00b02f';
ctx.fillRect(5*blockInfo.w,5*blockInfo.h,blockInfo.w,blockInfo.h);
//渲染播放器
ctx.fillStyle='#000000';
ctx.fillRect(player.x*blockInfo.w,player.y*blockInfo.h,player.width*blockInfo.w,player.height*blockInfo.h);
}
功能按钮(e){
设w=e;
if(renderObjects==true){
clearObjects();
如果(w==39){
player.x+=player.speed;
}否则如果(w==37){
player.x-=player.speed;
}否则如果(w==38){
player.y-=player.speed;
}否则如果(w==40){
player.y+=player.speed;
}
}
}
(函数循环(){
renderobjects=false;
renderObjects();
renderobjects=true;
请求动画帧(循环);
})();
正文{
保证金:0;
溢出:隐藏;
}

答复
虽然解决了这个问题,并提供了使用
requestAnimationFrame
自动批量重新渲染作为其优化动画支持的一部分的好建议,但还有更基本的设计问题。与其他任何东西相比,这部动画片更像是一种症状

尽管
requestAnimationFrame
足够聪明(无意中)保留了设计,但没有理由不可以使用
setInterval
很好(但不要出于其他原因使用
setInterval

设置动画的典型流程是:

 ______________________
|| :synchronous code: ||  :asynchronous code:
||                    ||
||   [update state]<---------+
||          |         ||     |
||          v         ||     | (keypresses are collected, etc)
||   [clear screen]   ||     |
||          |         ||     |
||          v         ||     |
||   [redraw screen]---------+
`|____________________|`
正文{
保证金:0;
溢出:隐藏;

}
完成此操作。点击代码段谢谢!不过我从没听说过requestAnimationFrame。谢谢你告诉我细节。里面有很多细节。我的也让你的细节去远足,因为它已经打包了。没问题。请记住,Stack Overflow是一个社区问答网站,所以这里的答案是为了帮助未来的读者。如果你需要一个TL;在这里,答案是您应该在更新循环中同时同步运行所有更新和渲染代码——不要在这样的按键处理程序中清除渲染循环外的屏幕。