通过多线程获得流畅的运动 Python 海龟图形

Get smooth motion by multi-threading Python turtle graphics

这是我的第一个问题!

我用 Python 海龟图形完成了一个简单的 space 入侵者游戏并注意到一个烦人的问题:屏幕上的对象越多,程序越慢 运行s .

我的朋友告诉我,我需要使用多线程,这样所有命令都会 运行 并发,这样游戏就会 运行 流畅。

我只添加了我的问题的相关代码,即将两个敌方入侵者从屏幕的一侧移动到另一侧。我认为这足以帮助我解决这个问题。

使用此代码,敌人时不时会卡在自己的位置几毫秒。很明显,我该怎么办?

one_enemy = turtle.Turtle()
one_enemy.shape("Invader.gif")
one_enemy.penup()
one_enemy.speed(0)
x = random.randint(-200, 200)
y = random.randint(100, 200)
one_enemy.setposition(x, y)

two_enemy = turtle.Turtle()
two_enemy.shape("Invader.gif")
two_enemy.penup()
two_enemy.speed(0)
x = random.randint(-200, 200)
y = random.randint(100, 200)
two_enemy.setposition(x, y)

def move_enemy_horizontally(enemy, direction):
    while True:
        while direction == "right":
            x = enemy.xcor()
            x += enemyspeed
            enemy.setx(x)
            if enemy.xcor() > 288:
                y = enemy.ycor()
                y -= 50
                enemy.sety(y)
                direction = "left"
        while direction == "left":
            x = enemy.xcor()
            x -= enemyspeed
            enemy.setx(x)
            if enemy.xcor() < -288:
                y = enemy.ycor()
                y -= 50
                enemy.sety(y)
                direction = "right"

t = threading.Thread(target=move_enemy_horizontally, args=(one_enemy, direction))
t.start()
t2 = threading.Thread(target=move_enemy_horizontally, args=(two_enemy, direction))
t2.start()

令我惊讶的是您的代码竟然能正常工作 -- 当我完成它并 运行 它时,只有一只乌龟在移动。也许这是 Windows 和 Unix 或类似系统之间的区别。无论如何,我一直认为除了主线程之外,您不能在任何线程中制作 tkinter/turtle 图形。所以,我开发了这种方法,它允许辅助线程计算有关它们的海龟的事情,但最终将图形命令传递给主线程:

from turtle import Screen, Turtle
from random import randint
from threading import Thread, active_count
from queue import Queue

QUEUE_SIZE = 1
ENEMY_SPEED = 3

def move_enemy_horizontally(enemy, direction):
    x, y = enemy.position()

    while True:
        while direction == "right":

            if x > 288:
                y -= 50
                actions.put((enemy.sety, y))
                direction = "left"
            else:
                x += ENEMY_SPEED
                actions.put((enemy.setx, x))

        while direction == "left":
            if x < -288:
                y -= 50
                actions.put((enemy.sety, y))
                direction = "right"
            else:
                x -= ENEMY_SPEED
                actions.put((enemy.setx, x))

def process_queue():
    while not actions.empty():
        action, argument = actions.get()
        action(argument)

    if active_count() > 1:
        screen.ontimer(process_queue, 100)

actions = Queue(QUEUE_SIZE)

x, y = randint(-200, 200), randint(100, 200)

direction = "right"

for dy in range(2):
    for dx in range(2):
        enemy = Turtle("turtle", visible=False)
        enemy.speed('fastest')
        enemy.setheading(270)
        enemy.penup()
        enemy.setposition(x + dx * 60, y + dy * 100)
        enemy.showturtle()

        Thread(target=move_enemy_horizontally, args=(enemy, direction), daemon=True).start()

    direction = ["left", "right"][direction == "left"]

screen = Screen()

process_queue()

screen.mainloop()

我并不是说线程可以解决您的问题,也不是说线程不会随着您添加更多敌人而变慢。另一种方法可能是将敌人更多地视为一个块,而不是完整的个体,并在图形库中使用计时器事件而不是线程。