From 48f5371c25273efd9a8d27762098a5602fcd1390 Mon Sep 17 00:00:00 2001 From: zouv Date: Wed, 28 Sep 2016 17:30:33 +0800 Subject: [PATCH] add examples --- examples/bte_ai.erl | 73 +++++++++++++++++++++ examples/bte_ai_test.erl | 29 +++++++++ examples/json/test1.json | 54 ++++++++++++++++ examples/json/test1.png | Bin 0 -> 2670 bytes examples/json/test2.json | 101 +++++++++++++++++++++++++++++ examples/json/test2.png | Bin 0 -> 7429 bytes examples/json/test3.json | 135 +++++++++++++++++++++++++++++++++++++++ examples/json/test3.png | Bin 0 -> 12112 bytes 8 files changed, 392 insertions(+) create mode 100644 examples/bte_ai.erl create mode 100644 examples/bte_ai_test.erl create mode 100644 examples/json/test1.json create mode 100644 examples/json/test1.png create mode 100644 examples/json/test2.json create mode 100644 examples/json/test2.png create mode 100644 examples/json/test3.json create mode 100644 examples/json/test3.png 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 0000000000000000000000000000000000000000..1259a055dfa971d1160744f6d35d886b8e8889de GIT binary patch literal 2670 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 LSKCJG>-YZ##|#w4 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..33fdb2f24d12a52d7e6921a8308d1e783e8d54f5 GIT binary patch literal 7429 zcmeHM_fu0*x0MbOB!Kj86zLu5K@d=oCIqBJ0qI4g89;hhx=0O8Kzgr+-itseh5(^R z@0}pMy!g$$f8fpg@w-3VxpU^unRC|JXRW>0{-UGxoZ>Fi-8*;gP^i67*1dBF4}<&e zBPGVY^>=vQ+_}Rtq^7J0@l4;HBZ`8e=fe*N**&;*XXnZg-Y!ad90;QDB|_?lfgC-- zCOiUcvvWLqxM%nh{8$>fDq17kBx|$Rk5%KU-Pzg8kVRd#wB=eH@6X?6X~aK7&)p7y z@2JI3Cvx(s={^W6eW><@p*sHIqj&x4@d=;*JNW+vh^PUEgrn%Dm&u{j@nW-p(*I^7 zH?~^g_NrzD6fg6QldtXzL#f!1@H5XLu@Sk&+qR3X5==O|9|Ie4`M63AnE(Y6m3 znT(X(Z^lS1N6}bfPmTtK!u$Hz{T&z7DMVFoZ?127E;$~eorXmEhVoOb z;f`ymHuvykFL!Ee$ORE*q!VOZDc=Y8ug}-Bo-MQk42fg_MX5OIbYWV{sd2DMhakoFXOXhrnkG!8(gf2;FOjYTa+@RHbMJ zgf0_qrOHf<|M~tm{;QY4BFeFGGoQReoqgM}2AL$#e9(!x!j8;Wnw5pMKXUYHzCM}B zraZkqou>@E98oCq*j#{Wi}c*b{P?B?kCxp-EbeDSogVz0_Zw`z+-uq?sc5zTby|yI ztkxw%AhhNGj%OP`GF(r08wM83aivIcsc~_X#mEu&)m37Nd zm*KbGyLG~i&5Xt%<5W(*zls2ZVgurF_ji>BUDAejd5N7Mb_AgE3o1yLSTOgqm-bHZ zuJkbDdW_ptVOkE%s=s)7>_`chbZ z)XVOF>lYj3d*v+894Fs+Q(TZP)^3BEvGP-O}jq=_Zx<*(|d z#%z^TWWI0Ot;c-YE~8&7_zmqPf;W7p>X4a)x>*qr1Nsf1EDMuSy)yGDj?KkVv7plYlq4}_LQVj<|oy8IBGw z5u8#dQx;v^Gq~UenS9#Jd)A-f+)0Kh`}qexheL1C+M@awSIM@^YbAzZ(Lw%2sOyal z+%CWJ4$1YDMu|BJKR;19lE3;z{e-c@^|pKtPs(}~M)4|jyS&NiiS6ijM=Vlu#Ne&h z>H!-yHK98rF20%%T6HK~^(t{OA3oVp^~Za^C3~dN(~(7NpC+pc7uqsDYXkOMYrX56 z1zE$bXG@W~e*R6B@%nvchk+6}0FJ-22)0KG)EgqsdRQGub8(B60W6rig6aFE0=`7b z#`>fjig{qHk`HQ}JBa8*T1!LejJYA*8lejwqmnP$9?C8O`>%WhiReh@^?cZT&9uSi zmQy(~3nunOdDTsOjeIPUrWIVb*dis;-)FvVBk~^gop<@Jwu5|;5|ftUEUqs|4V<_I z8#i)x+6gEDeVwPGcerlOlTH1|6v$^2fcJ-rRvxg#rp^2Iv3i6o$Brx#uVja_-8Jvr zULXz+IA2TqP>nV)5lEl+3BAN|UC44YL4IM***T$ObJ4=}!oG{&<325-mjQ=NxrSp& zp=qQ}mZa)$>2uShZ8RRelYHnz3dRxH&dudMC7p)O2Wct z>o|g-q*oKXfGU%L;i@AzY6g;e{PD8!)XH0@a)gEy^`0@A4~D|Or~4fJD!K9VyLprh zrRKHsqg!Nci%kn4VfPVkF8{nXi6aXBE5Xjag<#5irUgeTS7Ns~lG1x-dw3y)J5lF! z$$1|)Qb4}XL1R(e@_@cgrkAzt1go^GrRQ*@P%A@F*m_V}91i(Y)4r||E*+^!9Jk3Q z@{O3wsI^)Jwnt0egLFYUn)j?bqlsi$Tu_QVEhp0s;iqZL6b42)1FP6}7wmMAPth>D z=R)9EF3PS-$Dt-(-vk6{n5trhmWJq5$hr$A6=cAS&xG{RY~DLma3yVp>*G<#%g@&b zU6h;;Nsn>7DHX!3iIkjk*CUNv!op_W{{(hl$-%XY3hlHWabqj8se_~qq9MW1!V+J0 zWHID87JOj~!;x-Sz9qaPvK0sO=#{1l`C3Ni#|b0MLPzj3Jt4FZ?PEM833A>iN=aBH zqM_5@9-1l|SaJVX7Z`7^R*4X*ECWG%1Pjk7;GCdH1B})X4k= zz^G1um$%qJ(4LTt-Uq%?Sj-^)>2Oz1e-x^5>zMFC zkc+#Bt*Ernz&4D_83b3uW-HNfmTcY6dQLlVNId|xjO5$bVO+gsUrev)b?9jLe(QO@ znoKFl5pq5DoSk);2z|dTm?WF=7LfT|57vsGXAI)7od$1w55D>9eNW-)K<5iht$2nL zPU*5!(gJZK6ldAF8nlwTX&cR9GdEG9c6QzvQBv>4n-xPY7&Y1GdO6%J}jO-pmQ1WOl`&Zgv*dMQT z=X4XN1}iC>W&>VpCl=dYF2{|uRcPPW-t_$`dgjBA7m<c+w?tT6+|Br z)8kz9Ln<`9-CW#Of>01yNhqj4-yTTt?C$_khS}03W3!SWH6er-GR{ItZ=jSJDbPmW zvrgp-;K-2y4cWbWm|$!D2xznsy&iNI#x<88Itc}>jWq$*v z=ruMMYz`QCo&lh5U-|{#0Z+QnoM>S<0@CggDzNimDrz$DC5icbKLaj!z1K73oVpvdMh6xQJmw-z=3IvP-)-fN$E`k?PxECX zv)I#EhTO$%fdY95Fg71}Q6rv3brb@om6#)(mHV6jB?3ygN0}Y5J-&d3yHWz}`$&KKji_E;eJ${`Yv|M#9ve$dOd1Fz0XWhF7`NUx$642LO zC32DEzj6LIw5bb8pl5j2YCW+PIHTSHf9^mgxy14q}ll_m%q8z zeInIMugW+F10Dzhtteo{B!Z5mgM-0o#KlL5L^c7i&rJi*d&q(==HNrLzdxbgY(&iR zwi@{}u_b69p1m$8fx3ED#b9Rrs~zj(40m0GTZ}^qDs!ssDDV z+QAXoy`k!7P!K`RUunt8_e(ejL3=W>!jO8@xpM8fGwZAm2Wr#s(Q@!Tsv}p5vj0jF zsVdIvJR@zGCz?oIEslaTy{IH)L~m7^cd2UgnVSJ3<7gT+P~1y4hb&2N2#_E6ReA+E zciC!(KIC0w|9YImWZA<2`$xnG!eTfXI>1GA3P8-dF5-V4fetl=&mot69pX9R{dnmXNF^YyakqX(#`?mbu6_DQZ-ZX39Ro2^>9RqI`}?(S zk0p%tLLJ|Vn4w$#L?x8sfY9@e@DA3M4$3=_fT*vMv z-w5vf1>~_^r|Md>B)>!)mPSwK^<_P^I4Oys)w*3hT3@~2RdM*k1&d3z%_v21`bIF4 zgdZ8@!mCZC5J^so1|S$}G}u8=GpvegHJ&(aA+3Tr&H8_9l?~!@YR;fU*n3AD$@jD< z+AR_3?a<1X4iI<=1m4&?cA=(oE_9aq~-U8<#yG7G&Y8r z3O{PB3)$!=Qbx}L>YFCju*#0etH|O}J!U?Im9&Tgf#MA)LeuSlrw34YB$=VAx5q$R zhVe<+p12b*?yX&J@Fq=F z^RSqO#vyyNttMS!FfICbltqo|wXm*KIj|>~N5bXfch&5O3tUCmiBBe1$d+c+^>^y^ z;D!aAie3FGvDd!sgFiSA;PR^V5L~H5FIn15vK!_=uJ3Kym?uLqX`EEwve&rX+&iJD z7sB7j9A`%2do9wK6y242G5#$vc`MLbomVB_L}J;U8XO$LIL8>GT?6@~@g*lH?^oMf zNmat#Q2MtFK~J27F!vB)qqIGRpVB^ihfOG{o}(VE*VTW3TlYLZ^>UQ!+{L+5LYKmD zYDxE@5o?i11U_AfmWXHre^jf@N5Ki7a+^T{g~%+msUtJqH?oCR^Y;2{;JLpjah#C^ zy7-LQ4NvSR1~34fG;Eb}XL9~{oYityiqc{|zs}RAs))ZMdg zCVtShKM4iXePXdHPf~sH>(7wn((XFslNrdH`1mwDIxBN^ZK^)lPE}tR-qT4_e_yE^ z^*MrOx_l3jjmR69wRr;>wqE4~`HRLRY~Q8Qi-S*t?QFvUE}V+a;z^2V&@LMqeT-yI zU8-^!YJQ!5`OmGWeVc$zW?7#|#(YBE0~i&NEVb5`jsPaS^0N}0bNtiBN?bJXXwB=s z?n9uEf)Ghfl!gc=2Pq2SyNIj(Szt5~`qrhRyynvC`46amh`Z4=4h32P>FGblgacW@ zKAs5Mb$Y*Fpk~9$5JkIVwHin38_zSL8vFq^FXO@U+_tPq%^DjUxn`PeIMn5XI6~1|1d8@`g2d_5kPiWmo_ey>wFQ57BL2Gc4)H{AVIop$iH) z!?7BdCvXr7c65iP-@-!Yd)$-x$`KD{pLRRr$|{rwA3o(Ud*a7D?CU3;UlV&sHR!Ss!D*Zy+BrqaJ3j}T5zw%j@tF7R^6rVRwtpX13L!~^;o&2zA&()S zA@NnINdaYbALMB+Yk*#@OpvD)oL6>``$=H>io zNZI;H=ldo$IZ*IQ3oeb-=Z9NmSvwgQ5~sdZk#Zr>lk>M)_T?}%Qv5QI)t+Z6dz0b! z;lkADeu$!KMr({~lc;4LHBk3_;gRE}f{NqGL-7q7&K1H~Ab)HKOqXOTvmFC?g~Z% zijiMeZ%4#Y8rctW@K@X9&io;-t`vCrPJUaB>QuQdt=Di9U4M@95n!YAzJoHI0_b_# zOZy*xL{%8A4eNVNek|%qpH|$U7UkU^rSR7E(IxlGR zL{n5_pR`4?SR)_KLlv{kqkGl{0)4|IMg&TW*7-Qim#$sv{bo!Aqh4y<69yded%6co>e*?lwvGm zKVCR0G{`c8GlCG$=lyrlfxY<YY@Z=S`ynfpL4fqyk zjshGgvGP{?KlF%C%M5aH{(fYn;vly%{3+&30W~~~%#aST(H)RDVAikxJ^)WgqbvLT z+nR*|aKOTuCfL~X-bms&1FrwTMXFs4fkzur@j5;4JMsj$FF6pGjvHz%ew`+beCcyM z_T0ScZhlGS;>l+!Q0LQvCH&*~-!<`x(*W~uVP4<6o5#Ex-lidwVAb&E7Yj56BQ_)f`S27Fw9}F~t(EtDd literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..705990773514bb805efe985e5f9e5bd40f34f1bf GIT binary patch literal 12112 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 E7r75MSpWb4 literal 0 HcmV?d00001