获取“宝物"坐标(海龟)在使用 Python tkinter 和海龟的迷宫游戏中 [英] Get coordinates of "treasure" (turtles) in Maze Game that uses Python tkinter and turtle

查看:73
本文介绍了获取“宝物"坐标(海龟)在使用 Python tkinter 和海龟的迷宫游戏中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Python 3 使用 tkinter 和海龟图形制作迷宫.大多数代码都有效,除了我不知道如何摧毁"游戏中的黄金".具体来说,调用 player.collision(),它说 Question object has no attribute xcor 即使我从一个关于海龟 Python 迷宫游戏的教程中得到了这个.我认为它会像在那种情况下一样工作,但是有了 tkinter,一切似乎都改变了.问题发生在 player.collision() 和最后的 while 循环下.这两段代码旨在摧毁"或隐藏金"海龟.我已经包含了(几乎)我的全部代码,所以每个人都可以看到发生了什么.

I am using Python 3 to make a maze using tkinter and turtle graphics. Most of the code works, except I cannot figure out how to "destroy" the "gold" in the game. Specifically, calling player.collision(), it says Question object has no attribute xcor even though I got this from a tutorial about a turtle Python maze game. I figured it would work the same as it did in that context, but with tkinter, everything seems to change. The problem occurs under player.collision() and the while loop at the end. Those are the two sections of code that are meant to "destroy," or hide, the "gold" turtles. I have included (almost) my entire code so everyone can see what is going on.

(除了这个问题,我想创建一种使用箭头键而不是框架上的按钮移动播放器的方法,但我不知道如何.)

