SpriteKit添加子弹与精灵碰撞时玩家出现异常后坐问题如何解决
问题根因
你遇到的异常后移是两个核心代码错误共同导致的:
- 子弹物理体配置顺序错误:你在创建
bullet.physicsBody实例之前就对它的分类掩码、碰撞掩码等属性赋值,此时physicsBody为nil,所有预设配置完全不生效,后续创建的子弹物理体使用默认掩码规则,会和场景内所有带物理体的节点产生碰撞交互。 - 子弹分类掩码配置错误:你错误将子弹的
categoryBitMask设为了CollisionTypes.enemy.rawValue,等于物理引擎将子弹判定为敌人类型,会和设置了敌人碰撞掩码的玩家产生碰撞规则,加上子弹初始位置和玩家完全重叠,物理引擎会自动推开两个重叠的碰撞体,就出现了类似后坐力的后移效果。
修复步骤
- 首先确认你的
CollisionTypes是按位移枚举规范定义,示例如下:
enum CollisionTypes: UInt32 { case player = 1 << 0 case enemy = 1 << 1 case bullet = 1 << 2 }
- 调整子弹物理体的配置顺序,先创建物理体再配置属性,同时修正掩码参数,参考代码如下:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else { return} let location = touch.location(in: self) lastTouchPosition = location let bullet = SKSpriteNode(imageNamed: "bullet") bullet.name = "bullet" bullet.position = player.position bullet.size = CGSize(width: 40, height: 30) // 先创建物理体实例再配置属性 bullet.physicsBody = SKPhysicsBody(circleOfRadius: bullet.size.width / 2) // 修正掩码配置:子弹分类为bullet类型,仅检测和敌人的接触,不产生物理碰撞反馈 bullet.physicsBody?.categoryBitMask = CollisionTypes.bullet.rawValue bullet.physicsBody?.contactTestBitMask = CollisionTypes.enemy.rawValue bullet.physicsBody?.collisionBitMask = 0 // 可选:如果子弹不需要受重力影响可新增这行 bullet.physicsBody?.affectedByGravity = false addChild(bullet) }
- 检查你现有玩家物理体配置代码,注意你混用了
player和playerNode两个变量,确认是笔误、配置的是同一个玩家对象即可,你现有代码中已经关闭了玩家和子弹的碰撞掩码,无需额外修改。 - 可选兜底方案:如果玩家本身不需要被物理引擎驱动移动,可以直接设置
player.physicsBody?.isDynamic = false,从根源避免玩家被任何物理力推动。
内容的提问来源于stack exchange,提问作者nathandr
相关产品推荐
相关产品推荐

