LoginSignup
18
17

More than 5 years have passed since last update.

[Swift]状態を共有して変化を伝播させるサンプル~didSetなど~

Last updated at Posted at 2014-11-13

異なるクラス間で状態を共有する方法。

いくつか方法はありますが、今回はdelegateを使います。

あと、共有すると、状態の変化も伝播させたいですよね。

didSetと組み合わせて、"変更"を伝播させてみましょう。

GameSample.swift


/**
*  Delegateを定義する
*/
protocol PlayerDelegate: class {
    func improveStatus(newLevel:Int)->Void
}


/**
*  コントローラー
*/
class FieldViewController:UIViewController {

    var player:Player!
    var enemy:Enemy!

    @IBOutlet weak var enemyAttackButton: UIButton!
    @IBOutlet weak var playerAttackButton: UIButton!


    override func viewDidLoad(){
        super.viewDidLoad()

        self.playerAttackButton.addTarget(self, action: "playerAttack", forControlEvents: .TouchUpInside)
        self.enemyAttackButton.addTarget(self, action: "enemyAttack", forControlEvents: .TouchUpInside)

        self.player = Player.instance

        self.player.status.level = 2

        self.enemy = Enemy()
    }

    func enemyAttack(){
        self.player.status.hp -= self.enemy.status.attack
    }

    func playerAttack(){
        self.enemy.status.hp -= self.player.status.attack
    }

}


/**
*  プレイヤーのステータスセット
*/
class PlayerStatus {

    var delegate:PlayerDelegate?

    var level:Int = 1 {
        didSet {
            /// 変更されたら、新しいレベルに会わせて能力値が向上する
            self.delegate?.improveStatus(self.level)
            println("-- change level at delegate --")
        }
    }

    private var hp:Int = 1 {
        didSet {
            println("-- change hp --")
            println(self.hp.description)
            if self.hp < 0 {
                self.isAlive = false
            }
        }
    }

    private var power:Int = 1
    private var defence:Int = 1
    private var skil:Skil = .None

    var attack:Int {
        get {
            return self.power + self.skil.rawValue
        }
    }

    enum Skil:Int {
        case Cold = 10
        case Fire = 20
        case None = 0
    }

    var isAlive:Bool = true {
        didSet {
            if self.isAlive == false {
                // "負けました."アラートを出してスタートに戻る
            }
        }
    }
}


class GameMaster:PlayerDelegate {


    var status:PlayerStatus!


    init(){
        self.status = PlayerStatus()
        self.status.delegate = self

        /// level 1 からスタート
        self.status.level = 1
    }


    /**
    Levelアップ時のロジックを書く
    */
    func improveStatus(newLevel: Int) {

        println("-- change level --")

        self.status.hp = 15 * newLevel
        self.status.power = 5 * newLevel
        self.status.defence = 5 * newLevel

        if newLevel > 15 {
            self.status.skil = .Cold
            return
        }
        if newLevel > 5 {
            self.status.skil = .Cold
        }
    }


    /// instance
    class var instance:GameMaster {
        struct i {
            static let instance = GameMaster()
        }
        return i.instance
    }

}


/**
*  プレイヤーオブジェクト
*/
class Player {

    var status:PlayerStatus!

    init(){
        /// GameMasterからStatusセットをもらう
        let master = GameMaster()
        self.status = master.status
        self.status.level = 1
    }

    /// instance
    class var instance:Player {
        struct i {
            static let instance = Player()
        }
        return i.instance
    }
}


/**
*  敵のオブジェクト
*/
class Enemy {

    /// 本当はEnemyStatusを用意すべき
    var status:PlayerStatus!

    init(){
        let master = GameMaster()
        self.status = master.status
        self.status.level = 1
    }
}



18
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
17