Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

193
Vistas
C# Detención manual de una declaración for asíncrona (efecto de máquina de escribir)

Estoy haciendo un juego de estilo retro con C# .NET-Framework , y para el diálogo estoy usando una instrucción for, que imprime mi texto letra por letra ( como un efecto de máquina de escribir ):

ingrese la descripción de la imagen aquí

Estoy trabajando con diferentes escenas y tengo un botón de salto ( abajo a la derecha ) que salta el diálogo actual y pasa a la siguiente escena. Mi efecto de máquina de escribir se detiene automáticamente cuando se muestra todo el texto, pero cuando hago clic en el botón de salto, salta automáticamente a la siguiente escena.

Me gustaría que, cuando la máquina de escribir todavía esté activa, y si hago clic en el botón de saltar, primero muestre todo el texto, en lugar de saltar a la siguiente escena.

Para que solo salte a la siguiente escena cuando se muestre todo el texto (automática o manualmente).

Este es el (código de trabajo) que estoy usando para mi método de máquina de escribir (+ 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 } } }

Y este es el código que quiero obtener para mi botón de salto (llamado 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 } }

Pero no sé cómo formular la segunda parte del código. Probé muchos enfoques diferentes, como usar contadores que aumentan al hacer clic en un botón (y usarlos para verificar una declaración if), y muchos tipos diferentes de declaraciones if para ver si la máquina de escribir todavía está activa o no, pero yo no tengo nada para trabajar todavía.

Editar

Esta es la secuencia en la que se deben cargar los diferentes componentes (al hacer clic en el botón), que está relacionada con la forma en que se actualizan las diferentes variables:

  1. Gamestate_Cycle() --> llamado para cargar una nueva escena.
  2. FullTextBottom = LblTextBottom.Text --> llamado para actualizar variables para máquina de escribir.
  3. TypeWriterEffectBottom() --> llamado para realizar el efecto de máquina de escribir.
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Evite async void . De lo contrario, puede obtener una Exception que romperá su juego y no podrá catch .

Luego use la menor cantidad posible de variables globales en métodos async .

Sugiero CancellationTokenSource como una forma segura de detener el 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"; } }

Defina STC. Es seguro para subprocesos, por lo que está bien tenerlo en el ámbito global.

 private CancellationTokenSource cts = null;

Llame a TypeWriter desde el método async para poder await .

 // 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

Y finalmente

 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 Denunciar

0

Ajusté un poco tu código para lograr tu objetivo. No estoy seguro de que sea la mejor manera de hacerlo, pero debería funcionar.

 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: Acabo de darme cuenta de que Hans Kesting ha sugerido casi exactamente esto en su comentario.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda