python 贪吃蛇_python简易贪吃蛇
python簡易貪吃蛇
前言
開始
獻上代碼
from tkinter.messagebox import showinfo as msg
from random import randint as rand
from pygame.locals import *
import tkinter as tk
import pygame
import time
win = tk.Tk()
win.withdraw()
pygame.init()
def render(surf,blocks):
for x,y in blocks.keys():
renderingf = (x * 40,y * 40)
color = blocks[(x,y)]
pygame.draw.rect(surf,color,Rect(renderingf,(40,40)))
def render_snake(surf,pos):
def unique(pos):
for i in pos:
if(pos.count(i) > 1):
return False
return True
if(not unique(pos)):
return False
d = {}
for i in pos:
d[tuple(i)] = (255,255,255)
d[pos[-1]] = (0,0,255)
render(surf,d)
return True
def main(size):
scr = pygame.display.set_mode((40 * size[0],40 * size[1]))
stop = False
l = 3
pos = [(0,0),(1,0),(2,0)]
last = 'd'
dir = {'w':(0,-1),'s':(0,1),'a':(-1,0),'d':(1,0)}
oppsite = {'w':'s','s':'w','a':'d','d':'a'}
food = (rand(0,size[0] - 1),rand(0,size[1] - 1))
n = 1
speed = 30
while(1):
if((food in pos) and (not stop)):
l += 1
food = (rand(0,size[0] - 1),rand(0,size[1] - 1))
if(l == size[0] * size[1]):
return l
if(pos[-1][0] < 0 or pos[-1][1] < 0 or pos[-1][0] >= size[0] or pos[-1][1] >= size[1]):
return l
pygame.display.update()
speed = 30 - int(l / (1 - 3 / (size[0] * size[1])))
n += 1
n %= speed
pos = pos[-l:]
if((not n) and (not stop)):
t = (pos[-1][0] + dir[last][0],pos[-1][1] + dir[last][1])
pos.append(t)
scr.fill((0,0,0))
for ev in pygame.event.get():
if(ev.type == QUIT):
exit()
elif(ev.type == KEYDOWN and ev.unicode in 'aAwWsSdD' and ev.unicode):
if(ev.unicode == oppsite[last]):
return l
t = (pos[-1][0] + dir[ev.unicode.lower()][0],
pos[-1][1] + dir[ev.unicode.lower()][1])
pos.append(t)
last = str(ev.unicode.lower())
elif(ev.type == MOUSEBUTTONDOWN):
stop = not stop
elif(ev.type == KEYDOWN and ev.key == K_ESCAPE and stop):
return l
if(stop):
img = pygame.image.load('pause.jpg')
img = pygame.transform.scale(img,(40 * size[0],40 * size[1]))
scr.blit(img,(0,0))
else:
render(scr,{food:(0,255,0)})
if(not render_snake(scr,pos)):
return l
if(__name__ == '__main__'):
size = [15,15]
while(1):
l = main(size)
msg("GAMEOVER!","GAMEOVER! score:%s"%l)
代碼剖析
from tkinter.messagebox import showinfo as msg
from random import randint as rand
from pygame.locals import *
import tkinter as tk
import pygame
import time
win = tk.Tk()
win.withdraw()
pygame.init()
導入庫并初始化
注意??:tkinter一定要在pygame之前初始化
def render(surf,blocks):
for x,y in blocks.keys():
renderingf = (x * 40,y * 40)
color = blocks[(x,y)]
pygame.draw.rect(surf,color,Rect(renderingf,(40,40)))
渲染格子,surf是要渲染的Surface對象,blocks是要渲染的位置和顏色
def render_snake(surf,pos):
def unique(pos):
for i in pos:
if(pos.count(i) > 1):
return False
return True
if(not unique(pos)):
return False
d = {}
for i in pos:
d[tuple(i)] = (255,255,255)
d[pos[-1]] = (0,0,255)
render(surf,d)
return True
渲染蛇,即為render(點擊跳轉)的包裝。surf為要渲染的Surface對象,pos是蛇身子的每個格子的坐標列表。其中unique為蛇是否碰到自己的檢測,其思路是,如果pos中有重復的,蛇就否碰到自己,所以,unique就是檢測數組中是否有重復數據的
def main(size):
scr = pygame.display.set_mode((40 * size[0],40 * size[1]))
stop = False
l = 3
pos = [(0,0),(1,0),(2,0)]
last = 'd'
dir = {'w':(0,-1),'s':(0,1),'a':(-1,0),'d':(1,0)}
oppsite = {'w':'s','s':'w','a':'d','d':'a'}
food = (rand(0,size[0] - 1),rand(0,size[1] - 1))
n = 1
speed = 30
while(1):
if((food in pos) and (not stop)):
l += 1
food = (rand(0,size[0] - 1),rand(0,size[1] - 1))
if(l == size[0] * size[1]):
return l
if(pos[-1][0] < 0 or pos[-1][1] < 0 or pos[-1][0] >= size[0] or pos[-1][1] >= size[1]):
return l
pygame.display.update()
speed = 30 - int(l / (1 - 3 / (size[0] * size[1])))
n += 1
n %= speed
pos = pos[-l:]
if((not n) and (not stop)):
t = (pos[-1][0] + dir[last][0],pos[-1][1] + dir[last][1])
pos.append(t)
scr.fill((0,0,0))
for ev in pygame.event.get():
if(ev.type == QUIT):
exit()
elif(ev.type == KEYDOWN and ev.unicode in 'aAwWsSdD' and ev.unicode):
if(ev.unicode == oppsite[last]):
return l
t = (pos[-1][0] + dir[ev.unicode.lower()][0],
pos[-1][1] + dir[ev.unicode.lower()][1])
pos.append(t)
last = str(ev.unicode.lower())
elif(ev.type == MOUSEBUTTONDOWN):
stop = not stop
elif(ev.type == KEYDOWN and ev.key == K_ESCAPE and stop):
return l
if(stop):
img = pygame.image.load('pause.jpg')
img = pygame.transform.scale(img,(40 * size[0],40 * size[1]))
scr.blit(img,(0,0))
else:
render(scr,{food:(0,255,0)})
if(not render_snake(scr,pos)):
return l
這里分開分析
def main(size):
scr = pygame.display.set_mode((40 * size[0],40 * size[1]))
stop = False
l = 3
pos = [(0,0),(1,0),(2,0)]
last = 'd'
dir = {'w':(0,-1),'s':(0,1),'a':(-1,0),'d':(1,0)}
oppsite = {'w':'s','s':'w','a':'d','d':'a'}
food = (rand(0,size[0] - 1),rand(0,size[1] - 1))
n = 1
speed = 30
創建窗口,初始化是否暫停,蛇長,身體個塊坐標,最后一個操作,方向與偏移量的關系字典,相反動作字典,食物位置,輪回數,速度(住:這里speed越大,速度越慢,請記住這件事情,后面會用到)
while(1):
if((food in pos) and (not stop)):
l += 1
food = (rand(0,size[0] - 1),rand(0,size[1] - 1))
if(l == size[0] * size[1]):
return l
if(pos[-1][0] < 0 or pos[-1][1] < 0 or pos[-1][0] >= size[0] or pos[-1][1] >= size[1]):
return l
進入游戲循環,處理吃到食物,蛇占滿格子的問題
pygame.display.update()
speed = 30 - int(l / (1 - 3 / (size[0] * size[1])))
n += 1
n %= speed
pos = pos[-l:]
if((not n) and (not stop)):
t = (pos[-1][0] + dir[last][0],pos[-1][1] + dir[last][1])
pos.append(t)
scr.fill((0,0,0))
刷新窗口,清屏,這里中間的代碼的作用向↓
\downarrow↓看
speed = 30 - int(l / (1 - 3 / (size[0] * size[1])))
n += 1
n %= speed
pos = pos[-l:]
if((not n) and (not stop)):
t = (pos[-1][0] + dir[last][0],pos[-1][1] + dir[last][1])
pos.append(t)
scr.fill((0,0,0))
第一行更新速度,這里公式是由速
度
=
蛇
長
÷
[
(
最
長
長
度
?
初
始
長
度
)
÷
最
長
長
度
]
速度=蛇長 \p [(最長長度 - 初始長度) \p 最長長度]速度=蛇長÷[(最長長度?初始長度)÷最長長度],將(
最
長
長
度
?
初
始
長
度
)
÷
最
長
長
度
(最長長度 - 初始長度) \p 最長長度(最長長度?初始長度)÷最長長度改成最
長
長
度
÷
最
長
長
度
?
初
始
長
度
÷
最
長
長
度
最長長度 \p 最長長度 - 初始長度 \p 最長長度最長長度÷最長長度?初始長度÷最長長度也就是1
?
3
/
(
s
i
z
e
[
0
]
?
s
i
z
e
[
1
]
)
1 - 3 / (size[0] * size[1])1?3/(size[0]?size[1]),整理一下,變成s
p
e
e
d
=
l
÷
[
1
?
3
/
(
s
i
z
e
[
0
]
?
s
i
z
e
[
1
]
)
]
speed=l \p [1 - 3 / (size[0] * size[1])]speed=l÷[1?3/(size[0]?size[1])],由于速度是整數,所以去一下整。
再往后就要解釋一下為什么speed越大,速度越快了,因為speed指的就是經過speed個輪回之后蛇就自動挪一下,那么換句話說,speed 越大,不挪的輪回數就越多,挪動的時間間隔就越長
所以每次n
=
n
+
1
n = n + 1n=n+1就指的是又輪回了一次(因為n
nn這的就是輪回數),如果n
=
s
p
e
e
d
n = speedn=speed了,那么n
%
s
p
e
e
d
n~\%~speedn%speed就等于0,于是每次經過n
=
(
n
+
1
)
%
s
p
e
e
d
n = (n + 1)~\%~speedn=(n+1)%speed之后如果n
=
0
n = 0n=0,就代表改挪一下了。
for ev in pygame.event.get():
if(ev.type == QUIT):
exit()
elif(ev.type == KEYDOWN and ev.unicode in 'aAwWsSdD' and ev.unicode):
if(ev.unicode == oppsite[last]):
return l
t = (pos[-1][0] + dir[ev.unicode.lower()][0],
pos[-1][1] + dir[ev.unicode.lower()][1])
pos.append(t)
last = str(ev.unicode.lower())
elif(ev.type == MOUSEBUTTONDOWN):
stop = not stop
elif(ev.type == KEYDOWN and ev.key == K_ESCAPE and stop):
return l
處理事件
點x就退出
點awsd就按照方向移動
點擊鼠標暫停或繼續
暫停時點ESC就再來一局
if(stop):
img = pygame.image.load('pause.jpg')
img = pygame.transform.scale(img,(40 * size[0],40 * size[1]))
scr.blit(img,(0,0))
else:
render(scr,{food:(0,255,0)})
if(not render_snake(scr,pos)):
return l
如果是沒有在玩(暫停),那么將圖片與窗口調成同樣大小后顯示,顯示的圖片向↓
\downarrow↓看
不難看出就是暫停繼續的圖案
如果在玩(沒暫停),那么調用render_snake(點擊跳轉)渲染蛇,如果返回False,也就是撞自己上了,游戲結束。
if(__name__ == '__main__'):
size = [15,15]
while(1):
l = main(size)
msg("GAMEOVER!","GAMEOVER! score:%s"%l)
運行游戲,size中的兩個值表明區域大小,可自行更改(推薦≤
15
\le15≤15)。
項目github
作者
hit-road
拜拜,下課!
回到頂部
總結
以上是生活随笔為你收集整理的python 贪吃蛇_python简易贪吃蛇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源Webshell利用工具——Altm
- 下一篇: 造车新势力“蔚小理”变弱了?不,他们已走