目錄
0 引言
1 環境
2 需求分析
3 代碼實現
4 后記
0 引言
前幾天,星球有人提到貪吃蛇,一下子就勾起了我的興趣,畢竟在那個Nokia稱霸的年代,這款游戲可是經典中的經典啊!而用Python(蛇)玩Snake(貪吃蛇),那再合適不過了
1 環境
操作系統:Windows
Python版本:3.7.3
2 需求分析
我們先來回顧下貪吃蛇中的游戲元素及游戲規則。
首先呢,需要有貪吃蛇、有食物;需要能控制貪吃蛇來上下移動獲取食物;貪吃蛇在吃取食物后,自身長度增加,同時食物消失并隨機生成新的食物;如果貪吃蛇觸碰到四周墻壁或是觸碰到自己身體時,則游戲結束。
游戲規則就是這么簡單,接下來我們借助一個第三方庫pygame來實現它。
Pygame是一個利用SDL庫的游戲庫, 是一組用來開發游戲軟件的 Python 程序模塊。
SDL(Simple DirectMedia Layer)是一個跨平臺庫,支持訪問計算機多媒體硬件(聲音、視頻、輸入等),SDL非常強大,但美中不足的是它是基于 C 語言的。
PyGame是 SDL 庫的 Python 包裝器(wrapper),Pygame 在SDL庫的基礎上提供了各種接口,從而使用用戶能夠使用python語言創建各種各樣的游戲或多媒體程序。
它的安裝方法很簡單,如下:
pip install pygame
想要了解更多pygame功能的朋友也可以查閱官方的文檔。
3 代碼實現
首先導入我們要用到的模塊,除了第三方庫pygame外,我們還會用到一些Python內置的模塊如sys、random、time等,一并導入即可。
import
pygame
,
sys
,
random
,
time
# 從pygame模塊導入常用的函數和常量
from
pygame
.
locals
import
*
3.1 一些全局參數的初始化
接下來,我們需要聲明一些全局參數。如初始化pygame、定義游戲窗口的大小、窗口的標題、定義全局的顏色變量等信息。
# 初始化Pygame庫
pygame
.
init
(
)
# 初始化一個游戲界面窗口
DISPLAY
=
pygame
.
display
.
set_mode
(
(
640
,
480
)
)
# 設置游戲窗口的標題
pygame
.
display
.
set_caption
(
'人人都是Pythonista - Snake'
)
# 定義一個變量來控制游戲速度
FPSCLOCK
=
pygame
.
time
.
Clock
(
)
# 初始化游戲界面內使用的字體
BASICFONT
=
pygame
.
font
.
SysFont
(
"SIMYOU.TTF"
,
80
)
# 定義顏色變量
BLACK
=
pygame
.
Color
(
0
,
0
,
0
)
WHITE
=
pygame
.
Color
(
255
,
255
,
255
)
RED
=
pygame
.
Color
(
255
,
0
,
0
)
GREY
=
pygame
.
Color
(
150
,
150
,
150
)
3.2 初始化貪吃蛇及食物
游戲中需要有貪吃蛇及食物,我們給定一個初始值。我們將整個界面看成許多20*20的小方塊,每個小方塊代表一個標準小格子,貪吃蛇的長度就可以用幾個標準小格子表示。我們將貪吃蛇身體用列表的形式存儲,方便之后的刪減。
‘’‘初始化貪吃蛇及食物’’’
# 貪吃蛇的的初始位置
snake_Head
=
[
100
,
100
]
# 初始化貪吃蛇的長度 (注:這里以20*20為一個標準小格子)
snake_Body
=
[
[
80
,
100
]
,
[
60
,
100
]
,
[
40
,
100
]
]
# 指定蛇初始前進的方向,向右
direction
=
"right"
# 給定第一枚食物的位置
food_Position
=
[
300
,
300
]
# 食物標記:0代表食物已被吃掉;1代表未被吃掉。
food_flag
=
1
3.3 實現貪吃蛇的上下左右移動
我們需要控制貪吃蛇的上下左右的移動,這里通過監聽鍵盤輸入來實現。利用鍵盤中的上下左右鍵或WASD鍵來控制貪吃蛇的運動。
# 檢測按鍵等Pygame事件
for
event
in
pygame
.
event
.
get
(
)
:
if
event
.
type
==
QUIT
:
# 接收到退出事件后,退出程序
pygame
.
quit
(
)
sys
.
exit
(
)
# 判斷鍵盤事件,用 方向鍵 或 wsad 來表示上下左右
elif
event
.
type
==
KEYDOWN
:
if
(
event
.
key
==
K_UP
or
event
.
key
==
K_w
)
and
direction
!=
DOWN
:
direction
=
UP
if
(
event
.
key
==
K_DOWN
or
event
.
key
==
K_s
)
and
direction
!=
UP
:
direction
=
DOWN
if
(
event
.
key
==
K_LEFT
or
event
.
key
==
K_a
)
and
direction
!=
RIGHT
:
direction
=
LEFT
if
(
event
.
key
==
K_RIGHT
or
event
.
key
==
K_d
)
and
direction
!=
LEFT
:
direction
=
RIGHT
接下來就是將蛇前進方向按照鍵盤的輸入進行轉彎操作,并將蛇的頭部當前的位置加入到蛇身的列表中。
# 根據鍵盤的輸入,改變蛇的頭部,進行轉彎操作
if
direction
==
LEFT
:
snake_Head
[
0
]
-=
20
if
direction
==
RIGHT
:
snake_Head
[
0
]
+=
20
if
direction
==
UP
:
snake_Head
[
1
]
-=
20
if
direction
==
DOWN
:
snake_Head
[
1
]
+=
20
# 將蛇的頭部當前的位置加入到蛇身的列表中
snake_Body
.
insert
(
0
,
list
(
snake_Head
)
)
3.4 判斷是否吃到食物
如果蛇頭與食物的位置重合,則判定吃到食物,將食物數量清零;而沒吃到食物的話,蛇身就會跟著蛇頭運動,蛇身的最后一節將被踢出列表。
# 判斷是否吃掉食物
if
snake_Head
[
0
]
==
food_Position
[
0
]
and
snake_Head
[
1
]
==
food_Position
[
1
]
:
food_flag
=
0
else
:
snake_Body
.
pop
(
)
3.5 重新生成食物
當游戲界面中的食物數量為0時,需要重新生成食物。利用random函數來生成隨機位置
# 生成新的食物
if
food_flag
==
0
:
# 隨機生成x, y
x
=
random
.
randrange
(
1
,
32
)
y
=
random
.
randrange
(
1
,
24
)
food_Position
=
[
int
(
x
*
20
)
,
int
(
y
*
20
)
]
food_flag
=
1
3.6 繪制貪吃蛇、食物、分數等信息
定義貪吃蛇的繪制函數
# 繪制貪吃蛇
def
drawSnake
(
snake_Body
)
:
for
i
in
snake_Body
:
pygame
.
draw
.
rect
(
DISPLAY
,
WHITE
,
Rect
(
i
[
0
]
,
i
[
1
]
,
20
,
20
)
)
定義食物的繪制函數
# 繪制食物的位置
def
drawFood
(
food_Position
)
:
pygame
.
draw
.
rect
(
DISPLAY
,
RED
,
Rect
(
food_Position
[
0
]
,
food_Position
[
1
]
,
20
,
20
)
)
定義分數的繪制函數
# 打印出當前得分
def
drawScore
(
score
)
:
# 設置分數的顯示顏色
score_Surf
=
BASICFONT
.
render
(
'%s'
%
(
score
)
,
True
,
GREY
)
# 設置分數的位置
score_Rect
=
score_Surf
.
get_rect
(
)
score_Rect
.
midtop
=
(
320
,
240
)
# 綁定以上設置到句柄
DISPLAY
.
blit
(
score_Surf
,
score_Rect
)
這些都定義好之后,我們需要在游戲主邏輯中調用它們,并刷新Pygame的顯示層,貪吃蛇與食物的每一次移動,都會進行刷新顯示層的操作來顯示。最后我們可以設定一個速度值來合理控制游戲執行的速度。
DISPLAY
.
fill
(
BLACK
)
# 畫出貪吃蛇
drawSnake
(
snake_Body
)
# 畫出食物的位置
drawFood
(
food_Position
)
# 打印出玩家的分數
drawScore
(
len
(
snake_Body
)
-
3
)
# 刷新Pygame的顯示層,貪吃蛇與食物的每一次移動,都會進行刷新顯示層的操作來顯示。
pygame
.
display
.
flip
(
)
# 控制游戲速度
FPSCLOCK
.
tick
(
7
)
3.7 定義游戲結束的畫面并判斷游戲是否結束
定義函數,用于展示游戲結束的畫面并退出程序
# 游戲結束并退出
def
GameOver
(
)
:
# 設置GameOver的顯示顏色
GameOver_Surf
=
BASICFONT
.
render
(
'Game Over!'
,
True
,
GREY
)
# 設置GameOver的位置
GameOver_Rect
=
GameOver_Surf
.
get_rect
(
)
GameOver_Rect
.
midtop
=
(
320
,
10
)
# 綁定以上設置到句柄
DISPLAY
.
blit
(
GameOver_Surf
,
GameOver_Rect
)
pygame
.
display
.
flip
(
)
# 等待3秒
time
.
sleep
(
3
)
# 退出游戲
pygame
.
quit
(
)
# 退出程序
sys
.
exit
(
)
在游戲主邏輯中加入判斷,游戲是否結束
'''游戲結束的判斷'''
# 貪吃蛇觸碰到邊界
if
snake_Head
[
0
]
<
0
or
snake_Head
[
0
]
>
620
:
GameOver
(
)
if
snake_Head
[
1
]
<
0
or
snake_Head
[
1
]
>
460
:
GameOver
(
)
# 貪吃蛇觸碰到自己
for
i
in
snake_Body
[
1
:
]
:
if
snake_Head
[
0
]
==
i
[
0
]
and
snake_Head
[
1
]
==
i
[
1
]
:
GameOver
(
)
4 后記
本文利用Pygame模塊實現了最簡單的貪吃蛇版本。當然還有很多需要優化的地方,比如隨機生成食物時如何避免出現在貪吃蛇的自身上、通過貪吃蛇的長度來自動控制游戲速度等等。更高級一點的有如何通過AI自動玩貪吃蛇、貪吃蛇的雙人對戰等,期待大家利用Python可以把貪吃蛇玩出一個新的高度!
公眾號「 Python專欄 」后臺回復關鍵字「 貪吃蛇 」獲取本文全套完整代碼!
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
