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

时间:2018-10-31 19:11:10

标签: python multithreading turtle-graphics

这是我的第一个问题!

我用Python乌龟图形制作了一个简单的太空入侵者游戏,发现一个烦人的问题:我在屏幕上拥有的对象越多,程序运行的速度就越慢。

我的朋友告诉我,我需要使用多线程,以便所有命令可以同时运行,这样游戏才能流畅运行。

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

使用此代码,敌人会时不时地停留在自己的位置几毫秒。非常值得注意,我该怎么办?

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()

1 个答案:

答案 0 :(得分:1)

我很惊讶您的代码完全起作用-当我完成并运行它时,只有一只乌龟移动。也许这是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()

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