Hi Pygamers, I have created a series of pygame sprites. Visually, these sprites represent counters and may overlap. I want to determine which sprite the user clicked on.
This seems to me to be a fairly standard feature of a game interface, so I imagine that there is already a standard technique for achieving it. My current implementation (see below) is to use a "for" statement on the pygame.sprite group that contains the sprites. This means that I have to test all the sprites to determine the top-most sprite that is under the mouse. The sprites are blitted to the screen in the order they were added to the sprite group, so the sprite that appears on top is the last one in the group. I'd like to start at the top-most sprite and work backwards through the sprites in the group, and then use "break" to stop as soon as I find a sprite whose rect collides with the mouse position. In my code below, I've tried replacing the line... for vCounter in counters: # the pygame.sprite.RenderPlain() group ... with: vRange = range(len(counters)) vRange.reverse() for ii in vRange: vCounter = counters[ii] However this results in an error: #TypeError: 'Group' object is unindexable Is there a way to iterate backwards through a pygame sprite group? Or can you recommend an alternative method to achieve the same ends? My overall aim is to make the sprite the user clicks on jump to the top, so the order of the sprites in the group will change over time. Thanks in advance, James ----------------------------------------------------------- Here's my barebones code. It assumes that there are three 64 x 64 pixel image files named Counter_1.png through Counter_3.png in a subfolder named data. import os import pygame # Add QUIT, KEYDOWN and other event names to module namespace from pygame.locals import * # <COUNTER class Counter(pygame.sprite.Sprite): """ Creates a counter sprite from an image and places it in a tiled pattern relative to other counters """ def __init__(self, aIndex): pygame.sprite.Sprite.__init__(self) self.index = aIndex # Create a "surface" that we need to name "image" to overwrite # the Sprite's own .image property, which remains as None vFileName = "Counter_"+str(aIndex + 1)+".png" vPath = os.path.join('data', vFileName) self.image = pygame.image.load(vPath).convert() self.rect = self.image.get_rect() # Scatter the counters so they overlap self.rect.move_ip(aIndex * 24, aIndex * 24) def is_opaque_at(self, x, y): if self.rect.collidepoint(x, y): return True return False # COUNTER> # <MAIN def main(): """ Demonstrates the use of pygames RenderUpdates sprite group """ # Initialization pygame.init() clock = pygame.time.Clock() screen = pygame.display.set_mode((120, 120)) counters = pygame.sprite.RenderPlain() for i in range(0, 3): vCounter = Counter(i) vCounter.add(counters) # <Infinite loop while True: clock.tick(5) # 5 frames per second is quite sufficient for event in pygame.event.get(): if event.type in (QUIT, KEYDOWN): pygame.quit() return elif event.type == MOUSEBUTTONDOWN: vPos = pygame.mouse.get_pos() vIndex = None for vCounter in counters: vClicked = vCounter.is_opaque_at(*vPos) if vClicked: vIndex = vCounter.index print "Sprite "+str(vIndex)+" is under the mouse" #break # Uncomment to return the *lowest* sprite if vIndex != None: print vIndex counters.draw(screen) pygame.display.update() # Infinite loop> # MAIN> if __name__ == '__main__': main() _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor