Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

279
Views
C# Manually stopping an asynchronous for-statement (typewriter effect)

I'm making a retro-style game with C# .NET-Framework, and for dialogue I'm using a for-statement, that prints my text letter by letter (like a typewriter-effect):

enter image description here

I'm working with different scenes, and I have a skip button (bottom right) that skips the current dialogue and passes to the next scene. My typewriter-effect automatically stops when all the text is displayed, but when I click on the skip button, it automatically skips to the next scene.

I would like it, when the typewriter is still active, and if I click on the skip button, that it first shows all the text, instead of skipping to the next scene.

So that it only skips to the next scene when all the text is displayed (automatically or manually).

This is the (working code) that I'm using for my typewriter method (+ variables):

    public string FullTextBottom;
    public string CurrentTextBottom = "";
    public bool IsActive;
    
    public async void TypeWriterEffectBottom()
    {
        if(this.BackgroundImage != null) // only runs on backgrounds that arent black
        {
            for(i=0; i < FullTextBottom.Length + 1; i++)
            {
                CurrentTextBottom = FullTextBottom.Substring(0, i); // updating current string with one extra letter
                LblTextBottom.Text = CurrentTextBottom; // "temporarily place string in text box"
                await Task.Delay(30); // wait for next update
                
                #region checks for IsActive // for debugging only!

                if(i < FullTextBottom.Length + 1)
                {
                    IsActive = true;
                    Debug1.Text = "IsActive = " + IsActive.ToString();
                }
                if(CurrentTextBottom.Length == FullTextBottom.Length)
                {
                    IsActive = false;
                    Debug1.Text = "IsActive = " + IsActive.ToString();
                }

                #endregion
            }
        }

    }

And this is the code that I want to get for my skip button (named Pb_FastForward):

    private void PbFastForward_Click(object sender, EventArgs e)
    {
        if( //typewriter is active)
        {
             //print all text into the textbox
        }
        
        else if( //all text is printed)
        {
             // skip to the next scene
        }
    }   

But I don't know how to formulate the 2nd part of code. I've tried many different approaches, like using counters that increase on a buttonclick (and using that to check in an if-statement), and many different types of if-statements to see if the typewriter is still active or not, but I haven't got anything to work yet.

Edit

This is the sequence in which different components need to be loaded (on button click), which is related to the way different variables are updated:

  1. Gamestate_Cycle() --> called for loading new scene.
  2. FullTextBottom = LblTextBottom.Text --> called to refresh variables for typewriter.
  3. TypeWriterEffectBottom() --> called to perform typewriter effect.
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

I adjusted your code a little bit to achieve your goal. I'm not sure it's the best way to do it, but it should work.

public async void TypeWriterEffectBottom()
{
    if(this.BackgroundImage == null)
    {
        return;
    }
    IsActive = true;
    for(i=0; i < FullTextBottom.Length && IsActive; i++)
    {
        CurrentTextBottom = FullTextBottom.Substring(0, i+1);
        LblTextBottom.Text = CurrentTextBottom;
        await Task.Delay(30);
        Debug1.Text = "IsActive = " + IsActive.ToString();
    }
    IsActive = false;
}

private void PbFastForward_Click(object sender, EventArgs e)
{
    if(IsActive)
    {
        LblTextBottom.Text = FullTextBottom;
        IsActive = false;
        return;
    }
    
    // IsActive == false means all text is printed
    // skip to the next scene
}

UPD: Just noticed that Hans Kesting has suggested pretty much exactly this in his comment.

over 4 years ago · Santiago Trujillo Report

0

Avoid async void. Otherwise you can get an Exception that will break your game and you will not able to catch it.

Then use as less global variables in async methods as possible.

I suggest CancellationTokenSource as thread-safe way to stop the Type Writer.

public async Task TypeWriterEffectBottom(string text, CancellationToken token)
{
    if (this.BackgroundImage != null)
    {
        Debug1.Text = "TypeWriter is active";
        StringBuilder sb = new StringBuilder(text.Length);
        try
        {
            foreach (char c in text)
            {
                LblTextBottom.Text = sb.Append(c).ToString();
                await Task.Delay(30, token);
            }
        }
        catch (OperationCanceledException)
        {
            LblTextBottom.Text = text;
        }
        Debug1.Text = "TypeWriter is finished";
    }
}

Define CTS. It's thread-safe, so it's ok to have it in global scope.

private CancellationTokenSource cts = null;

Call TypeWriter from async method to be able to await it.

// set button layout as "Skip text" here
using (cts = new CancellationTokenSource())
{
    await TypeWriterEffectBottom(yourString, cts.Token);
}
cts = null;
// set button layout as "Go to the next scene" here

And finally

private void PbFastForward_Click(object sender, EventArgs e)
{
    if (cts != null)
    {
        cts?.Cancel();
    }
    else
    {
        // go to the next scene
    }
}   
over 4 years ago · Santiago Trujillo Report

0

You write what skip / forward button does, so you control it. Just have a check if the length of written text is equal to text that supposed to be written and if yes move as usual if not just display the text in full have delay to be read and move on

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!