(In addition to this question, I would like to create a way to move the player using the arrow keys rather than the buttons on the frame, but I can't figure out how.)

我曾尝试在 collision() 函数中专门命名海龟,而不仅仅是命名其他".我还尝试通过返回 tur3.xcor()tur3.ycor()<在 Question 类下创建新方法来getX"和getY"/code> 分别.但这没有做任何事情,除了给我另一个错误.就像我说的,当它只是一个乌龟迷宫时,这段代码有效,但自从添加 tkinter 后,我不得不改变一大堆东西.

I have tried naming the turtle specifically rather than just "other" in the collision() function. I have also tried making new methods under the Question class to "getX" and "getY" by returning tur3.xcor() and tur3.ycor() respectively. But this did not do anything except give me another error. Like I said, this code WORKED when it was just a turtle maze, but since adding tkinter, I have had to change a whole bunch of things.

import turtle
import tkinter
import math

# Create window and canvas using tkinter.
root = tkinter.Tk()
root.title("Language Labyrinth")
cv = tkinter.Canvas(root, width=600, height=600)
cv.pack()

# Create frame where button(s) will be.
frame = tkinter.Frame(root)
frame.pack()

# Create Pen class to draw the maze.
class Pen():
    def __init__(self):
        global tur
        global screen
        tur = turtle.RawTurtle(cv)
        screen = tur.getscreen()
        tur.shape("square")
        tur.color("white")
        screen.bgcolor("black")
        tur.penup()
        tur.speed(0)

# Create setup so the maze will be drawn.
    def setup(self, level):
        global tur, walls
        for y in range(len(level)):
            for x in range(len(level[y])):
                char = level[y][x]

                screenx = -288 + (x * 24)
                screeny = 288 - (y * 24)

                if char == "X":
                    tur.goto(screenx, screeny)
                    tur.stamp()

                    walls.append((screenx, screeny))

# Create player class to have a player.
class Player():
    def __init__(self):
        global tur2
        tur2 = turtle.RawTurtle(cv)
        tur2.shape("square")
        tur2.color("blue")
        tur2.penup()
        tur2.speed(0)

# Create setup to create the player on the screen.
    def setup2(self, level):
        global tur2
        for y in range(len(level)):
            for x in range(len(level[y])):
                char = level[y][x]

                screenx = -288 + (x * 24)
                screeny = 288 - (y * 24)

                if char == "P":
                    tur2.goto(screenx, screeny)

# Define a function that will allow player to move up.
    def up(self):
        global tur2, walls
        # Calculate the spot to move to.
        movetoX = tur2.xcor()
        movetoY = tur2.ycor() + 24

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            tur2.goto(movetoX, movetoY)

# Define a function that will allow player to move down.
    def down(self):
        global tur2, walls
        # Calculate the spot to move to.
        movetoX = tur2.xcor()
        movetoY = tur2.ycor() - 24

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            tur2.goto(movetoX, movetoY)

# Define a function that will allow player to move left.
    def left(self):
        global tur2, walls
        # Calculate the spot to move to.
        movetoX = tur2.xcor() - 24
        movetoY = tur2.ycor()

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            tur2.goto(movetoX, movetoY)

# Define a function that will allow player to move right.
    def right(self):
        global tur2, walls
        # Calculate the spot to move to.
        movetoX = tur2.xcor() + 24
        movetoY = tur2.ycor()

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            tur2.goto(movetoX, movetoY)

# Check if player touches the question.
    def collision(self, other):
        global tur2
        a = tur2.xcor() - other.xcor()
        b = tur2.ycor() - other.ycor()
        distance = math.sqrt((a ** 2) + (b ** 2))

        if distance < 5:
            return True
        else:
            return False

# Create Question class to create the "gold" in the game.
class Question():
    def __init__(self, x, y):
        global tur3
        tur3 = turtle.RawTurtle(cv)
        tur3.shape("circle")
        tur3.color("gold")
        tur3.penup()
        tur3.speed(0)
        tur3.goto(x, y)

    # Define function that will remove gold when collided with.
    def destroy(self):
        global tur3
        tur3.goto(2000, 2000)
        tur3.hideturtle()

# Create a levels list.
levels = [""]

# Define first level.
level_1 = [
"XXXXXXXXXXXXXXXXXXXXXXXXX",
"XP XXXXXXX          XXXXX",
"X  XXXXXXX  XXXXXX  XXXXX",
"X       XX  XXXXXX  XXXXX",
"X       XX  XXX        XX",
"XXXXXX  XX  XXX   Q    XX",
"XXXXXX  XX  XXXXXX  XXXXX",
"XXXXXX  XX    XXXX  XXXXX",
"X  XXX Q      XXXX  XXXXX",
"X  XXX  XXXXXXXXXXXXXXXXX",
"X         XXXXXXXXXXXXXXX",
"X     Q          XXXXXXXX",
"XXXXXXXXXXXX     XXXXX  X",
"XXXXXXXXXXXXXXX  XXXXX  X",
"XXX  XXXXXXXXXX         X",
"XXX               Q     X",
"XXX         XXXXXXXXXXXXX",
"XXXXXXXXXX  XXXXXXXXXXXXX",
"XXXXXXXXXX              X",
"XX   XXXXX        Q     X",
"XX   XXXXXXXXXXXXX  XXXXX",
"XX    XXXXXXXXXXXX  XXXXX",
"XX    Q     XXXX        X",
"XXXX                    X",
"XXXXXXXXXXXXXXXXXXXXXXXXX"
]

# Add questions list.
questions = []

# Add the level(s) to the levels list.
levels.append(level_1)

# Class instances.
pen = Pen()
player = Player()

# Wall coordinate list.
walls = []

# Define function to setup the "gold" in the game.
def setup3(level):
    for y in range(len(level)):
        for x in range(len(level[y])):
            char = level[y][x]

            screenx = -288 + (x * 24)
            screeny = 288 - (y * 24)

            if char == "Q":
                questions.append(Question(screenx, screeny))

#screen.onkeypress(player.up, "Up")
#screen.onkeypress(player.down, "Down")
#screen.onkeypress(player.left, "Left")
#screen.onkeypress(player.right, "Right")

# Creation of buttons that will allow player to move. (BIND ARROWS W/O BUTTONS??)
up = tkinter.Button(frame, text="Up", command=player.up)
up.bind("<Up>", player.up)
up.pack()
down = tkinter.Button(frame, text="Down", command=player.down)
down.bind("<Down>", player.down)
down.pack()
left = tkinter.Button(frame, text="Left", command=player.left)
left.bind("<Left>", player.left)
left.pack()
right = tkinter.Button(frame, text="Right", command=player.right)
right.bind("<Right>", player.right)
right.pack()

# Define a function for the quit button.
def quitPlaying():
    root.destroy()
    root.quit()

# Creation of quit button.
quitButton = tkinter.Button(frame, text="Quit", command=quitPlaying)
quitButton.pack()

# Game loop in regards to the gold. (Needs debugging)
while True:
    # Check for player collision with a question.
    # Iterate through the questions list.
    for question in questions:
        if player.collision(question):
            # Destroy the question.
            question.destroy()
            # Remove question from questions list.
            questions.remove(question)

    # Update screen.
    screen.update()

# Call main game loop.
tkinter.mainloop()

基本上,我希望当我移动金"海龟时,我希望它们消失,就像我收集它们一样.

Basically, I expect that when I move over the "gold" turtles, I want them to disappear as if I've collected them.

(对于移动,我希望使用箭头键而不是按钮进行移动,但同样,这是次要的.)

(And for the movement, I would expect to use the arrow keys for movement instead of the buttons, but again, this is a secondary thing.)

推荐答案

您当前的问题是:

if player.collision(question):

def collision(self, other):
    # ...
    a = tur2.xcor() - other.xcor()

您使用 question 调用 collision() 作为它的第二个参数,并且该函数在调用 .xcor()<时假定第二个参数是海龟/code> 就可以了.但它不是乌龟,它是一个问题实例,其中包含一只乌龟.

You call collision() with question as it's second argument and the function assumes that the second argument is a turtle when it invokes .xcor() on it. But it isn't a turtle, it's a Question instance that contains a turtle.

更大的问题是你的程序完全误解了类、实例和全局变量.考虑 Pen 类的 pen 实例——你创建它并忽略它,因为它的工作是由你创建的全局 tur 完成的副作用!这种事情在你的程序中反复出现.很明显你不理解 global 关键字,所以我建议你(重新)阅读一下.

The larger problem is that your program is a complete misunderstanding of classes, instances and globals. Consider the pen instance of the Pen class -- you create it and ignore it as it's work is done by the global tur you created as a side-effect! This sort of thing recurs throughout your program. And it's clear you don't understand the global keyword so I suggest your (re)read about that.

我已经在下面重新设计了您的程序,以修复我看到的许多(但不是全部)问题.类 PenPlayerQuestion 现在是 RawTurtle 的子类,而不是包含一个.并且没有通过副作用设置全局变量.当您到达时,您的黄金现在会消失,您可以使用箭头键(只需先点击窗口即可.)

I've reworked your program below to fix many, but not all, of the problems I saw. The classes Pen, Player, and Question are now subclasses of RawTurtle, rather than containing one. And no globals are set via side-effect. Your gold now disappears when you reach it and your can use the arrow keys (just click on the window first.)

from turtle import RawTurtle, TurtleScreen
import tkinter

# Create Pen class to draw the maze.
class Pen(RawTurtle):
    def __init__(self):
        super().__init__(screen, shape='square')
        self.speed('fastest')
        self.color('white')
        self.penup()

    # Create setup so the maze will be drawn.
    def setup(self, level):
        for y in range(len(level)):
            screen_y = 288 - (y * 24)

            for x in range(len(level[y])):
                if level[y][x] == 'X':
                    screen_x = (x * 24) - 288

                    self.goto(screen_x, screen_y)
                    self.stamp()

                    walls.append((screen_x, screen_y))

# Create player class to have a player.
class Player(RawTurtle):
    def __init__(self):
        super().__init__(screen, shape='square')
        self.speed('fastest')
        self.color('blue')
        self.penup()

    # Create setup to create the player on the screen.
    def setup(self, level):
        for y in range(len(level)):
            for x in range(len(level[y])):
                if level[y][x] == 'P':
                    screen_x = (x * 24) - 288
                    screen_y = 288 - (y * 24)

                    self.goto(screen_x, screen_y)

                    return

    # Define a function that will allow player to move up.
    def move_up(self):
        # Calculate the spot to move to.
        movetoX = self.xcor()
        movetoY = self.ycor() + 24

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            self.goto(movetoX, movetoY)

            gold_encounter()

    # Define a function that will allow player to move down.
    def move_down(self):
        # Calculate the spot to move to.
        movetoX = self.xcor()
        movetoY = self.ycor() - 24

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            self.goto(movetoX, movetoY)

            gold_encounter()

    # Define a function that will allow player to move left.
    def move_left(self):
        # Calculate the spot to move to.
        movetoX = self.xcor() - 24
        movetoY = self.ycor()

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            self.goto(movetoX, movetoY)

            gold_encounter()

    # Define a function that will allow player to move right.
    def move_right(self):
        # Calculate the spot to move to.
        movetoX = self.xcor() + 24
        movetoY = self.ycor()

        # Check if the space has a wall.
        if (movetoX, movetoY) not in walls:
            self.goto(movetoX, movetoY)

            gold_encounter()

    # Check if player touches the question.
    def collision(self, other):
        return self.distance(other) < 5

# Create Question class to create the "gold" in the game.
class Question(RawTurtle):
    def __init__(self, x, y):
        super().__init__(screen, shape='circle', visible=False)

        self.speed('fastest')
        self.color('gold')
        self.penup()
        self.goto(x, y)
        self.showturtle()

    # Define function that will remove gold when collided with.
    def destroy(self):
        self.hideturtle()

# Define function to setup the "gold" in the game.
def setup(level):
    for y in range(len(level)):
        for x in range(len(level[y])):
            char = level[y][x]

            screen_x = -288 + (x * 24)
            screen_y = 288 - (y * 24)

            if char == 'Q':
                questions.append(Question(screen_x, screen_y))

# Define a function for the quit button.
def quitPlaying():
    root.destroy()
    root.quit()

# Game loop in regards to the gold.
def gold_encounter():
    # Check for player collision with a question.
    # Iterate through the questions list.
    for question in questions:
        if player.collision(question):
            # Destroy the question.
            question.destroy()
            # Remove question from questions list.
            questions.remove(question)

# Create window and canvas using tkinter.
root = tkinter.Tk()
root.title("Language Labyrinth")

canvas = tkinter.Canvas(root, width=600, height=600)
canvas.pack()

screen = TurtleScreen(canvas)
screen.bgcolor('black')

# Create frame where button(s) will be.
frame = tkinter.Frame(root)
frame.pack()

# Add questions list.
questions = []

# Wall coordinate list.
walls = []

# Create a levels list.
levels = []

# Define first level.
level_1 = [
"XXXXXXXXXXXXXXXXXXXXXXXXX",
"XP XXXXXXX          XXXXX",
"X  XXXXXXX  XXXXXX  XXXXX",
"X       XX  XXXXXX  XXXXX",
"X       XX  XXX        XX",
"XXXXXX  XX  XXX   Q    XX",
"XXXXXX  XX  XXXXXX  XXXXX",
"XXXXXX  XX    XXXX  XXXXX",
"X  XXX Q      XXXX  XXXXX",
"X  XXX  XXXXXXXXXXXXXXXXX",
"X         XXXXXXXXXXXXXXX",
"X     Q          XXXXXXXX",
"XXXXXXXXXXXX     XXXXX  X",
"XXXXXXXXXXXXXXX  XXXXX  X",
"XXX  XXXXXXXXXX         X",
"XXX               Q     X",
"XXX         XXXXXXXXXXXXX",
"XXXXXXXXXX  XXXXXXXXXXXXX",
"XXXXXXXXXX              X",
"XX   XXXXX        Q     X",
"XX   XXXXXXXXXXXXX  XXXXX",
"XX    XXXXXXXXXXXX  XXXXX",
"XX    Q     XXXX        X",
"XXXX                    X",
"XXXXXXXXXXXXXXXXXXXXXXXXX"
]

# Add the level(s) to the levels list.
levels.append(level_1)

# Class instances.
pen = Pen()
pen.setup(level_1)
player = Player()
player.setup(level_1)
setup(level_1)

# Creation of quit button.
quitButton = tkinter.Button(frame, text='Quit', command=quitPlaying)
quitButton.pack()

screen.onkeypress(player.move_up, 'Up')
screen.onkeypress(player.move_down, 'Down')
screen.onkeypress(player.move_left, 'Left')
screen.onkeypress(player.move_right, 'Right')

screen.listen()

# Call main game loop.
screen.mainloop()

您似乎从 嵌入 tkinter 中的海龟中得到的很少,而这可能是一个独立海龟程序的更干净的选择.而且由于您的各种 setup*() 方法/函数从未被调用,您发布的代码实际上并没有做任何事情.

You seem to get very little out of embedding turtle in tkinter and this might have been cleaner left a standalone turtle program. And since your various setup*() methods/functions never got called, your posted code doesn't really do anything.

这篇关于获取“宝物"坐标(海龟)在使用 Python tkinter 和海龟的迷宫游戏中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