diff --git a/examples/bte_ai.erl b/examples/bte_ai.erl new file mode 100644 index 0000000..ae17cd2 --- /dev/null +++ b/examples/bte_ai.erl @@ -0,0 +1,73 @@ +%% @author zouv +%% @doc use bte for ai + +-module(bte_ai). + +-include_lib("erlbte/include/common.hrl"). + +-export([ + init/1, + tick/1 + ]). + +init(Data) -> + {ok, Json, _} = rfc4627:decode(Data), % depend on rfc4627_jsonrpc + RootId = get_field_string(Json, "root"), + {ok, NodesJson} = rfc4627:get_field(Json, "nodes"), + NodeList = init_nodes([RootId], NodesJson, []), + CustomNodesModule = bte_node_behaviour:init_nodes_moudle(?MODULE), % load self-defined bte node + BteConfigData = + #r_bte_config_data{ + root_id = RootId, + nodes = NodeList, + custom_nodes_moudle = CustomNodesModule + }, + BteStatus = bte_behavior:init(BteConfigData), + {ok, BteStatus}. + +init_nodes([], _NodesJson, NodeList) -> + NodeList; +init_nodes([Id | LeftIdList], NodesJson, NodeList) -> + {ok, NodeJson} = rfc4627:get_field(NodesJson, Id), + Name = get_field_string(NodeJson, "name"), + {ok, Parameters} = rfc4627:get_field(NodeJson, "parameters"), + ChildId = binary_to_list(rfc4627:get_field(NodeJson, "child", <<>>)), + Children = lists:map(fun(E) -> binary_to_list(E) end, rfc4627:get_field(NodeJson, "children", [])), + BteNode = + #r_bte_config_node{ + id = Id, + name = Name, + parameters = get_all(Parameters), + child = ChildId, + children = Children + }, + NewNodeList = [BteNode | NodeList], + if + ChildId /= "" -> + init_nodes([ChildId | LeftIdList], NodesJson, NewNodeList); + Children /= [] -> + init_nodes(Children ++ LeftIdList, NodesJson, NewNodeList); + true -> + init_nodes(LeftIdList, NodesJson, NewNodeList) + end. + +get_field_string(Json, Key) -> + {ok, Value} = rfc4627:get_field(Json, Key), + binary_to_list(Value). + +get_all(Parameters) -> + {obj, PrapList} = Parameters, + lists:map(fun({EKey, EValue}) -> + if + is_binary(EValue) -> + ENewValue = binary_to_list(EValue); + true -> + ENewValue = EValue + end, + {EKey, ENewValue} + end, + PrapList). + +tick(BteStatus) -> + bte_behavior:tick(BteStatus). + diff --git a/examples/bte_ai_test.erl b/examples/bte_ai_test.erl new file mode 100644 index 0000000..71bd469 --- /dev/null +++ b/examples/bte_ai_test.erl @@ -0,0 +1,29 @@ +%% @author zouv +%% @doc testing bte ai + +-module(bte_ai_test). + +-include_lib("erlbte/include/common.hrl"). + +-export([ + test/1 + ]). + +% json file edit by "Behavior3JS Edotor" +% url: http://behavior3js.guineashots.com +test(FileName) -> + case file:read_file("json/" ++ FileName) of + {ok, EBinary} -> + {ok, BteStatus} = bte_ai:init(EBinary), + io:format("test___1 ~p~n", [BteStatus#r_bte_status.status]), + BteStatus1 = bte_ai:tick(BteStatus), + io:format("test___2 ~p~n", [BteStatus1#r_bte_status.status]), + % BteStatus2 = bte_ai:tick(BteStatus1), % testing bte stack + % BteStatus3 = bte_ai:tick(BteStatus2), + % BteStatus4 = bte_ai:tick(BteStatus3), + % BteStatus5 = bte_ai:tick(BteStatus4), + ok; + _ -> + skip + end. + diff --git a/examples/json/test1.json b/examples/json/test1.json new file mode 100644 index 0000000..73dbff7 --- /dev/null +++ b/examples/json/test1.json @@ -0,0 +1,54 @@ +{ + "title": "A Behavior Tree", + "description": "", + "root": "8f154647-d5a8-46b0-83af-35324d33773c", + "display": { + "camera_x": 1366, + "camera_y": 648, + "camera_z": 1, + "x": -368, + "y": -64 + }, + "properties": {}, + "nodes": { + "8f154647-d5a8-46b0-83af-35324d33773c": { + "id": "8f154647-d5a8-46b0-83af-35324d33773c", + "name": "Sequence", + "title": "Sequence", + "description": "顺序节点", + "display": { + "x": -160, + "y": -64 + }, + "parameters": {}, + "properties": {}, + "children": [ + "2af0f62a-2956-4e38-93db-28d07438164a" + ] + }, + "2af0f62a-2956-4e38-93db-28d07438164a": { + "id": "2af0f62a-2956-4e38-93db-28d07438164a", + "name": "Wait", + "title": "Wait", + "description": "", + "display": { + "x": 48, + "y": -64 + }, + "parameters": { + "milliseconds": "" + }, + "properties": { + "milliseconds": "单位毫秒" + } + } + }, + "g_value": { + "parameters": {}, + "id": "GlobalValue", + "name": "GlobalValue", + "title": "GlobalValue", + "description": "全局变量" + }, + "custom_nodes": [] +} \ No newline at end of file diff --git a/examples/json/test1.png b/examples/json/test1.png new file mode 100644 index 0000000..1259a05 Binary files /dev/null and b/examples/json/test1.png differ diff --git a/examples/json/test2.json b/examples/json/test2.json new file mode 100644 index 0000000..dcc180f --- /dev/null +++ b/examples/json/test2.json @@ -0,0 +1,101 @@ +{ + "title": "A Behavior Tree", + "description": "", + "root": "aaa47257-0bd6-478a-87b7-dc925a003d6d", + "display": { + "camera_x": 1366, + "camera_y": 648, + "camera_z": 1, + "x": -496, + "y": -32 + }, + "properties": {}, + "nodes": { + "1682e79b-b870-4314-83fd-0b72734b7be8": { + "id": "1682e79b-b870-4314-83fd-0b72734b7be8", + "name": "Wait", + "title": "Wait", + "description": "", + "display": { + "x": 128, + "y": -64 + }, + "parameters": { + "milliseconds": "" + }, + "properties": { + "milliseconds": "单位毫秒" + } + }, + "fe7005b4-f1d4-472e-a289-7736b19665f3": { + "id": "fe7005b4-f1d4-472e-a289-7736b19665f3", + "name": "Init", + "title": "Init", + "description": "", + "display": { + "x": -80, + "y": 0 + }, + "parameters": {}, + "properties": {}, + "child": "eb1ed18e-e51e-4beb-8322-009eb91d77a2" + }, + "eb1ed18e-e51e-4beb-8322-009eb91d77a2": { + "id": "eb1ed18e-e51e-4beb-8322-009eb91d77a2", + "name": "Wait", + "title": "Wait", + "description": "", + "display": { + "x": 128, + "y": 0 + }, + "parameters": { + "milliseconds": "" + }, + "properties": { + "milliseconds": "单位毫秒" + } + }, + "aaa47257-0bd6-478a-87b7-dc925a003d6d": { + "id": "aaa47257-0bd6-478a-87b7-dc925a003d6d", + "name": "Selector", + "title": "Selector", + "description": "选择节点", + "display": { + "x": -288, + "y": -32 + }, + "parameters": {}, + "properties": {}, + "children": [ + "2e04f772-8d39-44da-8ea3-fd31a6b42d4a", + "fe7005b4-f1d4-472e-a289-7736b19665f3" + ] + }, + "2e04f772-8d39-44da-8ea3-fd31a6b42d4a": { + "id": "2e04f772-8d39-44da-8ea3-fd31a6b42d4a", + "name": "RepeatUntilSuccess", + "title": "RepeatUntilSuccess", + "description": "重复执行直到子节点返回成功", + "display": { + "x": -80, + "y": -64 + }, + "parameters": { + "maxLoop": -1 + }, + "properties": { + "maxLoop": "最大重复次数,-1表示无限" + }, + "child": "1682e79b-b870-4314-83fd-0b72734b7be8" + } + }, + "g_value": { + "parameters": {}, + "id": "GlobalValue", + "name": "GlobalValue", + "title": "GlobalValue", + "description": "全局变量" + }, + "custom_nodes": [] +} \ No newline at end of file diff --git a/examples/json/test2.png b/examples/json/test2.png new file mode 100644 index 0000000..33fdb2f Binary files /dev/null and b/examples/json/test2.png differ diff --git a/examples/json/test3.json b/examples/json/test3.json new file mode 100644 index 0000000..6b26c23 --- /dev/null +++ b/examples/json/test3.json @@ -0,0 +1,135 @@ +{ + "title": "A Behavior Tree", + "description": "", + "root": "b7025cc5-af44-4a7c-b627-f51968b51088", + "display": { + "camera_x": 1366, + "camera_y": 648, + "camera_z": 1, + "x": -464, + "y": -16 + }, + "properties": {}, + "nodes": { + "b7025cc5-af44-4a7c-b627-f51968b51088": { + "id": "b7025cc5-af44-4a7c-b627-f51968b51088", + "name": "RandomSelector", + "title": "RandomSelector", + "description": "随机选择节点", + "display": { + "x": -256, + "y": -16 + }, + "parameters": {}, + "properties": {}, + "children": [ + "0cb499a9-abff-4809-8afc-b132c0bb6cbe", + "5e3b77f6-7d41-46cc-98c1-b40be501ef0a", + "b09496f8-4192-46e7-9114-19eca4048ad3" + ] + }, + "0cb499a9-abff-4809-8afc-b132c0bb6cbe": { + "id": "0cb499a9-abff-4809-8afc-b132c0bb6cbe", + "name": "RepeatUntilSuccess", + "title": "RepeatUntilSuccess", + "description": "重复执行直到子节点返回成功", + "display": { + "x": -48, + "y": -80 + }, + "parameters": { + "maxLoop": -1 + }, + "properties": { + "maxLoop": "最大重复次数,-1表示无限" + }, + "child": "5381fa95-811b-4b65-a61c-ef6f4bd5539a" + }, + "5381fa95-811b-4b65-a61c-ef6f4bd5539a": { + "id": "5381fa95-811b-4b65-a61c-ef6f4bd5539a", + "name": "Inverter", + "title": "Inverter", + "description": "", + "display": { + "x": 160, + "y": -80 + }, + "parameters": {}, + "properties": {}, + "child": "cff3d48e-896b-4f62-87cc-f7a1c2d4f3ef" + }, + "cff3d48e-896b-4f62-87cc-f7a1c2d4f3ef": { + "id": "cff3d48e-896b-4f62-87cc-f7a1c2d4f3ef", + "name": "Wait", + "title": "Wait", + "description": "", + "display": { + "x": 368, + "y": -80 + }, + "parameters": { + "milliseconds": "" + }, + "properties": { + "milliseconds": "单位毫秒" + } + }, + "b09496f8-4192-46e7-9114-19eca4048ad3": { + "id": "b09496f8-4192-46e7-9114-19eca4048ad3", + "name": "Wait", + "title": "Wait", + "description": "", + "display": { + "x": -48, + "y": 48 + }, + "parameters": { + "milliseconds": "" + }, + "properties": { + "milliseconds": "单位毫秒" + } + }, + "5e3b77f6-7d41-46cc-98c1-b40be501ef0a": { + "id": "5e3b77f6-7d41-46cc-98c1-b40be501ef0a", + "name": "Repeater", + "title": "Repeater", + "description": "重复执行", + "display": { + "x": -48, + "y": -16 + }, + "parameters": { + "maxLoop": 3 + }, + "properties": { + "maxLoop": "最大重复次数,-1表示无限" + }, + "child": "58d3d3a6-5105-467e-88d3-184857c848aa" + }, + "58d3d3a6-5105-467e-88d3-184857c848aa": { + "id": "58d3d3a6-5105-467e-88d3-184857c848aa", + "name": "Wait", + "title": "Wait", + "description": "", + "display": { + "x": 160, + "y": -16 + }, + "parameters": { + "milliseconds": "" + }, + "properties": { + "milliseconds": "单位毫秒" + } + } + }, + "g_value": { + "parameters": {}, + "id": "GlobalValue", + "name": "GlobalValue", + "title": "GlobalValue", + "description": "全局变量" + }, + "custom_nodes": [] +} \ No newline at end of file diff --git a/examples/json/test3.png b/examples/json/test3.png new file mode 100644 index 0000000..7059907 Binary files /dev/null and b/examples/json/test3.png differ