Re: [pygame] Scaling the hitbox/rect of a sprite
Thanks guys, your solutions work fine. I didn't realize that the collided callback function automatically gets the two sprites as input. -- View this message in context: http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227p1242.html Sent from the pygame-users mailing list archive at Nabble.com.
Re: [pygame] Scaling the hitbox/rect of a sprite
Example attached. This might get you going. Gumm On 5/23/2014 07:02, Skorpio wrote: Thanks for the help everybody, but it still doesn't work. I've tried these functions as collided values (as Jeffrey Kleykamp suggested): pygame.sprite.collide_rect() takes only sprites as values and then uses their rects. That means I can't use the sprite's scaled "hitbox" attribute, otherwise I get this error: AttributeError: 'pygame.Rect' object has no attribute 'rect' And if I do sprite.rect = sprite.hitbox, the image gets blitted at the top left corner again. pygame.Rect.colliderect() doesn't work. pygame.sprite.collide_rect_ratio() works as intended but causes a huge performance drop, so it's not useable for me. I have quite a lot of sprites on the screen (sometimes over 100). Christopher Night is right. It would be a lot easier for me, if Pygame sprites had an additional (optional) hitbox rect. Maybe I should rewrite my collision detection passage and just use pygame.Rect.colliderect() instead of pygame.sprite.spritecollide(). -- View this message in context: http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227p1237.html Sent from the pygame-users mailing list archive at Nabble.com. import pygame from pygame.locals import * screen = pygame.display.set_mode((800, 600)) screen_rect = screen.get_rect() clock = pygame.time.Clock() avatar_group = pygame.sprite.Group() blob_group = pygame.sprite.Group() class Thing(pygame.sprite.Sprite): def __init__(self, rect, color): super(Thing, self).__init__() self.rect = rect self.color = color self.image = pygame.Surface(rect.size) self.image.fill(color) self.hitbox = rect.inflate(20, 20) def update(self): self.hitbox.center = self.rect.center def collided(this, other): return this.hitbox.colliderect(other.hitbox) avatar = Thing(Rect(screen_rect.center, (20, 20)), Color('blue')) avatar_group.add(avatar) for p in ((100, 100),(100, 400),(400, 400)): blob_group.add(Thing(Rect(p, (20, 20)), Color('red'))) while True: screen.fill((0, 0, 0)) clock.tick(30) if any([e.type == KEYDOWN for e in pygame.event.get()]): quit() pos = pygame.mouse.get_pos() avatar.rect.center = pos avatar_group.update() blob_group.update() blob_group.draw(screen) avatar_group.draw(screen) hits = pygame.sprite.groupcollide( avatar_group, blob_group, False, False, collided) for g in blob_group, avatar_group: for s in g: if s in hits: pygame.draw.rect(screen, Color('red'), s.hitbox, 1) else: pygame.draw.rect(screen, Color('grey'), s.hitbox, 1) pygame.display.flip()
Re: [pygame] Scaling the hitbox/rect of a sprite
Oops, my code was wrong, it should be, my_collide_rect = lambda a, b: a.hitbox.colliderect(b.hitbox) You want to use the colliderect function of the Rect module to test if they collide. http://www.pygame.org/docs/ref/rect.html#pygame.Rect.colliderect Jeffrey On Fri, May 23, 2014 at 10:02 AM, Skorpio wrote: > Thanks for the help everybody, but it still doesn't work. > > I've tried these functions as collided values (as Jeffrey Kleykamp > suggested): > > pygame.sprite.collide_rect() takes only sprites as values and then uses > their rects. That means I can't use the sprite's scaled "hitbox" attribute, > otherwise I get this error: AttributeError: 'pygame.Rect' object has no > attribute 'rect' > And if I do sprite.rect = sprite.hitbox, the image gets blitted at the top > left corner again. > > pygame.Rect.colliderect() doesn't work. > > pygame.sprite.collide_rect_ratio() works as intended but causes a huge > performance drop, so it's not useable for me. I have quite a lot of sprites > on the screen (sometimes over 100). > > Christopher Night is right. It would be a lot easier for me, if Pygame > sprites had an additional (optional) hitbox rect. > > Maybe I should rewrite my collision detection passage and just use > pygame.Rect.colliderect() instead of pygame.sprite.spritecollide(). > > > > -- > View this message in context: > http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227p1237.html > Sent from the pygame-users mailing list archive at Nabble.com. > -- Jeffrey Kleykamp
Re: [pygame] Scaling the hitbox/rect of a sprite
Thanks for the help everybody, but it still doesn't work. I've tried these functions as collided values (as Jeffrey Kleykamp suggested): pygame.sprite.collide_rect() takes only sprites as values and then uses their rects. That means I can't use the sprite's scaled "hitbox" attribute, otherwise I get this error: AttributeError: 'pygame.Rect' object has no attribute 'rect' And if I do sprite.rect = sprite.hitbox, the image gets blitted at the top left corner again. pygame.Rect.colliderect() doesn't work. pygame.sprite.collide_rect_ratio() works as intended but causes a huge performance drop, so it's not useable for me. I have quite a lot of sprites on the screen (sometimes over 100). Christopher Night is right. It would be a lot easier for me, if Pygame sprites had an additional (optional) hitbox rect. Maybe I should rewrite my collision detection passage and just use pygame.Rect.colliderect() instead of pygame.sprite.spritecollide(). -- View this message in context: http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227p1237.html Sent from the pygame-users mailing list archive at Nabble.com.
Re: [pygame] Scaling the hitbox/rect of a sprite
You don't need to do that. rect.inflate already preserves the center. The question is more about how to use a separate rect for hitbox than you do for blitting. On Thu, May 22, 2014 at 12:30 PM, Jake b wrote: > To preserve the center: > > > pos = self.rect.center > self.rect = self.rect.inflate(-85, -20) > self.rect.center = pos > > > > > > On Thu, May 22, 2014 at 5:47 AM, Skorpio wrote: > >> Hi everybody, >> >> How can you scale the hitbox of a sprite? I tried self.rect = >> self.rect.inflate(-85, -20) and that scaled the rect correctly (to the >> center of the rect), but the game still takes the upper left corner of the >> rect as the blit position for the image/surface. That means the rect >> covers >> only the upper left part of the sprite, so that the left half of the >> sprite >> image can be hit and the right half can't be hit. >> >> Regards, >> Skorpio >> >> >> >> -- >> View this message in context: >> http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227.html >> Sent from the pygame-users mailing list archive at Nabble.com. >> > > > > -- > Jake >
Re: [pygame] Scaling the hitbox/rect of a sprite
To preserve the center: pos = self.rect.center self.rect = self.rect.inflate(-85, -20) self.rect.center = pos On Thu, May 22, 2014 at 5:47 AM, Skorpio wrote: > Hi everybody, > > How can you scale the hitbox of a sprite? I tried self.rect = > self.rect.inflate(-85, -20) and that scaled the rect correctly (to the > center of the rect), but the game still takes the upper left corner of the > rect as the blit position for the image/surface. That means the rect covers > only the upper left part of the sprite, so that the left half of the sprite > image can be hit and the right half can't be hit. > > Regards, > Skorpio > > > > -- > View this message in context: > http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227.html > Sent from the pygame-users mailing list archive at Nabble.com. > -- Jake
Re: [pygame] Scaling the hitbox/rect of a sprite
Using spritecollide(sprite, group, dokill, collided = None) you can specify a collided function. They have one built in for a constant ratio pygame.sprite.collide_rect_ratio(). You can also specify your own function. If you do that you can specify a different variable of your sprite to be your collision rect. Eg. my_func = lambda left, right: pygame.sprite.collide_rect(left.scaled_rect, right.scaled_rect) spritecollide(sprite, group, dokill, collided = my_func) Jeff On Thu, May 22, 2014 at 9:08 AM, Skorpio wrote: > I don't blit the sprites at the rect/hitbox, Pygame does that. The sprites > are in a pygame.sprite.Group and when I call sprite_group.draw(screen) and > if the rects are scaled, their images get still blitted at the top left > corner of the rect. I'm using pygame.sprite.spritecollide() for the > collision detection. > > Is there a way to give a sprite a additional hitbox? > > > > -- > View this message in context: > http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227p1231.html > Sent from the pygame-users mailing list archive at Nabble.com. > -- Jeffrey Kleykamp
Re: [pygame] Scaling the hitbox/rect of a sprite
I don't blit the sprites at the rect/hitbox, Pygame does that. The sprites are in a pygame.sprite.Group and when I call sprite_group.draw(screen) and if the rects are scaled, their images get still blitted at the top left corner of the rect. I'm using pygame.sprite.spritecollide() for the collision detection. Is there a way to give a sprite a additional hitbox? -- View this message in context: http://pygame-users.25799.x6.nabble.com/pygame-Scaling-the-hitbox-rect-of-a-sprite-tp1227p1231.html Sent from the pygame-users mailing list archive at Nabble.com.
Re: [pygame] Scaling the hitbox/rect of a sprite
On ĵaŭ, 2014-05-22 at 03:47 -0700, Skorpio wrote: > How can you scale the hitbox of a sprite? I tried self.rect = > self.rect.inflate(-85, -20) and that scaled the rect correctly (to the > center of the rect), but the game still takes the upper left corner of the > rect as the blit position for the image/surface. That means the rect covers > only the upper left part of the sprite, so that the left half of the sprite > image can be hit and the right half can't be hit. I'm not sure why you would use the hitbox as your blit position, if the hitbox is a different size to the sprite. I'd probably keep the rect for the sprite, and then when doing hittesting, just do hit_test(self.rect.inflate(-85, -20)) or something (never actually storing the scaled rect). signature.asc Description: This is a digitally signed message part