python实现贪吃蛇
说明
从电脑里翻出来了两年前学习python时候做的贪吃蛇小游戏。当时在刷莫烦的视频教程,就学着做了这个。
代码
# coding: utf-8
# # 贪吃蛇
# 按键盘的上、下、左、右键控制
import tkinter as tk
import time
import threading
import random
snaker = tk.Tk()
snaker.title('Retro Snaker')
snaker.geometry('500x500')
canvas = tk.Canvas(snaker, width=400, height=400, bg='yellow')
canvas.focus_set()
canvas.pack()
x0, y0, x1, y1 = 10, 100, 20, 110
snake = [] ## 蛇的 list
## 刚开始有三个节点
head = canvas.create_rectangle(x0, y0, x1, y1, fill='black')
snake.append(head)
body = canvas.create_rectangle(x0-10, y0, x1-10, y1, fill='black')
snake.append(body)
body = canvas.create_rectangle(x0-10, y0, x1-10, y1, fill='black')
snake.append(body)
label = tk.Label(snaker, text='score: 0', width=15, height=2, font=('Arial', 30))
label.pack()
direction = 'Right' # 贪吃蛇前进的方向
lock = threading.Lock()
lock_over = threading.Lock()
def new_lattice():
stat = True
global new
while(stat):
stat = False
x0 = random.randint(0, 399)
y0 = random.randint(0, 399)
x0 = int(x0/10)*10
y0 = int(y0/10)*10
for i in range(len(snake)):
x0_s, y0_s, x1_s, y1_s = canvas.coords(snake[i])
if x0_s == x0 and y0_s == y0:
stat = True
new = canvas.create_rectangle(x0, y0, x0+10, y0+10, fill='black')
def add_to_snake():
global x0_lead, y0_lead, x1_lead, y1_lead
global new
x0_new,y0_new,x1_new,y1_new = canvas.coords(new) # 自己的位置
len_s = len(snake)
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(snake[len_s-1])
delta_x = x0_lead - x0_new
delta_y = y0_lead - y0_new
canvas.move(new, delta_x, delta_y)
for i in range(len(snake)):
if i==0:
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(snake[i])
if direction == 'Up':
canvas.move(snake[0],0,-10)
elif direction == 'Down':
canvas.move(snake[0],0,10)
elif direction == 'Left':
canvas.move(snake[0],-10,0)
elif direction == 'Right':
canvas.move(snake[0],10,0)
else:
x0_ego,y0_ego,x1_ego,y1_ego = canvas.coords(snake[i]) # 自己的位置
delta_x = x0_lead - x0_ego
delta_y = y0_lead - y0_ego
canvas.move(snake[i],delta_x,delta_y)
x0_lead,y0_lead,x1_lead,y1_lead = x0_ego,y0_ego,x1_ego,y1_ego
snake.append(new)
# print([i for i in snake])
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(new)
new_lattice()
label.config(text='score: ' + str(len_s-2))
# new = canvas.create_rectangle(x0-10,y0,x1-10,y1,fill='black')
def game_over():
print('game over')
image_file = tk.PhotoImage(file="gameover.gif")
image = canvas.create_image(200,200,anchor='center',image=image_file)
snaker.mainloop()
def auto_move(): ### 贪吃蛇自己走动
global x0_lead,y0_lead,x1_lead,y1_lead
global new
global direction
sleep = 0.1
lock.acquire()
time.sleep(sleep)
for i in range(len(snake)):
if i == 0:
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(snake[i])
if direction == 'Up':
canvas.move(snake[0],0,-10)
elif direction == 'Down':
canvas.move(snake[0],0,10)
elif direction == 'Left':
canvas.move(snake[0],-10,0)
elif direction == 'Right':
canvas.move(snake[0],10,0)
else:
x0_ego, y0_ego, x1_ego, y1_ego = canvas.coords(snake[i]) # 自己的位置
delta_x = x0_lead - x0_ego
delta_y = y0_lead - y0_ego
canvas.move(snake[i],delta_x,delta_y)
x0_lead,y0_lead,x1_lead,y1_lead = x0_ego,y0_ego,x1_ego,y1_ego
### 判断是否吃上
x0_head,y0_head,x1_head,y1_head = canvas.coords(snake[0])
x0_new,y0_new,x1_new,y1_new = canvas.coords(new) # 自己的位置
if direction == 'Up' and x0_head==x0_new and y0_head==y1_new:
add_to_snake()
elif direction == 'Down' and x0_head==x0_new and y1_head==y0_new:
add_to_snake()
elif direction == 'Left' and x0_head==x1_new and y0_head==y0_new:
add_to_snake()
elif direction == 'Right' and x1_head==x0_new and y0_head==y0_new:
add_to_snake()
elif x0_head==x0_new and y0_head==y0_new:
add_to_snake()
else:
pass
### 判断游戏是否结束
x0_head,y0_head,x1_head,y1_head = canvas.coords(head) # 头的位置
if x0_head<0 or x0_head>399 or y0_head<0 or y0_head>399:
lock.release()
game_over()
for i in range(len(snake)):
x0_ego,y0_ego,x1_ego,y1_ego = canvas.coords(snake[i])
if i>0 and x0_head == x0_ego and y0_head == y0_ego:
lock.release()
game_over()
lock.release()
canvas.after(10,auto_move)
def valid_order(keysym):
global direction
if {keysym, direction} == {"Up", "Down"} or {keysym, direction} == {"Left", "Right"}:
return False
else:
return True
def player_move(): ## 玩家控制运动
lock.acquire()
global x0_lead,y0_lead,x1_lead,y1_lead
global new
def snaker_move(ke):
global lock
global direction
if not valid_order(ke.keysym):
return
if ke.keysym == 'Up':
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(head)
canvas.move(head,0,-10)
direction = ke.keysym
elif ke.keysym == 'Down':
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(head)
canvas.move(head,0,10)
direction = ke.keysym
elif ke.keysym == 'Left':
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(head)
canvas.move(head,-10,0)
direction = ke.keysym
elif ke.keysym == 'Right':
x0_lead,y0_lead,x1_lead,y1_lead = canvas.coords(head)
canvas.move(head,10,0)
direction = ke.keysym
else:
pass
for i in range(len(snake)):
if i>0:
x0_ego,y0_ego,x1_ego,y1_ego = canvas.coords(snake[i]) # 自己的位置
delta_x = x0_lead - x0_ego
delta_y = y0_lead - y0_ego
canvas.move(snake[i],delta_x,delta_y)
x0_lead,y0_lead,x1_lead,y1_lead = x0_ego,y0_ego,x1_ego,y1_ego
### 判断是否吃上
x0_head,y0_head,x1_head,y1_head = canvas.coords(snake[0])
x0_new,y0_new,x1_new,y1_new = canvas.coords(new) # 自己的位置
if direction == 'Up' and x0_head==x0_new and y0_head==y1_new:
add_to_snake()
elif direction == 'Down' and x0_head==x0_new and y1_head==y0_new:
add_to_snake()
elif direction == 'Left' and x0_head==x1_new and y0_head==y0_new:
add_to_snake()
elif direction == 'Right' and x1_head==x0_new and y0_head==y0_new:
add_to_snake()
elif x0_head==x0_new and y0_head==y0_new:
add_to_snake()
else:
pass
### 判断游戏是否结束
x0_head,y0_head,x1_head,y1_head = canvas.coords(head) # 头的位置
if x0_head<0 or x0_head>399 or y0_head<0 or y0_head>399:
lock.release()
game_over()
for i in range(len(snake)):
x0_ego,y0_ego,x1_ego,y1_ego = canvas.coords(snake[i])
if i>0 and x0_head == x0_ego and y0_head == y0_ego:
# lock.release()
game_over()
canvas.bind(sequence="<Key>", func=snaker_move)
lock.release()
canvas.after(10,player_move)
new_lattice()
t1 = threading.Thread(player_move())
t2 = threading.Thread(auto_move())
t1.start()
t2.start()
t1.join()
t2.join()
snaker.mainloop()