[英]Snake game in python Turtle.update() causes problems
So I was trying to create a game of snake using python but I seem to get this error message所以我试图使用 python 创建一个蛇游戏,但我似乎收到了这个错误消息
Traceback (most recent call last):
File "C:\Users\user\source\repos\PythonApplication1\PythonApplication1\PythonApplication1.py", line 85, in <module>
wn.update()
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\turtle.py", line 1304, in update
t._update_data()
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\turtle.py", line 2647, in _update_data
self.screen._incrementudc()
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\turtle.py", line 1293, in _incrementudc
raise Terminator turtle.Terminator
I have tried some solutions I saw online but none of them worked我尝试了一些我在网上看到的解决方案,但没有一个奏效
import turtle
import time
import random
delay = 0.1
score = 0
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor("blue")
wn.setup(width=600 ,height=600)
wn.tracer(0)
#HEAD
head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0,0)
head.direction = "stop"
#FOOD
food = turtle.Turtle()
colors = random.choice(['red','green','black'])
shapes = random.choice(['square','triangle','circle'])
food.speed(0)
food.shape(shapes)
food.color(colors)
food.penup()
food.goto(0,100)
pen = turtle.Turtle()
pen.speed(0)
pen.shape("square")
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0,250)
pen.write("Score : 0 High Score : 0",align="center",font=("candara",24,"bold"))
def goup():
if head.direction !="down":
head.direction = "up"
def godown():
if head.direction !="up":
head.direction ="down"
def goleft():
if head.direction !="right":
head.direction ="left"
def goright():
if head.direction !="left":
head.direction ="right"
def move():
if head.direction == "up":
y=head.ycor()
head.sety(y+20)
if head.direction == "down":
y = head.ycor()
head.sety(y-20)
if head.direction == "left":
x = head.xcor()
head.setx(x-20)
if head.direction == "right":
x = head.xcor()
head.setx(x+20)
wn.listen()
wn.onkeypress(goup,"w")
wn.onkeypress(godown,"s")
wn.onkeypress(goleft,"a")
wn.onkeypress(goright,"d")
segments = []
#Main Gameplay
while True:
wn.update()
if head.xcor()>290 or head.xcor()<-290 or head.ycor()>290 or head.ycor()<-290:
time.sleep(1)
head.goto(0,0)
head.direction = "Stop"
colors = random.choice(['red','blue','green'])
shapes = random.choice(['square','circle'])
for segment in segments:
segments.goto(1000,1000)
segments.clear()
score = 0
delay = 0.1
pen.clear()
pen.write("Score : 0 High Score : 0",align="center",font=("candara",24,"bold"))
if head.distance(food)<20:
x = random.randint(-270,270)
y = random.randint(-270,270)
#Adding segments
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("orange")
new_segment.penup()
segments.append(new_segment)
delay -= 0.001
score += 10
if score > high_score:
high_score = score
pen.clear()
pen.write("Score : {} High Score : {} ".format(score,high_score),align="center", font=("candara",24,"bold"))
for index in range(len(segments)-1,0,-1):
x = segments[index-1].xcor()
y = segments[index-1].ycor()
segments[index].goto(x,y)
if len(segments) > 0:
x = head.xcor()
y = head.ycor()
segments[0].goto(x,y)
move()
for segment in segments:
if segment.distance(head) < 20:
time.sleep(1)
head.goto(0,0)
head.direction = "Stop"
colors = random.choice(['red','blue','green'])
shapes = random.choice(['square','circle'])
for segment in segments:
segment.goto(1000,1000)
segment.clear()
score = 0
delay = 0.1
pen.clear()
pen.write("Score : {} High Score : {} ".format(score,high_score),align="center", font=("candara",24,"bold"))
time.sleep(delay)
wn.mainloop()
EDIT:编辑:
Original code has wrong indentations and some elements doesn't work.原始代码缩进错误,某些元素不起作用。
I get this problem only when I close window with Turtle.只有当我用 Turtle 关闭窗口时才会遇到这个问题。 And this is normal behaviour because when I close window then it still runs while
-loop and wm.update()
tries to access window which is already closed.这是正常行为,因为当我关闭窗口时,它仍然运行while
-loop 和wm.update()
尝试访问已经关闭的窗口。
It would need to assign function which will be executed when window is closed and this function should stop while
loop.它需要分配将在窗口关闭时执行的函数,并且该函数应该while
循环中停止。 But this need to use while running:
with running = True
and access root
window created by tkinter
and assign function (which will set running = False
) to even "WM_DELETE_WINDOW"
但是,这需要使用while running:
与running = True
和访问root
窗口中创建tkinter
和分配功能(这将设置running = False
),甚至"WM_DELETE_WINDOW"
# ... code ...
running = True
def on_closing():
global running
running = False
#root.destroy()
canvas = turtle.getcanvas()
root = canvas.winfo_toplevel()
root.protocol("WM_DELETE_WINDOW", on_closing)
while running:
# ...code...
Full working code.完整的工作代码。
BTW: it doesn't need mainloop
if you runs own loop with update()
顺便说一句:如果您使用update()
运行自己的循环,则不需要mainloop
循环
import turtle
import time
import random
delay = 0.1
score = 0
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor("blue")
wn.setup(width=600 ,height=600)
wn.tracer(0)
#HEAD
head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0,0)
head.direction = "stop"
#FOOD
food = turtle.Turtle()
colors = random.choice(['red','green','black'])
shapes = random.choice(['square','triangle','circle'])
food.speed(0)
food.shape(shapes)
food.color(colors)
food.penup()
food.goto(0,100)
pen = turtle.Turtle()
pen.speed(0)
pen.shape("square")
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0,250)
pen.write("Score : 0 High Score : 0",align="center",font=("candara",24,"bold"))
def goup():
if head.direction !="down":
head.direction = "up"
def godown():
if head.direction !="up":
head.direction ="down"
def goleft():
if head.direction !="right":
head.direction ="left"
def goright():
if head.direction !="left":
head.direction ="right"
def move():
if head.direction == "up":
y=head.ycor()
head.sety(y+20)
if head.direction == "down":
y = head.ycor()
head.sety(y-20)
if head.direction == "left":
x = head.xcor()
head.setx(x-20)
if head.direction == "right":
x = head.xcor()
head.setx(x+20)
wn.listen()
wn.onkeypress(goup,"w")
wn.onkeypress(godown,"s")
wn.onkeypress(goleft,"a")
wn.onkeypress(goright,"d")
segments = []
running = True
def on_closing():
global running
running = False
root.destroy()
canvas = turtle.getcanvas()
root = canvas.winfo_toplevel()
root.protocol("WM_DELETE_WINDOW", on_closing)
#Main Gameplay
while running:
wn.update()
if head.xcor()>290 or head.xcor()<-290 or head.ycor()>290 or head.ycor()<-290:
time.sleep(1)
head.goto(0,0)
head.direction = "Stop"
colors = random.choice(['red','blue','green'])
shapes = random.choice(['square','circle'])
for segment in segments:
segments.goto(1000,1000)
segments.clear()
score = 0
delay = 0.1
pen.clear()
pen.write("Score : 0 High Score : 0",align="center",font=("candara",24,"bold"))
if head.distance(food)<20:
x = random.randint(-270,270)
y = random.randint(-270,270)
#Adding segments
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("orange")
new_segment.penup()
segments.append(new_segment)
delay -= 0.001
score += 10
if score > high_score:
high_score = score
pen.clear()
pen.write("Score : {} High Score : {} ".format(score,high_score),align="center", font=("candara",24,"bold"))
# --- after `if` ---
for index in range(len(segments)-1,0,-1):
x = segments[index-1].xcor()
y = segments[index-1].ycor()
segments[index].goto(x,y)
if len(segments) > 0:
x = head.xcor()
y = head.ycor()
segments[0].goto(x,y)
move()
for segment in segments:
if segment.distance(head) < 20:
time.sleep(1)
head.goto(0,0)
head.direction = "Stop"
colors = random.choice(['red','blue','green'])
shapes = random.choice(['square','circle'])
for segment in segments:
segment.goto(1000,1000)
segment.clear()
score = 0
delay = 0.1
pen.clear()
pen.write("Score : {} High Score : {} ".format(score,high_score),align="center", font=("candara",24,"bold"))
time.sleep(delay)
#wn.mainloop()
OR you should use ontimer(func, time) instead of while
-loop and time.sleep()
- and then it should stop it when you close window或者你应该使用ontimer(func, time)而不是while
-loop 和time.sleep()
- 然后它应该在你关闭窗口时停止它
def gameloop():
wn.update()
# ... code without `while` and without `sleep`
# run again
wn.ontimer(gameloop, 1000) # time in millisecons
# ---
# run first time
wn.ontimer(gameloop, 1000) # time in millisecons
wn.mainloop()
BTW: but it needs to use global
inside gameloop
to assign values to global variables instead of local variables.顺便说一句:但它需要在游戏gameloop
内使用global
来为全局变量而不是局部变量赋值。
Full code完整代码
It needs mainloop()
which will run gameloop()
ever 1000 milliseconds.它需要mainloop()
将运行gameloop()
曾经1000毫秒。
import turtle
import time
import random
delay = 0.1
score = 0
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor("blue")
wn.setup(width=600 ,height=600)
wn.tracer(0)
#HEAD
head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0,0)
head.direction = "stop"
#FOOD
food = turtle.Turtle()
colors = random.choice(['red','green','black'])
shapes = random.choice(['square','triangle','circle'])
food.speed(0)
food.shape(shapes)
food.color(colors)
food.penup()
food.goto(0,100)
pen = turtle.Turtle()
pen.speed(0)
pen.shape("square")
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0,250)
pen.write("Score : 0 High Score : 0",align="center",font=("candara",24,"bold"))
def goup():
if head.direction !="down":
head.direction = "up"
def godown():
if head.direction !="up":
head.direction ="down"
def goleft():
if head.direction !="right":
head.direction ="left"
def goright():
if head.direction !="left":
head.direction ="right"
def move():
if head.direction == "up":
y=head.ycor()
head.sety(y+20)
if head.direction == "down":
y = head.ycor()
head.sety(y-20)
if head.direction == "left":
x = head.xcor()
head.setx(x-20)
if head.direction == "right":
x = head.xcor()
head.setx(x+20)
wn.listen()
wn.onkeypress(goup,"w")
wn.onkeypress(godown,"s")
wn.onkeypress(goleft,"a")
wn.onkeypress(goright,"d")
segments = []
high_score = 0
def gameloop():
global score
global delay
global high_score
# ... etc. ...
wn.update()
if head.xcor()>290 or head.xcor()<-290 or head.ycor()>290 or head.ycor()<-290:
head.goto(0,0)
head.direction = "Stop"
colors = random.choice(['red','blue','green'])
shapes = random.choice(['square','circle'])
for segment in segments:
segments.goto(1000,1000)
segments.clear()
score = 0
delay = 0.1
pen.clear()
pen.write("Score : 0 High Score : 0",align="center",font=("candara",24,"bold"))
if head.distance(food)<20:
x = random.randint(-270,270)
y = random.randint(-270,270)
#Adding segments
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("orange")
new_segment.penup()
segments.append(new_segment)
delay -= 0.001
score += 10
if score > high_score:
high_score = score
pen.clear()
pen.write("Score : {} High Score : {} ".format(score,high_score),align="center", font=("candara",24,"bold"))
# --- after `if` ---
for index in range(len(segments)-1,0,-1):
x = segments[index-1].xcor()
y = segments[index-1].ycor()
segments[index].goto(x,y)
if len(segments) > 0:
x = head.xcor()
y = head.ycor()
segments[0].goto(x,y)
move()
for segment in segments:
if segment.distance(head) < 20:
time.sleep(1)
head.goto(0,0)
head.direction = "Stop"
colors = random.choice(['red','blue','green'])
shapes = random.choice(['square','circle'])
for segment in segments:
segment.goto(1000,1000)
segment.clear()
score = 0
delay = 0.1
pen.clear()
pen.write("Score : {} High Score : {} ".format(score,high_score),align="center", font=("candara",24,"bold"))
# run again
wn.ontimer(gameloop, 1000) # time in millisecons
# ---
# run first time
wn.ontimer(gameloop, 1000) # time in millisecons
wn.mainloop() # it needs `mainloop`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.