0

I'm making an RPG-type game, in which you can choose the attack your user has. I'm trying to make it so that I have a superclass named "Projectile", where general variables are described, and subclasses that change the variables. But whenever I override the value of the variables, I get an EXC_BAD_INSTRUCTION.

import Foundation
import SpriteKit

class Projectile: SKNode {


    var texture: SKTexture!
    var projectileBody = SKSpriteNode()
    var projectile: SKEmitterNode!
    var negativeEffect: DefaultNegativeEffect!


    func setUpValues() {

        texture = SKTexture(imageNamed: "bokeh.png")
        projectileBody = SKSpriteNode()
        projectile = SKEmitterNode(fileNamed: "testbokeh.sks")
        negativeEffect = DefaultNegativeEffect(runningSpeed: 0)


    }

     override init() {
        super.init()
        projectileBody.texture = texture
        projectileBody.size = texture.size()
        projectileBody.position = self.position
        self.physicsBody = SKPhysicsBody(circleOfRadius: 2)
        self.physicsBody?.dynamic = true
        self.physicsBody?.categoryBitMask = PhysicsCategory.Projectile
        self.physicsBody?.contactTestBitMask = PhysicsCategory.Monster
        self.physicsBody?.collisionBitMask = PhysicsCategory.None
        self.physicsBody?.usesPreciseCollisionDetection = true
        projectile.position = self.position
        self.addChild(projectileBody)
        self.addChild(projectile)

    }


    func update() {

    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}
import Foundation
import SpriteKit

class FireBall: Projectile {

    override func setUpValues() {

        texture = SKTexture(imageNamed: "spark5.png")
        projectileBody = SKSpriteNode()
        projectile = SKEmitterNode(fileNamed: "testbokeh.sks")
        negativeEffect = DefaultNegativeEffect(runningSpeed: 0)

    }

}
Mahmud Ahmad
  • 171
  • 3
  • 18

1 Answers1

1

It looks like class Projectile calls super.init() before setting its own properties, and never calls setUpValues() at all, meaning your variable properties never have values.

In the Fireball subclass the setUpValues function still isn't being called, and you don't have a separate init() function, so it's the same problem: the values aren't ever being set.

The rules for initialization in Swift are a bit different from Obj-C in that you need to initialize all stored instance properties before calling super.init(), and have to consider how you handle inherited properties as well to ensure you have a fully/properly initialized object.

From Apple's Swift Programming Guide:

  1. A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.

  2. A designated initializer must delegate up to a superclass initializer before assigning a value to an inherited property. If it doesn’t, the new value the designated initializer assigns will be overwritten by the superclass as part of its own initialization.

mc01
  • 3,750
  • 19
  • 24
  • Declaring with ! also initializes the values to nil. – dustincarr Dec 30 '14 at 22:44
  • Thank you! But I think doing what @dustincarr said is better, because when I tried the '?' I was getting errors telling me SKTexture doesn't have the member named 'size' – Mahmud Ahmad Dec 30 '14 at 22:57
  • Sorry, mistake on my part - implicitly unwrapping during declaration (as you did) still defaults to `nil` and allows you to skip the step of forced unwrapping later, which you would've had to do (`texture!.size` for example). Glad you were able to solve it! – mc01 Dec 30 '14 at 23:02