iOS 9の最新機能で自動ルート検索を簡単にゲームに組み込む:iOS SDKとSwiftで始めるゲーム作成入門(3)(1/3 ページ)
iPhoneゲームをSwift言語で作成してみたいという初心者向けにiOSのゲームフレームワークを使った作り方を一から解説する入門連載。今回は、敵の動きを改善する。GameplayKitのPathfindingを使ったルートの自動探索の使い方についてSpriteKitのSKActionでの実装と比べて解説。
iOS SDK 9の「GameplayKit」を使う
前回の「SwiftのSpriteKitで実装―タワーディフェンスゲームの大枠の作り方とコツ」では敵と味方の配置・移動と接触時の処理を実装してきました。ぼんやりとゲームの大枠が見えてきたのではないかと思います。
今回は敵の動きを改善しようと思います。今までは敵は真っすぐに移動するだけでしたが今回は道に沿って移動させます。移動経路の計算には、iOS SDK 9で登場したばかりの「GameplayKit」という最新フレームワークも利用します。
実装に入る前に本連載で作るアプリの完成形を確認しておきます。本連載では下記6つのルールを満たすタワーディフェンスを作っていきます。
- プレーヤーは開始前に与えられた所持金を元に、敵を攻撃するユニットを設置する
- ゲームは「Wave(ウェーブ)」という単位で行われる。基本的には1つのWaveで登場する敵の種類は1種類のみとなっている。Waveが始まると敵は入口から登場し、目的地に向かって行進する。プレーヤーが設置したユニットは攻撃可能範囲に入ると自動的に攻撃を行う
- 1Waveの敵を全て全滅させるとWaveクリアとなる。プレーヤーは次のWaveが始まるまでにユニットの増強(新設・アップグレード・売却など)を行う
- 以上の2と3を繰り返して行う
- 敵が目的地に到達すると、自分が所持しているライフが減少する。全て失うとゲームオーバーとなる
- ライフを全て失う前に、最終Waveの敵を全て全滅させることができればクリアとなる
今回はルール2に関する部分を実装していきます。
敵の通る道を2次元配列で作る
まずは画面に敵の通る道を表示します。キャラクターだけではなく、道の素材も「ぴぽや倉庫」のものを使わせていただきました。
最初に、こちらのFields.zipをダウンロードして、そこから「Field0.png」「Field1.png」という画像を取り出してください。
それらをXcodeのAssets.xcassetsファイルにドラッグ&ドロップすると、下図のように登録されると思います。
次は、これらの画像をフィールドに表示します。「GameScene.swift」のdidMoveToViewを以下のように書き換えてみましょう。
class GameScene: SKScene, SKPhysicsContactDelegate { // …略 override func didMoveToView(view: SKView) { physicsWorld.gravity = CGVectorMake(0, 0) physicsWorld.contactDelegate = self // 元々あった処理 /* let fieldImageLength: CGFloat = 32 for i in 0...Int(frame.size.width / fieldImageLength) + 1 { for j in 0...Int(frame.size.height / fieldImageLength) + 1 { let field = SKSpriteNode(imageNamed: "Field") field.position = CGPoint(x: CGFloat(i) * fieldImageLength, y: CGFloat(j) * fieldImageLength) field.zPosition = -1 addChild(field) } } */ let fieldData = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ] let fieldImageLength = view.frame.width / 10 for (i, data) in fieldData.enumerate() { for (j, value) in data.enumerate() { let field = SKSpriteNode(imageNamed: "Field\(value)") field.name = "Field\(value)" field.size = CGSize(width: fieldImageLength, height: fieldImageLength) field.physicsBody = SKPhysicsBody(rectangleOfSize: field.size) field.physicsBody?.categoryBitMask = 0x0 field.physicsBody?.collisionBitMask = 0x0 field.position = CGPoint( x: CGFloat(j) * fieldImageLength, y: view.frame.height - CGFloat(i - 1) * fieldImageLength) field.zPosition = -1 addChild(field) } } // …略 } // …略 }
アプリを起動するとフィールド上に敵の通り道が表示されていることが確認できると思います。
「0」が草むら、「1」が道の2次元配列
フィールドの情報はfieldDataという2次元配列の変数を使って表すようにしました(22〜43行目)。fieldDataの「0」が草むらで、「1」が道を表しています。上図の画面と22〜43行目のソースコードを見比べると、「1」が道になっていることを確認できると思います。
let fieldData = [ // …略 ]
フィールドの1パネルの大きさを画面サイズに合わせる
今回からはフィールドの1パネルの大きさを画面サイズによって変わるようにしました。こうすることで複数の画面サイズに対応できます。
let fieldImageLength = view.frame.width / 10
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 開発者向けiOS 9、WatchOS 2、Swift 2、Xcode 7の新機能と新しいApple Developer Programの参考情報まとめ
iOS 9、WatchOS 2、Swift 2、Xcode 7の新機能や、Apple Developer Programについて、その概要とアップルが公開している参考情報をまとめて紹介します。 - Apple WatchやiPhoneのアプリを作ろう! Playgroundで学ぶSwiftの基礎―変数、定数、型、演算
本連載では、これからプログラミングやiPhoneアプリ開発を始めてみたい方を対象に、開発に必要な知識を基礎から解説していきます。今回は、Swiftの変数、定数、型、演算などについてサンプルプログラムを交えて解説します。 - iOSアプリ開発でObjective-CからSwiftに移行するための手順、注意点まとめ〜言語仕様の違いは? 連携時の呼び出し方は?
開発生産性や品質を向上させたいiOSアプリ開発者のためにObjective-CからSwiftへ移行するメリットや手順、注意点など勘所をまとめて紹介します。 - いまなら無料! Unityで始めるiPhoneゲーム作成“超”入門
3Dコンテンツ開発ツール「Unity」を使った、簡単な3Dミニゲーム制作の流れを一から解説していきます