PyGame 基础语法


目录
  • PyGame 基础语法
    • 一、 模块简介
      • 1、 概述
      • 2、 安装
      • 3、 模块概览
      • 4、 第一个程序
      • 5、 事件循环
    • 二、 Display
      • 1、 简介
      • 2、 创建主窗口
      • 3、 添加元素
        • 3.1 简介
        • 3.2 语法
      • 4、 其他功能
    • 三、 Surface
      • 1、 创建图像
      • 2、 加载图像
      • 3、 其他方法
    • 四、 Transform
      • 1、 语法
      • 2、 案例
    • 五、 Time
      • 1、 简介
      • 2、 游戏暂停
      • 3、 设置游戏帧数
    • 六、 Rectangle
      • 1、 创建矩形
      • 2、 常用方法
      • 3、 成员属性
    • 七、 Event
      • 1、 事件类型
      • 2、 事件处理方法
      • 3、 键盘事件
      • 4、 鼠标事件
      • 5、 应用
    • 八、 Drawl
      • 1、 概述
      • 2、 绘制矩形
      • 3、 绘制多边形
      • 4、 绘制圆形
      • 5、 绘制椭圆形
      • 6、 绘制直线
      • 7、 绘制多条直线
      • 8、 案例
    • 九、Font
      • 1、 概述
      • 2、 从系统加载字体
      • 3、 通过外部加载
      • 4、 字体对象方法
      • 5、 案例
    • 十、 Sprite
      • 1、 简介
      • 2、 创建
      • 3、 碰撞检测
      • 4、 案例

PyGame 基础语法

一、 模块简介

1、 概述

pygame是Python的第三方库,里面提供了使用Python开发游戏的基础包,但是在进行游戏开发的时候不推荐使用pygame,本文章以示例的形式对pygame的一些简单的使用方式进行讲解

pygame中文文档,本文章只是对pygame模快有个大致的讲解,具体语法查看官方文档!

2、 安装

pip install pygame -i http://pypi.douban.com/simple/

3、 模块概览

模块名 功能
pygame.cdrom 访问光驱
pygame.cursors 加载光标
pygame.display 访问显示设备
pygame.draw 绘制形状、线和点
pygame.event 管理事件
pygame.font 使用字体
pygame.image 加载和存储图片
pygame.joystick 使用游戏手柄或者 类似的东西
pygame.key 读取键盘按键
pygame.mixer 声音
pygame.mouse 鼠标
pygame.movie 播放视频
pygame.music 播放音频
pygame.overlay 访问高级视频叠加
pygame 就是我们在学的这个东西了……
pygame.rect 管理矩形区域
pygame.sndarray 操作声音数据
pygame.sprite 操作移动图像
pygame.surface 管理图像和屏幕
pygame.surfarray 管理点阵图像数据
pygame.time 管理时间和帧信息
pygame.transform 缩放和移动图像

4、 第一个程序

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: hello_.py
# @time: 2022/4/18 23:21
from pygame.locals import *  # 里面存储了pygame模块要使用的所有的枚举值
import pygame  # 导入pygame模块
from sys import exit

# 初始化pygame,为使用硬件做准备
pygame.init()
# 创建一个窗口
screen = pygame.display.set_mode((480, 850), 0, 32)
# 设置窗口标题
pygame.display.set_caption("hello world")

# 加载图片
background = pygame.image.load("./img/background.png").convert_alpha()  # 加载透明背景图片
mouse_cursor = pygame.image.load("./img/cursor.ico").convert()  # 加载鼠标图片
mouse_cursor.set_colorkey((0, 0, 0))  # 设置加载图片时,忽略黑色

while True:
    for event in pygame.event.get():  # 添加事件监听
        if event.type == QUIT:  # 接收到退出事件后退出程序
            exit()
    screen.blit(background, (0, 0))  # 画上背景图

    x, y = pygame.mouse.get_pos()  # 获得鼠标位置
    # 计算光标左上角位置
    x -= mouse_cursor.get_width() / 2
    y -= mouse_cursor.get_height() / 2
    # 画上光标
    screen.blit(mouse_cursor, (x, y))
    # 刷新画面
    pygame.display.update()

set_mode:创建一个主窗口

convert:将图像转换为surface对象,每次加载完图片都要调用此方法

5、 事件循环

  1. 处理外部输入(鼠标点击或键盘按下事件)

    这意味着游戏在进行的同时,需要响应与处理用户的操作---这些可能是键盘上的键被按下,或鼠标被点击等事件。

  2. 更新游戏对象位置或状态

    如果飞机对象在空中飞行,收到重力作用,自身的位置需要改变。如果两个对象相互碰撞,则需要爆炸。

  3. 渲染

    此步骤中,在屏幕上重新绘制所有更新位置后的所有游戏对象。

二、 Display

1、 简介

