首页 > 解决方案 > 从被摧毁的外星人身上掉落电源 - 外星人入侵

问题描述

我目前正试图让我的外星人在被摧毁时有随机机会掉落道具。我似乎已经弄清楚了基本的结构和逻辑,但是我遇到了一个错误。

当一个外星人被击中并且它确实产生了一个电源时,我的游戏崩溃了,我收到了一个错误。

Traceback (most recent call last):
  File "/Users/austintesch/Documents/GitHub/alien_invasion/alien_invasion.py", line 358, in <module>
    ai.run_game()
  File "/Users/austintesch/Documents/GitHub/alien_invasion/alien_invasion.py", line 52, in run_game
    self._update_bullets()
  File "/Users/austintesch/Documents/GitHub/alien_invasion/alien_invasion.py", line 153, in _update_bullets
    self._check_bullet_alien_collisions()
  File "/Users/austintesch/Documents/GitHub/alien_invasion/alien_invasion.py", line 168, in _check_bullet_alien_collisions
    pow = Pow(aliens.rect.center)
AttributeError: 'list' object has no attribute 'rect'

一般来说,我对编码还是很陌生,所以我不确定如何解决这个问题,据我所知,这应该可以工作,但显然我在这里缺少一些简单的东西。

class AlienInvasion:
    """Overall class to manage game assets and behavior."""

    def __init__(self):
        """Initlize the game, and create game resources."""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption("Alien Invasion")

        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

        self.ship = Ship(self)

        self.walls = Wall(self)
        self.wall_direction = self.settings.wall_speed

        self._create_groups()
        self._create_fleet()
        self._create_buttons()
 def _check_bullet_alien_collisions(self):
        """respond to bullet-alien collisions"""
        collisions = pygame.sprite.groupcollide(
            self.bullets, self.aliens, True, True
        )

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

            #Here is where I'm getting the error.
            if random.random() > 0.9:
                pow = Pow(aliens.rect.center)
                self.powerups.add(pow)


        if not self.aliens:
            self.bullets.empty()
            self._create_fleet()
            self.settings.increse_speed()

            self.stats.level += 1
            self.sb.prep_level()
 def _update_screen(self):
        """Update images on screen and flip to the new screen."""
        #fill our background with our bg_color
        self.screen.fill(self.settings.bg_color)

        # draw scoreboard to screen
        self.sb.show_score()

        #draw ship to screen
        self.ship.blitme()

        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        self.alien_bombs.update()
        self.alien_bombs.draw(self.screen)

        self.aliens.draw(self.screen)

        self.powerups.update() 

        if self.stats.game_active and self.stats.level >= 5:
            self.walls.draw_wall()
            self.walls.update(self.wall_direction)
            self.check_wall_edges()
            self._check_wall_collosions()

        # draw play button if game is inactive
        if not self.stats.game_active:
            if self.stats.level == 1:
                self.play_button.draw_button()

            elif not self.stats.ships_left:
                self.game_over_button.draw_button()
                pygame.mouse.set_visible(True)

            elif self.stats.ships_left != 0:
                self.continue_button.draw_button()

        #Make the most recently drawn screen visible.
        #this clears our previous screen and updates it to a new one
        #this gives our programe smooth movemnt
        pygame.display.flip()

通电.py

"""attempt to make aliens drop powerups when killed"""
import random
import pygame
from pygame.sprite import Sprite

class Pow(Sprite):
    def __init__(self, center):
        super().__init__()

        self.type = random.choice(['shield', 'gun'])
        self.image = powerup_images[self.type]
        self.rect = self.image.get_rect()
        self.rect.center = center
        self.speedy = 2

    def update(self):
        self.rect.y += self.speedy
        if self.rect.top >= self.settings.screen_height:
            self.kill()

powerup_images = {'shield': pygame.image.load('images/shield.bmp')}
powerup_images['gun'] = pygame.image.load ('images/gun.bmp')

标签: pythonpygame

解决方案


pygame.sprite.groupcollide返回一个字典,其中元素是一个列表。因此aliens是一个列表:

pow = Pow(aliens.rect.center)

collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)
if collisions:
    for aliens in collisions.values():
        self.stats.score += self.settings.alien_points * len(aliens)
           
        for alien in aliens:
            if random.random() > 0.9:
                pow = Pow(alien.rect.center)
                self.powerups.add(pow)

推荐阅读