2

私はPygameでゲームを作っており、弾丸で打たれた小惑星をアニメートしようとしています。画面に小惑星の種類が1つしかない場合、アニメーションは正常に機能します。画面に同じ小惑星が2つあると、問題が発生します。私のアニメーションを使用しているのは最初のものだけのようです。

たとえば、ゲームが2つの小さな小惑星を生成するとします。これらはまったく同じで、glob.globを使用して4つのアニメーション画像を取得し、それらの画像をループして小さなアニメーションを作成します。これは小惑星の1つで機能し、もう1つはアニメーションを再生しません。一度に特定の画像を使用できるのは1つのオブジェクトだけだからだと思いますか?

ひどい説明でごめんなさい。

これが私が持っている小惑星のクラスとアニメーションを作成するための呼び出しです:

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()
4

1 に答える 1

1

あなたが更新を呼び出すビットが表示されていないため、私には確信が持てませんが、なぜそれが何をしているのかについていくつかのアイデアがあります. 2 番目の小惑星の更新が呼び出されていないようです。これにはいくつかの理由が考えられます。最初の理由は、小惑星を更新するためにグループを実装していない場合です。基本的に、小惑星の 1 つのインスタンスのみを呼び出した場合、2 番目のインスタンスは何もせず、画面に表示されることさえありません。この場合、グループを作成する必要があります。おそらくレンダリング更新グループですが、リストでも問題ありません。これは、次のようなことができることを意味します。

asteroids.update()

また

for asteroid in asteroids:
    asteroid.update()

上記の 2 つのコードは、小惑星と呼ばれる小惑星の何らかのグループがあることを前提としています。

グループを実装している場合に考えられるもう 1 つの問題は、2 番目の小惑星がこのグループに追加されない場合です。init関数で自分自身をグループに追加するように指示すると、この問題は発生しませんが、この関数の外で呼び出すと、2 番目の小惑星を作成するときにそうしない可能性があります。この問題に対処するには、小惑星を追加する部分を、小惑星のinit関数に更新されるグループに移動するだけです。

于 2013-11-24T03:31:41.947 に答える