微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Swift 游戏中处理圆环碰撞的最佳方法?

如何解决在 Swift 游戏中处理圆环碰撞的最佳方法?

我正在用 SpriteKit 制作一个类似于空气曲棍球的 Swift 游戏。

当球被球员的木槌击打时,我试图将准确/预期的“冲动”施加到球上。

我可以访问玩家的速度。我还通过使用 func didBegin(_ contact: SKPhysicsContact) 在两个圆圈之间进行了准确的碰撞检测。此外,我还根据球击中玩家槌的位置确定了球应该反弹的预期方向(因为它是一个圆,因此该方向可能与您通过查看玩家的 dx 和 dy 所期望的不同。)

这是我目前正在做的事情,但感觉有点不自然和不正常:

    func didBegin(_ contact: SKPhysicsContact)
    {
        if (contact.bodyA.categoryBitMask == BodyType.ball.rawValue && contact.bodyB.categoryBitMask == BodyType.player.rawValue) && (contact.bodyA.contactTestBitMask == 25 || contact.bodyB.contactTestBitMask == 25) && bottomTouchForCollision == true
        {
            ball!.physicsBody!.applyImpulse(CGVector(dx: CGFloat(UserDefaults.standard.float(forKey: "BottomVeLocity")) * contact.contactnormal.dx,dy: CGFloat(UserDefaults.standard.float(forKey: "BottomVeLocity")) * contact.contactnormal.dy))
        }
    }

对球产生准确而灵敏的冲量的最佳方法是什么?我认为仅依靠 contact.contactnormal.dy 来表示方向感觉不自然,因为如果玩家的圆圈在一个地方不移动,那么这就是预期的方向。数周以来,我一直在为这个问题苦苦挣扎,但不知道如何最好地解决它。代码解释表示赞赏,但任何帮助。

我以类似的方式问过这个问题并收到了这个回复

"考虑球击中固定槌的情况。它会以相同的速度反射出去,最终的运动方向是入射角等于接触点的反射角。然后对于以速度矢量 v 移动的木槌,从所有速度中减去 v 以转换为固定木槌情况。计算转换问题中的球速度。然后通过将 v 添加到结果中来转换回来。(如果你是这样计算的,不用applyImpulse,直接设置新的速度即可。)"

我无法理解如何实现这个想法,但如果有人能提供伪代码代码帮助,那就太好了!

编辑:这是我在下面的帮助下的方式。

        if (contact.bodyA.categoryBitMask == BodyType.ball.rawValue && contact.bodyB.categoryBitMask == BodyType.player.rawValue) && (contact.bodyA.contactTestBitMask == 75 || contact.bodyB.contactTestBitMask == 75) && northTouchForCollision == true
        {
            let vmallet = CGVector(dx: CGFloat(UserDefaults.standard.float(forKey: "northForceDX")),dy: CGFloat(UserDefaults.standard.float(forKey: "northForceDY")))
            let vball = ball?.physicsBody?.veLocity
            let vrelativedx = vball!.dx - vmallet.dx
            let vrelativedy = vball!.dy - vmallet.dy
            let vrelative = CGVector(dx: vrelativedx,dy: vrelativedy)
            let c = (vrelative.dx * contact.contactnormal.dx) + (vrelative.dy * contact.contactnormal.dy)
            let vperpendicular = CGVector(dx: contact.contactnormal.dx * c,dy: contact.contactnormal.dy * c)
            let vtangential = CGVector(dx: vrelative.dx - vperpendicular.dx,dy: vrelative.dy - vperpendicular.dy)
            // vtangential is unchanged in the collision,vperpendicular reflects
            let newvrelative = CGVector(dx: vtangential.dx - vperpendicular.dx,dy: vtangential.dy - vperpendicular.dy)
            let newvball = CGVector(dx: newvrelative.dx + vmallet.dx,dy: newvrelative.dy + vmallet.dy)
            // set ball veLocity to newvball
//            ball?.physicsBody?.veLocity = newvball
            ball!.physicsBody!.applyImpulse(newvball)
        }

解决方法

伪代码:

let vmallet = mallet velocity
let vball = ball velocity
let vrelative = vball - vmallet
let vperpendicular = dotProduct(vrelative,contactNormal) * contactNormal
let vtangential = vrelative - vperpendicular
// vtangential is unchanged in the collision,vperpendicular reflects
let newvrelative = vtangential - vperpendicular
let newvball = newvrelative + vmallet
// set ball velocity to newvball

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。