【问题标题】:Delay a xna game with timers使用计时器延迟 xna 游戏
【发布时间】:2011-08-23 01:20:19
【问题描述】:

我正在制作一个二十一点游戏,其中需要在最后一张牌之后显示一张牌。 我用谷歌搜索它并看到了 Thread.Sleep - 但人们说计时器会更好。 我怎样才能用计时器做到这一点? 谢谢!

【问题讨论】:

  • 你不应该使用任何一个(尤其是不要使用Thread.Sleep)。在调用Game.Update 时累积gameTime.ElapsedGameTime
  • @Andrew Russel +1 Thread.Sleep 应避免在 99.9% 的情况下您可能会使用它!
  • 你能举个例子吗?
  • @Matt - 为什么?在单独的线程中实现功能的原因之一是可以简单地“在线”执行此类操作 - 如果协议需要两秒延迟,sleep(2000) 是一个不会对任何其他协议产生不利影响的单行线程或需要任何计时器驱动的状态机。 Sleep() 当然可以被滥用,就像几乎任何东西一样。
  • @Martin James 关于这个主题有很多讨论.. stackoverflow.com/questions/1096794/is-sleep-evil

标签: c# multithreading timer xna


【解决方案1】:
float WaitTimeToShowCard = 0;


public void Update(GameTime gametime)
{

    if (HasToShowCard ()) 
    {
         WaitTimeToShowCard = 1;
    }

    if (WaitTimeToShowCard >0)
    {
         WaitTimeToShowCard -= (float) gametime.Elapsed.TotalSeconds;
         if (WaitTimeToShowCard <=0)
         {
             WaitTimeToShowCard = 0;
             ShowCard();
         } 
    }
}

public class Timer
{
    public Action Trigger;
    public float Interval;
    float Elapsed;

    Timer() {}

    public void Update(float Seconds)
    {
        Elapsed+= Seconds;
        if (Elapsed>= Interval)
        {
             Trigger.Invoke();
             Destroy();
        }
    }

    public void Destroy()
    {
        TimerManager.Remove(this);
    }

    public static void Create(float Interval, Action Trigger)
    {
        Timer Timer = new Timer() { Interval = Interval, Trigger = Trigger }
        TimerManager.Add(this);
    }
}


public class TimerManager : GameComponent
{
     List<Timer> ToRemove = new List<Timer>();
     List<Timer> Timers = new List<Timer>();

     public static TimerManager Instance;

     public static void Add(Timer Timer) { Instance.Timers.Add( Timer ); }
     public static void Remove(Timer Timer) { Instance.ToRemove.Add(Timer); }

     public void Update(GameTime gametime)
     {
         foreach (Timer timer in ToRemove) Timers.Remove(timer);
         ToRemove.Clear();
         foreach (Timer timer in Timers) timer.Update( (float) gametime.Elapsed.Totalseconds); 

     }
}


public class Game
{
     public void Initialize() { Components.Add(new TimerManager(this);}
     public Update()
     {
          if (HasToShowCard(out card)) 
          {
              Timer.Create(1, () => card.Show());
          }
     }
}   

【讨论】:

    【解决方案2】:
    using System.Timers;
    .
    .
    .    
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Timer t = new Timer(1000);
        //The number is the interval in miliseconds
    
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            t.Elapsed += new ElapsedEventHandler(t_Elapsed);
            t.Enabled = true;
        }
    
        void t_Elapsed(object sender, ElapsedEventArgs e)
        {
            //code
        }
    
    .
    .
    .
    }
    

    我复制了一些代码以显示添加代码的位置... 此外,在键入“t.Elapsed +=”后,按两次 TAB 以创建事件处理程序。 如果要停止计时器,请将“启用”属性设置为 false。 ('t' 是一个错误的变量名)

    【讨论】:

    • System.Timers.Timer 在紧凑框架中可用吗?可能值得让 OP 知道他正在牺牲 Xbox 和电话支持。
    • 嗯..我不知道是不是..但我不能评论他原来的问题来通知他。 (如果您看到此内容并希望获得 Xbox 或电话支持,请使用 Andrew Russel 的建议
    • 虽然 OP 要求提供计时器,但它确实不是游戏开发中的最佳解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 2013-10-23
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多