使用Pygame从列表随机生成自定义类对象的耗尽问题
问题描述
使用Python 3.10.4和Pygame开发游戏时,在主循环中尝试用random.choice从列表生成自定义类对象流遇到问题:代码能运行,但列表中的每个对象仅被生成一次后就不再重复生成。
相关代码片段:
def run_game(self): """Start the main loop for the game.""" list_of_particles = [Particle__SO2(self),Particle__H20(self),Particle__CO2(self),Particle__H2S(self), Particle__CO2(self)] while True: self._check_events() self.clock.tick(25) new_particle = random.choice(list_of_particles) self.particles.add(new_particle) self._update_particles()
完整代码:
import sys import pygame from pygame.sprite import Sprite import random class Volcano_game: """Overall class to manage game assets and behavior.""" def __init__(self): """Initialize the game, and create game resources.""" pygame.init() self.screen = pygame.display.set_mode((1920, 1080)) self.particles = pygame.sprite.Group() self.vent_location_xy = (952, 881) self.io_surface_y = 950 self.gravity = 1 self.clock = pygame.time.Clock() self.alpha_surf = pygame.Surface(self.screen.get_size(), pygame.SRCALPHA) def run_game(self): """Start the main loop for the game.""" list_of_particles = [Particle__SO2(self),Particle__H20(self),Particle__CO2(self),Particle__H2S(self), Particle__CO2(self)] while True: self._check_events() self.clock.tick(25) new_particle = random.choice(list_of_particles) self.particles.add(new_particle) self._update_particles() self.update_screen() self.alpha_surf.fill((255, 255, 255, 250), special_flags=pygame.BLEND_RGBA_MULT) def _update_particles(self): """Update position of particles and get rid of old particles.""" # Update bullet positions. self.particles.update() # Get rid of particles that have landed or gone off screen. for particle in self.particles.copy(): if particle.y > self.io_surface_y: self.particles.remove(particle) elif particle.y < 0: self.particles.remove(particle) elif particle.x < 0: self.particles.romove(particle) # 存在拼写错误 elif particle.x > 1920: self.particles.remove(particle) def update_screen(self): """Update images on the screen, and flip to the new screen.""" self.screen.fill((0, 0, 0)) self.screen.blit(self.alpha_surf, (0, 0)) for particle in self.particles.sprites(): particle.draw_particle() pygame.display.flip() def _check_events(self): """Respond to keypresses and mouse events.""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() class Particle(Sprite): """a class to manage sprites fired from the volcano""" def __init__(self, vg_game): super().__init__() self.screen = vg_game.alpha_surf self.colour = (60, 255, 60) self.rect_x = 952 self.rect_y = 881 self.y = self.rect_y self.x = self.rect_x self.speed_y = -15 self.speed_x = (random.randint(-11, 11)) self.gravity = vg_game.gravity def update(self): """move the particle around the screen""" # update the decimal position of the particle self.y += self.speed_y self.x += self.speed_x self.speed_y += self.gravity self.rect_y = self.y self.rect_x = self.x def draw_particle(self): """draw the particle on the screen""" pygame.draw.circle(self.screen, self.colour, (self.rect_x, self.rect_y), 2) class Particle__SO2(Particle): def __init__(self, vg_game): super().__init__(vg_game) self.colour = (255, 255, 255) self.speed_y = -17 class Particle__H20(Particle): def __init__(self, vg_game): super().__init__(vg_game) self.colour = (0, 0, 255) self.speed_y = -52.5 class Particle__CO2(Particle): def __init__(self, vg_game): super().__init__(vg_game) self.colour = (255, 0, 0) self.speed_y = -24.72 class Particle__H2S(Particle): def __init__(self, vg_game): super().__init__(vg_game) self.colour = (255, 255, 0) self.speed_y = -31.9 if __name__ == '__main__': # Make a game instance, and run the game. vg = Volcano_game() vg.run_game()
问题原因
你在list_of_particles里存放的是已经实例化完成的粒子对象,而不是粒子类本身。每次调用random.choice时,只是从列表里选出同一个对象实例,把它添加到sprite组中。当这个实例被_update_particles方法移除后,再次添加它也不会生成新的粒子——因为它还是原来那个对象,状态已经是移出屏幕的状态了。
解决方案
把列表改成存储粒子类,而不是实例。每次随机选择后,调用类并传入self来创建新的粒子实例:
修改run_game方法:
def run_game(self): """Start the main loop for the game.""" # 存储类,而不是实例 list_of_particles = [Particle__SO2, Particle__H20, Particle__CO2, Particle__H2S, Particle__CO2] while True: self._check_events() self.clock.tick(25) # 随机选择类,然后创建新实例 particle_class = random.choice(list_of_particles) new_particle = particle_class(self) self.particles.add(new_particle) self._update_particles() self.update_screen() self.alpha_surf.fill((255, 255, 255, 250), special_flags=pygame.BLEND_RGBA_MULT)
另外,注意修复_update_particles方法中的拼写错误:把self.particles.romove(particle)改成self.particles.remove(particle),否则当粒子超出左边界时会报错。
内容的提问来源于stack exchange,提问作者Mike B
相关产品推荐
相关产品推荐

