我正在使用Jupyter笔记本和python3.7.1版来构建一个使用tkinter包的snake游戏。嗯,这更像是从github复制别人的代码,然后自己修改。目标是制作一个蛇游戏,这个游戏由系统玩10次。所以在第一场比赛结束后,tkinter帧将关闭,另一个将弹出并重复10次。问题是,每次游戏结束和帧关闭时,系统都会发出警告,在5或6次迭代后,系统将强制停止并给出与警告相同的错误消息。在
以下是警告:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\user\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:\Users\user\Anaconda3\lib\tkinter\__init__.py", line 749, in callit
func(*args)
File "<ipython-input-18-b0768e06fac0>", line 132, in tick
self.render()
File "<ipython-input-18-b0768e06fac0>", line 95, in render
self.canvas.delete(tkinter.ALL)
File "C:\Users\user\Anaconda3\lib\tkinter\__init__.py", line 2514, in delete
self.tk.call((self._w, 'delete') + args)
_tkinter.TclError: invalid command name ".!frame.!canvas"
这是导致系统强制停止进程的错误消息:
^{2}$这是我修改过的代码:
from tkinter import Tk, Canvas, Frame, BOTH
import tkinter
from collections import deque
from random import randint
import random
from IPython.display import clear_output
class snake_bot():
def __init__(self, bot_id, speed):
#
self.bot_id = bot_id
self.speed = speed
self.X = 30
self.Y = 20
self.BLOCK_SIZE = 20
self.window = Tk()
self.window.geometry('{}x{}'.format(self.X * self.BLOCK_SIZE, self.Y * self.BLOCK_SIZE))
self.window.resizable(False, False)
self.frame = Frame(self.window)
self.frame.master.title('Snake Bot - ID - ' +str(self.bot_id))
self.frame.pack(fill=BOTH, expand=1)
self.canvas = Canvas(self.frame)
self.canvas.pack(fill=BOTH, expand=1)
self.VALID_DIRECTIONS = {
'Left': set(('Up', 'Down')),
'Right': set(('Up', 'Down')),
'Up': set(('Left', 'Right')),
'Down': set(('Left', 'Right'))
}
self.MOVEMENTS = {
'Left': lambda x, y: (x - 1, y),
'Right': lambda x, y: (x + 1, y),
'Up': lambda x, y: (x, y - 1),
'Down': lambda x, y: (x, y + 1)
}
self.score = 0
randX = randint(0, (self.X - 2))
randY = randint(0, (self.Y - 2))
coin_flip = randint(1, 2)
if(coin_flip == 1):
#X
coin_flip = randint(1, 2)
if(coin_flip == 1):
#-
self.snake = deque(((randX, randY), ((randX-1), randY)))
else:
#+
self.snake = deque(((randX, randY), ((randX+1), randY)))
else:
#Y
coin_flip = randint(1, 2)
if(coin_flip == 1):
#-
self.snake = deque(((randX, randY), (randX, (randY-1))))
else:
#+
self.snake = deque(((randX, randY), (randX, (randY+1))))
in_s = True
while(in_s == True):
self.food = (randint(0, (self.X - 1)), randint(0, (self.Y - 1)))
if self.food not in self.snake:
in_s = False
self.moves = deque()
availabel_directions = ['Down', 'Up', 'Right', 'Left']
self.direction = random.choice(availabel_directions)
self.start()
def draw_rect(self, x, y, color='#00f'):
self.x1 = x * self.BLOCK_SIZE
self.y1 = y * self.BLOCK_SIZE
self.x2 = self.x1 + self.BLOCK_SIZE
self.y2 = self.y1 + self.BLOCK_SIZE
return self.canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill=color)
def draw_background(self, x, y):
self.x1 = x * self.BLOCK_SIZE
self.y1 = y * self.BLOCK_SIZE
self.x2 = self.x1 + self.BLOCK_SIZE
self.y2 = self.y1 + self.BLOCK_SIZE
return self.canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill='white')
def render(self):
self.canvas.delete(tkinter.ALL)
for x in range(0, self.X):
for y in range(0, self.Y):
self.draw_background(x, y)
for self.x, self.y in self.snake:
self.draw_rect(self.x, self.y, color='#00f')
self.x, self.y = self.food
self.draw_rect(self.x, self.y, color='#f00')
def create_food(self):
self.s = set(self.snake)
while True:
self.food = randint(0, self.X - 1), randint(0, self.Y - 1)
if self.food not in self.s:
return self.food
def check_food(self):
self.s = set(self.snake)
if self.food in self.s:
self.increase_score()
self.food = self.create_food()
else:
self.snake.popleft()
def random_direction(self):
self._direction = self.moves[-1] if self.moves else self.direction
availabel_directions = ['Down', 'Up', 'Right', 'Left']
self.key = random.choice(availabel_directions)
if self.key in self.VALID_DIRECTIONS[self._direction]:
self.moves.append(self.key)
def tick(self):
self.random_direction()
self.direction = self.moves.popleft() if self.moves else self.direction
self.move_snake(self.direction)
self.check_food()
self.render()
self.window.after(int(1000 / self.speed), self.tick)
def start(self):
self.tick()
self.window.mainloop()
def increase_score(self):
self.score += 1
if not self.score % 5:
# increase speed after the snake eats 5 times
self.speed += 2
clear_output()
print('ID - ', self.bot_id, 'score:', self.score, 'speed:', self.speed)
def move_snake(self, direction):
self.x, self.y = self.snake[-1]
self.next_point = self.MOVEMENTS[self.direction](self.x, self.y)
self.s = set(self.snake)
if self.next_point in self.s:
self.window.destroy()
clear_output()
print('You just ate yourself')
print('ID - ', self.bot_id, 'score:', self.score, 'speed:', self.speed)
if self.x < 0 or self.x >= self.X or self.y < 0 or self.y >= self.Y:
self.window.destroy()
clear_output()
print('You crashed into a wall')
print('ID - ', self.bot_id, 'score:', self.score, 'speed:', self.speed)
self.snake.append(self.next_point)
bots = []
for i in range(0, 10):
bots.append(snake_bot((i + 1), 10))
我试图找到解决办法,但到现在为止我还是被卡住了。我希望有人能帮我找到解决这个问题的办法。提前谢谢你
我认为问题是你不能真正控制自我.windows以及
在自我.canvas存在。在
我做了两个改动,现在剧本显然起作用了……显然!在
这里呢
^{pr2}$我明白了
你刚刚吃了自己
ID-1分数:0速度:10
你刚刚吃了自己
ID-2分数:0速度:10
你撞墙了
ID-3分数:0速度:10
你撞墙了
ID-4得分:1速度:10
你撞墙了
ID-5分数:0速度:10
你撞墙了
ID-6分数:0速度:10
你撞墙了
ID-7分数:0速度:10
你撞墙了
ID-8分数:1速度:10
你刚刚吃了自己
ID-9分数:0速度:10
你撞墙了
ID-10分数:0速度:10
相关问题 更多 >
编程相关推荐