# Sprite erasing text in Pygame

I'm making a Pong clone in which the user can press the 'p' button to pause/unpause the game. When the user presses the 'p' button the word 'PAUSE' is drawn to the screen and when he presses again the word is erased. My problem is this:

As you can see, the ball sprite is erasing the text. Any clue on why this is happening? Here is the code for the main stuff.

In your code flow, you are drawing the "Pause" text immediately when the player presses p. Later on in the same frame, you draw the other sprites. Pygame blit operations always draw on top of what has already been drawn.

If you want the pause text to appear above everything else in the game environment, you'll have to move the code that blits it to a point after everything else is blitted. Also, you'll want to draw it every frame.

Some code snippets might look like the following:

# Declare a boolean to track pause state.
paused = False

# Some other game code...
# ...
# ...

elif event.type == KEYDOWN:
if event.key == K_p:
if not paused:
pygame.mixer.music.pause()
else:
pygame.mixer.music.unpause()
paused = not paused

# Some more game code...
# Blit the rest of the game world to the background.

if paused:
# Draw the pause text on top of everything else.
screen.blit(self.pause_text.image, self.pause_text.rect)
# Some other pause code...

pygame.display.flip()


I noticed that you tried to throw the game into a second loop while it's paused to limit what's executed. Personally, I don't recommend this pattern, but if you'd like to stick with it I think that you'd just need to add a pygame.display.flip() to that loop and pull the blitting of the pause text out of the conditional for unpausing:

while pause:
if event.type == KEYDOWN and event.key == K_p:
pygame.mixer.music.unpause()
pygame.time.delay(150)
pause = False

screen.blit(self.background, self.pause_text.rect, self.pause_text.rect)
pygame.display.flip()


It doesn't make any sense to re-blit the pause text when the player unpauses the game.

• What is the problem with the second loop? – bzzr Sep 19 '13 at 22:20
• It leads to a lot of duplicated code. For example, you had to rewrite some of the input capture code within that loop, and also needed the pygame.display.flip call. The more code that needs to be duplicated, the more you're likely to leave out by accident, and the more bugs you get. Also, if you are keeping track of frame deltas, an indeterminate-length loop in the middle of a frame can really throw off timing, and coordinating calculation of frame times between the two loops could get messy. – kevintodisco Sep 19 '13 at 22:49
• I did noticed some delay between paused/unpaused states. – bzzr Sep 19 '13 at 22:57
• So how would you do it? – bzzr Sep 19 '13 at 22:58
• The first block of code in my answer kind of hints at it. The paused variable is toggled when the p key is pressed, and sections of the main game loop are executed depending on the value of paused. The larger the main loop becomes, the more it should be separated into other functions. – kevintodisco Sep 19 '13 at 23:06

I have no experience with pygame specifically, but the problem is not unique to one language, engine or framework. Most likely it has to do with the order in which you draw things, or with the depth if you set that explicitly.

In most cases, the default behaviour without setting a draw depth is that things are layered in the order they are drawn, meaning the last object that is drawn will be on top of anything else that was drawn in that area. In this case, you probably draw the word at some point after the middle line, but before the ball sprite, which would be why the ball is on top. The solution would be to move the drawing of "PAUSE" to the last possible position in the code, to ensure that it is drawn on top of everything else. Another possibility would be to explicitly set a draw depth, telling each object that is drawn at which depth it is, but I don't know pygame well enough to give you an example.

If you already are setting draw depth explicitly, it's almost certainly a small error with the depth parameter either in the word or the ball sprite.