Making rows of sprites re-appear at top of screen in pygame

Viewed 143

I'm trying to make the rows of sprites reappear at the top of the screen when they disappear off of the bottom. I'm able to make the sprites move downwards and off the screen but don't know to get them to reappear as soon as one row moves off. Here is the code I have so far:

import pygame

import sys

from pygame.sprite import Sprite

class Rain:

    def __init__(self):

        pygame.init()

        self.screen = pygame.display.set_mode((1200, 800))
        pygame.display.set_caption("Rain Drops")

        self.bg_color = (100,100,100)


        self.rain_drops = pygame.sprite.Group()

        self._create_drop()
   

        drop = Drop()



    def run_rain(self):
           

        while True:

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        sys.exit()


            self.screen.fill(self.bg_color)


            self._update_drops()

            
            self.rain_drops.draw(self.screen)


            pygame.display.flip()


    def _create_drop(self):

        drop = Drop()
        drop.rect.x = -10 
        drop.rect.y = 4
        drop_start_x = drop.rect.x
        drop_start_y = drop.rect.y


        for row_number in range(5):
            for drop_number in range(20):
                drop = Drop()
                drop.rect.x = drop_start_x + 70 * drop_number
                drop.rect.y = drop_start_y + 100 * row_number


                self.rain_drops.add(drop)
    

    def _update_drops(self):
        self.rain_drops.update()



class Drop(Sprite):

    def __init__(self):

        super().__init__()

        self.image = pygame.image.load('smaller_drop.bmp')
        self.rect = self.image.get_rect()


    def update(self):
        self.rect.y += 1




rain = Rain()
rain.run_rain()
1 Answers

This sort of thing is best done in your sprite's .update() function. Check to see if the y co-ordinate of the sprites Rect is past the height of the window, and if-so move it back to the top.

However, you have hard-coded the window dimensions inside the display initialisation function. We need to know the window length in the update, so these need to be moved out to constant variables.

class Rain:
    WINDOW_WIDTH = 1200
    WINDOW_HEIGHT= 800

    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((self.WINDOW_WIDTH, self.WINDOW_HEIGHT))
        pygame.display.set_caption("Rain Drops")

Now in the DropSprite it's pretty easy to compare the position against the window height. if the position is greater than the window height,

class Drop(Sprite):

    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('smaller_drop.bmp')
        self.rect = self.image.get_rect()

    def update(self):
        self.rect.y += 1
        # if we go off the bottom of the window, move back to top
        if ( self.rect.y > Rain.WINDOW_HEIGHT ):   
            self.rect.y = 0 

You may also want the drop to start just above the screen so it "falls" into view. In this case start it with an x of (0 - self.rect.height), since the x,y of a rect is the top-left co-ordinate. Moving it to 0 makes it suddenly appear at the top. Moving it to -height puts it just above the player's view.

Related