2016-07-19 40 views
0

erbt. Ich versuche, eine generische Alien "Blueprint" -Klasse für mein erstes iPhone-Spiel zu schreiben. Diese Klasse enthält eine Handvoll Eigenschaften und Methoden, die von allen Unterklassen von Alien geerbt werden. Das heißt, Alien sollte eigentlich keine Textur haben und sollte keine eigenen definierten Werte haben.Eine Basisklasse erben, die von SKSpriteNode in Swift

//Generic alien type: a blue-print of sorts 
    class Alien:SKSpriteNode{ 

     let velocityVector:CGVector 
     let startPos:CGPoint 

     init(texture:SKTexture, startPosition startPos:CGPoint,moveSpeed: CGFloat,velocityVector:CGVector){ 
      super.init(texture: texture, color: UIColor.clearColor(), size: texture.size()) 

      self.velocityVector = normalizeVector(velocityVector) 
      self.position = position 
     } 

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

Jedes Mal, wenn ich versuchen, diese Einrichtung ich in einer Handvoll von Fehlern führen, wie:

"Use of instance member 'normalizeVector' on type GameScene; did you mean to use a value of type GameScene instead?" 

normalizeVector ist eine Funktion, die über der Alien Klasse geschrieben wird (innerhalb GameScene). Ich bin nicht sicher, was das bedeutet, da dies eine normale Funktion innerhalb des GameScene ist. Wenn ich dieses Stück entfernen, erhalte ich immer noch den Fehler:

"Property self.velocityVector is not initialized at super.init call" 

Ich bin verwirrt, weil ich gedacht hatte, dass super.init() war nur notwendig, weil ich eine Unterklasse von SKSpriteNode machte und dass es nicht zu haben braucht die an die Unterklasse spezifischen Eigenschaften.

Schließlich gibt es eine Möglichkeit, super.init() ohne eine tatsächliche Textur aufrufen, wie diese Blueprint-Klasse wird nie "angezeigt" werden? Nachdem ich die Apple-Dokumentation über Klassen/Initialisierung durchgelesen habe, bin ich immer noch festgefahren. Jede Hilfe wäre großartig, danke.

+0

Warum definieren Sie 'Alien' in' GameScene'? Eine separate Datei wäre angemessener. –

+0

@appzYourLife Ich habe etwas recherchiert und nicht viel gefunden - sollte ich alle Klassen außerhalb von GameScene schreiben? Wie steht es mit der Spiellogik? – Sam

+1

Es ist eine gute Übung, verschiedene Klassen in verschiedenen Dateien zu schreiben. Bitte lesen Sie auch den [SpriteKit Programmierleitfaden] (https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Introduction/Introduction.html). –

Antwort

2

Sie haben ein paar Probleme, vor allem, da die Fehlermeldung sagt, müssen Sie alle Variablen initialisieren, bevor Sie super.init nennen:

init(texture:SKTexture, startPosition startPos:CGPoint,moveSpeed: CGFloat,velocityVector:CGVector){ 
    self.velocityVector = Alien.normalizeVector(velocityVector) 
    self.startPos = startPos 

    super.init(texture: texture, color: UIColor.clearColor(), size: texture.size()) 

    self.position = position 
} 

Zweitens, es klingt wie du bist Definieren normalizeVector in einer Unterklasse oder woanders? Was ich getan habe, war, es als eine statische Methode zu definieren (da es vor der Initialisierung verwendet wird, kann es keine Instanzmethode sein) und dann können Sie es in der init-Methode verwenden. Setzen Sie alles zusammen und es sieht so aus:

class Alien:SKSpriteNode { 
    static func normalizeVector(vector:CGVector) -> CGVector { 
     let len = sqrt(vector.dx * vector.dx + vector.dy * vector.dy) 

     return CGVector(dx:vector.dx/len, dy:vector.dy/len) 
    } 

    let velocityVector:CGVector 
    let startPos:CGPoint 

    init(texture:SKTexture, startPosition startPos:CGPoint,moveSpeed: CGFloat,velocityVector:CGVector){ 
     self.velocityVector = Alien.normalizeVector(velocityVector) 
     self.startPos = startPos 

     super.init(texture: texture, color: UIColor.clearColor(), size: texture.size()) 

     self.position = position 
    } 

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

@ David Berry Danke, das war sehr hilfreich. Ich bin immer noch neugierig, warum ich keine einzige Funktion in der Klasse nennen könnte. Meine Funktion sah fast identisch mit deiner aus, aber sie wurde direkt über der Klasse platziert (innerhalb von GameScene). Ich habe diesen Fehler erhalten: '" Benutze das Instanzmitglied 'normalizeVector' vom Typ GameScene. Hast du stattdessen einen Wert vom Typ GameScene verwendet? "' Warum wird 'moveSpeed' hier nicht initialisiert? – Sam

+0

'moveSpeed' wird nicht benutzt, weil Sie es nicht für irgendwas verwenden, vielleicht wollten Sie ein anderes' let moveSpeed: CGFloat' erstellen, in welchem ​​Fall Sie es initialisieren sollten, bevor Sie 'super.init' aufrufen . Wie bei 'normalizeVector' funktionieren die Dinge immer noch wie erwartet, wenn ich sie aus der Klasse auf die Dateiebene heraushole.Vielleicht haben Sie es versehentlich in eine andere Klasse eingebettet? –

0

Sie haben velocityVector als eine nicht optionale Eigenschaft deklariert, also erhalten Sie natürlich einen Compilerfehler, wenn Sie es nicht in Ihrem Initialisierer auffüllen.

Deshalb, wenn Sie diese Zeile kommentieren, erhalten Sie einen Kompilierungsfehler.

self.velocityVector = normalizeVector(velocityVector)