前言
今天非常開心,觀看cocos官方直播居然在幾千人中中獎,可以買彩票了,
言歸正傳,所謂的人工智能,也就是大家常說的AI(Artificial Intelligence),一說到AI可能就會讓人覺得比較深奧,其實也就是非玩家角色思考和行為的綜合,比如,在什么樣的條件下,觸發什么樣的行為,
其實我們在游戲開發中的AI要比學術理論中的AI簡單很多,甚至有些行為不需要AI也能體現,比如使用劇情對話體現非玩家角色的想法,
那么AI 都涉及到哪些東西呢?
- 控制器
我理解的控制器,就是非玩家角色的大腦,是用來思考事情的,例如通過執行決策樹,得到一個有效的行為,使用不一樣的控制器就會有不一樣的思考方式,比如玩家的控制器就是根據按鍵操作觸發不同的行為,阿貓,阿狗的可能又不一樣了, - 感知器
獲得周圍環境的情況,不如距離誰有多遠,自身生命值多少,玩家生命值多少,等等, - 反應
也就是控制器執行決策樹后產生的有效行為,比如跳躍,跑,各種攻擊,防御等等, - 決策樹
我理解為思考時的思路,比如應該在什么樣的條件下執行什么樣的反應,比如當我的血量低于百分之30的時候我要逃跑,具體案例體現在我的游戲《星際迷航》的第一個boss身上, - 記憶
就是非玩家角色可以通過存盤資料,供控制器執行的時候使用,以提高非玩家角色的智商, - 學習
這個能力太牛逼了,實作起來也比較復雜,需要大量的資料和計算量為依托,而且在游戲開發中也并不一定實用,因此我也沒用過,
如何應用到程式中呢?
-
首先還是要定義好行為列舉,通過狀態機,不同的行為實作不同的邏輯,


-
定義感知器特征
不同的游戲感知的特征肯定是不一樣的,根據游戲需求而定

-
實作感知類

-
定義決策樹
export default class DecisionTree {
private decisionData: XlsxData;
private perception: Perception;
constructor(data: XlsxData) {
this.decisionData = https://www.cnblogs.com/cgw0827/p/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;
}
}
}
}
}
- 定義控制器
export default class EnemyController extends GameController {
private perception: Perception = new Perception();
private ai: DecisionTree;
constructor() {
super()
let ai_data: XlsxData = https://www.cnblogs.com/cgw0827/p/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)
}
}
-
在非玩家角色中宣告控制器和行為管理器

-
定義思考函式
think() {
this.ai.action(this, this.model.getAI())
}
- 呼叫

在動作執行結束后,如果非玩家角色沒有死亡,就會執行一次,然后再決策樹中呼叫非玩家角色的設定行為的方法,

至此 ,就執行了一次AI的完整流程,從代碼中我們可以看到,控制器是通過配置表資料執行操作的,接下來我們看配置表部分,
配置資料

- 首先資料表是二維的,我們要通過二維表模擬了樹形結構,判定條件就是感知特征的列舉值,判定引數是留給感知器使用的引數,如果不需要可以不填,中文部分可以僅用于注釋,并不會匯出,判定條件成立或者不成立的時候都會用0和1來決定是繼續判定還是處理行為選擇,如果是0 后一列的資料會填寫下一個節點的ID,也就是繼續思考,如果是1,表示可以執行對應的處理, 此時,后邊的列里邊我是存放了行為列舉值和對應的概率,因為并不是所有行為都是百分之百執行的,將這個表匯出之后提供給控制器使用就可以了,
- 資料表的索引方式
對于簡單的ai,可以一個敵人對應一個決策樹ID;對于復雜的AI,可以一個敵人的一個動作對應一個決策樹AI,所以這里拋出了一個問題,就是手動填寫這樣的表,維護成本也比較高了,所以這里對于復雜的AI需求,建議自己開發個小工具,這樣用起來不易出錯,且容易維護,
結語
以上就是我個人對游戲開發中AI的理解,當然我是拜讀了《游戲人工智能——計算機游戲中的人工智能》這本書的,好像此書已經絕版了,希望放出來對熱衷于游戲開發的小伙伴們有所幫助,
長按下方二維碼,關注《微笑游戲》公眾號,獲取更多精彩內容,

歡迎掃碼關注公眾號《微笑游戲》,瀏覽更多內容,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/31137.html
標籤:其他
上一篇:【科創人獨家】云風:從創業到招安,自由的游戲玩家+務實的程式員
下一篇:一個可屏蔽長短鏈接的網路模塊
