2009-12-17 19 views
31

मैं सिर्फ यह जानना चाहता हूं कि ब्लिंकिंग जैसे सरल एनिमेशन कैसे बनाएं, सी # कंसोल अनुप्रयोगों पर सामान ले जाएं। क्या इसके लिए कोई विशेष विधि है?कंसोल एनिमेशन

+0

+1 इस प्रश्न को प्यार किया, IMMD =) –

उत्तर

3

आप का उपयोग करने के Console.ForegroundColor, Console.BackgroundColor और Console.SetCursorPosition(int, int)

संपादित की आवश्यकता होगी: प्रेरणा के लिए, Let's Dance

+1

मुझे लेट्स डांस एनीमेशन के फ्रेम को पाठ के रूप में देखना अच्छा लगेगा, इसलिए हम कंसोल स्पिनर के रूप में ऐसी एनीमेशन को कार्यान्वित कर सकते हैं। – TaterJuice

5

हाँ, वहाँ इस के लिए quite a few methods हैं। क्षेत्रों के शीर्ष पर

  1. SetCursorPosition (आप के चारों ओर कर्सर ले जाने के कर सकते हैं, और तत्वों के ऊपर लिख)
  2. MoveBufferArea (कॉपी/पेस्ट:

    विशेष रूप से, आप निम्नलिखित कंसोल तरीकों को देखने के लिए चाहते हो सकता है)

  3. ForegroundColor और BackgroundColor (परिवर्तन रंग)
0

मैं भी यकीन है कि मैं वास्तव में क्या आप के बारे में पता कर रहे हैं नहीं कर रहा हूँ। लेकिन मैं इसे एक शॉट दे दूँगा। मुझे लगता है कि "झपकी" प्रभावित करने का सबसे बड़ा और सबसे अच्छा तरीका है (या मुझे लगता है कि झिलमिलाहट प्रभावित है) कैरिज रिटर्न का उपयोग करना है। आपको यह समझाने का सबसे अच्छा तरीका आपको फू बार प्रयोग दिखाना है। एक नई परियोजना शुरू करें, और अपने मुख्य समारोह में, इसे आज़माएं।

Console.WriteLine("Foo/nBar"); 

उत्पादन इस

Foo 
Bar 

की तरह दिखाई देगा लेकिन अगर आप एक गाड़ी वापसी का उपयोग करें।

Console.WriteLine("Foo/rBar"); 

उत्पादन इस

Bar 

कारण की तरह दिखाई देगा कि फू लिखा है, तो गाड़ी वापसी आप लाइन के शुरू करने के पीछे ले जाता है, तो बार लिखा गया है। आप जो भी देखते हैं वह बार है। यह एक पंक्ति पर चीजों को फिर से लिखने के बजाय, कई पंक्तियों पर फिर से लिखने के लिए सहायक हो सकता है। प्रगति करने का एक तरीका Console.Write() का उपयोग करना होगा; इसे आजमाएं।

Console.Write("Loading"); 
for(int i = 0; i < 10; i++) 
{ 
    Thread.Sleep(1000); 
    Console.Write("."); 
} 

उत्पादन होना चाहिए

Loading 

एक fullstop 10 सेकंड के लिए हर दूसरे इसके बाद।

यदि आप Console.Write() के साथ कैरिज रिटर्न को जोड़ते हैं; फ़ंक्शन आप एक ही पंक्ति पर कई चीजें लिख सकते हैं, रेखा को साफ़ कर सकते हैं और कुछ और लिख सकते हैं, या वास्तव में, वही चीज़ थोड़ा सा स्थानांतरित हो गई है। (यह निश्चित रूप से आपको दिखाए जाने से ज़्यादा ज़रूरत होगी, जैसे कि "ऑब्जेक्ट" जिसे आप नियंत्रित कर रहे हैं, रिकॉर्डिंग की तरह है। यदि आप एक छोटा सा उदाहरण चाहते हैं तो मुझे एक करने में खुशी होगी, बस टिप्पणी करें और इसके लिए मुझसे पूछें :)

