C
C#β€’14mo ago
Noah Here

❔ How can I make a Console app with cool text that when displayed slowly writes whatever

I'm trying to make a little story console app and I want to make the wording so that when you want to continue you hit enter then it displays the letter one by one in quick succession as if to type fast.
33 Replies
Hazel πŸŒŠπŸ’ƒ
Hazel πŸŒŠπŸ’ƒβ€’14mo ago
You could do a simple while with Console.ReadKey and move through a string one character at a time:
Noah Here
Noah HereOPβ€’14mo ago
How would I do that?
Hazel πŸŒŠπŸ’ƒ
Hazel πŸŒŠπŸ’ƒβ€’14mo ago
How experienced are you with C# so far?
Noah Here
Noah HereOPβ€’14mo ago
Only been using it less than a month here and there I know all the basics but not much
Hazel πŸŒŠπŸ’ƒ
Hazel πŸŒŠπŸ’ƒβ€’14mo ago
So how would you start tackling this given what I've already stated and your current experience?
Noah Here
Noah HereOPβ€’14mo ago
I'm not sure, I might try to set a timer and display a certain one of the letters correlating to the timer? But I'm probably not smart enough for that
ZacharyPatten
ZacharyPattenβ€’14mo ago
First off, I jsut want to mention that users typically hate slow text πŸ˜› but I will get you an example one moment
Noah Here
Noah HereOPβ€’14mo ago
ok, I'm not gonna make it realy slow, just not instant
Hazel πŸŒŠπŸ’ƒ
Hazel πŸŒŠπŸ’ƒβ€’14mo ago
Oh, so they're not holding down enter here They're just pressing it once and it starts printing it out ?
Noah Here
Noah HereOPβ€’14mo ago
Yes
ZacharyPatten
ZacharyPattenβ€’14mo ago
public static void WriteWithRandomDelays(
string @string,
TimeSpan? minDelay = null,
TimeSpan? maxDelay = null,
Action<TimeSpan>? delay = null)
{
if (@string is null)
{
throw new ArgumentNullException(nameof(@string));
}

delay ??= Thread.Sleep;
minDelay ??= TimeSpan.FromMilliseconds(50);
maxDelay ??= minDelay + TimeSpan.FromMilliseconds(350);

if (minDelay.Value.TotalMilliseconds <= 0)
{
throw new ArgumentOutOfRangeException(nameof(minDelay), minDelay, $"{nameof(minDelay)}.{nameof(minDelay.Value.TotalMilliseconds)} <= 0");
}
if (minDelay.Value.TotalMilliseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(minDelay), minDelay, $"{nameof(minDelay)}.{nameof(minDelay.Value.TotalMilliseconds)} > {nameof(Int32)}.{nameof(int.MaxValue)}");
}
if (maxDelay.Value.TotalMilliseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(maxDelay), maxDelay, $"{nameof(maxDelay)}.{nameof(maxDelay.Value.TotalMilliseconds)} > {nameof(Int32)}.{nameof(int.MaxValue)}");
}
if (maxDelay < minDelay)
{
throw new ArgumentOutOfRangeException(nameof(maxDelay), maxDelay, $"{nameof(maxDelay)} < {nameof(minDelay)}");
}

int randomMax = Math.Max((int)(maxDelay.Value - minDelay.Value).TotalMilliseconds, 1);
foreach (char c in @string)
{
TimeSpan delayTimeSpan = TimeSpan.FromMilliseconds(Random.Shared.Next(randomMax)) + minDelay.Value;
delay(delayTimeSpan);
Console.Write(c);
}
}
public static void WriteWithRandomDelays(
string @string,
TimeSpan? minDelay = null,
TimeSpan? maxDelay = null,
Action<TimeSpan>? delay = null)
{
if (@string is null)
{
throw new ArgumentNullException(nameof(@string));
}

delay ??= Thread.Sleep;
minDelay ??= TimeSpan.FromMilliseconds(50);
maxDelay ??= minDelay + TimeSpan.FromMilliseconds(350);

if (minDelay.Value.TotalMilliseconds <= 0)
{
throw new ArgumentOutOfRangeException(nameof(minDelay), minDelay, $"{nameof(minDelay)}.{nameof(minDelay.Value.TotalMilliseconds)} <= 0");
}
if (minDelay.Value.TotalMilliseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(minDelay), minDelay, $"{nameof(minDelay)}.{nameof(minDelay.Value.TotalMilliseconds)} > {nameof(Int32)}.{nameof(int.MaxValue)}");
}
if (maxDelay.Value.TotalMilliseconds > int.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(maxDelay), maxDelay, $"{nameof(maxDelay)}.{nameof(maxDelay.Value.TotalMilliseconds)} > {nameof(Int32)}.{nameof(int.MaxValue)}");
}
if (maxDelay < minDelay)
{
throw new ArgumentOutOfRangeException(nameof(maxDelay), maxDelay, $"{nameof(maxDelay)} < {nameof(minDelay)}");
}

