欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Pygame 外星人入侵(1)

程序员文章站 2022-07-01 20:30:46
Pygame外星人入侵(1)引言:最近从零开始学习python,在看了一些视频后,认识到了看书的重要性,于是选择了基本口碑很不错的Python书籍,目前正在阅读的就是《Python编程:从入门到实践》这本,目前第一部分(基础知识)已经阅读完了,现在要进行第二部分中第一个项目的编写(共3个项目),那就外星人入侵。写这个博文的目的是记录自己学习pygame的一些过程。一、安装pygamePygame是我们编写游戏所需的包,书中给出了不同操作系统下的安装方法,这里我个人没有按照书上的方法来安装,而是在...

Pygame外星人入侵(1)


引言:最近从零开始学习python,在看了一些视频后,认识到了看书的重要性,于是选择了基本口碑很不错的Python书籍,目前正在阅读的就是《Python编程:从入门到实践》这本,目前第一部分(基础知识)已经阅读完了,现在要进行第二部分中第一个项目的编写(共3个项目),那就外星人入侵。
写这个博文的目的是记录自己学习pygame的一些过程。

一、安装pygame

Pygame是我们编写游戏所需的包,书中给出了不同操作系统下的安装方法,这里我个人没有按照书上的方法来安装,而是在 https://pypi.org/ 下进行安装的。

具体安装方法是:
1、打开 https://pypi.org/ ,在搜索栏中输入 pygame 后回车,搜索结果中的第一个便是我们要使用的 pygame 包;单机pygame 1.9.6后,我们需要复制安装指令。
Pygame 外星人入侵(1)
Pygame 外星人入侵(1)
Pygame 外星人入侵(1)
2、在电脑上按下 Win + R 键,再输入 cmd ,按回车;打开命令行窗口。
直接在光标处按右键,可以粘贴我们刚才复制下来的安装指令。等待 pip 自动帮我们安装即可。
Pygame 外星人入侵(1)
Pygame 外星人入侵(1)
3、安装完成后,我们可以这样来验证安装是否成功:
同样是在命令行窗口下,输入 python 后回车,打开python环境。
然后输入 import pygame 尝试导入 pygame 包,成功安装会有相应的提示。Pygame 外星人入侵(1)
至此,我们安装了 pygame 包 作为游戏开发的重要工具。

二、开始游戏项目

新建项目后,我们开始对游戏进行开发,这里整理了书中提到的这个阶段需要做到的事情。

1、导入所需的包/模块

我们这里需要导入刚才安装的 pygame 包 和 sys 包。

首先,pygame包不用多说,游戏的主要功能都需要依靠它来完成。
其次,sys 包可以帮助我们退出游戏,关闭游戏。

import sys
import pygame

2、创建 Pygame 窗口

首先,我们所有游戏的内容,都是在一个游戏窗口上进行的,这里的“游戏窗口”,就是我们大家所熟知的游戏窗口,比如DNF会占电脑屏幕的一部分来游戏,而LOL会在屏幕上全屏显示。

我们的游戏,需要通过 pygame 中的 display 模块来创建窗口。

其次,我们要注意,使用 pygame 包的功能前,除了导入 pygame 包本身外,要需要初始化 pygame 包,才可以正常使用它。
也就是说,要想在程序中使用 pygame 的模块和类,需要两个步骤:
1、导入 pygame 包 或相应的模块
2、初始化 pygame

最后,我们通过 pygame.display.set_mode() 函数创建窗口,其中必须要传入的参数只有一个 size 参数,需要传入一个元组,表示窗口的分辨率,即窗口的大小。set_mode() 的其他参数,暂时不传。

pygame.init()
screen = pygame.display.set_mode(size=(500, 700))

注意:pygame 开发游戏中有一个重要概念,就是 Surface ,这是 pygame 中的一个类,用于表示图片,这是官方文档对于 Surface 的定义:

A pygame Surface is used to represent any image

那么这里为什么要提到 Surface 呢?是因为我们创建的游戏窗口其实就是一个 Surface 对象,我们对于游戏窗口的处理,可以像对一个正常 Surface 对象一个进行处理。换句话说,我们可以把整个游戏窗口,都看作是一张图片来处理。
而且一般来说,一个程序只有一个 display Surface ,所以 pygame.display 模块中的方法,都会自动作用于当前唯一的这个 display Surface 上。也就是说,display 模块的其他方法,都会自动作用于我们创建的游戏窗口。

