遊戲開發中的人工智能

前言

今天很是開心,觀看cocos官方直播竟然在幾千人中中獎,能夠買彩票了。
言歸正傳,所謂的人工智能,也就是你們常說的AI(Artificial Intelligence)。一說到AI可能就會讓人以爲比較深奧,其實也就是非玩家角色思考和行爲的綜合。好比,在什麼樣的條件下,觸發什麼樣的行爲。
其實咱們在遊戲開發中的AI要比學術理論中的AI簡單不少,甚至有些行爲不須要AI也能體現。好比使用劇情對話體現非玩家角色的想法。
那麼AI 都涉及到哪些東西呢?dom

  1. 控制器
    我理解的控制器,就是非玩家角色的大腦,是用來思考事情的。例如經過執行決策樹,獲得一個有效的行爲。使用不同的控制器就會有不同的思考方式。好比玩家的控制器就是根據按鍵操做觸發不一樣的行爲。阿貓,阿狗的可能又不同了。
  2. 感知器
    得到周圍環境的狀況,不如距離誰有多遠,自身生命值多少,玩家生命值多少,等等。
  3. 反應
    也就是控制器執行決策樹後產生的有效行爲。好比跳躍,跑,各類攻擊,防護等等。
  4. 決策樹
    我理解爲思考時的思路,好比應該在什麼樣的條件下執行什麼樣的反應。好比當個人血量低於百分之30的時候我要逃跑。具體案例體如今個人遊戲《星際迷航》的第一個boss身上。
  5. 記憶
    就是非玩家角色能夠經過存儲數據,供控制器執行的時候使用,以提升非玩家角色的智商。
  6. 學習
    這個能力太牛逼了。實現起來也比較複雜,須要大量的數據和計算量爲依託,並且在遊戲開發中也並不必定實用。所以我也沒用過。

如何應用到程序中呢?

  1. 首先仍是要定義好行爲枚舉,經過狀態機,不一樣的行爲實現不一樣的邏輯。
    image.png
    image.png函數

  2. 定義感知器特徵
    不一樣的遊戲感知的特徵確定是不同的,根據遊戲需求而定
    image.png工具

  3. 實現感知類
    image.png學習

  4. 定義決策樹this

export default class DecisionTree {

    private decisionData: XlsxData;
    private perception: Perception;

    constructor(data: XlsxData) {
        this.decisionData = data;
    }

    setPerception(perception: Perception) {
        this.perception = perception;
    }

    getPerception(obj, perceptionType: PerceptionType, value: number) {
        return this.perception.action(obj, perceptionType, value)
    }
    //開始思考
    action(obj: RoleView, decisionID: number) {

        let data = this.decisionData.getRowData(decisionID)
        let flag = false;
        if (data) {
            let perceptionType = data[Ai_dataEnum.condition];
            let type = 0;
            let id: number[] = null;
            flag = this.perception.action(obj, perceptionType, data[Ai_dataEnum.cParam])
            if (flag) {
                type = data[Ai_dataEnum.conditionYes]
                id = data[Ai_dataEnum.parm1]
            } else {
                type = data[Ai_dataEnum.conditionNo]
                id = data[Ai_dataEnum.parm2]
            }
            this.judge(obj, type, id)
        }else{
        }
        return flag;
    }
    //斷定感知條件
    private judge(obj: RoleView, type: ThinkType, param: number[]) {
        if (type == ThinkType.ACTION) {
            this.doLogic(obj, param)
        } else {
            for (let index = 0; index < param.length; index++) {
                const element = param[index];
                if (this.action(obj, element)) {
                    break;//目前僅支持串行,不支持並行。如需支持並行,須要添加是否攔截字段。
                }
            }
        }
    }

    // 50 30 20 : 80  根據機率選擇行爲
    private doLogic(obj: RoleView, param: number[]) {
        if (param.length > 0) {
            let r = RandomHelper.random(0, 100);
            let count = param.length / 2
            for (let index = 0; index < count; index++) {
                let behaveType: number = param[index * 2]
                let random: number = param[index * 2 + 1]
                //
                if (r <= random) {
                    // 設置非玩家角色的行爲。
                    obj.setBehaveType(behaveType)
                    return;
                }
            }
        }


    }
}
  1. 定義控制器
export default class EnemyController extends GameController {

    private perception: Perception = new Perception();
    private ai: DecisionTree;
    constructor() {
        super()
        let ai_data: XlsxData = GameDataManager.instance().get(DataName.ai_data)
        this.ai = new DecisionTree(ai_data)
        this.ai.setPerception(this.perception)
    }

    getPerception(obj, perceptionType: PerceptionType, value: number) {
        return this.perception.action(obj, perceptionType, value)
    }

    action(obj: RoleView, decisionID: number) {
        this.ai.action(obj, decisionID)
    }
}
  1. 在非玩家角色中聲明控制器和行爲管理器
    image.png人工智能

  2. 定義思考函數3d

think() {
        this.ai.action(this, this.model.getAI())
    }
  1. 調用
    image.png
    在動做執行結束後,若是非玩家角色沒有死亡,就會執行一次。而後再決策樹中調用非玩家角色的設置行爲的方法。
    image.png
    至此 ,就執行了一次AI的完整流程。從代碼中咱們能夠看到,控制器是經過配置表數據執行操做的,接下來咱們看配置表部分。

配置數據

image.png

  1. 首先數據表是二維的,咱們要經過二維表模擬了樹形結構。斷定條件就是感知特徵的枚舉值,斷定參數是留給感知器使用的參數,若是不須要能夠不填,中文部分能夠僅用於註釋,並不會導出,斷定條件成立或者不成立的時候都會用0和1來決定是繼續斷定仍是處理行爲選擇。若是是0 後一列的數據會填寫下一個節點的ID,也就是繼續思考,若是是1,表示能夠執行對應的處理。 此時,後邊的列裏邊我是存放了行爲枚舉值和對應的機率。由於並非全部行爲都是百分之百執行的。將這個表導出以後提供給控制器使用就能夠了。
  2. 數據表的索引方式
    對於簡單的ai,能夠一個敵人對應一個決策樹ID;對於複雜的AI,能夠一個敵人的一個動做對應一個決策樹AI。因此這裏拋出了一個問題,就是手動填寫這樣的表,維護成本也比較高了,因此這裏對於複雜的AI需求,建議本身開發個小工具,這樣用起來不易出錯,且容易維護。

結語

以上就是我我的對遊戲開發中AI的理解,固然我是拜讀了《遊戲人工智能——計算機遊戲中的人工智能》這本書的。好像此書已經絕版了。但願放出來對熱衷於遊戲開發的小夥伴們有所幫助。code

長按下方二維碼,關注《微笑遊戲》公衆號,獲取更多精彩內容。

image

歡迎掃碼關注公衆號《微笑遊戲》,瀏覽更多內容。blog

相關文章
相關標籤/搜索