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):
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.
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:
Gamestate_Cycle()
--> called for loading new scene.FullTextBottom = LblTextBottom.Text
--> called to refresh variables for typewriter.TypeWriterEffectBottom()
--> called to perform typewriter effect.C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
C is an imperative procedural language supporting structured programming, lexical variable scope, and recursion, with a static type system. It was designed to be compiled to provide low-level access to memory and language constructs that map efficiently to machine instructions, all with minimal runtime support.
Full form of C is “COMPILE”. One thing which was missing in C language was further added to C++ that is 'the concept of CLASSES'.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
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 } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With