1

This is the code I've used. I'm a beginner so I couldn't use the concept of "objects" here. When I run the code, multiple lines are drawn but all of them are frozen.

    import pygame
    import random

    y=0
    screen=pygame.display.set_mode((600,600))
    pygame.display.set_caption('Trial')
    running=1
    while running:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                running=0
        x=random.randint(0,600)
        pygame.draw.line(screen,(255,255,255),(x,y),(x,y+10))
        y+=1
        pygame.display.flip()
unknown
  • 13
  • 3

1 Answers1

1

I don't know if this is what you are expecting or if this is the right way to this, but I am updating the screen and waiting before filling the screen again with black colour. This seems to be working and lines are not freezing.

import pygame
import random

y = 0
screen = pygame.display.set_mode((600, 600))
pygame.display.set_caption('Trial')
running = 1
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = 0
    x = random.randint(0, 600)
    pygame.draw.line(screen, (255, 255, 255), (x, y), (x, y + 10))
    y += 1
    pygame.display.update()
    pygame.display.flip()
    pygame.time.wait(1)
    screen.fill(pygame.Color("black"))

The code for rain generator from this archive has done does a great job in generating rain effect. I have formatted the code and pasted it below (as the formatting was bit messy in that site).

import pygame
import random
import time

SCREENSIZE = 640, 480

class Rain(object):

    def __init__(self, screen, height = 160, speed = 3, color = (180, 215, 228, 255), numdrops = 10):
        'Create and reuse raindrop particles'
        self.screen     = screen
        self.drops      = []
        self.height     = height
        self.speed      = speed
        self.color      = color
        self.numdrops   = numdrops

        for i in range(self.numdrops):
            # Randomize the size of the raindrop.
            raindropscale = random.randint(40, 100) / 100.0
            w, h = 3, int(raindropscale * self.height)
            # The bigger the raindrop, the faster it moves.
            velocity = raindropscale * self.speed/10.0
            pic = pygame.Surface((w, h), pygame.SRCALPHA, 32).convert_alpha()
            colorinterval = float(self.color[3] * raindropscale)/h
            r, g, b = self.color[:3]
            for j in range(h):
                # The smaller the raindrop, the dimmer it is.
                a = int(colorinterval * j)
                pic.fill( (r, g, b, a), (1, j, w-2, 1) )
                pygame.draw.circle(pic, (r, g, b, a), (1, h-2), 2)
            drop = Rain.Drop(self.speed, velocity, pic)
            self.drops.append(drop)

    def Timer(self, now):
        ' Render the rain'
        dirtyrects = []
        for drop in self.drops:
            r = drop.Render(self.screen, now)
            if r:
                i = r.collidelist(dirtyrects)
                if i > -1:
                    dirtyrects[i].union_ip(r)
                else:
                    dirtyrects.append(r)
        return dirtyrects


    def AdjustSpeed(self, adj):
        newspeed = self.speed + adj
        newspeed = max(1, newspeed)
        newspeed = min(100, newspeed)
        self.speed = newspeed
        for drop in self.drops:
            drop.SetSpeed(newspeed)
        print ('Rain speed: %d' % newspeed)


    class Drop(object):
        ' Rain drop used by rain generator'
        nexttime = 0   # The next time the raindrop will draw
        interval = .01 # How frequently the raindrop should draw

        def __init__(self, speed, scale, pic):
            ' Initialize the rain drop'
            self.speed = speed
            self.scale = scale
            self.pic = pic
            self.size = pic.get_size()
            self.SetSpeed(speed)
            self.pos = [random.random() * SCREENSIZE[0], -random.randint(-SCREENSIZE[1], SCREENSIZE[1])]
            self.currentspeed = speed

        def SetSpeed(self, speed):
            ' Speed up or slow down the drop'
            self.speed = speed
            self.velocity = self.scale * self.speed/10.0

        def Reset(self):
            ' Restart the drop at the top of the screen.'
            self.pos = [random.random() * SCREENSIZE[0], -random.random() * self.size[1] - self.size[1]]
            self.currentspeed = self.speed

        def Render(self, screen, now):
            ' Draw the rain drop'
            if now < self.nexttime:
                return None
            self.nexttime = now + self.interval
            oldrect = pygame.Rect(self.pos[0], self.pos[1], self.size[0], self.size[1]+self.currentspeed)
            self.pos[1] += self.currentspeed
            newrect = pygame.Rect(self.pos[0], self.pos[1], self.size[0], self.size[1])
            r = oldrect.union(newrect)
            screen.blit(self.pic, self.pos)
            self.currentspeed += self.velocity
            if self.pos[1] > SCREENSIZE[1]:
                self.Reset()
            return r

def main():
    # Initialize pygame
    pygame.init()
    pygame.key.set_repeat(500, 30)
    screen = pygame.display.set_mode(SCREENSIZE, 0, 32)

    # Create rain generator
    rain = Rain(screen)
    print ('right arrow to increase speed, left arrow to decrease speed.')

    # Main loop
    quitgame = 0
    while not quitgame:

        # Emulate CPU usage.
        # Commenting this out will no longer matter,
        # as the raindrops update on a timer.
        time.sleep(.01)

        # Draw rain
        dirtyrects = rain.Timer(time.time())

        # Update the screen for the dirty rectangles only
        pygame.display.update(dirtyrects)

        # Fill the background with the dirty rectangles only
        for r in dirtyrects:
            screen.fill((0, 0, 0), r)

        # Look for user events
        pygame.event.pump()
        for e in pygame.event.get():
            if e.type in [pygame.QUIT, pygame.MOUSEBUTTONDOWN]:
                quitgame = 1
                break
            elif e.type == pygame.KEYDOWN:
                if e.key == 27:
                    quitgame = 1
                    break
                elif e.key in [pygame.K_LEFT, pygame.K_UP]:
                    rain.AdjustSpeed(-1)
                elif e.key in [pygame.K_RIGHT, pygame.K_DOWN]:
                    rain.AdjustSpeed(1)

    # Terminate pygame
    pygame.quit()

if __name__ == "__main__":
    main()
Bharat Sesham
  • 416
  • 4
  • 11
  • This is solving the freeze issue but the lines are moving horizontally. How do I make them move vertically and also loop the program for "continuous" rain? – unknown Jun 06 '20 at 05:42
  • 1
    Look at this [rain generator archive](https://archives.seul.org/pygame/users/Oct-2006/msg00213.html) in pygame. I have ran the code, it looks really beautiful. Use it if you like it. – Bharat Sesham Jun 06 '20 at 06:16
  • It looks perfect! Thank you so much! – unknown Jun 06 '20 at 11:50
  • Also,is it possible to change the color of the drop and the background? If so,how is it supposed to be done? – unknown Jun 06 '20 at 12:27
  • 1
    You can change the colour of the drop by changing the line `r, g, b = self.color[:3]` to whatever colour you want. For example, change it to `r, g, b = [255, 0, 0]` for red colour rain drops. Also can you accept my answer and upvote my comments if you feel they are useful. It will be of help to me as I am new to stack overflow. Thanks. – Bharat Sesham Jun 06 '20 at 17:11
  • Sure. Thanks a lot! The colour change worked perfectly for the drops. But is the same possible for the background? – unknown Jun 07 '20 at 03:08
  • You can use the `screen.fill(pygame.Color("black"))` command to change the background colour. [More info](https://stackoverflow.com/questions/41189928/pygame-how-to-change-background-color) – Bharat Sesham Jun 08 '20 at 01:39
  • Where should i write it? – unknown Jun 08 '20 at 01:41