1. 程式人生 > >pygame庫寫遊戲——入門——動畫和幀率

pygame庫寫遊戲——入門——動畫和幀率

理解幀率
FPS(Frame Per Second),一般電視畫面是24FPS,30FPS基本可提供流暢的體驗,60FPS是LCD常用的重新整理率;而絕大多數人無法分辨70FPS以上的畫面。

直線運動
嘗試讓hello world程式中的魚動起來:

background_filename = 'sushiplate.jpg'
mouse_filename = 'fugu.png'

import pygame
from pygame.locals import *

pygame.init()

screen = pygame.display.set_mode((640,480),RESIZABLE,32
) mouse_cursor = pygame.display.set_caption('hello world!') background = pygame.image.load(background_filename).convert() mouse_cursor = pygame.image.load(mouse_filename).convert_alpha() x == 0 while True: for event in pygame.event.get(): if event.type == KEYDOWN: if event.key == K_SPACE: pygame.quit() if
event.type == VIDEORESIZE: SCREEN_SIZE = event.size screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32) screen_width, screen_height = SCREEN_SIZE screen.blit(background,(0,0)) screen.blit(mouse_cursor,(x,240)) x += 1 if x > 640: x = 0 pygame.display.update()

可以調節x +=1來改變魚的執行速度。
有些時候動畫的元素很多,就會導致電腦的執行速率下降,我們要儘量避免這樣的情況。

關於時間
解決上一個問題的方法之一就是讓動畫基於時間運作——需要知道上一個畫面到現在經過了多長的時間,然後我們決定是否開始繪製下一幅圖。而pygame.time模組就給我們提供了一個Clock物件,使我們輕易做到這一點:

clock = pygame.time.Clock()
#初始化Clock物件
time_passed = clock.tick()
#返回上一個呼叫的時間(ms)
time_passed = clock.tick(30)
#在麼一個迴圈中加上它,其中的引數就成為了遊戲的最大幀率,避免遊戲佔用所有的CPU資源。

雖然可以設定最大的幀率,但是有些機器效能不足,實際幀率達不到如上效果,因此需要用另一個手段來控制。

為了使在不同的裝置上有一隻的效果,我們其實需要給定物體恆定的速度(精靈Sprite),這樣從起點到終點的時間就是一樣的,最終效果也就相同了,差別僅僅在於流暢度。
看圖理解

試用上面的結論,假設需要小魚每秒運動250畫素,游完一個螢幕需要大概2.56秒,這樣,我們就需要知道從上一幀開始到現在,小魚運動了多少畫素,即速度*時間,250*time_passed_second。不過時間單位是ms,需要除以1000。
程式可改為:

# -*- coding: utf-8 -*-
"""
Created on Tue Dec  5 14:42:51 2017

@author: zhang
"""

background_filename = 'sushiplate.jpg'
mouse_filename = 'fugu.png'

import pygame
from pygame.locals import *

pygame.init()

screen = pygame.display.set_mode((640,480),RESIZABLE,32)
mouse_cursor = pygame.display.set_caption('hello world!')

background = pygame.image.load(background_filename).convert()
mouse_cursor = pygame.image.load(mouse_filename).convert_alpha()

clock = pygame.time.Clock()
x = 0
speed = 250
while True:
  for event in pygame.event.get():
    if event.type == KEYDOWN:
      if event.key == K_SPACE:
        pygame.quit()
    if event.type == VIDEORESIZE:
        SCREEN_SIZE = event.size
        screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)

  screen_width, screen_height = SCREEN_SIZE

  screen.blit(background,(0,0))
  screen.blit(mouse_cursor,(x,100))

  time_passed = clock.tick()
  time_passed_seconds = time_passed / 1000
  distance = speed * time_passed_seconds


  x += distance
  if x > 640:
    x -= 640
  pygame.display.update()

斜線運動
即加上speed_y的程式片段即可。
同時可以使用片段

if x > 640:
    speed = -speed
  elif x < 0:
    speed = -speed

來做到使小球碰壁即反彈。