「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」
本系列专栏将通过不断编写游戏的方式,带你夯实 Python 知识。
本专栏追求迅速掌握 pygame 的同时,夯实 python 知识,所以一起来学习吧。
本篇博客目的
一次性加载所有素材图片,在通过调用指定图片的名称,获取图片上的某个目标区域(子图)。
可以先临摹并理解代码,最终实现效果如下所示。
实现上图效果的代码如下所示,在编写的时候可以在重要部分增加注释,辅助理解。
import pygame
import os
import sys
pygame.init()
screen = pygame.display.set_mode((400, 400))
# accept 参数限制了传入的图片格式
def load_graphics(path, accept=(".jpg", ".png", ".jpeg")):
graphics = {}
for pic in os.listdir(path):
name, ext = os.path.splitext(pic)
if ext.lower() in accept:
img = pygame.image.load(os.path.join(path, pic))
# 判断图片是否透明背景
if img.get_alpha():
img = img.convert_alpha()
else:
# 加快游戏加载图片操作
img = img.convert()
graphics[name] = img
return graphics
def get_image(target, x, y, width, height, colorkey):
image = pygame.Surface((width, height))
image.blit(target, (0, 0), (x, y, width, height))
image.set_colorkey(colorkey)
return image
if __name__ == "__main__":
while True:
# imgs 文件夹里面的图片自行准备即可,文件名随意
# 可以准备各种后缀名的图片
graphics = load_graphics("./imgs")
print(graphics)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill((12, 200, 180))
# 类似 335,160,70,60,都是根据不同图片测量的,你可以通过截图工具或者画板进行测量。
small_img = get_image(
graphics["one_pic1"], 335, 160, 70, 60, (0, 0, 0))
screen.blit(small_img, (100, 100))
pygame.display.update()
代码部分的详细说明与避坑指南
load_graphics
函数作用是调用文件夹所有图片,然后再返回一个字典,字典的键为图片名,值是 pygame.image.load
函数加载的一个 Surface 对象。
代码中需要掌握的重点函数有 img.get_alpha()
,该函数用于判断图片是否为透明图片,即带 alpha
值。
使用方式为 pygame.Surface.get_alpha()
,可获取整个图像的透明度,当图片有透明区域的时候,会返回具体的值,一般都是 255,测试本场景可以在文件夹中放置一些不具备透明度的图片,根据文件名进行返回,不透明图片返回不是 0,是 None。
图片1.png 255
图片2.png 255
图片3.png 255
图片4.png 255
图片5.jpg None
pygame.Surface.convert()
函数用于修改图像(Surface 对象)为像素格式;
pygame.Surface.convert_alpha()
函数也用于修改图像(Surface 对象)为像素格式,在颜色元组中比多了 alpha 值。
对于这二者的区别,就是透明与透明的区别,这两个函数会将图片转换成一种特殊的像素格式图片(pygame内部实现的),会使得游戏渲染图片速度加快,核心原理先不用深究,只需要在编写 pygame 的时候,使用这个函数即可。
在代码编写过程中,一定要记得中文名称会产生的问题,不过该案例无中文 BUG,图片读取中,图片名如果设置为中文,可以正常读取,但建议使用英文单词进行命名。
上文代码,在运行过程中,还会出现如下错误:
pygame.error: No video mode has been set
该异常出现的原因是调用图片之前,没有对游戏窗口进行初始化操作,也就是缺少了下述代码。
screen = pygame.display.set_mode((400, 400))
提取图片某个区域
该部分的内容是一个新知识点,也需要重点的学习一下,代码部分如下:
def get_image(target, x, y, width, height, colorkey):
image = pygame.Surface((width, height))
image.blit(target, (0, 0), (x, y, width, height))
image.set_colorkey(colorkey)
return image
通过 get_image
函数,可以获取指定图片区域,构造 Surface 对象的函数在之前的博客中已经学习了。
image = pygame.Surface((width, height))
创建了一个 Surface 对象。
image.blit(target, (0, 0), (x, y, width, height))
在上一行代码创建的 Surface 对象上进行绘制,目标图片是 target
,请回顾 blit
函数的三个参数含义,分别是图像,绘制的坐标点,绘制的截面。
翻译过来就是在一个 Surface 对象的 (0,0)
点开始绘制 target
上的一个区域。
或者理解成之前博客中提及的描述,拿着一个透明玻璃在一张图片上进行滑动,寻找目标区域。
set_colorkey
与 get_colorkey
这两个函数时用来操作透明相关数据的,set_colorkey
目标是当绘制 Surface
对象时,将与 colorkeys
相同的颜色值设为透明,colorkeys
一般传入 RGB 颜色,如果传入 None,则取消 colorkeys
设置。
需要注意,如果代码中的图片已经使用 convert_alpha()
函数转换为透明像素格式,那在进行透明度设置会实现混合效果。
不过该函数使用之后,效果并不是很理想,建议透明图片还是提前准备好。
上图上部图片是白色背景,下部图片是设置白色区域透明,效果不理想
本系列专栏属于番外篇,希望你能学到新知识。 有任何疑问,都可以联系橡皮擦进行解决,一起做游戏吧 本专栏每天的练习量大概在 1 小时左右,整篇博客节奏会比较快,毕竟咱们是有基础的人。