接着上次的继续。
简单的画图函数
Pygame给我们提供了几个简单的画图函数,比如画矩形,圆,椭圆,线,独立的像素点。
下面这个程序就实现了一些简单画图的操作
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((500,400),0,32)
BLACK = (0, 0 , 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
DISPLAYSURF.fill(WHITE)
pygame.draw.polygon(DISPLAYSURF, GREEN, ((146,0),(291,106),(236,277),(56,277),(0,106)))
pygame.draw.line(DISPLAYSURF, BLUE, (60, 60), (120,60), 4)
pygame.draw.line(DISPLAYSURF, BLUE, (20, 60), (60,20))
pygame.draw.line(DISPLAYSURF, BLUE, (60, 120), (120,120), 4)
pygame.draw.circle(DISPLAYSURF,BLUE, (300,50), 20, 0)
pygame.draw.ellipse(DISPLAYSURF,RED,(300,250,40,80),1)
pygame.draw.rect(DISPLAYSURF,RED,(200,150,100,50))
pixObj = pygame.PixelArray(DISPLAYSURF)
pixObj[480][380] = BLACK
pixObj[482][382] = BLACK
pixObj[484][384] = BLACK
pixObj[486][386] = BLACK
pixObj[488][388] = BLACK
del pixObj
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
执行后的效果如图
这里面有多一些新的Pygame的东西
fill(color)是Surface对象的一种方法,将surface对象的窗口全部填充一种颜色,就是背景色。
pygame.draw.polygon(surface, color, pointlist, width)画个多边形,其中surface和color参数告诉画在哪个对象里和使用的颜色,pointlist参数是由多个点构成的元组或列表,然后就会从第一个点开始,依次连接后面的点从而构成多边形,width参数是可选的,如果没有,则多边形会被color参数的颜色填充,如果有,而不会填充,多边形轮廓宽度就由width参数决定。传递0给width参数跟没有width参数是一样的。
需要注意的是,所有pygame.draw画图函数都有一个选择项参数width在最后,它们和pygame.draw,polygon函数中的width参数工作方式相同。
pygame.draw.line(surface, color, start_point, end_point, width) 画线函数
pygame.draw.lines(surface, color, closed, pointlist, width) 画多个相连的线,从起点到终点,与pygame.draw.polygon类似,唯一不同的是,如果closed参数为False,终点不会与起点相连接,传递True的话,终点会与起点想连接。
pygame.draw.circle(surface, color, center_point, radius, width) 画圆
pygame.draw.ellipse(surface, color, bounding_rectange, width) 画椭圆
pygame.draw.rect(surface, color, rectangle_tuple, width) 画矩形
pygame,PixelArray对象
pygame没有单独的画点函数。而方法就是创建pygame.PixelArray对象然后设置独立的像素点。创建一个关于Surface的PixelArray对象会‘锁住’Surface对象。一旦Surface对象被锁住,画图函数仍然可以使用,但是类似PNG或JPG的图片就不能作用在Surface对象上了,如果你想查看一个Surface对象是否锁住了,可以调用Surface对象get_locked()方法,如果锁住了会返回True,反之False。
设置这些独立像素点的方法是用两个索引值访问,比如pixObj[480][380] = BLACK ,这样就会将X坐标值的480和Y坐标的380这两个点设为黑色。
为了告诉pygame你完成了画完独立像素点,你需要通过一个del语句删除PixArray对象。删除PixArray对象会‘解锁’Surface对象,那样你就可以继续在上面加载图片了。如果忘了删除,则下次你想在Surface对象上加载图片的话就会报错。
pygame.display.update()函数
当你完成所有画图函数后,你必须调用pygame.display.update()函数让起显示在显示器上。
需要记住的一点是pygame.display.update()函数只会让显示对象(即通过调用pygame.display.set_mode()返回的对象)显示在屏幕上。如果你想让图片显示在屏幕上,你必须“blit”它们(复制它们的意思)到显示对象上通过blit()方法。
Animation
让图像动起来其实很简单,就是将图像从一个地方移动到另一个地方,就是清除掉图像原来所在地方的图像,然后在另一个地方加载这个图像,这样看上去图像就像动起来了一样。在计算机看来,其实就是一群像素的移动。下图就是一个例子
下面是一段示例代码
import pygame, sys
from pygame.locals import *
pygame.init()
FPS = 30 # frames per second setting
fpsClock = pygame.time.Clock()
# set up the window
DISPLAYSURF = pygame.display.set_mode((400, 300), 0, 32)
pygame.display.set_caption('Animation')
WHITE = (255, 255, 255)
catImg = pygame.image.load('cat.png')
catx = 10
caty = 10
direction = 'right'
while True: # the main game loop
DISPLAYSURF.fill(WHITE)
if direction == 'right':
catx += 5
if catx == 280:
direction = 'down'
elif direction == 'down':
caty += 5
if caty == 220:
direction = 'left'
elif direction == 'left':
catx -= 5
if catx == 10:
direction = 'up'
elif direction == 'up':
caty -= 5
if caty == 10:
direction = 'right'
DISPLAYSURF.blit(catImg, (catx, caty))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
fpsClock.tick(FPS)
其中cat.png的下载地址PDF上面已经给出了。下载后必须与源文件放在一个文件夹里面。执行效果就是一只猫儿在一个窗口里面移动。先右,再下,再左,再上,如此循环。
上面这段代码里面又出现了一些新的东西。
帧率和pygame.time.Clock对象
帧率与刷新率指的是程序一秒钟能显示图片的数目,用FPS和帧每秒来表示。(在其它电脑显示器上,FPS有个大众名字叫做赫兹,许多显示器都有60赫兹的帧速率,或者叫做每秒60帧)低的帧率出现在一些图像游戏里就会导致游戏看起来是跳跃和抖动的,如果程序有太多的代码而经常刷新屏幕的话,就会导致FPS下降。但是在这本书里面的游戏因为足够简单所以即使在一些老的电脑上也不会出现问题。
pygame.time.Clock对象能够帮助我们确认程序能跑到的一个最大的确定的FPS值。Clock对象将在游戏主循环中插入小小的暂停以确保我们的游戏程序不会跑的太快。如果我们没有这些暂停的话,我们的游戏就会跑得跟电脑一样快。对玩游戏的人来说它确实太快了。在游戏循环中调用Clock对象的tick()方法能保证我们的游戏跑到一个确定的速度不管电脑跑得有多么快。创建Clock对象如下语句
fpsClock = pygame.time.Clock()
tick方法应该在游戏循环的最末尾调用,也就是在pygame.display.update之后,调用语句如下
fpsClock.tick(FPS)