Pygame 外星人入侵(3)

Pygame 外星人入侵(3)

目录

  • Pygame 外星人入侵(3)
    • 引言
    • 一、重构事件循环
      • 1、自定义模块 game_functions
      • 2、封装函数 check_events()
      • 3、主模块代码缩减
    • 二、重构屏幕更新
      • 1、封装函数 update_screen()
      • 2、主模块代码缩减
    • 三、小结

引言

到这里为止,我们已经可以在一个 Pygame 游戏屏幕上绘制并显示出一架飞船了,且飞船的位置是我们所心仪的。
那么在这部分,我们要对现有的代码做一下重构。目的是简化主模块的代码量。

一、重构事件循环

在 https://blog.csdn.net/qq_32740521/article/details/107626753第一篇博文中,我们在游戏主模块的主循环中写入了一段事件循环代码,作用是不断响应玩家鼠标和键盘的命令,在那里,我们只对玩家关闭游戏的行为做了响应。
但是随着游戏功能的逐渐丰满,我们会要求响应更多的事件,比如鼠标左键点击某个按钮,或者键盘敲击了某个按键。因此,事件响应这一部分的代码,我们考虑用一个函数来进行封装,并且将函数的代码放到另外的模块中去。

1、自定义模块 game_functions

game_functions 模块专门用来存放我们在主模块中复杂的代码,用函数进行封装。
现在我们将事件循环的代码封装到自定义模块中去。

2、封装函数 check_events()

函数的命名要求能见名知意,这个循环的代码所实现的功能就是不断检查事件,因此得名 chcek_events。
现在我们将代码封装到函数中去.

game_functions.py
"""
专门用于存放主模块中复杂的代码,将其封装成一个个函数来使用
"""
import pygame
# 事件循环中有退出游戏的功能,因此需要导入sys模块
import sys


def check_events():
    """
    事件检测循环,持续检测来自鼠标、键盘的请求,并作出相应的相应
    """
    # 循环监视事件的发生
    for event in pygame.event.get():
        # 当玩家点击关闭按钮时,退出游戏
        if event.type == pygame.QUIT:
            sys.exit()
            

3、主模块代码缩减

由于我们已经在 game_functions 模块中封装了事件循环的函数 check_events(),所以主模块中的代码得以缩减。

我们这里要做的有如下几件事:
1、将主模块中原来的事件循环代码删除
2、在主模块中导入 game_functions 模块
3、由于 game_functions 模块中已经导入了 sys 模块,因此可以删除主模块中的 sys 导入代码
4、在原来事件循环的代码处,运行 check_events()函数。

此时的主模块代码:

import pygame
# 导入设置类,存放着我们要用到的所有设置参数
from settings import Settings
# 从ship模块中导入飞船类,用以创建飞船
from ship import Ship
# 从 game_functions 模块中导入所有函数,以供使用
from game_functions import *


# 游戏的主逻辑都在 run_game()函数中运行
def run_game():
    # 初始化 pygame
    pygame.init()

    # 初始化设置类,得到所有我们要用到的设置参数值
    my_setting = Settings()

    # 绘制游戏窗口 screen,所有的游戏元素都在这个窗口里运动交互
    screen = pygame.display.set_mode(size=(my_setting.screen_width, my_setting.screen_height))

    # 修改游戏窗口的标题,这里当然是‘外星人入侵’
    pygame.display.set_caption(my_setting.screen_title)

    # 初始化飞船对象,创建一架飞船
    my_ship = Ship(screen)

    # 游戏主循环,使得循环中的代码可以不断循环执行
    while True:
        # 事件检测,现在我们已经将事件循环的代码封装到函数中了,直接运行即可
        check_events()

        # 为纯黑的游戏屏幕填充上不一样的颜色
        screen.fill(my_setting.background_color)

        # 在背景之上绘制我们的飞船,注意这里的逻辑,必须是飞船在背景之后绘制,确保飞船在背景的上层
        my_ship.blitme()

        # 刷新屏幕,使得元素能够不断刷新位置
        pygame.display.flip()


# 运行游戏主逻辑
run_game()

将来我们如果要增加事件响应的种类和数量,就可以直接在 game_functions 模块下的 check_events() 函数中做修改。

二、重构屏幕更新

1、封装函数 update_screen()

同样,在主模块中,我们将屏幕背景、飞船都一起绘制到了游戏屏幕上,并进行了刷新,这一块代码在游戏主循环中是一定要一直不断执行的,不然会像我在第一篇博文中那样,屏幕一闪即消失。

基于这种情况,我们可以考虑将这部分代码也封装到函数中,并存放到另一个模块中。

def update_screen(screen, setting, ship):
    # 为纯黑的游戏屏幕填充上不一样的颜色
    screen.fill(setting.background_color)

    # 在背景之上绘制我们的飞船,注意这里的逻辑,必须是飞船在背景之后绘制,确保飞船在背景的上层
    ship.blitme()

    # 刷新屏幕,使得元素能够不断刷新位置
    pygame.display.flip()

2、主模块代码缩减

这里我们要做的修改很少,因为刚才在缩减事件循环时已经做了一些
1、删除主模块中原本填充背景色、绘制飞船、刷新屏幕的代码。
2、在删除代码的位置使用封装好的 update_screen() 函数。

import pygame
# 导入设置类,存放着我们要用到的所有设置参数
from settings import Settings
# 从ship模块中导入飞船类,用以创建飞船
from ship import Ship
# 从 game_functions 模块中导入所有函数,以供使用
from game_functions import *


# 游戏的主逻辑都在 run_game()函数中运行
def run_game():
    # 初始化 pygame。使其可以绘制屏幕
    pygame.init()

    # 初始化设置类,得到所有我们要用到的设置参数值
    my_setting = Settings()

    # 绘制游戏窗口 screen,所有的游戏元素都在这个窗口里运动交互
    screen = pygame.display.set_mode(size=(my_setting.screen_width, my_setting.screen_height))

    # 修改游戏窗口的标题,这里当然是‘外星人入侵’
    pygame.display.set_caption(my_setting.screen_title)

    # 初始化飞船对象,创建一架飞船
    my_ship = Ship(screen)

    # 游戏主循环,使得循环中的代码可以不断循环执行
    while True:
        # 事件检测,现在我们已经将事件循环的代码封装到函数中了,直接运行即可
        check_events()

        # 绘制游戏画面,包括屏幕\背景、飞船,并将内容显示到游戏屏幕上
        update_screen(screen, my_setting, my_ship)


# 运行游戏主逻辑
run_game()

至此,我们主模块的代码行数是 38 行(Pycharm提示根据PEP8,有些地方需要空行,这些地方需要空多少我都空出来了),且逻辑更加明了。

三、小结

与第一篇博文类似,书中作者一直在不断地给我们灌输大型项目中应该保持的思想,不断教给我们重构代码、封装代码的思想。我觉得这是很值得学习与借鉴的。
虽然没有功能上的增加,但是项目整体的结构更加丰满,不同模块之间的分工开始明确了;主模块中的代码得到了缩减,且之后的一些功能也会增加到其他模块中,主模块保持一个很少的代码量。

你可能感兴趣的:(外星人入侵,pygame,python,游戏开发)