python - 我正在尝试使用 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()
解决方案
我不知道这是否是您所期望的,或者这是否是正确的方法,但我正在更新屏幕并等待,然后再次用黑色填充屏幕。这似乎有效,线路没有冻结。
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()
推荐阅读
- javascript - 即使发送了响应,XMLHttpRequest 也只能达到 readystate 1
- r - R:是向量列表中的一个向量
- c++ - 如何继承不适用于基类实例的模板构造函数?
- javascript - 从另一个按钮触发一个按钮
- php - 在php中将sitemap.xml压缩成sitemap.xml.gz,导致文件损坏
- django - django 中的 Postgres 连接池
- vb.net - Convert.ToBase64String(Convert.FromBase64String(Convert.ToBase64String(mybytearray))) 不输出相同的字节数组
- hugo - 使用 Hugo,我们可以在 md 文件中使用 HTML 代码吗?
- python - Keras:MLP 的结果很好,但双向 LSTM 的结果很差
- php - Laravel嵌套'with'函数复杂查询问题