第三章:pyagme游戏开发基础
第一节:窗口图像渲染——Surface对象
pygame窗口使用Surface对象来显示内容,Surface对象相当于一个画布,它是pygame中用于表示图像的对象,可以渲染文本,也可以加载图片。pygame中的Surface对象就类似与我们在绘画时的画纸,Surface对象之间的相互绘制就类似于将画好的画纸进行叠加放置,放置与最上面的画纸就会覆盖下面所有的画纸。
在pygame中,Surface对象默认是纯黑色填充且不透明的,要想设置为别的颜色,则可以对其进行填充绘制,例如,在第一章第一个pygame程序中使用Surface对象的fill()函数实现清屏功能。代码如下:
screen.fill((25,102,173))
另外,在第一个pygame程序中将文本绘制到窗口上时,使用了Surface对象的blit()函数。代码如下:
screen.blit(mingri,(160,150))
blit()函数用来将一个图像(Surface对象)绘制到另一个图像上方,其语法格式如下:
pygame.Surface.blit(source,dest,area=None,special_flags=0)->Rect
参数说明如下:
source:必选参数,指定所要绘制的Surface对象。
dest:必选参数,指定所要绘制的位置,(X,Y)。
area:可选参数,限定所要绘制的Surface对象的绘制范围,一个四元元组。
special_flags:可选参数,指定混合的模式。
返回值:一个四元数组,表示在目标Surface对象上实际的绘制矩形区域。
除了上面的函数,Surface对象中还包含了其它的图像渲染相关函数,如下表显示:
pyame.Surface.convert() | 修改图像(Surface对象)的像素格式 |
pyame.Surface.convert_alpha() | 修改图像(Surface对象)的像素格式,包含alpha通道 |
pyame.Surface.copy() | 创建一个Surface对象的拷贝 |
pyame.Surface.scroll() | 移动Surface对象 |
pyame.Surface.set_colorkey() | 设置colorkeys |
pyame.Surface.get_colorkey() | 获取colorkeys |
pyame.Surface.set_alpha() | 设置整个图像的透明度 |
pyame.Surface.get_alpha() | 获取整个图像的透明度 |
pyame.Surface.lock() | 锁定Surface对象的内存使其可以进行像素访问 |
pyame.Surface.unlock() | 锁定Surface对象的内存使其无法进行像素访问 |
pyame.Surface.mustlock() | 检测该Surface对象是否需要被锁定 |
pyame.Surface.getlocked() | 检测该Surface对象当前是否为锁定状态 |
pyame.Surface.get_locks() | 返回该Surface对象的锁定 |
pyame.Surface.get_at() | 获取一个像素的颜色值 |
pyame.Surface.set_at() | 设置一个像素的颜色值 |
pyame.Surface.get_at_mapped() | 获取一个像素映射的颜色索引号 |
pyame.Surface.get_palette() | 获取Surface对象8位索引的调色板 |
pyame.Surface.get_palette_at() | 返回给定索引号在调色板中的颜色值 |
pyame.Surface.set_palette() | 设置Surface对象8位索引的调色板 |
pyame.Surface.set_palette_at() | 设置给定索引号在调色板中的颜色值 |
pyame.Surface.map_rgb() | 将一个RGBA颜色转换为映射的颜色值 |
pyame.Surface.unmap_rgb() | 将一个映射的颜色值转换为Color对象 |
pyame.Surface.set_clip() | 设置该Surface对象的当前剪切区域 |
pyame.Surface.get_clip() | 获取该Surface对象的当前剪切区域 |
pyame.Surface.Subsurface() | 根据父对象创建一个新的子Surface对象 |
pyame.Surface.get_parent() | 获取子Surface对象的父对象 |
pyame.Surface.get_abs_parent() | 获取子Surface对象的顶层父对象 |
pyame.Surface.get_offset() | 获取子Surface对象在父对象中的偏移位置 |
pyame.Surface.get_abs_offset() | 获取子Surface对象在顶层父对象中的偏移位置 |
pyame.Surface.get_size() | 获取Surface对象的尺寸 |
pyame.Surface.get_width() | 获取Surface对象的宽度 |
pyame.Surface.get_height() | 获取Surface对象的高度 |
pyame.Surface.get_rect() | 获取Surface对象的矩形区域 |
pyame.Surface.get_bitsize() | 获取Surface对象像素格式的位深度 |
pyame.Surface.get_bytesize() | 获取Surface对象每个像素使用的字节数 |
pyame.Surface.get_flags() | 获取Surface对象的附加标志 |
pyame.Surface.get_pitch() | 获取Surface对象每行占用的字节数 |
pyame.Surface.get_masks() | 获取颜色与映射索引号之间转换的掩码 |
pyame.Surface.set_masks() | 设置颜色与映射索引号之间转换的掩码 |
pyame.Surface.get_shifts() | 获取当位移动时在颜色与映射索引号之间转换的掩码 |
pyame.Surface.set_shifts() | 设置当位移动时在颜色与映射索引号之间转换的掩码 |
pyame.Surface.get_losses() | 获取最低有效位在颜色与映射索引号之间转换的掩码 |
pyame.Surface.get_bounding_rect() | 获取最小包含所有数据的Rect对象 |
pyame.Surface.get_view() | 获取Surface对象的像素缓冲区视图 |
pyame.Surface.get_buffer() | 获取Surface对象的像素缓冲区对象 |
另外,在Surface对象中还包含一个._pixels_address变量,用来表示像素缓冲区地址。
第二节:像素和pygame.Color对象
在pygame窗口中绘图时使用的颜色单位默认是像素。所谓像素,就是pygame窗口屏幕上的一个点。实际上,任何一张图片都是由叫做像素(pixel)的点组合而成,如果将浏览的图片放大若干倍,就可以清晰地看到这些点(小方格),所有的这些小方格通过笛卡尔坐标系都有明确的坐标位置以及被分配的色彩数值,从而决定了图片最终呈现出来的样子。
pygame中表示颜色用的是色光三原色表示法,即通过一个元组或列表来指定颜色的RGB值,每个值都在0至255的范围,由于每种原色都使用一个8位(bit)的值来表示,因此3种颜色相当于一共由24位构成,这就是常说的24位颜色表示法。
pygame使用是RGBA系统,其中,R表示的是红色值(Red),G表示的是绿色值(Green),B表示的是蓝色值(Blue),A表示的是透明度(Alpha),该值为可选值,在pygame中默认为255,一般不需要特别指定。例如:纯红色(255,0,0)、纯绿色(0,255,0)、纯蓝色(0,0,255)、纯白色(255,255,255)。
在程序开发中,如果不想使用RGB标记颜色,pygame自身还为开发者提供了一种通过常量定义颜色名称的方法,开发时可以直接使用这些常量命名颜色,这些定好的颜色常量一共有657个,可以在pygame.color模块中查看具体名称。使用颜色命名常量时,需要在程序中导入pygame.color模块中的包含所有颜色的字典常量THECOLORS,代码如下:
from pygame.color import THECOLORS
print("红色:",THECOLORS["red"])
print("绿色:",THECOLORS["green"])
print("蓝色:",THECOLORS["blue"])
print("白色:",THECOLORS["white"])
运行结果如下:
红色:(255,0,0,255)
绿色:(0,255,0,255)
蓝色:(0,0,255,255)
白色:(255,255,255,255)
另外,除了使用字典常量THECOLORS表示颜色外,在pygame.color模块中,还提供了一个pygame.color.Color对象(简称为Color对象)来表示或创建一种颜色,语法格式如下:
pygame.color.Color(name) #命名字符串
pygame.color.Color(r,g,b,a) #RGBA颜色值
pygame.color.Color(rgbvalue) #十六进制颜色码
在以上3种创建Color对象的方法中,第3种参数值为#rrggbbaa或0xrrggbbaa形式,其中aa是可选的。示例代码如下:
import pygame #导包,包括pygame.color.Color
#下面代码展示了创建红色值的不同方式
red_01=pygame.Color("red")
red_02=pygame.Color(255,0,0,255)
red_03=pygame.Color(255,0,0)
red_04=pygame.Color("#FF0000FF")
red_05=pygame.Color("0xFF0000FF")
red_06=pygame.Color("0xFF0000")
res=red_01==red_02==red_03==red_04==red_05==red_06
print(res) #结果为True
上面的代码中,没有导入pygame.color.Color类就可以直接创建Color对象,是因为在导入pygame模块时,在其自动执行的-init-.py文件中将pygame.color.Color变量赋值给了pygame.Color变量,因此可以直接通过pygame.Color变量来创建Color对象,极大地方便开发者的使用,同时减少代码的编写量。
使用Color对象创建完颜色后,可以分别使用该对象的r,g,b,a属性获取该颜色对应的R,G,B,A颜色值,代码如下:
print(red_01.r) #红
print(red_01.g) #绿
print(red_01.b) #蓝
print(red_01.a) #透明度
实例:展示所有颜色
一个1920*1680的显示器,正常有着1310720个像素,一般的32位RGB系统,每个像素可以显示(256的3次方)种颜色,下面编写一个pygame程序,通过3个for循环来显示一个1920*1680显示器的所有颜色。具体代码如下:
import pygame
pygame.init() # pygame 初始化
# 创建"画纸"
colors = pygame.Surface((1920, 1680), depth=32)
# 在"画纸"上渲染上像素点
for s in range(256):
x = (s % 16) * 256
y = (s // 16) * 256
for g in range(256):
for b in range(256):
# 设置一个像素的颜色值
colors.set_at((x + g, y + b), (s, g, b))
# 将"画纸" 保存为一张图片
pygame.image.save(colors, "colors.png")
第三节:pygame中的透明度
在pygame游戏窗口中,支持以下3种透明度类型:像素透明度(pixel alphas)、颜色值透明度(colorkeys)、图像透明度(surface alphas)。
像素透明度
在现实生活中,当透过一个绿色的玻璃片看其它物体时,其背后的所有颜色都会增加一个绿色的阴影,在pygame程序中,如果想实现类似的效果,可以通过给Color对象值添加第4个透明度参数的方式来实现,该值叫做alpha值,而这类透明度叫做像素透明度(pixel alpha)。通常情况下,在一个Surface对象上添加一个像素点时,其实是新的颜色值代替了原来的颜色值,但是,如果使用的是一个带有alpha值的颜色,就相当于给原来的颜色添加了一个带有颜色的色调。
默认情况下,当在pygame窗口上加载一张透明的图片时,它的执行效率是很慢的,为了能够更快地进行加载,pygame模块提供了一个名为convert_alpha()的函数,专门用于为alpha通道做优化,以便更快地绘制透明图片,其使用方法如下:
pixel_Sur=pygame.image.load(IMG_PATH).convert_alpha()
#IMG_PATH表示需要加载透明图片的路径
注:从pygame.display.set_mode()返回的的pyagme显示Surface对象不能够再调用convert.alpha()方法。
实例:测试像素透明度
创建一个pygame程序,有两张图片分别为透明和不透明的,分别用来测试加载到pygame窗口上的时的效果。另外,通过该程序对比使用两张图片的Surface对象各自调用自身convert_alpha()方法时有何不同效果。程序代码如下:
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 396))
# screen = pygame.display.set_mode((640, 396)).convert_alpha()
pygame.display.set_caption("测试像素透明度")
font = pygame.font.SysFont("Airal", 50)
mingri_soft = font.render("mingri_soft", \
True, pygame.Color("red"), )
size = 25
# 加载不透明的图片
# fire_img = pygame.image.load("not_alpha.png")
# fire_img = pygame.image.load("not_alpha.png").convert_alpha()
# 加载透明的图片
# fire_img = pygame.image.load("alpha.png")
# 添加 像素透明度(可验证图像本身是否是透明的), 优化 alpha 通道
fire_img = pygame.image.load("alpha.png").convert_alpha()
while True:
# 绘制文本
screen.blit(mingri_soft, (100, 100))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
# 监听鼠标单击事件,在单击处绘制图片
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
screen.blit(fire_img, (x - size, y - size))
pygame.display.update()
代码解析:
1,第7行代码通过加载系统字体文件创建并返回了一个用于构造文本Surface对象的pygame.font.Sysfont()对象,并在第8行代码中通过渲染文本创建了一个文本Surface。
2,第23行代码将文本Surface绘制到了pygame窗口上。
3,第12、13、16、18行代码分别使用不同的方式加载一张图片。
4,第30行代码用来监听鼠标单击事件,每当监听到鼠标单击事件时,在第31行代码中获取当前鼠标位置,然后将之前加载的图片Surface绘制在当前鼠标位置 。
图片资源(如有需要可自行截图):
透明图片:
不透明图片:
颜色值透明度
如果在上一个实例代码中加载的是一张原本不透明的图片,可以看见图片有一个白色的背景色,如果要去除该白色背景使其透明,该如何实现?这时需要使用另一种透明度类型——颜色值透明度(colorkeys)。
颜色值值透明度是指设置图像中的某个颜色值(任意像素的颜色值)为透明,主要是为了在绘制Surface对象时,将图像中所有与指定颜色值相同的颜色绘制为透明。在pygame中,Surface对象专门提供了一个名为set_colorkey()函数获取透明颜色值。使用set_colorkey()函数时,需要设置一个Color参数,该参数可以是一个RGB颜色,也可以是映射后的颜色索引号,如果传入None,则表示取消colorkeys的设置。set_colorkey()函数语法格式如下:
pygame.Surface.set_colorkey(Color)
#Color为需要传入的Color参数
实例:测试颜色值透明度
创建一个pygame程序,其中加载一张以不同颜色绘制的九宫格图片(如下图所示),然后将该图片中的红色以透明显示。
图片资源如下(如有需要请自行截图):
程序代码如下:
import pygame
size = width, height = 300, 300
pygame.init()
screen = pygame.display.set_mode(size)
# screen = pygame.display.set_mode(size).convert_alpha()
pygame.display.set_caption("测试颜色值透明度")
# 加载不透明的图片ra
fire_img = pygame.image.load("colorkeys.png")
# fire_img = pygame.image.load("colorkeys.png").convert_alpha()
# 设置颜色值透明度
fire_img.set_colorkey((255, 0, 0)) # 红色透明
# fire_img.set_colorkey((0, 255, 0)) # 绿色透明
# fire_img.set_colorkey((0, 0, 255)) # 蓝色透明
# fire_img.set_alpha(128) # 设置图像透明度
while True:
screen.fill((0, 163, 150))
# 绘制图像
screen.blit(fire_img, (width // 2 - 80, height // 2 - 80))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
pygame.display.update()
图像透明度
图像透明度类型是指整个图像的透明度,取值范围为0至255(0表示完全透明,255表示完全不透明,128表示半透明)。为了设置图像透明度,Surface对象提供了一个名为set_alpha()的函数,其参数是一个int或float类型的值,其语法格式如下:
pygame.Surface.set_alpha(value)
#value为需要传入的参数
窗口坐标系与pyagme.Rect对象
窗口坐标系
在pygame游戏窗口中,使用笛卡儿坐标系来表示窗口中的点,游戏窗口左上角为原点(0,0)坐标,X轴为水平方向向右,且逐渐递增,Y轴为垂直方向竖直向下。有了游戏窗口坐标系统,在游戏窗口中,通过X与Y的坐标可以精确确定在pygame窗口中每一个像素点的起始位置。
以上就是本章、篇的全部内容,由于条件限制,剩余内容将放到下一篇讲解,另外,如果这些内容对您有帮助,别忘了点赞+收藏+评论!,感谢您阅读本博客!