Thesaurus03
Thesaurus03

Reputation: 71

How to detect collisions between two fast moving objects?

Hey so I have a problem detecting collisions. I have this project I am making based on Ray Wenderlich's tutorial on How to Make a game like Mega Jump. So everything is works great at the beginning, where platforms and stars are static in one place. But as you go further in the game, stars and platforms start moving (I am using SKActions for this), tried to do this to make it a little harder. But when I get there, collision is NOT being detected at all, player just passes by through the objects like they weren't there. I've been reading everywhere online, I am using precise collision detection but still I see no difference. Any ideas on what can be wrong or what else can I do? Here is a bit of code on how I am doing this:

    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
           }

Upvotes: 1

Views: 1125

Answers (3)

Siriss
Siriss

Reputation: 3767

Slow the objects down and see if they collide. I had an issue where I was moving my nodes too fast and they were past the collision points when the new frame was rendered. If they move so fast they pass each other's physics body in the frame cycle they will not register a hit.

To detect a collision in that case, you can compare where they are in each frame, and if they have passed each other or their x/y plane values overlap, you can execute your collision code.

Upvotes: 2

user2039981
user2039981

Reputation:

Check out my collision physics engine, it's very simple but has support for continuous/predicting/bullet collisions. You might learn something from the code, and it's written in javascript so it should be easy to read.https://github.com/Murplyx/AAE---Axis-Aligned-Engine

Upvotes: 0

lchamp
lchamp

Reputation: 6612

The collision is not detected because you didn't set the collisionBitMask.

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

Contact and Collision aren't the same thing. You can find more information online.

If it still doesn't work, please show us your CollisionCategoryBitmask to make sure you created it properly.

Edit :

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

Here is a table I've made for another question, that might help you too : http://goo.gl/7D8EGY

Upvotes: 1

Related Questions