首页 > 解决方案 > 我正在尝试使用 Pygame 在 python 中下雨,但是当代码运行时所有的水滴都会冻结

问题描述

这是我使用的代码。我是初学者,所以我不能在这里使用“对象”的概念。当我运行代码时,会绘制多条线,但它们都被冻结了。

    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()

标签: pythonpython-3.xpygamejupyter-notebook

解决方案


我不知道这是否是您所期望的,或者这是否是正确的方法,但我正在更新屏幕并等待,然后再次用黑色填充屏幕。这似乎有效,线路没有冻结。

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"))

这个档案中的雨水发生器代码在产生雨水效果方面做得很好。我已经格式化了代码并将其粘贴在下面(因为该站点的格式有点混乱)。

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()

推荐阅读