[英]Tkinter & Turtle Snake Game
我一直在试验 Tkinter 的画布功能。 我把乌龟放在画布上,并试图制作一个蛇游戏。 我试图运行代码但有一些问题:
当您按退出退出时,它不会打印分数,
笔只能举一次,不能放回去,也不能再放,
称为玩家的乌龟有时不会生成在您实际可以看到的屏幕部分,
当您触摸名为 player 的乌龟或移动名为 player 的乌龟时,名为 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()
所以这里需要做几个更正。 我认为你对一些事情有一些误解。
您需要在包含全局命名空间中或需要存在的变量的函数中定义global
。 如果不这样做,则在尝试更新变量时会遇到诸如local variable 'score' referenced before assignment
类的错误。
==
只是一个比较。 您在需要是单个=
地方使用它。
您定义了一个名为quit
的函数,这是一个内置方法。 请注意不要覆盖内置方法。
您永远不会看到打印的分数,因为game
总是错误的。 您的代码中没有任何内容将其更改为 True。
while
和sleep()
不应与 tkinter 在同一线程中使用。 这将导致问题,因为这两种方法都会阻塞主循环。 管理这种情况的一种方法是改用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()
我看到的主要问题是您希望海龟随着程序的用户不断移动而只改变方向。 我不相信你会通过无限循环获得这种效果,例如:
while right == True:
forward == False
left == False
backward == False
t.forward(5)
这依赖于一些外部事件来改变right
的值,但并没有真正暂停让其他事件运行。 (加上==
与=
的错误使用。)
其他问题包括:
由于符号错误,玩家只能重新定位一次,始终移动到同一地点:
x = random.randint(-100, -100)
y = random.randint(-100, -100)
缺少必要的global
语句以及==
vs =
误用:
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.