pygame.display 其为显示模块,用于控制显示窗口和屏幕。

该模块提供对pygame显示的控制。Pygame有一个单一的显示Surface,它要么包含在一个窗口中,要么全屏运行。一旦你创建了显示,你就会把它当作一个普通的Surface。变化在屏幕上并不立即可见;你必须选择两个翻转功能中的一个来更新实际的显示。

显示的原点,其中x=0,y=0,是屏幕的左上方。两个轴都向屏幕右下角正向增加。

2、 创建主窗口

screen = pygame.display.set_mode(size=(),flags=0)

参数:

  • size:设置主窗口大小,传入一个元组

  • flag:功能标志位,表示创建的主窗口样式,比如创建全屏窗口、无边框窗口等,flags 参数值见下表

    标志位 功能
    pygame.FULLSCREEN 创建一个全屏窗口。
    pygame.HWSURFACE 创建一个硬件加速窗口,必须和 FULLSCREEN 同时使用。
    pygame.OPENGL 创建一个 OPENGL 渲染窗口。
    pygame.RESIZABLE 创建一个可以改变大小的窗口。
    pygame.DOUBLEBUF 创建一个双缓冲区窗口,建议在 HWSURFACE 或者 OPENGL 时使用。
    pygame.NOFRAME 创建一个没有边框的窗口。

3、 添加元素

3.1 简介

当运行程序后会在电脑桌面上出现一个游戏的主窗口,这个主窗口的本质是一个 surface 对象,把理解为画布、画板、白纸在合适不过了,它相当于一个载体,用于承载一切游戏所用到的元素。假如您需要将一段文本方放置到主窗口中,那么您需要先创建一个包含文本的 surface 对象,之后再将它附加到主窗口上。简单的理解,就是将一张图 A 粘贴到另一张图 B 上。

主窗口(screen)相当于游戏程序中尺寸最大的 Surface 对象,在这个最大的“画布”中,我们还可以添加其他“小”的 Surface 对象,这些对象以矩形的形式存在于主窗口中,它们共同组成了一个游戏程序。

3.2 语法

scrren.blit(source, dest, area=None, special_flags = 0)

参数:

  • source:表示要粘贴的 Surface 对象
  • dest:主窗口中的一个标识的坐标位置,可以接受一个 (x,y) 元组,或者 (x,y,width,height) 元组,也可以是一个 Rect 对象
  • area:接受一个 Rect 对象,默认为 None,如果提供该参数则相当于抠图操作,即在屏幕的指定区域显示想要的内容
  • special_flags:可选参数,它是 Pygame.1.8 版本新增的功能,用于指定对应位置颜色的混合方式,参数值有 BLEND_RGBA_ADD、BLEND_SUB 等。如果不提供该参数的情况下,默认使用 source 的颜色覆盖 screen 的颜色

注意:

  • 使用blit方法后,要使用update或flip方法更新界面

4、 其他功能

方法名称 说明
pygame.display.get_surface() 获取当前显示的 Surface 对象。
pygame.display.flip() 更新整个待显示的 Surface 对象到屏幕上。
pygame.display.update() 更新部分软件界面显示。
pygame.display.Info() 产生一个 VideoInfo 对象,包含了显示界面的相关信息。
pygame.display.set_icon() 设置左上角的游戏图标,图标尺寸大小为 32*32。
pygame.display.iconify() 将显示的主窗口即 Surface 对象最小化,或者隐藏。
pygame.display.get_active() 当前显示界面显示在屏幕上时返回 True,如果窗口被隐藏和最小化则返回 False。

三、 Surface

1、 创建图像

pygame 针对文本、图像、颜色提供了不同模块来生成它们各自的 Surface 对象。Surface 模块是Pygame 中专门用来新建图像的,通过该模块可以创建一个 Surface 对象,语法格式如下 :

surface = pygame.Surface(size=(width,height),flags,depth)

参数:

  • size:表示 Surface 对象的矩形区域大小;如果不设置尺寸,Surface 默认创建一个和主游戏屏幕同样大小的区域
  • flags:功能标志位,有两个可选参数值 HWSURFACE 和 SPCALPHA,前者代表将创建的 Surface 对象存放于显存中,后者表示让图像的每一个像素都包含一个 alpha 通道
  • depth:指定像素的颜色深度,默认为自适应模式,由 Pygame 自动调节

2、 加载图像

语法:

img = pygame.image.load("file_path").convert()  

注意:

  • 此处之所以使用 convert()来转换被加载图片的像素格式,是为了提升 Pygame 对图片的处理速度,该操作能够保证图像的像素格式与图片的显示格式是相同的

通过 image.load() 方法可以加载游戏的背景图,或者游戏中使用的其他元素,比如的人物、道具等等。

如:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: surface_.py
# @time: 2022/4/19 10:02
from pygame.locals import *
import pygame
from sys import exit

