在很久很久以前,手機屏幕都還是黑白的年代,有一款叫做“貪吃蛇”的游戲風靡了大街小巷,在那分辨率極低的屏幕上,幾條扭扭曲曲的弧線似乎穿越了整個童年。
這節課上,就讓我們用DFRobot行空板來實現一下這款經典的游戲吧!
任務目標
在屏幕上進行貪吃蛇小游戲。


知識點
1、認識pygame庫
2、學習使用pygame庫創建游戲窗口的方法
3、學習使用pygame庫繪制圖形、繪制文本、更新屏幕顯示的方法
4、學習使用pygame庫實現鍵盤交互的方法
材料清單
硬件清單:


軟件使用:Mind+編程軟件x1
知識儲備
1、貪吃蛇小游戲實現原理與邏輯
(1)實現原理
在這個貪吃蛇游戲中,我們將整個游戲區域劃分成一個個的小格子,每一個格子的所在位置可以通過行列來表示,由一組連在一起的小格子組成“蛇”,“蛇”分為“蛇頭”和“蛇身”兩部分。“蛇頭”用一個格子表示,“蛇身”用一個列表來存儲,結合不同的顏色,這樣一條“蛇”就出來了?!吧摺钡囊苿觿t是將下一格的行列位置添加到列表開頭,并移除列表的最后一個元素,就相當于“蛇”向前移動了一格。食物同樣以格子的形式隨機呈現,當“蛇頭”與食物的位置重合,那么“蛇”就吃到了食物,而當“蛇”移動超出了范圍亦或者“蛇頭”撞在了“蛇身”上,那么游戲結束并計算食物數量。
(2)游戲邏輯圖
由于游戲包含了蛇的移動、吃食物、事件監測、結束游戲等多個功能,在編程時,我們可以通過定義函數的方式,實現各個不同的功能部分,之后依據游戲邏輯在所需處調用即可。

