Fight Aliens 外星人展示/移动(左右/上下)

在根目录下新建 alien.py文件即外星人模块,这里把主循环中的代码做了封装,代码实现如下:
alien.py文件代码如下: 
# -*- coding: utf-8 -*-
# 作者: guos
# 日期: 2023/3/30
import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    """
        表示外星人的类
    """
    def __init__(self, screen, gc):
        super().__init__()
        self.screen = screen
        self.gc = gc
        # sprite 中需要 image 和 rect
        # 当指定了这两个属性后,调用group的draw方法时会自动对图层进行绘制
        # 约定优于配置
        self.image = pygame.image.load("./data/alien.bmp")  # 加载图片
        self.rect = self.image.get_rect()  # 获取外星人矩形


    def update(self):
        """
            要更新外星人的位置 即 移动
        :return:
        """
        self.rect.x += self.gc.alien_dir * self.gc.alien_speed
        # 在这里更新方向的话导致部分外星人偏离位置,是因为每次偏移方向会有不同导致有的向左有的向右移动
        # if self.check_side_edge():
        #     self.gc.alien_dir = - self.gc.alien_dir


    def check_side_edge(self):
        """
            检查飞船是否移动到边缘
        :return:
            到达边缘:True
            没有:False
        """
        return self.rect.x <= 0 or self.rect.right >= self.screen.get_rect().right

配置game_config.py文件代码更新如下:

# -*- coding: utf-8 -*-
# 作者: guos
# 日期: 2023/3/29


# 该模块[即一个py文件就是一个模块,命名小写开头]用来存储游戏的配置信息
class GameConfig:
    # 类名:大驼峰
    def __init__(self):
        # 直接将配置信息,存储到GameConfig实例对象中
        self.width = 800  # 游戏窗口宽度
        self.height = 600  # 游戏窗口高度
        self.title = 'Fight Aliens'  # 外星人入侵 游戏标题
        self.bg_color = (230, 230, 230)  # 窗口背景颜色
        self.ship_dir = 0  # 飞船移动的方向 -1 向左 1 向右
        self.ship_speed = 2  # 飞船移动的速度
        # 可以根据充值来提升武器的配置参数
        self.bullet_color = (0, 0, 0)  # 子弹的颜色
        self.bullet_width = 3  # 子弹的宽度
        self.bullet_height = 15  # 子弹的高度
        self.bullet_speed = 1  # 子弹的速度
        self.bullet_count = 3  # 限制子弹的数量【即满屏最多有三个】
        self.alien_dir = 1  # 外星人的移动方向 1 向右移动  -1 向左移动
        self.alien_speed = 1  # 外星人的移动速度


    @property
    def size(self):
        #  @property 使 size变为属性,可以直接 对象.size 来获取值
        # 这里使用来属性方法,返回元组 来动态计算窗口的大小
        return self.width, self.height

入口文件main.py文件代码更新如下:

# -*- coding: utf-8 -*-
# 作者: guos
# 日期: 2023/3/29


# 游戏的主文件,使用该文件来启动游戏
import pygame
from pygame.sprite import Group


from game_config import GameConfig
from ship import Ship


import game_func as gf


# 创建配置对象
gc = GameConfig()


# 初始化
pygame.init()
# 设置窗口大小
screen = pygame.display.set_mode(gc.size)
# 设置窗口的标题
pygame.display.set_caption(gc.title)


# 创建一个飞船实例对象
ship = Ship(screen, gc)


#  弹夹 -- 存放子弹的列表
# bullets = []
bullets = Group()
# 创建 一个group来保存外星人
aliens = Group()
gf.create_aliens(screen, gc, aliens)


# 创建主循环
while True:
    gf.check_and_do_event(screen, gc, bullets, ship)
    gf.show_screen_all(screen, gc, ship, bullets, aliens)

把主循环中的逻辑抽离出来,用函数来封装一下后期好维护,新建game_func.py模块,代码如下:

# -*- coding: utf-8 -*-
# 作者: guos
# 日期: 2023/3/30
# 把主循环中的逻辑拆分为不同的功能函数模块
import pygame
import sys
from bullet import Bullet
from alien import Alien


# 显示屏幕上需要的物料 屏幕 飞船 子弹 外星人
def show_screen_all(screen, gc, ship, bullets, aliens):
    """
        显示屏幕上需要的物料 屏幕 飞船 子弹 外星人
    :param screen: 屏幕对象
    :param gc: GameConfig 配置实例
    :param ship: 飞船实例
    :param bullets: 子弹集合
    :param aliens: 飞船集合
    :return:
    """
    # 设置窗口背景颜色, rgb值
    screen.fill(gc.bg_color)


    # 外星人移动
    aliens.update()
    # 检查外星人是否到边界,来改变其运动的方向,实现左右移动的效果
    check_aliens(gc, aliens)
    # 绘制外星人【需要在背景后绘制】这里使用了Group的draw的方法,但前提是我们的image的属性,必须是这个不然无法实现
    aliens.draw(screen)


    # 更新飞船的位置 必须在显示之前
    ship.update()
    # 只更新类位置,但无法调用 bullets里每个元素的draw_bullet, 所以需要自己调用的都写到update里来实现
    bullets.update()
    # 查看子弹数量是否有变化
    # print(len(bullets))
    # 飞船显示
    ship.blit_ship()
    # 对窗口进行重绘
    pygame.display.flip()




