2015-07-26 4 views
5

Ich habe eine Erweiterung der SKSpriteNode-Klasse erstellt. Ich mache Ziegel-Objekte, die sich anders verhalten, wenn sieiOS/Swift - Enum-Wert kann nicht auf Init gesetzt werden()

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 
    } 
} 

getroffen zu Dann mache ich eine Instanz dieser Klasse:

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

Mein Problem ist, dass trotz setType() innerhalb des convenience init() Aufruf, die Wert der öffentlichen brickType Variable ist immer noch die Standardeinstellung, Brick.type.None. Die Farbe wird ohne Probleme geändert, daher scheint das Argument korrekt zu übergeben.

Wenn ich den Standard-brickType Variable Brick.type.Yellow gesetzt, und führen Sie die gotHit() Funktion, die setType() Funktion wird die Art des Ziegels zu Brick.type.Green effektiv ändern, und nach erneuten Aufruf, wird der Knoten aus der Ansicht gelöscht durch self.removeFromParent() Aufruf . Daher bin ich sicher, das Problem ist, wenn ich die Funktion von convenience init() aufrufen, obwohl ich keine Fehler bekomme.

+0

Können Sie zeigen, wie Sie das Objekt erstellen und den Typ überprüfen? Ich habe gerade Ihren Code in einen Spielplatz eingefügt und es funktionierte einwandfrei – Paulw11

+0

Funktioniert immer noch für mich auf dem Spielplatz. – Paulw11

+0

Ich fügte ein einfaches "konvertiere die Enumeration in eine String-Funktion" - https://gist.github.com/paulw11/2010f0474429a679a0b9 und es gibt den entsprechenden Wert – Paulw11

Antwort

2

Wenn Sie es zum ersten Mal im Initialisierer festlegen, ist kein Standardwert erforderlich. Habe das nicht getestet, um zu sehen, ob es dein Problem behebt, aber ich habe den Code ein wenig aufgeräumt.

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 
+0

Danke - auf jeden Fall etwas gelernt! – Heriotza