【发布时间】:2020-06-04 09:26:10
【问题描述】:
我在 Python 3.8 中使用带有 tkinter 的 turtle 时遇到问题。还是编程新手,提前致谢!
我有一个 tkinter 窗口,您可以在其中选择播放第一级或第二级,每次启动程序时,任何一个级别都可以工作,但是一旦您完成该级别并尝试另一个级别,包括同一级别,我会收到错误.
错误信息:
"Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Kev\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "C:/Users/Kev/IdeaProjects/HelloWorld/Games/Maze.py", line 49, in load_level_2
set_up_maze(levels[2]) # choose what level to load
File "C:/Users/Kev/IdeaProjects/HelloWorld/Games/Maze.py", line 254, in set_up_maze
walls.goto(screen_x, screen_y) # make the * characters into walls
File "C:\Users\Kev\AppData\Local\Programs\Python\Python38\lib\turtle.py", line 1776, in goto
self._goto(Vec2D(x, y))
File "C:\Users\Kev\AppData\Local\Programs\Python\Python38\lib\turtle.py", line 3158, in _goto
screen._pointlist(self.currentLineItem),
File "C:\Users\Kev\AppData\Local\Programs\Python\Python38\lib\turtle.py", line 755, in _pointlist
cl = self.cv.coords(item)
File "<string>", line 1, in coords
File "C:\Users\Kev\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 2761, in coords
self.tk.call((self._w, 'coords') + args))]
_tkinter.TclError: invalid command name ".!canvas"
代码:
import turtle
import math
from time import monotonic as my_timer
import tkinter as tk
# turtle variables
bg_color = "black"
wall_shape = "square"
wall_color = "red"
player_shape = "classic"
player_color = "white"
def load_level_1():
hide_root()
main_level1 = turtle.Screen()
main_level1.bgcolor(bg_color)
main_level1.title("Level 1")
main_level1.setup(700, 700)
main_level1.tracer(0)
print("try to set level up")
set_up_maze(levels[1])
print("level set up")
start_time = my_timer()
level_finished = False
while not level_finished:
for treasure in treasures:
if player.has_collided(treasure):
player.gold += treasure.gold
treasure.destroy()
treasures.remove(treasure)
for end in end_points:
if player.has_collided(end):
print("Finish reached")
level_finished = True
main_level1.update()
main_level1.clear()
main_level1.bye()
show_root()
end_time = my_timer()
total_time = end_time - start_time
player.print_score()
print("Total time was {:.2f} seconds".format(total_time))
def load_level_2():
hide_root()
main_level2 = turtle.Screen()
main_level2.bgcolor(bg_color)
main_level2.title("Level 2")
main_level2.setup(700, 700)
main_level2.tracer(0)
print("try to set level up")
set_up_maze(levels[2]) # choose what level to load
print("level set up")
start_time = my_timer()
level_finished = False
while not level_finished:
for treasure in treasures:
if player.has_collided(treasure):
player.gold += treasure.gold
treasure.destroy()
treasures.remove(treasure)
for end in end_points:
if player.has_collided(end):
print("Finish reached")
level_finished = True
main_level2.update()
main_level2.clear()
main_level2.bye()
show_root()
print("finished")
end_time = my_timer()
total_time = end_time - start_time
player.print_score()
print("Total time was {:.2f} seconds".format(total_time))
# create the pen
class Walls(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape(wall_shape)
self.color(wall_color)
self.penup()
self.speed(0)
class Player(turtle.Turtle):
def __init__(self):
turtle.Turtle.__init__(self)
self.shape(player_shape)
self.color(player_color)
self.penup()
self.speed(0)
self.gold = 0
self.settiltangle(-90)
def move_up(self):
self.settiltangle(90)
if (self.xcor(), self.ycor() + 24) not in wall_coordinates:
self.goto(self.xcor(), self.ycor() + 24)
def move_down(self):
self.settiltangle(-90)
if (self.xcor(), self.ycor() - 24) not in wall_coordinates:
self.goto(self.xcor(), self.ycor() - 24)
def move_left(self):
self.settiltangle(180)
if (self.xcor() - 24, self.ycor()) not in wall_coordinates:
self.goto(self.xcor() - 24, self.ycor())
def move_right(self):
self.settiltangle(0)
if (self.xcor() + 24, self.ycor()) not in wall_coordinates:
self.goto(self.xcor() + 24, self.ycor())
def has_collided(self, other):
a = self.xcor() - other.xcor()
b = self.ycor() - other.ycor()
distance = math.sqrt((a ** 2) + (b ** 2))
if distance < 5:
return True
else:
return False
def print_score(self):
print("Your total score is: {} ".format(self.gold))
class Treasure(turtle.Turtle):
def __init__(self, x, y):
turtle.Turtle.__init__(self)
self.shape("circle")
self.color("yellow")
self.penup()
self.speed(0.5)
self.gold = 100
self.goto(x, y)
def destroy(self):
self.goto(2000, 2000)
self.hideturtle()
class Finish(turtle.Turtle):
def __init__(self, x, y):
turtle.Turtle.__init__(self)
self.shape("square")
self.color("green")
self.penup()
self.speed(0.5)
self.goto(x, y)
# lists
levels = [""]
wall_coordinates = []
treasures = []
end_points = []
level_template = ["*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************",
"*************************"]
level_1 = ['*************************',
'*S***** ********',
'* E******* *** *** *',
'** T **** *** ** *',
'**** ****** **** *** ** *',
'**** ** **** *** ** *',
'*** ** * ** ** *',
'**** * * T ******* * *',
'*** *** ** T ** * **',
'*T * ******** ** **',
'** ***** **** ** *',
'** ***T************** *',
'* ** *** **** ** T *',
'*T * *** ***** ****',
'** * ** **** * *',
'** * ** * ** ***** * **',
'** ** ** *** **',
'****** *** T **** **',
'** ** ** * ** ** **** **',
'*E* ** ** * ***** **** **',
'* * ** ** * ***',
'* * *** **** *****',
'* *********** *T** **',
'* * ** *',
'*************************']
level_2 = ['*************************',
'*******S E********',
'**T ******* *** *** *',
'*** **** *** ** *',
'**** ****** **** *** ** *',
'**** ** **** *** ** *',
'*** ** * ** ** *',
'**** * * T ******* * *',
'*** *** ** T ** * **',
'*T * ******** ** **',
'** ***** **** ** *',
'** ***T************** *',
'* ** *** **** ** T *',
'*T * *** ***** ****',
'** * ** **** * *',
'** * ** * ** ***** * **',
'** ** ** *** **',
'****** *** T **** **',
'** ** ** * ** ** **** **',
'** ** ** * *** ** **** **',
'*T* ** ** * ***',
'* * *** **** *****',
'* *********** *T** **',
'* * ** E*',
'*************************']
levels.append(level_1)
levels.append(level_2)
def set_up_maze(level):
for y in range(len(level)): # get the character co ordinates
for x in range(len(level[y])):
character = level[y][x] # save the character coordinates
screen_x = -288 + (x * 24) # calculate the screen co ordinates
screen_y = 288 - (y * 24)
if character == "*":
walls.goto(screen_x, screen_y) # make the * characters into walls
walls.stamp()
wall_coordinates.append((screen_x, screen_y))
if character == "S": # make the player start point
player.goto(screen_x, screen_y)
if character == "T": # make the treasure spawn points
treasures.append(Treasure(screen_x, screen_y))
if character == "E": # make the end point
end_points.append(Finish(screen_x, screen_y))
walls = Walls()
player = Player()
# key bindings
turtle.listen()
turtle.onkey(player.move_up, "Up")
turtle.onkey(player.move_down, "Down")
turtle.onkey(player.move_left, "Left")
turtle.onkey(player.move_right, "Right")
# tk variables
tk_bg_color = "light green"
font = ("comic sans ms", 20)
btn_height = 2
btn_width = 10
pad_x = 40
pad_y = 25
def hide_root():
root.withdraw()
def show_root():
root.deiconify()
root.update()
root = tk.Tk()
root.title("Maze game")
root.config(bg=tk_bg_color)
root.geometry("250x600+600+100")
root.resizable(width=False, height=False)
title_label = tk.Label(root, text="Maze Game", font=font, bg=tk_bg_color)
title_label.grid(row=0, column=0, padx=pad_x, pady=pad_y)
level_1_btn = tk.Button(root, text="Level 1", font=font, height=btn_height, width=btn_width, bg=tk_bg_color,
command=load_level_1)
level_1_btn.grid(row=1, column=0, padx=pad_x, pady=pad_y)
level_2_btn = tk.Button(root, text="Level 2", font=font, height=btn_height, width=btn_width, bg=tk_bg_color,
command=load_level_2)
level_2_btn.grid(row=2, column=0, padx=pad_x, pady=pad_y)
close_btn = tk.Button(root, text="Exit", font=font, height=btn_height, width=btn_width, bg=tk_bg_color,
command=quit)
close_btn.grid(row=3, column=0, padx=pad_x, pady=pad_y)
root.mainloop()
【问题讨论】:
标签: python python-3.x tkinter turtle-graphics python-turtle