2、什么是pygame庫
pygame是專為電子游戲設計的跨平臺Python庫。通過它,我們可以設計包含圖像、聲音等元素的電子游戲。pygame做游戲開發的優勢在于不需要過多地考慮底層相關的內容,而可以把重心放在游戲邏輯上,例如,pygame中集成了很多和底層相關的模塊,如訪問顯示設備、管理事件、使用字體等。關于pygame常用的一些模塊可參考下表。
模塊名 | 功能 |
pygame.display | 訪問顯示設備 |
pygame.event | 管理事件 |
pygame.draw | 繪制形狀、線和點 |
pygame.key | 讀取鍵盤按鍵 |
pygame.mouse | 控制鼠標事件 |
pygame.music | 播放音頻 |
3、pygame庫常見函數
pygame庫中的函數有很多,我們只使用其中的一部分,編程時,通過“import pygame”導入庫后可采用“pygame.函數名()”的形式來實現功能。
(1)init()函數初始化pygame模塊
通過init()函數我們可對pygame中的模塊進行初始化,在編程時,我們需要將這條指令放在其他pygame指令之前,初始化后方可使用其中的模塊。
pygame.init() # 初始化pygame
(2)quit()函數退出pygame庫
quit()函數是與init()函數功能相反的一個函數,可以實現退出pygame,使pygame庫結束工作。在編程時,我們通常在需要結束游戲時使用。
pygame.quit() # 退出pygame
4、pygame庫display模塊中的常用方法
pygame庫display模塊可用來訪問顯示設備,以便在設備上顯示內容。其中的方法有很多,我們只使用其中的一部分,在編程時,可通過“模塊名.方法名()”的形式來實現功能。
(1)set_mode()方法初始化一個準備顯示的窗口界面
set_mode()方法可以實現游戲窗口的創建
size=(240,320) # 定義尺寸
window = pygame.display.set_mode(size) # 創建游戲窗口,尺寸為(240,320)
其中,size是我們設定的要顯示的游戲窗口的尺寸大小,和行空板屏幕相同,window是一個生成的屏幕Surface對象,我們可以對它進行填充顏色、涂畫、添加其他對象等各種操作。
如下,在填充顏色時,我們可通過“對象.fill()”的指令實現。
bg_color=(255,255,255) # 定義背景色為白
window.fill(bg_color) # fillcolor # 填充窗口的背景顏色
而要想將其他對象添加到窗口對象上,我們可通過“對象.blit()”指令來實現。
window.blit(score, (40,250)) # 在窗口上(40,250)處顯示得分
(2)flip()方法更新屏幕
flip()方法可以將待顯示的畫面更新到屏幕上。通常,我們在使用pygame.display模塊編寫一些功能后,需要使用flip方法,才能將其更新顯示到屏幕上。
pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕
5、pygame庫draw模塊中的常用方法
pygame庫display模塊可用來繪制各種不同的形狀,其中的方法有很多,編程時,可通過“模塊名.方法名()”的形式來實現功能。
(1)rect()方法繪制矩形
rect()方法可以實現矩形的繪制。
left=point.col*15 # 定義小方格距離左邊緣的距離
top=point.row*15 # 定義小方格距離上邊緣的距離
pygame.draw.rect(window,color,(left,top,15,15)) # 在窗口上繪制矩形,顏色為color
其中,window表示矩形繪制在窗口上,color是指矩形的顏色,left和top分別指矩形距離窗口左邊緣和上邊緣的距離,用以表示矩形的位置區域。
6、pygame庫font模塊中的常用方法
pygame庫font模塊可實現字體的使用,其中的方法有很多,編程時,可通過“模塊名.方法名()”的形式來實現功能。
(1)SysFont()方法創建字體對象
SysFont()方法可以實現字體對象的創建。
font = pygame.font.SysFont('Arial', 20) # 設置字體
其中,Arial指的是具體的字體類型,20指的是字體大小,font是一個變量用于存儲生成的字體對象。
而在創建好字體對象后,我們就可以在其上繪制具體的文本,以達到顯示的效果,我們可通過“對象.render()”指令來實現。
score = font.render('Your Score is ' , False, 'pink') # 計算得分
其中,'Your Score is '指的是具體繪制的文本,False表示無需抗鋸齒,pink指的是文本的顏色,score是一個變量用于存儲生成的文本。
7、pygame庫中的事件、事件類型、鍵盤事件以及事件檢測
事件(Event)是 pygame 的重要模塊之一,它是構建整個游戲程序的核心,比如鼠標點擊、鍵盤敲擊、游戲窗口移動、退出游戲等等,這些都可以看做是“事件”,pygame 會接受用戶產生的各種操作(或事件),這些操作隨時產生,并且操作量可大可小,那么 pygame 是如何處理這些事件的呢?
pygame 定義了一個專門用來處理事件的結構,即事件隊列,該結構遵循隊列“先到先處理”的基本原則,通過事件隊列,我們可以有序的、逐一的處理用戶的操作(觸發事件)。對于 pygame 中常用的游戲事件,可參考下表:
事件類型 | 描述 | 成員屬性 |
QUIT | 用戶按下窗口的關閉按鈕 | None |
KEYDOWN | 鍵盤按下 | unicode、key、mod |
KEYUP | 鍵盤放開 | key、mod |
MOUSEBUTTONDOWN | 鼠標按下 | pos, button |
MOUSEBUTTONUP | 鼠標放開 | pos, button |
Tips:當使用 pygame 做游戲開發時,上述事件并非都會應用的到。
其中,鍵盤事件會涉及到大量的按鍵操作,比如游戲中的上下左右,或者人物的前進、后退等操作,這些都需要鍵盤來配合實現。
鍵盤事件提供了一個 key 屬性,通過該屬性可以獲取鍵盤的按鍵。pygame 將鍵盤上的字母鍵、數字鍵、組合鍵等按鍵以常量的方式進行了定義,對于部分常用按鍵的常量,可參考下表:
常量名 | 描述 |
K_SPACE | 空格鍵(Space) |
K_RETURN | 回車鍵(Enter) |
K_0...K_9 | 0...9 |
K_a...Kz | a...z |
K_UP | 向上箭頭(up arrow) |
K_DOWN | 向下箭頭(down arrow) |
K_LEFT | 向左箭頭(left arrow) |
K_RIGHT | 向右箭頭(right arrow) |
Tips :由于行空板在開發時已做處理,將按鍵a、b映射為鍵盤上的a、b按鍵,因此,在獲取鍵盤事件時,按下行空板上的按鍵a、b,同樣能夠被檢測出來。
最后,要想實現鍵盤按鍵控制游戲的進行,那么我們就需要先檢測事件,那如何才能實現呢?
pygame庫event 模塊提供了處理事件隊列的常用方法,我們通過其中的get()方法就可以實現對于事件的檢測。
events = pygame.event.get() # 獲取事件
其中,events是一個變量,用來存儲檢測到的事件。
而在獲取到了事件之后,我們就可以對它進行判別了
if (event.type == pygame.QUIT): # 如果事件類型為退出(關閉窗口)
pygame.quit() # 退出游戲
if (event.type == pygame.KEYDOWN): # 如果事件類型為鍵盤按下
if (event.key == pygame.K_a): # 如果是按鍵a被按下
.......
elif (event.key == pygame.K_b): # 如果是按鍵b被按下
其中,event.type表示事件的類型,pygame.QUIT表示退出事件,pygame.KEYDOWN表示鍵盤按下事件,event.key表示鍵盤的按鍵, pygame.K_a表示按鍵a,pygame.K_b表示按鍵b。
動手實踐
任務描述1:創建游戲窗口
通過pygame庫創建一個游戲窗口界面。
1、硬件搭建
通過USB連接線將行空板連接到計算機
2、程序編寫
STEP1:創建與保存項目文件
啟動Mind+,另存項目并命名為“006、貪吃蛇小游戲”。
STEP2:創建與保存Python文件
創建一個Python程序文件“main1.py”,雙擊打開。
STEP3:程序編寫
(1) 導入所需功能庫
在這個任務中,我們需要結合pygame庫和time庫來繪制游戲窗口,因此,我們須先導入它們。
import pygame # 導入pygame庫import time # 導入time庫 |
(2) 初始化游戲并創建指定尺寸的游戲窗口
在使用pygame進行游戲時,我們需先對其進行初始化操作,之后,為了能和行空板的屏幕一致,我們創建一個大小為(240,320)的游戲窗口。
pygame.init() # 游戲初始化W=240 # 定義寬H=320 # 定義高size=(240,320) # 定義尺寸window = pygame.display.set_mode(size) # 創建游戲窗口,尺寸為(240,320) |
(3) 定義背景色和初始運行狀態
創建好游戲窗口后,我們再為其定義一個背景色和初始的運行狀態以便在后續進行設置。
bg_color=(255,255,255) # 定義背景色為白run=True # 定義初始運行狀態為True,表示運行 |
(4) 填充窗口的背景顏色并保持窗口顯示
接下來,我們對窗口的背景進行顏色的填充,而為了能使窗口始終保持顯示,我們需要不斷刷新窗口屏幕的顯示內容,這里我們結合循環來實現。
while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # delay 0.2 seconds |
Tips:完整示例程序如下:
'''創建游戲窗口'''import pygame # 導入pygame庫import time # 導入time庫 pygame.init() # 游戲初始化W=240 # 定義寬H=320 # 定義高size=(240,320) # 定義尺寸window = pygame.display.set_mode(size) # 創建游戲窗口,尺寸為(240,320)bg_color=(255,255,255) # 定義背景色為白run=True # 定義初始運行狀態為True,表示運行 while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # delay 0.2 seconds |
3、程序運行
STEP1:遠程連接行空板
STEP2:點擊右上方的運行按鈕
STEP3:觀察效果
觀察行空板,首先可以看到行空板的屏幕變成了白色,而這,正是我們所創建游戲窗口的背景。

