Python Terminator Error

馋奶兔 提交于 2021-01-19 09:37:29

问题


I'm working on a Python project with a friend of mine for school. We have imported Turtle and Math. My problem is that when I use the "Esc" button to close the window, I get an error saying "Terminator Error"... I've asked the teachers but even they don't know what the problem is because they aren't very familiar with Turtle.

Could any of you guys tell me what I'm doing wrong ? btw : I'm using EduPython on Windows 10.

Here is the code :

import turtle
import math


fn = turtle.Screen()
fn.bgcolor("black")
fn.title("No Escape !")
fn.setup(700, 700)

images = ["right.gif", "left.gif", "face.gif", "back.gif", "tresor.gif", "mur.gif", "sol.gif"]

for image in images:
    # On ajoute l'image a notre labyrinthe.
    fn.addshape(image)
    turtle.shape(image)
    # On retire les mises a jour et deplace l'image de base qui etait au centre.
    fn.tracer(0)
    turtle.goto(-700, -700)



class Stylo(turtle.Turtle):
    def __init__(self):
        turtle.Turtle.__init__(self)
        self.shape("square")
        self.color("white")
        self.penup()
        self.speed(0)

def closefn():
    turtle.bye()

class Joueur(turtle.Turtle):
    def __init__(self):
        turtle.Turtle.__init__(self)
        self.shape("face.gif")
        self.color("blue")
        self.penup()
        self.speed(0)

    def haut(self):
        move_to_x = self.xcor()
        move_to_y = self.ycor() + 24
        self.shape("back.gif")
        if (move_to_x, move_to_y) not in murs:
        self.goto(move_to_x, move_to_y)

    def bas(self):
        move_to_x = self.xcor()
        move_to_y = self.ycor() - 24
        self.shape("face.gif")
        if (move_to_x, move_to_y) not in murs:
        self.goto(move_to_x, move_to_y)

    def gauche(self):  
        move_to_x = self.xcor() - 24
        move_to_y = self.ycor()
        self.shape("left.gif")
    if (move_to_x, move_to_y) not in murs:
        self.goto(move_to_x, move_to_y)

    def droite(self):
        move_to_x = self.xcor() + 24
        move_to_y = self.ycor()
        self.shape("right.gif")
        if (move_to_x, move_to_y) not in murs:
        self.goto(move_to_x, move_to_y)

    def collision(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


class Tresor(turtle.Turtle):
    def __init__(self, x, y):
        turtle.Turtle.__init__(self)
        self.shape("tresor.gif")
        self.penup()
        self.speed(0)
        self.goto(x, y)

    def destruction(self):
        self.goto(2000, 2000)
        self.hideturtle()

niveaux = []

niveaux.append([
    "XXXXXXXXXXXXXXXXXXXXXXXXX",
    "XJ X      X             X",
    "X  X XXX  X    XXXXXXX  X",
    "X  X  TX  X          X  X",
    "X  XXXXX  X  X XXXXXXX  X",
    "X           X  X        X",
    "XXXXXXXX    X  XT X X   X",
    "X X    X XXXXXXXXXXXXXX X",
    "X X X  X X            X X",
    "X X XT X   X X   X    XTX",
    "X X XXXX X X XXXXXX X XXX",
    "X X    X X X TX     X   X",
    "X XXX XX   XXXXXXXXXXXXXX",
    "X        X X            X",
    "XXXXXXXX   XTX  X X XXX X",
    "X      X X XXX  X X XT  X",
    "X  XXX X X      X X XXXXX",
    "X XXT  X X  XXXXXXX X X X",
    "X  XXXXX X              X",
    "X          XXXXXXXXXX X X",
    "XXXXX  XXXXX            X",
    "X          X X X XX XXXXX",
    "X XXXXXXXX X XXX  X    XX",
    "X     TX   X  XT X   X  X",
    "XXXXXXXXXXXXXXXXXXXXXXXXX"]);

tresors = []
murs = []


def setup_labyrinthe(niveau):
    for y in range(len(niveau)):
        for x in range(len(niveau[y])):
            caractere = niveau[y][x]
            ecran_x = -288 + (x * 24)
            ecran_y = 288 - (y * 24)
            if caractere == "X":
                stylo.goto(ecran_x, ecran_y)
                stylo.shape("mur.gif")
                stylo.stamp()
                murs.append((ecran_x, ecran_y))
            if caractere == "J":
                joueur.goto(ecran_x, ecran_y)
            if caractere == "T":
                tresors.append(Tresor(ecran_x, ecran_y))


stylo = Stylo()
joueur = Joueur()

score = 0

setup_labyrinthe(niveaux[0])


fn.tracer(0)

while True:
    # On associe les touches du clavier.
    turtle.listen()
    turtle.onkeypress(joueur.gauche, "Left")
    turtle.onkeypress(joueur.droite, "Right")
    turtle.onkeypress(joueur.haut, "Up")
    turtle.onkeypress(joueur.bas, "Down")
    turtle.onkey(closefn, "Escape")
    print(score)
    turtle.write(score)
    turtle.goto(180, 315)

    for tresor in tresors:
        if joueur.collision(tresor):
            tresor.destruction()
            score = score+100
            tresors.remove(tresor)
    fn.update()

回答1:


when I use the "Esc" button to close the window, I get an error saying "Terminator Error"

The problem is you're using while True: in an event-based world, effectively shutting out the event system and causing things to happen in non-synchronous ways. The Terminator Error occurs when the turtle screen has been closed but methods are still acting as if it's running.

One way around this is to make everything work within the event model. Below I've eliminated your while True: loop and replaced it with a function that's called whenever the player moves to a new position. And I've cleaned up lots of other stuff for efficiency and/or style:

from turtle import Turtle, Screen

IMAGES = ["right.gif", "left.gif", "face.gif", "back.gif", "tresor.gif", "mur.gif", "sol.gif"]

FONT = ('Arial', 18, 'bold')

class Stylo(Turtle):
    def __init__(self):
        Turtle.__init__(self, "mur.gif")
        self.color("white")
        self.penup()
        self.speed('fastest')

class Joueur(Turtle):
    def __init__(self):
        Turtle.__init__(self, "face.gif")
        self.color("blue")
        self.penup()
        self.speed('fastest')

    def haut(self):
        move_to_x = self.xcor()
        move_to_y = self.ycor() + 24
        self.shape("back.gif")
        if (move_to_x, move_to_y) not in murs:
            self.goto(move_to_x, move_to_y)
        scorefn()

    def bas(self):
        move_to_x = self.xcor()
        move_to_y = self.ycor() - 24
        self.shape("face.gif")
        if (move_to_x, move_to_y) not in murs:
            self.goto(move_to_x, move_to_y)
        scorefn()

    def gauche(self):
        move_to_x = self.xcor() - 24
        move_to_y = self.ycor()
        self.shape("left.gif")
        if (move_to_x, move_to_y) not in murs:
            self.goto(move_to_x, move_to_y)
        scorefn()

    def droite(self):
        move_to_x = self.xcor() + 24
        move_to_y = self.ycor()
        self.shape("right.gif")
        if (move_to_x, move_to_y) not in murs:
            self.goto(move_to_x, move_to_y)
        scorefn()

    def collision(self, other):

        return self.distance(other) < 5

class Tresor(Turtle):
    def __init__(self, x, y):
        Turtle.__init__(self, "tresor.gif")
        self.penup()
        self.speed('fastest')
        self.goto(x, y)

    def destruction(self):
        self.hideturtle()
        self.goto(2000, 2000)

NIVEAUX = [[
    "XXXXXXXXXXXXXXXXXXXXXXXXX",
    "XJ X      X             X",
    "X  X XXX  X    XXXXXXX  X",
    "X  X  TX  X          X  X",
    "X  XXXXX  X  X XXXXXXX  X",
    "X           X  X        X",
    "XXXXXXXX    X  XT X X   X",
    "X X    X XXXXXXXXXXXXXX X",
    "X X X  X X            X X",
    "X X XT X   X X   X    XTX",
    "X X XXXX X X XXXXXX X XXX",
    "X X    X X X TX     X   X",
    "X XXX XX   XXXXXXXXXXXXXX",
    "X        X X            X",
    "XXXXXXXX   XTX  X X XXX X",
    "X      X X XXX  X X XT  X",
    "X  XXX X X      X X XXXXX",
    "X XXT  X X  XXXXXXX X X X",
    "X  XXXXX X              X",
    "X          XXXXXXXXXX X X",
    "XXXXX  XXXXX            X",
    "X          X X X XX XXXXX",
    "X XXXXXXXX X XXX  X    XX",
    "X     TX   X  XT X   X  X",
    "XXXXXXXXXXXXXXXXXXXXXXXXX"]]

def setup_labyrinthe(niveau):
    for y in range(len(niveau)):
        for x in range(len(niveau[y])):
            caractere = niveau[y][x]
            ecran_x = -288 + (x * 24)
            ecran_y = 288 - (y * 24)

            if caractere == "X":
                stylo.goto(ecran_x, ecran_y)
                stylo.stamp()
                murs.append((ecran_x, ecran_y))
            elif caractere == "J":
                joueur.goto(ecran_x, ecran_y)
            elif caractere == "T":
                tresors.append(Tresor(ecran_x, ecran_y))

def scorefn():
    global score

    for tresor in tresors:
        if joueur.collision(tresor):
            tresor.destruction()
            score += 100
            # On associe les touches du clavier.
            marker.undo()
            marker.write(score, font=FONT)
            tresors.remove(tresor)

fn = Screen()
fn.bgcolor("black")
fn.title("No Escape!")
fn.setup(700, 700)

fn.tracer(False)  # turn off screen updates

for image in IMAGES:
    # On ajoute l'image a notre labyrinthe.
    fn.addshape(image)

stylo = Stylo()
joueur = Joueur()

tresors = []
murs = []

setup_labyrinthe(NIVEAUX[0])

fn.onkeypress(joueur.gauche, "Left")
fn.onkeypress(joueur.droite, "Right")
fn.onkeypress(joueur.haut, "Up")
fn.onkeypress(joueur.bas, "Down")
fn.onkey(fn.bye, "Escape")
fn.listen()

score = 0

marker = Turtle(visible=False)
marker.penup()
marker.color('green')
marker.goto(180, 315)
marker.write(score, font=FONT)

fn.tracer(True)  # turn screen updates back on

fn.mainloop()

My next warning is that turtles wander a floating point plane. Comparing wall positions in a list directly against turtle positions might not always work (ponder 315.0 vs. 315.00003). Like treasures, consider using turtle's distance() method (which works with positions as well as other turtles) and a fudge factor to determine if you will be too close to a wall instead of exactly at one.



来源:https://stackoverflow.com/questions/49587546/python-terminator-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!