如何制作可拖动的精灵确实碰撞但没有移动到新的位置?

时间:2016-07-04 07:45:52

标签: ios sprite-kit swift2

我正在尝试用Sprite Kit制作游戏。想法是用触摸和拖动移动精灵(在矿箱盒中)。当盒子相互碰撞时它们应该保持原位。我已经为所有盒子设置了physicsBody.dynamics当触摸框时,它变为动态=真。当触摸结束时,框被设置回动态=假。如果我慢慢拖动精灵(框),一切正常。当我开始快速拖动它时,它会通过其他精灵(盒子)与physicsBody.dynamic = false。

我是在朝着正确的方向思考,还是应该采用不同的方式?

任何建议都对我很好。谢谢!

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

 //When box is touched it becomes dynamic

    let touch = touches.first
    let touchLocation = touch?.locationInNode(self)
    if let body = physicsWorld.bodyAtPoint(touchLocation!) {
        if body.node?.name == "wall" {return}
        if body.node?.name == "wallRight"{return}
        else{
            body.node?.physicsBody?.dynamic = true
            body.node?.name = "touchedBody"
        }
    }

}


override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

// Here is everything ok

    for touch in touches{

        let location = touch.locationInNode(self)
        let previousLocation = touch.previousLocationInNode(self)
        if let body = physicsWorld.bodyAtPoint(location){
            guard let sprite = body.node as? SKSpriteNode else {return}
            if sprite.name == "touchedBody"{
                if sprite.size.height>sprite.size.width{
                    let spritePositionY = sprite.position.y + location.y - previousLocation.y
                    sprite.position.y = spritePositionY

                }else{
                    let spritePositionX = sprite.position.x + location.x - previousLocation.x
                    sprite.position.x = spritePositionX

                }  
            }
        }   
    }

 override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

// And here i think i have problem.

    for touch in touches{
        let location = touch.locationInNode(self)
        if let body = physicsWorld.bodyAtPoint(location){

            guard let sprite = body.node as? SKSpriteNode else {return}
            if sprite.name == "wall"{return}
            if sprite.name == "wallRight"{return}
            if sprite.size.height>sprite.size.width{
                moveVerticaly(sprite, wallCeiling: wallCeiling, wallFloor: wallFloor)
                moves += 1
                sprite.name = nil
            }else{
                guard let sprite = body.node as? SKSpriteNode! else {return}
                moveHorizontally(sprite, wallLeft: wallLeft, wallRight: wallRight)
                moves += 1
                sprite.name = nil

            }
                sprite.physicsBody?.dynamic = false 
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您可以随时使用此配置:

enum CollisionTypes: UInt32 {
    case Boxes = 1
    case Wall = 2
    //case Enemy1 = 4
    //case Enemy2 = 8
    //case Enemy3 = 16
    //case Bullets = 32
}

func setPhysics(sprite:SKSpriteKit) {
        sprite.physicsBody = SKPhysicsBody.init(edgeLoopFromRect: sprite.frame)
        sprite.physicsBody!.mass = 1
        sprite.physicsBody!.friction = 0
        sprite.physicsBody!.affectedByGravity = false // set as you want
        sprite.physicsBody?.linearDamping = 0
        sprite.physicsBody?.angularDamping = 0
        sprite.physicsBody?.restitution = 0
        sprite.physicsBody?.dynamic = false
        sprite.physicsBody?.usesPreciseCollisionDetection = true
        sprite.physicsBody!.categoryBitMask = CollisionTypes.Boxes.rawValue
        sprite.physicsBody!.contactTestBitMask = CollisionTypes.Boxes.rawValue || CollisionTypes.Wall.rawValue
}

func didBeginContact(contact: SKPhysicsContact) {
     if (contact.bodyA.categoryBitMask == CollisionTypes.Boxes.rawValue &&
            contact.bodyB.categoryBitMask == CollisionTypes.Boxes.rawValue) {
        print("boxes collided")
     }

}