我一直在尝试Tkinter的画布功能。我把乌龟放在画布上,试图做一个蛇游戏。我尝试运行代码,但遇到了一些问题:
按退出键退出时不打印分数
您只能拿起笔一次,不能放回或再放一次,
有时您不会在实际看到的屏幕上生成称为玩家的乌龟
当您触摸名为玩家的乌龟或移动名为玩家的乌龟时,名为t的乌龟不会增加得分。
可能还有其他问题,但这是我所知道的。
这是我的代码:
import tkinter as tk
import random
import turtle
import time
import sys
game = False
forward = False
left = False
right = False
backward = False
draw = True
score = 0
def spawn(e=None):
t.penup()
t.goto(0,0)
player=turtle.RawTurtle(app)
player.penup()
player.shapesize(0.5,0.5)
player.shape("square")
player.color("black")
xrand = random.randint(-100, 100)
yrand = random.randint(-100, 100)
player.goto(x=xrand,y=yrand)
if t.distance(player) <15:
x = random.randint(-100, -100)
y = random.randint(-100, -100)
player.goto(x,y)
score = score+1
def systemap(e=None):
app.place(x=100,y=-4)
button.place(x=660,y=470)
def f(e=None):
if game == False:
t.setheading(90)
t.forward(5)
elif game == True:
forward == True
while forward == True:
left == False
right == False
backward == False
t.forward(5)
if forward == False:
t.setheading(90)
t.forward(5)
def l(e=None):
if game == False:
t.setheading(180)
t.forward(5)
elif game == True:
left == True
while left == True:
forward == False
right == False
backward == False
t.forward(5)
if left == False:
t.setheading(180)
t.forward(5)
def r(e=None):
if game == False:
t.setheading(0)
t.forward(5)
elif game == True:
right == True
while right == True:
forward == False
left == False
backward == False
t.forward(5)
if right == False:
t.setheading(0)
t.forward(5)
def b(e=None):
if game == False:
t.setheading(270)
t.forward(5)
elif game == True:
backward == True
while backward == True:
forward == False
left == False
right == False
t.forward(5)
if backward == False:
t.setheading(270)
t.forward(5)
def quit(e=None):
if game == False:
time.sleep(1)
window.destroy()
sys.exit()
elif game == True:
time.sleep(2)
window.destroy()
print("Score: ",score)
sys.exit()
def pen(e=None):
if draw == True:
t.penup()
draw == False
if draw == False:
t.pendown()
draw == True
window = tk.Tk()
window.iconbitmap('py.ico')
window.title("Turtle Graphics")
window.geometry("750x500")
window.resizable(False, False)
button = tk.Button(window,
text=" Close ",
font="Calibri",
borderwidth=0,
background="White",
command=quit)
app = tk.Canvas(master=window, width=500, height=500, bg="white")
t=turtle.RawTurtle(app)
window.bind("<Up>", f)
window.bind("<Left>", l)
window.bind("<Right>", r)
window.bind("<Down>", b)
window.bind("<w>", f)
window.bind("<a>", l)
window.bind("<d>", r)
window.bind("<s>", b)
window.bind("<p>", pen)
window.bind("<Escape>", quit)
window.bind("<g>", spawn)
systemap()
window.mainloop()
答案 0 :(得分:0)
因此,这里需要进行一些更正。我认为您对某些事情有一些误解。
您需要在函数中定义global
,这些函数包含全局名称空间中的变量或需要存在于全局名称空间中的变量。如果不这样做,则在尝试更新变量时会遇到类似local variable 'score' referenced before assignment
之类的错误。
==
仅是比较。您正在需要单个=
的地方使用它。
您定义了一个名为quit
的函数,这是一个内置方法。请注意不要覆盖内置方法。
您永远不会看到打印出来的分数,因为game
始终为False。您的代码中没有任何内容将其更改为True。
while
和sleep()
不应与tkinter在同一线程中使用。这将导致问题,因为这两种方法都会阻塞mainloop。一种解决方法是使用after()
方法或线程。在这种情况下,我认为线程处理是多余的,after()
在这里可能是更好的选择。
最后,我不确定您是否需要在其中添加game = True
。
这是您的代码整理了一下。我已经纠正了所列的大部分内容,但没有更多详细信息,我无法猜测其余的内容。
如果您有任何疑问,请告诉我:
import tkinter as tk
import random, turtle
game = False
forward = False
left = False
right = False
backward = False
draw = True
score = 0
def spawn(_=None):
global score, forward, left, backward, player
t.penup()
t.goto(0, 0)
player = turtle.RawTurtle(app)
player.penup()
player.shapesize(0.5, 0.5)
player.shape("square")
player.color("black")
xrand = random.randint(-100, 100)
yrand = random.randint(-100, 100)
player.goto(x=xrand, y=yrand)
if t.distance(player) < 15:
x = random.randint(-100, -100)
y = random.randint(-100, -100)
player.goto(x, y)
score = score + 1
def systemap(_=None):
app.place(x=100, y=-4)
button.place(x=660, y=470)
def f(_=None):
global forward, left, right, backward
if not game:
t.setheading(90)
t.forward(5)
else:
forward = True
while forward:
left = False
right = False
backward = False
t.forward(5)
if not forward:
t.setheading(90)
t.forward(5)
def l(_=None):
global forward, left, right, backward
if not game:
t.setheading(180)
t.forward(5)
else:
left = True
while left:
forward = False
right = False
backward = False
t.forward(5)
if not left:
t.setheading(180)
t.forward(5)
def r(_=None):
global forward, left, right, backward
if not game:
t.setheading(0)
t.forward(5)
else:
right = True
while right:
forward = False
left = False
backward = False
t.forward(5)
if not right:
t.setheading(0)
t.forward(5)
def b(_=None):
global forward, left, right, backward
if not game:
t.setheading(270)
t.forward(5)
else:
backward = True
while backward:
forward = False
left = False
right = False
t.forward(5)
if not backward:
t.setheading(270)
t.forward(5)
def quit_func(_=None):
if not game:
window.destroy()
else:
window.destroy()
print("Score: ", score)
def pen(_=None):
global draw
if draw:
t.penup()
draw = False
else:
t.pendown()
draw = True
window = tk.Tk()
window.title("Turtle Graphics")
window.geometry("750x500")
window.resizable(False, False)
button = tk.Button(window, text="Close", font="Calibri", borderwidth=0, background="White", command=quit_func)
app = tk.Canvas(master=window, width=500, height=500, bg="white")
t = turtle.RawTurtle(app)
window.bind("<Up>", f)
window.bind("<Left>", l)
window.bind("<Right>", r)
window.bind("<Down>", b)
window.bind("<w>", f)
window.bind("<a>", l)
window.bind("<d>", r)
window.bind("<s>", b)
window.bind("<p>", pen)
window.bind("<Escape>", quit_func)
window.bind("<g>", spawn)
systemap()
window.mainloop()
答案 1 :(得分:0)
我看到的主要问题是您希望乌龟与程序用户一起不断移动,只改变方向。我不相信您会像这样的无限循环获得这种效果:
while right == True:
forward == False
left == False
backward == False
t.forward(5)
这依赖于某个外部事件来更改right
的值,但并没有真正暂停让其他事件运行。 (加上==
与=
的错误使用。)
其他问题包括:
由于符号错误,玩家只能重定位一次,总是重定位到同一位置:
x = random.randint(-100, -100)
y = random.randint(-100, -100)
缺少必要的global
语句以及==
与=
的滥用:
def pen(e=None):
if draw == True:
t.penup()
draw == False
if draw == False:
t.pendown()
draw == True
如果不测试这些基本功能中的某些功能,那么您应该从来没有像现在这样编码过。您编写的未经测试的代码越多,调试起来就越困难。
下面是我对您的代码的重做,实现了乌龟(蛇)的恒定运动。我还将一些与乌龟相关的代码从tkinter领域移到了乌龟方法中。我为示例简化了一些操作(例如,只有一组运动键,箭头。)但我相信它现在是一个非常基本但可玩的游戏:
import tkinter as tk
from turtle import TurtleScreen, RawTurtle
from random import randint
direction = None
score = 0
def spawn():
player = RawTurtle(screen)
player.hideturtle()
player.shape('square')
player.shapesize(0.5)
player.color('black')
player.penup()
x = randint(-100, 100)
y = randint(-100, 100)
player.goto(x, y)
player.showturtle()
players.append(player)
def check_collision():
global score
for player in players:
if turtle.distance(player) < 15:
x = randint(-100, 100)
y = randint(-100, 100)
player.goto(x, y)
score += 1
def f():
global direction
def move():
check_collision()
if direction == 'forward':
turtle.forward(5)
screen.ontimer(move, 100)
if direction != 'forward':
direction = 'forward'
turtle.setheading(90)
move()
def l():
global direction
def move():
check_collision()
if direction == 'left':
turtle.forward(5)
screen.ontimer(move, 100)
if direction != 'left':
direction = 'left'
turtle.setheading(180)
move()
def r():
global direction
def move():
check_collision()
if direction == 'right':
turtle.forward(5)
screen.ontimer(move, 100)
if direction != 'right':
direction = 'right'
turtle.setheading(0)
move()
def b():
global direction
def move():
check_collision()
if direction == 'backward':
turtle.forward(5)
screen.ontimer(move, 100)
if direction != 'backward':
direction = 'backward'
turtle.setheading(270)
move()
def pen():
if turtle.isdown():
turtle.penup()
else:
turtle.pendown()
def quit_game(e=None): # called from either turtle or tkinter
window.destroy()
print("Score:", score)
exit()
players = []
window = tk.Tk()
# window.iconbitmap('py.ico')
window.title("Turtle Graphics")
window.geometry("600x600")
window.resizable(False, False)
canvas = tk.Canvas(master=window, width=500, height=500)
canvas.pack()
tk.Button(window, width=17, text='Close', borderwidth=0, command=quit_game).pack()
screen = TurtleScreen(canvas)
turtle = RawTurtle(screen)
screen.onkey(f, 'Up')
screen.onkey(l, 'Left')
screen.onkey(r, 'Right')
screen.onkey(b, 'Down')
screen.onkey(pen, 'p')
screen.onkey(quit_game, 'Escape')
screen.onkey(spawn, 'g')
screen.listen()
screen.mainloop()