首页 > 解决方案 > 如何删除屏幕中间的黑色精灵?

问题描述

我有一个迷宫游戏,它包含 3 个不同的类,其中包括 2 个迷宫解决算法和一个让玩家用上、下、左和右键四处移动的类。所以在类之间切换的方法是使用 tab 键。但是,当我到达用户可以手动控制精灵的类时,总会有一个随机的黑色箭头,看起来像是在我的窗口中间穿过痉挛。即使我可以设法控制橙色精灵,但那个黑色箭头仍然存在。无论如何我可以删除它吗?我尝试使用hideturtle隐藏箭头,但无济于事。

我高度怀疑是由于我的这部分代码导致出现黑色箭头。但我无法找到替代品。

while True:
    ManualMovements()

这是黑色精灵现在的样子: 在此处输入图像描述

我当前的代码:

from turtle import * # import the turtle library

# define the tile_size and cursor_size for usage later on
TILE_SIZE = 24 
CURSOR_SIZE = 20

screen = Screen() # instantiate the Screen class from turtle
screen.setup(700, 700) # determine the size of the turtle pop out window

class Wall(Turtle): # create Wall class to plot out the walls
    def __init__(self):
        super().__init__() # inherit from Turtle(parent class)
        self.hideturtle() # hide the cursor
        self.shape('square') # define the shape of the object we wanna draw out
        self.shapesize(TILE_SIZE / CURSOR_SIZE) # define the size of the square
        self.pencolor('black') #  define the color that we are going to plot the grids out
        self.penup() # to prevent the pen from leaving a trace
        self.speed('fastest') # get the fastest speed

class Path(Turtle): # create Path class to plot out the path
    def __init__(self):
        super().__init__() # inherit from Turtle(parent class)
        self.hideturtle() # hide the cursor
        self.shape('square') # define the shape of the object we wanna draw out
        self.shapesize(TILE_SIZE / CURSOR_SIZE) # define the size of the square
        self.pencolor('white') #  define the color that we are going to plot the grids out
        self.penup() # to prevent the pen from leaving a trace
        self.speed('fastest') # get the fastest speed

class Sprite(Turtle): # create Sprite class to define the turtle and its characteristics
    def __init__(self):
        super().__init__() # inherit from Turtle(parent class)
        self.shape('turtle') # define the shape of the object we wanna draw out
        self.shapesize((TILE_SIZE / CURSOR_SIZE)-0.4) # define the size of the square
        self.color('orange') #  define the color that we are going to plot the turtle
        self.penup() # to prevent the pen from leaving a trace
        self.speed('slowest') # set speed to slowest to observe the sprite movement

class ManualMovements(Sprite): # create ManualMovement class to let the user manually control the sprite
    def __init__(self):
        super().__init__()
        self.moves = 0
        self.hideturtle()
        self.screen.onkeypress(self.go_up, "Up")
        self.screen.onkeypress(self.go_down, "Down")
        self.screen.onkeypress(self.go_left, "Left")
        self.screen.onkeypress(self.go_right, "Right")

    def go_up(self):
        xcor = sprite.xcor()
        ycor = sprite.ycor()

        if (xcor, ycor + TILE_SIZE) not in walls:
            sprite.setheading(90)
            sprite.goto(xcor, ycor + TILE_SIZE)

    def go_down(self):
        xcor = sprite.xcor()
        ycor = sprite.ycor()

        if (xcor, ycor - TILE_SIZE) not in walls:
            sprite.setheading(270)
            sprite.goto(xcor, ycor - TILE_SIZE)

    def go_left(self):
        xcor = sprite.xcor()
        ycor = sprite.ycor()

        if (xcor - TILE_SIZE, ycor) not in walls:
            sprite.setheading(180)
            sprite.goto(xcor - TILE_SIZE, ycor)

    def go_right(self):
        xcor = sprite.xcor()
        ycor = sprite.ycor()

        if (xcor + TILE_SIZE, ycor) not in walls:
            sprite.setheading(0)
            sprite.goto(xcor + TILE_SIZE, ycor)

