Узел преждевременно удален со сцены (игра Swift) - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть следующий код в Swift для простой игровой платформы:

import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    var me : SKSpriteNode?
    var ceiling : SKSpriteNode?
    var studentTimer : Timer?
    var cloudTimer : Timer?
    let meCategory : UInt32 = 0x1 << 1
    let studentCategory : UInt32 = 0x1 << 2
    let cloudCategory : UInt32 = 0x1 << 3
    let groundAndCeilingCategory : UInt32 = 0x1 << 4

    var numberofStudents = 0
    var education = ["edu1", "edu2", "edu3", "edu4"]

    override func didMove(to view: SKView) {

        physicsWorld.contactDelegate = self

        me = childNode(withName: "me") as? SKSpriteNode
        me?.physicsBody?.categoryBitMask = meCategory
        me?.physicsBody?.contactTestBitMask = studentCategory
        me?.physicsBody?.collisionBitMask = groundAndCeilingCategory

        // make me run
        var meRun : [SKTexture] = []
        for number in 1...6 {
            meRun.append(SKTexture(imageNamed: "Armature_Run_\(number)"))
        }
        me?.run(SKAction.repeatForever(SKAction.animate(with: meRun, timePerFrame: 0.1)))

        ceiling = childNode(withName: "ceiling") as? SKSpriteNode
        ceiling?.physicsBody?.categoryBitMask = groundAndCeilingCategory
        ceiling?.physicsBody?.collisionBitMask = meCategory

        startTimers()
    }

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

        me?.physicsBody?.applyForce(CGVector(dx: 0, dy: 20000))

        var meJump : [SKTexture] = []
        for number in 0...9 {
            meJump.append(SKTexture(imageNamed: "Armature_Jump_0\(number)"))
        }
        me?.run(SKAction.animate(with: meJump, timePerFrame: 0.1))
    }

    func createStudent() {

        let student = SKSpriteNode(imageNamed: "student")
        student.physicsBody = SKPhysicsBody(rectangleOf: student.size)
        student.physicsBody?.affectedByGravity = false
        student.physicsBody?.categoryBitMask = studentCategory
        student.physicsBody?.contactTestBitMask = meCategory
        student.physicsBody?.collisionBitMask = 0
        addChild(student)
        student.position = CGPoint(x: size.width / 2 + student.size.width, y: (-size.height / 2) + ((student.size.height)*2))
        let moveLeft = SKAction.moveBy(x: -size.width - student.size.width, y: 0, duration: 4)
        student.run(SKAction.sequence([moveLeft, SKAction.removeFromParent()]))
    }

    func startTimers() {

        studentTimer = Timer.scheduledTimer(withTimeInterval: 4, repeats: true, block: { (timer) in
            if self.numberofStudents < 4 {
            self.createStudent()
            }
        })

        cloudTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: { (timer) in
            self.createCloud()
        })
    }

    func createCloud() {

        let cloud = SKSpriteNode(imageNamed: "cloud")
        cloud.zPosition = -1
        cloud.physicsBody = SKPhysicsBody(rectangleOf: cloud.size)
        cloud.physicsBody?.affectedByGravity = false
        cloud.physicsBody?.collisionBitMask = 0
        cloud.physicsBody?.categoryBitMask = cloudCategory
        addChild(cloud)
        let maxY = size.height / 2 - cloud.size.height / 2
        let minY = CGFloat(0)
        let range = maxY - minY
        let cloudY = maxY - CGFloat(arc4random_uniform(UInt32(range)))
        cloud.position = CGPoint(x: size.width / 2 + cloud.size.width / 2, y: cloudY)
        let moveLeft = SKAction.moveBy(x: -size.width - cloud.size.width, y: 0, duration: 4)
        cloud.run(SKAction.sequence([moveLeft, SKAction.removeFromParent()]))
    }

    func didBegin(_ contact: SKPhysicsContact) {

        if contact.bodyA.categoryBitMask == studentCategory {
            contact.bodyA.node?.removeFromParent()
            numberofStudents += 1
            print(numberofStudents)
            print(education[(numberofStudents)-1])
        }

        if contact.bodyB.categoryBitMask == studentCategory {
            contact.bodyB.node?.removeFromParent()
            numberofStudents += 1
            print(numberofStudents)
            print(education[(numberofStudents)-1])
        }
    }
}

Я работаю над тем, что происходит, когда главный герой («я») сталкивается со «учеником».

Перед добавлением 'physWorld.contactDelegate = self' "студент" обнаружился отлично, двигаясь по экрану.Однако, когда я добавляю эту строку кода и запускаю приложение, ученик становится невидимым.Я полагаю, что он все еще где-то есть, так как общий текст печати все еще работает, когда персонаж сталкивается, но он явно ни с чем не сталкивается.

Я удалил contact.bodyB.node? .RemoveFromParent () и запустил егоИ действительно, «студент» снова появляется, но, очевидно, не исчезает при контакте.

Я смотрел на это целую вечность и уверен, что упускаю что-то очевидное, но не могу понять, что это такое.

1 Ответ

0 голосов
/ 26 сентября 2019

вы не предоставляете нам всю информацию.

Поскольку ваш код работает так, как ожидалось.

Вот видео с вашим работающим кодом (мне пришлось использовать свой собственныйimages)

Вот мой анализ того, что может быть неправильным.

Я удалил все элементы последовательности анимации, потому что они не имеют к этому никакого отношения.

Я заметил, что вы неставить zPositions ... тск тск тск.У всех предметов должна быть zPosition.

вы не показываете нам, как вы определяете физику тела в вашем спрайте "я".Предположительно в редакторе?Вы должны включить эту информацию в следующий раз.

Мне пришлось создать символ «я» и поместить его в код, поскольку вы также не показываете, откуда это происходит.Я также создал физику тела в коде, чтобы заставить его работать.

Вот код, который я использовал

me = SKSpriteNode(imageNamed: "orange")
me.position = CGPoint(x: -400, y: (-size.height / 2) + ((me.size.height) * 2))
me.zPosition = 10
addChild(me)

me.physicsBody = SKPhysicsBody(rectangleOf: me.size)
me.physicsBody?.categoryBitMask = meCategory
me.physicsBody?.contactTestBitMask = studentCategory
me.physicsBody?.collisionBitMask = groundAndCeilingCategory
me.physicsBody?.affectedByGravity = false

func createStudent() {

    let student = SKSpriteNode(imageNamed: "apple")
    student.setScale(0.5)
    student.position = CGPoint(x: size.width / 2 + student.size.width, y: (-size.height / 2) + ((student.size.height) * 2))
    student.zPosition = 10
    addChild(student)

    student.physicsBody = SKPhysicsBody(rectangleOf: student.size)
    student.physicsBody?.affectedByGravity = false
    student.physicsBody?.categoryBitMask = studentCategory
    student.physicsBody?.contactTestBitMask = meCategory
    student.physicsBody?.collisionBitMask = 0

    let moveLeft = SKAction.moveBy(x: -size.width - student.size.width, y: 0, duration: 4)
    student.run(SKAction.sequence([moveLeft, SKAction.removeFromParent()]))
}

В примечании к стороне, нет необходимости использовать таймеры.SpriteKit имеет встроенную функцию для этого «обновления» функции.

enter image description here

...