Search code examples
pythonpygameevent-driven

What is the correct sequence for bliting surfaces to the screen in pygame?


I am creating a simple mp3 player and my first task was to create a simple button that a user could press. I created a class called Button which handled this behavior and detects if a user has clicked it and then changes color. I am now trying to have a default text that the button displays and another string (pres_string) which will be displayed if the button is being pressed.

The only problem is my background surface seems to be in the wrong place and is drawing over any changes I have made.

Here is my code:

http://pastebin.com/Nh3yy01X

As you can see I've commented out the lines I described and tried it with basic variables in the main function just to test what was going wrong.

Thanks for any help.

(Feel free to change the title of the question, I wasn't sure what most accuratelydescribed my problem)


Solution

  • Clear the surface every loop

    def draw(self):
        # clear screen."
        self.screen.fill( self.color_bg )
    
        # first draw background
        # Then buttons
        # then any extra top level text
    
        # update
        pygame.display.flip()
    

    tip: For colors, you can call pygame.Color() with human-names like red ( gray20 and gray80 have a nice contrast, to use for bg and text. )

        from pygame import Color
        text = Color('gray20')
    

    Your button, psuedocode. Fix: moved color as an instance member.

    class Button(object):
        def __init__(self, text, rect=None):
            self.color_bg = Color("gray20")
            self.color_text = color("gray80")
    
            if rect is None: rect = Rect(0,0,1,1)
            self.rect = rect
            self._render()   
        def _render(self):
            # draw button and .render() font, cache to surface for later.    
            self.surface_cached = self.surface.copy()
            # render text
    
            #if size changes, save rect.size of cached surface , mantaining location
            self.rect.size = cache.get_rect.size
        def draw(self):
            # draw cached surface
            screen.blit( self.surface_cached, self.rect)
    

    For testClick use Rect.collidepoint http://www.pygame.org/docs/ref/rect.html#Rect.collidepoint