赞
踩
各位好,很久没更新博客了,最近较为深入研究pygame库,有些心得体会,想分享给各位,准备做成一个系列知识。欢迎各位查阅。
这篇作为一个基础知识的宣贯,想和各位深入分享一下pygame的基础知识,深入理解函数的使用。
pygame是一个非常非常火的游戏库,那么作为游戏,我相信大家第一印象就是包括:游戏的主界面、游戏里面酷炫的动态效果。
这个相信大家都懂了,就不深入介绍了。
pip install pygame
如果下载很慢,可以搜索一下国内的pip源下载。
在python代码中,需要使用到该库时,需要进行导入。
import pygame
要使用 pygame 提供的所有功能之前,需要调用 init
方法,在游戏结束前需要调用一下 quit
方法
导入并初始化所有 pygame 模块,使用其他模块之前,必须先调用 init 方法
卸载所有 pygame 模块,在游戏结束之前调用!
pygame 专门提供了一个类 pygame.Rect 用于描述 矩形区域Rect(x, y, width, height) -> Rect
。
所有可见的元素 都是以 矩形区域 来描述位置的,要描述一个矩形区域有四个要素:原点 在 左上角 (0, 0),其中:x 轴水平方向向右,逐渐增加;y 轴 垂直方向向 下,逐渐增加。
示例代码如下:
import pygame
pygame.init()
myrect = pygame.Rect(300, 500, 200, 256)
print("myrect坐标原点:%d %d 大小:%d %d" % (myrect.x, myrect.y,myrect.width, myrect.height))
pygame 专门提供了一个 模块 pygame.display
用于创建、管理 游戏窗口
方法 | 说明 |
---|---|
pygame.display.set_mode() | 初始化显示窗口 |
pygame.display.update() | 更新部分内容显示到屏幕上,如果没有参数,则与flip功能相同 |
pygame.display.flip() | 更新整个待显示的Surface对象到屏幕上 |
set_mode(resolution=(0,0), flags=0, depth=0) -> Surface
第一个参数为元祖,代表分 辨率(必须);
第二个参数是一个标志位,如果不用什么特性,就指定0;
第三个参数为色深。
参数 | 说明 |
---|---|
resolution | 指定屏幕的 宽 和 高,默认创建的窗口大小和屏幕大小一致 |
flags | 参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递 |
depth | 参数表示颜色的位数,默认自动匹配 |
返回值:Surface对象(可以理解为:游戏的屏幕),游戏的元素 都需要被绘制到游戏的屏幕上,后续所有的图像绘制都基于这个返回结果
flags标识位 | 功能 |
---|---|
FULLSCREEN | 创建一个全屏窗口 |
DOUBLEBUF | 创建一个“双缓冲“窗口,建议在HWSURFACE或OPENGL时使用 |
HWSURFACE | 创建一个硬件加速窗口,必须和FULLSCREEN同时使用 |
OPENGL | 创建一个OPENGL渲染的窗口 |
RESIZABLE | 创建一个可以改变大小的窗口 |
NOFRAME | 创建一个没有边框的窗口 |
import pygame pygame.init() #游戏初始化的设置,他应该在游戏代码编写的最前边 screen = pygame.display.set_mode((960, 600)) #创建窗口以进行显示;screen定义了一个游戏的屏幕,后续游戏场景中的游戏对象,都要在这个screen上绘制 pygame.display.set_caption("全屏窗口切换") #设置当前游戏窗口的标题 fullscreen = False while True: screen.fill((0, 255, 255)) for event in pygame.event.get(): #pygame.event.get() 游戏中的事件 if event.type == pygame.QUIT: #如果事件类型是退出 exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_F2: fullscreen = not fullscreen if fullscreen: screen = pygame.display.set_mode((1440, 900), pygame.FULLSCREEN) else: screen = pygame.display.set_mode((960, 600), 0) pygame.display.update() #更新窗口
import pygame pygame.init() SCREEN_SIZE = (640, 480) screen = pygame.display.set_mode(SCREEN_SIZE,pygame.RESIZABLE) pygame.display.set_caption("窗口RESIZABLE变换") fullscreen = False while True: screen.fill((0, 255, 255)) for event in pygame.event.get(): if event.type == pygame.QUIT: exit() if event.type == pygame.VIDEORESIZE: #如果窗口大小发生了变化 SCREEN_SIZE=event.size #返回当前窗口大小--元组(宽,高) print(event.size) screen = pygame.display.set_mode(SCREEN_SIZE, pygame.RESIZABLE) pass pygame.display.update()
显示屏幕的更新部分,在调用了绘制函数以便让显示Surface对象看上去是你想要的方式之后,必须调用pygame.display.update()让显示Surface真正地出现在用户的显示器上。
属性:
update(rectangle=None) -> None
update(rectangle_list) -> None
此函数类似于用于软件显示的pygame.display.flip()的优化版本。它只允许更新屏幕的一部分,而不是整个区域。如果没有传递参数,它将更新整个表面积,如pygame.display.flip()。
可以向函数传递单个矩形或一系列矩形。一次传递多个矩形比使用单个或部分矩形列表多次调用update更有效。如果传递了一个不包含任何值矩形序列,则会被跳过。
将整个显示 Surface 更新到屏幕
属性:flip() -> None
这将更新整个显示的内容。如果set_mode函数中设置了显示模式使用的flags是 pygame.HWSURFACE
和 pygame.DOUBLEBUF
,则将等待垂直回溯并交换曲面。如果使用的是不同类型的显示模式,则只需更新窗口的全部内容。
flip函数将重新绘制整个屏幕对应的窗口。
update函数仅仅重新绘制窗口中有变化的区域。
如果仅仅是几个物体在移动,那么他只重绘其中移动的部分,没有变化的部分,并不进行重绘。update比flip速度更快。
在一般的游戏中,如果不是场景变化非常频繁的时候,我们建议使用update函数,而不是flip函数。但是,当使用OpenGL的时候,不能使用pygame.display.update()来更新窗口,需要使用pygame.display.flip()来更新
在游戏中,能够看到的 游戏元素 大多都是 图像
图像文件 初始是保存在磁盘上的,如果需要使用,第一步 就需要 被加载到内存,要在屏幕上 看到某一个图像的内容,需要按照三个步骤:
1、 使用 pygame.image.load() 加载图像的数据 使用 游戏屏幕 对象,
2、使用convert函数是将图像数据都转化为Surface对象,每次加载完图像以后就应该做这件事件(如果你不写pygame也会帮你做);convert_alpha相比convert,保留了Alpha通道信息。
3、调用 blit 方法 将图像绘制到指定位置
使用 pygame.image.load() 加载图像的数据 使用 游戏屏幕 对象。
import pygame import sys # 全局初始化 pygame.init() # 设置窗口的分辨率和标题 resolution = width,height = 480,700 #设置窗口大小和标题 windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】 pygame.display.set_caption("风景如画")#设置标题 #加载背景图,返回的表面可以用于绘制其它对象于其上 bgSurface = pygame.image.load("temp.jpg").convert() while True: for event in pygame.event.get(): # 处理退出事件 if event.type == pygame.QUIT: pygame.quit() sys.exit() # 将背景图像绘制于窗口表面windowSurface windowSurface.blit(bgSurface, (0, 0)) # 绘制结束,刷新界面 pygame.display.update()
可以在 screen 对象完成 所有 blit 方法之后,统一调用一次 display.update 方法,同样可以在屏幕上 看到最终的绘制结果。display.update() 会将 画布 的 最终结果 绘制在屏幕上,这样可以 提高屏幕绘制效率,增加游戏的流畅度。
效果图:
原图:
可以发现原图和效果图对比,明显显示不全。那么我们如何可以显示全呢?
这里就使用了另外的一个函数pygame.transform.scale
,通过该函数调整文件的大小,适配整个屏幕。
picture = pygame.transform.scale(pygame.image.load("image/cc.png"), (480,700))
# (480,700)标识图片的大小信息。
相关代码如下:
import pygame import sys # 全局初始化 pygame.init() # 设置窗口的分辨率和标题 resolution = width,height = 480,700 #设置窗口大小和标题 windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】 pygame.display.set_caption("风景如画")#设置标题 #加载背景图,返回的表面可以用于绘制其它对象于其上 bgSurface = pygame.transform.scale(pygame.image.load("temp.jpg"), (480, 700)).convert() while True: # 将背景图像绘制于窗口表面windowSurface for event in pygame.event.get(): # 处理退出事件 if event.type == pygame.QUIT: pygame.quit() sys.exit() windowSurface.blit(bgSurface, (0, 0)) # 绘制结束,刷新界面 pygame.display.update()
效果图:
可以看到,显示是完整了,但是图片明显是别压缩过。
surface.blit(image,(x,y),rect)
那么,我们可以尝试一下让图片动起来。
import pygame import sys # 全局初始化 pygame.init() # 设置窗口的分辨率和标题 resolution = width,height = 480,700 #设置窗口大小和标题 windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】 pygame.display.set_caption("风景如画")#设置标题 #加载背景图,返回的表面可以用于绘制其它对象于其上 bgSurface = pygame.image.load("temp.jpg").convert() frameRect = bgSurface.get_rect() clock = pygame.time.Clock() while True: # 将背景图像绘制于窗口表面windowSurface for event in pygame.event.get(): # 处理退出事件 if event.type == pygame.QUIT: pygame.quit() sys.exit() windowSurface.blit(bgSurface, (0, 0),frameRect) frameRect.x += 1 # 绘制结束,刷新界面 pygame.display.flip() # 时钟停留一帧的时长 clock.tick(60)
效果图:
pygame 专门提供了一个类 pygame.time.Clock 可以非常方便的设置屏幕绘制速度 —— 刷新帧率,要使用 时钟对象 需要两步:
1)在 游戏初始化 创建一个 时钟对象
2)在 游戏循环 中让时钟对象调用 tick(帧率) 方法
tick 方法会根据 上次被调用的时间,自动设置 游戏循环 中的延时:
clock = pygame.time.Clock()
i = 0
# 游戏循环
while True:
# 设置屏幕刷新帧率
clock.tick(60)
print(i)
i += 1
事件 event:
就是游戏启动后,用户针对游戏所做的操作
例如:点击关闭按钮,点击鼠标,按下键盘…
在 游戏循环 中,判断用户 具体的操作,只有 捕获 到用户具体的操作,才能有针对性的做出响应pygame 中通过 pygame.event.get() 可以获得 用户当前所做动作 的 事件列表
#初始化时钟对象
clock = pygame.time.Clock()
#游戏循环
while True:
# 设置屏幕刷新帧率
clock.tick(60)
# 事件监听
for event in pygame.event.get():
# 判断用户是否点击了关闭按钮
if event.type == pygame.QUIT:
print("退出游戏...")
pygame.quit()
下表是一个常用事件集:
事件 | 说明 |
---|---|
QUIT | 用户按下关闭按钮 |
KEYDOWN | 键盘被按下 |
KEYUP | 键盘被放开 |
MOUSEMOTION | 鼠标移动 |
MOUSEBUTTONDOWN | 鼠标按下 |
MOUSEBUTTONUP | 鼠标放开 |
VIDEORESIZE | 窗口缩放 |
while True:
for event in pygame.event.get():
if event.type == QUIT:
# 接收到退出时间后退出程序
exit()
# 获得鼠标位置
x, y = pygame.mouse.get_pos()
# 将光标画上去
screen.blit(img, (x, y))
# 刷新画面
pygame.display.update()
while True: for event in pygame.event.get(): if event.type == QUIT: exit() if event.type == KEYDOWN: if event.key == K_LEFT: move_x = -1 elif event.key == K_RIGHT: move_x = 1 elif event.key == K_UP: move_y = -1 elif event.key == K_DOWN: move_y = 1 elif event.type == KEYUP: move_x = 0 move_y = 0 x += move_x y += move_y screen.fill((0, 0, 0)) screen.blit(img, (x, y)) # 在新的位置上画图 pygame.display.update()
KEYDOWN和KEYUP的参数说明:
使用VIDEORESIZE进行事件监听。
while True:
event = pygame.event.wait()
if event.type == VIDEORESIZE:
add user code
pygame.display.update()
import pygame import sys pygame.init() resolution = width,height = 800,600 #设置窗口大小和标题 windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】 pygame.display.set_caption("风景如画")#设置标题 bgSurface = pygame.image.load("temp.jpg").convert() # 创建时钟对象 clock = pygame.time.Clock() if __name__ == '__main__': while True: # 处理用户输入 for event in pygame.event.get(): # 处理退出事件 if event.type == pygame.QUIT: pygame.quit() sys.exit() windowSurface.blit(bgSurface, (0, 0)) # 绘制结束,刷新界面 pygame.display.flip() # 时钟停留一帧的时长 clock.tick(60)
运行效果如下:
好的,其实,这篇博文只是想跟大家介绍一下pygame库中的主要函数、实现流程及相关的主要对象,让大家有一个粗略的、较为概念性的认识,后面将会有更多的实战案例和细节分享给大家
欢迎大家持续关注,感谢支持!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。