FactoryMethodパターンでリファクタリングすると、ゲーム開発がどう便利になるのかをSwiftコードで学ぶiOS SDKとSwiftで始めるゲーム作成入門(6)(4/4 ページ)

» 2016年05月17日 05時00分 公開
[杉本裕樹マネーフォワード]
前のページへ 1|2|3|4       

FactoryMethodパターンを使って自機の生成を改善

 最後に、生成処理をFactoryMethodパターンを使ってリファクタリングしようと思います。

 FactoryMethodパターンとはGoFデザインパターンの1つで、オブジェクトの生成に関するものです。Charの生成処理をFactoryに持たせることで分岐を減らそうと思います。

 まずは、「CharFactory.swift」を作って以下のように書いてください。

class CharFactory {
    func createChar() -> Char {
        return Char()
    }
}
 
class Char1Factory: CharFactory {
    override func createChar() -> Char {
        return Char1()
    }
}
 
class Char2Factory: CharFactory {
    override func createChar() -> Char {
        return Char2()
    }
}
 
class Char3Factory: CharFactory {
    override func createChar() -> Char {
        return Char3()
    }
}

 次に自機をセットする処理を修正します。SetCharScene.swiftを修正します。

class SetCharScene: SKScene {
    var coin = 100
    var charData = [(factory: CharFactory, position: CGPoint)]()
 
    // 省略
 
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if touches.count == 1, let point = touches.first?.locationInNode(self) {
            let alert = UIAlertController(title: nil, message: "どのキャラクターを設置しますか?",
                                          preferredStyle: .Alert)
            let rootViewController = UIApplication.sharedApplication().delegate?.window??.rootViewController
            alert.addAction(UIAlertAction(title: "Char1を設置", style: .Default, handler: { _ in
                let factory = Char1Factory()
                let char = factory.createChar()
                char.position = point
                self.coin -= char.cost
                self.addChild(char)
                self.charData.append((factory: factory, position: point))
            }))
            alert.addAction(UIAlertAction(title: "Char2を設置", style: .Default, handler: { _ in
                let factory = Char2Factory()
                let char = factory.createChar()
                char.position = point
                self.coin -= char.cost
                self.addChild(char)
                self.charData.append((factory: factory, position: point))
            }))
            alert.addAction(UIAlertAction(title: "Char3を設置", style: .Default, handler: { _ in
                let factory = Char3Factory()
                let char = Char3()
                char.position = point
                self.coin -= char.cost
                self.addChild(char)
                self.charData.append((factory: factory, position: point))
            }))
            alert.addAction(UIAlertAction(title: "キャンセル", style: .Cancel, handler: nil))
            rootViewController?.presentViewController(alert, animated: true, completion: nil)
        }
    }
}

 次にGameSceneのcreateCharsも少し修正します。今まであった分岐がなくなりすっきりとしました。

class GameScene: SKScene, SKPhysicsContactDelegate {
    // 省略
    func createChars(charData: [(factory: CharFactory, position: CGPoint)]) {
        charData.forEach {
            let char = $0.factory.createChar()
            char.position = $0.position
            char.physicsBody = SKPhysicsBody(rectangleOfSize: char.size)
            char.physicsBody?.contactTestBitMask = 0x1
            addChild(char)
            chars.append(char)
        }
    }
    // 省略
}

 以上でFactoryMethodパターンを使った書き換えは終了です。FactoryMethodパターンを使ったことで「どのCharを生成するか」の処理をSetCharSceneだけに持たせることができました。これによって、今後Charの種類が増えたときもSetCharSceneの変更だけで済むようになりました。

 FactoryMethodパターンは局所的なパターンで、とても使いやすいので、機会あればぜひ試してみてください。

次回は、iOS 9のReplayKitも使う

 今回はFactoryMethodパターンを使いつつ自機の配置周りの改善を行ってきました。

 今回実装したソースコード「konkai.zip」は、こちらからダウンロードできます

 次回はタワーディフェンスとして不足している機能の実装を進めてゲームとしての完成度を高めていきます。iOS 9から登場したゲーム録画機能ができるReplayKitも使っていくので、どうぞお楽しみに。

筆者紹介

杉本裕樹

田町のベンチャーで働くエンジニア。

仕事ではiPhoneアプリの開発やRailsを使ったWebサービス開発を行っている。最近のマイブームはUnityを使った3Dゲーム開発。


前のページへ 1|2|3|4       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。