Typewriter GUI

Started by frission, Tue 09/10/2007 18:34:34

Previous topic - Next topic

frission

I'm trying to make it so that whenever my character enters a new scene, overlayed upon the screen will be some sort of line (e.g. "Somewhere in L.A.") that will by typed out character by character and then fade away. Ideally this would not be totally blocking (sometimes I will want people to be walking across the screen as it is typing, for example).

I searched for Typewriting on the forums but all the other examples were in an earlier version of the language, I believe, and most were blocking, and from what I could tell none of them could be faded out.

At the moment I have started putting it together in the following fashion. I know that Wait() is not an ideal function here and I will eventually replace it with timers (one step at a time here!).

Code: ags

function typeText(String TextToType) {
	gTypewriter.Y = 100;
	gTypewriterText.Text = " ";
	gTypewriter.Transparency = 0;
	gTypewriter.Visible = true;	
	int i = TextToType.Length-1;
	int x = 0;
	while(x<i) {
		x++;
		gTypewriterText.Text = String.Format("%s%s",gTypewriterText.Text,TextToType.Chars[x]);
		Wait(1);
	}	
	int trans = gTypewriter.Transparency;
	while (trans < 100) {
		trans++;
		gTypewriter.Transparency = trans;
		Wait(1);
	gTypewriter.Visible = false;
	}
}


Where gTypewriter is a GUI with no background color or border, and gTypewriterText is a label on that GUI.

Now the above looks to me like it ought to work in some fashion, and compiles fine, but unfortunately I just get an awful, awful error message when I try to run it.

Quote
---------------------------
Illegal exception
---------------------------
An exception 0xC0000005 occured in ACWIN.EXE at EIP = 0x0047AA75 ; program pointer is +6, ACI version 2.72.920, gtags (5,0)

AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and notify CJ on the Tech forum.

in Room 1 script (line 81)
from Room 1 script (line 98)


Most versions of Windows allow you to press Ctrl+C now to copy this entire message to the clipboard for easy reporting.
---------------------------
OK   
---------------------------

Line 81 in the room script is the one with the String.Format on it. I'm only using that String.Format because I'm having trouble concactenating the text otherwise (it doesn't like me mixing string and char types, apparently).

Any thoughts/suggestions?

SSH

Quote from: frission on Tue 09/10/2007 18:34:34
String.Format("%s%s",gTypewriterText.Text,TextToType.Chars
  • );
You want "%s%c" instead...
12

frission

Quote from: SSH on Tue 09/10/2007 18:39:21
Quote from: frission on Tue 09/10/2007 18:34:34
String.Format("%s%s",gTypewriterText.Text,TextToType.Chars
  • );
You want "%s%c" instead...

Ah, I see. I keep getting confused with the char type; I thought %c gave you the ASCII code for it and Chars gave you the string, but I've got it all backwards. Thanks. (It doesn't quite work yet, despite that, but it's not crashing anyway!)

frission

Just for the curious, here's the working version. With the Wait()s, it is super annoying (you can't do a thing until it finishes), but I'll work those out with Timer functions eventually...

Code: ags

function typeText(String TextToType) {
	gTypewriter.Y = 160;
	gTypewriterText.Text = " ";
	gTypewriter.Visible = true;	
	int i = TextToType.Length-1;
	int x = -1;
	Wait(10);
	while(x<i) {
		x++;
		gTypewriterText.Text = String.Format("%s%c",gTypewriterText.Text,TextToType.Chars[x]);
		Wait(8);
	}	
	Wait(10);
	int trans = gTypewriter.Transparency;
	while (trans < 100) {
		trans++;
		trans++;
		gTypewriter.Transparency = trans;
		Wait(1);
	}
	gTypewriter.Visible = false;
}

monkey0506

%c will produce the "printable" version of the character if one exists. If it cannot be printed in the current font the game will crash.

%d would produce the ASCII code if given a char variable or single-quoted character such as 'A' (which would yield the result "65").

And here I go being needlessly excessive again.

Code: ags
struct TypewriterBase {
  writeprotected Label* LabelToUse;
  writeprotected String Text;
  writeprotected String ShownText;
  int CharacterDelay;
  int PreFadeDelay;
  int FadeDelay;
  int X;
  int Y;
  int Sound;
  import void SetLabel(Label* labelToUse);
  import void Type(String message, int x, int y, int characterDelay=1, int preFadeDelay=10, int fadeDelay=1, Label* labelToUse=0, int sound=-1);
  protected int Delay;
  protected bool DonePreFade;
  import void Update(); // $AUTOCOMPLETEIGNORE$
  import void Clear();
  };

