一、帧率
1.帧率就是每秒显示的帧数,一般的电视画面是24FPS;30FPS基本可以给玩家提供流程的体验了(每秒30帧);LCD的话,60FPS是常用的刷新率,所以你的游戏的帧率再高也就没什么意义了;而绝大多数地球人都无法分辨70FPS以上的画面了!
2.pygame.time.Clock
1 2 3 | clock = pygame.time.Clock() time_passed = clock.tick() time_passed = clock.tick(30) |
第一行初始化了一个Clock对象;第二行的意识是返回一个上次调用的时间(以毫秒计);第三行非常有用,在每一个循环中加上它,那么给tick方法加上的参数就成为了游戏绘制的最大帧率,这样的话,游戏就不会用掉你所有的CPU资源了!但是这仅仅是“最大帧率”,并不能代表用户看到的就是这个数字,有些时候机器性能不足,或者动画太复杂,实际的帧率达不到这个值,我们需要一种更有效的手段来控制我们的动画效果。
假设让我们的小鱼儿每秒游动250像素,这样游动一个屏幕差不多需要2.56秒。我们就需要知道,从上一帧开始到现在,小鱼应该游动了多少像素,这个算法很简单,速度*时间就行了,也就是250 * time_passed_second。不过我们刚刚得到的time_passed是毫秒,不要忘了除以1000.0,当然我们也能假设小鱼每毫秒游动0.25像素,这样就可以直接乘了,不过这样的速度单位有些怪怪的……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | background_image_filename = 'sushiplate.jpg' sprite_image_filename = '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和直接归零有何不同? if x > 640.: x -= 640. pygame.display.update() |
好了,这样不管你的机器是更深的蓝还是打开个记事本都要吼半天的淘汰机,人眼看起来,不同屏幕上的鱼的速度都是一致的了。请牢牢记住这个方法,在很多情况下,通过时间控制要比直接调节帧率好用的多。
下面有一个更有趣一些的程序,不再是单纯的直线运动,而是有点像屏保一样,碰到了壁会反弹。不过也并没有新的东西在里面,原理上来说,反弹只不过是把速度取反了而已~ 可以先试着自己写一个,然后与这个对照一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | background_image_filename = 'sushiplate.jpg' sprite_image_filename = '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).convert_alpha() 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 # 到达边界则把速度反向 if x > 640 - sprite.get_width(): speed_x = -speed_x x = 640 - sprite.get_width() elif x < 0: speed_x = -speed_x x = 0. 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() |
二、向量
1.计算两个点之间的向量AB=vector2.from_points(A,B)
2.计算向量的大小 AB.get_magnitude()
3.计算单位向量 AB.get_normalized()
A=(10.0,20.0)
B=(30.0,35.0)
AB=vector2.from_points(A,B) #计算两个点之间的向量
print "Vector AB is", AB #(20,15)
print "AB * 2 is", AB * 2 #(40,30)
print "AB / 2 is", AB / 2 #(10,7.5)
print "AB + (–10, 5) is", AB + (–10, 5) #(10,20)
print "Magnitude of AB is", AB.get_magnitude() #计算向量的大小 25.0
print "AB normalized is", AB.get_normalized() #计算单位向量(0.8,0.6)
三、键盘设备
1.pygame.key.get_pressed()来获得所有按下的键值,它会返回一个元组。这个元组的索引就是键值,对应的就是是否按下
- key.get_focused —— 返回当前的pygame窗口是否激活
- key.get_pressed —— 刚刚解释过了
- key.get_mods —— 按下的组合键(Alt, Ctrl, Shift)
- key.set_mods —— 你也可以模拟按下组合键的效果(KMOD_ALT, KMOD_CTRL, KMOD_SHIFT)
- key.set_repeat —— 无参数调用设置pygame不产生重复按键事件,二参数(delay, interval)调用设置重复事件发生的时间
- key.name —— 接受键值返回键值
实例1:使用键盘上下左右控制小鱼移动
#-*- coding:UTF-8-*- #使用键盘控制使小鱼能以八个方向移动 background_image = 'sushiplate.jpg' sprite_image = 'fugu.png' import pygame from pygame.locals import * from sys import exit from gameobjects.vector2 import Vector2 pygame.init() clock=pygame.time.Clock() #初始化一个colock对象 sprite_pos=Vector2(200,0) sprite_speed=300. screen=pygame.display.set_mode((640,480),0,32) background=pygame.image.load(background_image).convert() sprite=pygame.image.load(sprite_image).convert_alpha() while True: for event in pygame.event.get(): if event.type == QUIT: exit() pressed_keys = pygame.key.get_pressed() #获得所有按下的键值,他会返回一个元组,这个元组的索引就是键值 key_direction = Vector2(0, 0) if pressed_keys[K_LEFT]: key_direction.x = -1. elif pressed_keys[K_RIGHT]: key_direction.x = +1. if pressed_keys[K_UP]: key_direction.y = -1. elif pressed_keys[K_DOWN]: key_direction.y = +1. key_direction.normalize() #向量标准化 screen.blit(background, (0, 0)) screen.blit(sprite, sprite_pos) time_passed = clock.tick(30) time_passed_seconds = time_passed / 1000.0 sprite_pos += key_direction * sprite_speed * time_passed_seconds pygame.display.update()
四、鼠标
1 2 3 | clock = pygame.time.Clock() time_passed = clock.tick() time_passed = clock.tick(30) |
第一行初始化了一个Clock对象;第二行的意识是返回一个上次调用的时间(以毫秒计);第三行非常有用,在每一个循环中加上它,那么给tick方法加上的参数就成为了游戏绘制的最大帧率,这样的话,游戏就不会用掉你所有的CPU资源了!但是这仅仅是“最大帧率”,并不能代表用户看到的就是这个数字,有些时候机器性能不足,或者动画太复杂,实际的帧率达不到这个值,我们需要一种更有效的手段来控制我们的动画效果。