前言
基础模块的知识通过这么长时间的学习已经有所了解,更加深入的话需要通过完成各种项目,在这个过程中逐渐学习,成长。
我们的下一步目标是完成python crash course中的外星人入侵项目,这是一个2D游戏项目。在这之前,我们先简单学习一下pygame模块。
私信我发送消息python资料,领取python crash course中文版PDF。
Pygame
Pygame是一个开源的Python多媒体开发库,专门用于开发2D游戏。它是Python编程语言的一个扩展,基于 SDL (Simple DirectMedia Layer) 库,提供了丰富的功能来处理图形、声音、事件处理等游戏开发所需的基本要素,使得创建游戏变得更加简单直接。
图形绘制
主要使用pygame.draw模块进行基本图形的绘制,包括矩形,圆形,多边形等。
Surface
Surface
是一个非常核心的概念。Surface
对象可以被理解为一个二维的矩形画布,它有自己的像素格式和尺寸。这个对象允许你在其上绘制图像、图形、文本等内容,并且可以与其他 Surface
对象进行组合或层叠,以构建复杂的游戏画面。
图形绘制的操作,都需要在这个对象上进行。
Surface 对象具有以下特性:
- 像素访问:你可以直接访问 Surface 上的每一个像素,进行读取或修改。
- 绘制功能:Surface 提供了多种方法来在上面绘制图形,如 draw.rect(), draw.circle(), draw.line() 等。
- 转换:你可以使用 convert() 或 convert_alpha() 方法来改变 Surface 的像素格式,以优化性能或支持透明度。
- 混合:Surface 支持像素级别的混合操作,可以将一个 Surface 的颜色与另一个 Surface 的颜色混合。
- 复制和剪切:你可以从一个 Surface 复制部分区域到另一个 Surface 上,或者剪切并粘贴。
- 位图操作:Surface 支持位图操作,如翻转(flip())和旋转(rotate())。
- blit:这是 Surface 最常用的方法之一,用于将一个 Surface 的内容绘制到另一个 Surface 上。
- 透明度:Surface 可以设置全局的 alpha 透明度,也可以在绘制时指定局部的透明度。
在 Pygame 中,最常见的 Surface 类型是 Display Surface,它是游戏主窗口的 Surface。你可以使用 pygame.display.set_mode() 来创建一个 Display Surface。此外,你还可以使用 pygame.Surface() 构造函数来创建任意大小和格式的 Surface 对象。
我们的图形绘制,可以简单理解为在主窗口的Surface
基础上堆叠自己定义的子Surface
。
下面我们通过简单的一个示例,执行了解一下。
import pygame
# 初始化 Pygame
pygame.init()
# 创建一个 Display Surface, 也就是我们说的主窗口
screen = pygame.display.set_mode((800, 600))
# 创建一个额外的 Surface,这个就是我们堆叠在主窗口中的子画布对象
extra_surface = pygame.Surface((200, 100))
# 在 extra_surface 上绘制一个矩形,这些参数在图形绘制里面会讲,这里主要理解Surface堆叠
pygame.draw.rect(extra_surface, (255, 0, 0), (0, 0, 100, 50))
# 将 extra_surface 绘制到 screen (主窗口) 上
screen.blit(extra_surface, (300, 200))
# 更新屏幕显示
pygame.display.flip()
# 点击关闭退出程序,这个后面再讲,代码可以先写上。
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
可以看到,我们的窗口中间有个红色的正方形,这就是我们在新画布上绘制的一个矩形。
这部分主要帮助理解pygame中的类似图层的一种概念,帮助后面在绘制图形和游戏制作的时候不会迷糊。
draw
pygame.draw模块就是我们实际用于绘制图形的模块,当然图形绘制的函数中都有一个参数是Surface
,这是绘制图形所需的画布。接下来讲解一下常用的几个图形绘制函数。
矩形(rect)
pygame.draw.rect(Surface, color, Rect, width=0)函数可以绘制矩形。
参数说明:
- Surface: 要在其上绘制矩形的窗口或屏幕对象。
- color: 矩形的颜色,一个 RGB 值的三元组,其中每个颜色通道的值范围从 0 到 255。例如,纯红色可以用 (255, 0, 0) 表示,纯绿色用 (0, 255, 0),纯蓝色用 (0, 0, 255),而白色则是 (255, 255, 255),黑色是 (0, 0, 0)。
- Rect: 矩形的位置和尺寸,格式为 [x坐标, y坐标, 宽度, 高度]。通常以画布左上角顶点为基准位置,即x=0,y=0,区别与一般的坐标轴,y的值都是正值。
- width: 矩形的边框宽度,如果为 0 或省略,则矩形将被填充。
接下里看代码和执行结果解释函数。
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
pygame.display.set_caption('Draw Shapes')
# 绘制一个填充的红色矩形
pygame.draw.rect(screen, (255, 0, 0), (50, 50, 100, 100))
# 绘制一个未填充的蓝色矩形,边框宽度为 3
pygame.draw.rect(screen, (0, 0, 255), (150, 150, 100, 100), 3)
# 更新屏幕
pygame.display.flip()
# 点击关闭退出程序,这个后面再讲,代码可以先写上。
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
代码解释如下:
1. 导入pygame。
2. 初始化pygame模块。
3. 创建一个400*400的窗口。
4. 设置窗口名为Draw Shapes
。
5. 绘制一个矩形。绘制画布是主窗口(之前讲解Surface
的时候用的是新建的字画布,这里直接用窗口,窗口也是画布,都是Surface
对象),设置矩形颜色为红色,设置矩形的信息(50,50,100,100),宽度为默认值0,也就是说这个矩形会被红色填充。
6. 绘制一个矩形,绘制画布同样是主窗口,设置矩形颜色为蓝色,矩形信息(150,150,100,100),宽度为3,说明这个矩形是蓝色边框,未被填充的矩形。
7. 更新屏幕,就是把图形更新的到窗口上显示出来。
8. while循环监听事件,如果点击了关闭窗口,我们的Python程序结束。这一步其实是从17行开始的所有代码,后面讲到事件和输入的时候再仔细讲。
通过代码和执行结果,很简单就能矩形的绘制了。那么,关于width参数,如果参数大于等于矩形最大边长,会发生什么呢?大家自行了解。
圆形(circle)
pygame.draw.circle(Surface, color, center, radius, width=0)函数可以绘制圆形。
参数说明:
- Surface: 要在其上绘制圆形的窗口或屏幕对象。
- color: 圆形的颜色。
- center: 圆心的位置,一个二元组 (x, y)。
- radius: 圆的半径。
- width: 边框宽度,如果为 0 或省略,则圆形将被填充。
圆形的参数就很简单了,不单独讲水字数了,通过代码和执行结果就能明白。
# 省略与矩形绘制相同的代码,后面不在单独注释了
--snip--
# 绘制一个填充的红色圆
pygame.draw.circle(screen, (255, 0, 0), (200, 100), 50)
# 绘制一个未填充的绿色圆
pygame.draw.circle(screen, (0, 255, 0), (200, 200), 50, 5)
# 省略与矩形绘制相同的代码,后面不在单独注释了
--snip--
执行结果如上图,圆心坐标的基准值依旧是窗口左上角顶点为坐标轴顶点。
多边形(polygon)
pygame.draw.polygon(Surface, color, pointlist, width=0)函数用于绘制多边形。
参数说明:
- Surface: 要在其上绘制多边形的窗口或屏幕对象。
- color: 多边形的颜色。
- pointlist: 多边形顶点的列表,每个顶点是一个二元组 (x, y)。
- width: 边框宽度,如果为 0 或省略,则多边形将被填充
参数大同小异,区别在顶点坐标的元组。也就是说我们绘制多边形的时候,如果想绘制等边多边形,必须自己计算好坐标的值,都学Python了,肯定不能硬算,写个程序计算各个坐标吧。
--snip--
# 绘制一个填充的不知道啥颜色的多边形
pygame.draw.polygon(screen, (125, 125, 125), ((250, 50), (350, 50), (350, 150), (250, 150)))
# 绘制一个未填充的不知道啥颜色的多边形
pygame.draw.polygon(screen, (125, 125, 125), ((250, 150), (350, 150), (350, 250), (250, 250)), 5)
--snip--
注意看,我们通过多边形的函数,画出了一个正方形并设置了一个灰色的参数。这里要注意的是,这个顶点的坐标元组,每个顶点的左边必须按正常绘画顺序来添加。比如正方是的左边顶点分别为AB,右边顶点分别为CD。那么我们在设置顶点元组的顺序时,必须按照绘画顺序也就是A=>B=>D=>C或者A=>D=>C=>B这样的顺序添加顶点坐标到元组。当然你也可以试试不按顺序。
线条(line)
pygame.draw.line(Surface, color, start_pos, end_pos, width)函数可以绘制出线条,或者说是线段。
参数说明:
- Surface: 要在其上绘制线条的窗口或屏幕对象。
- color: 线条的颜色。
- start_pos: 线条起点的位置,一个二元组 (x, y)。
- end_pos: 线条终点的位置,一个二元组 (x, y)。
- width: 线条的宽度,必填!!!线条没有填充的说法,必填宽度。
线条的绘制比较简单,就标两个点的坐标就行,当然线条没有填充这个说法,宽度参数就是线条的宽度。简单过一下。
--snip--
# 绘制一个绿色线条
pygame.draw.line(screen, (0, 255, 0), (400, 50), (400, 250), 1)
# 绘制一个绿色线条
pygame.draw.line(screen, (0, 255, 0), (450, 50), (450, 250), 5)
--snip--
椭圆(ellipse)
pygame.draw.ellipse(Surface, color, Rect, width=0)函数可以绘制椭圆。
参数说明:
- Surface: 要在其上绘制椭圆的窗口或屏幕对象。
- color: 椭圆的颜色。
- Rect: 椭圆的边界矩形,格式为 [x坐标, y坐标, 宽度, 高度]。
- width: 边框宽度,如果为 0 或省略,则椭圆将被填充。
看参数的话,椭圆的绘制和矩形的绘制差不多,底层应该是用矩形的边界确定椭圆的长边和短边然后绘制出椭圆,也简单过一下就好。
--snip--
# 绘制一个填充的红色椭圆
pygame.draw.ellipse(screen, (0, 0, 255), (550, 50, 150, 100))
# 绘制一个未填充的蓝色椭圆,边框宽度为 3
pygame.draw.ellipse(screen, (0, 0, 255), (550, 150, 150, 100), 3)
--snip--
假如我们绘制椭圆时,边界矩形是个正方形,我们绘制出的图形会是什么呢?
结尾
图形绘制就将这个几个函数,基本上已经满足图形绘制的要求了。后面在学习图片的填充,在2D游戏中,所有的模型基本都是由图形绘制或者图片填充而成的,这两个模块的内容学完,基本就可以绘制出游戏的人物和地图了。
作业
- 绘制矩形,圆形,多边形,线条,矩形。
- 验证绘制多边形时不按顺序填入顶点元组。
- 绘制椭圆时边界矩形设置成正方形。