pygame(1):基本使用(更新中~~~)

楔子

这一次我们来聊一聊python中用于开发2D游戏的框架:pygame,这个框架的历史渊源我就不说了,说这些东西感觉没啥卵用,我们直接来学习怎么用即可。这里我的开发环境是python3.8.1,使用的是Windows系统,而pygame是1.9.6。至于安装的话,直接pip install pygame即可。

# 直接导入,然后执行,如果输出下面这段话、或者不报错,说明安装成功
import pygame
"""
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
"""

绘制一个窗口

当你打开一个游戏,那么首先显示的就是窗口,那么如何显示一个窗口呢?

import pygame, sys

pygame.init()
pygame.display.set_mode((400, 300))
pygame.display.set_caption("你好呀")

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    pygame.display.update()

在解释上面的代码之前,我们先来看看输出:

pygame(1):基本使用(更新中~~~)

我们来解释一下上面的代码:

pygame.init():

这一行表示pygame的初始化,会对pygame内部各功能模块进行初始化创建以及变量设置,确保各个功能能够正常使用。这一行代码会默认调用,所以也可以不写

pygame.display.set_mode((400, 300)):

创建一个窗口,宽400像素、高300像素,需要传入一个元组。这个函数会返回一个pygame中的Surface对象(这里就是屏幕),这个Surface对象是pygame中的一个非常重要的对象,我们后面会详细说。这里只需要知道这里创建了窗口,但是我们并不需要使用变量去接收它。

pygame.display.set_caption("你好呀"):

设置窗口的标题,没什么好说的。

重点来了,下面的那个while循环是非常重要的。

对于游戏来讲,事件是一个非常重要的概念,pygame需要接收事件并且进行响应。而对于pygame来讲,用户的键盘输入、鼠标移动、点击以及窗体的移动等等都是事件,pygame会把所有的事件都放在一个队列里面。通过pygame.event.get()即可拿到存放所有事件的队列,每一个事件在pygame中都是一个Event对象。

所以我们for循环所有的事件,然后对每一个事件进行检测,通过event.type即可得到事件的类型。然后判断是键盘敲击、还是鼠标点击等等,不同的事件我们执行不同的逻辑,这个我们后面会说。我们目前来讲,只进行了一个判断,也就是只检测了一种事件。因为至少要检测一种事件,那就是退出事件。当我们鼠标点击窗口右上角的红色小×,那么事件队列里面就会有事件类型等于pygame.QUIT的事件,然后循环到该事件的时候,我们执行sys.exit(),程序退出。如果连这一个事件检测都没有,而是在for循环里面只写一个pass,那么你会发现游戏的窗口你是关不掉的,只能强行结束python程序。

关于事件,其实很好理解,就是一个接收事件、响应事件的过程,然后还有一个刷新屏幕,为什么要刷新屏幕呢?我们可以从玩游戏的角度来理解。

假设游戏中有一个小人在移动,那么它是怎么移动的呢?首先屏幕中出现的小人,只是我们将小人对应的模型绘制在指定的位置上。小人所谓的移动,只是计算出其移动后的坐标,然后将小人的模型绘制在新的坐标上,所以看起来就像是小人移动了一样。假设小人的初始坐标为(0, 0),然后向右移动,移动到(1, 0),就在(1, 0)的位置上绘制出小人,就像是小人从(0, 0)移动到了(1, 0)。但是问题来了,那么(0, 0)位置上的小人要不要删掉,肯定要。对于游戏来讲,你人物移动了,那么人物就要被绘制在新的位置上,原来位置的人物就不能有了,否则一个单独的人物不就变成多个了吗?移动到新的位置上了,那么老位置上的人物就要删掉。

而pygame.display.update()就是用来刷新屏幕的,它会将屏幕清空,变成初始的样子。因为你游戏中可以不止一个人物在动,所以当所有事件响应完毕、计算出新的位置之后,会将屏幕刷新,然后在新的位置上重新绘制所有人物(或者模型),就仿佛人物在移动一样。另外,这个游戏默认应该是不退出的,也就是要不停的循环事件、并响应,所以我们外面要有一个while True:

当然,由于我们这里没有出现人物的绘制,坐标的计算什么的,可能无法生动形象的解释,但是目前只要理解了相关的机制即可,至于绘制模型、以及加载文字、音乐什么的都很简单。

pygame(1):基本使用(更新中~~~)

最后说一下坐标系,对于pygame来说,一个宽400、高300像素的坐标系,那么它的左上角坐标就是(0, 0),右下角就是(400, 300)。

加载图像

下面我们来看看如何加载一个图像

import pygame, sys

pygame.init()
# 这里用变量来接收
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("你好呀")

# 加载一个图像,支持多种格式,这个同样会返回一个Surface对象
image = pygame.image.load("1.png")
rect = image.get_rect()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    # 绘制
    screen.blit(image, rect)
    pygame.display.update()

pygame(1):基本使用(更新中~~~)

我们来解释上面的代码,我们说pygame.image.load表示加载一个图片,支持多种格式,然后返回一个Surface对象。所以这里有必要介绍一下什么是Surface对象:

我们说创建窗口返回的也是一个Surface对象,加载一个图像也会转化成一个Surface对象,而这个Surface对象就是将图像转化之后的结果。它有一个get_rect函数,表示获取与该图像紧密相切的最小矩形区域

上一篇:IfcBSplineSurface


下一篇:Windows 10 & Linux 的艰难历程