Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS / Swift - Unable to set Enum Value on Init()

I created an extension of SKSpriteNode class. I am making brick objects, which have different behavior when they get hit

import SpriteKit

class Brick: SKSpriteNode {

    enum type {
        case None, Green, Yellow, Orange, Red
    }

    static let colorMap = [
        Brick.type.Green : UIColor.greenColor(),
        Brick.type.Yellow : UIColor.yellowColor(),
        Brick.type.Orange : UIColor.orangeColor(),
        Brick.type.Red : UIColor.redColor()
    ]

    var brickType = Brick.type.None

    convenience init (size: CGSize, type: Brick.type) {
        self.init(color: UIColor.whiteColor(), size: size)

        // Here I set the initial type and color
        // The color is assigned just fine, but the brickType
        // variable is still Brick.type.None
        self.setType(type)
    }

    func gotHit () -> Int {
        switch (self.brickType) {
            case Brick.type.Yellow:
                setType(Brick.type.Green);
                break;

            case Brick.type.Orange:
                setType(Brick.type.Yellow);
                break;

            case Brick.type.Red:
                setType(Brick.type.Orange);
                break;

            case Brick.type.Green: // Green
                self.removeFromParent()
                return 1

            default:
                break
        }

        return 0
    }

    func setType (typeToSet: Brick.type) {
        self.brickType = typeToSet // only works when called from gotHit()
        self.color = Brick.colorMap[typeToSet]! // this works everytime
    }
}

Then I make an instance of this class:

let brickPrototype = Brick(size: CGSizeMake(55, 25), type: Brick.type.Green)

My issue is that, despite calling setType() inside the convenience init (), the value of the public brickType variable is still the default one, Brick.type.None. The color is changed without problems, so the argument seems to be passed correctly.

If I set the default brickType variable to Brick.type.Yellow, and execute the gotHit() function, the setType() function will effectively change the type of the brick to Brick.type.Green, and after calling it again, the node gets deleted from the view by calling self.removeFromParent(). Hence I am sure the issue is when I call the function from convenience init(), even though I get no errors.

like image 379
zantuja Avatar asked Oct 31 '22 22:10

zantuja


1 Answers

There's no need to have a default value if you set it for the first time in the initializer. Haven't tested this to see if it fixes your issue, but I did clean up the code a bit.

class Brick: SKSpriteNode {

enum BrickColorType: UInt {
    case Red
    case Orange
    case Yellow
    case Green //This order matters for nextColor

    func color() -> UIColor {
        switch self {
        case Green:
            return .greenColor() //Swift does not need break statements in cases.
        case Yellow:
            return .yellowColor()
        case Orange:
            return .orangeColor()
        case Red:
            return .redColor()
        }
    }

    func nextColor() -> BrickColorType? {
        return BrickColorType(rawValue: self.rawValue.successor()) //If self = green, this will return nil.
    }

}

var brickType: BrickColorType {
    didSet {
        self.color = brickType.color()
    }
}

init (size: CGSize, type: BrickColorType) {
    brickType = type
    super.init(texture: nil, color: .whiteColor(), size: size) //Because the earlier one was a convenience init and Xcode was complaining
    self.color = brickType.color() //Because didSet is not called in initializer
}

required init?(coder aDecoder: NSCoder) { //This is just boilerplate required to inherit from any NSObject
    brickType = .Red //Or whatever else. If you really want to add a None case to the enum, might I suggest instead making brickType optional?
    super.init(coder: aDecoder)
}

func gotHit () -> Int { //Consider making this a Bool

    if let next = self.brickType.nextColor() {
        //There is a valid next color
        brickType = next
        return 0
    }

    //There is no valid next color
    self.removeFromParent()
    return 1

}
} //Weird formatting because of StackOverflow
like image 156
rsmoz Avatar answered Nov 09 '22 12:11

rsmoz