使用turtle模块异步移动海龟

问题描述 投票:0回答:1

我想使用海龟模块创建一个运行的机器人,一段时间后,创建另一个在第一个机器人之后运行,依此类推。基本上:

  • 创建第一个机器人
  • 第一个机器人移动
  • 当第一个机器人仍在移动时,创建第二个机器人
  • 第二个机器人动作

等等。

我有一个名为 Robot() 的类:

class Robot(Turtle):
    def __init__(self):
        super().__init__()
        self.create_car()

它有两个方法:create_robot(),它简单地告诉机器人应该是什么样子以及它的位置+方向:

    def create_robot(self):
        self.shape('square')
        self.setheading(180)
        self.penup()
        random_y = random.choice(range(-250, 250))
        self.goto(280, random_y)

另一种方法是:

def movement(self):
   self.forward(10)

之后,这个 while 循环实际上使机器人连续移动:

robot = Robot()
while game_is_on:
    time.sleep(0.1)
    screen.update()
    screen.ontimer(robot.movement(), t=10)

这只会创建一个可以移动并正常工作的机器人。

现在,我想通过使用空列表或不同的方式创建第二个机器人,但似乎:

  • 更多机器人被创建并且它们同步移动
  • 在不同位置创建了更多机器人,但没有人移动
  • 创建了更多机器人,但只有一个动作(我假设创建了第一个机器人)

为了创建多个机器人,我使用 for 循环:

for i in range(3):
    robot = Robot()

如果我在 while 循环中添加 robots.create_robot(),它永远不会到达 robots.movement()

python class oop turtle-graphics python-turtle
1个回答
0
投票

让我们尝试一个基于您的代码的简单示例,该示例创建一小组彼此远离的机器人,并偶尔在自己的图像中生成新机器人:

from turtle import Screen, Turtle
from random import randrange

class Robot(Turtle):
    BODIES = ('circle', 'triangle', 'square', 'turtle')

    def __init__(self, body, origin=(0, 0)):
        super().__init__(body, visible=False)
        self.create_robot(origin)

    def create_robot(self, origin):
        self.setheading(randrange(360))
        self.penup()
        self.goto(origin)
        self.showturtle()
        self.movement()

    def spawn(self):
        Robot(self.shape(), self.position())

    def movement(self):
        self.forward(1)
        screen.update()

        if randrange(1000) < 3:  # conditions are right to spawn
            self.spawn()

        width, height = screen.window_width(), screen.window_height()
        x, y = self.position()

        if -width//2 < x < width//2 and -height//2 < y < height//2:
            screen.ontimer(self.movement, 33)
        else:
            self.hideturtle()

screen = Screen()
screen.tracer(False)

for body in Robot.BODIES:
    Robot(body)

screen.exitonclick()

当然,这个简单的例子浪费了未被垃圾收集的全局海龟对象。在真实的程序中,我们会在它们停用时保存这些列表,并在生成新列表时重用旧列表(如果可用)。

© www.soinside.com 2019 - 2024. All rights reserved.