почему это - AttributeError: у объекта «Чужой» нет атрибута «изображение» исходит от aliens.draw (экран)? - PullRequest
0 голосов
/ 13 января 2020

** В этой игре шесть модулей, и главная проблема заключается в том, что он показывает все ошибки, на самом деле я делал этот проект из книги под названием python cra sh Конечно, все шло хорошо, пока не появилась эта ошибка, и я пробовать все возможные пути, но это не идет вперед **

"Traceback (most recent call last):
  File "C:/Users/oracle.DESKTOP-DESAP2E/PycharmProjects/Alien_invasion/start_game", line 29, in <module>
    run_game()
  File "C:/Users/oracle.DESKTOP-DESAP2E/PycharmProjects/Alien_invasion/start_game", line 27, in run_game
    gf.update_screen(ai_settings, screen, ship, aliens, bullets)
  File "C:\Users\oracle.DESKTOP-DESAP2E\PycharmProjects\Alien_invasion\game_functions.py", line 74, in update_screen
    aliens.draw(screen)
  File "C:\Users\oracle.DESKTOP-DESAP2E\PycharmProjects\Alien_invasion\venv\lib\site-packages\pygame\sprite.py", line 476, in draw
    self.spritedict[spr] = surface_blit(spr.image, spr.rect)
AttributeError: 'Alien' object has no attribute 'image'"

----- и код здесь ....

start_game.py

import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group

def run_game():
    pygame.init()
    ai_settings = Settings()

    screen = pygame.display.set_mode((ai_settings.screenwidth,ai_settings.screenheight))
    pygame.display.set_caption("Alien Invasion")

    # Make a ship, a group of bullets, and a group of aliens.
    ship = Ship(ai_settings,screen)
    # Make a group to store bullets in.
    bullets = Group()
    aliens = Group()

    # Create a fleet of aliens
    gf.create_fleet(ai_settings, screen, aliens)
    while True:
        gf.check_events(ai_settings,screen,ship,bullets)
        ship.update()
        bullets.update()
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)

run_game()

game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien

def check_keydown_evnets(event,ai_settings,screen,ship,bullets):
    """This part works when right arrow key is pressed"""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_SPACE:
        fire_bullet(ai_settings,screen,ship,bullets)
    elif event.key == pygame.K_q:
        sys.exit()


def check_keyup_events(event,ship):
    """This part works when right arrow key is released"""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False

def check_events(ai_settings, screen, ship, bullets):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_evnets(event, ai_settings, screen, ship, bullets)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,ship)

def update_bullets(bullets):
    """Update position of bullets and get rid of old bullets."""
    # Update bullet positions.
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)

def fire_bullet(ai_settings, screen, ship, bullets):
    # checks whether max bullets on screen are 3 and adds new bullet
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)

def create_fleet(ai_settings, screen, aliens):
    """Create a full fleet of aliens."""
    # Create an alien and find the number of aliens in a row.
    # Spacing between each alien is equal to one alien width.
    alien = Alien(ai_settings,screen)
    alien_width = alien.rect.width
    available_space_x = ai_settings.screenwidth - (2 * alien_width)
    number_alien_x = int(available_space_x / (2 * alien_width))

    # Create the first row of the alien
    for alien_number in range(number_alien_x):
        # Create an alien and place it in a row
        alien = Alien(ai_settings, screen)
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        aliens.add(alien)


"""updates the screen"""
def update_screen(ai_settings,screen,ship,aliens,bullets):
    # redraw the screen during each pass of the loop
    screen.fill(ai_settings.bg_color)
    # Redraw all bullets behind ship and aliens.
    for bullet in bullets.sprites():
        bullet.draw_bullet()

    ship.blitme()
    aliens.draw(screen)


    # Make the most recently drawn screen visible.
    pygame.display.flip()

bullet.py

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """a class to manage bullets fired from the ship"""
    def __init__(self,ai_settings,screen,ship):
        # create a bullet object from ship current position
        super().__init__()
        self.screen = screen

        # create a bullet
        self.rect = pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top

        # stores bullets position as a decimal
        self.y = float(self.rect.y)

        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor

    def update(self):
        """Move the bullet up the screen."""
        # Update the decimal position of the bullet.
        self.y -= self.speed_factor
        # Update the rect position.
        self.rect.y = self.y

    def draw_bullet(self):
        """Draw the bullets to the screen"""
        pygame.draw.rect(self.screen,self.color,self.rect)

settings.py

class Settings():
    """A class to store all the settings of the game"""

    def __init__(self):
        """Initializes the game settings"""
        #screen settings
        self.screenwidth = 1200
        self.screenheight = 600
        self.bg_color = (200,230,230)

        #ship settings
        self.ship_speed_factor = 1.5

        # Bullet settings
        self.bullet_speed_factor = 0.5
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60, 60, 60
        self.bullets_allowed = 3

ship.py

import pygame

class Ship():
    def __init__(self,ai_settings,screen):
        """Initialize ship at starting position"""
        self.screen = screen
        self.ai_settings = ai_settings
        self.image = pygame.image.load('images/ship2.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = self.screen.get_rect()
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        # Store a decimal value for the ship's center.
        self.center = float(self.rect.centerx)

        # movement flags
        self.moving_right = False
        self.moving_left = False

    """Updates ship when key is pressed whether left or right based on movement flags"""
    def update(self):
        # Update the ship's center value, not the rect.
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.ship_speed_factor

        # Update rect object from self.center.
        self.rect.centerx = self.center

    def blitme(self):
        """Draw the ship at its current location"""
        self.screen.blit(self.image,self.rect)

alien.py

from pygame.sprite import Sprite
import pygame

class Alien(Sprite):
    """A class to represent a single alien in the fleet."""
    def __init__(self, ai_settings, screen):
        """Initialize the alien and set its starting position."""
        super().__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        # Load the alien image and set its rect attribute.
        self.alien_img = pygame.image.load('images/alien.bmp')
        self.rect = self.alien_img.get_rect()

        # Start each new alien near the top left of the screen.
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        # Stores alien's exact position
        self.x = float(self.rect.x)

    def blitme(self):
        """ Draw the aliens at its current position"""
        self.screen.blit(self.alien_img, self.rect)

1 Ответ

1 голос
/ 13 января 2020

Если вы используете Pygame Sprite и Group для рисования спрайта на экране, спрайту требуется атрибут image.

Это не относится ни к классу Alien, ни к Bullet class.

Быстрое исправление для класса Alien - переименовать атрибут alien_img в image, как уже сказал Натан в комментарии.

Есть также много других странных вещей в этом коде, таких как это копирование / удаление

for bullet in bullets.copy():
    if bullet.rect.bottom <= 0:
        bullets.remove(bullet)

вместо использования kill() класса Ship, который выглядит как Sprite с это rect и изображение attribute, но оно не наследуется от pygame.Sprite et c et c.

...