/// @desc 对句柄进行每帧例行初始化 function _handle_init(){ if (!variable_global_exists("input_handles_list")) global.input_handles_list = []; global.input_consumed = {}; var _max_priority = 0; for(var i = 0; i < array_length(global.input_handles_list); i++){ var _ch = global.input_handles_list[i]; if(_ch.active){ _max_priority = max(_max_priority, _ch.priority); } } global.current_priority = _max_priority } /// @desc 尝试对按键进行消费 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 /// @param {Constant.Real} _priority 当前句柄的优先级 function _try_input_consume(_key, _priority){ //如果低于最高优先级 且 非debugger级优先级( -1 ), 则拒绝访问 if(_priority < global.current_priority && _priority != -1) return false; //同一帧内已经被同级句柄/更高级句柄访问( 消费 ), 则拒绝访问 var _key_id = string(_key); if (struct_exists(global.input_consumed, _key_id)) return false; return true; } /// @desc 强制消费给定键盘按键 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 function _force_input_consume(_key){ var _id = key_get_id(_key); global.input_consumed[$ string(_id)] = true; } /// @desc 优雅地检测此帧某给定键盘按键是否被按住 /// @desc 使用{HandleName}.kc()而非此函数 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 /// @param {Constant.Real} _priority 当前句柄的优先级 function _kc(_key, _priority = 0) { var _id = key_get_id(_key); if (_try_input_consume(_id, _priority) && keyboard_check(_id)) { //判定成功则对按键进行消费 global.input_consumed[$ string(_id)] = true; return true; } return false; } /// @desc 优雅地检测此帧某给定键盘按键是否被按住 /// @desc 使用{HandleName}.kcp()而非此函数 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 /// @param {Constant.Real} _priority 当前句柄的优先级 function _kcp( _key, _priority = 0) { var _id = key_get_id(_key); if (_try_input_consume(_id, _priority) && keyboard_check_pressed(_id)) { //判定成功则对按键进行消费 global.input_consumed[$ string(_id)] = true; return true; } return false; } /// @desc 优雅地检测此帧某给定键盘按键是否被松开 /// @desc 使用{HandleName}.kcr()而非此函数 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 /// @param {Constant.Real} _priority 当前句柄的优先级 function _kcr(_key, _priority = 0) { var _id = key_get_id(_key); if (_try_input_consume(_id, _priority) && keyboard_check_released(_id)) { //判定成功则对按键进行消费 global.input_consumed[$ string(_id)] = true; return true; } return false; } /// @desc Get the first gamepad function _firstpad(){ if (variable_global_exists("gamepads_list") && array_length(global.gamepads_list) > 0) { return global.gamepads_list[0]; } return 0 } /// @desc 优雅地检测此帧某给定手柄按键是否被按住 /// @desc 使用{HandleName}.gc()而非此函数 /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键 /// @param {Constant.Real} _priority 当前句柄的优先级 function _gc(_id, _priority = 0) { var _pad = _firstpad(); if (_try_input_consume(_id, _priority) && gamepad_button_check(_pad, _id)) { //判定成功则对按键进行消费 global.input_consumed[$ string(_id)] = true; return true; } return false; } /// @desc 优雅地检测此帧某给定手柄按键是否被按住 /// @desc 使用{HandleName}.gcp()而非此函数 /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键 /// @param {Constant.Real} _priority 当前句柄的优先级 function _gcp( _id, _priority = 0) { var _pad = _firstpad(); if (_try_input_consume(_id, _priority) && gamepad_button_check_pressed(_pad, _id)) { //判定成功则对按键进行消费 global.input_consumed[$ string(_id)] = true; return true; } return false; } /// @desc 优雅地检测此帧某给定手柄按键是否被松开 /// @desc 使用{HandleName}.gcr()而非此函数 /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键 /// @param {Constant.Real} _priority 当前句柄的优先级 function _gcr(_id, _priority = 0) { var _pad = _firstpad(); if (_try_input_consume(_id, _priority) && gamepad_button_check_released(_pad, _id)) { //判定成功则对按键进行消费 global.input_consumed[$ string(_id)] = true; return true; } return false; } /// @desc 不优雅地检测此帧 gamepad axis /// @desc 使用{HandleName}.ga()而非此函数 /// @param {Constant.VirtualKey|Real} _id 检测的手柄 axis /// @param {Constant.Real} _priority 当前句柄的优先级 function _ga(_id, _priority = 0) { var _pad = _firstpad(); if (_try_input_consume(_id, _priority)) { //判定成功则对 axis 进行消费 global.input_consumed[$ string(_id)] = true; return gamepad_axis_value(_pad, _id); } return 0; } function input_handle(_reg_name, _priority) constructor { reg_name = _reg_name; priority = _priority; // 理论上,你不应该修改active来控制启用情况,而是使用标准的注册注销流程 active = true; if (!variable_global_exists("input_handles_list")) global.input_handles_list = []; array_push(global.input_handles_list, self); /// @desc 优雅地检测此帧某给定键盘按键是否被按住 /// @desc priority继承自其句柄 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 static kc = function(_key) { if (!active) return false; // 自动将自己的 priority 传给底层函数 return _kc(_key, self.priority); } /// @desc 优雅地检测此帧某给定键盘按键是否被按住 /// @desc priority继承自其句柄 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 static kcp = function(_key) { if (!active) return false; return _kcp(_key, self.priority); } /// @desc 优雅地检测此帧某给定键盘按键是否被松开 /// @desc priority继承自其句柄 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键 static kcr = function(_key) { if (!active) return false; return _kcr(_key, self.priority); } /// @desc 优雅地检测此帧某给定手柄按键是否被按住 /// @desc priority继承自其句柄 /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键 static gc = function(_id) { if (!active) return false; // 自动将自己的 priority 传给底层函数 return _gc(_id, self.priority); } /// @desc 优雅地检测此帧某给定手柄按键是否被按住 /// @desc priority继承自其句柄 /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键 static gcp = function(_id) { if (!active) return false; return _gcp(_id, self.priority); } /// @desc 优雅地检测此帧某给定手柄按键是否被松开 /// @desc priority继承自其句柄 /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键 static gcr = function(_id) { if (!active) return false; return _gcr(_id, self.priority); } /// @desc 不优雅地检测此帧某给定手柄按键是否被松开 /// @desc priority继承自其句柄 /// @param {Constant.VirtualKey|Real} _id 检测的手柄按键 static ga = function(_id) { if (!active) return false; return _ga(_id, self.priority); } /// @desc 注销当前句柄 static destroy = function() { if (!variable_global_exists("input_handles_list")) return; var _len = array_length(global.input_handles_list); for (var i = 0; i < _len; i++) { if (global.input_handles_list[i] == self) { array_delete(global.input_handles_list, i, 1); break; } } } } /// @desc 通过注册名寻找句柄 /// @param {String} _reg_name 注册名 function input_handle_find(_reg_name) { var _len = array_length(global.input_handles_index); for (var i = 0; i < _len; i++) { if (global.input_handles_list[i].reg_name == _reg_name) { return global.input_handles_list[i]; } } return undefined; } /// @desc 创建空句柄 function create_dummy_handle(){ global.handle_dummy = { kc: function() { return false; }, kcp: function() { return false; }, kcr: function() { return false; }, gc: function() { return false; }, gcp: function() { return false; }, gcr: function() { return false; }, ga: function() { return false; }, destroy: function() { }, active: false, priority: -9999 }; } /// @desc 自动化注册句柄,核心部分等效于 _new_handle = new input_handle(_reg_name, _priority) /// @param {String} _func_name handle变量名 /// @param {String} _reg_name 注册名 /// @param {Real} _priority 优先级 function autoreg_handle(_func_name, _reg_name, _priority){ var _found = false; var _len = array_length(global.input_handles_index); for (var i = 0; i < _len; i++) { if (global.input_handles_index[i] == _func_name) { _found = true; break; } } if (!_found) throw("ERROR:尝试注册的变量名'" + _func_name + "'不在input_handles_index内") var _current = variable_instance_get(id, _func_name); // 如果已经存在,则销毁旧的 if (is_struct(_current) && _current != global.handle_dummy) { _current.destroy(); } var _new_handle = new input_handle(_reg_name, _priority); variable_instance_set(id, _func_name, _new_handle); } /// @desc 自动化注销句柄 /// @param {String} _func_name handle变量名 function autodel_handle(_func_name){ var _handle = variable_instance_get(id, _func_name); if (is_struct(_handle) && _handle != global.handle_dummy) { if (variable_struct_exists(_handle, "destroy")) { _handle.destroy(); } } variable_instance_set(id, _func_name, global.handle_dummy); }