def setup_maze(level): # create a setup_maze function so that we can plot out the map in turtle
    # declare maze_height and maze_width first as the limits for the entire maze
    maze_height, maze_width = len(level), len(level[0])

    # get the center point for each maze
    center_horizontal_point = (maze_width + 1) / 2
    center_vertical_point = (maze_height + 1) / 2    

    for y in range(maze_height): # for loop to limit the entire maze
        for x in range(maze_width):
            character = level[y][x] # get the character at each x,y coordinate

            # calculate the screen x, y coordinates
            screen_x = ((x - maze_width) * TILE_SIZE) + (center_horizontal_point * TILE_SIZE)
            screen_y = ((maze_height - y) * TILE_SIZE) - (center_vertical_point * TILE_SIZE)

            if character == "X":
                maze.fillcolor('grey')
                maze.goto(screen_x, screen_y)
                maze.stamp()
                walls.append((screen_x, screen_y)) # add coordinates for the wall to the list
            else:
                maze.fillcolor('white')
                maze.goto(screen_x, screen_y)
                maze.stamp()
                paths.append((screen_x, screen_y)) # add coordinates for the path to the list

            if character == "e":
                maze.fillcolor(['white', 'red'][character == 'e'])
                maze.goto(screen_x, screen_y) # proceed on to the coordinates on turtle
                maze.stamp() # stamp out the boxes
                finish.append((screen_x, screen_y)) # add coordinates for the endpoint to the list             

            if character == 's': # if statement to determine if the character is s
                maze.fillcolor('green')
                maze.goto(screen_x, screen_y)
                maze.stamp() # stamp out the boxes
                start.append((screen_x, screen_y)) # add coordinates for the startpoint to the list
                sprite.goto(screen_x, screen_y) # move the sprite to the location where it is supposed to start

def endProgram(): # exit the entire program upon clicking anywhere in the turtle window
    screen.exitonclick()

grid = []                               # create a grid list to store the labels while reading from the txt file
walls = []                              # create walls coordinate list
start = []
finish = []                             # enable the finish array
paths = []
maze = Wall()                           # enable the Wall class
sprite = Sprite()                       # enable the Sprite class
path = Path() 

with open("map02.txt") as file:         # open the txt file and read contents and append it to maze
    for line in file:
        grid.append(line.strip())

setup_maze(grid)                        # call the setup maze function

start_x, start_y = (start[0])[0], (start[0])[1]

sprite.seth(0)
sprite.goto(start_x, start_y)

while True:
    ManualMovements()

screen.listen() # we need this in order to allow turtle to detect what key we are pressing and respond to it
screen.mainloop()

一个示例 txt 文件映射:

XXXXXXXXXXXXXXXXXXXX
Xe.................X
XXXXXXX...X..XXXXX.X
XXXXXX....X.....XXXX
XXX.......X...X.XXXX
XXXXXX....X.....XXXX
X.........X...XXXXXX
X.XXXXXX..X...XXXXXX
X.X.......X..XXXXXXX
X.X...XXXX.........X
X.XXXXXsXX..XXXXXXXX
X..............XXXXX
XXXXXXXXXXXXXXXXXXXX

编辑:已经进行了一些编辑。请再看一遍。为了执行代码,您必须先按一次 Tab,然后再按我身边的上、下、左、右按钮。我还删除了这两个类以防止混淆,而且因为我指出这部分代码是我的错误应该来自的地方。上面的当前代码也确实复制了相同的错误。

标签: pythonpython-3.xpython-turtle

解决方案


问题是你的ManualMovements班级是错误的。而不是一个奇怪的辅助类,它应该是Sprite. (类似于完全自动化的 Sprite 子类。)我在下面相应地修改了您的代码,并进行了其他修复和优化 - 选择您认为合适的:

from turtle import Screen, Turtle

# define some global constants for use later
TILE_SIZE = 24
CURSOR_SIZE = 20

class Wall(Turtle):
    ''' class to plot out walls '''

    def __init__(self):
        super().__init__(shape='square')  # inherit from parent class

        self.hideturtle()
        self.shapesize(TILE_SIZE / CURSOR_SIZE)  # define the size of the square
        self.penup()  # prevent the pen from leaving a trace
        self.speed('fastest')

class Path(Wall):
    ''' class to plot out the path '''

    def __init__(self):
        super().__init__()  # inherit from parent class

        self.pencolor('white')  # define the color that we are going to plot the grids out