int randomMax = Math.Max((int)(maxDelay.Value - minDelay.Value).TotalMilliseconds, 1);
foreach (char c in @string)
{
TimeSpan delayTimeSpan = TimeSpan.FromMilliseconds(Random.Shared.Next(randomMax)) + minDelay.Value;
delay(delayTimeSpan);
Console.Write(c);
}
}
I realize this may be look a little complicated but I can strip it down for you that is a helper method that will print the output with small random delays
Hazel πŸŒŠπŸ’ƒ
Hazel πŸŒŠπŸ’ƒβ€’14mo ago
O_O way above what I was going to do lol Impressive πŸ˜„
ZacharyPatten
ZacharyPattenβ€’14mo ago
you could call it like
ConsoleHelpers.WriteWithRandomDelays("Hello World! Hello World! Hello World! Hello World!");
Console.WriteLine();
Console.Write("Press Enter To Continue...");
Console.ReadLine();
ConsoleHelpers.WriteWithRandomDelays("Hello World! Hello World! Hello World! Hello World!");
Console.WriteLine();
Console.Write("Press Enter To Continue...");
Console.ReadLine();
and it would slowly print "Hello World! Hello World! Hello World! Hello World!"
Hazel πŸŒŠπŸ’ƒ
Hazel πŸŒŠπŸ’ƒβ€’14mo ago
private static void PrintWithDelay(string input, TimeSpan delay)
{
if (string.IsNullOrWhiteSpace(input))
return;

foreach (char character in input)
{
Thread.Sleep(delay);
Console.Write(character);
}
}

...
PrintWithDelay("This is an example", TimeSpan.FromMillisconds(50));
private static void PrintWithDelay(string input, TimeSpan delay)
{
if (string.IsNullOrWhiteSpace(input))
return;

foreach (char character in input)
{
Thread.Sleep(delay);
Console.Write(character);
}
}

...
PrintWithDelay("This is an example", TimeSpan.FromMillisconds(50));
I like ZP's version better because it's probably much closer to what you truly want visually, but perhaps this simplified snippet will help you better understand what their snippet is doing.
ZacharyPatten
ZacharyPattenβ€’14mo ago
here is a simplified version of the same method:
public static void WriteWithRandomDelays(string @string)
{
if (@string is null)
{
throw new ArgumentNullException(nameof(@string));
}

TimeSpan minDelay = TimeSpan.FromMilliseconds(50);
TimeSpan maxDelay = minDelay + TimeSpan.FromMilliseconds(350);
int randomMax = Math.Max((int)(maxDelay - minDelay).TotalMilliseconds, 1);
foreach (char c in @string)
{
TimeSpan delayTimeSpan = TimeSpan.FromMilliseconds(Random.Shared.Next(randomMax)) + minDelay;
Thread.Sleep(delayTimeSpan);
Console.Write(c);
}
}
public static void WriteWithRandomDelays(string @string)
{
if (@string is null)
{
throw new ArgumentNullException(nameof(@string));
}

TimeSpan minDelay = TimeSpan.FromMilliseconds(50);
TimeSpan maxDelay = minDelay + TimeSpan.FromMilliseconds(350);
int randomMax = Math.Max((int)(maxDelay - minDelay).TotalMilliseconds, 1);
foreach (char c in @string)
{
TimeSpan delayTimeSpan = TimeSpan.FromMilliseconds(Random.Shared.Next(randomMax)) + minDelay;
Thread.Sleep(delayTimeSpan);
Console.Write(c);
}
}
just without the extra optional parameters and withotu the extra parameters you don't need the extra exception handling adding a little bit of randomness to it goes a long ways imo
Noah Here
Noah HereOPβ€’14mo ago
Ok, I’m had to step away from my computer but I will try it out when I get back thanks So will I have to do this individually for each new line I write?
Hazel πŸŒŠπŸ’ƒ
Hazel πŸŒŠπŸ’ƒβ€’14mo ago
No; you call it for each line I may have misunderstood your question tacolost
Noah Here
Noah HereOPβ€’14mo ago
No worries I explained it bad, just a simple text adventure game. A bunch of if statement for multiple options of paths in the game, simple do this or do that, then based on the option I want it to write out the story quickly, a speed just fast enough so you can’t catch up while reading, instead instantly displaying it the second you hit enter to continue the story
ZacharyPatten
ZacharyPattenβ€’14mo ago
so you need help with menuing? if you can share your current code that would help
Noah Here
Noah HereOPβ€’14mo ago
Currently I cannot but I can in a couple hour, we can continue then if you’d prefer
ZacharyPatten
ZacharyPattenβ€’14mo ago
using System;

