[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] blit() problem



<I>
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>

DROID - No, I don't think that applies to my problem. Thanks for the suggestion, though.

Take a look at the sample code I have attached. You'll notice that the static white rectangle in the middle is erased by the moving black rectangle. The code is supposed to re-blit the area of the white rectangle erased by the black rectangle as it moves:

(lines 88 - 89)
<B># Re-blit area of static rect erased by background
screen.blit(static_sprite.image, clip_rect, clip_rect) # This doesn't work</b>

I'm almost tempted to think that this is a problem with the blit() method itself. If you replace line 91......:
<B>screen.blit(moving_sprite.image, moving_sprite.rect) # Change here</b>

.....with this.....:
<B>screen.blit(moving_sprite.image, moving_sprite.rect, moving_sprite.rect)</b>

.....the black moving rectangle doesn't appear at all, but you can still see where it erases the white rectangle as it moves. I'll see if there's a Surface method that might help, but I'd like to try and get this to work, if anyone has any idea how.....

BTW, yes, DROID, I do plan on making my own layering system in the near future, I don't know whether I posted that or not... either way, I need to get this issue out of the way first.

For God's glory,
Geekius


New Yahoo! Messenger with Voice. Call regular phones from your PC and save big.
# 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()