if one has two rects, r1 and r2 colliding, then the clipped rect rc =
r1.clip(r2) existst. If now one want to blit the area from one the
other
then it is like this:
rc = r1.clip(r2)
image1.blit(image2, rc, pygame.Rect(r2.x-clip.x, r2.y-clip.y, rc.w,
rc.h) )</i>
# Example.py # Written by Geekius Maximus (n00bgeek@xxxxxxxxx) import pygame class Rectangle(object): """ A rectangle. Attributes: image, rect, color Methods: <none>""" def __init__(self, color, rect): """ (self, color) : initialize the rectangle. """ super(Rectangle, self).__init__() self.image = pygame.Surface(rect.size) self.image.fill(color) self.rect = rect class MobileRectangle(Rectangle): """ A moving rectangle. Attributes: image, rect, color, velocity Methods: <none>""" def __init__(self, color): """ (self, color) : initialize the moving rectangle. """ rect = pygame.rect.Rect(0, 0, 30, 30) super(MobileRectangle, self).__init__(color, rect) self.velocity = [5, 5] def update(self): """ (self) : move the image by its velocity. """ new_left = self.rect.left + self.velocity[0] new_top = self.rect.top + self.velocity[1] if new_left < 0 or (new_left + self.rect.width) > RESOLUTION[0]: new_left -= (2 * self.velocity[0]) self.velocity[0] = -self.velocity[0] if new_top < 0 or (new_top + self.rect.height) > RESOLUTION[1]: new_top -= (2 * self.velocity[1]) self.velocity[1] = -self.velocity[1] old_rect = pygame.rect.Rect(self.rect) # Copy orig rect so that changes don't affect it self.rect.left = new_left self.rect.top = new_top return old_rect def main(): global RESOLUTION RESOLUTION = (640, 480) global screen screen = pygame.display.set_mode(RESOLUTION) global background background = pygame.Surface(RESOLUTION) background.fill((63, 88, 190)) screen.blit(background, (0, 0)) moving_sprite = MobileRectangle((0, 0, 0)) screen.blit(moving_sprite.image, moving_sprite.rect) static_sprite = Rectangle((255, 255, 255), pygame.rect.Rect(290, 210, 100, 100)) screen.blit(static_sprite.image, static_sprite.rect) pygame.display.flip() clock = pygame.time.Clock() fps = 60 while True: clock.tick(fps) for event in pygame.event.get(): if event.type == pygame.QUIT: return elif event.type == pygame.KEYDOWN: # Press 's' to change fps if event.key == K_s: if fps == 60: fps = 2 else: fps = 60 dirty = [] clear_rect = moving_sprite.update() # Blit background over moving_sprite's pre-move rect screen.blit(background, clear_rect, clear_rect) # This works dirty.append(clear_rect) if clear_rect.colliderect(static_sprite.rect): # Create a clip rect so that only the area over the sprite is blitted clip_rect = static_sprite.rect.clip(clear_rect) # Re-blit area of static rect erased by background screen.blit(static_sprite.image, clip_rect, clip_rect) # This doesn't work # Blit moving_sprite at post-move rect screen.blit(moving_sprite.image, moving_sprite.rect) # Change here dirty.append(moving_sprite.rect) pygame.display.update(dirty) if __name__ == "__main__" : main()