while (true)
{
Console.Clear();
Console.WriteLine("""
My Game :)

Menu

1: Option A
2: Option B
3: Exit
""");
Console.CursorVisible = false;
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.D1 or ConsoleKey.NumPad1: OptionA(); break;
case ConsoleKey.D2 or ConsoleKey.NumPad2: OptionB(); break;
case ConsoleKey.D3: return;
}
}

void OptionA()
{
while (true)
{
Console.Clear();
Console.WriteLine("""
My Game :)

You chose Option A.

1: return to main menu
""");
Console.CursorVisible = false;
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.D1 or ConsoleKey.NumPad1: return;
}
}
}

void OptionB()
{
while (true)
{
Console.Clear();
Console.WriteLine("""
My Game :)

You chose Option B.

1: return to main menu
""");
Console.CursorVisible = false;
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.D1 or ConsoleKey.NumPad1: return;
}
}
}
using System;

while (true)
{
Console.Clear();
Console.WriteLine("""
My Game :)

Menu

1: Option A
2: Option B
3: Exit
""");
Console.CursorVisible = false;
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.D1 or ConsoleKey.NumPad1: OptionA(); break;
case ConsoleKey.D2 or ConsoleKey.NumPad2: OptionB(); break;
case ConsoleKey.D3: return;
}
}

void OptionA()
{
while (true)
{
Console.Clear();
Console.WriteLine("""
My Game :)

You chose Option A.

1: return to main menu
""");
Console.CursorVisible = false;
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.D1 or ConsoleKey.NumPad1: return;
}
}
}

void OptionB()
{
while (true)
{
Console.Clear();
Console.WriteLine("""
My Game :)

You chose Option B.

1: return to main menu
""");
Console.CursorVisible = false;
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.D1 or ConsoleKey.NumPad1: return;
}
}
}
there is another example if that helps at all. based on your last comment you sounded like you were struggling switching between views there are multiple ways to do it in the code above it will start at the main menu. the user has to press either 1, 2, or 3 and when they do it will transition to another "view" based on what they pick
Noah Here
Noah HereOPβ€’14mo ago
Mines way more basic, it like β€œconsole.writeline”story” String optionOne = console.read key If optionOne == (one of the option) { (More Story then another if option and on and on) } Else if (other option) { More story on and on }
ZacharyPatten
ZacharyPattenβ€’14mo ago
that's okay, but you will likely need some loops. you don't want your game to break the second the user provides invalid input and spliting your code up into methods can help keep it clean
Noah Here
Noah HereOPβ€’14mo ago
How do I split it up to methods and make loops? Sorry if I’m asking for too much, you don’t need to help with the whole game
ZacharyPatten
ZacharyPattenβ€’14mo ago
this (reply) example alreay splits things up into methods and includes loops for exmaple, if you are on the main menu and you press "4", the game will not crash it won't do anything it will loop until the user provides valid input
Noah Here
Noah HereOPβ€’14mo ago
Ah
ZacharyPatten
ZacharyPattenβ€’14mo ago
the user must press either 1, 2, or 3 the loop is the
while (true)
{
...
}
while (true)
{
...
}
while (true) is an "infinite loop" so it will go on forever. In general you don't want to code infinite loops if possible, but for console games like this, it is fine return; exits the current method
Noah Here
Noah HereOPβ€’14mo ago
Alright
ZacharyPatten
ZacharyPattenβ€’14mo ago
so even though there is a while (true), when the user presses 3 while in the main menu, the return will break out of the current method and end your code Side Note: If you are interested in making console games there are lots of examples on GitHub. If you would like a link to some just ask.
Noah Here
Noah HereOPβ€’14mo ago
Sure, would Definitly like some reference
ZacharyPatten
ZacharyPattenβ€’14mo ago
https://github.com/dotnet/dotnet-console-games here are some examples. and you can play most of them in your browser so you don't even have to download and compile them. but they are all open source so you can see how they are coded
Noah Here
Noah HereOPβ€’14mo ago
Awesome thanks a lot!
Accord
Accordβ€’14mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server