2015/11/2用Python寫游戲,pygame入門(2):游戲中的事件和顯示


pygame是一個比較大的庫,以我這點弱小的實力是沒辦法詳解的。所以我只講我懂得那些部分,其他部分由大家慢慢查找了解。

-------------------------------

我用pygame的目標很明確,寫一個自己的游戲娛樂,權當學習時的放松。一個小項目的運行是非常有成就感的,所以一切講解都按這樣的簡單步驟來。

 

首先,我們來理解動畫:

上面是一種給孩子玩的小游戲,將幾張不同姿態的圖片放在一個轉軸上,旋轉轉軸時我們就能看到一個連貫的飛翔動畫,幾張斷開的靜止的圖像,當我們以高速切換時,人眼就會認為是連續的動作。這就是視覺暫留效應的體現。根據這種原理,人類發明了電影。

1824年,英國倫敦大學教授皮特.馬克.羅葛特在他的研究報告《移動物體的視覺暫留現象》中最先提出視覺暫留或者“余暉”效應
人眼在觀察景物時,光信號傳入大腦神經,需經過一段短暫的時間,光的作用結束后,視覺形象並不立即消失,這種殘留的視覺稱“后像”。
 
一般來說,視覺暫留會停留0.1-0.4秒左右,當然這因人而異。電影業開始時認為24幀(一秒鍾24張圖)的圖像就可以讓所有的人都察覺不到異常,成為真正的動圖。當然,隨着現在技術的發展,電影的幀率是高於這個值的。在游戲業的實驗中,為了擺脫卡頓感,我們一般是使用30~40幀的圖像速率,這是因為游戲的圖像是離散的,並不是連續的,所以需要更高的幀率來提高體驗,幀率一般是越高越平滑,但超過100幀以后變化就不明顯了。
 
游戲的過程其實就是一個動畫的過程,與單純的動畫不一樣的是,我們還加入了玩家對畫面的反饋。也就是事件。
反饋是通過輸入設備完成的,如鼠標、鍵盤、手柄等等,每個設備有相應的反饋信息,比如說鼠標移動,按鍵按下,松開。這些事都在pygame里成為了基礎的事件,可以直接使用。
 
接下來我通過一個例子來說明基礎的動畫和事件:
 
# -*- coding: utf8 -*-

background_image_filename = 'sky.jpg'
mouse_image_filename = 'cloud.png'
#指定圖像文件名稱
 
import pygame #導入pygame庫
from sys import exit #向sys模塊借一個exit函數用來退出程序
 
pygame.init() #初始化pygame,為使用硬件做准備
screen = pygame.display.set_mode((600, 450), 0, 32)
#創建了一個窗口
pygame.display.set_caption("Hello, World!")
#設置窗口標題
 
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
#加載並轉換圖像
while True:
#游戲主循環
 
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            #接收到退出事件后退出程序
            pygame.quit()
            exit()
 
    screen.blit(background, (0,0))
    #將背景圖畫上去
 
    x, y = pygame.mouse.get_pos()
    #獲得鼠標位置
    x-= mouse_cursor.get_width() / 2
    y-= mouse_cursor.get_height() / 2
    #計算光標的左上角位置
    screen.blit(mouse_cursor, (x, y))
    #把光標畫上去
 
    pygame.display.update()
    #刷新一下畫面

運行結果是這樣的:

當鼠標在屏內移動時,雲也會跟着移動,當然這朵雲是我臨時摳的,實在是很違和。。大家略過這一點。

 

大家先看主循環里的

while True:
#游戲主循環
    ...    
    screen.blit(background, (0,0))
    #將背景圖畫上去
    ...
    screen.blit(mouse_cursor, (x, y))
    #把光標畫上去
    pygame.display.update()
    #刷新畫面

把不需要的東西省略掉,先看這幾句。在主循環里,我們一次次地執行下面三句代碼的操作。就是先畫背景圖,再花光標圖,然后刷新畫面。每次因為光標發生了變化,它就每次畫出不同的圖像,所以這就變成了動畫,也就能實時顯示,也就是我上面說的部分。

 

那么,事件呢?

看這段代碼:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            #接收到退出事件后退出程序
            pygame.quit()
            exit()

這是一段事件響應代碼,pygame.event.get()方法會接受所有程序中發生的事件。當判斷這個事件是一個關閉程序(QUIT)的事件時,就將程序關閉。

那么有哪些事件呢?

事件 產生途徑 參數
QUIT 用戶按下關閉按鈕 none
ATIVEEVENT Pygame被激活或者隱藏 gain, state
KEYDOWN 鍵盤被按下 unicode, key, mod
KEYUP 鍵盤被放開 key, mod
MOUSEMOTION 鼠標移動 pos, rel, buttons
MOUSEBUTTONDOWN 鼠標按下 pos, button
MOUSEBUTTONUP 鼠標放開 pos, button
JOYAXISMOTION 游戲手柄(Joystick or pad)移動 joy, axis, value
JOYBALLMOTION 游戲球(Joy ball)?移動 joy, axis, value
JOYHATMOTION 游戲手柄(Joystick)?移動 joy, axis, value
JOYBUTTONDOWN 游戲手柄按下 joy, button
JOYBUTTONUP 游戲手柄放開 joy, button
VIDEORESIZE Pygame窗口縮放 size, w, h
VIDEOEXPOSE Pygame窗口部分公開(expose)? none
USEREVENT 觸發了一個用戶事件 code

 

這里有很多事件,我們當然是不用把它背下來的,這里只是一個說明。之后在font模塊時,我將寫一個可以顯示所有你得到的事件的程序。

 

再詳細說明上述代碼

background_image_filename = 'sky.jpg'

這句是簡單的字符串賦值語句,只是為了之后使用時能更簡單地理解名稱的意義。

screen = pygame.display.set_mode((600, 450), 0, 32)

這一句使用了pygame.display.set_mode((640, 450), 0, 32)這一句是創建一個窗口,第一個參數是一個元組,用於傳遞窗口的大小,第二個參數是窗口的模式,默認可以寫0,第三個參數為色深,一般寫32就行。

set_mode()返回一個Surface對象,之后可以對這個對象操作。

第二個參數有如下使用:

標志位 功能
FULLSCREEN 創建一個全屏窗口
DOUBLEBUF 創建一個“雙緩沖”窗口,建議在HWSURFACE或者OPENGL時使用
HWSURFACE 創建一個硬件加速的窗口,必須和FULLSCREEN同時使用
OPENGL 創建一個OPENGL渲染的窗口
RESIZABLE 創建一個可以改變大小的窗口
NOFRAME 創建一個沒有邊框的窗口

大家可以自己使用看看效果。

background = pygame.image.load(background_image_filename).convert()

convert()可以把圖像數據都轉化為Surface對象,每次加載完圖像以后就應該做這件事件(事實上因為它太常用了,如果你不寫pygame也會幫你做);convert_alpha相比convert,保留了Alpha 通道信息(可以簡單理解為透明的部分),這樣我們的光標才可以是不規則的形狀。

blit()是個重要函數,第一個參數為一個Surface對象,第二個為左上角位置。將第一個對象畫到相應的位置上。

但是畫完還沒有用,必須把畫完以后的圖像用update()顯示在屏幕上,否則畫面一片漆黑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM