2013-06-03 33 views
1

幾個月前我剛開始學習編程,並決定做一個控制檯蛇遊戲。對於一件事情,一切都很有期待。c#控制檯蛇卡在長按鍵

如果我的蛇向上並按下箭頭並保持按下,我的蛇剛停止並停止停止一段時間後停止按下按鈕。

同樣的事情發生,如果我的蛇是正確的,我按右箭頭太長,我失去了一段時間的控制權(但蛇不停止)。它發生在每一個方面(左,右,上,下)。

我試圖將cki與另一個ConsoleKeyInfo進行比較,但它們之間有些微的延遲,但沒關係。如果我按住鍵,我的程序就會保持該位置並更新一個鍵。 (至少我認爲這是問題)

這是Console.ReadKey的「功能」,或者有什麼辦法讓這個?

請記住,我剛剛開始,所以我不知道高級的東西,但。

只要我不保持按鍵超過1秒,一切都完美無瑕。

public void LiikutaMato() //movesnake 
    { 

     if (Console.KeyAvailable) 
     { 
       ConsoleKeyInfo cki; 
       cki = Console.ReadKey(true); // <-- I believe this is where it gets stuck 

    } 
+0

輪詢率堆放在readkey輸入和你最終不得不等待它清除任何新的前堆被接受......只是猜測 – emd

+0

按下並保持按下時,系統會(我認爲)開始向控制檯發送多個按鍵事件。如果由於這些原因而導致阻塞(例如,您的計算或控制檯重繪需要比發送每個按鍵之間的時間更長的時間)或使蛇停止(例如,因爲您沒有在關鍵點瞬間移動蛇按通常改變方向),這可能會導致你的問題。 –

+1

只是一個建議......寫這樣的遊戲,作爲控制檯應用程序是有點矯枉過正和一點「解決方法」。您可能希望進一步提高您的通用編碼技能,因爲您將使用C#來學習XNA。 – Renan

回答

5

玩這個...它使用一個緊密的循環消耗按鍵,直到設置的延遲已經過期。你也不必按住鑰匙來保持蛇的移動。這是我的系統上非常敏感: Snake Console

class Program 
{ 

    public enum Direction 
    { 
     Up, 
     Down, 
     Right, 
     Left 
    } 

    static void Main(string[] args) 
    { 
     const int delay = 75; 
     string snake = "O"; 
     char border = 'X'; 

     int x, y; 
     int length; 
     bool crashed = false; 
     Direction curDirection = Direction.Up; 
     Dictionary<string, bool> eaten = new Dictionary<string, bool>(); 
     Console.CursorVisible = false; 

     ConsoleKeyInfo cki; 
     bool quit = false; 
     while (!quit) 
     { 
      Console.Clear(); 
      Console.Title = "Use 'a', 's', 'd' and 'w' to steer. Hit 'q' to quit."; 

      // draw border around the console: 
      string row = new String(border, Console.WindowWidth); 
      Console.SetCursorPosition(0, 0); 
      Console.Write(row); 
      Console.SetCursorPosition(0, Console.WindowHeight - 2); 
      Console.Write(row); 
      for (int borderY = 0; borderY < Console.WindowHeight - 2; borderY++) 
      { 
       Console.SetCursorPosition(0, borderY); 
       Console.Write(border.ToString()); 
       Console.SetCursorPosition(Console.WindowWidth - 1, borderY); 
       Console.Write(border.ToString()); 
      } 

      // reset all game variables: 
      length = 1; 
      crashed = false; 
      curDirection = Direction.Up; 
      eaten.Clear(); 
      x = Console.WindowWidth/2; 
      y = Console.WindowHeight/2; 
      eaten.Add(x.ToString("00") + y.ToString("00"), true); 

      // draw new snake: 
      Console.SetCursorPosition(x, y); 
      Console.Write(snake); 

      // wait for initial keypress: 
      while (!Console.KeyAvailable) 
      { 
       System.Threading.Thread.Sleep(10); 
      } 

      // see if intitial direction should be changed: 
      cki = Console.ReadKey(true); 
      switch (cki.KeyChar) 
      { 
       case 'w': 
        curDirection = Direction.Up; 
        break; 

       case 's': 
        curDirection = Direction.Down; 
        break; 

       case 'a': 
        curDirection = Direction.Left; 
        break; 

       case 'd': 
        curDirection = Direction.Right; 
        break; 

       case 'q': 
        quit = true; 
        break; 
      } 

      // main game loop: 
      DateTime nextCheck = DateTime.Now.AddMilliseconds(delay); 
      while (!quit && !crashed) 
      { 
       Console.Title = "Length: " + length.ToString(); 

       // consume keystrokes and change current direction until the delay has expired: 
       // *The snake won't actually move until after the delay! 
       while (nextCheck > DateTime.Now) 
       { 
        if (Console.KeyAvailable) 
        { 
         cki = Console.ReadKey(true); 
         switch (cki.KeyChar) 
         { 
          case 'w': 
           curDirection = Direction.Up; 
           break; 

          case 's': 
           curDirection = Direction.Down; 
           break; 

          case 'a': 
           curDirection = Direction.Left; 
           break; 

          case 'd': 
           curDirection = Direction.Right; 
           break; 

          case 'q': 
           quit = true; 
           break; 
         } 
        } 
       } 

       // if the user didn't quit, attempt to move without hitting the border: 
       if (!quit) 
       { 
        string key = ""; 
        switch (curDirection) 
        { 
         case Direction.Up: 
          if (y > 1) 
          { 
           y--; 
          } 
          else 
          { 
           crashed = true; 
          } 
          break; 

         case Direction.Down: 
          if (y < Console.WindowHeight - 3) 
          { 
           y++; 
          } 
          else 
          { 
           crashed = true; 
          } 
          break; 

         case Direction.Left: 
          if (x > 1) 
          { 
           x--; 
          } 
          else 
          { 
           crashed = true; 
          } 

          break; 

         case Direction.Right: 
          if (x < Console.WindowWidth - 2) 
          { 
           x++; 
          } 
          else 
          { 
           crashed = true; 
          } 
          break; 
        } 

        // if the user didn't hit the border, see if they hit the snake 
        if (!crashed) 
        { 
         key = x.ToString("00") + y.ToString("00"); 
         if (!eaten.ContainsKey(key)) 
         { 
          length++; 
          eaten.Add(key, true); 
          Console.SetCursorPosition(x, y); 
          Console.Write(snake); 
         } 
         else 
         { 
          crashed = true; 
         } 
        } 

        // set the next delay: 
        nextCheck = DateTime.Now.AddMilliseconds(delay); 
       } 
      } // end main game loop 

      if (crashed) 
      { 
       Console.Title = "*** Crashed! *** Length: " + length.ToString() + "  Hit 'q' to quit, or 'r' to retry!"; 

       // wait for quit or retry: 
       bool retry = false; 
       while (!quit && !retry) 
       { 
        if (Console.KeyAvailable) 
        { 
         cki = Console.ReadKey(true); 
         switch (cki.KeyChar) 
         { 
          case 'q': 
           quit = true; 
           break; 

          case 'r': 
           retry = true; 
           break; 
         } 
        } 
       } 
      } 

     } // end main program loop 

    } // end Main() 

} 
+0

Thank you Idle_Mind。它的工作原理是,我的問題是我同時更新了密鑰和蛇的長度,現在我首先檢查while循環中的密鑰,並在計時器過去之後因爲它,然後我修改了我的蛇座標,沒有更多的停止,我的蛇總是以相同的速度移動。 – Ville

+1

你從來沒有得到一個很酷的小遊戲upvote? – jp2code