Parcourir la source

+ 更加现代化的handle input,内置一个title handle

tianhaobu il y a 3 mois
Parent
commit
6ef93f7b25

+ 18 - 2
notes/必读(更新日志)/必读(更新日志).txt

@@ -73,15 +73,16 @@ gml内部会计算image_index += sprite_fps / game_fps * image_speed等等公式
 
 
 2026/2/14 tianhaobu
+//注册与注销建议使用更加现代化的autoreg_handle和autodel_handle,详见2/18
 1. 引入了新的输入方法,相关函数在interaction.gml里,大致逻辑是这样的:
 在监听任何按键前,需要先注册一个句柄(handle)
-{句柄外部名称} = new input_handle("{句柄内部名称}",{优先级})
+{句柄函数名} = new input_handle("{句柄注册名}",{优先级})
 句柄外部名称是调用该句柄的名称,句柄内部名称建议与外部名称保持一致.
 优先级描述了该句柄的优先使用程度,通常来说,''高优先级句柄独占所有的输入''(例外是 debug 句柄).
 意味着若存在优先级10的句柄foo与优先级为1的句柄bar,基于bar的任何按键监听都是无效的,句柄foo独占整个输入.
 
 监听按键时,需要使用如下格式
-{句柄外部名称}.kc({按键}) | {句柄外部名称}.kcr({按键}) | {句柄外部名称}.kcp({按键})
+{句柄函数名}.kc({按键}) | {句柄函数名}.kcr({按键}) | {句柄函数名}.kcp({按键})
 假设为存在foo = foo_A.kc("A"); bar_A = bar.kc("A"); foo_B = bar.kc("B"); bar_B = bar.kc("B")
 如果只有按键A被按下: 则foo_A = true; foo_B = false; bar_A = false; bar_B = false
 如果按键A、B被按下: 则foo_A = true; foo_B = true; bar_A = false; bar_B = false
@@ -97,6 +98,21 @@ gml内部会计算image_index += sprite_fps / game_fps * image_speed等等公式
 3) _handle_init()放在begin_step里.
 
 语言能力极差... 看不懂的可以参考oInput
+
+2026/2/18 tianhaobu
+TL;DR: 给大忙人的handleinput30秒速通
+必修:
+autoreg_handle("A","B",C)
+注册handle用,"A"表示这个handle函数的名字;"B"表示这个handle的注册名(小名),通常"A"="B";C表示优先级
+
+autodel_handle("A")
+注销handle用,"A"表示这个handle函数的名字
+
+选择性必修:
+input_handle_find("A")
+根据注册名返回函数名,"A"表示注册名
+通常搭配autodel_handle()使用
+
 2026/2/15 Dr.Duck
 
 1. 优化check_hazard逻辑,功能实现没问题但不够优雅

+ 8 - 1
objects/oInput/Create_0.gml

@@ -1,4 +1,11 @@
-ingame = new input_handle("ingame",1)
+global.input_handles_index = [
+	"ingame",
+	"title"
+]
+for (var i = 0; i < array_length(global.input_handles_index); i++) {
+    variable_instance_set(id, global.input_handles_index[i], undefined);
+}
+autoreg_handle("ingame","ingame",1)
 
 jump_buffer_timer = 0;
 jump_buffer_max = 6;

+ 9 - 1
objects/oInput/Step_0.gml

@@ -7,8 +7,16 @@ _down   = ingame.kc("S")  || ingame.kc(vk_down);
 _dash   = ingame.kcp("C") || ingame.kcp("L");
 _attack = ingame.kcp("X") || ingame.kcp("J");
 
+if (ingame.kcp(vk_escape)) {
+    autoreg_handle("title", "title", 100); 
+}
+if (title != undefined && title.kcp(vk_escape)) {
+    autodel_handle("title"); 
+}
+
 if _jump_p
     jump_buffer_timer = jump_buffer_max;
 	
 if jump_buffer_timer > 0
-    jump_buffer_timer--;
+    jump_buffer_timer--;
+	

+ 43 - 2
scripts/Interaction/Interaction.gml

@@ -75,8 +75,8 @@ function _kcr(_key, _priority = 0) {
     return false;
 }
 
-function input_handle(_name, _priority) constructor {
-	name = _name;
+function input_handle(_reg_name, _priority) constructor {
+	reg_name = _reg_name;
 	priority = _priority;
 	// 理论上,你不应该修改active来控制启用情况,而是使用标准的注册注销流程
 	active = true;
@@ -121,4 +121,45 @@ function input_handle(_name, _priority) constructor {
             }
         }
     }
+}
+
+/// @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 自动化注册句柄,核心部分等效于 _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 _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 (_handle != undefined && is_struct(_handle)) {
+        _handle.destroy();
+        variable_instance_set(id, _func_name, undefined);
+    }
 }