# 初始化界面
pygame.init()

# 创建一个窗口
screen = pygame.display.set_mode((300, 300), 0)
# 设置标题
pygame.display.set_caption("Surface对象")
# 使得主窗口的界面为纯白色
screen.fill((255, 255, 255))

# 创建一个Surface对象
surface = pygame.Surface((20, 20), flags=pygame.HWSURFACE)
# 对象填充粉色
surface.fill("pink")

# 加载一个图像对象
img_background = pygame.image.load("./img/background.png").convert()

# 添加事件循环
while True:
    # 循环获取事件,监听事件
    for event in pygame.event.get():
        # 判断用户是否点了关闭按钮
        if event.type == pygame.QUIT:
            # 卸载所有模块
            pygame.quit()
            # 终止程序
            exit()
    # 设置背景图片
    screen.blit(img_background, (0, 0))
    # 将绘制的图像添加到主屏幕上,(100,100)是位置坐标,显示屏的左上角为坐标系的(0,0)原点
    screen.blit(surface, (100, 100))
    pygame.display.update()  # 更新屏幕内容

3、 其他方法

方法 说明
pygame.Surface.blit() 将一个图像(Surface 对象)绘制到另一个图像上
pygame.Surface.convert() 修改图像(Surface 对象)的像素格式
pygame.Surface.fill() 使用纯色填充 Surface 对象
pygame.Surface.scroll() 复制并移动 Surface 对象
pygame.Surface.set_alpha() 设置整个图像的透明度
pygame.Surface.get_at() 获取一个像素的颜色值
pygame.Surface.set_at() 设置一个像素的颜色值
pygame.Surface.get_palette() 获取 Surface 对象 8 位索引的调色板
pygame.Surface.map_rgb() 将一个 RGBA 颜色转换为映射的颜色值
pygame.Surface.set_clip() 设置该 Surface 对象的当前剪切区域
pygame.Surface.subsurface() 根据父对象创建一个新的子 Surface 对象
pygame.Surface.get_offset() 获取子 Surface 对象在父对象中的偏移位置
pygame.Surface.get_size() 获取 Surface 对象的尺寸

四、 Transform

1、 语法

pygame.transform 模块允许您对加载、创建后的图像进行一系列操作,比如调整图像大小、旋转图片等操作,常用方法如下所示:

方法 说明
pygame.transform.scale() 将图片缩放至指定的大小,并返回一个新的 Surface 对象
pygame.transform.rotate() 将图片旋转至指定的角度
pygame.transform.rotozoom() 以角度旋转图像,同时将图像缩小或放大至指定的倍数

2、 案例

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: surface_.py
# @time: 2022/4/19 10:02
from pygame.locals import *
import pygame
from sys import exit

# 初始化界面
pygame.init()

# 创建一个窗口
screen = pygame.display.set_mode((300, 300), 0)
# 设置标题
pygame.display.set_caption("Surface对象")
# 使得主窗口的界面为纯白色
screen.fill((255, 255, 255))
# 加载一个图像对象
img_background = pygame.image.load("./img/background.png").convert()
# 对图像进行缩放
img_new = pygame.transform.scale(img_background, (100, 100))
# 对图像进行旋转
img_new = pygame.transform.rotate(img_new, 45)

# 添加事件循环
while True:
    # 循环获取事件,监听事件
    for event in pygame.event.get():
        # 判断用户是否点了关闭按钮
        if event.type == pygame.QUIT:
            # 卸载所有模块
            pygame.quit()
            # 终止程序
            exit()

    # 添加变换后的图片
    screen.blit(img_new, (100, 100))
    pygame.display.update()  # 更新屏幕内容

五、 Time

1、 简介

pygame.time 时间控制模块,是 Pygame 中使用频率较高的模块,其主要功能是管理时间和游戏帧数率(即 FPS)。

时间在游戏开发中承担着非常重要的作用,比如释放某个技能所消耗的时间,或者播放动画、声音的持续时间,这些都需要时间来管理。time 模块另外一个重要作用是控制游戏帧数率(即 FPS),它是评价游戏画面是否流畅的关键指标。在一般情况下,计算机的 FPS 都能达到 60帧/s 的速度,这足够我们使用,如果当帧数小于 30 的时候,游戏画面就会变得卡顿。

2、 游戏暂停

方法 说明
pygame.time.get_ticks() 以毫秒为单位获取时间
pygame.time.wait() 使程序暂停一段时间
pygame.time.set_timer() 创建一个定时器,即每隔一段时间,去执行一些动作
pygame.time.Clock() 创建一个时钟对象来帮我们确定游戏要以多大的帧数运行
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: surface_.py
# @time: 2022/4/19 10:02
from pygame.locals import *
import pygame
from sys import exit