TypewriterBase Typewriter;

void TypewriterBase::SetLabel(Label* labelToUse) {
  if (labelToUse == null) return;
  this.LabelToUse = labelToUse;
  }

void TypewriterBase::Clear() {
  if (this.LabelToUse != null) this.LabelToUse.OwningGUI.Visible = false;
  this.LabelToUse = null;
  this.Text = null;
  this.ShownText = null;
  this.CharacterDelay = 0;
  this.FadeDelay = 0;
  this.X = 0;
  this.Y = 0;
  this.Delay = 0;
  }

void TypewriterBase::Type(String message, int x, int y, int characterDelay, int preFadeDelay, int fadeDelay, Label* labelToUse, int sound) {
  if (labelToUse != null) {
    this.LabelToUse = labelToUse;
    labelToUse.OwningGUI.Visible = true;
    labelToUse.OwningGUI.Transparency = 0;
    }
  if ((message == null) || (message == "") || (this.LabelToUse == null)) return;
  if (x < 0) x = 0;
  int width = GetTextWidth(message, this.LabelToUse.Font);
  if ((x + width) > System.ViewportWidth) x = System.ViewportWidth - width;
  if (y < 0) y = 0;
  if ((y + GetTextHeight(message, this.LabelToUse.Font, width)) > System.ViewportHeight)
    y = System.ViewportHeight - GetTextHeight(message, this.LabelToUse.Font, width);
  this.CharacterDelay = characterDelay;
  if (preFadeDelay < 0) preFadeDelay = 0;
  this.PreFadeDelay = preFadeDelay;
  this.FadeDelay = fadeDelay;
  this.Text = message;
  this.ShownText = "";
  this.X = x;
  this.Y = y;
  this.Delay = characterDelay;
  if (this.Delay < 0) this.Delay = -this.Delay;
  this.Sound = sound;
  }

void TypewriterBase::Update() {
  if (this.Text == null) return;
  if (this.ShownText != this.Text) {
    if (this.Delay) this.Delay--;
    else {
      int z = this.ShownText.Length;
      if (this.CharacterDelay >= 0) this.ShownText = this.Text.Substring(0, this.ShownText.Length);
      else this.ShownText = this.Text.Substring(0, this.ShownText.Length - this.CharacterDelay);
      while ((z < this.ShownText.Length) && (this.Sound >= 0)) {
        PlaySound(this.Sound);
        z++;
        }
      if (this.ShownText != this.Text) this.Delay = this.CharacterDelay;
      else this.Delay = this.PreFadeDelay;
      this.LabelToUse.Text = this.ShownText;
      }
    }
  else if (!this.DonePreFade) {
    this.Delay--;
    if (!this.Delay) {
      this.DonePreFade = true;
      this.Delay = this.FadeDelay;
      if (this.Delay < 0) this.Delay = -this.Delay;
      }
    }
  else {
    if (this.Delay) this.Delay--;
    else {
      if (this.FadeDelay >= 0) this.LabelToUse.OwningGUI.Transparency = (this.LabelToUse.OwningGUI.Transparency - 1);
      else this.LabelToUse.OwningGUI.Transparency = (this.LabelToUse.OwningGUI.Transparency + this.FadeDelay);
      if (this.LabelToUse.OwningGUI.Transparency) this.Delay = this.FadeDelay;
      else this.Clear();
      if (this.Delay < 0) this.Delay = -this.Delay;
      }
    }
  if (this.X < 0) this.X = 0;
  int width = GetTextWidth(this.Text, this.LabelToUse.Font);
  if ((this.X + width) > System.ViewportWidth) this.X = System.ViewportWidth - width;
  if (this.Y < 0) this.Y = 0;
  if ((this.Y + GetTextHeight(this.Text, this.LabelToUse.Font, width)) > System.ViewportHeight)
    this.Y = System.ViewportHeight - GetTextHeight(this.Text, this.LabelToUse.Font, width);
  this.LabelToUse.OwningGUI.X = this.X;
  this.LabelToUse.OwningGUI.Y = this.Y;
  if (this.LabelToUse.OwningGUI.Transparency == 100) this.Clear();
  }

function repeatedly_execute() {
  Typewriter.Update();
  }


This is really rather absurd. You don't need something this complex. Really I think it's great you're working it out on your own. So why then did I type all this out? Boredom. := Hopefully you'll be able to gather something from it...though I'm not sure what. ;D

SMF spam blocked by CleanTalk