在屏幕上移动线条时,Pygame屏幕撕裂

时间:2015-06-19 10:51:22

标签: python pygame raspberry-pi vsync

我正试图移动此图片:

enter image description here

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

enter image description here

我使用的代码是一个类似于此的循环:

screen.blit(img, (x,y))
pygame.update((x,y),(w,h))
pygame.draw.rect(screen,(0,0,0),((x,y),(w,h)))

到目前为止,我已尝试以下方法解决此问题:

在创建屏幕时使用HWSURFACEFULLSCREENDOUBLEBUF标记,这没有效果,我还将.update(rect)调整为.flip()(如使用DOUBLEBUF时建议使用此方法?)

在GPU和CPU之间拆分内存(我在覆盆子pi 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)))

slower变量是为了给人一种惯性的感觉,因为当它到达扫描的最左侧和右侧时,它会慢慢减速。

firstTime变量用于首次出现时条形图中的淡入淡出。

在此下面还有另一个非常相似的循环,但是以另一种方式扫描图像。

1 个答案:

答案 0 :(得分:0)

这种撕裂只是屏幕渲染方式的产物。该线的下一个位置是渲染位置,而上一个位置被绘制。如果屏幕的刷新率和更新率是同步的,则此问题消失。但是由于几乎不可能准确地执行此操作,因此建议您使程序采用PICO-8进行管理的路线,在更改屏幕缓冲区以防止撕裂之前等待屏幕刷新完成。我不确定是否有等待屏幕刷新完成的方法,但是如果有,那么序列应为:update back buffer -> wait for screen to stop being drawn -> flip buffers -> screen is drawn again

刷新是从左到右,从上到下,逐像素绘制屏幕的地方。这是因为与屏幕的三重BUS连接仅一次允许一个像素的亮度来自屏幕存储器,因此每个像素都是按顺序绘制的。撕裂的原因是内存在刷新过程中发生了变化,因此该行将位置移动到了屏幕下方。