3、设置窗口的标题

如果我们直接使用刚才创建的pygame窗口来使用,那么你会发现窗口的标题是默认的信息。现在我们想让这个窗口能一眼就让玩家知道,自己是在玩《外星人入侵》这款游戏,那么就可以通过 display 模块的 set_caption 方法来设置窗口的标题。

pygame.display.set_caption('外星人入侵')

4、事件循环

到这里为止,我们已经创建好了 Pygame 窗口并为其修改了标题,使之能显示”外星人入侵“这样的信息。

接下来我们要做的,是为游戏加入一个”事件循环“。
所谓”事件“,也就是 event ,是指所有鼠标、键盘的指令,我们可以通过一个循环来获取鼠标和键盘的指令,也就是我们希望”做出什么样的动作“。

pygame 有一个 event 模块,专门处理事件有关的操作。现在我们可以通过这个模块,来实现当用户点击窗口右上角的关闭按钮时,游戏关闭,窗口消失的效果。

for event in pygame.event.get():
	if event.type == pygame.QUIT:
		sys.exit()

4、显示屏幕

实现了基本的游戏窗口以后,我们需要将这个窗口显示出来,让我们可以在屏幕上看到。

这里同样是使用 display 模块来实现窗口的显示。

pygame.display.flip()

5、填充背景色

如果按照上一小节的方法显示了游戏窗口,那么你会发现,这个游戏窗口的底色是全黑的,这是因为 pygame 默认的游戏窗口就是全黑的,给人一种很压抑的感觉,现在我们想修改游戏窗口的底色,也就是背景色。

首先,需要知道我们到底想设置一个怎么样的颜色作为背景色,也就是设置一个背景色变量,采用(R, G, B)格式的一个元组。(R、G、B的值在0~255之间)。这里我用的是(230, 230, 230)代表一个浅灰色。

其次,我们可以通过 Surface 对象的 fill() 方法来实现对图片进行填充颜色的操作,这个方法可以在一张图片上填充我们指定的颜色,正如之前所说,我们创建的游戏窗口本身就是一个 Surface 对象,因此可以通过 fill() 方法来对其进行填充。

badkground_color = (230, 230, 230)
screen.fill(badkground_color)

6、代码整合

现在,我们需要将上面实现的4部分代码进行一个简单的整合,即封装到一个函数中去。

这里我们将其封装到 run_game()函数中:

def run_game():
    # 初始化 pygame。使其可以绘制屏幕
    pygame.init()

    # 绘制游戏窗口 screen,所有的游戏元素都在这个窗口里运动交互
    screen = pygame.display.set_mode(size=(500, 700))
	
	# 设置游戏窗口背景色 参数
    badkground_color = (230, 230, 230)
    
    # 修改游戏窗口的标题,这里当然是‘外星人入侵’
    pygame.display.set_caption('外星人入侵')

	# 事件检测循环,持续检测来自鼠标、键盘的请求,并作出相应的相应
 	for event in pygame.event.get():
		# 当玩家点击关闭按钮时,退出游戏
 		if event.type == pygame.QUIT:
			sys.exit()
	
	# 为纯黑的游戏屏幕填充上不一样的颜色
    screen.fill(badkground_color)
        
	# 显示屏幕,使得绘制在窗口中的事物能够被观察到
    pygame.display.flip()

至此,我们尝试自己实现书中所提到的内容,并封装成一个函数。

三、运行并调试

现在我们尝试运行刚才写好的函数,看看能否达到我们的预期。

结果是不行的。

游戏窗口确实可以显示出来,但是一瞬间就会消失,所以连截图展示都做不到。那么到底为什么会这样的?

原因是由于我们运行这个函数时,只会刷新一次屏幕,刷新完以后,程序就结束了,那么窗口自然就消失了。

如果需要一直显示游戏窗口,那么就需要将 ‘显示屏幕’ 的代码放到一个循环中,不断地重复刷新屏幕,达到窗口一直显示的预期结果。

但是如果在一个死循环中不断绘制屏幕,那么什么时候才可以退出来呢?

