0

i am making a text-based game, i wanted to make an intro with text printing slowly(char by char with a difference of ~100ms) i tried making a loop that loops through the string and prints the chars one by one, but i need a timer inbetween something i wasn't able to achieve even with the help of google. so i need help with making a timer or an another algorithm in order to print strings slowly. my code:

static void PrintSlowly(string print)
{
    foreach(char l in print) {
        Console.Write(l);
        //timer here
    }
    Console.Write("\n");
}
Ravid
  • 9
  • 2

2 Answers2

1

Nasty, nasty cheap solution :

static void PrintSlowly(string print)
{
    foreach(char l in print) {
        Console.Write(l);
        Thread.sleep(10); // sleep for 10 milliseconds    
    }
    Console.Write("\n");
}

Since you probably don't care much about performance, you could go with this. but keep in mind that Thread.Sleep is pretty wasteful

Community
  • 1
  • 1
Timothy Groote
  • 8,614
  • 26
  • 52
  • milliseconds, like the comment behind it states – Timothy Groote Jun 19 '15 at 10:45
  • why is threading so awful? didn't really understand the thread(i had to) – Ravid Jun 19 '15 at 10:49
  • 1
    Threading isn't awful. Once you wrapped your head around the concept of concurrent threads and their synchronization, you have a monstrous mighty tool to achieve solutions. But it is one of the not-beginner-friendly topics. – Patrik Jun 19 '15 at 11:02
  • @Ravid `Thread.Sleep` causes the current thread you are in to wait for a specific number of milliseconds before continuing. every program you run has at least one thread. if you're calling `Thread.Sleep` on the main thread of a program, and there is only one thread, that means nothing at all can happen while the thread is sleeping. – Timothy Groote Jun 19 '15 at 11:31
1

Based on apomene's solution I'd opt for a (real) timer based solution, since Thread.Sleep is pretty imprecise.

static void PrintSlowly(string print)
{
    int index = 0;
    System.Timers.Timer timer = new System.Timers.Timer();

    timer.Interval = 100;
    timer.Elapsed += new System.Timers.ElapsedEventHandler((sender, args) =>
    {
        if (index < print.Length)
        {
            Console.Write(print[index]);
            index++;
        }
        else
        {
            Console.Write("\n");
            timer.Enabled = false;
        }
    });

    timer.Enabled = true;
}

The Timer will come back every 100 milliseconds, pick the next character and print it. If no more characters are available, it prints return and disables itself. I wrote it using an anonymous handling method using a lambda-expression - not the cleanest way. It's just about the principle. This implementation runs complete in parallel to your application, so it does not block your code-execution. If you want that, a different approach may be better.

Alternatively - as a modification of apomene's solution without busy-wait - you can use a ManualResetEvent.

static System.Timers.Timer delay = new System.Timers.Timer();
static AutoResetEvent reset = new AutoResetEvent(false);

private static void InitTimer()
{
    delay.Interval = 100;
    delay.Elapsed += OnTimedEvent;
    delay.Enabled = false;
}

private static void OnTimedEvent(object sender, ElapsedEventArgs e)
{
    ((System.Timers.Timer)sender).Enabled = false;
    reset.Set();
}

static void PrintSlowly2(string print)
{
    InitTimer();

    foreach (char l in print)
    {
        Console.Write(l);
        delay.Enabled = true;

        reset.WaitOne();
    }
    Console.Write("\n");
}

It waits using a AutoResetEvent, so other applications/threads can use the processor!

Patrik
  • 1,355
  • 12
  • 22