【python3】第12~14章外星人入侵

第一步 安装pygame

pip install pygame

第二步 创建项目

alien_invasion.py:游戏窗体

settings.py:设置类

ship.py:飞船类

alien_invasion.py
import pygame
import game_functions
from ship import Ship
from settings import Settings
from pygame.sprite import Group
 
def run_game():
    # 初始化背景设置
    pygame.init()
    # 创建名为screen的显示窗口, (1000, 500)为一个元组,指定游戏窗口的尺寸(宽10200px,高500px)
    ai_setting = Settings()
    screen = pygame.display.set_mode((
        ai_setting.screen_width, ai_setting.screen_height
    ))
    # 显示窗口的标题为'Alien Invasion'
    pygame.display.set_caption("Alien Invasion")
 
    # 创建一艘飞船
    ship = Ship(ai_setting, screen)
    # 创建一个用于存储子弹的编组
    bullets = Group()
 
    while True:
        game_functions.check_events(ai_setting, screen, ship, bullets)
        ship.update()
 
        # 删除已消失的子弹
        game_functions.update_bullets(bullets)
         
        game_functions.update_screen(ai_setting, screen, ship, bullets)
 
run_game()
ship.py
import pygame
 
class Ship:
    def __init__(self, ai_settings, screen):
        """初始化飞船并设置其初始位置"""
        self.screen = screen
        self.ai_settings = ai_settings
 
        # 加载飞船图像并获取其外接矩阵
        self.image = pygame.image.load('images/ship.png')
        # get_rect()获取相应surface的属性rect
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
 
        # 将每艘新飞船放在屏幕底部中央
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
 
        # 在飞船的属性center种存储小数值
        self.center = float(self.rect.centerx)
 
        # 移动标志
        self.moving_right = False
        self.moving_left = False
 
    def update(self):
        """根据移动标志调整飞船的位置"""
        if self.moving_right and self.rect.right < self.screen_rect.right:
            # 向右移动飞船
            self.rect.centerx += self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.left > 0:
            # 向左移动飞船
            self.rect.centerx -= self.ai_settings.ship_speed_factor
 
 
    def blitme(self):
        """在指定位置绘制飞船"""
        self.screen.blit(self.image, self.rect)
game_functions.py
import sys
import pygame
from bullet import Bullet
 
def check_keydown_events(event, ai_settings, screen, ship, bullets):
    """响应按键"""
    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)
 
 
def fire_bullet(ai_settings, screen, ship, bullets):
    """如果还没有达到限制,就发射一颗子弹"""
    # 创建新子弹并将其加入到编组bullets中
    if len(bullets) < ai_settings.bullet_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)
 
 
def check_keyup_events(event, ship):
    """响应松开"""
    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循环运行
    for event in pygame.event.get():
        # 单击游戏窗口的关闭按钮时,将触发pygame.QUIT事件
        if event.type == pygame.QUIT:
            # 退出游戏
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, ai_settings, screen, ship, bullets)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event, ship)
 
 
def update_screen(ai_settings, screen, ship, bullets):
    """更新屏幕上的图像,并切换到新屏幕"""
    # 每次循环时都重绘屏幕
    # fill()用于背景色填充屏幕,只接受一个实参:一种颜色
    screen.fill(ai_settings.bg_color)
 
    # 再飞船和外星人后面重绘所有子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()
 
    # 将飞船绘制在屏幕上,确保它出现在背景前面
    ship.blitme()
 
    # 每次执行while循环时都绘制一个空屏幕,并擦去旧屏幕,使得只有新屏幕可见
    # pygame.display.flip()不断更新屏幕,以显示元素的新位置,并在原来的位置影藏元素
    pygame.display.flip()
 
 
def update_bullets(bullets):
    """更新子弹的位置,并删除已消失的子弹"""
    # 更新子弹的位置
    bullets.update()
 
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)
settins.py
class Settings:
    def __init__(self):
        """初始化游戏的设置"""
        # 屏幕设置
        self.screen_width = 1000
        self.screen_height = 500
        self.bg_color = (230230230)
 
        # 飞船的设置
        self.ship_speed_factor = 1.5
 
        # 子弹设置
        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 606060
        self.bullet_allowed = 3
bullet.py
import pygame
from pygame.sprite import Sprite
 
class Bullet(Sprite):
    """一个对飞船发射的子弹进行管理的类"""
 
    def __init__(self, ai_settings, screen, ship):
        """在飞船所处的位置创建一个子弹对象"""
        # 调用super()来继承Sprite
        # 也可写为super().__init__()
        super(Bullet, self).__init__()
        self.screen = screen
 
        # 在(0, 0)出创建一个表示字段的矩形,再设置正确的位置
        self.rect = pygame.Rect(00, ai_settings.bullet_width, ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top
 
        # 存储用小数表示的子弹位置
        self.y = float(self.rect.y)
 
        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor
 
    def update(self):
        """向上移动子弹"""
        # 更新表示子弹位置的小数值
        self.y -= self.speed_factor
        # 更新表示子弹的rect的位置
        self.rect.y = self.y
 
    def draw_bullet(self):
        """再屏幕上绘制子弹"""
        pygame.draw.rect(self.screen, self.color, self.rect)
原文地址:https://www.cnblogs.com/CSgarcia/p/13267941.html