Python Canvas获取方块对象bbox返回None,2D Minecraft游戏设置洞穴背景报错
问题根因
你遇到的bbox返回None有两个核心原因:
- 参数类型错误:Tkinter Canvas的
bbox()、coords()方法只接受Canvas自身创建元素时返回的整数ID作为参数,你传入自定义的Block类实例,Canvas无法识别,自然返回None。 - 执行顺序错误:你当前的代码流程中,
draw_current_pos只创建了Block实例、存入列表,没有将方块对应的图像实际绘制到Canvas上。在绘制之前调用bbox查询不存在的元素,必然返回None。
修复方案
第一步:修改Block类,存储Canvas元素ID
在Block类的初始化逻辑中,绘制图像到Canvas后,将返回的ID保存为实例属性,示例如下:
class Block: def __init__(self, x, y, parent, block_type): # 保留你原有的初始化逻辑 # 绘制图像到canvas,保存返回的元素ID self.grid_x = x self.grid_y = y self.image_id = parent.canvas.create_image(x*16, y*16, image=self.image, anchor="nw") # 上面的16是方块像素大小,按你实际设定的值修改 # 新增方法返回元素ID def get_image_id(self): return self.image_id
第二步:调整执行顺序,先绘制所有方块再计算背景位置
你的camera函数需要保证方块绘制完成后再计算背景高度,调整后逻辑如下:
def camera(self): # 删除旧元素逻辑和原有一致 for i in self.block_sprites: self.canvas.delete(i.get_image()) for i in self.sprites: self.canvas.delete(i) # 第一步:创建Block实例,此时对应图像会被绘制到Canvas上 self.draw_current_pos() # 第二步:再计算草地方块高度、绘制背景 self.draw_background()
第三步:修改draw_background的查询逻辑
def draw_background(self): grass_y = 1000 test_for_grass = False for block in self.block_sprites: if block.get_type() == 1: block_id = block.get_image_id() block_bbox = self.canvas.bbox(block_id) # 增加非空判断避免异常 if block_bbox and block_bbox[1] > grass_y: grass_y = self.canvas.coords(block_id)[1] test_for_grass = True if not test_for_grass and self.posy < 30: grass_y = 1000 - grass_y cave = self.canvas.create_image(0, grass_y, image=self.cavebg, anchor="nw") self.sprites.append(cave)
可选性能优化
你完全不需要调用Canvas接口查询坐标,Block实例初始化时已经传入了网格坐标,直接用block.grid_y * 方块像素高度就能拿到对应Y轴坐标,性能更高也不会出现查询返回空的问题。
内容的提问来源于stack exchange,提问作者gwoonryan
相关产品推荐
相关产品推荐

