最後に、生成処理を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パターンは局所的なパターンで、とても使いやすいので、機会あればぜひ試してみてください。
今回はFactoryMethodパターンを使いつつ自機の配置周りの改善を行ってきました。
今回実装したソースコード「konkai.zip」は、こちらからダウンロードできます。
次回はタワーディフェンスとして不足している機能の実装を進めてゲームとしての完成度を高めていきます。iOS 9から登場したゲーム録画機能ができるReplayKitも使っていくので、どうぞお楽しみに。
田町のベンチャーで働くエンジニア。
仕事ではiPhoneアプリの開発やRailsを使ったWebサービス開発を行っている。最近のマイブームはUnityを使った3Dゲーム開発。
Copyright © ITmedia, Inc. All Rights Reserved.
Smart & Social 記事ランキング