【python游戲編程之旅】第三篇---pygame事件與設備輪詢


本系列博客介紹以python+pygame庫進行小游戲的開發。有寫的不對之處還望各位海涵。

 

在上一篇博客中,我們學習了pygame中的IO、數據http://www.cnblogs.com/msxh/p/4973003.html。

這次我們來一起了解一下pygame事件與設備輪詢。

 

一、pygame事件

1.簡介

pygame事件可以處理游戲中的各種事情。其實在前兩節的博客中,我們已經使用過他們了。如下是pygame的完整事件列表:

QUIT,ACTIVEEVENT,KEYDOWN,KEYDOWN,MOUSEMOTION,MOUSEBUTTONUP,MOUSEBUTTONDOWN,JOYAXISMOTION,

JOYBALLMOTION,JOYHATMOTION........

更多的事件可以去查pygame的文檔。http://www.pygame.org/docs/index.html

查看pygame的文檔是一種非常好的學習方式。

2.實時事件循環

pygame中的事件處理是放在一個實時的循環中來完成的。將代碼都放在一個while True的循環中,但是這樣會造成死循環,所以在里面加一句sys.exit()來退出。

for event in pygame.event.get()

上面的代碼將會創建當前等待處理的事件的一個列表,然后使用for循環來遍歷里面的事件。這樣,我們將會根據事件產生的順序依次地進行不同的操作。常見的事件是按鍵按下,按鍵釋放以及鼠標移動。通常需要最先處理QUIT事件(在用戶關閉窗口的時候會產生該事件。)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()        

3.鍵盤事件

鍵盤事件包括最典型的keyup 和 keydown 當按鍵按下的時候響應KEYDOWN事件,按鍵彈起的時候響應KEYDOWN事件。通常可以設置一個事件變量,然后根據keyup或者keydown給它賦不同的值。

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        elif event.type == KEYDOWN:
            key_flag = True
        elif event.type == KEYUP:
            key_flag = False

默認的話pygame不會重復地去響應一個被一直按住的鍵,只是在按鍵第一次被按下的時候響應一次,如果需要重復響應一個按鍵的話下面的操作:

pygame.key.set_repeat(10)
#參數是一個以毫秒為單位的值

4.鼠標事件

pygame支持一些鼠標事件,他們包括MOUSEMOTION,MOUSEBUTTONUP,MOUSEBUTTONDOWN.

在MOUSEMOTION中包含了一些屬性:event.pos,event.rel,event.buttons

 for event in pygame.event.get():
        if event.type == MOUSEMOTION:
             mouse_x,mouse_y = event.pos
             move_x,move_y = event.rel

MOUSEBUTTONDOWN里面的屬性:

event.type == MOUSEBUTTONDOWN:
            mouse_down = event.button
            mouse_down_x,mouse_down_y = event.pos

MOUSEBUTTONUP里面的屬性:

event.type == MOUSEBUTTONUP:
            mouse_up = event.button
            mouse_up_x,mouse_up_y = event.pos

 

 

二、設備輪詢

在pygame中除了pygame事件,還可以使用設備輪詢的方法來檢測是否有事件發生。而且在python里面是沒有switch語句的,因此當需要處理的事件過多時,我們肯定不會去一條一條的去寫if...elif....else來匹配,而設備輪詢正好解決了這個棘手的問題。

1.輪詢鍵盤

在pygame中,使用pygame.key.get_pressed()來輪詢鍵盤接口。這個方法會返回布爾值的一個列表,其中每個鍵一個標志。使用鍵常量值來匹配按鍵,這樣的好處就是不必遍歷事件系統就可以檢測多個鍵的按下。例如:

keys = pygame.key.get_pressed()

if keys[K_ESCAPE]:

   pygame.quit()

        sys.exit()

 

我們可以設計一個打字測速小游戲來綜合練習一下鍵盤的輪詢:

 1 import sys, random, time, pygame
 2 from pygame.locals import *
 3 
 4 def print_text(font, x, y, text, color=(255,255,255)):
 5     imgText = font.render(text, True, color)
 6     screen.blit(imgText, (x,y))
 7     
 8 
 9 #主程序
10 pygame.init()
11 screen = pygame.display.set_mode((600,500))
12 pygame.display.set_caption("Keyboard Demo")
13 font1 = pygame.font.Font(None, 24)
14 font2 = pygame.font.Font(None, 200)
15 white = 255,255,255
16 yellow = 255,255,0
17 color = 125,100,210
18 
19 key_flag = False
20 correct_answer = 97 
21 seconds = 10
22 score = 0
23 clock_start = 0
24 game_over = True
25 
26 while True:
27     for event in pygame.event.get():
28         if event.type == QUIT:
29             pygame.quit()
30             sys.exit()
31         elif event.type == KEYDOWN:
32             key_flag = True
33         elif event.type == KEYUP:
34             key_flag = False
35 
36     keys = pygame.key.get_pressed()
37     if keys[K_ESCAPE]:
38         sys.exit()
39 
40     if keys[K_RETURN]:
41         if game_over:
42             game_over = False
43             score = 0
44             seconds = 11
45             clock_start = time.clock()
46 
47     current = time.clock() - clock_start
48     speed = score * 6
49     if seconds-current < 0:
50         game_over = True
51     elif current <= 10:
52         if keys[correct_answer]:
53             correct_answer = random.randint(97,122)
54             score += 1
55 
56  
57     #清屏
58     screen.fill(color)
59 
60     print_text(font1, 0, 20, "Try to keep up for 10 seconds...")
61 
62     if key_flag:
63         print_text(font1, 450, 0, "you are keying...")
64 
65     if not game_over:
66         print_text(font1, 0, 80, "Time: " + str(int(seconds-current)))
67 
68     print_text(font1, 0, 100, "Speed: " + str(speed) + " letters/min")
69 
70     if game_over:
71         print_text(font1, 0, 160, "Press Enter to start...")
72 
73     print_text(font2, 0, 240, chr(correct_answer-32), yellow)
74 
75     
76     #更新
77     pygame.display.update()
78 
79     

 

在這個程序中,我們使用到了一些新的模塊和函數,讓我們來了解一下。

Random.randint(x,y);看名字知道這個函數的作用了,它可以返回一個x~y之間的隨機數。

另外一個模塊是time。time.clock()函數會返回從程序啟動到現在為止的時間。

 

2.輪詢鼠標

同樣,我們可以使用類似的方法去輪詢鼠標事件。

這里有3個相關的函數:

(1)pygame.mouse.get_pos(),這個函數會返回鼠標當前的坐標x,y;

(2)pygame.mouse.get_rel();

rel_x ,rel_y = pygame.mouse.get_rel().利用這個函數可以讀取鼠標的相對移動。

(3)btn_one,btn_two,btn_three = pygame.mouse.get_pressed();

利用這個函數,可以獲取鼠標按鈕的狀態。比如當左鍵按下的時候btn_one 的值會被賦值為1,鼠標按鍵彈起是會被賦值為0。

 

同樣我們可以設計一個小案例來熟悉一下鼠標輪詢,比如當鼠標按下的時候 打印鼠標按的是左鍵還是右鍵,鼠標點擊的位置,鼠標當前的坐標等等。這里就不給出實現代碼了,感興趣的可以自己實現一下。

 

下個博客中我們將會一起學習如何在pygame中加載位圖,以及pygame中一些常用的數學函數。並且還會綜合前幾次學到的知識制作一個小游戲。游戲效果圖如下:


免責聲明!

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



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