class Sprite(Turtle):
    ''' class to define turtle sprite and its characteristics '''

    def __init__(self):
        super().__init__(shape='turtle')  # inherit from parent class

        self.shapesize((TILE_SIZE / CURSOR_SIZE) - 0.4)  # define the size of the square
        self.color('orange')  # color that we are going to plot the turtle
        self.penup()  # prevent the pen from leaving a trace
        self.speed('slowest')  # set speed to slowest to observe the sprite movement

class ManualSprite(Sprite):
    ''' class to let the user manually control the sprite '''

    def __init__(self):
        super().__init__()

        screen.onkeypress(self.go_up, 'Up')
        screen.onkeypress(self.go_down, 'Down')
        screen.onkeypress(self.go_left, 'Left')
        screen.onkeypress(self.go_right, 'Right')

    def go_up(self):
        screen.onkeypress(None, 'Up')  # disable handler inside handler

        xcor = int(self.xcor())
        ycor = int(self.ycor())

        if (xcor, ycor + TILE_SIZE) not in walls:
            self.setheading(90)
            self.sety(ycor + TILE_SIZE)

        screen.onkeypress(self.go_up, 'Up')  # reenable handler on exit

    def go_down(self):
        screen.onkeypress(None, 'Down')

        xcor = int(self.xcor())
        ycor = int(self.ycor())

        if (xcor, ycor - TILE_SIZE) not in walls:
            self.setheading(270)
            self.sety(ycor - TILE_SIZE)

        screen.onkeypress(self.go_down, 'Down')

    def go_left(self):
        screen.onkeypress(None, 'Left')

        xcor = int(self.xcor())
        ycor = int(self.ycor())

        if (xcor - TILE_SIZE, ycor) not in walls:
            self.setheading(180)
            self.setx(xcor - TILE_SIZE)

        screen.onkeypress(self.go_left, 'Left')

    def go_right(self):
        screen.onkeypress(None, 'Right')

        xcor = int(self.xcor())
        ycor = int(self.ycor())

        if (xcor + TILE_SIZE, ycor) not in walls:
            self.setheading(0)
            self.setx(xcor + TILE_SIZE)

        screen.onkeypress(self.go_right, 'Right')

def setup_maze(level):
    ''' plot out the map as a maze in turtle '''

    # declare the limits for the entire maze
    maze_height, maze_width = len(level), len(level[0])

    # get the center point for each maze
    center_horizontal_point = (maze_width + 1) / 2
    center_vertical_point = (maze_height + 1) / 2

    start = finish = None

    for y in range(maze_height):
        for x in range(maze_width):
            character = level[y][x]  # get the character at each coordinate

            # calculate the screen x, y coordinates
            screen_x = int((x - maze_width) * TILE_SIZE + center_horizontal_point * TILE_SIZE)
            screen_y = int((maze_height - y) * TILE_SIZE - center_vertical_point * TILE_SIZE)
            maze.goto(screen_x, screen_y)

            if character == 'X':
                maze.fillcolor('grey')
                walls.append((screen_x, screen_y))  # add coordinates for the wall
            else:
                paths.append((screen_x, screen_y))  # add coordinates for the path

                if character == 'e':
                    maze.fillcolor('red')
                    finish = (screen_x, screen_y)
                elif character == 's':
                    maze.fillcolor('green')
                    start = (screen_x, screen_y)
                else:
                    maze.fillcolor('white')

            maze.stamp()

    return start, finish

grid = []  # create a grid list to store the labels while reading from the txt file

with open("map02.txt") as file:  # open the txt file and read contents and append it to maze
    for line in file:
        grid.append(line.strip())

screen = Screen()  # extract the Screen class from turtle
screen.setup(700, 700)  # set the size of the turtle window

sprite = ManualSprite()  # instantiate a Sprite instance

walls = []  # walls coordinate list
paths = []

maze = Wall()  # instantiate the Wall class
path = Path()

start, finish = setup_maze(grid)

sprite.setheading(0)
sprite.goto(start) # move the sprite to the start location

screen.listen() # allow turtle to detect key press and respond to it
screen.mainloop()

我已经抛出了简单地回应显而易见的评论。此外,您的逻辑没有考虑浮点坐标的不精确性,这使得它们难以比较——我已将这些比较转换为int.


推荐阅读