问题描述
我正在从 python 速成课本上做一个练习,我希望雨滴在它们击中屏幕底部后消失(移除)。他们没有消失,而是停止移动。当我在其他类似项目中编写相同的代码(删除部分)时,它可以工作。这是代码中没有像我希望的那样工作的部分。
import pygame
from settings import Settings
import sys
from raindrop import Image
from pygame.sprite import Sprite
class Raindrop(Sprite):
def __init__(self):
# Initialize pygame and create screen
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode(
[self.settings.screen_width,self.settings.screen_height])
self.screen.fill(self.settings.bg)
# Create group of raindrops
self.raindrop = Image(self)
self.raindrops = pygame.sprite.Group()
self.raindrops.add(self.raindrop)
self.row_of_raindrops()
def run_game(self):
while True:
self.not_quit()
self._update_raindrop()
self.update_screen()
for drop in self.raindrops.copy():
if drop.rect.bottom >= 750:
self.raindrops.remove(drop)
def not_quit(self):
# Not close the pygame window
for event in pygame.event.get():
if event.type == pygame.QUIT or (
event.type == pygame.KEYDOWN and event.key == pygame.K_q):
sys.exit()
def row_of_raindrops(self):
raindrop = Image(self)
raindrop_width,raindrop_height = raindrop.rect.size
width_for_raidnrops = self.settings.screen_width - (2 * raindrop_width)
range_for_raindrops = width_for_raidnrops // (2 * raindrop_width)
raindrop_width,raindrop_height = raindrop.rect.size
height_for_raindrops = self.settings.screen_height - (3 * raindrop_height)
range_height_for_raindrops = height_for_raindrops // (2 * raindrop_height)
for raindrop_number in range(range_for_raindrops):
for column_numbers in range(range_height_for_raindrops):
raindrop = Image(self)
raindrop.x = raindrop_width + 2 * raindrop_width * raindrop_number
raindrop.rect.x = raindrop.x
raindrop.y = raindrop_height + 2 * raindrop_height * column_numbers
raindrop.rect.y = raindrop.y
self.raindrops.add(raindrop)
def _update_raindrop(self):
self.raindrops.update()
def update_screen(self):
self.raindrops.draw(self.screen)
pygame.display.flip()
if __name__ == "__main__":
x = Raindrop()
x.run_game()
import pygame
from pygame.sprite import Sprite
class Image(Sprite):
def __init__(self,x_game):
super().__init__()
self.screen = x_game.screen
self.settings = x_game.settings
# Load image and get it rect
self.image = pygame.image.load("C:/Users/lukas/Desktop/python/raindrops/raindrop.jpg")
self.image = pygame.transform.scale(self.image,(50,50))
self.rect = self.image.get_rect()
# Raindrop position
self.rect.x = self.rect.width
self.rect.y = self.rect.height
self.y = float(self.rect.y)
def update(self):
self.y += self.settings.raindrop_speed
self.rect.y = self.y
解决方法
在每一帧中重新绘制场景。因此,您需要清除应用程序循环中的显示:
class Raindrop(Sprite):
# [...]
def update_screen(self):
self.screen.fill(self.settings.bg)
self.raindrops.draw(self.screen)
pygame.display.flip()
您需要调用 kill
来移除 Sprites。 kill()
从所有组中删除 Sprite,您可以在遍历 Group 时调用此方法。
另外使用 pygame.time.Clock
控制每秒帧数,从而控制游戏速度。
tick()
对象的方法 pygame.time.Clock
以这种方式延迟游戏,即循环的每次迭代消耗相同的时间段。见pygame.time.Clock.tick()
:
这个方法应该每帧调用一次。
class Raindrop(Sprite):
# [...]
def run_game(self):
clock = pygame.time.Clock()
while True:
clock.tick(100)
self.not_quit()
self._update_raindrop()
self.update_screen()
for drop in self.raindrops:
if drop.rect.bottom >= self.settings.screen_height:
drop.kill()