behavior3行为树
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

126 Zeilen
4.1 KiB

  1. %%%-------------------------------------------------------------------
  2. %%% @author DY
  3. %%% @copyright (C) 2020, <COMPANY>
  4. %%% @doc
  5. %%% 游戏进程
  6. %%% @end
  7. %%%-------------------------------------------------------------------
  8. -module(game_process).
  9. -behaviour(gen_server).
  10. -include("example.hrl").
  11. -export([start_link/0]).
  12. -export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
  13. -define(SERVER, ?MODULE).
  14. %%%===================================================================
  15. %%% Spawning and gen_server implementation
  16. %%%===================================================================
  17. start_link() ->
  18. gen_server:start_link(?MODULE, [], []).
  19. init([]) ->
  20. {TitleMaps, TreeMaps, TreeNodeMaps} = behavior_tree:load_tree_file("examples/example.json"),
  21. ZombieList = [
  22. %% <<"HUNTER"/utf8>>,
  23. %% <<"BOMMER"/utf8>>,
  24. %% <<"JOCKEY"/utf8>>,
  25. %% <<"SOMKER"/utf8>>,
  26. %% <<"SPITTER"/utf8>>,
  27. %% <<"CHARGER"/utf8>>,
  28. %% <<"TANK"/utf8>>,
  29. <<"WITCH"/utf8>>
  30. ],
  31. init_zombie(ZombieList, TitleMaps, TreeMaps, TreeNodeMaps),
  32. UID = <<"凯恩"/utf8>>,
  33. init_patrol(UID, TitleMaps, TreeMaps, TreeNodeMaps),
  34. erlang:put(uid_list, ZombieList ++ [UID]),
  35. self() ! run,
  36. {ok, #{frame => 1}}.
  37. handle_call(_Request, _From, State) ->
  38. {reply, ok, State}.
  39. handle_cast(_Request, State) ->
  40. {noreply, State}.
  41. handle_info(run, #{frame := Frame} = State) ->
  42. try
  43. ?INFO("~w分钟", [Frame]),
  44. Fun = fun(UID) -> run(UID) end,
  45. lists:foreach(Fun, get(uid_list)),
  46. erlang:send_after(1000, self(), run),
  47. {noreply, State#{frame := Frame + 1}}
  48. catch
  49. Error:Reason:StackTrace ->
  50. ?INFO("Error:~w Reason:~w ~n StackTrace:~p", [Error, Reason, StackTrace]),
  51. {stop, normal, State}
  52. end;
  53. handle_info(finish, State) ->
  54. {stop, normal, State};
  55. handle_info({died, UID}, State) ->
  56. erlang:put(uid_list, lists:delete(UID, erlang:get(uid_list))),
  57. {noreply, State};
  58. handle_info(_Info, State) ->
  59. {noreply, State}.
  60. %%%===================================================================
  61. %%% Internal functions
  62. %%%===================================================================
  63. new_state(UID, Type, CurGrid) ->
  64. case Type of
  65. ?HUMAN ->
  66. Power = ?MAX_POWER;
  67. ?ZOMBIE ->
  68. Power = ?RAND(?MAX_POWER div 2, ?MAX_POWER)
  69. end,
  70. State = #{
  71. uid => UID,
  72. type => Type,
  73. cur_state => ?STATE_TYPE_IDLE,
  74. cur_power => Power,
  75. cur_rage => 0,
  76. grid_list => [],
  77. cur_grid => CurGrid,
  78. rival_list => [],
  79. misc => #{}
  80. },
  81. ?INFO("生成单位:~tp", [State]),
  82. State.
  83. init_zombie([UID | T], TitleMaps, TreeMaps, TreeNodeMaps) ->
  84. {ok, InitiativeBTreeID} = behavior_tree:init_btree_by_title(<<"丧尸主动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps),
  85. {ok, PassivityBTreeID} = behavior_tree:init_btree_by_title(<<"丧尸被动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps),
  86. game_dict:put_initiative_btree_id(UID, InitiativeBTreeID),
  87. game_dict:put_passivity_btree_id(UID, PassivityBTreeID),
  88. Grid = {?RAND(0, ?MAX_X), ?RAND(0, ?MAX_Y)},
  89. game_dict:put_role_state(UID, new_state(UID, ?ZOMBIE, Grid)),
  90. init_zombie(T, TitleMaps, TreeMaps, TreeNodeMaps);
  91. init_zombie([], _TitleMaps, _TreeMaps, _TreeNodeMaps) ->
  92. ok.
  93. init_patrol(UID, TitleMaps, TreeMaps, TreeNodeMaps) ->
  94. {ok, InitiativeBTreeID} = behavior_tree:init_btree_by_title(<<"巡逻兵主动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps),
  95. {ok, PassivityBTreeID} = behavior_tree:init_btree_by_title(<<"巡逻兵被动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps),
  96. game_dict:put_initiative_btree_id(UID, InitiativeBTreeID),
  97. game_dict:put_passivity_btree_id(UID, PassivityBTreeID),
  98. Grid = {?RAND(0, ?MAX_X), ?RAND(0, ?MAX_Y)},
  99. game_dict:put_role_state(UID, new_state(UID, ?HUMAN, Grid)).
  100. run(UID) ->
  101. BTreeID = game_dict:get_initiative_btree_id(UID),
  102. #{cur_state := CurState} = State = game_dict:get_role_state(UID),
  103. case ?IS_STATE(?STATE_TYPE_DEAD, CurState) of
  104. true ->
  105. ok;
  106. false ->
  107. {_, State1} = behavior_tree:execute(BTreeID, State),
  108. game_dict:put_role_state(UID, State1)
  109. end.