pygame.init()
screen = pygame.display.set_mode((500, 500))
pygame.display.set_caption("计时器")
# 获取以毫秒为单位的时间
t = pygame.time.get_ticks()  # 该时间指的从pygame初始化后开始计算,到调用该函数为止
print(t)
t1 = pygame.time.wait(3000)  # 暂停游戏3000毫秒
# 暂停t1时间后,加载图片
image_surface = pygame.image.load("./img/background.png")
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    screen.blit(image_surface, (0, 0))
    pygame.display.update()

3、 设置游戏帧数

方法 说明
pygame.time.Clock.tick() 更新clock对象
pygame.time.Clock.get_time() 获取上一个tick中的时间
pygame.time.Clock.get_fps() 计算clock对象的帧率
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: surface_.py
# @time: 2022/4/19 10:02
from pygame.locals import *
import pygame
from sys import exit

pygame.init()  # 初始化游戏
screen = pygame.display.set_mode((500, 500))  # 设置窗口大小
pygame.display.set_caption("计时器")  # 设置标题
clock = pygame.time.Clock()  # 添加一个时钟
image_surface = pygame.image.load("./img/background.png")  # 加载图片
while True:
    clock.tick(40)  # 设置fps最大为每秒40帧
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    screen.blit(image_surface, (0, 0))
    pygame.display.update()

注意:FPS(游戏帧率)影响效果只有在动态图时才能显现出来,不过无论静态图还是动态图,它们的使用规则都是一样的

六、 Rectangle

1、 创建矩形

在 Pygame 中我们使用 Rect() 方法来创建一个指定位置,大小的矩形区域。函数的语法格式如下 :

rect = pygame.Rect(left,top,width,height) 

参数说明:

在 Pygame 中以游戏主窗口的左上角为坐标原点

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: surface_.py
# @time: 2022/4/19 10:02
from pygame.locals import *
import pygame
from sys import exit

pygame.init()  # 初始化游戏
screen = pygame.display.set_mode((500, 500))  # 设置窗口大小
pygame.display.set_caption("计时器")  # 设置标题
image_surface = pygame.image.load("./img/background.png")  # 加载图片
rect = Rect(10, 10, 100, 100)  # 创建一个左上角位于 (10, 10) 宽高为100 的矩形
# 在原图的基础上创建一个新的子图(surface对象)
img_new = image_surface.subsurface(rect)
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    screen.blit(img_new, (0, 0))
    pygame.display.update()

2、 常用方法

方法 说明
pygame.Rect.copy() 复制矩形
pygame.Rect.move() 移动矩形区域,接受一个列表参数
pygame.Rect.move_ip() 移动矩形(无返回)
pygame.Rect.inflate() 增大或缩小矩形大小
pygame.Rect.clamp() 将矩形移到另一个矩形内
pygame.Rect.union() 返回一个两个矩形合并后的矩形
pygame.Rect.fit() 按纵横比调整矩形的大小或移动矩形
pygame.Rect.contains() 测试一个矩形是否在另一个矩形内
pygame.Rect.collidepoint() 测试点是否在矩形内
pygame.Rect.colliderect() 测试两个矩形是否重叠

3、 成员属性

x,y  # 表示矩形距离 x、y 轴的距离
top, left, bottom, right  # 在坐标系内描述矩形的大小
topleft, bottomleft, topright, bottomright  # 返回一个描述矩形大小的元组
midtop, midleft, midbottom, midright  # 返回一个描述矩形大小的元组
center, centerx, centery  # (centerx,centery)表示矩形中央坐标(x,y)的值
size, width, height
w,h  # 用于描述矩形的width、height

这些属性是有读写权限的

七、 Event

事件(Event)是 Pygame 的重要模块之一,它是构建整个游戏程序的核心,比如鼠标点击、键盘敲击、游戏窗口移动、调整窗口大小、触发特定的情节、退出游戏等等,这些都可以看做是“事件”,Pygame 会接受用户产生的各种操作(或事件),这些操作随时产生,并且操作量可大可小,那么 Pygame 是如何处理这些事件的呢?

1、 事件类型

Pygame 定义了一个专门用来处理事件的结构,即事件队列,该结构遵循遵循队列“先到先处理”的基本原则,通过事件队列,我们可以有序的、逐一的处理用户的操作(触发事件)。下述表格列出了 Pygame 中常用的游戏事件:

