連載
» 2017年05月23日 05時00分 UPDATE

ゲームの「敵」キャラで分かる「人工知能」の作り方(3) :iOS GameplayKitのRule SystemsでゲームAIプログラミングはどう変わるのか (1/2)

iPhone向け鬼ごっこアプリを作りながら人工知能(AI)について学んでいく連載。今回は、さらにゲーム性を持たせるため「経過時間によって鬼の移動速度が変わる」という修正を条件式を使って行い、その条件式をRule Systemsで管理する。

[杉本裕樹,マネーフォワード]

 本連載『ゲームの「敵」キャラで分かる「人工知能」の作り方』では、iPhone向け鬼ごっこアプリを作りながら人工知能(AI)について学んでいきます。鬼の動きにAIを活用して、自動でプレイヤーを追いかけるようなAIを作ります。

 前回の「SwiftのGameplayKitでAIに追いかける、避ける、逃げる処理を追加するには」まで、「Agents, Goals, and Behaviors」の「GKAgent2D」「GKGoal」「GKBehavior」クラスを使って、AIに「追い掛ける」「遠ざかる」などさまざまな動きを実装しました。

 今回は、さらにゲーム性を持たせるため「経過時間によって鬼の移動速度が変わる」という修正を行います。

 具体的には、下記のような修正を条件式を使って行い、その条件式をGameplayKitの「Rule Systems」という機能で管理します。

  1. 各30秒のうち25〜30秒の間は敵のスピードがアップする
  2. 1分ごとに鬼のスピードが上がっていく(3分間上がり続ける)

 前回のソースコードは、こちらです。今回は、このソースコードを元に機能を追加します。

ゲーム上に経過時間を表示

 最初にゲーム上に経過時間を表示します。GameScene.swiftを下記のように修正します。

class GameScene: SKScene {
    // 省略
    let timeLabel = SKLabelNode(text: "○秒") // 今回追加
 
    override func didMove(to view: SKView) {
        // 省略
 
        // ここから今回追加
        timeLabel.fontSize = 60
        timeLabel.position = CGPoint(x: frame.size.width / 2 - 80, y: frame.size.height / 2 - 80)
        addChild(timeLabel)
        // ここまで今回追加
    }
}

 GameScene.swiftのupdateメソッドを以下のように修正してください。これはラベルに秒数をセットする処理です。

class GameScene: SKScene {
    // 省略
 
    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))
        let time = Int(currentTime - startTime) // 今回追加
        timeLabel.text = "\(time)秒" // 今回追加
 
        // 省略
    }
 
    // 省略
}

 これで画面の右上に経過秒数を表示できました。

コラム「SpriteKitの位置指定について」

 SpriteKitですが、UIKitとは要素の位置指定が違うので注意が必要です。

 まずは、「(x: 0, y: 0)」と指定したときの位置が異なります。UIKitでは画面左上に配置されますが、SpriteKitの場合は画面中心に配置されます。

 他にも、UIKitでは画面下部の方がy値が大きく、SpriteKitは画面上部の方がy値が大きいという違いもあります。

 この辺りは慣れるまで戸惑うことが多いので注意が必要です。


経過時間を元に鬼の速度を変える

 次は、経過時間を元に鬼の速度を変える修正を行います。GameSceneのupdateメソッドを下のように修正してください。

class GameScene: SKScene {
    // 省略
 
    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))
        let time = Int(currentTime - startTime)
        timeLabel.text = "\(time)秒"
        // ここから今回追加
        var enemySpeedRate: Float = 1.0
        if time % 30 >= 25 {
            enemySpeedRate += 3.0
        }
        if time >= 60 {
            enemySpeedRate += 1.0
        }
        if time >= 120 {
            enemySpeedRate += 1.0
        }
        if time >= 180 {
            enemySpeedRate += 1.0
        }
        enemyAgents.forEach {
            $0.maxAcceleration = 30 * enemySpeedRate
            $0.maxSpeed = 20 * enemySpeedRate
        }
        // ここまで今回追加
 
        // 省略
    }
 
    // 省略
}

 これで秒数によって鬼のスピードが変わるようになりました。

 ここまで経過時間によって鬼のスピードが変わるように実装しました。次ページからは、実装した条件式を「Rule Systems」で管理します。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。