这里我们就想到了之前所做的 ‘事件循环’ 了,在事件循环中,我们可以在用户点击关闭按钮时退出游戏,关闭程序。那么将事件循环的代码,和 显示屏幕 的代码放到同一个死循环中去,就可以达到不断显示屏幕且在用户想退出时,点击关闭按钮即可退出的效果。

此处我们对代码做了如下修改
1、创建一个死循环,达到不断刷新屏幕的效果。
2、在死循环中加入可以退出循环的语句,基于事件。
3、基于上述的描述,为代码加上基本的注释

import sys
import pygame


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

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

    # 设置游戏窗口背景色 参数
    badkground_color = (230, 230, 230)

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

    # 游戏主循环,使得循环中的代码可以不断循环执行
    while True:
        # 事件检测循环,持续检测来自鼠标、键盘的请求,并作出相应的相应
        for event in pygame.event.get():
            # 当玩家点击关闭按钮时,退出游戏
            if event.type == pygame.QUIT:
                sys.exit()

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

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


# 运行游戏主逻辑
run_game()

此时,再运行这段代码,就会得到如下结果:
Pygame 外星人入侵(1)
至此,就达到我们编写代码的预期了。

四、封装设置

我们通过代码实现了简单的 Pygame 窗口的创建,标题的修改,背景色的修改等功能,并将这些代码封装到了一个函数中运行。

但是也存在一些问题,就是我们在写代码过程中,用到了很多参数,比如屏幕的分辨率、标题内容的字符串、背景色的元组 等,在之后可能会用到更多的参数,如果哪天我们需要修改其中的一个参数,那么只能从代码中去找位置,然后修改,这样显然是很不便于维护的。

基于这种考虑,我们可以将所有用到的设置,都保存到一个专门的模块中去,并定义一个设置类,该类的属性即为我们需要用到的参数。

这样处理以后,我们只需要在 run_game() 方法中实例化这个设置类,就可以使用其中的所有属性,即设置的参数了。

动手实践,创建一个 settings.py 模块,在其中定义 Settings 类:

class Settings(object):
    # 设置一系列属性,作为我们游戏中需要用到的参数,
    # 初始化设置类后即可使用.
    def __init__(self):
        # 1、Pygame游戏屏幕的尺寸size
        self.screen_width = 500
        self.screen_height = 700

        # 2、Pygame游戏屏幕上方的标题字符串
        self.screen_title = '外星人入侵'

        # 3、Pygame游戏屏幕的背景色元组(R,G,B)
        self.background_color = (230, 230, 230)

定义完设置类后,游戏主模块的代码就可以做相应的缩减了。
这里我们主要对主模块做了如下修改:
1、从 settings 模块中导入设置类
2、初始化 pygame 时,也初始化 Settings 对象 my_setting 以供使用
3、删除定义背景色的代码
4、将原来代码中所有用到设置参数的位置,都改成从 my_setting 对象中获取参数。

import sys
import pygame
# 导入设置类,存放着我们要用到的所有设置参数
from settings import Settings


# 游戏的主逻辑都在 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)

    # 游戏主循环,使得循环中的代码可以不断循环执行
    while True:
        # 事件检测循环,持续检测来自鼠标、键盘的请求,并作出相应的相应
        for event in pygame.event.get():
            # 当玩家点击关闭按钮时,退出游戏
            if event.type == pygame.QUIT:
                sys.exit()

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

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


# 运行游戏主逻辑
run_game()

这样处理以后,当我们想修改游戏的设置参数值时,只需要在 settings 模块下进行修改即可,不需要对主模块进行修改。

需要注意的是,为了让我们能更加轻松地维护游戏,需要对Settings类中的属性标记上明确的注释,不能有参数意义上的歧义存在。

五、小结

虽然这篇博文中实现的功能很少、很简单、很基础,但是是在脱离书本以后,自己尝试对所学进行输出而得。毕竟学习一些知识以后,检验知识的最好方法就是实践,即输出。在输出的过程中,也遇到了一些问题(三、处的问题),说明自己对于游戏开发的流程还不是很熟悉。而且书中对于代码封装和参数封装的处理思想,我觉得是很值得拿出来记录并分享的,在大型的项目中,这两种思想都很值得借鉴。

本文地址:https://blog.csdn.net/qq_32740521/article/details/107626753