1. 程式人生 > >遊戲開發中的人工智慧

遊戲開發中的人工智慧

# 前言 今天非常開心,觀看cocos官方直播居然在幾千人中中獎,可以買彩票了。 言歸正傳,所謂的人工智慧,也就是大家常說的AI(Artificial Intelligence)。一說到AI可能就會讓人覺得比較深奧,其實也就是非玩家角色思考和行為的綜合。比如,在什麼樣的條件下,觸發什麼樣的行為。 其實我們在遊戲開發中的AI要比學術理論中的AI簡單很多,甚至有些行為不需要AI也能體現。比如使用劇情對話體現非玩家角色的想法。 那麼AI 都涉及到哪些東西呢? 1. 控制器 我理解的控制器,就是非玩家角色的大腦,是用來思考事情的。例如通過執行決策樹,得到一個有效的行為。使用不一樣的控制器就會有不一樣的思考方式。比如玩家的控制器就是根據按鍵操作觸發不同的行為。阿貓,阿狗的可能又不一樣了。 2. 感知器 獲得周圍環境的情況,不如距離誰有多遠,自身生命值多少,玩家生命值多少,等等。 3. 反應 也就是控制器執行決策樹後產生的有效行為。比如跳躍,跑,各種攻擊,防禦等等。 4. 決策樹 我理解為思考時的思路,比如應該在什麼樣的條件下執行什麼樣的反應。比如當我的血量低於百分之30的時候我要逃跑。具體案例體現在我的遊戲《星際迷航》的第一個boss身上。 5. 記憶 就是非玩家角色可以通過儲存資料,供控制器執行的時候使用,以提高非玩家角色的智商。 6. 學習 這個能力太牛逼了。實現起來也比較複雜,需要大量的資料和計算量為依託,而且在遊戲開發中也並不一定實用。因此我也沒用過。 # 如何應用到程式中呢? 1. 首先還是要定義好行為列舉,通過狀態機,不同的行為實現不同的邏輯。 ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230636677-1154121108.png) ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230636845-2088653090.png) 2. 定義感知器特徵 不同的遊戲感知的特徵肯定是不一樣的,根據遊戲需求而定 ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230637136-1045796394.png) 3. 實現感知類 ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230637347-803699459.png) 4. 定義決策樹 ``` 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; } } } } } ``` 5. 定義控制器 ``` 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) } } ``` 6. 在非玩家角色中宣告控制器和行為管理器 ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230637602-514497123.png) 7. 定義思考函式 ``` think() { this.ai.action(this, this.model.getAI()) } ``` 8. 呼叫 ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230637782-1318073394.png) 在動作執行結束後,如果非玩家角色沒有死亡,就會執行一次。然後再決策樹中呼叫非玩家角色的設定行為的方法。 ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230637970-110809141.png) 至此 ,就執行了一次AI的完整流程。從程式碼中我們可以看到,控制器是通過配置表資料執行操作的,接下來我們看配置表部分。 # 配置資料 ![image.png](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230638184-266043555.png) 1. 首先資料表是二維的,我們要通過二維表模擬了樹形結構。判定條件就是感知特徵的列舉值,判定引數是留給感知器使用的引數,如果不需要可以不填,中文部分可以僅用於註釋,並不會匯出,判定條件成立或者不成立的時候都會用0和1來決定是繼續判定還是處理行為選擇。如果是0 後一列的資料會填寫下一個節點的ID,也就是繼續思考,如果是1,表示可以執行對應的處理。 此時,後邊的列裡邊我是存放了行為列舉值和對應的概率。因為並不是所有行為都是百分之百執行的。將這個表匯出之後提供給控制器使用就可以了。 3. 資料表的索引方式 對於簡單的ai,可以一個敵人對應一個決策樹ID;對於複雜的AI,可以一個敵人的一個動作對應一個決策樹AI。所以這裡丟擲了一個問題,就是手動填寫這樣的表,維護成本也比較高了,所以這裡對於複雜的AI需求,建議自己開發個小工具,這樣用起來不易出錯,且容易維護。 # 結語 以上就是我個人對遊戲開發中AI的理解,當然我是拜讀了《遊戲人工智慧——計算機遊戲中的人工智慧》這本書的。好像此書已經絕版了。希望放出來對熱衷於遊戲開發的小夥伴們有所幫助。 # 長按下方二維碼,關注《微笑遊戲》公眾號,獲取更多精彩內容。 ![image](https://img2020.cnblogs.com/other/330473/202007/330473-20200701230638421-835422696.webp) 歡迎掃碼關注公眾號《微笑遊戲》,瀏覽更多