संपादित करें: मैंने लोगों को रंग का जिक्र करते हुए देखा, जिसे मैं भूल गया। अगर आप एनीमेशन कर रहे थे तो मुझे लगता है कि रंग जरूरी होगा। अग्रभूमि रंग और पृष्ठभूमि रंग जहां यह है। ध्यान दें कि ForegroundColor कंसोल पर लिखे गए अगले वर्णों पर लागू होगा, यह कंसोल को पूरी तरह से याद नहीं करेगा। /संपादित

मुझे आशा है कि इस मदद करता है,

Skintkingle;)

+0

दुर्भाग्यवश, यह ज्यादातर मामलों के लिए काम नहीं करता है। आप यूपी को \ r के साथ एक लाइन नहीं जा सकते हैं, इसलिए आप कंसोल का उपयोग किए बिना बहुत सीमित हैं। SetCursorPosition –

+0

आह हां बिल्कुल। मैं अब कंसोल में चारों ओर नहीं खेलता हूं, मैं सबसे स्पष्ट चीजों को भूल जाता हूं। :) – Skintkingle

41

पारंपरिक कंसोल स्पिनर:

static void Main(string[] args) 
    { 
     ConsoleSpiner spin = new ConsoleSpiner(); 
     Console.Write("Working...."); 
     while (true) 
     { 
      spin.Turn(); 
     } 
    } 

public class ConsoleSpiner 
{ 
    int counter; 
    public ConsoleSpiner() 
    { 
     counter = 0; 
    } 
    public void Turn() 
    { 
     counter++;   
     switch (counter % 4) 
     { 
      case 0: Console.Write("/"); break; 
      case 1: Console.Write("-"); break; 
      case 2: Console.Write("\\"); break; 
      case 3: Console.Write("|"); break; 
     } 
     Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); 
    } 
} 
4

बस इसके बारे में इस और कुछ अन्य धागे को देखा और सामान इस तरह का प्यार ! मैंने तुकुका के कोड का अच्छा टुकड़ा लिया और इसे थोड़ा सुधार लिया ताकि कक्षा आसानी से किसी भी स्पिन अनुक्रम के लिए सेट की जा सके। मैं शायद इसे कुछ पॉलिश करने के लिए कुछ एक्सेसर्स और ओवरलोडेड कन्स्ट्रक्टर जोड़ दूंगा और इसे ओल 'टूलबॉक्स में रखूंगा। मजेदार चीजें!

class ConsoleSpinner 
{ 
    int counter; 
    string[] sequence; 

    public ConsoleSpinner() 
    { 
     counter = 0; 
     sequence = new string[] { "/", "-", "\\", "|" }; 
     sequence = new string[] { ".", "o", "0", "o"}; 
     sequence = new string[] { "+", "x" }; 
     sequence = new string[] { "V", "<", "^", ">" }; 
     sequence = new string[] { ". ", ".. ", "... ", "...." }; 
    } 

    public void Turn() 
    { 
     counter++; 

     if (counter >= sequence.Length) 
      counter = 0; 

     Console.Write(sequence[counter]); 
     Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop); 
    } 
} 
1

मैंने सोचा कि मैं पहले सूचीबद्ध कोड के अपने संस्करण के साथ झुकाऊंगा। संदेश यह है:

class ConsoleSpinner 
{ 
    bool increment = true, 
     loop = false; 
    int counter = 0; 
    int delay; 
    string[] sequence; 

    public ConsoleSpinner(string sSequence = "dots", int iDelay = 100, bool bLoop = false) 
    { 
     delay = iDelay; 
     if (sSequence == "dots") 
     { 
      sequence = new string[] { ". ", ".. ", "... ", "...." }; 
      loop = true; 
     } 
     else if (sSequence == "slashes") 
      sequence = new string[] { "/", "-", "\\", "|" }; 
     else if (sSequence == "circles") 
      sequence = new string[] { ".", "o", "0", "o" }; 
     else if (sSequence == "crosses") 
      sequence = new string[] { "+", "x" }; 
     else if (sSequence == "arrows") 
      sequence = new string[] { "V", "<", "^", ">" }; 
    } 

    public void Turn() 
    { 
     if (loop) 
     { 
      if (counter >= sequence.Length - 1) 
       increment = false; 
      if (counter <= 0) 
       increment = true; 

      if (increment) 
       counter++; 
      else if (!increment) 
       counter--; 
     } 
     else 
     { 
      counter++; 

      if (counter >= sequence.Length) 
       counter = 0; 
     } 

     Console.Write(sequence[counter]); 
     Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop); 

     System.Threading.Thread.Sleep(delay); 
    } 
} 

जोड़ता देरी (दुर्भाग्य से Thread.Sleep() के माध्यम से लेकिन, हे), पाश करने की क्षमता एनीमेशन आगे और पीछे की (उल्टा करने के लिए जब यह अंत हिट शुरू होता है), और कुल मिलाकर सामान्य सुधार। का आनंद लें!

public sealed class Spinner 
{ 
    private static Lazy<Spinner> lazy = 
     new Lazy<Spinner>(()=> new Spinner()); 

    public static void Reset() 
    { 
     lazy = new Lazy<Spinner>(()=> new Spinner()); 
    } 

    public static Spinner Instance { get { return lazy.Value; }} 

    private readonly int _consoleX; 
    private readonly int _consoleY; 
    private readonly char[] _frames = { '|', '/', '-', '\\' }; 
    private int _current; 

    private Spinner() 
    { 
     _current = 0; 
     _consoleX = Console.CursorLeft; 
     _consoleY = Console.CursorTop; 
    } 

    public void Update() 
    { 
     Console.Write(_frames[_current]); 
     Console.SetCursorPosition(_consoleX, _consoleY); 

     if (++_current >= _frames.Length) 
      _current = 0; 
    } 
} 

कॉल Spinner.Instance.Update() कंसोल की वर्तमान स्थिति पर स्पिनर शुरू करने के लिए:

1

यह मेरा पसंदीदा तरीका होगा। कोई भी लगातार कॉल अगले फ्रेम को उसी स्थिति में प्रस्तुत करेगा।

कॉल Spinner.Reset() यदि आप अधिक टेक्स्ट लिखना चाहते हैं और फिर एक नए स्थान पर एक नया स्पिनर जोड़ें।

8

यहां मेरा स्पिनर है। यह करने के उद्देश्य से है, जबकि उपयोगकर्ता के लिए स्पिनर प्रदर्शित करता है कि कुछ वास्तव में क्या हो रहा है एक कार्यक्रम कुछ काम करना है:

public class Spinner : IDisposable 
    { 
    private const string Sequence = @"/-\|"; 
    private int counter = 0; 
    private readonly int left; 
    private readonly int top; 
    private readonly int delay; 
    private bool active; 
    private readonly Thread thread; 

    public Spinner(int left, int top, int delay = 100) 
    { 
     this.left = left; 
     this.top = top; 
     this.delay = delay; 
     thread = new Thread(Spin); 
    } 

    public void Start() 
    { 
     active = true; 
     if (!thread.IsAlive) 
      thread.Start(); 
    } 

    public void Stop() 
    { 
     active = false; 
     Draw(' '); 
    } 

    private void Spin() 
    { 
     while (active) 
     { 
      Turn(); 
      Thread.Sleep(delay); 
     } 
    } 

    private void Draw(char c) 
    { 
     Console.SetCursorPosition(left, top); 
     Console.ForegroundColor = ConsoleColor.Green; 
     Console.Write(c); 
    } 

    private void Turn() 
    { 
     Draw(Sequence[++counter % Sequence.Length]); 
    } 

    public void Dispose() 
    { 
     Stop(); 
    } 
    } 

और तुम इस तरह वर्ग का उपयोग करें: के साथ

 var spinner = new Spinner(10, 10); 

    spinner.Start(); 

    // Do your work here instead of sleeping... 
    Thread.Sleep(10000); 

    spinner.Stop(); 
+0

बहुत बढ़िया उदाहरण, बिल्कुल वही जो मैं चाहता था: जबकि मैं एक गहन कार्य कर रहा हूं, मुझे कुछ प्रगतिशील – jjay225

+0

चाहिए कृपया मेरे anwser पर एक नज़र डालें, मैंने आपका कोड लिया और इसे थोड़ा सा संशोधित किया। – Rumplin

1

बढ़िया काम ConsoleSpinner और अनुक्रम कार्यान्वयन। कोड के लिए धन्यवाद। मैंने अपने अनुकूलित दृष्टिकोण को साझा करने के बारे में सोचा।

public class ConsoleSpinner 
{ 
    static string[,] sequence = null; 

    public int Delay { get; set; } = 200; 

    int totalSequences = 0; 
    int counter; 

    public ConsoleSpinner() 
    { 
     counter = 0; 
     sequence = new string[,] { 
      { "/", "-", "\\", "|" }, 
      { ".", "o", "0", "o" }, 
      { "+", "x","+","x" }, 
      { "V", "<", "^", ">" }, 
      { ". ", ".. ", "... ", "...." }, 
      { "=> ", "==> ", "===> ", "====>" }, 
      // ADD YOUR OWN CREATIVE SEQUENCE HERE IF YOU LIKE 
     }; 

     totalSequences = sequence.GetLength(0); 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="sequenceCode"> 0 | 1 | 2 |3 | 4 | 5 </param> 
    public void Turn(string displayMsg = "", int sequenceCode = 0) 
    { 
     counter++; 

     Thread.Sleep(Delay); 

     sequenceCode = sequenceCode > totalSequences - 1 ? 0 : sequenceCode; 

     int counterValue = counter % 4; 

     string fullMessage = displayMsg + sequence[sequenceCode, counterValue]; 
     int msglength = fullMessage.Length; 

     Console.Write(fullMessage); 

     Console.SetCursorPosition(Console.CursorLeft - msglength, Console.CursorTop); 
    } 
} 

कार्यान्वयन:

ConsoleSpinner spinner = new ConsoleSpinner(); 
spinner.Delay = 300; 
while (true) 
{ 
    spinner.Turn(displayMsg: "Loading ",sequenceCode:5); 
} 

आउटपुट:

enter image description here

0

मैं @ThisGuy से anwser लिया और यह थोड़ा संशोधित, लेकिन मैंने देखा है, कि कभी कभी पंक्ति को साफ़ नहीं किया जाना चाहिए जैसा कि इसे करना चाहिए।

static void Main(string[] args) 
    { 
     Console.WriteLine("1"); 
     var tddf = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd 4343",() => 
     { 
      return ""; 
     }); 
     Console.WriteLine("2"); 
     var tdd = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd",() => 
     { 
      Thread.Sleep(1); 
      return ""; 
     }); 
     Console.WriteLine("3"); 
     var t = XConsole.BusyIndicator("test 1 trtg vdgd",() => 
     { 
      Thread.Sleep(1000); 
      return ""; 
     }); 
     Console.WriteLine("4"); 
     var xt = XConsole.BusyIndicator("test 2",() => 
     { 
      Thread.Sleep(2000); 
      return ""; 
     }); 
     var xtx = XConsole.BusyIndicator("test 2 csds fsd fdsf ds s",() => 
     { 
      Thread.Sleep(2000); 
      return ""; 
     }); 

     Console.WriteLine("5"); 
     Thread.Sleep(4000); 
    } 

स्पिनर वर्ग:

