Проблема с использованием одного и того же изображения для нескольких объектов

Я делаю игру с 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()

person Hyzenthlay    schedule 04.01.2013    source источник
comment
Где в коде вы создаете новые объекты Asteroid?   -  person calderonmluis    schedule 05.01.2013
comment
Извините, я добавил их сейчас.   -  person Hyzenthlay    schedule 05.01.2013
comment
я не уверен, что это проблема, но вы должны загрузить все изображения в начале игры и использовать их соответственно при создании, вместо того, чтобы загружать их с жесткого диска во время игры   -  person Bartlomiej Lewandowski    schedule 05.01.2013
comment
Вы используете таблицу спрайтов? И вы можете загрузить анимацию один раз, повторно используя поверхность для всех экземпляров астероидов.   -  person ninMonkey    schedule 06.01.2013


Ответы (1)


Хотя я не могу быть уверен, потому что бит, в котором вы вызываете update, не отображается, у меня есть несколько идей, почему он делает именно то, что есть. Похоже, что обновление второго астероида не называется. Это могло быть по нескольким причинам. Первая причина в том, что вы не реализуете группы для обновления вашего астероида. По сути, если вы вызываете только свой единственный экземпляр астероида, второй ничего не сделает, даже не появится на экране. В этом случае вам нужно будет создать группу, возможно, группу обновлений рендеринга, но даже список подойдет. Это означало бы, что вы могли бы сделать что-то вроде:

asteroids.update()

or

for asteroid in asteroids:
    asteroid.update()

приведенные выше два кода предполагают, что у вас есть некая группа астероидов, называемая астероидами.

Другая возможная проблема, если вы реализуете группы, заключается в том, что второй астероид не добавляется в эту группу. Если вы укажете ему добавить себя в группу в функции init, этой проблемы не будет, однако, если вы вызовете его вне этой функции, вы, возможно, не сделаете этого, когда сделаете свой второй астероид. Чтобы решить эту проблему, просто переместите часть, в которой вы добавляете астероид, в группу, которая будет обновлена ​​до функции init астероидов.

person trevorKirkby    schedule 24.11.2013