2015-11-04 79 views
0

我有一个关于计时器的简短问题。在我的代码中,我想创建一个种植农场的游戏,并带有一个显示工厂是否完成的计时器。
为什么这样的:C#Timer-Crop农场游戏错误

public static string currentPlant; 
    public static Timer growTimer; 
    public static void InitGrowTimer(int time, string name) 
    { 
     growTimer = new Timer(); 
     growTimer.Tick += new EventHandler(growTimer_Finished); 
     growTimer.Interval = time; 

     currentPlant = name; 
    } 
    public static void plantCrop(string crop) 
    { 
     if (plantActive == false) 
     { 
      if (plants.Contains(crop.ToLower())) 
      { 

       // growTimer.Interval = <plant>Time; 
       // proceed plants 
       switch (crop.ToLower()) 
       { 
        case "wheat": 
         InitGrowTimer(wheatTime, wheatName); 
         growTimer.Start(); 
         break; 

        default: 
         MessageBox.Show("FATAL ERROR\nThe plant is contained in the definition list but not in the plant menu!", "Civilisation", MessageBoxButtons.OK, MessageBoxIcon.Error); 
         break; 
       } 

      } 
      else 
      { 
       MessageBox.Show("This plant is not available!", "Civilisation", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
     } 
     else 
     { 
      Console.ForegroundColor = ConsoleColor.Red; 
      Console.WriteLine("There is already a plant in progress! Current plant: {0}", currentPlant); 
     } 
    } 

    private static void growTimer_Finished (object sender, EventArgs e) 
    { 
     growTimer.Stop(); 
     MessageBox.Show("Your " + currentPlant + " is finished!", "Civilisation", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
    } 

不启动定时器,或只是不显示在最后的消息框。我在创建计时器或创建滴答事件时做错了什么?

编辑:这是我的主要方法:

static void Main(string[] args) 
    { 
     InitializeLists(); 
     // game begin 
     Farm.plantCrop("wheat"); 
     Console.ForegroundColor = ConsoleColor.Green; 
     Console.Write("Please enter your desired name: "); 
     QC.resetColors(); 
     name = Console.ReadLine(); 
     Console.WriteLine(/*Introduction*/"Welcome to the world of Civilisation. In this world it is your choice what\n" + 
              "you are up to. You can be a farmer, miner or fighter, whatever you want, the\n" + 
              "world is yours to explore! Have fun!" 
             ); 
     Console.ReadKey(); 
     Console.Clear(); 

     while (true) // run game 
     { 
      // menu 
      Console.Write("   What do you want to do?\n" + 
          "Farm Mine Explore Go to the city\n" 
         ); 
      input = Console.ReadLine(); 
      if (menuContent.Contains(input.ToLower())) 
      { 
       if (input.ToLower() == menuContent.ElementAt(0)) 
       { 
        // farm 
        Console.ForegroundColor = ConsoleColor.Green; 
        Console.WriteLine("-- Farm --\nSelect a crop to plant:"); 
        Console.ForegroundColor = ConsoleColor.DarkGreen; 
        int icount = 0; 
        for (int i = 0; i < Farm.plants.Count; i++) 
        { 
         if (icount < 3) 
         { 
          Console.Write(Farm.plants.ElementAt(i)); 
          Console.Write("\t\t"); 
          icount++; 
         } 
         else 
         { 
          Console.Write("\n"); 
          icount = 0; 
          Console.Write(Farm.plants.ElementAt(i)); 
          Console.Write("\t\t"); 
          icount++; 
         } 
        } 
        Console.WriteLine(); 
        QC.resetColors(); 
        string crop = Console.ReadLine(); 
        Farm.plantCrop(crop); 
       } 
       if (input.ToLower() == menuContent.ElementAt(1)) 
       { 
        // miner 

       } 
       if (input.ToLower() == menuContent.ElementAt(2)) 
       { 
        // fight 

       } 
      } 





     } 
    } 
+1

你确定'growTimer.Start();'被调用吗?在具有断点或记录的调试模式下。 –

+0

@ Pierre-LucPineault是的,它的值是growTimer {Interval = 2000},wheatTime = 2000 –

+0

你在哪里叫'plantCrop(“wheat”)'? – phoog

回答

2

System.Windows.Forms.Timer定时器是为具有单个UI线程的Windows窗体应用程序制作的。

您需要使用System.Threading.Timer计时器代替您的控制台应用程序。

它的创建和回调的参数是有一点不同:

public static void InitGrowTimer(int time, string name) 
    { 
     growTimer = new System.Threading.Timer(GrowTimer_Finished, null, time, Timeout.Infinite); 
     currentPlant = name; 
    } 

    private static void GrowTimer_Finished(object sender) 
    { 
     MessageBox.Show("Your " + currentPlant + " is finished!", "Civilisation", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
    } 

你不需要任何Start方法,它会自动在创建时启动。

你也不需要Stop;由于参数Timeout.Infinite,它将只运行一次。

如果需要(例如EventArgs),您可以用想要回叫接收的对象代替null


小方面说明:我已将PascalCase中的回调方法重命名。按照惯例,C#中的方法应始终以大写字母开头。

+0

的价值你确定他应该在调用WinForms'MessageBox.Show'时使用'System.Threading.Timer'吗? – Enigmativity

+0

啊,这是有道理的,我明天会测试它的第一件事。我正在用骆驼套写作,因为这是我们在商店课程中使用的。 –

+0

@Enigmativity那是另一个问题,从另一个线程更新UI。那样我推荐他阅读[.NET 4中的并行性](http://reedcopsey.com/series/parallelism-in-net4/)。 – mijail

-2

因为你,因为你告诉自己,不要启动定时器。

growTimer = new Timer(); 
growTimer.Tick += new EventHandler(growTimer_Finished); 
growTimer.Interval = time; 
growTimer.Start(); 
+0

它在'InitGrowTimer'方法调用下开始。 –

+0

@ Pierre-LucPineault可能是这个问题吧? –

+0

@Ian号将'Start'行移入方法不会改变任何内容。它在退出'InitGrowTimer'后立即被调用。除非你试图从'plantCrop'之外的地方开始你的计时器。 –