我有一个管理键盘输入并触发 KeyPressed , KeyReleased 或 KeyHeld 事件的类。如果密钥存在于Controller组件的KeyBindings集合中,它仅触发事件。既然我已经完成了所有这些工作,我就会遇到问题。我想要的是以下内容:
Key pressed.
if(Key bind exists)
Fire key pressed event.
foreach(function in keyBinds)
{
execute function, fire event, whatever...
}
我无法弄清楚foreach循环是如何工作的。关于如何将这样的东西拉出来的任何想法?
KeyboardController组件:
public class KeyboardController : IComponent
{
//Fields
private Dictionary<Keys, HashSet<Delegate>> m_keyBindings = new Dictionary<Keys,HashSet<Delegate>>();
//Properties
public Dictionary<Keys, HashSet<Delegate>> KeyBindings
{
get { return m_keyBindings; }
}
}
这是包含Keys及其函数/ delegate / event /无论绑定的类。事件代码不能包含在此类中,因为该类仅用于存储数据。我需要传递一个Key绑定和一个动作或一组动作,以便在按下这个绑定时执行。
添加绑定:
//Set key bindings
KeyboardController kbController = entityManager.GetComponent<KeyboardController>(1);
kbController.KeyBindings.Add(Keys.Up, new HashSet<Delegate>());
kbController.KeyBindings[Keys.Up].Add(function);
我不知道如何在“添加绑定:”工作中创建第三行。
答案 0 :(得分:4)
您可以使用multicast delegate自动为给定密钥触发多个事件,这样您就不需要维护一系列事件。例如:
Dictionary<Key, Action> bindings = ...
Action binding;
if (binding.TryGetValue(key, out binding))
binding(); // this will execute multiple events if they are hooked
挂钩活动:
bindings[Keys.A] += new Action(MyAKeyHandler);
如果由于某种原因你不想使用多播委托,你可以这样做:
List<Action> handlers = binding[key];
...
if (handlers != null)
foreach (var handler in handlers)
handler();
而不是HashSet使用实际的委托类型,例如Action&lt;&gt;。例如:
Dictionary<Keys, Action> handlers = ...
handlers[key] += function;
答案 1 :(得分:2)
由于C#将委托类型作为第一类语言对象,因此您可以直接保留一组函数
var keyBinds = new List<Action<KeyPressEventArgs>>();
KeyPressEventArgs args = /* Something from the actual keypress event */;
foreach (Action<KeyPressEventArgs> function in keyBinds)
{
function(args);
}
答案 2 :(得分:1)
您可以为此目的使用代表集。请检查此链接:http://xenta.codeplex.com/SourceControl/changeset/view/068ddfd6bf36#trunk%2fSrc%2fFwk%2fXenta.EventBroker.Default%2fBroker.cs。这是一个事件经纪人,我们使用代表名单。