mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
feat(input): 引入输入转换器接口及实现
新增 `IInputTranslator` 接口用于解耦原始输入与游戏事件的转换逻辑。 在 `InputSystem` 中增加注册、注销和处理原始输入的方法,支持优先级控制。 重构 `GodotInputBridge`,移除原有硬编码翻译逻辑,改为通过 `HandleRaw` 调用转换器处理。 新增 `GodotInputTranslator` 实现 `IInputTranslator`,负责将 Godot 输入事件翻译为游戏事件。 模块初始化时自动注册该转换器至输入系统。
This commit is contained in:
parent
339498e629
commit
4bd9853ec1
15
GFramework.Game/input/IInputTranslator.cs
Normal file
15
GFramework.Game/input/IInputTranslator.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace GFramework.Game.input;
|
||||
|
||||
/// <summary>
|
||||
/// 输入转换器接口
|
||||
/// </summary>
|
||||
public interface IInputTranslator
|
||||
{
|
||||
/// <summary>
|
||||
/// 尝试将引擎输入翻译为游戏输入
|
||||
/// </summary>
|
||||
/// <param name="rawInput">原始的引擎输入对象</param>
|
||||
/// <param name="gameEvent">输出参数,如果翻译成功则包含对应的游戏输入事件</param>
|
||||
/// <returns>如果翻译成功返回true,否则返回false</returns>
|
||||
bool TryTranslate(object rawInput, out IGameInputEvent gameEvent);
|
||||
}
|
||||
@ -1,6 +1,4 @@
|
||||
using System.Numerics;
|
||||
|
||||
namespace GFramework.Game.input;
|
||||
namespace GFramework.Game.input;
|
||||
|
||||
public static class InputEvents
|
||||
{
|
||||
|
||||
@ -8,6 +8,7 @@ namespace GFramework.Game.input;
|
||||
/// </summary>
|
||||
public class InputSystem : AbstractSystem
|
||||
{
|
||||
private readonly List<IInputTranslator> _translators = [];
|
||||
private readonly InputContextStack _contextStack = new();
|
||||
|
||||
/// <summary>
|
||||
@ -43,4 +44,44 @@ public class InputSystem : AbstractSystem
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销输入转换器
|
||||
/// </summary>
|
||||
/// <param name="translator">要注销的输入转换器接口实例</param>
|
||||
public void UnregisterTranslator(IInputTranslator translator)
|
||||
=> _translators.Remove(translator);
|
||||
|
||||
/// <summary>
|
||||
/// 注册输入转换器
|
||||
/// </summary>
|
||||
/// <param name="translator">输入转换器接口实例</param>
|
||||
/// <param name="highPriority">是否为高优先级,true时插入到转换器列表开头,false时添加到列表末尾</param>
|
||||
public void RegisterTranslator(IInputTranslator translator, bool highPriority = false)
|
||||
{
|
||||
if (_translators.Contains(translator))
|
||||
return;
|
||||
// 根据优先级设置决定插入位置
|
||||
if (highPriority)
|
||||
_translators.Insert(0, translator);
|
||||
else
|
||||
_translators.Add(translator);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 处理原始输入数据
|
||||
/// </summary>
|
||||
/// <param name="rawInput">原始输入对象</param>
|
||||
public void HandleRaw(object rawInput)
|
||||
{
|
||||
// 遍历所有注册的转换器,尝试将原始输入转换为游戏事件
|
||||
foreach (var t in _translators)
|
||||
{
|
||||
if (!t.TryTranslate(rawInput, out var gameEvent)) continue;
|
||||
Handle(gameEvent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -25,55 +25,6 @@ public partial class GodotInputBridge : Node
|
||||
/// <param name="event">Godot输入事件</param>
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
var gameEvent = Translate(@event);
|
||||
if (gameEvent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_inputSystem.Handle(gameEvent);
|
||||
GetViewport().SetInputAsHandled();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将Godot输入事件翻译为游戏框架输入事件
|
||||
/// </summary>
|
||||
/// <param name="evt">Godot输入事件</param>
|
||||
/// <returns>翻译后的游戏输入事件,如果无法翻译则返回null</returns>
|
||||
private static IGameInputEvent? Translate(InputEvent evt)
|
||||
{
|
||||
// 处理动作输入事件
|
||||
if (evt is InputEventAction action)
|
||||
{
|
||||
return new InputEvents.KeyInputEvent(
|
||||
action.Action,
|
||||
action.Pressed,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
// 鼠标按钮
|
||||
if (evt is InputEventMouseButton mb)
|
||||
{
|
||||
return new InputEvents.PointerInputEvent<Vector2>(
|
||||
mb.Position,
|
||||
Vector2.Zero,
|
||||
(int)mb.ButtonIndex,
|
||||
mb.Pressed
|
||||
);
|
||||
}
|
||||
|
||||
// 鼠标移动
|
||||
if (evt is InputEventMouseMotion mm)
|
||||
{
|
||||
return new InputEvents.PointerInputEvent<Vector2>(
|
||||
mm.Position,
|
||||
mm.Relative,
|
||||
0,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
_inputSystem.HandleRaw(@event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,5 +57,7 @@ public sealed class GodotInputModule<T> : AbstractGodotModule<T>
|
||||
{
|
||||
// 从架构中获取输入系统实例
|
||||
_inputSystem = architecture.GetSystem<InputSystem>()!;
|
||||
// 注册输入转换器
|
||||
_inputSystem.RegisterTranslator(new GodotInputTranslator());
|
||||
}
|
||||
}
|
||||
|
||||
65
GFramework.Godot/input/GodotInputTranslator.cs
Normal file
65
GFramework.Godot/input/GodotInputTranslator.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using GFramework.Game.input;
|
||||
using Godot;
|
||||
|
||||
namespace GFramework.Godot.input;
|
||||
|
||||
/// <summary>
|
||||
/// 将Godot引擎的输入事件转换为游戏通用输入事件的翻译器
|
||||
/// </summary>
|
||||
public sealed class GodotInputTranslator : IInputTranslator
|
||||
{
|
||||
/// <summary>
|
||||
/// 尝试将原始输入对象转换为游戏输入事件
|
||||
/// </summary>
|
||||
/// <param name="rawInput">原始输入对象,应为Godot的InputEvent类型</param>
|
||||
/// <param name="gameEvent">输出参数,转换成功时返回对应的游戏输入事件,失败时返回null</param>
|
||||
/// <returns>转换成功返回true,否则返回false</returns>
|
||||
public bool TryTranslate(object rawInput, out IGameInputEvent gameEvent)
|
||||
{
|
||||
gameEvent = null!;
|
||||
|
||||
// 检查输入是否为Godot的InputEvent类型
|
||||
if (rawInput is not InputEvent evt)
|
||||
return false;
|
||||
|
||||
// Action
|
||||
// 处理动作输入事件(如键盘按键、手柄按钮等)
|
||||
if (evt is InputEventAction action)
|
||||
{
|
||||
gameEvent = new InputEvents.KeyInputEvent(
|
||||
action.Action,
|
||||
action.Pressed,
|
||||
false
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mouse button
|
||||
// 处理鼠标按钮输入事件
|
||||
if (evt is InputEventMouseButton mb)
|
||||
{
|
||||
gameEvent = new InputEvents.PointerInputEvent<Vector2>(
|
||||
mb.Position,
|
||||
Vector2.Zero,
|
||||
(int)mb.ButtonIndex,
|
||||
mb.Pressed
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mouse motion
|
||||
// 处理鼠标移动输入事件
|
||||
if (evt is InputEventMouseMotion mm)
|
||||
{
|
||||
gameEvent = new InputEvents.PointerInputEvent<Vector2>(
|
||||
mm.Position,
|
||||
mm.Relative,
|
||||
0,
|
||||
false
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user