pygame库写游戏——入门<6>——存储图像

来源:互联网 发布:填表软件 编辑:程序博客网 时间:2024/05/28 15:07

RBG图像,游戏中往往使用RBGA图像,A即Alpha,也就是表示透明度的部分(0~255),0代表完全透明。可以使用多种软件创建含有Alpha通道的图片

存储图像的方式(图片格式),JPEG、PNG等等,python大多能支持。

使用surface对象
对于Pygame,加载图片就是python.image.load,给定一个文件名,就还你一个surface对象。事实上屏幕也是一个surface,pygame.display.set_mode即返回了一个屏幕surface对象。
创建Surface对象的方法:1、就是pygame.image.load,这个对象有与图像相同的尺寸和颜色;2、就是指定尺寸创建一个空的surface,
blank_surface == pygame.Surface((256,256),flags,depth)
其中第一个参数是对象的像素256*256;
第二个参数flags可以设定为HWSURFACE – 类似于前面讲的,更快!不过最好不设定,Pygmae可以自己优化。或者SRCALPHA – 有Alpha通道的surface,如果你需要透明,就要这个选项。这个选项的使用需要第三个参数为32。
第三个参数是depth,pygame.display.set_mode中的一样,你可以不设定,Pygame会自动设的和display一致。不过如果你使用了SRCALPHA,还是设为32吧:

bland_alpha_surface = pygame.Surface((256, 256), flags=SRCALPHA, depth=32)

转换Surfaces
最开始的hello world程序中有两句转换背景图和鼠标图的程序,包括第一个普通的转换convert(),等价于display;第二个是带有alpha通道的转换convert_alpha()

矩形对象(Rectangle Objects)
一般来说在制定一个区域的时候,矩形是必须的,比如在屏幕的一部分画东西。在pygame中矩形对象极为常用,它的指定方法可以用一个四元素的元组,或者两个二元素的元组,前两个数为左上坐标,后两位为右下坐标。
Pygame中有一个Rect类,用来存储和处理矩形对象(包含在pygame.locals中,所以如果你写了from pygame.locals import *就可以直接用这个对象了),比如:

my_rect1 = (100, 100, 200, 150)my_rect2 = ((100, 100), (200, 150))#上两种为基础方法,表示的矩形也是一样的my_rect3 = Rect(100, 100, 200, 150)my_rect4 = Rect((100, 100), (200, 150))

一旦有了Rect对象,我们就可以对其做很多操作,比如调整位置和大小,判断一个点是否在其中等等。

剪裁(clipping)
通常的游戏只需要绘制屏幕的一部分,如菜单栏等等。为实现这一点,surface就有了剪裁区域(clipping area),一旦定义这个区域,那么只有这个区域内的像素会被更改,其他位置不变。这个区域默认是所有地方,但是可以通过set_clip()来设定,通过get_clip()来获得这个区域。

如下几段代码:

screen.set_clip(0,400,200,600)draw_map()#在左下角画地图

子表面(Subsurfaces)
Subsurface就是在一个Surface中再提取一个Surface,记住当你往Subsurface上画东西的时候,同时也向父表面上操作。这可以用来绘制图形文字,尽管pygame.font可以用来写很不错的字,但只是单色,游戏可能需要更丰富的表现,这时候你可以把每个字母(中文的话有些吃力了)各自做成一个图片,不过更好的方法是在一张图片上画满所有的字母。把整张图读入,然后再用Subsurface把字母一个一个“抠”出来,就像下面这样

my_font_image = Pygame.load("font.png")letters = []letters["a"] = my_font_image.subsurface((0,0), (80,80))letters["b"] = my_font_image.subsurface((80,0), (80,80))

填充(fill)Surface
填充有时候能够作为一种清屏的操作,把整个surface填上一种颜色。

screen.fill((0,0,0))

同样可以提供一个矩形来制定填充某个部分(也可以作为画矩形的方法)

设置像素
set_at方法可以做到这一点,它的参数是坐标和颜色,下面的小脚本会随机的在屏幕上画点:

import pygamefrom pygame.locals import *from sys import exitfrom random import randintpygame.init()screen = pygame.display.set_mode((640, 480), 0, 32)while True:    for event in pygame.event.get():        if event.type == QUIT:            exit()    rand_col = (randint(0, 255), randint(0, 255), randint(0, 255))    #screen.lock()    #很快你就会知道这两句lock和unlock的意思了    for _ in range(100):        rand_pos = (randint(0, 639), randint(0, 479))        screen.set_at(rand_pos, rand_col)    #screen.unlock()    pygame.display.update()

获得Surface上的像素
get_at()可以帮我们做到这一点,接受一个坐标,返回这个坐标上的颜色。但是
不过记住get_at在对hardware surface操作的时候很慢,而全屏的时候总是hardware的,所以慎用这个方法!

锁定Surface

当Pygame往surface上画东西的时候,首先会把surface锁住,以保证不会有其它的进程来干扰,画完之后再解锁。锁和解锁时自动发生的,所以有时候可能不那么有效率,比如上面的例子,每次画100个点,那么就得锁解锁100次,现在我们把两句注释去掉,再执行看看是不是更快了(好吧,其实我没感觉出来,因为现在的机器性能都不错,这么点的差异还不太感觉的出来。不过请相信我~复杂的情况下会影响效率的)?

当你手动加锁的时候,一定不要忘记解锁,否则pygame有可能会失去响应。虽然上面的例子可能没问题,但是隐含的bug是我们一定要避免的事情。

Blitting

blit的的中文翻译给人摸不着头脑的感觉,可以译为位块传送(bit block transfer),其意义是将一个平面的一部分或全部图象整块从这个平面复制到另一个平面,下面还是直接使用英文。

blit是对表面做的最多的操作,我们在前面的程序中已经多次用到,不多说了;blit的还有一种用法,往往用在对动画的表现上,比如下例通过对frame_no的值的改变,我们可以把不同的帧(同一副图的不同位置)画到屏幕上:

screen.blit(ogre, (300, 200), (100 * frame_no, 0, 100, 100))
阅读全文
0 0
原创粉丝点击