如何实现类的值与关联的独立海龟?

0 投票
1 回答
38 浏览
提问于 2025-04-12 16:42

基本上,我正在尝试编写一个视频中的项目,链接在这里:https://www.youtube.com/watch?v=jAMegKEetx4&t=338s。这个项目是一个打字游戏,单词从左边出现,向右移动,你需要把它们打出来,这样它们就会消失。我正在用Python的turtle模块来编写这个项目,但现在在为每个单词创建turtle“写字者”时遇到了困难。

这个类有一个“记忆”列表,用来把输入的单词拆分成字母,这样可以更方便地检查第一个字母。如果我在__innit__部分(我想这叫构造函数)里创建写字的turtle,就会出现以下错误:

     self.turtle.write("".join(self.memory))
TypeError: RawTurtle.write() missing 1 required positional argument: 'arg'".
                self.turtle.write("".join(self.memory))
                self.turtle.goto(Word.x, self.y)
                self.Word.x += 1
                self.turtle.clear()

如果我尝试在构造函数外面(但仍在类里面)创建turtle,所有的单词都会被同一个turtle写,这样就只能同时写一个单词,然后另一个单词又会出现,来回切换。请问我该怎么解决这个问题?

应要求,这里有一段最小的代码来重现这个问题:

import turtle
import random
wn = turtle.Screen()
class Word():
    turtle = turtle.Turtle
    def __init__(self,word):
        self.word = word
        self.ycor = random.randint(-100,100)
        self.xcor = 0
    def write(self):
        self.xcor += 10
        turtle.goto(self.xcor,self.ycor)
        turtle.write(self.word)
word1 = Word("Banana")
word2 = Word("Test")
while True:
    word1.write()
    word2.write()
    wn.update()

在这里,一个turtle尝试写这个类的每个单词,但每个创建的对象应该有自己的turtle来写出它的单词。如果我尝试创建一个self.turtle,并把函数改成:

    def write(self):
        self.xcor += 10
        self.turtle.goto(self.xcor,self.ycor)
        self.turtle.write(self.word)

我就会得到以下错误:AttributeError: 'int' object has no attribute '_goto'。我该如何修改,让每个创建的对象都有自己的turtle来写单词,并且能够独立行动,而不是让一个turtle去写所有的单词呢?

1 个回答

0

下面的代码解决了你提到的问题,并且实现了你想要的视觉效果。同时,它也考虑到了你可能会遇到的下一个问题:turtle可以设置一个处理器来响应你输入的任何键,但它不知道是哪个键触发的。因为你需要知道这个键,我在这里提供了一个修改过的turtle事件处理器,它会把你输入的键返回给你:

from turtle import Screen, Turtle
from functools import partial
from random import randint

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

class Word():
    words = {}

    def __init__(self, string):
        self.string = string

        self.turtle = Turtle()
        self.turtle.hideturtle()
        self.turtle.penup()

        ycor = randint(-200, 200)
        xcor = -200
        self.turtle.goto(xcor, ycor)

        self.words[self.string] = self

    def write(self):
        self.turtle.forward(10)
        self.turtle.clear()
        self.turtle.write(self.string, font=FONT)
        screen.update()

def _onkeypress(self, fun, key=None):
    if fun is None:
        if key is None:
            self.cv.unbind("<KeyPress>", None)
        else:
            self.cv.unbind("<KeyPress-%s>" % key, None)
    elif key is None:
        def eventfun(event):
            fun(event.char)
        self.cv.bind("<KeyPress>", eventfun)
    else:
        def eventfun(event):
            fun()
        self.cv.bind("<KeyPress-%s>" % key, eventfun)

def letter(character):
    string = None
    words = Word.words

    for candidate in Word.words:
        if candidate.startswith(character):
            string = candidate
            break
    if string:
        words[string].turtle.clear()
        del words[string]

def demonstrate():
    values = Word.words.values()

    for word in values:
        word.write()

    screen.ontimer(demonstrate, 100)

screen = Screen()
screen._onkeypress = partial(_onkeypress, screen)
screen.tracer(False)

screen.onkeypress(letter)
screen.listen()

for string in ("banana", "test", "gyro"):
    Word(string)

demonstrate()

screen.exitonclick()

如果你输入任何单词的第一个字母,这些单词就会从屏幕上消失。你需要把这个功能扩展到逐字消除单词的效果。而且,我建议你改进一下,重复使用turtle,因为它们是全局的,不会被垃圾回收。

撰写回答