在改变SKSpriteNode位置的同时更改SKPhysicsBody

3

我有一个非常简单的游戏。它类似于经典的迷宫游戏,使用加速度计,但用户还可以使用3D Touch改变矩形的大小。

玩家的节点是一个矩形,通过从加速度计获取数据的世界物理来移动(在这里没有什么特别的):

motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data, error) in
    if let motionData = data{
        self.physicsWorld.gravity = CGVector(dx: motionData.acceleration.x * 7, dy: motionData.acceleration.y * 7)
    }
}

并且 touchesMoved :

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first{
            let maxForce = touch.maximumPossibleForce
            let force = touch.force

            let forceValue = force/maxForce

            player.size = CGSize(width: 26-forceValue*16, height: 26-forceValue*16)
            player.physicsBody = SKPhysicsBody(rectangleOf: player.size)
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    resetSize()
}

func resetSize(){
    player.size = CGSize(width: 26, height: 26)
}

当我更改播放器的大小时,它可以正常工作:节点根据设备的方向在屏幕上移动,并且按下更硬时变小。问题是物理体(我在GameViewController.swift中设置了view.showsPhysics = true)始终相同,因此我添加了player.physicsBody = SKPhysicsBody(rectangleOf: player.size),但现在当我按压屏幕时,播放器的节点会调整大小,但也停止移动。如何同时更改节点的大小和物理体并保持其运动?
1个回答

1
当你更改physicsBody时,你会失去与之前的physicsBody相关的所有物理参数:你可以复制velocityangularVelocity或其他可用参数,但这还不够,因为SpriteKit框架(在当前版本中)没有这个选项:在游戏过程中动态更改physicsBody
你也可以改变节点的缩放来修改physicsBody,但是你总是会失去物理变量,例如由于重力而累积的速度:这是因为SpriteKit在缩放期间自动更改physicsBody以创建其他身体,而不保留累积属性。
因此,我的建议是在触摸球时创建一种“冻结时间”,在球停止时可以更改physicsBody

4
投反对票的人应该提供解决方案(但必须是真实的物理变量和真实传播时间,而不是伪造的...),并尝试解释他们对我的说法持相反意见,以帮助原始发帖人。 - Alessandro Ornano
冻结时间是什么意思?我是否应该在想要改变大小时停止物体的移动,在大小调整到位后继续物体的运动呢? - mikro098
这只是一个想法,但你可以找到其他模式:你可以创建像“黑客帝国”电影场景一样的效果(减慢音乐速度和游戏元素的所有动作,仅适用于此状态...) - Alessandro Ornano
是的,这是一个解决方案,但不是我预期的。我对Swift还很新,也许会有人发表解决方案。 - mikro098
你的球有固定的大小限制吗?还是可以根据需要调整大小?因为另一个想法是制作一个隐藏的大球,它可以像你的球一样做同样的事情,然后你可以通过动画将小球渐隐,将大球渐显(或相反)来切换。无论如何,祝你的游戏好运 :-) - Alessandro Ornano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接