TclError:命令名无效“。!相框。!帆布“

2024-04-26 05:27:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用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))

我试图找到解决办法,但到现在为止我还是被卡住了。我希望有人能帮我找到解决这个问题的办法。提前谢谢你


Tags: inselfsizeiffoodtkinterdefbot
1条回答
网友
1楼 · 发布于 2024-04-26 05:27:06

我认为问题是你不能真正控制自我.windows以及

在自我.canvas存在。在

我做了两个改动,现在剧本显然起作用了……显然!在

def render(self):

    try:
        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')
    except:
        pass

这里呢

^{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

相关问题 更多 >