在游戏“外星人入侵”中,为什么我的外星人只出现了一排?

2022-02-22 00:00:00 python python-3.x pygame

问题描述

(instance.py)

    import pygame
    from settings import Settings
    from ship import Ship
    import game_functions as gf

def run_game():
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption('Alien Invasion')
    ship = Ship(ai_settings,screen)
    bullets = pygame.sprite.Group()
    aliens = pygame.sprite.Group()

    gf.create_fleet(ai_settings,screen,ship,aliens)

    while 1:
        gf.check_events(ai_settings,screen,ship,bullets)
        ship.update()
        gf.update_bullet(bullets)
        gf.update_alien(ai_settings,aliens)
        gf.update_screen(ai_settings,screen,ship,bullets,aliens)

run_game()

(Game_functions.py)

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

def check_events(ai_settings,screen,ship,bullets):
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            check_keydown_events(ai_settings,screen,ship,bullets,event)
        if event.type == pygame.KEYUP:
            check_keyup_events(ship,event)

def check_keydown_events(ai_settings,screen,ship,bullets,event):
    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_UP:
        ship.moving['up'] = True
    elif event.key == pygame.K_DOWN:
        ship.moving['down'] = True
    elif event.key == pygame.K_SPACE:
        new_bullet = Bullet(ai_settings,screen,ship)
        bullets.add(new_bullet)
    elif event.key == pygame.K_q:
        sys.exit()

def check_keyup_events(ship,event):
    if event.key == pygame.K_RIGHT:
        ship.moving['right'] = False
    elif event.key == pygame.K_LEFT:
        ship.moving['left'] = False
    elif event.key == pygame.K_UP:
        ship.moving['up'] = False
    elif event.key == pygame.K_DOWN:
        ship.moving['down'] = False

def update_screen(ai_settings,screen,ship,bullets,aliens):
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    aliens.draw(screen)
    pygame.display.flip()

def update_bullet(bullets):
    bullets.update()
    for bullet in bullets.copy():
        if bullet.rect.y < 0:
            bullets.remove(bullet)

def create_fleet(ai_settings,screen,ship,aliens):
    sample_alien = Alien(ai_settings,screen)
    alien_width = sample_alien.rect.width
    alien_height = sample_alien.rect.height

    available_space_x = ai_settings.screen_width - 2 * alien_width
    numbers_alien_x = int(available_space_x / ( 2 * alien_width ))
    available_space_y = ai_settings.screen_height - 3 * alien_height - ship.rect.height
    numbers_alien_y = int(available_space_y / ( 2 * alien_height ))

    for number_alien_y in range(numbers_alien_y):
        for number_alien_x in range(numbers_alien_x):
            alien = Alien(ai_settings,screen)
            alien.rect.x = alien_width + 2 * alien_width * number_alien_x
            alien.rect.y = alien_height + 2 * alien_height * number_alien_y
            aliens.add(alien)

def update_alien(ai_settings,aliens):
    check_fleet_edges(ai_settings,aliens)
    aliens.update()

def check_fleet_edges(ai_settings,aliens):
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(ai_settings,aliens)
            break

def change_fleet_direction(ai_settings,aliens):
    for alien in aliens.sprites():
        alien.rect.y += ai_settings.fleet_drop_speed
    ai_settings.fleet_direction *= -1

(settings.py)

class Settings(object):
    def __init__(self):
        self.screen_width = 1200
        self.screen_height = 700
        self.bg_color = 230,230,230

        self.ship_speed_factor = 1.5

        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 15,15,15
        self.bullet_speed_factor = 1

        self.alien_speed_factor = 2

        self.fleet_drop_speed = 10
        self.fleet_direction = 1

(ship.py)

import pygame

class Ship(object):
    def __init__(self,ai_settings,screen):
        self.ai_settings = ai_settings
        self.screen = screen

        self.image = pygame.image.load('images/ship.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

        self.moving = {'right':False,'left':False,'up':False,'down':False}
        self.centerx = float(self.rect.centerx)
        self.centery = float(self.rect.centery)
        self.speed = self.ai_settings.ship_speed_factor

    def update(self):
        if self.moving['right'] and self.rect.right < self.ai_settings.screen_width:
            self.centerx += self.speed
        if self.moving['left'] and self.rect.left > 0:
            self.centerx -= self.speed
        if self.moving['up'] and self.rect.top > 0:
            self.centery -= self.speed
        if self.moving['down'] and self.rect.bottom < self.ai_settings.screen_height:
            self.centery += self.speed
        self.rect.centerx = self.centerx
        self.rect.centery = self.centery

    def blitme(self):
        self.screen.blit(self.image,self.rect)

(bullet.py)

import pygame
from random import randint

class Bullet(pygame.sprite.Sprite):
    def __init__(self,ai_settings,screen,ship):
        super().__init__()
        self.ai_settings = ai_settings
        self.screen = screen
        self.ship = ship

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

        self.speed = self.ai_settings.bullet_speed_factor
        self.y = float(self.rect.y)

        self.color = randint(1,255),randint(1,255),randint(1,255)

    def update(self):
        self.y -= self.speed
        self.rect.y = self.y

    def draw_bullet(self):
        pygame.draw.rect(self.screen,self.color,self.rect)

(alien.py)

import pygame

class Alien(pygame.sprite.Sprite):
    def __init__(self,ai_settings,screen):
        super().__init__()
        self.ai_settings = ai_settings
        self.screen = screen

        self.image = pygame.image.load('images/alien.bmp')
        self.rect = self.image.get_rect()

        self.speed = self.ai_settings.alien_speed_factor
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)

    def check_edges(self):
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <= 0:
            return True

    def update(self):
        self.x += (self.speed * self.ai_settings.fleet_direction)
        self.rect.x = self.x

我的目标是在整个屏幕上创建外星舰队。 为什么只有一排外星人?


解决方案

问题是在Alienupdate(self)使用self.x的值,但在运行create_fleet(...)时从未设置此值。所以你所有的外星人都已经在那里了,他们只是一个接一个地在上面!

一个简单的解决方案是在create_fleet(...)中初始化每个Alien时,同时设置self.x和For Eachself.rect.x。所以不是:

alien.rect.x = alien_width + 2 * alien_width * number_alien_x

您将拥有:

alien.rect.x = alien.x = alien_width + 2 * alien_width * number_alien_x

相关文章