1
0

Interaction.gml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /// @desc 对句柄进行每帧例行初始化
  2. function _handle_init(){
  3. if (!variable_global_exists("input_handles_list")) global.input_handles_list = [];
  4. global.input_consumed = {};
  5. var _max_priority = 0;
  6. for(var i = 0; i < array_length(global.input_handles_list); i++){
  7. var _ch = global.input_handles_list[i];
  8. if(_ch.active){
  9. _max_priority = max(_max_priority, _ch.priority);
  10. }
  11. }
  12. global.current_priority = _max_priority
  13. }
  14. /// @desc Get gamepad and maintain a list through Async System events... Well, ungracefully.
  15. function _gamepad_get(){
  16. if (!variable_global_exists("gamepads_list")) global.gamepads_list = [];
  17. if (async_load[? "event_type"] == "gamepad discovered")
  18. {
  19. var _pad = async_load[? "pad_index"];
  20. gamepad_set_axis_deadzone(_pad, 0.4);
  21. array_push(global.gamepads_list, _pad);
  22. }
  23. else if (async_load[? "event_type"] == "gamepad lost")
  24. {
  25. var _pad = async_load[? "pad_index"];
  26. var _index = array_get_index(global.gamepads_list, _pad);
  27. array_delete(global.gamepads_list, _index, 1);
  28. }
  29. }
  30. /// @desc 尝试对按键进行消费
  31. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  32. /// @param {Constant.Real} _priority 当前句柄的优先级
  33. function _try_input_consume(_key, _priority){
  34. //如果低于最高优先级 且 非debugger级优先级( -1 ), 则拒绝访问
  35. if(_priority < global.current_priority && _priority != -1) return false;
  36. //同一帧内已经被同级句柄/更高级句柄访问( 消费 ), 则拒绝访问
  37. var _key_id = string(_key);
  38. if (struct_exists(global.input_consumed, _key_id)) return false;
  39. return true;
  40. }
  41. /// @desc 强制消费给定键盘按键
  42. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  43. function _force_input_consume(_key){
  44. var _id = key_get_id(_key);
  45. global.input_consumed[$ string(_id)] = true;
  46. }
  47. /// @desc 优雅地检测此帧某给定键盘按键是否被按住
  48. /// @desc 使用{HandleName}.kc()而非此函数
  49. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  50. /// @param {Constant.Real} _priority 当前句柄的优先级
  51. function _kc(_key, _priority = 0)
  52. {
  53. var _id = key_get_id(_key);
  54. if (_try_input_consume(_id, _priority) && keyboard_check(_id)) {
  55. //判定成功则对按键进行消费
  56. global.input_consumed[$ string(_id)] = true;
  57. return true;
  58. }
  59. return false;
  60. }
  61. /// @desc 优雅地检测此帧某给定键盘按键是否被按住
  62. /// @desc 使用{HandleName}.kcp()而非此函数
  63. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  64. /// @param {Constant.Real} _priority 当前句柄的优先级
  65. function _kcp( _key, _priority = 0) {
  66. var _id = key_get_id(_key);
  67. if (_try_input_consume(_id, _priority) && keyboard_check_pressed(_id)) {
  68. //判定成功则对按键进行消费
  69. global.input_consumed[$ string(_id)] = true;
  70. return true;
  71. }
  72. return false;
  73. }
  74. /// @desc 优雅地检测此帧某给定键盘按键是否被松开
  75. /// @desc 使用{HandleName}.kcr()而非此函数
  76. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  77. /// @param {Constant.Real} _priority 当前句柄的优先级
  78. function _kcr(_key, _priority = 0) {
  79. var _id = key_get_id(_key);
  80. if (_try_input_consume(_id, _priority) && keyboard_check_released(_id)) {
  81. //判定成功则对按键进行消费
  82. global.input_consumed[$ string(_id)] = true;
  83. return true;
  84. }
  85. return false;
  86. }
  87. /// @desc Get the first gamepad
  88. function _firstpad(){
  89. if (variable_global_exists("gamepads_list") && array_length(global.gamepads_list) > 0) {
  90. return global.gamepads_list[0];
  91. }
  92. return 0
  93. }
  94. /// @desc 优雅地检测此帧某给定手柄按键是否被按住
  95. /// @desc 使用{HandleName}.gc()而非此函数
  96. /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键
  97. /// @param {Constant.Real} _priority 当前句柄的优先级
  98. function _gc(_id, _priority = 0)
  99. {
  100. var _pad = _firstpad();
  101. if (_try_input_consume(_id, _priority) && gamepad_button_check(_pad, _id)) {
  102. //判定成功则对按键进行消费
  103. global.input_consumed[$ string(_id)] = true;
  104. return true;
  105. }
  106. return false;
  107. }
  108. /// @desc 优雅地检测此帧某给定手柄按键是否被按住
  109. /// @desc 使用{HandleName}.gcp()而非此函数
  110. /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键
  111. /// @param {Constant.Real} _priority 当前句柄的优先级
  112. function _gcp( _id, _priority = 0) {
  113. var _pad = _firstpad();
  114. if (_try_input_consume(_id, _priority) && gamepad_button_check_pressed(_pad, _id)) {
  115. //判定成功则对按键进行消费
  116. global.input_consumed[$ string(_id)] = true;
  117. return true;
  118. }
  119. return false;
  120. }
  121. /// @desc 优雅地检测此帧某给定手柄按键是否被松开
  122. /// @desc 使用{HandleName}.gcr()而非此函数
  123. /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键
  124. /// @param {Constant.Real} _priority 当前句柄的优先级
  125. function _gcr(_id, _priority = 0) {
  126. var _pad = _firstpad();
  127. if (_try_input_consume(_id, _priority) && gamepad_button_check_released(_pad, _id)) {
  128. //判定成功则对按键进行消费
  129. global.input_consumed[$ string(_id)] = true;
  130. return true;
  131. }
  132. return false;
  133. }
  134. /// @desc 不优雅地检测此帧 gamepad axis
  135. /// @desc 使用{HandleName}.ga()而非此函数
  136. /// @param {Constant.VirtualKey|Real} _id 检测的手柄 axis
  137. /// @param {Constant.Real} _priority 当前句柄的优先级
  138. function _ga(_id, _priority = 0) {
  139. var _pad = _firstpad();
  140. if (_try_input_consume(_id, _priority)) {
  141. //判定成功则对 axis 进行消费
  142. global.input_consumed[$ string(_id)] = true;
  143. return gamepad_axis_value(_pad, _id);
  144. }
  145. return 0;
  146. }
  147. function input_handle(_reg_name, _priority) constructor {
  148. reg_name = _reg_name;
  149. priority = _priority;
  150. // 理论上,你不应该修改active来控制启用情况,而是使用标准的注册注销流程
  151. active = true;
  152. if (!variable_global_exists("input_handles_list")) global.input_handles_list = [];
  153. array_push(global.input_handles_list, self);
  154. /// @desc 优雅地检测此帧某给定键盘按键是否被按住
  155. /// @desc priority继承自其句柄
  156. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  157. static kc = function(_key) {
  158. if (!active) return false;
  159. // 自动将自己的 priority 传给底层函数
  160. return _kc(_key, self.priority);
  161. }
  162. /// @desc 优雅地检测此帧某给定键盘按键是否被按住
  163. /// @desc priority继承自其句柄
  164. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  165. static kcp = function(_key) {
  166. if (!active) return false;
  167. return _kcp(_key, self.priority);
  168. }
  169. /// @desc 优雅地检测此帧某给定键盘按键是否被松开
  170. /// @desc priority继承自其句柄
  171. /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
  172. static kcr = function(_key) {
  173. if (!active) return false;
  174. return _kcr(_key, self.priority);
  175. }
  176. /// @desc 优雅地检测此帧某给定手柄按键是否被按住
  177. /// @desc priority继承自其句柄
  178. /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键
  179. static gc = function(_id) {
  180. if (!active) return false;
  181. // 自动将自己的 priority 传给底层函数
  182. return _gc(_id, self.priority);
  183. }
  184. /// @desc 优雅地检测此帧某给定手柄按键是否被按住
  185. /// @desc priority继承自其句柄
  186. /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键
  187. static gcp = function(_id) {
  188. if (!active) return false;
  189. return _gcp(_id, self.priority);
  190. }
  191. /// @desc 优雅地检测此帧某给定手柄按键是否被松开
  192. /// @desc priority继承自其句柄
  193. /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键
  194. static gcr = function(_id) {
  195. if (!active) return false;
  196. return _gcr(_id, self.priority);
  197. }
  198. /// @desc 不优雅地检测此帧某给定手柄按键是否被松开
  199. /// @desc priority继承自其句柄
  200. /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键
  201. static ga = function(_id) {
  202. if (!active) return false;
  203. return _ga(_id, self.priority);
  204. }
  205. /// @desc 注销当前句柄
  206. static destroy = function() {
  207. if (!variable_global_exists("input_handles_list")) return;
  208. var _len = array_length(global.input_handles_list);
  209. for (var i = 0; i < _len; i++) {
  210. if (global.input_handles_list[i] == self) {
  211. array_delete(global.input_handles_list, i, 1);
  212. break;
  213. }
  214. }
  215. }
  216. }
  217. /// @desc 通过注册名寻找句柄
  218. /// @param {String} _reg_name 注册名
  219. function input_handle_find(_reg_name) {
  220. var _len = array_length(global.input_handles_index);
  221. for (var i = 0; i < _len; i++) {
  222. if (global.input_handles_list[i].reg_name == _reg_name) {
  223. return global.input_handles_list[i];
  224. }
  225. }
  226. return undefined;
  227. }
  228. /// @desc 创建空句柄
  229. function create_dummy_handle(){
  230. global.handle_dummy = {
  231. kc: function() { return false; },
  232. kcp: function() { return false; },
  233. kcr: function() { return false; },
  234. gc: function() { return false; },
  235. gcp: function() { return false; },
  236. gcr: function() { return false; },
  237. ga: function() { return false; },
  238. destroy: function() { },
  239. active: false,
  240. priority: -9999
  241. };
  242. }
  243. /// @desc 自动化注册句柄,核心部分等效于 _new_handle = new input_handle(_reg_name, _priority)
  244. /// @param {String} _func_name handle变量名
  245. /// @param {String} _reg_name 注册名
  246. /// @param {Real} _priority 优先级
  247. function autoreg_handle(_func_name, _reg_name, _priority){
  248. var _found = false;
  249. var _len = array_length(global.input_handles_index);
  250. for (var i = 0; i < _len; i++) {
  251. if (global.input_handles_index[i] == _func_name) {
  252. _found = true;
  253. break;
  254. }
  255. }
  256. if (!_found) throw("ERROR:尝试注册的变量名'" + _func_name + "'不在input_handles_index内")
  257. var _current = variable_instance_get(id, _func_name);
  258. // 如果已经存在,则销毁旧的
  259. if (is_struct(_current) && _current != global.handle_dummy) {
  260. _current.destroy();
  261. }
  262. var _new_handle = new input_handle(_reg_name, _priority);
  263. variable_instance_set(id, _func_name, _new_handle);
  264. }
  265. /// @desc 自动化注销句柄
  266. /// @param {String} _func_name handle变量名
  267. function autodel_handle(_func_name){
  268. var _handle = variable_instance_get(id, _func_name);
  269. if (is_struct(_handle) && _handle != global.handle_dummy) {
  270. if (variable_struct_exists(_handle, "destroy")) {
  271. _handle.destroy();
  272. }
  273. }
  274. variable_instance_set(id, _func_name, global.handle_dummy);
  275. }