** 说明: ** 贪吃蛇, tkinter找不到文档, 勉强写一个界面
思路
二维界面 一位数组
(0, 0) (1, 0) (2, 0) 0 1 2
(0, 1) (1, 1) (2, 1) 3 4 5
(0, 2) (1, 2) (2, 2) 6 7 8
将界面转为一位数组, 那么地图可以这么定义
map = range(9)
x坐标的长度, 或者界面宽度
width = 3
y坐标的长度, 界面长度
height = 3
坐标为(1,1)的点:
pos = 4
求坐标
x = pos % width
y = pos // width
方向的值
up = -w
down = w
right = 1
left = -1
移动
pos = pos + left # 左移
pos = pos + up # 上移
pos = pos + down # 下移
pos = pos + right # 右移
判断碰撞边界
pos + direction < 0 or pos + direction >= width * height #上下方向
pos % width + direction == -1 or pos % width + direction == width * height # 左右方向
吃豆子
bean == pos + direction
代码(python3):
import tkinter
import random
import time
class Game(object):
"""docstring for Game"""
w, h, length, unit = 50, 50, 2500, 10
over = pause = False
gmap = bean = snake = canvas_after_id = None
direction = -1
pause_text, restart_text = 'pause', 'restart'
bg, snake_bg, bean_bg = 'white', 'purple', 'green'
duration = 400
def __init__(self):
super(Game, self).__init__()
root = tkinter.Tk()
self.keys = {'a': -1, 'w': -self.w, 's': self.w, 'd': 1}
self.pause_btn = tkinter.Button(root, text=self.pause_text, command=self.game_pause)
self.restart_btn = tkinter.Button(root, text=self.restart_text, command=self.start)
self.pause_btn.grid(row=0, column=0)
self.restart_btn.grid(row=0, column=1)
self.c = tkinter.Canvas(root, width=self.w * self.unit, height=self.h * self.unit, bg=self.bg)
self.c.grid(row=1, columnspan=10)
self.c.bind_all("<KeyPress>", self.set_direction)
self.start()
tkinter.mainloop()
def run(self):
if self.over:
return
if self.pause:
self.c.after_cancel(self.canvas_after_id)
return
self.crawl()
self.canvas_after_id = self.c.after(self.duration, self.run)
def crawl(self):
pos = self.snake[0] + self.direction
if pos in self.snake or pos < 0 or pos >= self.length or (self.snake[0] % self.w + self.direction) in [-1, self.w]:
self.over = True
print('game over')
return
self.snake.insert(0, pos)
if pos == self.bean:
self.new_bean()
else:
tail = self.snake.pop()
self.draw(tail, self.bg)
self.draw(pos, self.snake_bg)
def game_pause(self):
self.pause = not self.pause
self.pause_text = 'continue' if self.pause else 'pause'
self.pause_btn.config(text=self.pause_text)
if not self.pause:
self.run()
def set_direction(self, e):
arrow = self.keys.get(e.char)
self.direction = self.direction if not arrow or -self.direction == arrow else arrow
def start(self):
self.reset()
self.run()
def reset(self):
t1 = time.time()
self.over = self.pause = False
self.c.delete("all")
self.gmap = {i: self.create_rectangle(i, self.bg) for i in range(self.length)}
self.new_snake()
self.new_bean()
def new_snake(self):
self.snake = [self.w * (self.h + 1) // 2, self.w * (self.h + 1 ) // 2 + 1]
self.direction = -1
for i in self.snake:
self.draw(i, self.snake_bg)
def new_bean(self):
self.bean = None
while not self.bean or self.bean in self.snake:
self.bean = random.randint(0, self.length - 1)
self.draw(self.bean, self.bean_bg)
def draw(self, pos, color):
if self.gmap[pos]:
self.c.itemconfig(self.gmap[pos], fill=color)
def create_rectangle(self, pos, color):
x1 = pos % self.w * self.unit
y1 = pos // self.w * self.unit
x2 = x1 + self.unit -1
y2 = y1 + self.unit -1
return self.c.create_rectangle(x1, y1, x2, y2, fill=color, outline=self.bg)
Game()