简体   繁体   中英

How to initialise classes correctly

The following code produces an error on the line pickUp.spawnShield() from my GameScene class whenever I try to call it.

There is no message from the compiler about what is causing the error, though I think it may be to do with the fact that my var pickUp: Pickup! is nil. If thats the case, how do I initialise it correctly?

class Pickup {

    var game: GameScene!

    func spawnShield() {

        let randomXStart = Random().random(min: game.gameArea.minX + game.player.size.width/2, max: game.gameArea.maxX - game.player.size.width/2)

        let randomXEnd = Random().random(min: game.gameArea.minX + game.player.size.width/2, max: game.gameArea.maxX - game.player.size.width/2)

        let startPoint = CGPoint(x: randomXStart, y: game.size.height * 1.1)
        let endPoint = CGPoint(x: randomXEnd, y: -game.size.height * 0.1)

        let shield = SKSpriteNode(imageNamed: "shieldDrop")
        shield.setScale(2)
        shield.position = startPoint
        shield.zPosition = 3

        game.addChild(shield)

        let moveShield = SKAction.move(to: endPoint, duration: TimeInterval(Helper().randomBetweenTwoNumbers(firstNumber: 3, secondNumber: 5)))

        shield.run(moveShield)
    }
}

Then I call it in my class like so:

class GameScene: SKScene, SKPhysicsContactDelegate {

    var pickUp: Pickup!

    override init(size: CGSize) {

        ....

        pickUp = Pickup() //something like this?

        super.init(size: size)
    }

    func startNewLevel() {

        pickUp.spawnShield()
    }
}

First: you have to create an instance of Pickup class stored (referenced) in var pickUp. I do not see anything like

class Pickup {
  weak var game: GameScene?
  init(game: GameScene) {
    self.game = game
  }
  func spawnShield() {...}
}

class GameScene: SKScene, SKPhysicsContactDelegate {
  var pickUp: Pickup!
  override init(size: CGSize) {
    super.init(size: size)
    pickUp = Pickup(game: self)
}

Second: I do not see too much reason to have pickUp implicitly unwrapped (!). I would rather propose weak var pickUp: Pickup? to avoid reference cycle (if referenced in cycle)

Third: it is strange that you see no compiler error of missing initializer, as you have properties in your classes and then initializer must be defined. Do not forget to call super.init(...) in your initializer, after you initialize your class properties.

here, I think you can do somthing like this

class GameScene: SKScene, SKPhysicsContactDelegate {

    var pickUp = Pikup()

    func startNewLevel() {

        pickUp.spawnShield()
    }
}

or you can just initialize you variable "pikUp" before calling spawnShield(), maybe in init method as you wrote.

so also make sure that you use 'game' variable after initializing it, because as I can see in your code it will also crash because it is nil when you use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM