Этот рецепт называется «Обнаружение столкновений между объектами» в «Tkinter GUI Разработка приложений - 2018». Код работает идеально так, как вам нужно: вы можете переместить больший прямоугольник, нажимая клавиши со стрелками, в то время как четыре меньших сохраняют положение c около углов. Как только большее прикосновение к любому из меньших, последнее изменит цвет с зеленого на желтый. Однако, поскольку в обращении precess_movements есть два последовательных цикла for, я полагаю, что меньший прямоугольник, к которому прикоснулись, должен часто менять свой цвет, что противоречит наблюдениям во время работы. Чтобы убедиться в правильности моего анализа, я поместил «print (« item: »+ str (item))» в первый l oop, чтобы отслеживать ситуацию, и оказалось, что в первом «for» l oop, все четыре меньших прямоугольника снова становятся зелеными, когда один из них сталкивается с большим движущимся прямоугольником. Это очевидно странно. Может ли кто-нибудь пролить свет на это явление? Спасибо вот код:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Detecting collisions between items")
self.canvas = tk.Canvas(self, bg="white")
self.canvas.pack()
self.update()
self.width = w = self.canvas.winfo_width()
self.height = h = self.canvas.winfo_height()
pos = (w / 2 - 15, h / 2 - 15, w / 2 + 15, h / 2 + 15)
self.item = self.canvas.create_rectangle(*pos, fill="blue")
positions = [(60, 60), (w - 60, 60), (60, h - 60), (w - 60, h - 60)]
for x, y in positions:
self.canvas.create_rectangle(x - 10, y - 10, x + 10, y + 10,
fill="green")
self.pressed_keys = {}
self.bind("<KeyPress>", self.key_press)
self.bind("<KeyRelease>", self.key_release)
self.process_movements()
def key_press(self, event):
self.pressed_keys[event.keysym] = True
def key_release(self, event):
self.pressed_keys.pop(event.keysym, None)
def process_movements(self):
all_items = self.canvas.find_all()
for item in filter(lambda i: i is not self.item, all_items):
self.canvas.itemconfig(item, fill="green")
print("item:" + str(item)) # monitoring items which have been turned green
x0, y0, x1, y1 = self.canvas.coords(self.item)
items = self.canvas.find_overlapping(x0, y0, x1, y1)
for item in filter(lambda i: i is not self.item, items):
self.canvas.itemconfig(item, fill="yellow")
off_x, off_y = 0, 0
speed = 3
if 'Right' in self.pressed_keys:
off_x += speed
if 'Left' in self.pressed_keys:
off_x -= speed
if 'Down' in self.pressed_keys:
off_y += speed
if 'Up' in self.pressed_keys:
off_y -= speed
pos_x = x0 + (x1 - x0) / 2 + off_x
pos_y = y0 + (y1 - y0) / 2 + off_y
if 0 <= pos_x <= self.width and 0 <= pos_y <= self.height:
self.canvas.move(self.item, off_x, off_y)
self.after(100, self.process_movements)
if __name__ == "__main__":
app = App()
app.mainloop()