I am trying to move this image:
Across my PyGame screen, from right to left and back again, However as the image moves, every second or so I have a flicker of screen tear make its way up the image like so:
The code I am using is a loop similar to this:
screen.blit(img, (x,y))
pygame.update((x,y),(w,h))
pygame.draw.rect(screen,(0,0,0),((x,y),(w,h)))
So far I have tried the following to solve the issue:
Using HWSURFACE
, FULLSCREEN
, DOUBLEBUF
flags when creating the screen, this had no effect, I also adjusted my .update(rect)
to a .flip()
(as this is recommended when using DOUBLEBUF
?)
Splitting the memory between GPU and CPU (I am running this on a raspberry pi 2) I have tried giving both more memory, no change.
Setting a clock.tick to throttle the update rate to 60 FPS (above and below as well) this did smooth out some of the tearing but not all
Adjusting the size of each increment left or right, making the increments smaller results in less tearing, but also less speed. (Can't have it going too slow)
Blitting a new black surface rather than drawing a black rect over the previous position (when moving the image to ensure there is no trail behind it) as I read somewhere that blit
is better supported with HWSURFACE
than drawing, although I can't confirm this? - This had no effect
If anyone has any other solutions that may improve the situation I'd be grateful.
I would rather not change from PyGame to anything else (like pyglet) as I have done quite a lot of implementation so far using PyGame, but I am open to suggestions.
Cheers
EDIT
Relevant code as requested:
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)))
The slower
variable is to give a feel of inertia as the bar reaches the far left and right sides of its sweep across the speed it will slow down a little.
The firstTime
variable is for fading in the bar when it first appears.
There is another loop just below this that is very similar, but sweeps the image back the other way.
Set
in
pygame.display.set_mode()