事件类型 描述 成员属性
QUIT 用户按下窗口的关闭按钮 none
ATIVEEVENT Pygame被激活或者隐藏 gain,state
KEYDOWN 键盘按下 unicode、key、mod
KEYUP 键盘放开 key、mod
MOUSEMOTION 鼠标移动 pos, rel, buttons
MOUSEBUTTONDOWN 鼠标按下 pos, button
MOUSEBUTTONUP 鼠标放开 pos, button
JOYAXISMOTION 游戏手柄(Joystick or pad) 移动 joy, axis, value
JOYBALLMOTION 游戏球(Joy ball) 移动 joy, axis, value
JOYHATMOTION 游戏手柄(Joystick) 移动 joy, axis, value
JOYBUTTONDOWN 游戏手柄按下 joy, button
JOYBUTTONUP 游戏手柄放开 joy, button
VIDEORESIZE Pygame窗口缩放 size, w, h
VIDEOEXPOSE Pygame窗口部分公开(expose) none
USEREVENT 触发一个用户事件 事件代码

注意,当使用 Pygame 做游戏开发时,上述事件并非都会应用的到,因此在学习的过程中,我们要懂得触类旁通、举一反三。

2、 事件处理方法

Pygame.event 模块提供了处理事件队列的常用方法,如下表所示:

方法 说明
pygame.event.get() 从事件队列中获取一个事件,并从队列中删除该事件
pygame.event.wait() 阻塞直至事件发生才会继续执行,若没有事件发生将一直处于阻塞状态
pygame.event.set_blocked() 控制哪些事件禁止进入队列,如果参数值为None,则表示禁止所有事件进入
pygame.event.set_allowed() 控制哪些事件允许进入队列
pygame.event.pump() 调用该方法后,Pygame 会自动处理事件队列
pygame.event.poll() 会根据实际情形返回一个真实的事件,或者一个None
pygame.event.peek() 检测某类型事件是否在队列中
pygame.event.clear() 从队列中清除所有的事件
pygame.event.get_blocked() 检测某一类型的事件是否被禁止进入队列
pygame.event.post() 放置一个新的事件到队列中
pygame.event.Event() 创建一个用户自定义的新事件

当我们使用 Pygame 处理事件时,逻辑一般都是相似的。首先是判断事件的类型,然后根据不同的事件操作,执行不同的游戏操作。因此这种情况非常适合使用if ... else语句。如下所示 :

while True:
    #等待事件发生
    event = pygame.event.wait()
    if event.type == pygame.QUIT:
        exit()
    if event.type == pygame.MOUSEBUTTONDOWN:
        print('鼠标按下',event.pos)
    if event.type == pygame.MOUSEBUTTONUP:
        print('鼠标弹起')
    if event.type == pygame.MOUSEMOTION:
        print('鼠标移动')
        # 键盘事件
    if event.type ==pygame.KEYDOWN:
        # 打印按键的英文字符
        print('键盘按下',chr(event.key))
        print(event.key == pygame.K_a)  # 判断按下到的是否为a键
    if event.type == pygame.KEYUP:
        print('键盘弹起')

3、 键盘事件

键盘事件会涉及到大量的按键操作,比如游戏中的上下左右,或者人物的前进、后退等操作,这些都需要键盘来配合实现。

键盘事件提供了一个 key 属性,通过该属性可以获取键盘的按键。Pygame 将键盘上的字母键、数字键、组合键等按键以常量的方式进行了定义,下表列出了部分常用按键的常量:

常量名 描述
K_BACKSPACE 退格键(Backspace)
K_TAB 制表键(Tab)
K_CLEAR 清除键(Clear)
K_RETURN 回车键(Enter)
K_PAUSE 暂停键(Pause)
K_ESCAPE 退出键(Escape)
K_SPACE 空格键(Space)
K_0...K_9 0...9
K_a...Kz a...z
K_DELETE 删除键(delete)
K_KP0...K_KP9 0(小键盘)...9(小键盘)
K_F1...K_F15 F1...F15
K_UP 向上箭头(up arrow)
K_DOWN 向下箭头(down arrow)
K_RIGHT 向右箭头(right arrow)
K_LEFT 向左箭头(left arrow)
KMOD_ALT 同时按下Alt键

关于按键的更多信息:按键信息

4、 鼠标事件

鼠标是计算机最重要外接设备之一,同时它也是游戏玩家必不可少的工具之一。

Pygame 提供了三个鼠标事件,分别是鼠标移动(MOUSEMOTION)、鼠标按下(MOUSEBUTTONDOWN)、鼠标释放(MOUSEBUTTONUP),不同事件类型对应着不同的成员属性。

  • pygame.event.MOUSEMOTION:鼠标移动事件

    • event.pos :相对于窗口左上角,鼠标的当前坐标值(x,y)
    • event.rel :鼠标相对运动距离(X,Y),相对于上次事件
    • event.buttons :鼠标按钮初始状态(0,0,0),分别对应(左键,滑轮,右键),移动过程中点击那个键,相应位置变会为1
  • pygame.event.MOUSEBUTTONUP:鼠标键释放事件

    • event.pos: 相对于窗口左上角,鼠标的当前坐标值(x,y)
    • event.button: 鼠标释放键编号(整数)左键为1,按下滚动轮2、右键为3
  • pygame.event.MOUSEBUTTONDOWN :鼠标键按下事件

    • event.pos: 相对于窗口左上角,鼠标的当前坐标值(x,y)
    • event.button: 鼠标按下键编号(整数),左键为1,按下滚动轮2、右键为3,向前滚动滑轮4、向后滚动滑轮5

