2017-04-22 45 views
0

我想使用Swift做一個簡單的遊戲。遊戲具有不同的級別,每個級別都要求遊戲的行爲方式略有不同。我決定爲每個級別使用不同的類,這些類都是從基本級別繼承而來的。在Swift類中重寫的可選函數?

這是基礎:

import SpriteKit 

class LevelBase { 

    var scene: GameScene! // Seems very dodgy 
    var blocks = [SKSpriteNode]() 

    init(scene: GameScene) { // Should this be required init? 
    self.scene = scene 
    } 

    func filterBlock(_ block: SKSpriteNode) { 
    blocks = blocks.filter() { $0 !== block } // Looks really dodgy to me 
    } 

    func update(time: TimeInterval) { 
    // For override 
    } 

    func levelUp() { 
    // For override 
    } 

    func postGenerate() { 
    // For override 
    } 
} 

但是,對我來說,這個類似乎很不好寫。我無法在類中創建的任何函數的任何地方被覆蓋,這讓我覺得我做錯了什麼。我應該如何使用擴展或協議來實現可選功能?我不太明白他們是如何工作的,所以迄今爲止我還沒有使用過。

的第二個問題是,這一類需要與遊戲場景變量初始化,因爲有些水平需要它來添加或刪除精靈。考慮到課程是在遊戲場景的文件中創建的,這看起來特別狡猾。

當然有更好的方法嗎?

+0

創建您可以提取共同的功能,以誰的方法給出的默認實現在擴展協議。符合類型可以使用這種默認行爲,或者自己實現它 – Alexander

+0

我寧願有一個(最終)級別的類,我可以實例化具有該方法的對象。 – vikingosegundo

+0

https://en.wikipedia.org/wiki/Composition_over_inheritance – vikingosegundo

回答

3

我有SpriteKit沒有經驗,但是從一般的角度來看,你應該考慮到"Favour composition over Inheritance"

你將有一個不用於子類,但可以有不同的實現對象或值來實例化一個等級類。

此外,您應該使用協議來定義這些協議,您可以添加默認實現作爲協議擴展。

final class Level { 
    init(levelImplementation: LevelImplementationType) { 
     self.levelImplementation = levelImplementation 
    } 

    let levelImplementation: LevelImplementationType 

    func navigate() { 
     levelImplementation.navigate() 
    } 

    func update(timeInterval: TimeInterval) { 
     levelImplementation.update(timeInterval: timeInterval) 
    } 

} 

水平將與對象被實例化或結構符合LevelImplementationType

protocol LevelImplementationType { 
    func navigate() 
    func update(timeInterval: TimeInterval) 
} 

默認的實現可以通過擴展來完成。

extension LevelImplementationType { 
    func navigate() { 

    } 
    func update(timeInterval: TimeInterval) { 

    } 
} 

的LevelImpelmenation需要順應LevelImplementationType,但沒有任何進一步的限制。即它們可以具有非常不同的初始化器。

struct LevelImplementation1: LevelImplementationType { 
    // useses default implementation of `navigate` and `update` from extension 
} 

struct LevelImplementation2: LevelImplementationType { 
    // useses default implementation of `update` from extension 

    func navigate() { 
    } 
} 

struct LevelFileImplementation: LevelImplementationType { 
    init(with path: String) { 
     // read variables from file at path 
    } 

    func navigate() { 
     // navigate as given in file 
    } 

} 

級實例甘蔗像

let level1 = Level(levelImplementation: LevelImplementation1()) 
let level2 = Level(levelImplementation: LevelImplementation2()) 
let level3 = Level(levelImplementation: LevelFileImplementation(with: "path/to/file")) 
+0

此外,對於這個愚蠢的問題感到抱歉,但爲什麼當實現是結構時,這個關卡是基於類的呢? – MysteryPancake

+0

另外,當我試圖使用擴展名爲協議定義默認值時,我該如何定義filterBlock?塊表中不存在的擴展,僅在基本級別的文件,所以我不能訪問它:'擴展LevelImplementation { FUNC filterBlock(_塊:SKSpriteNode){ badBlocks = badBlocks.filter(){$ 0 !==塊} chosenBlocks = chosenBlocks.filter(){$ 0!==塊}} } '不工作 – MysteryPancake

+0

我想我會開始一個新的線程 – MysteryPancake