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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章