5、 应用

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: event_.py
# @time: 2022/4/19 10:02
from pygame.locals import *  # 导入常量
import pygame
from random import randint
from sys import exit  # 使得程序退出

pygame.init()  # 初始化游戏
screen = pygame.display.set_mode((500, 500))  # 设置窗口大小
pygame.display.set_caption("事件处理")  # 设置标题
image_surface = pygame.image.load("./img/cursor.ico")  # 加载图片
pos = image_surface.get_rect()  # 获取图片位置
while True:
    site = [0, 0]  # 定义变化的位置

    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == KEYUP:
            if event.key == K_RIGHT or event.key == K_a:  # 右移
                site[0] -= 8
            elif event.key == K_LEFT or event.key == K_d:  # 左移
                site[0] += 8
            elif event.key == K_UP or event.key == K_w:  # 上移
                site[1] -= 8
            elif event.key == K_DOWN or event.key == K_s:  # 下移
                site[1] += 8
            pos = pos.move(site)  # 使得坐标移动
            pygame.display.update()  # 更新界面

        if event.type == pygame.MOUSEBUTTONDOWN:
            # pos 获取鼠标当前位置
            mx, my = event.pos
            r = randint(0, 255)
            g = randint(0, 255)
            b = randint(0, 255)
            # 调用 pygame.draw 模块画圆
            pygame.draw.circle(screen, (r, g, b), (mx, my), 50)
            pygame.display.update()  # 更新界面

    screen.fill("white")  # 填充背景,覆盖原来的图标
    screen.blit(image_surface, pos)  # 不断改变图标位置

八、 Drawl

1、 概述

pygame 中提供了一个draw模块用来绘制一些简单的图形状,比如矩形、多边形、圆形、直线、弧线等 。

方法 说明
pygame.draw.rect() 绘制矩形
pygame.draw.polygon() 绘制多边形
pygame.draw.circle() 根据圆心和半径绘制圆形
pygame.draw.ellipse() 绘制一个椭圆形
pygame.draw.arc() 绘制弧线(挥着椭圆的一部分)
pygame.draw.line() 绘制线段(直线)
pygame.draw.lines() 绘制多条连续的线段
pygame.draw.aaline() 绘制一条平滑的线段(抗锯齿)
pygame.draw.aalines() 绘制多条连续的线段

表格中的函数使用方法大同小异,它们都可以在 Surface 对象上绘制一些简单的形状,返回值是一个 Rect 对象,表示实际绘制图形的矩形区域。上述绘图函数都提供了一个 color 参数,我们可以通过以下三种方式来传递 color 参数值:

  • 使用 pygame.color 对象
  • RGB 三元组
  • RGBA 四元组

2、 绘制矩形

pygame.draw.rect(surface, color, rect, width)

参数:

  • surface:指主游戏窗口,无特殊情况,一般都会绘制在主屏幕上
  • color:该参数用于该图形着色
  • rect:绘制图形的位置和尺寸大小
  • width:可选参数,指定边框的宽度,默认为 0,表示填充该矩形区域

注意,当 width > 0 时,表示线框的宽度;而 width < 0 时,此时不会绘制任何图形

3、 绘制多边形

pygame.draw.polygon(surface, color, points, width)

其中 points 一个列表参数,它表示组成多边形顶点的 3 或者多个 (x,y) 坐标,通过元组或者列表来表示这些多边形顶点

4、 绘制圆形

pygame.circle(surface, color, pos, radius, width=0)

参数:

  • pos:该参数用来指定的圆心位置
  • radius:用来指定圆的半径

5、 绘制椭圆形

pygame.draw.ellipse(surface, color, Rect, width=0)

绘制椭圆形的过程,其实就是在矩形区域内部(Rect)绘制一个内接椭圆形

6、 绘制直线

pygame.draw.line(surface, color, start_pos, end_pos, width=1)  # 绘制直线
pygame.aaline(surface, color, startpos, endpos, blend=1)  # 绘制抗锯齿直线

参数:

  • start_pos 和 end_pos 表示线段的起始位置,此处使用 [x,y] 来表示起始位置
  • width =1 表示直线的宽度,默认为 1
  • blend 参数表示通过绘制混合背景的阴影来实现抗锯齿功能

7、 绘制多条直线

pygame.lines(surface, color, closed, pointlist, width=1)  # 绘制多条直线
pygame.draw.aalines(surface, color, closed, pointlist, blend=1)  # 绘制抗锯齿直线

