精灵节点定相

时间:2018-12-11 15:08:43

标签: swift xcode sprite-kit

我正在尝试制作一个迷宫应用。目的是使球(用手指拖动球)穿过“迷宫”状的水平,该水平具有陷阱和其他危险。但是,当我使球/播放器在拖动时移动时,它现在开始通过其他精灵节点移相,而不是停留在关卡内。我该如何做才能使它不会超出关卡?

代码:

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

        print("x: \(ball.position.x), y: \(ball.position.y)")

    }

    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
        }
    }

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

游戏截图: Maze Level

2 个答案:

答案 0 :(得分:0)

您需要为节点设置collisionBitMask并相应地设置所需的碰撞规则(即,防止球穿过迷宫壁或危险夹入):

我建议查看相应的Apple开发人员文档:https://developer.apple.com/documentation/spritekit/skphysicsbody/1520003-collisionbitmask

另一个问题的答案也可能会有所帮助:What are Sprite Kit's "Category Mask" and "Collision Mask"?

这也是一个视频,当我学习用于检测SKSpriteNodehttps://youtu.be/467Doas5J6I?t=1114之间的冲突和接触的位掩码时,我发现它很有帮助

*编辑*

您还需要通过contactTestBitMask设置接触检测,以便知道何时球接触到墙壁,此时您可以实施逻辑以将其从拖动手势中“放下”。正如@Steve Ives正确指出的那样,拖动将覆盖碰撞物理,如果没有此操作,您仍然会得到裁剪。

答案 1 :(得分:0)

您的主要问题是,上帝的手直接移动您的球。

您需要做的是按照系统规则进行操作。与其直接应用位置,不如设置球的速度以将球推到手指所在的位置。这需要一些数学运算:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        //set the location's coordinate system to match the ball
        let location = touch.location(in: ball.parent)
        let angle = atan2(location.x,location.y)
        let velocity = 1.0f //(change this to whatever speed you want your ball to move at)
        ball.velocity =  CGVector(velocity * cos(angle),velocity * sin(angle)) // you may have to swap around the sin/-sin/cos/-cos to get it the way you like it,  I am assuming at angle 0 your ball is facing right, and it rotates in a counter clockwise direction)

    }
}

现在,您的球将永远被推向接触点。

为避免弹跳,请确保在物理物体上将恢复设置为0,以使其在撞到墙壁时失去所有能量。

还要检查categoryBitmask在所有需要物理学的物体上具有2的幂(在您的示例中为1),以便它可以与所发生的一切发生碰撞