public class Spinner : IDisposable 
    { 
     private const string Sequence1 = @"/-\|"; 
     private const string Sequence3 = @".o0o"; 
     private const string Sequence2 = @"<^>v"; 
     private const string Sequence4 = @"#■."; 
     private const string Sequence5 = @"▄▀"; 
     private const string Sequence = @"└┘┐┌"; 
     private string BusyMessage = ""; 
     private int counter = 0; 
     private readonly int delay; 
     private bool active; 
     private readonly Thread thread; 

     public Spinner(int delay = 200) 
     { 
      this.delay = delay; 
      thread = new Thread(Spin); 
     } 

     public void Start() 
     { 
      active = true; 
      Console.CursorVisible = false; 
      if (!thread.IsAlive) 
      { 
       thread.Start(); 
      } 
     } 

     public void Start(string busyMessage) 
     { 
      BusyMessage = busyMessage; 
      Start(); 
     } 

     public void Stop() 
     {   
      active = false; 
      Console.CursorVisible = true; 
      ClearCurrentConsoleLine(); 
      BusyMessage = ""; 
     } 

private static void ClearCurrentConsoleLine() 
{ 
    int currentLineCursor = Console.CursorTop; 
    Console.SetCursorPosition(0, Console.CursorTop); 
    Console.Write(new string(' ', Console.WindowWidth)); 
    Console.SetCursorPosition(0, currentLineCursor); 
} 

     private void Spin() 
     { 
      while (active) 
      { 
       Turn(); 
       Thread.Sleep(delay); 
      } 
     } 

     /// <summary> 
     /// Draws the busy indicator 
     /// </summary> 
     /// <param name="c">if empty char, then clear screen</param> 
    private void Draw(char c) 
    { 
     int left = Console.CursorLeft; 
     int top = Console.CursorTop; 

     Console.Write('['); 
     Console.ForegroundColor = ConsoleColor.Green; 
     Console.Write(c); 
     Console.ForegroundColor = ConsoleColor.Gray; 
     Console.Write(']'); 
     if (!string.IsNullOrEmpty(BusyMessage)) 
     { 
      Console.Write(" " + BusyMessage); 
     } 

     //reset cursor position 
     Console.SetCursorPosition(left, top); 
    } 

     private void Turn() 
     { 
      Draw(Sequence[++counter % Sequence.Length]); 
     } 

     public void Dispose() 
     { 
      Stop(); 
     } 
    } 

मेरे कंसोल वर्ग:

public static class XConsole { 
    public static T BusyIndicator<T>(Func<T> action) 
    { 
     T result; 

     using (var spinner = new Spinner()) 
     { 
      spinner.Start(); 

      result = action(); 

      spinner.Stop(); 
     } 

     return result; 
    } 

    public static T BusyIndicator<T>(string content, Func<T> action) 
    { 
     T result; 

     using (var spinner = new Spinner()) 
     { 
      spinner.Start(content); 

      result = action(); 

      spinner.Stop(); 
     } 

     return result; 
    } 
} 

क्यों मैं इस परिणाम कभी कभी देखते हैं?

1 
2 
3 st 0 trtg fdfdfvdgd ] 
4 
[└] test 2 csds fsd fdsf ds s 

ऐसा लगता है कि निपटान ट्रिगर नहीं हुआ था? या एक नया Task क्षय शुरू हुआ?

यह इस तरह दिखना चाहिए:

1 
2 
3 
4 
[└] test 2 csds fsd fdsf ds s 

अद्यतन:

मैं ClearCurrentConsoleLine(); जोड़ा गया है और बदल Draw विधि, इस समस्या का समाधान हो।

+0

मुझे लगता है कि यह थ्रेड सुरक्षित नहीं है, लेकिन इसे कैसे ठीक किया जाए? – Rumplin

+0

पहली दो नींद ड्रॉ (200 एमएस) की शुरुआती देरी से कम है। यही कारण है कि तीसरी पंक्ति संदेश प्रदर्शित करने वाला पहला व्यक्ति है। आपकी नींद कॉलबैक में हो रही है, इसलिए वे सभी समानांतर में लात मारे जा रहे हैं। आप वर्तमान कंसोल स्थिति पर स्थिति मुद्रित कर रहे हैं जो निष्पादन के दौरान बदलता है। हार्डकोड बाएं = 0 और शीर्ष = 5 और आप जो आउटपुट चाहते हैं उसे देखेंगे। कहा के साथ, मैं समझ में नहीं आता कि आप क्या करने की कोशिश कर रहे हैं। – ThisGuy

+0

नेटवर्क शेयर से फ़ाइलें पढ़ना। इसके साथ उपयोगकर्ता देखेंगे कि कुछ हो रहा है। यह बड़ी मात्रा में फाइल पढ़ रहा है और इसमें नेटवर्क शेयर के साथ कुछ समय लगता है। 'थ्रेड स्लीप' यहां सिमुलेट करता है। – Rumplin

संबंधित मुद्दे