任務描述2:添加游戲元素
上述生成的屏幕窗口上空空如也,為了完善游戲,接下來,我們將在其上添加游戲中的最重要的角色元素---蛇和食物。
1、程序編寫
STEP1:創建與保存項目文件
新建一個Python程序文件“main2.py”,雙擊打開。
Step2:程序編寫
和任務一相同,在程序的開始部分,我們依舊導入所需功能庫,初始化游戲并創建游戲窗口。之后再在此基礎上編寫其他部分程序。
(1)定義游戲方式
在貪吃蛇游戲中,有蛇和食物兩個最重要的元素,那么如何才能在我們的屏幕上表示它呢?
這里,我們將游戲窗口劃分成一個個小方格,通過方格來表示界面內的元素,每個小方格的寬和高皆為15像素,這樣,由于窗口大小為240*320,因此在橫向上會有18個方格,縱向上會有24個,即24行18列的小方格。
# 將游戲窗口劃分為一個個小方格,每個方格的寬和高皆為15,共計24行,18列ROW=24 # 定義行數,每格15*15,24行18列COL=18 # 定義列數cell_width=W/COL # 定義格子的寬cell_height=H/ROW # 定義格子的高 |
(4)定義方格位置
接下來,我們定義一個Point類,將方格看作一個點,通過行與列來表示它的位置。
# 定義Point類以表示方格的位置class Point: row=0 # 行 col=0 # 列 def __init__(self,row,col): # 行 列 self.row=row self.col=col |
(5)定義蛇頭、蛇身、食物的位置和顏色
之后,我們將蛇分為蛇頭和蛇身兩部分,設定其初始時各占一個和三個方格,而食物也作為一個元素占一格。
接著我們通過實例化類的方式來定義他們的位置,同時也定義好他們顏色,其中,蛇身的位置我們以列表來表示,具體過程如下。
# 定義蛇頭、蛇身、食物的位置和顏色head = Point(row=int(ROW/2),col=int(COL/2)) # 定義蛇頭的小方格位置在第12行,第9列snakes=[ Point(row=head.row,col=head.col+1), # 定義蛇身1的小方格位置在第12行,第10列 Point(row=head.row,col=head.col+2), # 定義蛇身2的小方格位置在第12行,第11列 Point(row=head.row,col=head.col+3) # 定義蛇身3的小方格位置在第12行,第12列]food = Point(row=2,col=3) # 定義食物的小方格位置在第2行,第3列head_color=(65,105,225) # 定義蛇頭顏色snake_color=(204,204,204) # 定義蛇身顏色food_color=(255,10,10) # 定義食物顏色 |
(6)定義每個小方格的繪制方法
隨后,我們通過pygame庫繪制矩形的方法來繪制小方格,由于每個小方格的尺寸大小一致,僅位置和顏色不同,因此,我們可定義一個繪制方格的通用函數,將位置和顏色作為兩個參數傳入,其中,各個方格的位置,我們可以通過其所在的行和列來確定。
# 定義每個小方格的繪制(包含兩個參數:位置和顏色)def rect(point,color): left=point.col*cell_width # 定義小方格距離左邊緣的距離 top=point.row*cell_height # 定義小方格距離上邊緣的距離 pygame.draw.rect(window,color,(left,top,cell_width,cell_height)) # 在窗口上繪制矩形 |
(6)實例化Star類,并結束繪圖
最后,我們在指定的位置上繪制指定顏色的方格,分別代表蛇頭、蛇身和食物,而為了使其始終出現,編程時我們將其放在循環中。
while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 # 以小方格來定義蛇身、蛇頭和食物 for snake in snakes: rect(snake,snake_color) # 創建蛇身,顏色為snake_color rect(head,head_color) # 創建蛇頭,顏色為head_color rect(food,food_color) # 創建食物,顏色為food_color pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # delay 0.2 seconds |
Tips:完整示例程序如下:
'''在游戲窗口上添加蛇和食物'''import pygame # 導入pygame庫import time # 導入time庫 pygame.init() # 游戲初始化W=240 # 定義寬H=320 # 定義高size=(240,320) # 定義尺寸window = pygame.display.set_mode(size) # 創建游戲窗口,尺寸為(240,320)bg_color=(255,255,255) # 定義背景色為白 # 將游戲窗口劃分為一個個小方格,每個方格的寬和高皆為15,共計24行,18列ROW=24 # 定義行數,每格15*15,24行18列COL=18 # 定義列數cell_width=W/COL # 定義格子的寬cell_height=H/ROW # 定義格子的高 # 定義Point類以表示方格的位置class Point: row=0 # 行 col=0 # 列 def __init__(self,row,col): # 行 列 self.row=row self.col=col# 定義蛇頭、蛇身、食物的位置和顏色head = Point(row=int(ROW/2),col=int(COL/2)) # 定義蛇頭的小方格位置在第12行,第9列snakes=[ Point(row=head.row,col=head.col+1), # 定義蛇身1的小方格位置在第12行,第10列 Point(row=head.row,col=head.col+2), # 定義蛇身2的小方格位置在第12行,第11列 Point(row=head.row,col=head.col+3) # 定義蛇身3的小方格位置在第12行,第12列]food = Point(row=2,col=3) # 定義食物的小方格位置在第2行,第3列head_color=(65,105,225) # 定義蛇頭顏色snake_color=(204,204,204) # 定義蛇身顏色food_color=(255,10,10) # 定義食物顏色 # 定義每個小方格的繪制(包含兩個參數:位置和顏色)def rect(point,color): left=point.col*cell_width # 定義小方格距離左邊緣的距離 top=point.row*cell_height # 定義小方格距離上邊緣的距離 pygame.draw.rect(window,color,(left,top,cell_width,cell_height)) # 在窗口上繪制矩形,顏色為color run=True # 定義初始運行狀態為True,表示運行while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 # 以小方格來定義蛇身、蛇頭和食物 for snake in snakes: rect(snake,snake_color) # 創建蛇身,顏色為snake_color rect(head,head_color) # 創建蛇頭,顏色為head_color rect(food,food_color) # 創建食物,顏色為food_color pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # delay 0.2 seconds |
2、程序運行
STEP1:遠程連接行空板
STEP2:運行程序并觀察效果
點擊運行后,觀察行空板,可以看到在游戲窗口內顯示出了一條紅頭藍身的蛇,以及一顆黃色的食物。

