sorry to bother anyone but when I run my code (my first attempt at a real game) everything works fine, but then after I close it some errors print and I can't find anyone else with my problem. My files is called Space Invaders.py, I am using Pycharm (these errors also occur with the IDLE). This is my code:
import turtle
import math
print("------------Space Invaders - Python------------")
print("-------------GAME NOT YET COMPLETED------------")
print("This console is simply a status readout.")
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("Space Invaders")
borderPen = turtle.Turtle()
borderPen.speed(0)
borderPen.color("white")
borderPen.penup()
borderPen.setposition(-400, -400)
borderPen.pendown()
borderPen.pensize(3)
for i in range(4):
borderPen.fd(800)
borderPen.lt(90)
borderPen.hideturtle()
player = turtle.Turtle()
player.setheading(90)
player.shape("triangle")
player.color("blue")
player.penup()
player.speed(0)
player.setposition(0, -350)
enemy = turtle.Turtle()
enemy.color("red")
enemy.shape("circle")
enemy.penup()
enemy.speed(0)
enemy.setposition(-300, 250)
movementStepE = 2
movementStepEY = -15
movementStepP = 5
def move_left():
x = player.xcor()
new_x = x - movementStepP
if new_x < -380:
new_x = -380
player.setx(new_x)
def move_right():
x = player.xcor()
new_x = x + movementStepP
if new_x > 380:
new_x = 380
player.setx(new_x)
def distancepyth(x1, x2, y1, y2):
pyth = math.sqrt((x1 - x2) ** 2) + (y1 - y2 ** 2)
return(pyth)
turtle.listen()
turtle.onkeypress(move_left, "Left")
turtle.onkeypress(move_right, "Right")
new_y = 250 # 250
while True:
x = enemy.xcor()
y = enemy.ycor()
new_x = x + movementStepE
if new_x > 380:
movementStepE = movementStepE * -1
new_y = y + movementStepEY
new_x = 380
elif new_x < -380:
movementStepE = movementStepE * -1
new_y = y + movementStepEY
new_x = -380
enemy.setposition(new_x, new_y)
turtle.done()
print("-------PROGRAM TERMINATED INTENTIONALLY-------")
and these are the errors:
Traceback (most recent call last):
File "C:/Users/Noname Antilabelson/PycharmProjects/Space Invaders Game/Code/Space Invaders.py", line 97, in <module>
enemy.setposition(new_x, new_y)
File "C:\Users\Noname Antilabelson\AppData\Local\Programs\Python\Python37\lib\turtle.py", line 1776, in goto
self._goto(Vec2D(x, y))
File "C:\Users\Noname Antilabelson\AppData\Local\Programs\Python\Python37\lib\turtle.py", line 3158, in _goto
screen._pointlist(self.currentLineItem),
File "C:\Users\Noname Antilabelson\AppData\Local\Programs\Python\Python37\lib\turtle.py", line 755, in _pointlist
cl = self.cv.coords(item)
File "<string>", line 1, in coords
File "C:\Users\Noname Antilabelson\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 2469, in coords
self.tk.call((self._w, 'coords') + args))]
_tkinter.TclError: invalid command name ".!canvas"
Sorry if I've done anything stupid, your help would be greatly appreciated! Regards - Jacob Sutton
As you noted in your comment, the while True:
is your problem as it has no place in an event driven environment like turtle. Closing a window is an event that's firing asynchronous to your main loop. To make it synchronous, we can use an ontimer()
event. I've made that change to your code below as well as thrown in other turtle idioms and code cleanup:
from turtle import Screen, Turtle
print("------------Space Invaders - Python------------")
print("-------------GAME NOT YET COMPLETED------------")
print("This console is simply a status readout.")
def move_left():
new_x = player.xcor() - movementStepP
if new_x < -380:
new_x = -380
player.setx(new_x)
def move_right():
new_x = player.xcor() + movementStepP
if new_x > 380:
new_x = 380
player.setx(new_x)
def move_enemy():
global new_y, movementStepE
new_x = enemy.xcor() + movementStepE
if new_x > 380:
movementStepE *= -1
new_y += movementStepEY
new_x = 380
elif new_x < -380:
movementStepE *= -1
new_y += movementStepEY
new_x = -380
enemy.setposition(new_x, new_y)
screen.ontimer(move_enemy, 50)
movementStepE = 2
movementStepEY = -15
movementStepP = 5
screen = Screen()
screen.bgcolor("black")
screen.title("Space Invaders")
borderPen = Turtle(visible=False)
borderPen.speed("fastest")
borderPen.color("white")
borderPen.pensize(3)
borderPen.penup()
borderPen.setposition(-400, -400)
borderPen.pendown()
for _ in range(4):
borderPen.forward(800)
borderPen.left(90)
player = Turtle("triangle")
player.speed("fastest")
player.setheading(90)
player.color("blue")
player.penup()
player.setposition(0, -350)
enemy = Turtle("circle")
enemy.speed("fastest")
enemy.color("red")
enemy.penup()
enemy.setposition(-300, 250)
screen.onkeypress(move_left, "Left")
screen.onkeypress(move_right, "Right")
screen.listen()
new_y = 250
move_enemy()
screen.mainloop()
print("-------PROGRAM TERMINATED INTENTIONALLY-------")
With this change, the console shows:
> python3 test.py
------------Space Invaders - Python------------
-------------GAME NOT YET COMPLETED------------
This console is simply a status readout.
-------PROGRAM TERMINATED INTENTIONALLY-------
>
Even when you close the window while the enemy is in motion.
You could also put a try catch statement round it as well, like so:
while True:
try:
x = enemy.xcor()
y = enemy.ycor()
new_x = x + movementStepE
if new_x > 380:
movementStepE = movementStepE * -1
new_y = y + movementStepEY
new_x = 380
elif new_x < -380:
movementStepE = movementStepE * -1
new_y = y + movementStepEY
new_x = -380
enemy.setposition(new_x, new_y)
except: #For more accuracy on catching, try something like 'except _tkinter.TclError:'
break #if error raised
turtle.done()
print("-------PROGRAM TERMINATED INTENTIONALLY-------")
Please be aware though that without something like 'except _tkinter.TclError:' then any errors will just close the window.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.