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

Kivy中Image碰撞体尺寸过大导致持续触发碰撞问题求助

解决Kivy玩家精灵尺寸异常导致持续碰撞的问题

我一眼就瞅出问题所在啦——你的Basic(玩家精灵)和Collider(中间方块)类都继承自Image,但没覆盖Kivy控件默认的size_hint属性!

问题根源

Kivy的Widget(包括Image)默认size_hint=(1, 1),这个属性会强制控件自动拉伸填满父容器空间。哪怕你手动设置了size=(32,32),只要size_hint还是默认值,Kivy就会直接忽略你的手动尺寸设置,让玩家精灵占满整个屏幕。这就解释了为什么pdb显示玩家尺寸是屏幕大小,也导致碰撞检测一直触发——整个屏幕都和中间方块重叠了啊!

修复步骤

  1. 修正控件尺寸属性:在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)
        # 剩下的键盘绑定代码保持不变...
  1. 简化碰撞检测逻辑:你当前的碰撞检测代码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("碰撞到方块啦!")
  1. 调整玩家初始位置:你设置的初始位置pos=(270,-120)会让玩家精灵跑到屏幕外面,建议改成可见位置,比如pos=(270, 200),方便测试碰撞效果。

额外优化建议

  • 别用全局的root = FloatLayout(),最好在GameScreen内部创建布局,代码更模块化,也不会出现层级混乱的问题。
  • 给Collider加个初始位置,比如在GameScreen的__init__里加self.block.pos = (300, 200),让方块出现在屏幕中央附近。

按照上面的修改,玩家精灵就会变成你设置的32×32大小,只有真正碰到中间方块时才会打印碰撞提示啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:47:31