首页 > 解决方案 > P速成班,外星人入侵计划第14章-游戏黑屏而不是显示按钮

问题描述

所以我正在经历外星人入侵项目,除此之外我还没有遇到任何我无法解决的问题。我正在尝试从书中输入并制作一个在游戏开始时透明覆盖的按钮。当我这样做时,游戏以黑屏开始。我已经在 Vs Code 和 Sublime 中测试了该程序,它在两者中都做了同样的事情。

按钮在那里,我使用下一章的代码对其进行了测试。我可以在那里告诉它,因为当我将鼠标移动到屏幕中间时,它会正常触发游戏。这真的很奇怪。

我一直在反复检查代码,但我找不到任何输入问题。我也会检查前几章的输入。

任何帮助都会很棒,因为这似乎真的很愚蠢。

注意:我只包括了相关的方法。如果您想查看其他人的代码,请询问。

链接到问题的图像在这里。

alien_invasion.py
import sys
import pygame
from time import sleep
from settings import Settings
from game_stats import GameStats
from ship import Ship
from bullet import Bullet
from alien import Alien
from button import Button

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

def __init__(self):
    """Initialize the game and create game resources."""
    pygame.init()
    
    self.settings = Settings()
    #window settings
    self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
    
    #windowed settings
    #fullscreen 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
    #fullscreen settings
    pygame.display.set_caption("Alien Invasion")
    self.stats = GameStats(self) 
    self.ship = Ship(self)
    self.bullets = pygame.sprite.Group()
    self.aliens = pygame.sprite.Group()
    self._create_fleet()

    #Make the Play button.
    self.play_button = Button(self, "Play")

def run_game(self):
    """Start the main loop for the game."""
    while True:
        self._check_events()
        
        if self.stats.game_active:
            self.ship.update()
            self._update_bullets()
            self._update_screen()
            self._update_aliens()

        
def _check_events(self):
    """Respond to keypresses and mouse events."""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            self._check_keydown_events(event)
        elif event.type == pygame.KEYUP:
            self._check_keyup_events(event)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            self._check_play_button(mouse_pos)



def _ship_hit(self):
    """Respond to the ship being hit by an alien."""
    if self.stats.ships_left > 0:
        #Decrement ships_left.
        self.stats.ships_left -= 1

        #Get rid of any remaining aliens and bullets.
        self.aliens.empty()
        self.bullets.empty()

        #Create a new fleet and center the ship.
        self._create_fleet()
        self.ship.center_ship()

        #Pause
        sleep(0.5)
    else:
        self.stats.game_active = False

def _update_screen(self):
    """Update images on the screen, and flip to the new screen."""
    self.screen.fill(self.settings.bg_color)
    self.ship.blitme()
    
    for bullet in self.bullets.sprites():
        bullet.draw_bullet()
    
    self.aliens.draw(self.screen)
    
    #Draw the play button if the game is inactive.
    if not self.stats.game_active:
        self.play_button.draw_button()

    pygame.display.flip()

if __name__ == '__main__':
    #Make a game instance and run the game.
    ai = AlienInvasion()
    ai.run_game()

按钮.py

import pygame.font

class Button:

def __init__(self, ai_game, msg):
    """Initialize button attributes."""
    self.screen = ai_game.screen
    self.screen_rect = self.screen.get_rect()
    #Set the dimensions and properties of the button.
    self.width, self.height = 200, 50
    self.button_color = (0, 255, 0)
    self.text_color = (255, 255, 255)
    self.font = pygame.font.SysFont(None, 48)

    #Build the button's rect object and center it.
    self.rect = pygame.Rect(0, 0, self.width, self.height)
    self.rect.center = self.screen_rect.center

    #The buttone needs to be prepped only once.
    self._prep_msg(msg)

def _prep_msg(self, msg):
    """Turn msg into a rendered image and center text on the button."""
    self.msg_image = self.font.render(msg, True, self.text_color, self.button_color)
    self.msg_image_rect = self.msg_image.get_rect()
    self.msg_image_rect.center = self.rect.center

def draw_button(self):
    #Draw a blank button then draw message
    self.screen.fill(self.button_color, self.rect)
    self.screen.blit(self.msg_image, self.msg_image_rect)

游戏统计.py

class GameStats:

def __init__(self, ai_game):
    """Initialise statistics."""
    self.settings = ai_game.settings
    self.reset_stats()
    
    #Start Alien Invasion in an inactive state.
    self.game_active = False

def reset_stats(self):
    """Initialise statistics that can change during the game."""
    self.ships_left = self.settings.ship_limit
    

标签: pythonbuttonpygame

解决方案


你的按钮代码很好。

问题是您只能在_update_screen()任何时候将按钮绘制到屏幕上not self.stats.game_active。这都很好。

但!您不会调用_update_screen()unless self.stats.game_active,因此在“按钮显示”模式下,不会绘制任何内容:

def run_game(self):
    """Start the main loop for the game."""
    while True:
        self._check_events()
        
        if self.stats.game_active:      #  <<-- HERE
            self.ship.update()
            self._update_bullets()
            self._update_screen()       #  <<-- AND HERE
            self._update_aliens()

解决方案是始终绘制屏幕:

def run_game(self):
    """Start the main loop for the game."""
    while True:
        self._check_events()
        
        if self.stats.game_active:     
            self.ship.update()
            self._update_bullets()
            self._update_aliens()

        self._update_screen()           #  <<-- HERE (always paint)

推荐阅读