通过多线程获得流畅的运动 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()
我并不是说线程可以解决您的问题,也不是说线程不会随着您添加更多敌人而变慢。另一种方法可能是将敌人更多地视为一个块,而不是完整的个体,并在图形库中使用计时器事件而不是线程。
这是我的第一个问题!
我用 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()
我并不是说线程可以解决您的问题,也不是说线程不会随着您添加更多敌人而变慢。另一种方法可能是将敌人更多地视为一个块,而不是完整的个体,并在图形库中使用计时器事件而不是线程。