如何检测两个快速移动物体之间的碰撞?

时间:2015-04-21 23:51:19

标签: swift xcode6 sprite-kit

嘿所以我在检测碰撞时遇到了问题。我根据Ray Wenderlich关于如何制作像Mega Jump这样的游戏的教程制作了这个项目。所以一切都在一开始就很有效,平台和星星在一个地方是静止的。但随着你在游戏中的进一步发展,星星和平台开始移动(我正在使用SKActions),试图做到这一点使它变得更难。但是当我到达那里时,根本没有检测到碰撞,玩家只是穿过物体,就像他们不在那里一样。我一直在网上阅读,我正在使用精确的碰撞检测,但我仍然没有看到任何区别。关于什么可能是错的或者我还能做什么的任何想法?以下是关于我如何做到这一点的一些代码:

    player = SKSpriteNode(texture: firstFrame)
    player.position = (CGPoint(x: self.size.width / 2, y: 50.0))
    player.physicsBody = SKPhysicsBody(circleOfRadius: player.size.width / 2)
    player.physicsBody?.dynamic = true
    player.physicsBody?.allowsRotation = false
    player.physicsBody?.restitution = 1.0
    player.physicsBody?.friction = 0.0
    player.physicsBody?.angularDamping = 0.0
    player.physicsBody?.linearDamping = 0.0
    player.physicsBody?.usesPreciseCollisionDetection = true
    player.physicsBody?.categoryBitMask = CollisionCategoryBitmask.Player
    player.physicsBody?.collisionBitMask = 0
    player.physicsBody?.contactTestBitMask = CollisionCategoryBitmask.Star | CollisionCategoryBitmask.Platform | CollisionCategoryBitmask.Monster
    foregroundNode.addChild(player)  

func createPlatformAtPosition(position: CGPoint, ofType type: PlatformType) -> PlatformNode {

    let node = PlatformNode()
    let thePosition = CGPoint(x: position.x * scaleFactor, y: position.y)
    node.position = thePosition
    node.name = "NODE_PLATFORM"
    node.platformType = type

    var sprite: SKSpriteNode
    var spriteFrames : [SKTexture]!
    if type == .Break {

        let spriteAnimatedAtlas = SKTextureAtlas(named: "CloudBreak")
        var cloudFrames = [SKTexture]()
        spriteFrames = cloudFrames
        let firstFrame = SKTexture(imageNamed: "Cloud02")
        sprite = SKSpriteNode(texture: firstFrame)

        let move = SKAction.moveToX(self.position.x - 160.0, duration:2.0)
        let back = SKAction.moveToX(self.position.x, duration:2.0)
        let sequence = SKAction.sequence([move, back, move, back])
        sprite.runAction(SKAction.repeatActionForever(sequence))

    } else {     
        let spriteAnimatedAtlas = SKTextureAtlas(named: "Cloud")
        var cloudFrames = [SKTexture]()
        spriteFrames = cloudFrames
        let firstFrame = SKTexture(imageNamed: "Cloud")
        sprite = SKSpriteNode(texture: firstFrame)

    }

    node.addChild(sprite)
    node.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
    node.physicsBody?.dynamic = false
    node.physicsBody?.categoryBitMask = CollisionCategoryBitmask.Platform
    node.physicsBody?.contactTestBitMask = CollisionCategoryBitmask.Player
    node.physicsBody?.collisionBitMask = 0

    return node
}

 func didBeginContact(contact: SKPhysicsContact) {

    var updateHUD = false
    let whichNode = (contact.bodyA.node != player) ? contact.bodyA.node : contact.bodyB.node
    let other = whichNode as GameObjectNode
    updateHUD = other.collisionWithPlayer(player)

}

    struct CollisionCategoryBitmask {
      static let Player: UInt32 = 0x00
      static let Star: UInt32 = 0x01
      static let Platform: UInt32 = 0x02
      static let Monster: UInt32 = 0x03
           }

3 个答案:

答案 0 :(得分:2)

减慢对象的速度并查看它们是否发生碰撞。我有一个问题,我移动我的节点太快,他们在渲染新帧时经过了碰撞点。如果它们移动速度如此之快,它们会在帧周期内通过彼此的物理体,它们就不会记录命中。

要在这种情况下检测碰撞,您可以比较它们在每个帧中的位置,如果它们相互通过或它们的x / y平面值重叠,则可以执行碰撞代码。

答案 1 :(得分:1)

未检测到碰撞,因为您未设置collisionBitMask

player.physicsBody?.collisionBitMask = CollisionCategoryBitmask.Star | CollisionCategoryBitmask.Platform | CollisionCategoryBitmask.Monster
node.physicsBody?.collisionBitMask = CollisionCategoryBitmask.Player

接触和碰撞不是一回事。您可以在线找到更多信息。

如果仍然无效,请向我们展示您的CollisionCategoryBitmask,以确保您正确创建。

修改:

struct CollisionCategoryBitmask {
    static let Player:    UInt32 = 0
    static let Star:      UInt32 = 0b1
    static let Platform:  UInt32 = 0b10
    static let Monster:   UInt32 = 0b100
}

以下是我为another question制作的表格,可能对您有所帮助: http://goo.gl/7D8EGY

答案 2 :(得分:0)

查看我的碰撞物理引擎,它非常简单但支持连续/预测/子弹碰撞。你可以从代码中学到一些东西,它是用javascript编写的,所以应该很容易阅读。https://github.com/Murplyx/AAE---Axis-Aligned-Engine