pygame 鍵盤和滑鼠事件的處理
pygame 的鍵盤和滑鼠事件的處理
所謂事件,就是程式上發生的事。例如使用者按下鍵盤上的某個鍵或者單擊、移動滑鼠,對於這些事件,遊戲程式需要作出反應。如《 pygame 影象/圖形繪製》中例子,程式會一直執行下去,直到使用者關閉視窗而產生一個 QUIT 事件,pygame 會接收使用者的各種操作(例如按鍵盤上的鍵、移動滑鼠等)產生事件。事件隨時可能發生,而且量可能會很大,pygame 的做法是把一系列的事件存放到一個佇列裡逐個處理。
在上節例子中使用了 pygame.event.get()
來處理所有事件,如果使用 pygame.event.wait()
, pygame 會等到發生一個事件時才繼續下去,一般在遊戲中不太實用,因為遊戲往往是需要動態運作的。pygame 的常用事件如下所示:
事件 | 產生途徑 | 引數 |
---|---|---|
QUIT | 使用者按下“關閉”按鈕 | None |
ACTIVEEVENT | pygame 被啟用或者隱藏 | gain 、state |
KEYDOWN | 鍵盤被按下 | unicode 、key 、mod |
KEYUP | 鍵盤被放開 | key 、mod |
MOUSEMOTION | 滑鼠移動 | pos 、rel 、buttons |
MOUSEBUTTONDOWN | 滑鼠被按下 | pos 、button |
MOUSEBUTTONUP | 滑鼠被放開 | pos 、button |
1. pygame 的鍵盤事件的處理
通常用 pyagme.event.get()
獲取所有事件,若 event.type == KEYDOWN
event.key
的種類(即 K_a 、 K_b 、 K_LEFT 這種形式)。使用者也可以使用 pygame.key.get_pressed()
來獲取所有被按下的鍵值,對應的就是鍵是否被按下。
keys_pressed = pygame.key.get_pressed()
if keys_pressed[K_SPACE]:
# 空格鍵被按下
fire() # 發射子彈
在 key 模組下有很多函式,如下:
- key.get_focused(): 返回當前的 pygame 視窗是否被啟用。
- key.get_pressed(): 獲得所有被按下的鍵值。
- key.get_mods(): 按下的組合鍵(Alt 、Ctrl 、Shift)。
- key.set_mods(): 模擬按下組合鍵的效果(KMOD_ALT 、 KMOD_CTRL 、 KMOD_SHIFT)。
使用 pygame 開發一個由使用者控制坦克移動的遊戲。在上節例子的基礎上增加通過方向鍵控制坦克移動的功能,併為遊戲增加背景圖片。程式碼如下:
import pygame
def tank_play():
pygame,inite()
tank_image = pygame.image.load("../images/tank.png")
tank_rect = tank_image.get_rect()
back_image = pygame.iamge.load("../images/background2.jpg")
back_rect = back_image.get_rect()
screen = pygame.display.set_mode(back_rect.size)
pygame.display.set_caption("使用者方向鍵控制移動的坦克")
offset = 2 # 偏移量
fps_clock = pygame.time.Clock()
while True:
fps_clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
keys_pressed = pygame.key.get_presssed()
if keys_pressed[pygame.K_RIGHT]:
tank_rect.x += offset
if keys_pressed[pygame.K_LEFT]:
tank_rect.x -= offset
if keys_pressed[oygame.K_UP]:
tank_rect.y -= offset
if keys_pressed[pygame.K_DOWN]:
tank_rect.y += offset
tank_rect.clamp_ip(back_rect)
screen.blit(back_image, back_rect)
screen.blit(tank_image, tank_rect)
pygame.display.update()
if __name__ == '__main--':
tank_play()
當用戶按下方向鍵時坦克按指定方向移動,釋放方向鍵時坦克停止移動。如下所示:
2. pygame 的滑鼠事件的處理
pygame.mouse 的函式如下:
-
pygame.mouse.get_pressed(): 返回按鍵的按下情況,返回的是一元組,分別為左鍵、中鍵、右鍵,如果被按下則為 True 。
-
pygame.mouse.get_rel(): 返回相對偏移量,即(x 方向偏移量,y 方向偏移量)的一元組。
-
pygame.mouse.get_pos(): 返回當前滑鼠位置(x, y)。
例如:
x, y = pygame.mouse.get_pos()
用於獲取滑鼠位置。 -
pygame.mouse.set_pos(): 設定滑鼠位置。
-
pygame.mouse.set_visible(): 設定滑鼠游標是否可見。
-
pygame.mouse.get_focused(): 如果滑鼠在 pygame 視窗內有效,返回 True 。
-
pygame.mouse.set_cursor(): 設定滑鼠的預設游標樣式。
-
pygame.mouse.get_cursor(): 返回滑鼠的游標樣式。
演示滑鼠事件的處理程式,程式碼如下:
from math import pi
from random import randint
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
points = []
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
# 按任意鍵可清屏,並把點恢復到原始狀態
points = []
srceen.fill((255, 255, 255)) # 用白色填充視窗背景
if event.type == pygame.MOUSEBUTTONDOWN: # 滑鼠按下
screen.fill((255, 255, 255))
# 畫隨機矩形
rc = (255, 0, 0) # 紅色
rp = (randint(0, 639), randint(0, 479))
rs = (639 - randint(rp[0], 639), 479 - randint(rp[1], 479))
pygame.draw.rect(screen, rc, pygame.Rect(rp, rs))
# 畫隨機圓形
rc = (0, 255, 0) # 綠色
rp = (randint(0, 639), randint(0, 479))
rr = randint(1, 200)
pygame.draw.circle(screen, rc, rp, rr)
# 獲取當前滑鼠單擊位置
x, y = pygame.mouse.get_pos()
points.append((x, y))
# 根據單擊位置畫弧線
angle = (x / 639) * pi * 2
pygame.draw.arc(screen, (0, 0, 0), (0, 0, 639, 479), 0, angle, 3)
# 根據單擊位置畫橢圓
pygame.draw.ellipse(screen, (0, 255, 0), (0, 0, x, y))
# 從左上和右下畫兩根連線到單擊位置
pygame.draw.line(screen, (0, 0, 255), (0, 0), (x, y))
pygame.draw.line(screen, (255, 0, 0), (640, 480), (x, y))
# 畫單擊軌跡圖
if len(points) > 1:
pygame.draw.lines(screen, (155, 155, 0), points, False, 2)
# 把滑鼠單擊的每個點畫明顯點
for p in points:
pygame.draw.circle(screen, (155, 155, 155), p, 3)
pygame.display.update()
執行這個程式,在視窗上單擊滑鼠就會有圖形出來,按鍵盤上任意鍵可清屏重新開始。如下: