iPhoneゲームをSwift言語で作成してみたいという初心者向けにiOSのゲームフレームワークを使った作り方を一から解説する入門連載。今回は、ステージを1から3に増やし、出てくる敵の種類もステージに応じて変わるようにします。さらに「ReplayKit」というフレームワークも使ってプレー動画の撮影・共有機能を実装します。
本連載「iOS SDKとSwiftで始めるゲーム作成入門」は、iPhone向けのゲーム開発の入門連載です。タワーディフェンスを題材に、「SpriteKit」というゲーム開発フレームワークの解説やゲームの開発手法について書いています。
実装に入る前に本連載で作るアプリの完成形を確認しておきます。本連載では、下記6つのルールを満たすタワーディフェンスを作っていきます。
前回の「FactoryMethodパターンでリファクタリングすると、ゲーム開発がどう便利になるのかをSwiftコードで学ぶ」では自機を3種類から自由に選べるようにしました。それと同時にGoFデザインパターンの1つであるFactoryMethodパターンを使って、複数種類のオブジェクト生成をすっきりさせる方法を学んできました。
今回はステージも1から3に増やし、出て来る敵の種類もステージに応じて変わるようにします。さらにiOS 9から追加された「ReplayKit」というフレームワークを使ってプレー動画の撮影・共有機能も実装します。
今回は、こちらのコードを元に実装を進めていきます。
今は1ステージだけクリアすればゲーム終了になります。これをステージ3までクリアすればゲーム終了になるように変更します。ステージとステージの間では、自機を設置できるようにします。
まずはSetCharScene.swiftを以下のように変更してください。stageプロパティと前のステージからのデータ引き継ぎ処理を入れます。
class SetCharScene: SKScene { var stage = 1 // 省略 override func didMoveToView(view: SKView) { // 省略 let button = Button(text: "ゲーム開始", rect: buttonRect, afterTap: { let scene = GameScene(fileNamed: "GameScene") scene?.stage = self.stage // この1行を追加 scene?.scaleMode = .ResizeFill view.presentScene(scene) scene?.createChars(self.charData) }) addChild(button) } // 前ステージから情報を引き継ぐ為のメソッド func createChars(charData: [(factory: CharFactory, position: CGPoint)]) { charData.forEach { let char = $0.factory.createChar() char.position = $0.position char.physicsBody = SKPhysicsBody(rectangleOfSize: char.size) addChild(char) self.charData.append($0) } } // 省略 }
続けてGameScene.swiftも修正します。
class GameScene: SKScene, SKPhysicsContactDelegate { var stage = 1 var charData = [(factory: CharFactory, position: CGPoint)]() // 省略 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) self.charData.append($0) // この1行を追加 } } // 省略 override func update(currentTime: NSTimeInterval) { chars.forEach { char in char.stateMachine.updateWithDeltaTime(currentTime) if let charState = char.stateMachine.currentState as? Char.CharState where charState.enableToAttack() { enemyList.enemiesCloseToPoint(char.frame.origin, distance: 50).forEach { $0.life -= charState.power char.stateMachine.enterState(Char.StayState.self) if $0.life <= 0 { $0.physicsBody?.node?.removeFromParent() $0.physicsBody?.node?.removeAllActions() if enemyList.isAllEnemyRemoved() { // ここから追加処理 if stage < 3 { let scene = SetCharScene() scene.stage = self.stage + 1 scene.scaleMode = .ResizeFill scene.createChars(charData) self.view?.presentScene(scene) return } // ここまで追加処理 state = .GameClear let myLabel = SKLabelNode(fontNamed: "HiraginoSans-W6") myLabel.text = "ゲームクリア" myLabel.fontSize = 45 myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame) - 20) addChild(myLabel) } } } } } } }
実行すると、ステージが1から3に増えていることが分かります。
Copyright © ITmedia, Inc. All Rights Reserved.