You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter矩形碰撞检测问题:移动红矩形时黑矩形未触发删除

Tkinter矩形碰撞检测修复方案

我正在做课程作业,用Tkinter写对象碰撞检测(不能用Pygame)。创建了红、黑两个矩形,移动红矩形时,希望两者重叠就删除黑矩形,但实际重叠时黑矩形没被删除,求修复方法。

原代码

import tkinter as tk 
from tkinter import *

window = Tk()
window.geometry("1366x768")
canvas = tk.Canvas(window, width = 1300, height = 700)

rec1 = canvas.create_rectangle(100, 100, 150, 150, fill = "black") #black rectangle
mover = canvas.create_rectangle(400, 400, 450, 450, fill = "red", outline = "red")  #red moving rectangle

canvas.pack() 

def left(event):
    x = -10
    y = 0 
    canvas.move(mover, x, y)
    
def right(event):
    x = 10
    y = 0 
    canvas.move(mover, x, y)

def up (event):
    x = 0
    y = -10 
    canvas.move(mover, x, y)

def down(event):
    x = 0
    y = 10 
    canvas.move(mover, x, y)

window.bind("<Left>", left)
window.bind("<Right>", right)
window.bind("<Up>", up )
window.bind("<Down>", down)

a = canvas.bbox(1) # coordinates of the black rectangle
b = canvas.bbox(2) # coordinates of the red, moving rectangle

if b[0] in range(a[0],a[2]) or b[2] in range(a[0],a[2]) and b[1] in range(a[1],a[3]) or b[3] in range(a[1],a[3]):
    canvas.delete(rec1)  #if they overlap, then delete the static black rectangle

window.mainloop()

问题根源

  1. 碰撞检测仅执行一次:碰撞判断代码只在程序启动时运行了一次,此时两个矩形不重叠,后续移动红矩形时不会再触发检测,因此不会删除黑矩形。
  2. 碰撞逻辑错误:
    • 使用range(a[0],a[2])判断坐标区间存在缺陷,range仅处理整数,且逻辑上不符合矩形重叠的判断逻辑。
    • 逻辑运算符优先级混乱,and优先级高于or,导致判断条件不符合实际重叠场景。
  3. 依赖创建顺序获取边界:用canvas.bbox(1)和bbox(2)依赖矩形创建顺序,直接使用变量rec1和mover更可靠。

修复步骤

  1. 将碰撞检测嵌入移动函数:每次移动红矩形后立即执行碰撞检测。
  2. 修正碰撞判断逻辑:矩形重叠的正确判断是:红矩形左边界 < 黑矩形右边界,且红矩形右边界 > 黑矩形左边界;同时红矩形上边界 < 黑矩形下边界,且红矩形下边界 > 黑矩形上边界。
  3. 通过变量获取边界:直接用canvas.bbox(rec1)和canvas.bbox(mover)获取两个矩形的坐标。

修复后的完整代码

import tkinter as tk 
from tkinter import *

window = Tk()
window.geometry("1366x768")
canvas = tk.Canvas(window, width = 1300, height = 700)

rec1 = canvas.create_rectangle(100, 100, 150, 150, fill = "black") # 黑色矩形
mover = canvas.create_rectangle(400, 400, 450, 450, fill = "red", outline = "red")  # 可移动红色矩形

canvas.pack() 

def check_collision():
    # 获取矩形边界坐标,格式为(left, top, right, bottom)
    black_bbox = canvas.bbox(rec1)
    red_bbox = canvas.bbox(mover)
    
    if black_bbox and red_bbox:  # 确保两个矩形都存在
        # 判断x轴和y轴是否同时存在重叠区域
        overlap_x = red_bbox[0] < black_bbox[2] and red_bbox[2] > black_bbox[0]
        overlap_y = red_bbox[1] < black_bbox[3] and red_bbox[3] > black_bbox[1]
        if overlap_x and overlap_y:
            canvas.delete(rec1)

def left(event):
    x = -10
    y = 0 
    canvas.move(mover, x, y)
    check_collision()  # 移动后触发碰撞检测
    
def right(event):
    x = 10
    y = 0 
    canvas.move(mover, x, y)
    check_collision()

def up (event):
    x = 0
    y = -10 
    canvas.move(mover, x, y)
    check_collision()

def down(event):
    x = 0
    y = 10 
    canvas.move(mover, x, y)
    check_collision()

window.bind("<Left>", left)
window.bind("<Right>", right)
window.bind("<Up>", up )
window.bind("<Down>", down)

window.mainloop()

额外说明

  • 新增check_collision函数统一处理碰撞检测,避免重复代码,提升可读性。
  • 添加if black_bbox and red_bbox判断,防止黑矩形被删除后调用canvas.bbox(rec1)返回None引发报错。

内容的提问来源于stack exchange,提问作者sm2002

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 11:39:47