[英]How do i move multiple objects at the same time but every object by different distance in tkinter python?
I have a game that generates multiple objects and which object comes to other side of canvas wins.我有一个生成多个对象的游戏,object 来到 canvas 的另一边获胜。 When you press button every object moves a different random distance forward.
当您按下按钮时,每 object 向前移动不同的随机距离。 The problem is that firts object moves the least and last object moves the most.
问题是第一个 object 移动最少,最后一个 object 移动最多。 So last object always wins.
所以最后一个 object 总是赢。 How do i made it that random object will win and not always the last one.
我如何做到随机 object 会获胜而不总是最后一个。
import tkinter
import random
canvas=tkinter.Canvas(width=400, height=400)
canvas.pack()
label=tkinter.Label(text='set amout of cars')
label.pack()
entry=tkinter.Entry()
entry.pack()
def car():
global move
move=0
canvas.delete('all')
p=int(entry.get())
for i in range(p):
canvas.create_rectangle(20,20+i*20,40,30+i*20, fill='coral')
move=0
def race():
global move
canvas.delete('all')
p=int(entry.get())
for i in range(p):
rand=random.randint(5,20)
move=move+rand
canvas.create_rectangle(20+move,20+i*20,40+move,30+i*20, fill='coral')
button=tkinter.Button(text='start', command=car)
button.pack()
button2=tkinter.Button(text='forward', command=race)
button2.pack()
As described in the comments, every object shares the same move
variable, so each object starts where the last one stopped.如评论中所述,每个 object 共享相同的
move
变量,因此每个 object 从最后一个停止的地方开始。
The better solution is to call the move
method on the canvas for each of the objects.更好的解决方案是为每个对象调用 canvas 上的
move
方法。 You can either save a list of objects or just ask the canvas to give you the objects.您可以保存对象列表,也可以要求 canvas 为您提供对象。 You can then use
randint
to decide how much to move each item.然后,您可以使用
randint
来决定每个项目移动多少。
The race
function would look something like this: race
function 看起来像这样:
def race():
for car in canvas.find("all"):
delta_x = random.randint(5,20)
delta_y = 0
canvas.move(car, delta_x, delta_y)
All your objects use the same variable move
- so in every execution of race
they use the same position. But in every loop you add new values to move
- so first object use distance move+rand1
, second move+rand1+rand2
, third move+rand1+rand2+rand3
, etc - and this makes problem.您的所有对象都使用相同的变量
move
- 因此在每次执行race
时,它们都使用相同的 position。但是在每个循环中,您都添加新的值来move
- 所以首先 object 使用 distance move+rand1
,第二个move+rand1+rand2
,第三个move+rand1+rand2+rand3
等 - 这会产生问题。
Every object should have own variable with position.每个 object 都应该有自己的变量 position。
So it would need to use list with positions.所以它需要使用带位置的列表。
Or better create object only once and get ID
或者最好只创建一次 object 并获取
ID
car_id = canvas.create_rectangle(...)
and later use ID
to move this object然后用
ID
移动这个object
canvas.move(car_id, ...)
and this way every car will use own position.这样每辆车都会使用自己的 position。
And of course it also need to use list to keep all IDs
当然还需要用list来保存所有的
IDs
def restart():
canvas.delete('all')
all_cars.clear()
number = int(entry.get())
for i in range(number):
car_id = canvas.create_rectangle(20, 20+i*20, 40, 30+i*20, fill='coral')
all_cars.append( car_id )
def race():
for car_id in all_cars:
distance_x = random.randint(5,20)
distance_y = 0
canvas.move(car_id, distance_x, distance_y)
# --- main ---
all_cars = []
EDIT:编辑:
Full working code:完整的工作代码:
I also used我也用过
after(100, race)
- so it automatically repeate function after 100ms and you don't have to click button race
again and again. after(100, race)
- 所以它会在 100 毫秒后自动重复 function,你不必一次又一次地点击按钮race
。
canvas.corrds()
to get current position and check if it end of race. canvas.corrds()
获取当前 position 并检查它是否结束比赛。
create_line
to show finish line create_line
显示终点线
import tkinter as tk
import random
# --- functions ---
def restart():
canvas.delete('all')
all_cars.clear()
number = int(entry.get())
for i in range(number):
car_id = canvas.create_rectangle(20, 20+i*20, 40, 30+i*20, fill='coral')
all_cars.append( car_id )
# finish line
canvas.create_line(360, 10, 360, 30+(number-1)*20 + 10, fill='red')
def race():
winner = False
for car_id in all_cars:
distance_x = random.randint(5, 20)
distance_y = 0
canvas.move(car_id, distance_x, distance_y)
x1, y1, x2, y2 = canvas.coords(car_id)
if x1 >= 360:
winner = True
canvas.moveto(car_id, 360, y1-1)
canvas.itemconfig(car_id, fill='green')
if not winner:
root.after(100, race)
# --- main ---
all_cars = [] # list for all IDs
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=400)
canvas.pack()
label = tk.Label(root, text='set amout of cars')
label.pack()
entry = tk.Entry(root)
entry.pack()
button = tk.Button(root, text='start', command=restart)
button.pack()
button2 = tk.Button(root, text='forward', command=race)
button2.pack()
root.mainloop()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.