SpriteKit中Sprite无法移动及实现墙面反弹效果问题求助
问题解决方法
你遇到的两个问题都是SpriteKit物理世界的默认配置和位掩码设置错误导致的,按以下步骤修改即可实现类Pong的匀速反弹效果:
- 第一步:关闭场景全局重力
Pong类游戏不需要重力作用,在场景初始化方法didMove(to view: SKView)中添加以下代码:
physicsWorld.gravity = .zero
- 第二步:添加场景边界物理体
你需要先给游戏区域添加碰撞边界,否则小球不会触发墙面反弹,同上述初始化方法中添加:
// 用场景边框创建物理边界 let borderPhysics = SKPhysicsBody(edgeLoopFrom: frame) borderPhysics.categoryBitMask = 1 // 标记边界的分类标识 borderPhysics.friction = 0 borderPhysics.restitution = 1 // 完全反弹无能量损失 borderPhysics.isDynamic = false // 边界固定不动 physicsBody = borderPhysics
- 第三步:修正小球物理体属性
你现有代码缺少阻尼、摩擦配置,且位掩码设置有误,修改后的代码如下:
let boxTexture2 = SKTexture(imageNamed: "movingEnemy.png") let box = SKSpriteNode(texture: boxTexture2) box.position = randomPos() box.name = "enemy" box.physicsBody = SKPhysicsBody(circleOfRadius: player.size.width / 2) box.physicsBody!.restitution = 1 // 完全反弹 box.physicsBody!.friction = 0 // 无摩擦 box.physicsBody!.linearDamping = 0 // 无线性速度衰减 box.physicsBody!.angularDamping = 0 // 无旋转速度衰减 box.physicsBody!.categoryBitMask = 2 // 标记小球的分类标识 box.physicsBody!.collisionBitMask = 1 // 仅和边界碰撞 // 不需要监听碰撞回调的话可以删除下面这行 box.physicsBody!.contactTestBitMask = 1 box.physicsBody!.isDynamic = true // 可根据需要调整冲量大小控制移动速度 box.physicsBody?.applyImpulse(CGVector(dx: 30 , dy: 30)) addChild(box)
- 若修改后还是没有移动,检查你的冲量添加时机是否在物理世界初始化完成之后(必须在
didMove(to view:)方法执行后再添加力,不要在节点的init方法中执行applyImpulse) - 循环创建多个小球时,每个节点都需要单独调用applyImpulse添加初始动力
内容的提问来源于stack exchange,提问作者JohnM
相关产品推荐
相关产品推荐

