使精灵随速度移动

时间:2018-12-13 14:23:52

标签: swift sprite-kit

我正在尝试使用速度使精灵跟随我的手指,以使其不会移过其他精灵节点,也不会推开它们。我只希望Sprite节点(也就是球)简单地击中另一个Sprite节点并弹起,或者只是将其击打并坐在那里直到其再次移动。

此刻,我正在使用基于位置的移动方式:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            ball.position.x = location.x
            ball.position.y = location.y
            print("x: \(ball.position.x), y: \(ball.position.y)")
        }
    }

我如何做到这一点,使其不会在其他sprite节点周围移动,而实际上与categoryBitMask元素发生反应?

我对这件事一无所知。希望你能理解:)

其余代码:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

var ball = SKSpriteNode()
var danger1 = SKSpriteNode()
var danger2 = SKSpriteNode()
var goal = SKSpriteNode()


override func didMove(to view: SKView) {

    ball = self.childNode(withName: "ball") as! SKSpriteNode
    danger1 = self.childNode(withName: "danger1") as! SKSpriteNode
    danger2 = self.childNode(withName: "danger2") as! SKSpriteNode
    goal = self.childNode(withName: "goal") as! SKSpriteNode

    let border = SKPhysicsBody(edgeLoopFrom: self.frame)
    border.friction = 0
    border.restitution = 0

    danger1.physicsBody = SKPhysicsBody()
    danger1.physicsBody?.categoryBitMask = PhysicsCategories.dangerCategory
    danger2.physicsBody = SKPhysicsBody()
    danger2.physicsBody?.categoryBitMask = PhysicsCategories.dangerCategory

    ball.physicsBody = SKPhysicsBody()
    ball.physicsBody?.categoryBitMask = PhysicsCategories.ballCategory
    ball.physicsBody?.contactTestBitMask = PhysicsCategories.dangerCategory
    ball.physicsBody?.collisionBitMask = PhysicsCategories.none

    goal.physicsBody = SKPhysicsBody(circleOfRadius: goal.size.width/2)
    goal.physicsBody?.categoryBitMask = PhysicsCategories.goalCategory

    danger1.physicsBody?.isDynamic = true
    ball.physicsBody?.isDynamic = true
    goal.physicsBody?.isDynamic = true
    danger2.physicsBody?.isDynamic = true
    danger2.physicsBody!.affectedByGravity = false
    danger1.physicsBody!.affectedByGravity = false
    goal.physicsBody!.affectedByGravity = false
    ball.physicsBody!.affectedByGravity = false
    setupPhysics()

}
func setupPhysics() {
    physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
    physicsWorld.contactDelegate = self
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        ball.position.x = location.x
        ball.position.y = location.y
        print("x: \(ball.position.x), y: \(ball.position.y)")
    }
}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
}
}

extension GameScene: SKPhysicsContactDelegate {



func didBegin(_ contact: SKPhysicsContact) {
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    if contactMask == PhysicsCategories.ballCategory | PhysicsCategories.dangerCategory {
        ball.position = CGPoint(x: 0, y: 550)
    } else if contactMask == PhysicsCategories.ballCategory | PhysicsCategories.goalCategory {
        print("Goal!")
    }
}

}

1 个答案:

答案 0 :(得分:0)

尝试注释此行:

ball.physicsBody?.collisionBitMask = PhysicsCategories.none

防止球与任何物体碰撞,即不受任何物体碰撞的影响。注意-这并不意味着其他物体不会受到与球的碰撞的影响。碰撞是双向的-给定2个节点A和B,您必须定义A是否与B碰撞 和B是否与A碰撞。这对于接触不是必需的-足以定义A联系B。如果实际上是b移到A,则didBegin()仍会被调用。您不必也定义B联系人A。

您似乎没有在其他任何物理物体上设置collisionBitMask,这意味着它们将与所有物体碰撞。

这解释了为什么球穿过壁移动-因为它不会与壁碰撞,尽管所有其他对象都应该被球推挤。

尝试放入:

print("Contact") 

作为didBegin()的第一行,以查看是否已注册任何联系人。

如果您想用手指拖动精灵,然后使其反弹(与其他精灵碰撞)可能会比较棘手,因为拖动意味着您想要手动设置其位置,而反弹则意味着您想要移动精灵Sprite-Kit引擎和2并不是真正兼容的。

可能值得指出的是,“碰撞”是相互反射的精灵,由SK引擎处理。 collisionBitMask控制哪些对象会相互反弹。

“联系人”只是当2个对象接触时得到通知的一种方式。它们由contactTestBitMask控制。

接触和碰撞均取决于categoryBitMAsk

我的碰撞和接触逐步指南: https://stackoverflow.com/a/51041474/1430420

以及碰撞和接触的指南测试位掩码: https://stackoverflow.com/a/40596890/1430420

操纵位掩码可打开和关闭单个碰撞和触点。 https://stackoverflow.com/a/46495864/1430420

相关问题