任務描述3:設定游戲機制
在上個任務中,我們在游戲界面內添加了蛇和食物,但這還不夠,接下來,我們將設定游戲機制,使得能通過行空板的板載按鍵a和b控制蛇左右移動來吃食物,并且,食物由原來在固定位置生成改為隨機生成。
1、程序編寫
STEP1:創建與保存項目文件
新建一個Python程序文件“main3.py”,雙擊打開。
STEP2:程序編寫
這個程序中,我們承任務2繼續編寫。
(1)設定食物的隨機生成
這里,我們修改原來固定位置的食物,使其在屏幕窗口內隨機位置生成。
# 定義食物的生成位置def gen_food(): pos = Point(row=random.randint(0,ROW-1),col=random.randint(0,COL-1)) # 定義食物的小方格位置在窗口內隨機的地方 return posfood = gen_food() # 生成食物的位置 |
(2)定義事件監測
為了能通過行空板上的按鍵來控制蛇的移動,我們首先需要定義一個事件監測,具體過程如下。
# 定義事件監測def detect(): global direction global run events = pygame.event.get() # 獲取事件 for event in events: # 遍歷所有事件 if (event.type == pygame.QUIT): # 如果事件類型為退出(關閉窗口) pygame.quit() # 退出游戲 run = 0 if (event.type == pygame.KEYDOWN): # 如果事件類型為鍵盤按下 if (event.key == pygame.K_a): # 如果是按鍵a被按下 if (direction == 'up'): # 如果原來方向為up(向上) direction = 'left' # 將方向設為left(向左) elif (direction == 'left'): direction = 'down' elif (direction == 'down'): direction = 'right' elif (direction == 'right'): direction = 'up' print(direction) elif (event.key == pygame.K_b): # 如果是按鍵b被按下 if (direction == 'up'): # 如果原來方向為up(向上) direction = 'right' # 將方向設為right(向右) elif (direction == 'right'): direction = 'down' elif (direction == 'down'): direction = 'left' elif (direction == 'left'): direction = 'up' print(direction) |
(3)定義移動方式并設定初始方向
之后,我們設定蛇的移動方式,并定義初始方向為left,具體過程如下。
# 定義移動方式def move(): global direction if direction == 'left': # 如果方向為left head.col-=1 # 設置蛇頭向左移動一格(蛇頭所在的列數-1) elif direction == 'right': head.col+=1 elif direction == 'up': head.row-=1 elif direction == 'down': head.row+=1 direction = 'left' # 定義初始方向為left |
(4)復制方格位置
由于蛇在吃到食物時蛇身會增加,從效果上看蛇頭的位置變成了蛇身第一格,因此,我們需要在定義Point類時,補充一個copy實例方法,達到復制方格自身位置的功能,以便后續在吃食物時調用。
# 定義Point類以表示方格的位置class Point: row=0 # 行 col=0 # 列 def __init__(self,row,col): # 行 列 self.row=row self.col=col def copy(self): # 復制 return Point(row=self.row,col=self.col) |
(5)定義吃食物
接下來,我們定義蛇吃食物的方法,具體過程如下。
# 定義吃食物def eat(): global food eating = (head.row == food.row and head.col == food.col) # 定義正在吃的形式:蛇頭的行列位置與食物相同 if eating : # 如果正在吃 food = Point(row=random.randint(0,ROW-1),col=random.randint(0,COL-1)) # 在隨機處再生成一顆食物 snakes.insert(0,head.copy()) # 處理蛇身:1、把原來的頭,插入到蛇身的最初位置(即在snakes蛇身列表的第0個位置增加一個元素) if not eating: # 如果不在吃了,吃完后 snakes.pop() #處理蛇身:2、把蛇身的最后一格移除(即移除snakes蛇身列表的最后一個元素) |
(6)循環調用
最后,我們將上述定義好的事件監測、移動、吃食物三個功能函數放入循環中,使其永久執行。
while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 # 以小方格來定義蛇身、蛇頭和食物 for snake in snakes: rect(snake,snake_color) # 創建蛇身,顏色為snake_color rect(head,head_color) # 創建蛇頭,顏色為head_color rect(food,food_color) # 創建食物,顏色為food_color eat() # 吃 detect() # 事件監測 move() # 移動 pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # 可修改延時的時間改變蛇的移動速度,調整游戲難易度 |
Tips:完整示例程序如下:
'''控制蛇的移動、生成隨機的食物、蛇吃食物'''import pygame # 導入pygame庫import random # 導入隨機數庫import time # 導入time庫 pygame.init() # 游戲初始化W=240 # 定義寬H=320 # 定義高size=(240,320) # 定義尺寸window = pygame.display.set_mode(size) # 創建游戲窗口,尺寸為(240,320)bg_color=(255,255,255) # 定義背景色為白 # 將游戲窗口劃分為一個個小方格,每個方格的寬和高皆為15,共計24行,18列ROW=24 # 定義行數,每格15*15,24行18列COL=18 # 定義列數cell_width=W/COL # 定義格子的寬cell_height=H/ROW # 定義格子的高 # 定義Point類以表示方格的位置class Point: row=0 # 行 col=0 # 列 def __init__(self,row,col): # 行 列 self.row=row self.col=col def copy(self): # 復制 return Point(row=self.row,col=self.col) # 定義蛇頭、蛇身的位置和顏色head = Point(row=int(ROW/2),col=int(COL/2)) # 定義蛇頭的小方格位置在第12行,第9列snakes=[ # 定義蛇身列表 Point(row=head.row,col=head.col+1), # 定義蛇身1的小方格位置在第12行,第10列 Point(row=head.row,col=head.col+2), # 定義蛇身2的小方格位置在第12行,第11列 Point(row=head.row,col=head.col+3) # 定義蛇身3的小方格位置在第12行,第12列]# 定義食物的生成位置def gen_food(): pos = Point(row=random.randint(0,ROW-1),col=random.randint(0,COL-1)) # 定義食物的小方格位置在窗口內隨機的地方 return posfood = gen_food() # 生成食物的位置 head_color=(65,105,225) # 定義蛇頭顏色snake_color=(204,204,204) # 定義蛇身顏色food_color=(255,10,10) # 定義食物顏色 # 定義每個小方格的繪制(包含兩個參數:位置和顏色)def rect(point,color): left=point.col*cell_width # 定義小方格距離左邊緣的距離 top=point.row*cell_height # 定義小方格距離上邊緣的距離 pygame.draw.rect(window,color,(left,top,cell_width,cell_height)) # 在窗口上繪制矩形,顏色為color # 定義事件檢測def detect(): global direction global run events = pygame.event.get() # 獲取事件 for event in events: # 遍歷所有事件 #for event in pygame.event.get(): if (event.type == pygame.QUIT): # 如果事件類型為退出(關閉窗口) pygame.quit() # 退出游戲 run = 0 if (event.type == pygame.KEYDOWN): # 如果事件類型為鍵盤按下 if (event.key == pygame.K_a): # 如果是按鍵a被按下 if (direction == 'up'): # 如果原來方向為up(向上) direction = 'left' # 將方向設為left(向左) elif (direction == 'left'): direction = 'down' elif (direction == 'down'): direction = 'right' elif (direction == 'right'): direction = 'up' print(direction) elif (event.key == pygame.K_b): # 如果是按鍵b被按下 if (direction == 'up'): # 如果原來方向為up(向上) direction = 'right' # 將方向設為right(向右) elif (direction == 'right'): direction = 'down' elif (direction == 'down'): direction = 'left' elif (direction == 'left'): direction = 'up' print(direction) # 定義移動方式def move(): global direction if direction == 'left': # 如果方向為left head.col-=1 # 設置蛇頭向左移動一格(蛇頭所在的列數-1) elif direction == 'right': head.col+=1 elif direction == 'up': head.row-=1 elif direction == 'down': head.row+=1 # 定義吃食物def eat(): global food eating = (head.row == food.row and head.col == food.col) # 定義正在吃的形式:蛇頭的行列位置與食物相同 if eating : # 如果正在吃 food = Point(row=random.randint(0,ROW-1),col=random.randint(0,COL-1)) # 在隨機處再生成一顆食物 snakes.insert(0,head.copy()) # 處理蛇身:1、把原來的頭,插入到蛇身的最初位置(即在snakes蛇身列表的第0個位置增加一個元素) if not eating: # 如果不在吃了,吃完后 snakes.pop() #處理蛇身:2、把蛇身的最后一格移除(即移除snakes蛇身列表的最后一個元素) direction = 'left' # 定義初始方向為leftrun = True # 定義初始運行狀態為True,表示運行while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 # 以小方格來定義蛇身、蛇頭和食物 for snake in snakes: rect(snake,snake_color) # 創建蛇身,顏色為snake_color rect(head,head_color) # 創建蛇頭,顏色為head_color rect(food,food_color) # 創建食物,顏色為food_color eat() # 吃 detect() # 事件監測 move() # 移動 pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # 可修改延時改變蛇的移動速度,調整游戲難易度 |
2、程序運行
STEP1:遠程連接行空板
STEP2:運行程序并觀察效果
點擊運行后,觀察行空板,可以看到在游戲窗口內顯示出了一條紅頭藍身的蛇,以及一顆黃色的食物。隨后蛇向左移動,此時,我們可通過按下板載按鍵a和b來分別控制蛇左轉和右轉。

