iOS GameplayKitの「Agents, Goals, and Behaviors」で作る、鬼ごっごの鬼AI:ゲームの「敵」キャラで分かる「人工知能」の作り方(1)(3/3 ページ)
iPhone向け鬼ごっこアプリを作りながら人工知能(AI)について学んでいく連載。Appleが提供する「SpriteKit」「GameplayKit」の2つのフレームワークを使いながらゲームAIを作っていきます。
Agents, Goals, and Behaviorsを使う
最後に鬼の動きを「Agents, Goals, and Behaviors」を使った形に置き換えてみようと思います。「GameScene.swift」を下のように修正します。
import SpriteKit import GameplayKit class GameScene: SKScene { let player = SKShapeNode(circleOfRadius: 10) var enemies = [SKShapeNode]() var timer: Timer? var prevTime: TimeInterval = 0 var startTime: TimeInterval = 0 var isGameFinished = false // ここから今回追加分 let playerAgent = GKAgent2D() let agentSystem = GKComponentSystem(componentClass: GKAgent2D.self) var enemyAgents = [GKAgent2D]() // ここまで今回追加分 // 省略 func createEnemy() { let enemy = SKShapeNode(circleOfRadius: 10) enemy.position.x = size.width / 2 enemy.fillColor = UIColor(red: 0.94, green: 0.14, blue: 0.08, alpha: 1.0) enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.frame.width / 2) addChild(enemy) enemies.append(enemy) // ここから今回追加分 let anemyAgent = GKAgent2D() anemyAgent.maxAcceleration = 30 anemyAgent.maxSpeed = 70 anemyAgent.position = vector_float2(x: Float(enemy.position.x), y: Float(enemy.position.y)) anemyAgent.delegate = self anemyAgent.behavior = GKBehavior(goals: [ GKGoal(toSeekAgent: playerAgent), ]) agentSystem.addComponent(anemyAgent) enemyAgents.append(anemyAgent) // ここまで今回追加分 } override func update(_ currentTime: TimeInterval) { if prevTime == 0 { prevTime = currentTime startTime = currentTime } // ここから今回追加分 agentSystem.update(deltaTime: currentTime - prevTime) playerAgent.position = vector_float2(x: Float(player.position.x), y: Float(player.position.y)) // ここまで今回追加分 // 下は今回で削除 // if Int(currentTime) != Int(prevTime) { // enemies.forEach { enemy, _ in // enemy.removeAllActions() // // let path = CGMutablePath() // path.move(to: CGPoint()) // path.addLine(to: CGPoint(x: player.position.x - enemy.position.x, y: player.position.y - enemy.position.y)) // enemy.run(SKAction.follow(path, speed: 50.0)) // } // } if !isGameFinished { for enemy in enemies { let dx = enemy.position.x - player.position.x let dy = enemy.position.y - player.position.y if sqrt(dx*dx + dy*dy) < player.frame.width / 2 + enemy.frame.width / 2 { isGameFinished = true timer?.invalidate() let label = SKLabelNode(text: "記録:\(Int(currentTime - startTime))秒") label.fontSize = 80 label.position = CGPoint(x: 0, y: -100) addChild(label) break } } } prevTime = currentTime } } // ここから今回追加分 extension GameScene: GKAgentDelegate { func agentDidUpdate(_ agent: GKAgent) { if let agent = agent as? GKAgent2D, let index = enemyAgents.index(where: { $0 == agent }) { let enemy = enemies[index] enemy.position = CGPoint(x: CGFloat(agent.position.x), y: CGFloat(agent.position.y)) } } } // ここまで今回追加分
アプリを起動すると、鬼がプレイヤーを追い掛けてくるのが分かります。
GKAgent2D、GKGoals、GKBehaviorの役割
今回は「GKAgent2D」「GKGoal」「GKBehavior」という3つのクラスを使いました。名前の通り、この3つが「Agents, Goals, and Behaviors」の主な要素です。
GKGoalは1つ1つのルールを表現するクラスです。今回は「GKGoal(toSeekAgent: playerAgent)」というplayerAgentに向かって動くようなものでした。逆にplayerAgentから逃げたり、特定の障害物を避けたりするものなどを作ることもできます。
そしてGKGoalをまとめるのがGKBehaviorクラスです。GKBehaviorは1つ以上のGKGoalを重み付け込みで管理します。今回はGKGoalが1つでしたが、次回以降では複数のGKGoalを使っていこうと思います。
GKAgent2Dはルールに基づいて移動するクラスです。GKAgent2DにGKBehaviorインスタンスを渡すことで、ルールに基づいた行動をするようになります。
次回は、さらに複雑な条件で動くAIを作る
今回は「Agents, Goals, and Behaviors」を使ったAIを作ってみましたがいかがでしたか。次回は障害物や味方キャラクターを追加して、さらに複雑な条件で動くAIを作ってみようと思います。
今回作成したコードは、こちらからダウンロードできます。
筆者紹介
杉本裕樹
田町のベンチャーで働くエンジニア。
仕事ではiPhoneアプリの開発やRailsを使ったWebサービス開発を行っている。最近のマイブームはUnityを使った3Dゲーム開発。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- iOS 9の最新機能で自動ルート検索を簡単にゲームに組み込む
iPhoneゲームをSwift言語で作成してみたいという初心者向けにiOSのゲームフレームワークを使った作り方を一から解説する入門連載。今回は、敵の動きを改善する。GameplayKitのPathfindingを使ったルートの自動探索の使い方についてSpriteKitのSKActionでの実装と比べて解説。 - iOS 10 SDKの新機能SiriKit、音声認識、iMessage拡張を自作アプリに生かすには
iOS 10で開発者にAPIが解放されたと話題の音声アシスタント「Siri」。その実態はどんなものなのか。SiriKit、Speech/Messages Frameworkの使い方と併せて、簡単なアプリを作りながら解説します。 - スマホ世代でも分かるMacの基本的な使い方&Xcodeをインストールする手順
本連載では、これからプログラミングやiPhoneアプリ開発を始めてみたい方を対象に、開発に必要な知識を基礎から解説していきます。今回は、プログラミングを学び始める前に、まずはMacの基本的な使い方を学び、Xcodeをインストールし、Playgroundを起動してみましょう。