Skip to main content
 首页 » 编程设计

python之无法为多个对象使用相同的图像

2025年05月04日11shangdawei

我正在使用 Pygame 制作游戏,我正在尝试制作被子弹击中的小行星的动画。如果屏幕上只有一种小行星类型,则动画效果很好。当屏幕上出现两颗相同的小行星时,我遇到了麻烦。似乎第一个是唯一使用我的动画的。

例如,假设游戏产生了两个小行星,它们完全相同,我正在使用 glob.glob 获取 4 个动画图像,然后我将使用这些图像循环创建一个小动画他们。这适用于其中一颗小行星,另一颗不会播放动画。我想这一定是因为在任何时候只有一个对象可以使用特定图像?

对于糟糕的解释,我深表歉意。

这是我拥有的小行星类和创建动画的调用:

class Asteroid(pygame.sprite.Sprite): 
    def __init__(self, screen, size): 
        pygame.sprite.Sprite.__init__(self) 
        self.screen = screen 
        self.size = size 
        self.pos_x = random.randint(100,900) 
        pos_y= random.randint(100, 700) 
        self.pos_y = -pos_y 
        self.vel_y = 3 
        self.update_main = True 
        self.animation_path = "" 
 
        #load the image then put it above the screen, ready to drop 
        if self.size == "small": 
            self.asteroid_image = pygame.image.load("asteroid_small.tga") 
            self.animation_path = "C:/Programming/Stupid Games/Alien Invasion/animations/asteroid_small/*.tga" 
        elif self.size == "medium": 
            self.asteroid_image = pygame.image.load("asteroid_medium.tga") 
            self.animation_path = "C:/Programming/Stupid Games/Alien Invasion/animations/asteroid_medium/*.tga" 
        elif self.size == "med_large": 
            self.asteroid_image = pygame.image.load("asteroid_med_large.tga") 
            self.animation_path = "C:/Programming/Stupid Games/Alien Invasion/animations/asteroid_med_large/*.tga" 
        elif self.size == "small_med": 
            self.asteroid_image = pygame.image.load("asteroid_small_med.png") 
        elif self.size == "small_1": 
            self.asteroid_image = pygame.image.load("small1.tga") 
            self.animation_path = "C:/Programming/Stupid Games/Alien Invasion/animations/small/*.tga" 
        else: 
            self.asteroid_image = pygame.image.load("asteroid_large.tga") 
            self.animation_path = "C:/Programming/Stupid Games/Alien Invasion/animations/asteroid_large/*.tga" 
 
        #make the asteroid transparent 
        corner = self.asteroid_image.get_at((0,0)) 
        self.asteroid_image.set_colorkey(corner, RLEACCEL) 
 
        #randomly rotate the image 
        self.new_asteroid_image = pygame.transform.rotate(self.asteroid_image, random.randint(0,340)) 
 
        self.rect = self.new_asteroid_image.get_rect() 
        self.rect.x, self.rect.y = ((self.pos_x, self.pos_y)) 
        self.start_animate = False 
        self.times = 0 
 
        #load the asteroid animation 
        self.animation = glob.glob(self.animation_path) 
        self.animation.sort() 
        self.animation_pos = 0 
        self.animation_max = len(self.animation)-1 
        self.animation_speed_init = 50 
        self.animation_speed = self.animation_speed_init 
 
    def update(self): 
        #if asteroid has left the screen, place it back to the top 
        if self.rect.y > 900: 
            pos_y = random.randint(100,500) 
            self.rect.y = -pos_y 
            self.rect.x = random.randint(100,900) 
 
        self.rect.y += self.vel_y 
        self.position = self.rect.x, self.rect.y 
        self.screen.blit(self.new_asteroid_image.convert(), self.position) 
 
        if self.start_animate == True: 
            self.animation_speed += 25 
            if self.animation_speed > 60: 
                self.update_main = False 
                self.new_asteroid = pygame.image.load(self.animation[self.times]) 
                corner = self.new_asteroid.get_at((0,0)) 
                self.new_asteroid.set_colorkey(corner, RLEACCEL) 
                self.new_asteroid_image = self.new_asteroid 
                self.animation_speed = 0 
                self.animation_pos += 1 
                self.times += 1 
 
            if self.times > self.animation_max: 
                self.kill() 
 
    def start_animation(self): 
        self.start_animate = True 
 
 
 
#create asteroids at the start of the game 
if keys[K_SPACE]: 
    game_over = False 
    player = Space_Ship("space_ship.tga", screen) 
    asteroid_small = Asteroid(screen, "small") 
    asteroid_large = Asteroid(screen, "large") 
    asteroid_medium = Asteroid(screen, "medium") 
    asteroid_med_large = Asteroid(screen, "med_large") 
    asteroid_group.add(asteroid_small, asteroid_large, asteroid_medium, asteroid_med_large) 
    player_group.add(player) 
    score = 0 
 
 
 
#add asteroids after the game has started 
if len(asteroid_group) < difficulty: 
    random_asteroid_number = random.randint(0,5) 
    if random_asteroid_number == 0: 
        #large asteroid 
        asteroid_large = Asteroid(screen, "large") 
        asteroid_group.add(asteroid_large) 
    elif random_asteroid_number == 1: 
        #medium asteroid 
        asteroid_medium = Asteroid(screen, "medium") 
        asteroid_group.add(asteroid_medium) 
    elif random_asteroid_number == 2: 
        #medium large asteroid 
        asteroid_med_large = Asteroid(screen, "med_large") 
        asteroid_group.add(asteroid_med_large) 
    elif random_asteroid_number == 3: 
        #small medium asteroid 
        asteroid_small_med = Asteroid(screen, "small_med") 
        asteroid_group.add(asteroid_small_med) 
    elif random_asteroid_number == 4: 
        #small_1 asteroid 
        asteroid_small_1 = Asteroid(screen, "small_1") 
        asteroid_group.add(asteroid_small_1) 
    else: 
        #small asteroid 
        asteroid_small = Asteroid(screen, "small") 
        asteroid_group.add(asteroid_small) 
 
 
 
#bullet - asteroid collision 
collisions = pygame.sprite.groupcollide(bullet_group, asteroid_group, True, False) 
if collisions != None: 
    for i in collisions.values(): 
            for sprite in i: 
                channel2.play(asteroid_audio) 
                if sprite == asteroid_large: 
                    score += 3 
                    sprite.start_animation() 
                elif sprite == asteroid_small_1 or sprite == asteroid_med_large or sprite == asteroid_medium or sprite == asteroid_small: 
                    score += 1 
                    sprite.start_animation() 
                else: 
                    score += 1 
                    sprite.kill() 

请您参考如下方法:

虽然我不能确定,因为没有显示你调用更新的位,但我对它为什么这样做有一些想法。似乎没有调用第二颗小行星的更新。这可能有几个原因。第一个原因是如果你不实现小组来更新你的小行星。基本上,如果您只调用小行星的单个实例,则第二个实例不会执行任何操作,甚至不会显示在屏幕上。如果是这种情况,您将需要创建一个组,也许是一个渲染更新组,但即使是一个列表也可以。这意味着您可以执行以下操作:

asteroids.update() 

或

for asteroid in asteroids: 
    asteroid.update() 

以上两个代码假定您有某种小行星分组,称为小行星。

另一个可能的问题是,如果您正在实现组,则第二颗小行星没有被添加到该组中。如果你在init函数中告诉它把自己加到组里,就不会出现这个问题,但是,如果你在这个函数之外调用它,你做你的时候可能没有这样做第二颗小行星。要解决此问题,只需将添加小行星的部分移动到一个组中,该组将更新为小行星的 init 函数。