python - Pygame: Rect Objects Don't Render Properly in For Loops -


i'm using pygame develop game , i've decided i'd group gui objects in dictionary so:

gui_objects = {     # guiobject parameters define rect (for positioning) , background colour.     "healthbar" : guiobject((10,  10, 100, 20), colour.blue),     "mini_map"  : guiobject((10, 400,  50, 50), colour.white) } 

the reason i'm grouping gui objects can modify them like:

gui_objects.get("mini_map").set_enabled(false) 

now, when want render gui objects screen, did this:

for key, value in gui_objects.iteritems():     value.render(screen) 

this works, reason, white "mini_map" guiobject gets rendered underneath "healthbar" guiobject. decided put "mini_map" above "healthbar" in dictionary, changed nothing. here's weird part. if render gui objects separately, is, calling render() functions separately, this:

gui_objects.get("healthbar").render(screen) gui_objects.get("mini_map" ).render(screen) 

then guiobjects overlap properly. question is, why guiobjects not overlap when render them using loop? yet overlap fine when rendered separately?

unfortunately, can't upload images because don't have enough reputation ¬_¬ but, here's source code:

import pygame  # definition of few colours class colour(object):     white = (255, 255, 255)     grey  = (128, 128, 128)     blue  = ( 64, 128, 255)  # guiobject rectangle colour @ moment (for testing purposes). class guiobject(object):     def __init__(self, rect, colour):         self.rect   = rect         self.colour = colour      def render(self, screen):         pygame.draw.rect(screen, self.colour, self.rect)  def main():     ############################################################################     # initialise     pygame.init()     screen = pygame.display.set_mode((800, 600))      # if render_type = 0 render guiobjects using loop     # if render_type = 1 render guiobjects separately.     render_type = 1      gui_objects = {         "hpbar_bg"    : guiobject(( 0,  0, 150, 600), (colour.blue)),         "enemy_hpbar" : guiobject((10, 10, 200, 400), (colour.white)),     }      ############################################################################     # main loop     while true:         ########################################################################         # event handling         event in pygame.event.get():             if event.type == pygame.quit:                 pygame.quit()                 exit(0)          ########################################################################         # render         screen.fill((0, 0, 0))          # here, render guiobjects.         if render_type == 0:             # loop messes overlapping.             key, value in gui_objects.iteritems():                 value.render(screen)         elif render_type == 1:             # works fine.             gui_objects.get("hpbar_bg").render(screen)             gui_objects.get("enemy_hpbar").render(screen)          pygame.display.flip()  if __name__ == "__main__":     main() 

has got clue why overlapping guiobjects doesn't work when using loop?

i hope i've explained myself enough. if not, ask , i'll try clarify.

because dictionaries aren't ordered , drawing objects in different order other method.

a dictionary not designed holding objects need stay in order.

you can either:

  1. use pygame render group instead.

this pygame-recommended way store groups of objects going drawn, have convert gui objects sprites believe. edit: also, pygame render groups still not ordered wouldn't solve particular problem.

  1. use list of tuples [(name,value),...] instead (this similar current method because that's iteritems() dictionary method returns).

here code re-written using method 2:

import pygame  # definition of few colours class colour(object):     white = (255, 255, 255)     grey  = (128, 128, 128)     blue  = ( 64, 128, 255)  # guiobject rectangle colour @ moment (for testing purposes). class guiobject(object):     def __init__(self, rect, colour):         self.rect   = rect         self.colour = colour      def render(self, screen):         pygame.draw.rect(screen, self.colour, self.rect)  def main():     ############################################################################     # initialise     pygame.init()     screen = pygame.display.set_mode((800, 600))      # if render_type = 0 render guiobjects using loop     # if render_type = 1 render guiobjects separately.     render_type = 0      gui_objects = [         ("hpbar_bg", guiobject(( 0,  0, 150, 600), (colour.blue))),         ("enemy_hpbar", guiobject((10, 10, 200, 400), (colour.white))),     ]      ############################################################################     # main loop     while true:         ########################################################################         # event handling         event in pygame.event.get():             if event.type == pygame.quit:                 pygame.quit()                 exit(0)          ########################################################################         # render         screen.fill((0, 0, 0))          # here, render guiobjects.         if render_type == 0:             # loop no longer messes overlapping.             key, value in gui_objects:                 value.render(screen)          pygame.display.flip()  if __name__ == "__main__":     main() 

because able things gui_objects.hpbar_bg.set_enabled(false) third option:

  1. restructuring code contain gui within class itself, , order drawing of components within draw method.

here example of 3 doesn't deviate far you've got:

import pygame  # definition of few colours class colour(object):     white = (255, 255, 255)     grey  = (128, 128, 128)     blue  = ( 64, 128, 255)  # guiobject rectangle colour @ moment (for testing purposes). class guiobject(object):     def __init__(self, rect, colour):         self.rect   = rect         self.colour = colour         self.enabled = true      def render(self, screen):         if self.enabled:             pygame.draw.rect(screen, self.colour, self.rect)  class gui(object):     def __init__(self):         self.hpbar_bg = guiobject(( 0,  0, 150, 600), (colour.blue))         self.enemy_hpbar = guiobject((10, 10, 200, 400), (colour.white))         self.enabled = true      def render(self, screen):         #render gui in order want         if self.enabled:             self.hpbar_bg.render(screen)             self.enemy_hpbar.render(screen)   def main():     ############################################################################     # initialise     pygame.init()     screen = pygame.display.set_mode((800, 600))      gui = gui()      #uncomment enabled/disabled behavior     #gui.hpbar_bg.enabled = false      #or disable whole gui     #gui.enabled = false      ############################################################################     # main loop     while true:         ########################################################################         # event handling         event in pygame.event.get():             if event.type == pygame.quit:                 pygame.quit()                 exit(0)          ########################################################################         # render         screen.fill((0, 0, 0))          # render gui         gui.render(screen)          pygame.display.flip()  if __name__ == "__main__":     main() 

Comments

Popular posts from this blog

php - Submit Form Data without Reloading page -

linux - Rails running on virtual machine in Windows -

php - $params->set Array between square bracket -