英雄遠征Erlang源碼分析(8)-怪物相關

與怪物相關的模塊有三個:mod_mon_create.erl,mod_mon_active.erl,lib_mon.erl
mod_mon_create:創建負責創建怪物的進程,通過mod_mon_create:create_mon([MonId, Scene, X, Y, Type])創建怪物進程

怪物創建進程的state
-record(state, {auto_id}).
用於保存怪物的自增id,每一個怪物id都不同

mod_mon_active負責創建怪物進程,每個怪物進程是一個有限狀態機(gen_fsm)

怪物進程state保存當前怪物所追蹤的玩家Pid列表,當前怪物的#ets_mon信息

在mod_mon_active:start([Id,MonId,Scene,X,Y,Type])中創建怪物進程,根據配置表和傳入的參數,初始化一個#ets_mon,插入到?ETS_MON表中,進程進入sleep狀態。

怪物進程的有限狀態機主要有以下幾種狀態:
sleep:休眠狀態,怪物進程被創建後爲該狀態,當有玩家進入追蹤範圍後會去跟隨(trace)
trace:跟隨狀態,如果玩家進入攻擊範圍則發起戰鬥,否則繼續跟隨,或者玩家離開追蹤範圍,則返回出生點(back)
back:返回出生點,進入sleep狀態
rerive:復活,進入sleep狀態

sleep,trace狀態中如果怪物Hp爲0,則進入rerive狀態。
怪物進程接收last_red_hp消息,收到該消息後會減少hp,當hp爲0時,無論何種狀態都進入revive

有限狀態機大致圖示:

初始化 -> sleep

sleep - timeout - 未死亡 - 附近有玩家 -> trace
sleep - timeout - 未死亡 - 附近沒有玩家 -> sleep
sleep - timeout - 已死亡 -> revive

trace - timeout - 在攻擊範圍內 - mod_battle:battle/2發起戰鬥 -> trace
trace - timeout - 不足攻擊範圍 -trace_line - move -> trace
trace - timeout - 在追蹤範圍外 -> back
trace - timeout - 怪物死亡 -> revive

trace - repeat -> trace

back - timeout - 返回(瞬移)出生點 -> sleep

revive - timeout - #ets_mon.retime大於0 -> sleep
revive - timeout - #ets_mon.retime小於0 -> 關閉怪物進程

任何狀態下 - 掉血 - 怪物死亡 -> revive
任何狀態下 - 掉血 - 怪物未死亡 -> 狀態不變

怪物進程中兩個handle_info方法:
handle_info(clear, _StateName, [Att, Minfo])    清除怪物,停止進程
handle_info({last_red_hp, Hp, _Pid}, StateName, [Att, Minfo])    掉血,修改後的#ets_mon回寫?ETS_MON

距離相關方法:

is_attack(Status,X,Y):判斷是否進入攻擊距離,根據#ets_mon.att_area判斷

trace_area(Status,X,Y):判斷是否進入追蹤距離,根據#ets_mon.trace_area判斷

trace_line(X1,Y1,X2,Y2,AttArea):計算追蹤玩家所需要走的路線,返回移動的下一個座標點,每次移動2格

move(X,Y,[Pid,Minfo]):怪物移動,判斷區域是否有障礙,將怪物新座標寫回?ETS_MON

auto_move(Minfo):隨機移動,每次走兩格

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章