每個初學寫代碼的人可能都想在學習了一些基礎知識後,希望能夠寫出一點拿得出手,秀的出來,但又在自己能力範圍内的東西(沒錯,說的是我自己)。

本人是個在讀大學生,python小白,就想完成個多年前“自己寫出個遊戲的夢想”,選擇了好像不難的貪吃蛇。
寫之前,因為有用C試寫過貪吃蛇,是以有個大概方向與思路,但python和C畢竟還是有點差別的,是以先是查閱了很多現有的大佬寫的貪吃蛇小遊戲,牛嗎?都很牛,但就是太牛了啊,牛到我這種小白真看不太懂,各種建立類,然後用什麼pygame裡面的某些我看不懂的又沒有解釋的變量,然後寫出了華麗、靈活的小蛇在螢幕上亂舞,但我除了複制代碼,我真看不懂啊!
萬一我拿複制的代碼裝X的時候,别人問我這行的解釋,我可咋辦?
是以這篇文章就教你怎麼用python寫出一個簡易的,但五髒俱全的貪吃蛇小遊戲。我保證每步不重複的步驟都有最白話的注釋,說了這麼多廢話,我們開始一步步開始吧!
首先寫貪吃蛇的基本思路:
1.安裝python的pygame子產品
2.設定遊戲視窗資訊
3.畫出小蛇、畫出蛇愛吃的食物
4.讓小蛇能跟着方向鍵随意舞動,并且在我們不變方向鍵的時候它會朝着最後一次的方向一直移動
5.蛇該死的時候還是得死的,比如“咬蛇自盡”,“撞牆示冤”而死
6.運作,然後發個pyq,文案我都幫你想好了“古有圖靈人工智能,今有新秀寫蛇玩蛇,計算機革命,非我無能,實屬無志”(忘記押韻了,sorry)
好了讓我們正式開始!(好多廢話,現在才開始)
第一步:安裝pygame首先去python的官網https://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame
選擇适合你的python版本的pygame,比如我的python是3.7的,系統是win64位的就選擇
然後把下載下傳下來的檔案放到全英文目錄下(可以直接放C槽),然後在cmd裡面進入C槽
然後輸入pip install pygame-1.9.6-cp37-cp37m-win_amd64.whl(把install後面的一串改成你自己下載下傳的檔案的名字,然後回車就開始安裝了)安裝完後,可以在python裡面輸入import pygame如果沒有報錯,那就完成了萬裡長征的第一裡了!
然後就可以在python裡面使用pygame了
注意,在使用pygame之前一定要先輸入
我個人的了解是:初始化 pygame子產品,確定pygame子產品完整可用
第二步:設定遊戲視窗資訊建立一個視窗
設定視窗的長度與寬度,視窗長度從左往右0-XXX,寬度從上往下0-XXX
設定視窗标題
彙總一下第二步
運作就會出現一個黑框啦!
先有雞還是先有蛋,先有蛇還是先有食物?這值得思考(個P)
3.1畫蛇!
先給畫布和蛇一個顔色,我喜歡Blue,就畫一個小藍蛇吧
藍色的RGB,喜歡什麼顔色可以直接百度XX色的RGB
給畫布的顔色
蛇是不是要有蛇頭和蛇身?
蛇頭坐标
蛇身坐标,初始蛇隻有三節
可以把蛇畫出來了,rect表示畫的是矩形組成的蛇,喜歡圓形可以用circle,10*10表示畫出的矩形尺寸
食物隻有一節,是以隻要有一個坐标就行,但食物要是随機産生的
彙總一下第三步:
得到了小藍蛇和食物(好刺激,如果隻要圖檔的話,已經可以發pyq了!)
不能止步!我要玩蛇!
第四步:讓蛇能跟着你的方向鍵動起來!動起來~首先我們用1234分别表示上下左右
1-上 2-下 3-左 4-右
我們以“上”為例
不要把蛇的移動想得太複雜了,剛開始我想蛇的移動是整個蛇發生了位移,就要改變所有蛇身的坐标,這也太麻煩了吧!
其實仔細想一下,蛇在移動的時候,是不是其實
隻有蛇頭和蛇尾發生了變化!當蛇往上移動的時候,新蛇頭的位置就變成了舊蛇頭上面的那一格!原有的蛇不發生變化,隻是多出來一個新的蛇頭取代了舊蛇頭(舊蛇頭變成了蛇身)
實體學家邁爾說過:能量是守恒的!
既然多出了個蛇頭,相應的蛇尾隻要删掉就完成了蛇的移動!
當然有小天才要問了“如果剛好我上移的時候吃到了食物怎麼辦?”
根據守恒,食物沒了,就得長在蛇身上,那我們前面說的蛇頭的變化還是照舊,隻是蛇尾我們不用删掉,就完成了蛇的增長了!
并且食物被吃後要産生新的食物下次接着吃!
看下代碼:
其它移動方向同理:
現在蛇各個方向移動的代碼完成了,那麼怎麼讓她和我們的方向鍵聯系起來呢?
這裡要用到pygame内置的“監聽事件資訊”
監聽所有事件資訊
擷取鍵盤按鍵資訊
同時要注意當我們想要改變小藍蛇的移動方向時,如果原來移動方向是“上”,我們就不能讓蛇往下移動,同理原左的時候不能變成向右。
同時因為小藍蛇一直在移動,是以畫布需要一直重新整理變化,需要控制一下重新整理的頻率
建立時鐘對象 (可以控制遊戲循環頻率)
第五步:同時在移動的時候不能讓蛇無所畏懼吧,該死的時候還是得死的有兩種死亡情況:
1.含冤撞牆而死
2.懷才不遇咬蛇自盡
将死亡觸發條件添加進移動函數中
彙總一下目前代碼:
看下運作結果:
知乎視訊www.zhihu.com
可以看到現在的這條蛇就不再是一條普通的蛇了!
他會向各個方向沖鋒嘗試,有時也會一個方向不轉彎,也會因為過于執拗撞牆而死,或者因為不謹慎跌入進自己挖的坑!
他現在是哲學蛇!
當然我們也可以繼續添加一些元素,讓這個貪吃蛇看起來更完整。
附加1:添加遊戲初始界面與結束界面設定遊戲開始界面包括圖像、文字等(字型包可以百度一下自己電腦的的字型都放在哪裡,我的是在C:WindowsFonts選擇一個中文字型放進與py檔同目錄下即可)
通過監聽按鍵資訊,達成按任意鍵進入遊戲的要求
其中蒂芙尼藍的RGB為:Tiffanyblue=(129,216,209)
在進入正式遊戲前加載初始界面
結束界面與初始界面設定基本相同,
将結束函數替換原先的死亡退出語句
初始界面:
結束界面:
得分情況可以在每次移動吃到食物後得分+1即可,比較簡單,然後再用于與初始結束界面相同的繪制文字的方法繪制出來即可。
每個方向都添加score = score + 1
在主程式中添加顯示成績語句(重新整理畫布前)其中Red = (255,0,0)
初始與結束界面圖檔:
最終運作結果:
知乎視訊www.zhihu.com
本人純屬python小白,當最終看到這條騷動的小藍蛇時,内心還是有點難以抑制的喜悅的,希望各位在自己嘗試後也能有所收獲!
同時貪吃蛇還有很多的元素可以添加,比如設定不同按鈕選擇進入“無敵模式”或者現在的會死亡的模式,結束時不直接退出,而是可以選擇重新開始等,期待大家的進一步完善!
代碼的備援度,規範性等還有很大的問題,但确實已經用心啦,能力所限,還望各位包涵包涵,也期待各位對其中代碼的改進,與對錯誤的批評指正。
我在夢中聽見圖靈說過“貪吃蛇都寫出來了,LOL、魔獸等還會遠嗎?”
附上完整程式代碼:
import pygame #載入pygame子產品
import random #載入random子產品
pygame.init() #初始化 pygame子產品,確定pygame子產品完整可用
#設定遊戲視窗的基本資訊
length = 600 #視窗長度
width = 600 #視窗寬度
score = 0 #初始成績
window = pygame.display.set_mode((length,width)) #設定視窗的長度與寬度
pygame.display.set_caption('我想玩一下蛇') #設定視窗标題
blue=(0,0,255) #藍色RGB
black=(0,0,0) #黑色RGB
Tiffanyblue=(129,216,209) #蒂芙尼藍的RGB
Red=(255,0,0) #紅色RGB
#給出蛇的坐标
head=[300,300]#蛇頭的坐标
snake=[[300,300], [290,300], [280,300]]#蛇身體的三個矩形的坐标
#随機給出食物的坐标
food_rd=[random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
#遊戲開始與遊戲結束界面
#設定遊戲開始界面
def start(window):
font = pygame.font.Font('simhei.ttf', 30) #設定字型與字号
prompt = font.render('按任意鍵開始玩蛇,按ESC可退出', 1 , Tiffanyblue) #設定文本内容和字型顔色
startimage = pygame.image.load('start.jpg') #加載圖像
window.blit(prompt, (90, 400)) #繪制出字型
window.blit(startimage, (55, 50)) #繪制出加載的圖像
pygame.display.update() #重新整理
while True: #進行按鍵監聽
for event in pygame.event.get(): #擷取所有事件資訊
if event.type == pygame.QUIT: #如果使用者滑鼠點選了視窗的X
pygame.quit() #終止程式
exit() #終止程式
elif event.type == pygame.KEYDOWN:#擷取鍵盤按鍵資訊
if event.key == pygame.K_ESCAPE: #終止程式
pygame.quit() #終止程式
else:
return 0 #結束初始界面,開始玩蛇
#設定遊戲結束界面
def over(window):
font = pygame.font.Font('simhei.ttf', 25)
prompt = font.render('蛇都不會玩???自己按ESC或者點X退出吧', 1 , Tiffanyblue)
startimage = pygame.image.load('over.jpg')
window.blit(prompt, (70, 400))
window.blit(startimage, (50, 50))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
exit()
#貪吃蛇死亡的兩種情況
#含冤撞牆而死
def hit_wall(head):
if head[0] >= length or head[0]<0 or head[1] >= width or head[1] < 0: #如果蛇頭坐标超出四周的界線
return 1 #撞牆發生
else:
return 0
#因懷才不遇咬蛇自盡
def hit_snake():
if snake[0] in snake[1:]: #如果蛇頭坐标與身體中坐标重合
return 1 #咬蛇自盡發生
else:
return 0
#控制蛇的移動
def movesnake (direction):
global food_rd #聲明全局變量(在函數中有指派時使用)
global score
if direction == 1: #如果移動方向為上
head[1] = head[1] - 10 #Y軸坐标-10
snake.insert(0, list(head)) #插入新的頭部坐标
if head != food_rd: #如果沒有吃到食物
snake.pop(-1) #删去最後一個元素
else: #頭部坐标等于食物坐标時即吃到食物,不删除末尾元素即完成增長
score = score + 1
food_rd = [random.randrange(1, 50) * 10, random.randrange(1, 50) * 10] #食物被吃後随機産生新食物
elif direction == 2:
head[1] = head[1] + 10
snake.insert(0, list(head))
if head != food_rd:
snake.pop(-1)
else:
score = score + 1
food_rd = [random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
elif direction == 3:
head[0] = head[0] - 10
snake.insert(0, list(head))
if head != food_rd:
snake.pop(-1)
else:
score = score + 1
food_rd = [random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
elif direction == 4:
head[0] = head[0] + 10
snake.insert(0, list(head))
if head != food_rd:
snake.pop(-1)
else:
score = score + 1
food_rd = [random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
#蛇在移動中該死的時候還是要死的
if hit_snake() or hit_wall(head): #如果蛇撞到自身或者撞到牆
over(window) #進入結束界面
speed = pygame.time.Clock() #建立時鐘對象 (可以控制遊戲循環頻率)
direction = 4 #初始化移動方向為右
start(window) #進入初始界面
#主程式
while True:
for event in pygame.event.get():#擷取所有事件資訊
if event.type == pygame.QUIT: #如果使用者滑鼠點選了視窗的X
pygame.quit() #終止pygame程式
exit() #終止所有程式
if event.type == pygame.KEYDOWN: #擷取鍵盤按鍵資訊
if event.key == pygame.K_ESCAPE: #如果按鍵ESC
pygame.quit()
exit()
if direction != 2 and event.key == pygame.K_UP: #如果原始方向不是下,并且現在按鍵為上
direction = 1 #方向改變為上
elif direction != 1 and event.key == pygame.K_DOWN:
direction = 2
elif direction != 4 and event.key == pygame.K_LEFT:
direction = 3
elif direction != 3 and event.key == pygame.K_RIGHT:
direction = 4
movesnake(direction) #根據按鍵方向移動蛇
window.fill(black) #給視窗繪制黑色的畫布
pygame.draw.rect(window,blue,pygame.Rect(food_rd[0],food_rd[1],10,10)) #畫出食物
#畫出小藍蛇
for i in snake:
pygame.draw.rect(window, blue, pygame.Rect(i[0], i[1], 10, 10))
#顯示成績
font = pygame.font.Font('simhei.ttf', 25)
score_show = font.render('得分: %s' % score, 1 , Red) #格式化輸出得分資訊
window.blit(score_show, (500, 20))
pygame.display.update() #重新整理界面
speed.tick(10) #FPS(數值越大蛇移動的速度越快)