1
0
Эх сурвалжийг харах

功能:不优雅地增加初步手柄支持

在 Scripts/Interaction 中增加了 gc、gcp 和 gcr 以进行手柄按键检测(和键盘风格相同)。
同时增加了 ga 以进行手柄轴(摇杆)的值检测。
在 oMain 中增加了基础手柄键位。
总是使用第一个检测到的手柄。

TODO:
(或许)模拟值的角色移动(摇杆少推,角色走得慢);
包装 ga 为类似于按键的 gap 和 gar;
标题界面中的手柄支持;
可调整的按键映射;
可调整的手柄死区。
Eason20000 2 сар өмнө
parent
commit
36e196a025

+ 2 - 0
objects/oBeginStepManager/Other_75.gml

@@ -0,0 +1,2 @@
+
+_gamepad_get();

+ 1 - 0
objects/oBeginStepManager/oBeginStepManager.yy

@@ -3,6 +3,7 @@
   "%Name":"oBeginStepManager",
   "eventList":[
     {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":1,"eventType":3,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
+    {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":75,"eventType":7,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
   ],
   "managed":true,
   "name":"oBeginStepManager",

+ 22 - 22
objects/oMain/Step_0.gml

@@ -1,16 +1,16 @@
 if !global.altcontrol
 {
-	_jump_p    = ingame.kcp("Z");
-	_jump_r    = ingame.kcr("Z");
-	_dash      = ingame.kcp("C");
-	_attack    = ingame.kcp("X");
-	_left      = ingame.kc(vk_left);
-	_right     = ingame.kc(vk_right);
-	_up        = ingame.kc(vk_up);
-	_down      = ingame.kc(vk_down);
-	_inventory = ingame.kcp("I");
-	_focus     = ingame.kcp("A");
-	_pause     = ingame.kcp(vk_escape);
+	_jump_p    = ingame.kcp("Z")       || ingame.gcp(gp_face1);
+	_jump_r    = ingame.kcr("Z")       || ingame.gcr(gp_face1);
+	_dash      = ingame.kcp("C")       || ingame.gcp(gp_shoulderr);
+	_attack    = ingame.kcp("X")       || ingame.gcp(gp_face3);
+	_left      = ingame.kc(vk_left)    || ingame.gc(gp_padl) || (ingame.ga(gp_axislh) < 0);
+	_right     = ingame.kc(vk_right)   || ingame.gc(gp_padr) || (ingame.ga(gp_axislh) > 0);
+	_up        = ingame.kc(vk_up)      || ingame.gc(gp_padu) || (ingame.ga(gp_axislv) < 0);
+	_down      = ingame.kc(vk_down)    || ingame.gc(gp_padd) || (ingame.ga(gp_axislv) > 0);
+	_inventory = ingame.kcp("I")       || ingame.gcp(gp_face4);
+	_focus     = ingame.kcp("A")       || ingame.gcp(gp_face2);
+	_pause     = ingame.kcp(vk_escape) || ingame.gcp(gp_start);
 }
 else
 {
@@ -26,20 +26,20 @@ else
 	_focus     = ingame.kcp("U");
 	_pause     = ingame.kcp(vk_escape);
 }
-_up_title     = title.kcp(vk_up)    || title.kcp("W");
-_down_title   = title.kcp(vk_down)  || title.kcp("S");
-_left_title   = title.kcp(vk_left)  || title.kcp("A");
-_right_title  = title.kcp(vk_right) || title.kcp("D");
-_select_title = title.kcp("Z")      || title.kcp("J");
+_up_title     = title.kcp(vk_up)    || title.kcp("W") || title.gcp(gp_padu);
+_down_title   = title.kcp(vk_down)  || title.kcp("S") || title.gcp(gp_padd);
+_left_title   = title.kcp(vk_left)  || title.kcp("A") || title.gcp(gp_padl);
+_right_title  = title.kcp(vk_right) || title.kcp("D") || title.gcp(gp_padr);
+_select_title = title.kcp("Z")      || title.kcp("J") || title.gcp(gp_face1);
 
-_left_inv  = inventory.kcp(vk_left);
-_right_inv = inventory.kcp(vk_right);
-_up_inv    = inventory.kcp(vk_up);
-_down_inv  = inventory.kcp(vk_down);
-_close_inv = inventory.kcp("I") || inventory.kcp(vk_escape);
+_left_inv  = inventory.kcp(vk_left)  || inventory.gcp(gp_padu);
+_right_inv = inventory.kcp(vk_right) || inventory.gcp(gp_padd);
+_up_inv    = inventory.kcp(vk_up)    || inventory.gcp(gp_padl);
+_down_inv  = inventory.kcp(vk_down)  || inventory.gcp(gp_padr);
+_close_inv = inventory.kcp("I") || inventory.kcp(vk_escape) || inventory.gcp(gp_face4) || inventory.gcp(gp_start);
 
 _save_pause  = pause.kcp("Z");
-_close_pause = pause.kcp("X") || pause.kcp(vk_escape);
+_close_pause = pause.kcp("X") || pause.kcp(vk_escape) || pause.gcp(gp_face2) || pause.gcp(gp_start);
 
 if room != rTitle
 	exit;

+ 123 - 7
scripts/Interaction/Interaction.gml

@@ -13,6 +13,23 @@ function _handle_init(){
 	global.current_priority = _max_priority
 }
 
+/// @desc Get gamepad and maintain a list through Async System events... Well, ungracefully.
+function _gamepad_get(){
+	if (!variable_global_exists("gamepads_list")) global.gamepads_list = [];
+	if (async_load[? "event_type"] == "gamepad discovered")
+	{
+	    var _pad = async_load[? "pad_index"];
+	    gamepad_set_axis_deadzone(_pad, 0.1);
+	    array_push(global.gamepads_list, _pad);
+	}
+	else if (async_load[? "event_type"] == "gamepad lost")
+	{
+	    var _pad = async_load[? "pad_index"];
+	    var _index = array_get_index(global.gamepads_list, _pad);
+	    array_delete(global.gamepads_list, _index, 1);
+	}
+}
+
 /// @desc 尝试对按键进行消费
 /// @param {Constant.VirtualKey|Real} _key 检测的键盘按键
 /// @param {Constant.Real} _priority 当前句柄的优先级
@@ -75,6 +92,68 @@ function _kcr(_key, _priority = 0) {
     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;
@@ -108,6 +187,39 @@ function input_handle(_reg_name, _priority) constructor {
         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() {
@@ -138,13 +250,17 @@ function input_handle_find(_reg_name) {
 /// @desc 创建空句柄
 function create_dummy_handle(){
 	global.handle_dummy = {
-    kc:  function() { return false; },
-    kcp: function() { return false; },
-    kcr: function() { return false; },
-    destroy: function() {  },
-    active: false,
-    priority: -9999
-};
+        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)