参数:

  • pointlist:参数值为列表,包含了一些列点坐标的列表
  • closed:布尔值参数,如果设置为 True,表示直线的第一个端点和直线的最后一个端点要首尾相连

8、 案例

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: drawl_.py
# @time: 2022/4/19 14:08
from pygame.locals import *  # 导入常量
import pygame
from random import randint
from sys import exit  # 使得程序退出

pygame.init()  # 初始化游戏
screen = pygame.display.set_mode((500, 500))  # 设置窗口大小
pygame.display.set_caption("事件处理")  # 设置标题
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    screen.fill("white")  # 填充背景,覆盖原来的图标
    r = randint(0, 255)
    g = randint(0, 255)
    b = randint(0, 255)
    pygame.draw.line(screen, (r, g, b), [0, 0], (500, 500), 3)  # 画一条直线
    pygame.draw.rect(screen, (r, g, b), Rect(0, 0, 100, 20), 2)  # 画一个矩形线框
    pygame.display.flip()  # 更新画面

九、Font

1、 概述

文本是任何一款游戏中不可或缺的重要要素之一,Pygame 通过pygame.font模块来创建一个字体对象,从而实现绘制文本的目的。该模块的常用方法如下所示:

方法 说明
pygame.font.init() 初始化字体模块
pygame.font.quit() 取消初始化字体模块
pygame.font.get_init() 检查字体模块是否被初始化,返回一个布尔值。
pygame.font.get_default_font() 获得默认字体的文件名。返回系统中字体的文件名
pygame.font.get_fonts() 获取所有可使用的字体,返回值是所有可用的字体列表
pygame.font.match_font() 从系统的字体库中匹配字体文件,返回值是完整的字体文件路径
pygame.font.SysFont() 从系统的字体库中创建一个 Font 对象
pygame.font.Font() 从一个字体文件创建一个 Font 对象

2、 从系统加载字体

语法:

pygame.font.SysFont(name, size, bold=False, italic=False)

参数:

  • name:列表参数值,表示要从系统中加载的字体名称,它会按照列表中的元素顺序依次搜索,如果系统中没有列表中的字体,将使用 Pygame 默认的字体
  • size:表示字体的大小
  • bold:字体是否加粗
  • italic:字体是否为斜体

注意:

  • 如果要显示中文,那么一定要使用中文字体文件,比如“方正粗黑宋简体”,否则会出现文字乱码的现象(编程帮三个字无法显示)

3、 通过外部加载

语法:

my_font = pygame.font.Font(filename, size) 

参数:

  • filename:字体路径
  • size:字体大小

该字体可以从网上下载

4、 字体对象方法

方法 说明
pygame.font.Font.render() 该函数创建一个渲染了文本的 Surface 对象
pygame.font.Font.size() 该函数返回渲染文本所需的尺寸大小,返回值是一个一元组 (width,height)
pygame.font.Font.set_underline() 是否为文本内容绘制下划线
pygame.font.Font.get_underline() 检查文本是否绘制了下划线
pygame.font.Font.set_bold() 启动粗体字渲染
pygame.font.Font.get_bold() 检查文本是否使用粗体渲染
pygame.font.Font.set_italic() 启动斜体字渲染
pygame.font.Font.metrics() 获取字符串中每一个字符的详细参数
pygame.font.Font.get_italic() 检查文本是否使用斜体渲染
pygame.font.Font.get_linesize() 获取字体文本的行高
pygame.font.Font.get_height() 获取字体的高度
pygame.font.Font.get_ascent() 获取字体顶端到基准线的距离
pygame.font.Font.get_descent() 获取字体底端到基准线的距离

5、 案例

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: font_.py
# @time: 2022/4/19 14:08
from pygame.locals import *  # 导入常量
import pygame
from sys import exit  # 使得程序退出

# 初始化
pygame.init()
screen = pygame.display.set_mode((600, 400))
# 填充主窗口的背景颜色
screen.fill((20, 90, 50))
# 设置窗口标题
pygame.display.set_caption('字体设置')
f = pygame.font.Font(r'C:\Windows\Fonts\方正字迹-邢体草书简体.ttf', 50)
# render(text, antialias, color, background=None) -> Surface  antialias 是否抗锯齿
text = f.render("A.L.Kun 坤", True, (255, 0, 0), (255, 255, 255))
# 获得显示对象的 rect区域大小
textRect = text.get_rect()
# 设置显示对象居中
textRect.center = (300, 200)
screen.blit(text, textRect)
while True:
    # 循环获取事件,监听事件
    for event in pygame.event.get():
        # 判断用户是否点了关闭按钮
        if event.type == QUIT:
            # 卸载所有pygame模块
            pygame.quit()
            # 终止程序
            exit()
    pygame.display.flip()  # 更新屏幕内容

还有一个字体处理的更加高级的库,请看官方文档学习: Freetype

