理解帧率
这是一个被说烂了的词,FPS(Frame Per Second)是游戏和硬件间较量的永恒话题,我也不想多插话了,相信玩游戏的朋友都知道。
只是记住几个常用的量:一般的电视画面是24FPS;30FPS基本可以给玩家提供流程的体验了;LCD的话,60FPS是常用的刷新率,所以你的游戏的帧率再高也就没什么意义了;而绝大多数地球人都无法分辨70FPS以上的画面了!
直线运动
#-*- coding:utf-8 -*- background_image_filename = './images/sushiplate.jpg' sprite_image_filename = './images/fugu.png' import pygame from pygame.locals import * from sys import exit pygame.init() screen = pygame.display.set_mode((640, 480), 0, 32) background = pygame.image.load(background_image_filename).convert() sprite = pygame.image.load(sprite_image_filename) #sprite起始坐标 x = 0 while True: for event in pygame.event.get(): if event.type == QUIT: exit() screen.blit(background, (0, 0)) #画出sprite screen.blit(sprite, (x, 100)) #每循环一次移动1个像素 x += 1 #若超出边界则从头开始 if x > 640: x = 0 pygame.display.update()
关于时间
有一个解决上述问题的方法,就是让我们的动画基于时间运作,我们需要知道上一个画面到现在经过了多少时间,然后我们才能决定是否开始绘制下一幅。pygame.time模块给我们提供了一个Clock的对象,使我们可以轻易做到这一些:
clock = pygame.time.Clock() time_passed = clock.tick() time_passed = clock.tick(30)第一行初始化了一个Clock对象;第二行的意思是返回一个上次调用的时间(以毫秒计);第三行非常有用,在每一个循环中加上它,那么给tick方法加上的参数就成为了游戏绘制的最大帧率,这样的话,游戏就不会用掉你所有的CPU资源了!
为了使得在不同机器上有着一致的效果,我们其实是需要给定物体(我们把这个物体叫做精灵,Sprite)恒定的速度。这样的话,从起点到终点的时间点是一样的,最终的效果也就相同了,所差别的,只是流畅度。看下面的图试着理解一下~
我们把上面的结论实际试用一下,假设让我们的小鱼儿每秒游动250像素,这样游动一个屏幕差不多需要2.56秒。我们就需要知道,从上一帧开始到现在,小鱼应该游动了多少像素,这个算法很简单,速度*时间就行了,也就是250 * time_passed_second。不过我们刚刚得到的time_passed是毫秒,不要忘了除以1000.0,当然我们也能假设小鱼每毫秒游动0.25像素,这样就可以直接乘了,不过这样的速度单位有些怪怪的……
#-*- coding:utf-8 -*- background_image_filename = './images/sushiplate.jpg' sprite_image_filename = './images/fugu.png' import pygame from pygame.locals import * from sys import exit pygame.init() screen = pygame.display.set_mode((640, 480), 0, 32) background = pygame.image.load(background_image_filename).convert() sprite = pygame.image.load(sprite_image_filename) # Clock对象 clock = pygame.time.Clock() x = 0. # 速度(像素/秒) speed = 250. while True: for event in pygame.event.get(): if event.type == QUIT: exit() screen.blit(background, (0, 0)) screen.blit(sprite, (x, 100)) #上次调用经过的时间 time_passed = clock.tick() time_passed_seconds = time_passed / 1000.0 #移动距离 distance_moved = time_passed_seconds * speed x += distance_moved #区别并不是很大,减去640可能每次的起点不一定是0 if x > 640.: x -= 640 pygame.display.update()
斜线运动
#-*- coding:utf-8 -*- background_image_filename = './images/sushiplate.jpg' sprite_image_filename = './images/fugu.png' import pygame from pygame.locals import * from sys import exit pygame.init() screen = pygame.display.set_mode((640, 480), 0, 32) background = pygame.image.load(background_image_filename).convert() sprite = pygame.image.load(sprite_image_filename) # Clock对象 clock = pygame.time.Clock() #设置初始位置,初始速度 x, y = 100., 100. speed_x, speed_y = 133.,170. while True: for event in pygame.event.get(): if event.type == QUIT: exit() screen.blit(background, (0, 0)) screen.blit(sprite, (x, y)) #上次调用经过的时间 time_passed = clock.tick(30) time_passed_seconds = time_passed / 1000.0 #鱼每次移动的距离 x += speed_x * time_passed_seconds y += speed_y * time_passed_seconds #当x超出右边界时,速度反向,起始点为右边界 if x > 640 - sprite.get_width(): speed_x = -speed_x x = 640 - sprite.get_width() elif x < 0: speed_x = -speed_x x = 0 #当y超出上边界时,速度反向,起始点为上边界 if y > 480 - sprite.get_height(): speed_y = -speed_y y = 480 - sprite.get_height() elif y < 0: speed_y = -speed_y y = 0 pygame.display.update()