任務描述4:結束游戲并計分
最后,我們在上述功能的基礎上添加結束游戲和計分機制。
1、程序編寫
STEP1:創建與保存項目文件
新建一個Python程序文件“main4.py”,雙擊打開。
Step2:程序編寫
(1)導入所需功能庫創建字體對象
由于需要顯示得分,因此,我們需要提前在定義背景顏色后創建一個字體對象。
font = pygame.font.SysFont('Arial', 20) # 設置字體 |
(2)結束游戲機制
之后,我們在吃食物的功能后再定義結束游戲的方式:要么蛇撞上窗口四周,要么撞上自身。同時,我們設定在結束前顯示最終的游戲得分。
# 定義游戲結束def game_over(): global run dead=False # 定義一個狀態dead # 游戲結束方式1、撞墻 if head.col<0 or head.row<0 or head.col>=COL or head.row>=ROW: # 如果蛇頭的行和列在屏幕外 dead = True # 游戲結束方式2、撞自己 for snake in snakes: if head.col==snake.col and head.row==snake.row: # 如果蛇頭和蛇身位置相同 dead = True break if dead: # 如果狀態為dead score = font.render('Your Score is ' + str(10*len(snakes)-30), False, 'pink') # 計算得分 window.blit(score, (40,250)) # 在窗口上顯示得分 pygame.display.flip() # Refresh all displays to the screen # 更新所有顯示的內容到屏幕 print("GG") # goodgame! =-= time.sleep(5) # delay 5 seconds run=False # set state False |
(3)循環執行
最后,我們將上述定義好的結束游戲功能函數放入循環中,使其永久執行。
while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 # 以小方格來定義蛇身、蛇頭和食物 for snake in snakes: rect(snake,snake_color) # 創建蛇身,顏色為snake_color rect(head,head_color) # 創建蛇頭,顏色為head_color rect(food,food_color) # 創建食物,顏色為food_color eat() # 吃 detect() # 事件監測 move() # 移動 game_over() # 結束游戲 pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # delay 0.2 seconds # 可修改延時的時間改變蛇的移動速度,調整游戲難易度 |
Tips:完整示例程序如下:
'''計分和結束游戲'''import pygame # 導入pygame庫import random # 導入隨機數庫import time # 導入 time庫 pygame.init() # 游戲初始化W=240 # 定義寬H=320 # 定義高size=(240,320) # 定義尺寸window = pygame.display.set_mode(size) # 創建游戲窗口,尺寸為(240,320)bg_color=(255,255,255) # 定義背景色為白 font = pygame.font.SysFont('Arial', 20) # 創建字體對象 # 將游戲窗口劃分為一個個小方格,每個方格的寬和高皆為15,共計24行,18列ROW=24 # 定義行數,每格15*15,24行18列COL=18 # 定義列數cell_width=W/COL # 定義格子的寬cell_height=H/ROW # 定義格子的高 # 定義Point類以表示方格的位置class Point: row=0 # 行 col=0 # 列 def __init__(self,row,col): # 行 列 self.row=row self.col=col def copy(self): # 復制 return Point(row=self.row,col=self.col) # 定義蛇頭、蛇身的位置和顏色head = Point(row=int(ROW/2),col=int(COL/2)) # 定義蛇頭的小方格位置在第12行,第9列snakes=[ # 定義蛇身列表 Point(row=head.row,col=head.col+1), # 定義蛇身1的小方格位置在第12行,第10列 Point(row=head.row,col=head.col+2), # 定義蛇身2的小方格位置在第12行,第11列 Point(row=head.row,col=head.col+3) # 定義蛇身3的小方格位置在第12行,第12列]# 定義食物的生成位置def gen_food(): pos = Point(row=random.randint(0,ROW-1),col=random.randint(0,COL-1)) # 定義食物的小方格位置在窗口內隨機的地方 return posfood = gen_food() # 生成食物的位置 head_color=(65,105,225) # 定義蛇頭顏色snake_color=(204,204,204) # 定義蛇身顏色food_color=(255,10,10) # 定義食物顏色 # 定義每個小方格的繪制(包含兩個參數:位置和顏色)def rect(point,color): left=point.col*cell_width # 定義小方格距離左邊緣的距離 top=point.row*cell_height # 定義小方格距離上邊緣的距離 pygame.draw.rect(window,color,(left,top,cell_width,cell_height)) # 在窗口上繪制矩形,顏色為color # 定義事件檢測def detect(): global direction global run events = pygame.event.get() # 獲取事件 for event in events: # 遍歷所有事件 #for event in pygame.event.get(): if (event.type == pygame.QUIT): # 如果事件類型為退出(關閉窗口) pygame.quit() # 退出游戲 run = 0 if (event.type == pygame.KEYDOWN): # 如果事件類型為鍵盤按下 if (event.key == pygame.K_a): # 如果是按鍵a被按下 if (direction == 'up'): # 如果原來方向為up(向上) direction = 'left' # 將方向設為left(向左) elif (direction == 'left'): direction = 'down' elif (direction == 'down'): direction = 'right' elif (direction == 'right'): direction = 'up' print(direction) elif (event.key == pygame.K_b): # 如果是按鍵b被按下 if (direction == 'up'): # 如果原來方向為up(向上) direction = 'right' # 將方向設為right(向右) elif (direction == 'right'): direction = 'down' elif (direction == 'down'): direction = 'left' elif (direction == 'left'): direction = 'up' print(direction) # 定義移動方式def move(): global direction if direction == 'left': # 如果方向為left head.col-=1 # 設置蛇頭向左移動一格(蛇頭所在的列數-1) elif direction == 'right': head.col+=1 elif direction == 'up': head.row-=1 elif direction == 'down': head.row+=1 # 定義吃食物def eat(): global food eating = (head.row == food.row and head.col == food.col) # 定義正在吃的形式:蛇頭的行列位置與食物相同 if eating : # 如果正在吃 food = Point(row=random.randint(0,ROW-1),col=random.randint(0,COL-1)) # 在隨機處再生成一顆食物 snakes.insert(0,head.copy()) # 處理蛇身:1、把原來的頭,插入到蛇身的最初位置(即在snakes蛇身列表的第0個位置增加一個元素) if not eating: # 如果不在吃了,吃完后 snakes.pop() #處理蛇身:2、把蛇身的最后一格移除(即移除snakes蛇身列表的最后一個元素) # 定義游戲結束def game_over(): global run dead=False # 定義一個狀態dead # 游戲結束方式1、撞墻 if head.col<0 or head.row<0 or head.col>=COL or head.row>=ROW: # 如果蛇頭的行和列在屏幕外 dead = True # 游戲結束方式2、撞自己 for snake in snakes: if head.col==snake.col and head.row==snake.row: # 如果蛇頭和蛇身位置相同 dead = True break if dead: # 如果狀態為dead score = font.render('Your Score is ' + str(10*len(snakes)-30), False, 'pink') # 計算得分 window.blit(score, (40,250)) # 在窗口上顯示得分 pygame.display.flip() # Refresh all displays to the screen # 更新所有顯示的內容到屏幕 print("GG") # goodgame! =-= time.sleep(5) # delay 5 seconds run=False # set state False direction = 'left' # 定義初始方向為leftrun = True # 定義初始運行狀態為True,表示運行while run: # 游戲循環 window.fill(bg_color) # fillcolor # 填充窗口的背景顏色 # 以小方格來定義蛇身、蛇頭和食物 for snake in snakes: rect(snake,snake_color) # 創建蛇身,顏色為snake_color rect(head,head_color) # 創建蛇頭,顏色為head_color rect(food,food_color) # 創建食物,顏色為food_color eat() # 吃 detect() # 事件監測 move() # 移動 game_over() # 結束游戲 pygame.display.flip() # Refresh all displays to the window # 更新所有待顯示的內容到屏幕 time.sleep(0.2) # delay 0.2 seconds # 可修改延時的時間改變蛇的移動速度,調整游戲難易度 |
2、程序運行
STEP1:遠程連接行空板
STEP2:運行程序并觀察效果
運行程序后,我們可通過板載按鍵a、b控制蛇的移動,當蛇撞上自身或撞上窗口四邊時,游戲結束,此時可看到我們游戲的最終得分。


挑戰自我
1、和同學比一比,看誰的得分更高吧!
2、嘗試減小屏幕刷新的時間間隔,使蛇移動得更快,加大難度試一試吧!
3、想一想,我們是否可以給不同難度的游戲設置關卡呢,自己動手修改程序,練習一下吧!
審核編輯:符乾江
-
python
+關注
關注
56文章
4813瀏覽量
85299 -
DFRobot
+關注
關注
4文章
1160瀏覽量
9917
發布評論請先 登錄
相關推薦
視頻詳解:上海尤老師verilog入門到實戰第六課
【FPGA DEMO】Lab 9:貪吃蛇小游戲
基于stm32的貪吃蛇小游戲的設計資料分享
單片機入門教程第六課-單片機的內外部結構分析(四)
基于嵌入式linux開發板的貪吃蛇游戲運行
基于stm32的貪吃蛇小游戲

基于STM32的貪吃蛇小游戲

【STM32】貪吃蛇小游戲

評論