【问题标题】:C# How to notify other classes with a single timer?C#如何用一个定时器通知其他类?
【发布时间】:2015-06-11 05:45:25
【问题描述】:

我正在尝试制作一个全局计时器,在特定时间过后需要通知的所有内容。

例如,在游戏中,会有增益和攻击冷却计时器以及物品冷却等等。

单独管理它们很好,但我如何让它们都在同一个计时器上运行?

我尝试使用带有浮点数作为键和委托作为值的 SortedList,以便在时间到时简单地调用,但我似乎无法管理它。尝试使用 Generic 参数的委托,但我无法将其放入排序列表中。

谁能指出我正确的方向?

【问题讨论】:

    标签: c# timer delegates


    【解决方案1】:

    我可以指出两个选项:

    1. 创建一个类似TimerControlled 的接口(所有名称都可以更改)使用方法TimerTick(whatever arguments you need)(和其他如果需要),它实现了该类的计时器滴答逻辑。在每个使用计时器相关机制的类上实现接口。最后,在您的基础(逻辑)类上,将您的所有 TimerControlled 对象添加到一个数组(TimerControlled)中,这将允许您循环遍历该数组并使用 2 行代码调用这些对象的 TimerTick 方法。

    界面:

    interface TimerControlled
    {
       void TimerTick();
    }
    

    在你的每个类中实现它:

    public class YourClass: TimerControlled{
       ....
       public void TimerTick(){
          advanceCooldown();
          advanceBuffTimers();
       }
    }
    

    最后将您的课程添加到TimerControlled 列表中:

    class YourLogicClass{
       List<YourClass> characters= new List<YourClass>();
       private timer;
       List<TimerControlled> timerControlledObjects = new List<TimerControlled>();
       ...
       public void Initialize(){
          ... //your code, character creation and such
          foreach(YourClass character in characters){ //do the same with all objects that have TimerControlled interface implemented
             timerControlledObjects.add(character);
          }
          timer = new Timer();
          timer.Tick += new EventHandler(timerTick)
          timer.Start();
    
       } 
    
       public void timerTick(Object sender, EventArgs e){
          foreach(TimerControlled timerControlledObject in timerControlObjects){
             timerControlledObject.TimerTick();
          }
       }
    
    }
    
    1. (从长远来看不是一个很好的选择)静态类中的静态计时器,如Global.timer,这意味着该计时器仅存在一个实例。然后将事件处理程序附加到每个相关类的计时器以处理计时器滴答声。

    代码:

    public static class Global{
    //I usually create such class for global settings
       public static Timer timer= new Timer();
    }
    
    
    
    class YourLogicClass{
       public void Initialize(){
           ... 
           Global.timer.Start();
       }
    }
    
    class YourClass{
    
       public YourClass(){
          Global.timer.tick += new EventHandler(timerTick);
       }
    
    
       private void timerTick(Object sender,EventArgs e){
          advanceCooldowns();
          advanceBuffTimers();
       }
    }
    

    请记住,我已经在脑海中编写了代码,因此可能存在一些语法错误,但逻辑是正确的。

    如果您对答案还有其他问题,请尽管提问。

    【讨论】:

    • 我想我需要解释一下。
    • 我有一个全局计时器,它接受在特定时间通知的请求。我还为每个拥有 buff 数据的角色设置了一个 buff 管理器。确实需要时间检查才能删除增益,不是吗?因此,buff 管理器请求一个 buff 在计时器上登记,并在结束时通知。麻烦的是,我还希望有物品冷却时间、攻击冷却时间、技能冷却时间和任何其他需要时间检查或通知的东西。
    • 我接近它的方法不是通知冷却时间/buff计时器何时到达目标,而是记录剩余时间并逐个滴答地耗尽该时间,当时间用完时激活任何类型的逻辑重新启用项目/删除 buff 等。这样所有逻辑都保留在相关类中,并且计时器所做的只是通知你的类每个滴答声。
    • 这是一种方式。但是,每次滴答进行大量浮点计算会不会太昂贵?
    • 如果你仔细想想,不管你把逻辑放在哪里,你都会做同样的事情。无论哪种方式,您都将继续加/减并检查计时器是否达到您的目标。我的意思是,即使您从逻辑类通知所有单独的 Buff Manager,逻辑类仍然必须跟踪何时通知每个管理器,并且可以参考何时放置计时器以及何时调用它或单个变量对于每个与我之前在评论中描述的类似的增益。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 2021-12-21
    • 1970-01-01
    • 2021-09-09
    • 2017-10-06
    相关资源
    最近更新 更多