怎樣從零開始用 Python 寫一個貪吃蛇?
PS: 感覺好像被當成伸手黨了 ,題主我一開始也是有個想法的,只是感覺運行效率太渣,來學習學習各位的方法。
還有現在忙著高考,也沒多少時間實踐這個貪吃蛇程序了。 但還是感謝各位提出的思路。==--------以下為原問題--------==首先說明「從零開始」不是指零基礎
首先說明「從零開始」不是指零基礎首先說明「從零開始」不是指零基礎是指從頭寫起。1. 使用現有模塊的話有什麼模塊推薦?2. 不使用現有模塊的話怎麼自己從底層開始寫?需要具備哪些知識?
大一,標準庫,沒有用到pygame。 代碼很醜,見諒。
# -*- coding:utf-8 -*-
# __author__ = "wj"
from Tkinter import *
import random
from time import *
import thread
import sys
sys.setrecursionlimit(sys.maxint)
def callback1(): # difficulty
global diff
diff = difficulty(0)
def callback11(): # difficulty
global diff
diff = difficulty(1)
def callback12(): # difficulty
global diff
diff = difficulty(2)
def callback2(): # start
start()
def callback3(): # exit
root.destroy()
def callback4(event): # up
m.append(0)
def callback5(event): # down
m.append(1)
def callback6(event): # left
m.append(2)
def callback7(event): # right
m.append(3)
def difficulty(x=2):
if x == 0:
return 0.5
if x == 1:
return 0.3
if x == 2:
return 0.1
def createfood():
x = random.randint(0, 39)
y = random.randint(0, 29)
return (x, y)
def pan(now):
for i in range(len(l)):
if lx[i] == now[0] * 20 and ly[i] == now[1] * 20:
return False
def food():
now = createfood()
while pan(now):
now = createfood()
r = f.create_rectangle(now[0] * 20, now[1] * 20, now[0] * 20 + 20, now[1] * 20 + 20, fill="red")
f.update()
z.append(r)
lxf.append(now[0] * 20)
lyf.append(now[1] * 20)
def gameover():
if lx[-1] &> 780 or lx[-1] &< 0 or ly[-1] &> 580 or ly[-1] &< 0:
try:
f.create_text(400, 250, text="Game Over", font=("Fixdsys", 40), fill="red", justify=CENTER)
f.create_text(400, 330, text="Ur Score : " + str(len(l) - 3), font=("Fixdsys", 40), fill="blue", justify=CENTER)
f.create_text(400, 400, text="please click exit", fill="black",font=("Fixdsys", 20))
except:
print "Game Over"
f.create_text(400,400,text="please click exit",fill="black",font=("Fixdsys", 20))
sleep(100)
for i in range(len(l) - 1):
if lx[i] == lx[-1] and ly[i] == ly[-1]:
try:
f.create_text(400, 250, text="Game Over", font=("Fixdsys", 40), fill="red", justify=CENTER)
f.create_text(400, 330, text="Ur Score : " + str(len(l) - 3), font=("Fixdsys", 40), fill="blue",justify=CENTER)
f.create_text(400, 400, text="please click exit", fill="black",font=("Fixdsys", 20))
except:
print "Game Over"
f.create_text(400, 400, text="please click exit", fill="black",font=("Fixdsys", 20))
sleep(100)
#控制移動函數
def move():
if m[-1] == 0:
up_move1()
m.pop(0)
elif m[-1] == 1:
down_move1()
m.pop(0)
elif m[-1] == 2:
left_move1()
m.pop(0)
elif m[-1] == 3:
right_move1()
m.pop(0)
def crash():
for i in range(len(l) - 1):
if lx[i] == lx[-1] and ly[i] == ly[-1]:
return True
#自動移動
def up_move():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
else:
r = f.create_rectangle(lx[-1], ly[-1] - 20, lx[-1] + 20, ly[-1], fill="white")
l.append(r)
lx.append(lx[-1])
ly.append(ly[-1] - 20)
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
if len(m) != 0:
thread.start_new_thread(move, ())
sleep(diff)
move_straight()
#自動移動
def down_move():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
else:
r = f.create_rectangle(lx[-1], ly[-1] + 20, lx[-1] + 20, ly[-1] + 40, fill="white")
f.update()
l.append(r)
lx.append(lx[-1])
ly.append(ly[-1] + 20)
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
if len(m) != 0:
thread.start_new_thread(move, ())
sleep(diff)
move_straight()
#自動移動
def left_move():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
else:
r = f.create_rectangle(lx[-1] - 20, ly[-1], lx[-1], ly[-1] + 20, fill="white")
f.update()
l.append(r)
lx.append(lx[-1] - 20)
ly.append(ly[-1])
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
if len(m) != 0:
thread.start_new_thread(move, ())
sleep(diff)
move_straight()
#自動移動
def right_move():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
else:
r = f.create_rectangle(lx[-1] + 20, ly[-1], lx[-1] + 40, ly[-1] + 20, fill="white")
l.append(r)
lx.append(lx[-1] + 20)
ly.append(ly[-1])
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
f.update()
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
if len(m) != 0:
thread.start_new_thread(move, ())
sleep(diff)
move_straight()
#自動移動
def move_straight(): # 坐標比較 然後調用四個方向移動的函數
if lx[-1] == lx[-2] and ly[-1] &> ly[-2]:
down_move()
if lx[-1] == lx[-2] and ly[-1] &< ly[-2]:
up_move()
if lx[-1] &> lx[-2] and ly[-1] == ly[-2]:
right_move()
if lx[-1] &< lx[-2] and ly[-1] == ly[-2]:
left_move()
#控制移動函數
def up_move1():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
r = f.create_rectangle(lx[-1], ly[-1] - 20, lx[-1] + 20, ly[-1], fill="white")
l.append(r)
lx.append(lx[-1])
ly.append(ly[-1] - 20)
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
#控制移動函數
def down_move1():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
else:
r = f.create_rectangle(lx[-1], ly[-1] + 20, lx[-1] + 20, ly[-1] + 40, fill="white")
f.update()
l.append(r)
lx.append(lx[-1])
ly.append(ly[-1] + 20)
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
#控制移動函數
def left_move1():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
else:
r = f.create_rectangle(lx[-1] - 20, ly[-1], lx[-1], ly[-1] + 20, fill="white")
f.update()
l.append(r)
lx.append(lx[-1] - 20)
ly.append(ly[-1])
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
#控制移動函數
def right_move1():
if lx[-1] &< 0 or lx[-1]&>780 or ly[-1]&<0 or ly[-1]&>580:
pass
elif crash():
pass
else:
r = f.create_rectangle(lx[-1] + 20, ly[-1], lx[-1] + 20 + 20, ly[-1] + 20, fill="white")
l.append(r)
lx.append(lx[-1] + 20)
ly.append(ly[-1])
gameover()
if lx[-1] != lxf[-1] or ly[-1] != lyf[-1]: # 沒碰到
f.delete(l[0])
f.update()
l.pop(0)
lx.pop(0)
ly.pop(0)
else: # 碰到了
f.delete(z[-1])
food()
f.update()
def start():
global r1
global r2
l.append(r1)
l.append(r2)
lx.append(0)
lx.append(20)
ly.append(0)
ly.append(0)
food()
move_straight()
root = Tk()
root.title("snake")
root.geometry("800x600")
m = Menu(root)
root.config(menu=m)
m.add_command(label="Start", command=callback2)
difmenu = Menu(m)
m.add_cascade(label="Difficulty", menu=difmenu)
difmenu.add_command(label="Easy", command=callback1)
difmenu.add_separator()
difmenu.add_command(label="Normal", command=callback11)
difmenu.add_separator()
difmenu.add_command(label="Difficult", command=callback12)
paumenu = Menu(m)
m.add_cascade(label="Pause", menu=paumenu)
m.add_command(label="Exit", command=callback3)
f = Canvas(root, width=800, height=600, bg="white")
f.bind("&
f.bind("&
f.bind("&
f.bind("&
f.focus_set()
f.pack()
#這裡需要一張底色不為白色、gif格式的圖片,可以自行調整(我劃的線是白色)
#pic = PhotoImage(file="C:UserswjDesktop\snake.gif")
#f.create_image(400, 300, image=pic)
for i in range(20 - 1, 600 - 1, 20):
f.create_line(0, i, 800, i, smooth=0, fill="white")
for i in range(20 - 1, 800 - 1, 20):
f.create_line(i, 0, i, 600, smooth=0, fill="white")
l = []
lx = []
ly = []
lxf = []
lyf = []
z = []
m = []
r1 = f.create_rectangle(0, 0, 20, 20, fill="white")
r2 = f.create_rectangle(20, 0, 40, 20, fill="white")
diff = difficulty()
root.mainloop()
pygame
100來行就可以了源碼:
codetimer/Snake一、前言看了提問者在另一個回答的評論
真的覺得提問者應該試試pygame。「工欲善其事,必先利其器。」個人認為,python與其他編程語言相比,亮點在於它有豐富的第三方庫。比如用python做爬蟲,原生庫urllib2和第三方庫requests相比,哪個效率更高?
- pygame遊戲編程(1)--pygame簡介及安裝
- pygame遊戲編程(2)--第一個pygame程序
- pygame遊戲編程(3)--文本列印及字體
- pygame遊戲編程(4)--像素、顏色和圖像
- pygame遊戲編程(5)--surface對象
- pygame遊戲編程(6)--窗口顯示
- pygame遊戲編程(7)--繪製幾何圖像
- pygame遊戲編程(8)--event事件
- pygame遊戲編程(9)--動畫之直線運動
- pygame遊戲編程(10)--動畫之向量
- pygame遊戲編程(11)--人機交互
- pygame遊戲編程(12)--人工智慧
- pygame遊戲編程(13)--聲音
- pygame遊戲編程(14)--音樂播放器
- pygame遊戲編程(15)--貪吃蛇遊戲
沒錯,博客作者提供了如何使用pygame開發貪吃蛇的教程,詳見pygame遊戲編程(16)--貪吃蛇遊戲-pygame教程-Daydayblog,作者程序運行界面如下:
貪吃蛇主要包括以下幾個方面:
- 物體表示:蛇和蘋果如何存儲和顯示、蛇如何移動和吃蘋果變長;
- 字體顯示:提示玩家該如何操作,顯示玩家的分數;
- 人機交互:使用鍵盤的方向鍵來控制蛇的移動;
- 矩形繪圖:繪製各種基本的圖形來組成圖像。
- pygame簡介及安裝
- surface對象
- 窗口顯示
- 繪製幾何圖形
- event事件
- 人機交互
pygame開發2D遊戲簡直不能太簡單,我粗略看了教程之後,就自主完成兩個遊戲開發:
1、貪吃蛇 附上本人貪吃蛇遊戲代碼(很多細節沒處理好,勿噴。)#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys,pygame,random
from pygame.locals import *
windowWidth=600
windowHeight=600
cellSize=20
head = 0
def main():
#初始化
pygame.init()
global screen
screen=pygame.display.set_mode((windowWidth,windowHeight))
pygame.display.set_caption("Greedy Snake")
gameStart()
FPS=pygame.time.Clock()
startX=cellSize*random.randint(8,windowWidth/cellSize-8)
startY=cellSize*random.randint(8,windowHeight/cellSize-8)
snake=[{"x": startX , "y": startY},
{"x": startX - 1 * cellSize, "y": startY},
{"x": startX - 2 * cellSize, "y": startY},
{"x": startX - 3 * cellSize, "y": startY}]
appleX = cellSize * random.randint(0, windowWidth / cellSize)
appleY = cellSize * random.randint(0, windowHeight / cellSize)
while True:
FPS.tick(15)
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
turn(snake,event)
move(snake)
if snake[head]["x"]==appleX and snake[head]["y"]==appleY:
appleX = cellSize * random.randint(0, windowWidth / cellSize)
appleY = cellSize * random.randint(0, windowHeight / cellSize)
eat(snake)
if snake[head]["x"]&<0 or snake[head]["x"]&>windowWidth or snake[head]["y"]&<0 or snake[head]["y"]&>windowHeight:
gameOver(snake)
for body in snake[1:]:
if body==snake[head]:
gameOver(snake)
screen.fill((0, 150, 0))
drawgrid()
drawSnake(snake)
pygame.draw.rect(screen, (255, 0, 0), (appleX, appleY, cellSize, cellSize))
pygame.display.update()
#繪製網格
def drawgrid():
for i in xrange(cellSize,windowWidth,cellSize):
pygame.draw.line(screen,(0,255,0),(i,0),(i,windowHeight),1)
for j in xrange(cellSize,windowHeight,cellSize):
pygame.draw.line(screen,(0,255,0),(0,j),(windowWidth,j),1)
#繪製蛇
def drawSnake(snake):
for cood in snake:
pygame.draw.rect(screen,(150,150,0),(cood["x"],cood["y"],cellSize,cellSize))
pygame.draw.rect(screen, (250, 250, 0), (snake[head]["x"], snake[head]["y"], cellSize, cellSize))
def turn(snake,event):
# 上下轉向
if snake[head]["y"] == snake[1]["y"]:
if event.key == K_UP:
del snake[-1]
newHead = {"x": snake[head]["x"], "y": snake[head]["y"] - cellSize}
snake.insert(0, newHead)
elif event.key == K_DOWN:
del snake[-1]
newHead = {"x": snake[head]["x"], "y": snake[head]["y"] + cellSize}
snake.insert(0, newHead)
# 左右轉向
if snake[head]["x"] == snake[1]["x"]:
if event.key == K_LEFT:
del snake[-1]
newHead = {"x": snake[head]["x"] - cellSize, "y": snake[head]["y"]}
snake.insert(0, newHead)
if event.key == K_RIGHT:
del snake[-1]
newHead = {"x": snake[head]["x"] + cellSize, "y": snake[head]["y"]}
snake.insert(0, newHead)
def move(snake):
# 向左運動
if snake[head]["x"] &< snake[1]["x"]:
del snake[-1]
newHead = {"x": snake[head]["x"] - cellSize, "y": snake[head]["y"]}
snake.insert(0, newHead)
# 向右運動
elif snake[head]["x"] &> snake[1]["x"]:
del snake[-1]
newHead = {"x": snake[head]["x"] + cellSize, "y": snake[head]["y"]}
snake.insert(0, newHead)
# 向上運動
elif snake[head]["y"] &< snake[1]["y"]:
del snake[-1]
newHead = {"x": snake[head]["x"], "y": snake[head]["y"] - cellSize}
snake.insert(0, newHead)
# 向下運動
elif snake[head]["y"] &> snake[1]["y"]:
del snake[-1]
newHead = {"x": snake[head]["x"], "y": snake[head]["y"] + cellSize}
snake.insert(0, newHead)
def eat(snake):
# 向左運動
if snake[head]["x"] &< snake[1]["x"]:
newHead = {"x": snake[head]["x"] - cellSize, "y": snake[head]["y"]}
snake.insert(0, newHead)
# 向右運動
elif snake[head]["x"] &> snake[1]["x"]:
newHead = {"x": snake[head]["x"] + cellSize, "y": snake[head]["y"]}
snake.insert(0, newHead)
# 向上運動
elif snake[head]["y"] &< snake[1]["y"]:
newHead = {"x": snake[head]["x"], "y": snake[head]["y"] - cellSize}
snake.insert(0, newHead)
# 向下運動
elif snake[head]["y"] &> snake[1]["y"]:
newHead = {"x": snake[head]["x"], "y": snake[head]["y"] + cellSize}
snake.insert(0, newHead)
def gameStart():
screen.fill((0, 150, 0))
drawgrid()
fontObj1 = pygame.font.Font("freesansbold.ttf", 60)
textSurfaceObj1 = fontObj1.render("Greedy Snake", True, (255,255,255))
textRectObj1 = textSurfaceObj1.get_rect()
textRectObj1.center = (windowWidth/2, windowHeight/3)
screen.blit(textSurfaceObj1,textRectObj1)
fontObj2 =pygame.font.Font("freesansbold.ttf", 30)
textSurfaceObj2 = fontObj2.render("Devloper: JIE ", True,(0, 0, 0))
textRectObj2 = textSurfaceObj2.get_rect()
textRectObj2.center = (windowWidth/2, windowHeight*2/3)
screen.blit(textSurfaceObj2,textRectObj2)
pygame.display.update()
flag=True
while(flag):
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_SPACE:
flag=False
def gameOver(snake):
screen.fill((0, 150, 0))
drawgrid()
fontObj = pygame.font.Font("freesansbold.ttf", 60)
textSurfaceObj1 = fontObj.render("Game over!", True, (255,0,0))
textRectObj1 = textSurfaceObj1.get_rect()
textRectObj1.center = (windowWidth/3, windowHeight/3)
screen.blit(textSurfaceObj1,textRectObj1)
textSurfaceObj2 = fontObj.render("Score: %s" % (len(snake)-4), True, (255, 0, 0))
textRectObj2 = textSurfaceObj2.get_rect()
textRectObj2.center = (windowWidth*2/3, windowHeight*2/3)
screen.blit(textSurfaceObj2,textRectObj2)
pygame.display.update()
while(True):
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
附上本人打飛機遊戲代碼(很多細節沒處理好,勿噴。)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys,pygame,random
from pygame.locals import *
windowWidth=420
windowHeight=600
cellSize=20
shots=[]#飛行的子彈
enemys=[]#飛行的敵機
def main():
#初始化
global shoted
shoted= 0
global enemyed
enemyed = 0
pygame.init()
pygame.key.set_repeat(10) #重複響應一個按鍵
global screen,guard
screen=pygame.display.set_mode((windowWidth,windowHeight))
pygame.display.set_caption("aircraft")
gamestart()
FPS=pygame.time.Clock()
guard=[{"x":windowWidth/2-cellSize/2,"y":windowHeight-cellSize},#中0
{"x":windowWidth/2-cellSize/2,"y":windowHeight-2*cellSize},#上1
{"x": windowWidth / 2-cellSize*3/2, "y": windowHeight - cellSize},#左2
{"x": windowWidth / 2+cellSize/2, "y": windowHeight - cellSize}]#右3
while True:
screen.fill((0, 0, 0))
FPS.tick(5)
gamemedium()
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
#飛機左移
if event.key==K_LEFT and guard[2]["x"]&>-1:
for body in guard:
body["x"]-=cellSize
#飛機右移
if event.key == K_RIGHT and guard[3]["x"] &< windowWidth:
for body in guard:
body["x"] += cellSize
#發射子彈
if event.key==K_UP:
shoted+=1
shot={"x":guard[1]["x"],"y":guard[1]["y"]}
shots.insert(0,shot)
#子彈飛行
if shots != [] :
for s in shots:
s["y"]-=2*cellSize
flag=True
while(flag and shots!=[]):
flag=False
if shots[-1]["y"]&<0:
del shots[-1]
flag=True
#產生敵機
if random.randint(0,1)==0:
newenemy={"x":cellSize*random.randint(0,windowWidth/cellSize-1),"y":0}
enemys.insert(0,newenemy)
if enemys!=[]:
for enemy in enemys:
enemy["y"] += 0.5*cellSize #敵機飛行速度
drawenemys()
delshots=[]
delenemys=[]
for i in xrange(len(shots)):
for j in xrange(len(enemys)):
if len(shots) != [] and len(enemys) != []:
if shots[i]["x"]==enemys[j]["x"] and shots[i]["y"]&
gameover()
drawshots()
#drawgrid()
drawguard()
pygame.display.update()
#繪製網格
def drawgrid():
for i in xrange(cellSize,windowWidth,cellSize):
pygame.draw.line(screen,(255,255,255),(i,0),(i,windowHeight),1)
for j in xrange(cellSize,windowHeight,cellSize):
pygame.draw.line(screen,(255,255,255),(0,j),(windowWidth,j),1)
#繪製自己的戰機
def drawguard():
for body in guard:
pygame.draw.rect(screen, (255, 255, 255), (body["x"], body["y"], cellSize, cellSize))
#繪製子彈
def drawshots():
for s in shots:
pygame.draw.rect(screen, (255, 255, 255), (s["x"]+cellSize/3, s["y"]+cellSize/4, cellSize / 3, cellSize/2))
#繪製敵機
def drawenemys():
for e in enemys:
pygame.draw.rect(screen, (255, 255, 255), (e["x"], e["y"], cellSize, cellSize/2))
pygame.draw.rect(screen, (255, 255, 255), (e["x"]+cellSize/4, e["y"]+cellSize/2, cellSize/2, cellSize / 2))
#遊戲開始界面
def gamestart():
#drawgrid()
fontObj1 = pygame.font.Font("freesansbold.ttf", 60)
textSurfaceObj1 = fontObj1.render("Aircraft", True, (255,255,255))
textRectObj1 = textSurfaceObj1.get_rect()
textRectObj1.center = (windowWidth/2, windowHeight/3)
screen.blit(textSurfaceObj1,textRectObj1)
fontObj2 =pygame.font.Font("freesansbold.ttf", 30)
textSurfaceObj2 = fontObj2.render("Developer : JIE", True,(255, 255, 255))
textRectObj2 = textSurfaceObj2.get_rect()
textRectObj2.center = (windowWidth/2, windowHeight*2/3)
screen.blit(textSurfaceObj2,textRectObj2)
pygame.display.update()
flag=True
while(flag):
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_SPACE:
flag=False
#遊戲顯示界面
def gamemedium():
fontObj1 = pygame.font.Font("freesansbold.ttf", 20)
textSurfaceObj1 = fontObj1.render("enemy: %d"%enemyed , True, (255, 255, 0))
textRectObj1 = textSurfaceObj1.get_rect()
textRectObj1.center = (windowWidth-3*cellSize, 2*cellSize)
screen.blit(textSurfaceObj1, textRectObj1)
fontObj2 = pygame.font.Font("freesansbold.ttf", 20)
textSurfaceObj2 = fontObj2.render("shot: %d" % shoted, True, (255, 255, 0))
textRectObj2 = textSurfaceObj2.get_rect()
textRectObj2.center = (2*cellSize, 2*cellSize)
screen.blit(textSurfaceObj2, textRectObj2)
#遊戲結束界面
def gameover():
#drawgrid()
fontObj1 = pygame.font.Font("freesansbold.ttf", 50)
textSurfaceObj1 = fontObj1.render("Game over!", True, (255, 0, 0))
textRectObj1 = textSurfaceObj1.get_rect()
textRectObj1.center = (windowWidth / 2, windowHeight*3 / 8)
screen.blit(textSurfaceObj1, textRectObj1)
fontObj2 = pygame.font.Font("freesansbold.ttf", 30)
textSurfaceObj2 = fontObj2.render("shot: %d"%shoted, True, (255, 255, 255))
textRectObj2 = textSurfaceObj2.get_rect()
textRectObj2.center = (windowWidth / 2, windowHeight * 8 / 16)
screen.blit(textSurfaceObj2, textRectObj2)
fontObj3 = pygame.font.Font("freesansbold.ttf", 30)
textSurfaceObj3 = fontObj3.render("enemy: %d" % enemyed, True, (255, 255, 255))
textRectObj3 = textSurfaceObj3.get_rect()
textRectObj3.center = (windowWidth / 2, windowHeight * 9 / 16)
screen.blit(textSurfaceObj3, textRectObj3)
pygame.display.update()
flag = True
while (flag):
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_SPACE:
flag = False
if __name__ == "__main__":
main()
新建一個文本文檔,複製粘貼下面的代碼進去,保存,關閉,更改擴展名為html,用瀏覽器打開。這就是一個只用了一行代碼的貪吃蛇程序。
&
&
&
&
&
&
&
&
&
&
&
歪個樓,放一下CovScript編寫的貪吃蛇。CovScript和Python差不多,但格式相對自由些。Github源碼地址
共183行,用到了Darwin圖形庫擴展
import darwin
const var head_pix=darwin.pixel("#",darwin.white,darwin.black)
const var body_pix=darwin.pixel("+",darwin.white,darwin.black)
const var food_pix=darwin.pixel("@",darwin.white,darwin.black)
var snake_body={}
var snake_head={0,0}
var food={0,0}
var heading=2
const var init_long=5
var god_mode=false
var cross_wall=false
const var hard=2
var score=0
darwin.load()
var pic=darwin.get_drawable()
function die()
var str0="You die!Your score is "+score+"."
var str1="Press any key to continue..."
loop
if(darwin.is_kb_hit())
darwin.get_kb_hit()
break
end
pic.clear()
pic.fill(darwin.pixel(" ",darwin.white,darwin.red))
pic.draw_string(0.5*(pic.get_width()-str0.size()),0.5*pic.get_height(),str0,darwin.pixel(" ",darwin.white,darwin.red))
pic.draw_string(0.5*(pic.get_width()-str1.size()),pic.get_height()-1,str1,darwin.pixel(" ",darwin.white,darwin.red))
darwin.update_drawable()
end
end
function gen_food()
var is_fit=true
while(is_fit)
food[0]=runtime.randint(0,pic.get_width()-1)
food[1]=runtime.randint(0,pic.get_height()-1)
is_fit=false
for it iterate snake_body
if(it[0]==food[0]it[1]==food[1])
is_fit=true
end
end
end
end
function start()
snake_head={init_long,to_integer(0.5*pic.get_height())}
for i=0 to init_long-2
snake_body.push_back({snake_head[0]-i,snake_head[1]})
end
gen_food()
var frame=0
var pause=false
loop
if(darwin.is_kb_hit())
switch darwin.get_kb_hit()
case "p"
pic.save_to_file("./screen_shot.cdpf")
end
case "w"
if(!pause(god_mode||heading!=4))
heading=3
end
end
case "s"
if(!pause(god_mode||heading!=3))
heading=4
end
end
case "a"
if(!pause(god_mode||heading!=2))
heading=1
end
end
case "d"
if(!pause(god_mode||heading!=1))
heading=2
end
end
case " "
if(pause)
pause=false
else
pause=true
end
end
end
end
if(!pauseframe==hard)
switch heading
case 1
--snake_head[0]
end
case 2
++snake_head[0]
end
case 3
--snake_head[1]
end
case 4
++snake_head[1]
end
end
if(cross_wall)
if(snake_head[0]&<0)
snake_head[0]=snake_head[0]+pic.get_width()
end
if(snake_head[0]&>pic.get_width()-1)
snake_head[0]=snake_head[0]-pic.get_width()
end
if(snake_head[1]&<0)
snake_head[1]=snake_head[1]+pic.get_height()
end
if(snake_head[1]&>pic.get_height()-1)
snake_head[1]=snake_head[1]-pic.get_height()
end
else
if(snake_head[0]&<0||snake_head[0]&>pic.get_width()-1||snake_head[1]&<0||snake_head[1]&>pic.get_height()-1)
die()
return 0
end
end
if(!god_mode)
for it iterate snake_body
if(it[0]==snake_head[0]it[1]==snake_head[1])
die()
return 0
end
end
end
snake_body.push_front(snake_head)
if(snake_head[0]==food[0]snake_head[1]==food[1])
gen_food()
score=score+to_integer(10*(1.0/hard))
else
snake_body.pop_back()
end
frame=0
end
pic.clear()
pic.draw_string(0,0,"Score:"+to_string(score),darwin.pixel(" ",darwin.black,darwin.white))
if(cross_wall)
pic.draw_string(0,1,"Cross Wall",darwin.pixel(" ",darwin.white,darwin.blue))
end
if(god_mode)
pic.draw_string(0,2,"God Mode",darwin.pixel(" ",darwin.white,darwin.red))
end
if(pause)
pic.draw_string(0,3,"Pause",darwin.pixel(" ",darwin.white,darwin.yellow))
end
for it iterate snake_body
pic.draw_pixel(it[0],it[1],body_pix)
end
pic.draw_pixel(snake_head[0],snake_head[1],head_pix)
pic.draw_pixel(food[0],food[1],food_pix)
darwin.update_drawable()
if(!pause)
++frame
end
end
end
for i=1 to system.args.size()-1
switch system.args.at(i)
case "--god-mode"
god_mode=true
end
case "--cross-wall"
cross_wall=true
end
default
throw runtime.exception("Unknown arguments")
end
end
end
darwin.ui.message_box("Greedy Snake","Press any key to start","OK")
darwin.fit_drawable()
loop
snake_body.clear()
heading=2
start()
end
這兩天寫了一個貪吃蛇 用的是 pygame
純原創 暑假自學了python 有些演算法可能有不太合適的地方 大神請無視
放在了Github上
qizhenkang/Snaker_AI
如有不懂需要解釋的地方可在評論區回復~
pygame的貪吃蛇,一次投遞多個食物,默認畫布帶下15*15,一次投遞20個食物,食物之間、食物與蛇之間不會重疊。當方塊總數 - 蛇身長度 - 食物個數 &< 20時,判斷玩家勝利。有生之年終於可以看到貪吃蛇的結局了!
稍作修改也可以成為命令行版本的貪吃蛇
# -*- coding: utf-8 -*-
"""
Created on Tue May 16 07:24:28 2017
@author: zbg
"""
import pygame
from pygame.locals import *
from random import randint, choice, shuffle
class Map(dict):
def __init__(self, w, h):
dict.__init__(self)
self.w = w
self.h = h
self.clear()
def __str__(self):
s = ""
for j in range(self.h):
for i in range(self.w):
s += self[(i, j)]
s += "
"
return s
def clear(self):
for i in range(self.w):
for j in range(self.h):
self[(i, j)] ="."
class Food(object):
def __init__(self, world, n = 1):
self.n = n #一次產生n個食物
self.m = world.m
self.world = world
self.w = self.m.w
self.h = self.m.h
self.locations = {}#用字典是為了吃食物時方便刪除
def generate(self):#由外部world調用,維持n個食物
space = []#除開蛇以外的地方的坐標
for i in range(self.w):
for j in range(self.h):
if (i, j) not in self.world.snake.body:
space.append((i, j))
shuffle(space)
while len(self.locations) &< self.n:
self.locations[space[-1]] = 1 #後面的值1並沒有意義。
del space[-1]
def draw(self):
for l in self.locations:
self.m[l] = "o"
class Snake(object):
"""
蛇做一些簡單的移動、計算和繪製
改變移動方向交給外部的World來處理
"""
def __init__(self, world):
self.world = world
self.m = world.m
self.h = self.m.h
self.w = self.m.w
self.direction = "left" #
self.state = "alive" # "alive" or "dead"
cw, ch = self.w / 2, self.h / 2
self.body = [(cw, ch), (cw + 1, ch), (cw + 2, ch)]
def draw(self):
for b in self.body:
self.m[b] = "x"
def newhead(self):
headw, headh = self.body[0]
newheadw, newheadh = headw, headh
if self.direction == "left":
newheadw = headw - 1
elif self.direction == "right":
newheadw = headw + 1
elif self.direction == "up":
newheadh = headh - 1
elif self.direction == "down":
newheadh = headh + 1
return newheadw, newheadh
def move(self):
x, y = self.newhead()
if len(self.body) + self.world.food.n + 20 &> self.w * self.h:
print "fine, you win!!"
elif x == -1 or y == -1 or x == self.w or y == self.h:
print "error, dead"
elif (x, y) in self.body:
print "error, dead"
elif (x, y) in self.world.food.locations:
self.body = [self.newhead()] + self.body[:]
del world.food.locations[(x, y)]
else:
self.body = [self.newhead()] + self.body[0: -1]
def changedirection(self, direction):
self.direction = direction
class World(object):
def __init__(self, w, h):
self.m = Map(w, h)
self.snake = Snake(self)
self.food = Food(self, 20)
self.w, self.h = w, h
def run(self):
self.food.generate()
self.m.clear()
self.snake.move()
self.food.draw()
self.snake.draw()
def show(screen, m):
for i in range(m.w):
for j in range(m.h):
if m[(i, j)] == "x":
r = pygame.Rect(i * unit, j * unit, unit, unit)
pygame.draw.rect(screen,(136,0,21),r,0)
elif m[(i, j)] == "o":
r = pygame.Rect(i * unit, j * unit, unit, unit)
pygame.draw.rect(screen,(0,174,21),r,0)
h = 15
w = 15
unit = 30
SCREEN_SIZE = (w * unit, h * unit)
DIRECTION = {pygame.K_UP: "up", pygame.K_DOWN: "down", pygame.K_LEFT: "left", pygame.K_RIGHT:"right"}
world = World(15,15)
clock = pygame.time.Clock()
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit(0)
if event.type == pygame.KEYDOWN:
if event.key in DIRECTION:
direction = DIRECTION[event.key]
if direction in ["up", "down"] and world.snake.direction in ["up", "down"]:
pass
elif direction in ["left", "right"] and world.snake.direction in ["left", "right"]:
pass
else:
world.snake.changedirection(direction)
screen.fill((255,255,255))
world.run()
show(screen, world.m)
pygame.display.update()
print world.m
clock.tick(3)
大概看了下,如果不調用包吧。你至少知道怎麼搞gui。python主要的Gui是pyqt,tkinter,GKT,wxpython。 第一、第五個重點參考吧。你同時再知道一個隨機數的生成方式。至於調用包寫的話,推薦pygame,random夠了。一百行左右的代碼量吧。
貪吃蛇只需要有如下基本的 IO 功能就可以寫了:
- 在指定坐標寫/畫一個塊
- 不阻塞不回顯地讀鍵盤
Console 下面能寫,GUI 也可以。甚至 Console 需要的功能還少些。
所以最簡單就是用標準庫 curses 寫個 Console 的貪吃蛇。curses 入門可以看官方的 How to:
Curses Programming with Python
如果用 Windows,可能需要下載安裝非官方的 curses 包:http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses而如果用 GUI,效果會好些,概念也要多些。我想 pygame 是很應景的東西,用起來比較方便,網站上有教程。注意 IO 是操作系統提供的功能,由庫包裝一下系統功能來提供上面兩個 IO 操作就已經算是從零開始了。如果你覺得用 curses 還不夠「從零開始」,那麼你就得針對不同操作系統來寫了。例如對於 Windows,就是調用諸如 SetConsoleCursorPosition、WriteConsole 等 API 完成基本的輸出,調用 SetConsoleMode、ReadConsole 之類函數處理輸入。用 C 寫貪吃蛇倒常有人這麼干,Python 沒見過這樣的。用print寫的貪吃蛇,pygame只用監視鍵盤,其他都是標準庫
import pygame
from time import time
from random import choice
from collections import deque
def getdrt():
pygame.event.pump()
keys = pygame.key.get_pressed()
if keys[pygame.K_UP] and olddrt[1] != 1:
return (0,-1)
elif keys[pygame.K_DOWN] and olddrt[1] != -1:
return (0,1)
elif keys[pygame.K_LEFT] and olddrt[0] != 1:
return (-1,0)
elif keys[pygame.K_RIGHT] and olddrt[0] != -1:
return (1,0)
else:
return drt
def show():
global score
show_out = ""
for row in layout:
for i in row:
show_out += shape[i]
show_out += "
"
show_out += " Score: " + str(score)
print("
"*50) #more beautiful
print(show_out)
def move(drt):
global snake_x,snake_y
snake_x += drt[0]
snake_y += drt[1]
thing = layout[snake_y][snake_x]
layout[snake_y][snake_x] = 2
snake.append((snake_x,snake_y))
if thing == 0:
go()
elif thing == 1 or thing == 2:
die(thing)
elif thing == 3:
eat()
def die(thing):
if thing == 1:
print("You moved into the wall!")
elif thing == 2:
print("You ate yourself!")
quit()
def eat():
global score,move_speed,food
score += 1
move_speed *= 0.94
i = j = 0 #food
while layout[j][i]:
i = choice(range(1,width-1))
j = choice(range(1,height-1))
layout[j][i] = 3 #food
def go():
i = snake.popleft()
layout[i[1]][i[0]] = 0
#settings and initializations
width = 18
height = 20
shape = [" "," X "," * "," $ "] #0=nothing 1=wall 2=snake 3=food
layout = [[0 for i in range(width)] for i in range(height)] #wall
for i in [0,width-1]:
for j in range(0,height):
layout[j][i] = 1
for i in [0,height-1]:
for j in range(0,width):
layout[i][j] = 1
snake_x = snake_y = 10
olddrt = drt = (1,0) #initial moving direction
snake = deque([(snake_x,snake_y)])
layout[snake_y][snake_x] = 2 #snake
layout[choice(range(1,height-1))][choice(range(1,width-1))] = 3 #food
move_speed = 0.7 #snake moves * time per second
score = 0
pygame.init()
loop = True
move_time = show_time = time()
while loop:
drt = getdrt()
if time() - move_time &> move_speed:
move(drt)
show()
olddrt = drt
move_time = time()
天辣嚕 。我要好好學習一下python 了感覺很不錯啊。
不懂python,水一下,做遊戲界面為什麼用python
推薦閱讀:
※python3.5 pip安裝庫,無法找到vcvarsall.bat錯誤?裝VS、改源碼無效
※用python寫程序時,怎麼知道我想實現的功能有沒有現成的函數?
※python爬蟲如何深入學習?