Как заставить дочерний узел следовать родительскому узлу в Swift 4.2 SpriteKit - PullRequest
0 голосов
/ 27 декабря 2018

Я хочу сделать так, чтобы дочерний спрайт следовал за соответствующим родительским спрайтом.У дочернего спрайта есть физическое тело, которое не должно связываться с физическим телом родителя.Я попытался в подклассе родительского спрайта переопределить эти функции следующим образом:

public override func run(_ action: SKAction) {
    super.run(action)
    physicsSprite.run(action)
}
public override func run(_ action: SKAction, withKey key: String) {
    super.run(action, withKey: key)
    physicsSprite.run(action, withKey: key)
}
public override func removeAllActions() {
    super.removeAllActions()
    physicsSprite.removeAllActions()
}

безуспешно, однако: (
Я исключительно перемещаю родительский спрайт с помощью SKActions. В результате получается, чтоспрайты не слипаются.

physicsSprite.zPosition = 10
physicsSprite.physicsBody = SKPhysicsBody(circleOfRadius: playerInfo.width+2)
physicsSprite.physicsBody?.affectedByGravity = false
physicsSprite.physicsBody?.isDynamic = false
physicsSprite.physicsBody?.restitution = 0
physicsSprite.physicsBody?.collisionBitMask = 0
addChild(physicsSprite)

В этом случае физика - это дочерний узел в подклассе SKSpriteNode. Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Множество способов сделать это.Сравнение позиций узлов (лидер / последователь) на регулярной основе и обновление позиций соответственно должно работать.Пример: лидер идет на некоторые позиции> позиции не совпадают> переместить последователя в местоположение лидера.

Пример кода

class GameScene: SKScene {
    private var leader: SKSpriteNode!
    private var follower: SKSpriteNode!

    override func didMove(to view: SKView) {
        self.leader = SKSpriteNode(color: UIColor.red, size: CGSize(width: 30, height: 30))
        self.follower = SKSpriteNode(color: UIColor.green, size: CGSize(width: 30, height: 30))
        self.addChild(leader)
        self.addChild(follower)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches {
            let target = t.location(in: self)
            // Move the leader to the touch location
            leader.run(SKAction.move(to: target, duration: 1), withKey: "moving")
        }
    }

    override func update(_ currentTime: TimeInterval) {
        // Check positions
        if follower.position != leader.position {
            // Check if the follower has a 'following' action already
            if follower.action(forKey: "following") == nil {
                // Move the follower
                follower.run(SKAction.move(to: leader.position, duration: 1), withKey: "following")
            }
        }
    }
}

Обратите внимание, что действие обновления вызывается один раз за кадр, что может быть слишком много.В зависимости от вашей ситуации, вы можете создать какой-то цикл, который будет вызываться каждую секунду.

Другим способом было бы всегда выполнять одно и то же действие на следующем узле (возможно, с более длительной продолжительностью, такой, что вы можете на самом делесм. следующий узел).

Редактировать: Подробнее о коллизиях: Не могу понять, как работает битовая маска коллизий (просто убедитесь, что они имеют разные битовые маски контактов - т. Е. 0b01 и 0b10 и не находятся в коллизиях друг другабитовая маска)

0 голосов
/ 27 декабря 2018

Попробуйте это:

parentSprite.physicsBody?.categoryBitMask = 0
parentSprite.physicsBody?.collisionBitMask = 0

physicsSprite.physicsBody?.collisionBitMask = 1
physicsSprite.physicsBody?.categoryBitMask = 1

Для получения дополнительной информации проверьте Документация

...