Python|200行代码实现贪吃蛇小游戏
游戏预览
控制项
- 游戏从一条长度为3的蛇开始等待用户开始游戏
- 键盘上、下、右和左用于控制蛇头方向
- 游戏结束展示游戏结果
- 在结果屏幕上单击任意位置以再次游戏
程序解读
from tkinter import *
import random
import time
import numpy as np
# 参数定义
size_of_board = 600
rows = 10
cols = 10
DELAY = 100
snake_initial_length = 3 # 初始化蛇身长度
symbol_size = (size_of_board / 3 - size_of_board / 8) / 2
symbol_thickness = 2
RED_COLOR = "#EE4035"
BLUE_COLOR = "#0492CF"
Green_color = "#7BC043"
BLUE_COLOR_LIGHT = '#67B0CF'
RED_COLOR_LIGHT = '#EE7E77'
class SnakeAndApple:
# ------------------------------------------------------------------
# 初始化函数:
# ------------------------------------------------------------------
def __init__(self):
self.window = Tk()
self.window.title("贪吃蛇")
self.canvas = Canvas(self.window, width=size_of_board, height=size_of_board)
self.canvas.pack()
# 键盘输入&鼠标点击
self.window.bind("<Key>", self.key_input)
self.window.bind("<Button-1>", self.mouse_input)
self.play_again()
self.begin = False
def initialize_board(self):
self.board = []
self.apple_obj = []
self.old_apple_cell = []
for i in range(rows):
for j in range(cols):
self.board.append((i, j))
for i in range(rows):
self.canvas.create_line(
i * size_of_board / rows, 0, i * size_of_board / rows, size_of_board,
)
for i in range(cols):
self.canvas.create_line(
0, i * size_of_board / cols, size_of_board, i * size_of_board / cols,
)
def initialize_snake(self):
self.snake = []
self.crashed = False
self.snake_heading = "Right"
self.last_key = self.snake_heading
self.forbidden_actions = {}
self.forbidden_actions["Right"] = "Left"
self.forbidden_actions["Left"] = "Right"
self.forbidden_actions["Up"] = "Down"
self.forbidden_actions["Down"] = "Up"
self.snake_objects = []
for i in range(snake_initial_length):
self.snake.append((i, 0))
def play_again(self):
self.canvas.delete("all")
self.initialize_board()
self.initialize_snake()
self.place_apple()
self.display_snake(mode="complete")
self.begin_time = time.time()
def mainloop(self):
while True:
self.window.update()
if self.begin:
if not self.crashed:
self.window.after(DELAY, self.update_snake(self.last_key))
else:
self.begin = False
self.display_gameover()
# ------------------------------------------------------------------
# 图形函数:
# 在画布上绘制所需基于游戏对象所需的模块
# ------------------------------------------------------------------
def display_gameover(self):
score = len(self.snake)
self.canvas.delete("all")
score_text = "游戏分数 \n"
# 将gif图像放在画布上
# 图片在画布上的左上角(坐标):x=50 y=10
self.canvas.create_text(
size_of_board / 2,
3 * size_of_board / 8,
font="cmr 40 bold",
fill=Green_color,
text=score_text,
)
score_text = str(score)
self.canvas.create_text(
size_of_board / 2,
1 * size_of_board / 2,
font="cmr 50 bold",
fill=BLUE_COLOR,
text=score_text,
)
# 游戏耗时
time_spent = str(np.round(time.time() - self.begin_time, 1)) + 'sec'
self.canvas.create_text(
size_of_board / 2,
3 * size_of_board / 4,
font="cmr 20 bold",
fill=BLUE_COLOR,
text=time_spent,
)
score_text = "再来一局 \n"
self.canvas.create_text(
size_of_board / 2,
15 * size_of_board / 16,
font="cmr 20 bold",
fill="gray",
text=score_text,
)
def place_apple(self):
# 将苹果随机放置在任何地方(排除蛇身体区域)
unoccupied_cels = set(self.board) - set(self.snake)
self.apple_cell = random.choice(list(unoccupied_cels))
row_h = int(size_of_board / rows)
col_w = int(size_of_board / cols)
x1 = self.apple_cell[0] * row_h
y1 = self.apple_cell[1] * col_w
x2 = x1 + row_h
y2 = y1 + col_w
self.apple_obj = self.canvas.create_rectangle(
x1, y1, x2, y2, fill=RED_COLOR_LIGHT, outline=BLUE_COLOR,
)
def display_snake(self, mode=""):
#
if self.snake_objects != []:
self.canvas.delete(self.snake_objects.pop(0))
if mode == "complete":
for i, cell in enumerate(self.snake):
# print(cell)
row_h = int(size_of_board / rows)
col_w = int(size_of_board / cols)
x1 = cell[0] * row_h
y1 = cell[1] * col_w
x2 = x1 + row_h
y2 = y1 + col_w
self.snake_objects.append(
self.canvas.create_rectangle(
x1, y1, x2, y2, fill=BLUE_COLOR, outline=BLUE_COLOR,
)
)
else:
# 头部+1
cell = self.snake[-1]
row_h = int(size_of_board / rows)
col_w = int(size_of_board / cols)
x1 = cell[0] * row_h
y1 = cell[1] * col_w
x2 = x1 + row_h
y2 = y1 + col_w
self.snake_objects.append(
self.canvas.create_rectangle(
x1, y1, x2, y2, fill=BLUE_COLOR, outline=RED_COLOR,
)
)
if self.snake[0] == self.old_apple_cell:
self.snake.insert(0, self.old_apple_cell)
self.old_apple_cell = []
tail = self.snake[0]
row_h = int(size_of_board / rows)
col_w = int(size_of_board / cols)
x1 = tail[0] * row_h
y1 = tail[1] * col_w
x2 = x1 + row_h
y2 = y1 + col_w
self.snake_objects.insert(
0,
self.canvas.create_rectangle(
x1, y1, x2, y2, fill=BLUE_COLOR, outline=RED_COLOR
),
)
self.window.update()
# ------------------------------------------------------------------
# 逻辑函数:
# 游戏运行逻辑
# ------------------------------------------------------------------
def update_snake(self, key):
# 判断是否撞墙&碰触身体
tail = self.snake[0]
head = self.snake[-1]
if tail != self.old_apple_cell:
self.snake.pop(0)
if key == "Left":
self.snake.append((head[0] - 1, head[1]))
elif key == "Right":
self.snake.append((head[0] + 1, head[1]))
elif key == "Up":
self.snake.append((head[0], head[1] - 1))
elif key == "Down":
self.snake.append((head[0], head[1] + 1))
head = self.snake[-1]
if (
head[0] > cols - 1
or head[0] < 0
or head[1] > rows - 1
or head[1] < 0
or len(set(self.snake)) != len(self.snake)
):
# 撞墙/碰触身体
self.crashed = True
elif self.apple_cell == head:
# Got the apple
self.old_apple_cell = self.apple_cell
self.canvas.delete(self.apple_obj)
self.place_apple()
self.display_snake()
else:
self.snake_heading = key
self.display_snake()
def check_if_key_valid(self, key):
valid_keys = ["Up", "Down", "Left", "Right"]
if key in valid_keys and self.forbidden_actions[self.snake_heading] != key:
return True
else:
return False
def mouse_input(self, event):
self.play_again()
def key_input(self, event):
if not self.crashed:
key_pressed = event.keysym
# 判断键盘输入是否有效
if self.check_if_key_valid(key_pressed):
# print(key_pressed)
self.begin = True
self.last_key = key_pressed
game_instance = SnakeAndApple()
game_instance.mainloop()
本文版权归作者所有,转载请注明出处http://www.cnblogs.com/iloverain/.未经作者同意必须保留此段声明,否则保留追究法律责任的权利.