通过多线程 Python 海龟图形获得平滑运动 [英] Get smooth motion by multi-threading Python turtle graphics

查看:46
本文介绍了通过多线程 Python 海龟图形获得平滑运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一个问题!

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

I finished making a simple space invaders game in Python turtle graphics and noticed an annoying problem: the more objects I have on my screen, the slower the program runs.

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

My friend told me that I need to use multi-threading so that all the commands will run concurrently, and that way, the game will run smooth.

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

I added only the relevent code for my problem which is to move two enemy invaders from side to side of the screen. I think this will be enough to help me through this.

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

With this code, the enemies get stuck in their own place a couple of miliseconds every now and then. It's very noticable, what should I do?

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 图形.因此,我开发了这种方法,它允许辅助线程计算有关其海龟的信息,但最终将图形命令传递给主线程:

I'm surprised your code works at all -- when I finish it off and run it, only one turtle moves. Perhaps it's a difference between Windows and Unix or some such. Regardless, my belief has been that you can't do tkinter/turtle graphics in any thread but the main one. So, I've developed this approach which allows the secondary threads to calculate things about their turtle but ultimately pass the graphics command onto the primary thread:

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

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

I'm not saying that threads are the answer to your problem, nor that they won't slow down as you add more enemies. Another approach might be to treat the enemies more as a block, not complete individuals, and use timer events within the graphics library instead of threads.

这篇关于通过多线程 Python 海龟图形获得平滑运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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