# 处理主循环中处理事件函数
def check_and_do_event(screen, gc, bullets, ship):
    """
        处理主循环中处理事件函数
    :param screen: 屏幕对象
    :param gc: GameConfig 配置实例
    :param bullets: 子弹合集
    :param ship: 飞船实例
    :return:
    """
    # 处理事件
    for event in pygame.event.get():
        # 处理退出的事件
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            # 键盘按下
            check_and_do_keydown(event, screen, gc, bullets, ship)
        elif event.type == pygame.KEYUP:
            # 当键盘松开,如果此时为向左移动或者向右移动时
            check_and_do_keyup(event, gc)




# 处理键盘按下事件
def check_and_do_keydown(event, screen, gc, bullets, ship):
    """
        处理键盘按下事件
    :param event: 事件对象
    :param screen: 屏幕对象
    :param gc: GameConfig 配置实例对象
    :param bullets: 子弹合集
    :param ship: 飞船实例
    :return:
    """
    if event.key == pygame.K_LEFT:
        # 向左移动,设置飞船的移动方向,而不是控制飞船移动 -1
        # 这里把这个方向 放入到 配置对象里
        gc.ship_dir = -1
    elif event.key == pygame.K_RIGHT:
        # 向右移动 1
        gc.ship_dir = 1
    elif event.key == pygame.K_SPACE:
        # 限制子弹数量
        if len(bullets) < gc.bullet_count:
            # 点击空格键开跑 创建子弹实例对象
            # 当我们按下空格键后创建,并append到弹夹中
            # bullets.append(Bullet(screen, gc, ship))
            bullets.add(Bullet(screen, gc, ship))




# 处理键盘松开事件
def check_and_do_keyup(event, gc):
    """
        处理键盘松开事件
    :param event: 事件对象
    :param gc: GameConfig 配置实例
    :return:
    """
    # 何时将 ship_dir 设置为0
    if gc.ship_dir == 1 and event.key == pygame.K_RIGHT or gc.ship_dir == -1 and event.key == pygame.K_LEFT:
        gc.ship_dir = 0




# 创建外星人
def create_aliens(screen, gc, aliens):
    """
        创建外星人
    :param screen: 游戏屏幕对象
    :param gc: GameConfig 配置实例
    :param aliens: 外星人集合
    :return:
    """
    # 如何计算和设计 外星人的数量和位置


    # 外星人的生存空间
    screen_width = gc.width
    screen_height = gc.height
    alien = Alien(screen, gc)
    alien_width = alien.rect.width
    alien_height = alien.rect.height


    # 计算外星人每行的数量: 屏幕宽度 - 留有移动空间(两个外星人的宽度) 剩余空间 使每个外星人占自身宽度的两倍的位置
    alien_col_count = int((screen_width - alien_width * 2) / (alien_width * 2))


    # 计算外星人的行数
    alien_row_count = int((screen_height - alien_height * 3) / (alien_height * 2))


    # 创建外星人的外层循环,控制外星人的行数
    for j in range(alien_row_count):
        # 根据计算出来的外星人每行数量来创建外星人
        for i in range(alien_col_count):
            alien_obj = Alien(screen, gc)
            # 排列   ---外星人---外星人---外星人---外星人   【--- 代表一个外星人】
            # x值:   width * 1  width * 3  width * 5  width * 7
            alien_obj.rect.x = alien_width * (1 + 2 * i)
            # 与顶部保持一个外星人的高度显示上看着更好一些
            alien_obj.rect.y = alien_height * (1 + 2 * j)  # 每行之间的距离算法和每行外星人间的距离算法一样
            aliens.add(alien_obj)




# 检查外星人是否到边界并在到达边界时向下移动
def check_aliens(gc, aliens):
    """
        检查外星人是否移动到边界
    :param gc: GameConfig 配置模块实例
    :param aliens: 外星人集合
    :return:
    """
    for alien in aliens.sprites():
        if alien.check_side_edge():
            gc.alien_dir = - gc.alien_dir


            # 改变方向的时候 改变外星人 y值
            for alien1 in aliens:
                alien1.rect.y += 10
            break

 

posted @ 2023-03-30 16:16  以赛亚  阅读(39)  评论(0编辑  收藏  举报