十、 Sprite

1、 简介

? 精灵(英文译为 Sprite),其实在一个游戏程序中,精灵本质指的是一张张小尺寸的图片,比如游戏中的各种道具、人物、场景装饰等,它们都可以看做成一张张小的“精灵”图。除此之外,人物的移动也可以看做是一系列小精灵图构成的序列

? 如果将逐帧分解后的动作,按照一定的频率播放,那么就形成了动画精灵,您将会看到雄鹰展翅高飞、人在策马奔腾、运动员奋力跳远。

? 精灵有个特点就是允许精灵之间进行交互,也称之为碰撞,而碰撞检测,指的就是检测两个精灵之间是否发生了碰撞。比如在贪吃蛇游戏中蛇的头部是否与食物发生了碰撞,或者飞机大战游戏中子弹是否击中了外星人等等。当检测到碰撞发生后,接下来会触发某些事件,比如子弹击中外星人,外星人就会消失,玩家的得分也会随之增加,并且在游戏屏幕上又会出现一个外星人。

? Pygame 专门提供了一个处理精灵的模块,也就是 sprite(pygame.sprite)模块。通常情况下,我们使用该模块的基类 Sprite 来创建一个子类,从而达到处理精灵的目的,该子类提供了操作精灵的常用属性和方法。

2、 创建

属性&方法 说明
self.image 加载要显示的精灵图片,控制图片大小和填充色
self.rect 精灵图片显示在哪个位置
Sprite.update() 刷新精灵图,使其相应效果生效
Sprite.add() 添加精灵图到精灵组中(groups)
Sprite.remove() 从精灵组中删除选中的精灵图
Sprite.kill() 删除精灵组中全部的精灵
Sprite.alive() 判断某个精灵是否属于精灵组

注意,当游戏中有大量的精灵时,操作它们将变得复杂,此时通过构建精灵容器(group 类)也就是精灵组来统一管理这些精灵。构建方法如下 :

# 创建精灵组
group = pygame.sprite.Group()
# 向组内添加一个精灵
group.add(sprite_one)

3、 碰撞检测

方法 说明
pygame.sprite.collide_rect() 两个精灵之间的矩形检测,即矩形区域是否有交汇,返回一个布尔值。
pygame.sprite.collide_circle() 两个精灵之间的圆形检测,即圆形区域是否有交汇,返回一个布尔值。
pygame.sprite.collide_mask() 两个精灵之间的像素蒙版检测,更为精准的一种检测方式。
pygame.sprite.spritecollide() 精灵和精灵组之间的矩形碰撞检测,一个组内的所有精灵会逐一地对另外一个单个精灵进行碰撞检测,返回值是一个列表,包含了发生碰撞的所有精灵。
pygame.sprite.spritecollideany() 精灵和精灵组之间的矩形碰撞检测,上述函数的变体,当发生碰撞时,返回组内的一个精灵,无碰撞发生时,返回 None。
pygame.sprite.groupcollide() 检测在两个组之间发生碰撞的所有精灵,它返回值是一个字典,将第一组中发生碰撞的精灵作为键,第二个组中发生碰撞的精灵作为值。

4、 案例

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: font_.py
# @time: 2022/4/19 14:08
from pygame.locals import *  # 导入常量
import pygame
from sys import exit  # 使得程序退出


class Snake(pygame.sprite.Sprite):
    # 定义构造函数
    def __init__(self, filename, location):
        # 调父类来初始化子类
        pygame.sprite.Sprite.__init__(self)
        # 加载图片
        self.image = pygame.image.load(filename)
        # 获取图片rect区域
        self.rect = self.image.get_rect()
        # 设置位置
        self.rect.topleft = location


# 初始化pygame
pygame.init()
screen = pygame.display.set_mode((500, 400))
pygame.display.set_caption('C语言中文网')
# 填充为白色屏幕
screen.fill((255, 255, 255))
filename = "./aircraft battle/Sprites/hero/fly/hero1.png"
location = (100, 150)
snake1 = Snake(filename, location)
# 碰撞检测,必须有两个精灵,因此再创建一个精灵,并使用location来控制第二个精灵的位置
location_2 = (100, 80)
snake2 = Snake('./aircraft battle/Sprites/hero/fly/hero2.png', location_2)
# 调用 collide_rect()进行矩形区域检测,返回一个布尔值,碰撞返回True,否则返回False
crash_result = pygame.sprite.collide_rect(snake1, snake2)
if crash_result:
    print("精灵碰撞了!")
    pass
else:
    print('精灵没碰撞')
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    # 绘制精灵到屏幕上
    screen.blit(snake1.image, snake1.rect)
    screen.blit(snake2.image, snake2.rect)
    # 刷新显示屏幕
    pygame.display.update()

此外,除了这些主要的模块,还有等,其他的请通过官网学习