文章目录
pygame是Python的第三方库,里面提供了使用Python开发游戏的基础包,但是在进行游戏开发的时候不推荐使用pygame,本文章以示例的形式对pygame的一些简单的使用方式进行讲解
pygame中文文档,本文章只是对pygame模快有个大致的讲解,具体语法查看官方文档!

pip install pygame -i http://pypi.douban.com/simple/
| 模块名 | 功能 |
|---|---|
| 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 | 缩放和移动图像 |
#!/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对象,每次加载完图片都要调用此方法
处理外部输入(鼠标点击或键盘按下事件)
这意味着游戏在进行的同时,需要响应与处理用户的操作—这些可能是键盘上的键被按下,或鼠标被点击等事件。
更新游戏对象位置或状态
如果飞机对象在空中飞行,收到重力作用,自身的位置需要改变。如果两个对象相互碰撞,则需要爆炸。
渲染
此步骤中,在屏幕上重新绘制所有更新位置后的所有游戏对象。
pygame.display 其为显示模块,用于控制显示窗口和屏幕。
该模块提供对pygame显示的控制。Pygame有一个单一的显示Surface,它要么包含在一个窗口中,要么全屏运行。一旦你创建了显示,你就会把它当作一个普通的Surface。变化在屏幕上并不立即可见;你必须选择两个翻转功能中的一个来更新实际的显示。
显示的原点,其中x=0,y=0,是屏幕的左上方。两个轴都向屏幕右下角正向增加。
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 创建一个没有边框的窗口。
当运行程序后会在电脑桌面上出现一个游戏的主窗口,这个主窗口的本质是一个 surface 对象,把理解为画布、画板、白纸在合适不过了,它相当于一个载体,用于承载一切游戏所用到的元素。假如您需要将一段文本方放置到主窗口中,那么您需要先创建一个包含文本的 surface 对象,之后再将它附加到主窗口上。简单的理解,就是将一张图 A 粘贴到另一张图 B 上。
主窗口(screen)相当于游戏程序中尺寸最大的 Surface 对象,在这个最大的“画布”中,我们还可以添加其他“小”的 Surface 对象,这些对象以矩形的形式存在于主窗口中,它们共同组成了一个游戏程序。
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方法更新界面
| 方法名称 | 说明 |
|---|---|
| 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。 |
pygame 针对文本、图像、颜色提供了不同模块来生成它们各自的 Surface 对象。Surface 模块是Pygame 中专门用来新建图像的,通过该模块可以创建一个 Surface 对象,语法格式如下 :
surface = pygame.Surface(size=(width,height),flags,depth)
参数:
- size:表示 Surface 对象的矩形区域大小;如果不设置尺寸,Surface 默认创建一个和主游戏屏幕同样大小的区域
- flags:功能标志位,有两个可选参数值 HWSURFACE 和 SPCALPHA,前者代表将创建的 Surface 对象存放于显存中,后者表示让图像的每一个像素都包含一个 alpha 通道
- depth:指定像素的颜色深度,默认为自适应模式,由 Pygame 自动调节
语法:
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() # 更新屏幕内容
| 方法 | 说明 |
|---|---|
| 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 对象的尺寸 |
pygame.transform 模块允许您对加载、创建后的图像进行一系列操作,比如调整图像大小、旋转图片等操作,常用方法如下所示:
| 方法 | 说明 |
|---|---|
| pygame.transform.scale() | 将图片缩放至指定的大小,并返回一个新的 Surface 对象 |
| pygame.transform.rotate() | 将图片旋转至指定的角度 |
| pygame.transform.rotozoom() | 以角度旋转图像,同时将图像缩小或放大至指定的倍数 |
#!/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() # 更新屏幕内容
pygame.time 时间控制模块,是 Pygame 中使用频率较高的模块,其主要功能是管理时间和游戏帧数率(即 FPS)。
时间在游戏开发中承担着非常重要的作用,比如释放某个技能所消耗的时间,或者播放动画、声音的持续时间,这些都需要时间来管理。time 模块另外一个重要作用是控制游戏帧数率(即 FPS),它是评价游戏画面是否流畅的关键指标。在一般情况下,计算机的 FPS 都能达到 60帧/s 的速度,这足够我们使用,如果当帧数小于 30 的时候,游戏画面就会变得卡顿。
| 方法 | 说明 |
|---|---|
| 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()
| 方法 | 说明 |
|---|---|
| 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(游戏帧率)影响效果只有在动态图时才能显现出来,不过无论静态图还是动态图,它们的使用规则都是一样的
在 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()
| 方法 | 说明 |
|---|---|
| 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() | 测试两个矩形是否重叠 |
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)是 Pygame 的重要模块之一,它是构建整个游戏程序的核心,比如鼠标点击、键盘敲击、游戏窗口移动、调整窗口大小、触发特定的情节、退出游戏等等,这些都可以看做是“事件”,Pygame 会接受用户产生的各种操作(或事件),这些操作随时产生,并且操作量可大可小,那么 Pygame 是如何处理这些事件的呢?
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 做游戏开发时,上述事件并非都会应用的到,因此在学习的过程中,我们要懂得触类旁通、举一反三。
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('键盘弹起')
键盘事件会涉及到大量的按键操作,比如游戏中的上下左右,或者人物的前进、后退等操作,这些都需要键盘来配合实现。
键盘事件提供了一个 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键 |
关于按键的更多信息:按键信息
鼠标是计算机最重要外接设备之一,同时它也是游戏玩家必不可少的工具之一。
Pygame 提供了三个鼠标事件,分别是鼠标移动(MOUSEMOTION)、鼠标按下(MOUSEBUTTONDOWN)、鼠标释放(MOUSEBUTTONUP),不同事件类型对应着不同的成员属性。
pygame.event.MOUSEMOTION:鼠标移动事件
event.pos :相对于窗口左上角,鼠标的当前坐标值(x,y)event.rel :鼠标相对运动距离(X,Y),相对于上次事件event.buttons :鼠标按钮初始状态(0,0,0),分别对应(左键,滑轮,右键),移动过程中点击那个键,相应位置变会为1pygame.event.MOUSEBUTTONUP:鼠标键释放事件
event.pos: 相对于窗口左上角,鼠标的当前坐标值(x,y)event.button: 鼠标释放键编号(整数)左键为1,按下滚动轮2、右键为3pygame.event.MOUSEBUTTONDOWN :鼠标键按下事件
event.pos: 相对于窗口左上角,鼠标的当前坐标值(x,y)event.button: 鼠标按下键编号(整数),左键为1,按下滚动轮2、右键为3,向前滚动滑轮4、向后滚动滑轮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) # 不断改变图标位置
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 四元组
pygame.draw.rect(surface, color, rect, width)
参数:
- surface:指主游戏窗口,无特殊情况,一般都会绘制在主屏幕上
- color:该参数用于该图形着色
- rect:绘制图形的位置和尺寸大小
- width:可选参数,指定边框的宽度,默认为 0,表示填充该矩形区域
注意,当 width > 0 时,表示线框的宽度;而 width < 0 时,此时不会绘制任何图形
pygame.draw.polygon(surface, color, points, width)
其中 points 一个列表参数,它表示组成多边形顶点的 3 或者多个 (x,y) 坐标,通过元组或者列表来表示这些多边形顶点
pygame.circle(surface, color, pos, radius, width=0)
参数:
- pos:该参数用来指定的圆心位置
- radius:用来指定圆的半径
pygame.draw.ellipse(surface, color, Rect, width=0)
绘制椭圆形的过程,其实就是在矩形区域内部(Rect)绘制一个内接椭圆形
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 参数表示通过绘制混合背景的阴影来实现抗锯齿功能
pygame.lines(surface, color, closed, pointlist, width=1) # 绘制多条直线
pygame.draw.aalines(surface, color, closed, pointlist, blend=1) # 绘制抗锯齿直线
参数:
- pointlist:参数值为列表,包含了一些列点坐标的列表
- closed:布尔值参数,如果设置为 True,表示直线的第一个端点和直线的最后一个端点要首尾相连
#!/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() # 更新画面
文本是任何一款游戏中不可或缺的重要要素之一,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 对象 |
语法:
pygame.font.SysFont(name, size, bold=False, italic=False)
参数:
- name:列表参数值,表示要从系统中加载的字体名称,它会按照列表中的元素顺序依次搜索,如果系统中没有列表中的字体,将使用 Pygame 默认的字体
- size:表示字体的大小
- bold:字体是否加粗
- italic:字体是否为斜体
注意:
- 如果要显示中文,那么一定要使用中文字体文件,比如“方正粗黑宋简体”,否则会出现文字乱码的现象(编程帮三个字无法显示)
语法:
my_font = pygame.font.Font(filename, size)
参数:
- filename:字体路径
- size:字体大小
该字体可以从网上下载
| 方法 | 说明 |
|---|---|
| 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() | 获取字体底端到基准线的距离 |
#!/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),其实在一个游戏程序中,精灵本质指的是一张张小尺寸的图片,比如游戏中的各种道具、人物、场景装饰等,它们都可以看做成一张张小的“精灵”图。除此之外,人物的移动也可以看做是一系列小精灵图构成的序列
如果将逐帧分解后的动作,按照一定的频率播放,那么就形成了动画精灵,您将会看到雄鹰展翅高飞、人在策马奔腾、运动员奋力跳远。
精灵有个特点就是允许精灵之间进行交互,也称之为碰撞,而碰撞检测,指的就是检测两个精灵之间是否发生了碰撞。比如在贪吃蛇游戏中蛇的头部是否与食物发生了碰撞,或者飞机大战游戏中子弹是否击中了外星人等等。当检测到碰撞发生后,接下来会触发某些事件,比如子弹击中外星人,外星人就会消失,玩家的得分也会随之增加,并且在游戏屏幕上又会出现一个外星人。
Pygame 专门提供了一个处理精灵的模块,也就是 sprite(pygame.sprite)模块。通常情况下,我们使用该模块的基类 Sprite 来创建一个子类,从而达到处理精灵的目的,该子类提供了操作精灵的常用属性和方法。
| 属性&方法 | 说明 |
|---|---|
| self.image | 加载要显示的精灵图片,控制图片大小和填充色 |
| self.rect | 精灵图片显示在哪个位置 |
| Sprite.update() | 刷新精灵图,使其相应效果生效 |
| Sprite.add() | 添加精灵图到精灵组中(groups) |
| Sprite.remove() | 从精灵组中删除选中的精灵图 |
| Sprite.kill() | 删除精灵组中全部的精灵 |
| Sprite.alive() | 判断某个精灵是否属于精灵组 |
注意,当游戏中有大量的精灵时,操作它们将变得复杂,此时通过构建精灵容器(group 类)也就是精灵组来统一管理这些精灵。构建方法如下 :
# 创建精灵组
group = pygame.sprite.Group()
# 向组内添加一个精灵
group.add(sprite_one)
| 方法 | 说明 |
|---|---|
| pygame.sprite.collide_rect() | 两个精灵之间的矩形检测,即矩形区域是否有交汇,返回一个布尔值。 |
| pygame.sprite.collide_circle() | 两个精灵之间的圆形检测,即圆形区域是否有交汇,返回一个布尔值。 |
| pygame.sprite.collide_mask() | 两个精灵之间的像素蒙版检测,更为精准的一种检测方式。 |
| pygame.sprite.spritecollide() | 精灵和精灵组之间的矩形碰撞检测,一个组内的所有精灵会逐一地对另外一个单个精灵进行碰撞检测,返回值是一个列表,包含了发生碰撞的所有精灵。 |
| pygame.sprite.spritecollideany() | 精灵和精灵组之间的矩形碰撞检测,上述函数的变体,当发生碰撞时,返回组内的一个精灵,无碰撞发生时,返回 None。 |
| pygame.sprite.groupcollide() | 检测在两个组之间发生碰撞的所有精灵,它返回值是一个字典,将第一组中发生碰撞的精灵作为键,第二个组中发生碰撞的精灵作为值。 |
#!/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()
此外,除了这些主要的模块,还有背景音乐等,其他的请通过官网学习
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
这个问题在这里已经有了答案:WhatisRuby'sdouble-colon`::`?(12个答案)关闭8年前。什么是::?@song||=::TwelveDaysSong.new