Aph*_*ire 5 python pygame vsync raspberry-pi
我正在尝试移动这张图片:

在我的 PyGame 屏幕上,从右到左,然后再返回,但是随着图像移动,每隔一秒左右,我就会看到屏幕撕裂的闪烁,如下所示:

我正在使用的代码是与此类似的循环:
screen.blit(img, (x,y))
pygame.update((x,y),(w,h))
pygame.draw.rect(screen,(0,0,0),((x,y),(w,h)))
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已尝试以下方法来解决该问题:
创建屏幕时使用HWSURFACE, FULLSCREEN,DOUBLEBUF标志,这没有效果,我也将其调整.update(rect)为 a .flip()(因为在使用 时建议这样做DOUBLEBUF?)
在 GPU 和 CPU 之间分割内存(我在树莓派 2 上运行)我尝试给两者提供更多内存,但没有改变。
设置clock.tick将更新速率限制为60 FPS(也高于和低于),这确实消除了一些撕裂,但不是全部
向左或向右调整每个增量的大小,使增量变小会减少撕裂,但也会降低速度。(不能太慢)
blit当我读到比绘图更受支持的地方时,虽然我无法确认这一点,但在以前的位置上绘制一个新的黑色表面而不是绘制一个黑色矩形(当移动图像以确保其后面没有痕迹时)HWSURFACE?- 这没有效果
如果有人有任何其他可以改善情况的解决方案,我将不胜感激。
我宁愿不从 PyGame 更改为其他任何东西(如 pyglet),因为到目前为止我已经使用 PyGame 完成了相当多的实现,但我愿意接受建议。
干杯
编辑
根据要求提供相关代码:
if scanner == True:
clocker.tick(clockspeed)
if x < 11:
slower = 3
if firstTime == True:
img.set_alpha(int(x * 25))
newSurf.set_alpha(int(x * 25))
screen.blit(newSurf,(xText,35))
pygame.display.update((xText,35),((xText + newSurf.get_width()),(50 + newSurf.get_height())))
img.set_alpha(255)
elif x > (divider - 15):
slower = 3
else:
slower = 0
firstTime = False
screen.blit(img, ((xStart - (x * increment) + slower),100))
pygame.display.update(((xStart - (x * increment) + slower),100),(95,450))
pygame.draw.rect(screen, (0,0,0), (((xStart - (x * increment) + slower),100),(95,450)))
Run Code Online (Sandbox Code Playgroud)
该slower变量是为了给人一种惯性的感觉,当杆到达其扫描的最左侧和右侧时,它的速度会稍微减慢。
该firstTime变量用于在条首次出现时淡入淡出。
下面还有另一个循环,非常相似,但以另一种方式将图像扫回。
小智 0
这种撕裂只是屏幕渲染方式的产物。线条的下一个位置正在渲染,而前一个位置正在被绘制。如果屏幕的刷新率和更新率是同步的,那么这个问题就会消失。但由于几乎不可能准确地做到这一点,我建议让您的程序采用 PICO-8 管理此问题的路线,等待屏幕刷新完成,然后更改屏幕缓冲区以防止撕裂。我不确定是否有等待屏幕刷新完成的方法,但如果有,那么顺序应该是:update back buffer -> wait for screen to stop being drawn -> flip buffers -> screen is drawn again。
刷新是指从左到右、从上到下、逐个像素地绘制屏幕。这是因为与屏幕的三重总线连接一次只允许来自屏幕内存的一个像素的亮度,因此每个像素都是按顺序绘制的。撕裂来自于刷新过程中内存的变化,因此该线将位置移动到屏幕的中间位置。