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に増えていることが分かります。
開発者向けiOS 9、WatchOS 2、Swift 2、Xcode 7の新機能と新しいApple Developer Programの参考情報まとめ
Apple WatchやiPhoneのアプリを作ろう! Playgroundで学ぶSwiftの基礎―変数、定数、型、演算
iOSアプリ開発でObjective-CからSwiftに移行するための手順、注意点まとめ〜言語仕様の違いは? 連携時の呼び出し方は?Copyright © ITmedia, Inc. All Rights Reserved.