python - Tkinter 线程使用键盘事件为两组对象设置动画
问题描述
我正在设计一个类似于水果忍者的游戏的主要游戏区域。我试图让激光动画效果在他用户按下时显示,spacebar但一旦玩家放开它就会消失。
基本上,激光只会在用户按住空格键时出现。水果会被破坏,而分数会加分。但现在我只是在研究激光效果。该create_fruit()
函数和move_fruit()
函数旨在使水果随机生成并落在屏幕上。他们在没有激光动画的情况下工作得非常顺利。但是一旦添加了激光动画,整个东西就变得非常长,激光只会动画大约 0.5 秒然后冻结。
我试图将它添加到不同的线程,但结果是相同的。错误信息:RuntimeError: main thread is not in main loop
。此外,由于极其滞后的效果和运行时错误,键盘事件基本上根本不起作用。
这是我的代码:
from tkinter import *
import time
from random import randint
from PIL import Image, ImageTk
from threading import *
#make the fruits appear on the screen
def create_fruits():
global fruits_list
#choose random fruits with different possibilities
which_fruit = randint(1,10)
this_fruit = ImageTk.PhotoImage(Image.open(fruit_dic[which_fruit]))
#randomly generate which colum (four in total) the fruits will be
choose_position = randint (1,4)
x_position = x_positions_dic[choose_position] # choose the position from dict
my_photo = canvas.create_image(x_position, 80, image = this_fruit, anchor = 's')
#append it to the list(image_if, x position, image)
fruits_list.append([my_photo, randint(5,10), this_fruit])
#repeatedly generate fruit images every 0.25 second (change the density of the fruit)
root.after(250,create_fruits)
def move_fruits():
#iterate through the fruit list
for fruit in fruits_list:
#call the move function, move the fruit
canvas.move(fruit[0], 0, fruit[1])
#if the fruit gets outside of the canvas, delete it on the canvas and in the list
if canvas.bbox(fruit[0])[3] >= canvas.winfo_height()+200:
canvas.delete(fruit[0])
fruits_list.remove(fruit)
root.after(5, move_fruits) # calls the move_fruits after every 5 seconds (change the speed of the fruit)
def laser_threading(event = None):
# Call work function
t1=Thread(target=laser)
t1.start()
def laser():
# create a list of image objects
for imagefile in laser_list:
global laser_photo
laser_photo = PhotoImage(file=imagefile)
laser_giflist.append(laser_photo)
# loop through the gif image objects for a while
for k in range(0, 1000):
for gif in laser_giflist:
#place each frame on the canvas
canvas.create_image(400, 600, image=gif)
canvas.update()
time.sleep(0.1)
#create game area
root = Tk ()
canvas = Canvas (root, height = 1200, width = 800, bg = 'black')
canvas.pack()
fruits_list = []
laser_list = ["laser_1.png","laser_2.png","laser_3.png",
"laser_4.png"]
laser_giflist = []
x_positions_dic = {1: 160, 2: 287.5, 3: 462.5, 4:637.5}
fruit_dic = {
1: r"bomb.png" ,
2: r"apple.png" ,
3: r"pear.png",
4: r"blueberry.png",
5: r"banana.png",
6: r"cherry.png",
7: r"mango.png",
8: r"lemon.png",
9: r"watermelon.png",
10: r"bomb.png",
} # images path
create_fruits()
move_fruits()
root.bind("<space>", laser_threading)
mainloop()
解决方案
推荐阅读
- react-native - 反应原生 Redux
- flutter - Flutter - OneSignal - setNotificationOpenedHandler - OpenPage
- python - 无法使用 python 打印 API 响应的输出
- javascript - 如何生成 HTML 文档 Deno
- python - 如何隐藏 QFileSystemModel 上的文件扩展名
- node.js - 如果未找到 Id,Mongoose findByIdAndUpdate 不会返回错误
- rust - 如何制作递归宏来分解此代码?
- vb.net - 如何从 VB .Net 表单应用程序访问 Google Datastore LocalStructuredProperty?VB 将其视为一个 blob
- azure - Azure VMSS 缩减策略不允许我为缩减规则设置超过 60 分钟的冷却时间
- python - 在 python/javascript/shell 中打开带有 Windows 64 位附件的 Outlook