Kivy中Image碰撞体尺寸过大导致持续触发碰撞问题求助
解决Kivy玩家精灵尺寸异常导致持续碰撞的问题
我一眼就瞅出问题所在啦——你的Basic(玩家精灵)和Collider(中间方块)类都继承自Image,但没覆盖Kivy控件默认的size_hint属性!
问题根源
Kivy的Widget(包括Image)默认size_hint=(1, 1),这个属性会强制控件自动拉伸填满父容器空间。哪怕你手动设置了size=(32,32),只要size_hint还是默认值,Kivy就会直接忽略你的手动尺寸设置,让玩家精灵占满整个屏幕。这就解释了为什么pdb显示玩家尺寸是屏幕大小,也导致碰撞检测一直触发——整个屏幕都和中间方块重叠了啊!
修复步骤
- 修正控件尺寸属性:在
Basic和Collider的初始化方法里,添加size_hint=(None, None),这样手动设置的size才会真正生效:
class Collider(Image): def __init__(self, **kwargs): super(Collider, self).__init__(**kwargs) self.size_hint = (None, None) # 禁用自动拉伸 class Basic(Image): pFrame = 0 def __init__(self, **kwargs): super(Basic, self).__init__(**kwargs) self.size_hint = (None, None) # 禁用自动拉伸 self._keyboard = Window.request_keyboard(None, self) # 剩下的键盘绑定代码保持不变...
- 简化碰撞检测逻辑:你当前的碰撞检测代码
self.parent.parent.block.collide_widget(self.parent.parent.wimg)层级太绕,容易出错。可以改成让玩家精灵直接引用方块:
先修改GameScreen的playy方法,把方块实例传给玩家精灵:
def playy(self): root.add_widget(self.wimg) self.wimg.block = self.block # 让玩家精灵直接拿到方块引用 Clock.schedule_interval(self.wimg.update, 1.0 / 60.0)
然后Basic的update方法就能简化成:
def update(self, dt): self.pFrame += 1 if self.block.collide_widget(self): print("碰撞到方块啦!")
- 调整玩家初始位置:你设置的初始位置
pos=(270,-120)会让玩家精灵跑到屏幕外面,建议改成可见位置,比如pos=(270, 200),方便测试碰撞效果。
额外优化建议
- 别用全局的
root = FloatLayout(),最好在GameScreen内部创建布局,代码更模块化,也不会出现层级混乱的问题。 - 给
Collider加个初始位置,比如在GameScreen的__init__里加self.block.pos = (300, 200),让方块出现在屏幕中央附近。
按照上面的修改,玩家精灵就会变成你设置的32×32大小,只有真正碰到中间方块时才会打印碰撞提示啦!
内容的提问来源于stack exchange,提问作者Azazer
相关产品推荐
相关产品推荐

