Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - TypewriterTextLover

#1
If you ever update the demo, I think the caret code could be a bit better perhaps. It seems to not work if you use transparent backgrounds like say if you use COLOR_TRANSPARENT, it shows every tick of the caret sprite moving. This forced me to use a single color for the paper instead of a very worn looking detailed paper than I initally planned. I also had to use a smaller caret than I would have liked since the caret in the demo seems to be lower than the text and not evenly centered with the font height. I just altered my sprite a bit to make it center with extra spaces, but that just eats up pixel space I could have used to make the sprite more detailed. I tried messing around with the caret code with no luck.

Just nitpicks though. 700,000 views !!!!  8-)

I also added a FirstPage function that basically replaces the initial ttdraw.

So now if you want to type first page you do FirstPage("text string")
If you want more pages then you use AddPage("text string").

Thank you for everything!
#2
Thank you Crimson Wizard! Everything we talked about finally clicked! I have learned a lot and understand modules, importing, where to put variables, simplying code, and I even wrote my own functions today and..... THEY WORKED!!! All of the typewriter text is working perfectly with zero hangups and even controlled completely through mouse clicks that wait on user input in and... IT'S IN IT'S OWN MODULE! THANK YOU!!!!!!!!  (laugh)  (laugh)  (laugh)

#3
I'm having some issues getting the typewriter to work in the global script. I'm not sure what to put in the header and not sure the correct nomenclature for importing functions.
This is what I added to the global header:
Code: ags
import void StartTypewriter();
import function AddPage(String text);
import function ClearPages();
import void PaperLinesShow();
import void PaperLinesHide();

#ifndef SCRIPT_API_v350
  #define eAlignCenter eAlignCentre
#endif

#define MAX_PAGES 100

String PageStrings[MAX_PAGES];
int TotalPages = 0; // remember how many pages scheduled
int CurrentPage = -1; // remember which is the current page

TypedTextDrawing ttdraw;
DynamicSprite *papersprite;
int paper_original_pos;

The typewriter currently shows the first page as being blank. No typewriting sounds. If I click the paper, it will type out the second page.
I'm also not sure what the point of int paper_original_pos and gGuiPaper.Y = paper_original_pos; If I use this line of code it makes my GUI paper appear super high up on the screen. So I put // in front of it.

I think maybe I've written the import Start Typewriter portion wrong.

Thank you for your time Crimson. I'm struggling over here!!  (laugh)  (laugh)  (laugh)
#4
Crimson Wizard,

I took the Wait(60); out of the demo and it does fix the hanging problem with the text in the demo. It still hangs in my game but only on the last page of text when you try to skip even when I take the Wait(60); out. My code has gotten rather complicated because of one issue:

The typewriter can not seem to interact with inventory items since they are called from the global script and not the room script. To get around this I have have two typewriters going now. One in the room script and one in the global script. I think they are conflicting with each other and causing the hanging problem still. I have looked up importing and exporting to try to call the inventory items from the room script with no luck. Basically what I'm trying to do is if I look at a inventory item, the typewriter will type out a description.

I also have no idea how to get the pages to stop and wait for a mouse click before displaying. I'm going to look into it further and try to mess around with timers although I'd rather have a mouse click to skip text and then wait for user mouse click input again to go to next page.

I'm also using the TUMBLEWEED template which uses a lot of repeatedly executable code which maybe is causing a conflict as well maybe.

I am making a game where it has one central area where all the text is displayed when you look, pickup, etc. All of the text is typewritten like a MacVenture style game.

I appreciate all of your help!
#5
Hey Crimson Wizard! I'm back with another question!  :grin:

I've noticed a potential weird bug with ttdraw.Skip();

If more than ~ 50% of the text has already been typed, and then you try to skip it, the typewriter will just pause and hang instead of displaying the rest of the intended message.

I've looked over the code for ttdraw.Skip which is:

Code: ags
void TypedText::Skip()
{
  this._cur = this._full;
  this._justTyped = false;
  this._hasChanged = true;

Not sure what I could change to fix this problem. Maybe this has something to do with how it calculates split text? Any ideas? Thank you.

Crimson Wizard,

Thank you for the quick reply. Replace the room code with this code to replicate the error. It doesn't happen every time but when the text comes up that says "Best Module of all time! 700,000 Views Baby!!!"
If you try to skip by clicking on the paper between the word "all" and "time" it should hang. It sometimes hangs if you click on the paper right after it types "Crimson" on the first sentence.

Code: ags
// room script file
// Compatibility macros

#ifndef SCRIPT_API_v350
  #define eAlignCenter eAlignCentre
#endif

#define MAX_PAGES 100

String PageStrings[MAX_PAGES];
int TotalPages = 0; // remember how many pages scheduled
int CurrentPage = -1; // remember which is the current page

TypedTextDrawing ttdraw;
DynamicSprite *papersprite;
int paper_original_pos;

function ClearPages()
{
    TotalPages = 0;
    CurrentPage = -1;
}

function AddPage(String text)
{
    if (TotalPages == MAX_PAGES)
        return; // no more place to store pages
    PageStrings[TotalPages] = text;
    TotalPages++;
}

function StartTypeNextPage()
{   if (CurrentPage < TotalPages - 1) // has more pages to display?
    {
        CurrentPage++;
        ttdraw.Start(PageStrings[CurrentPage]);
    }
}

void ClearTypewriter()
{
  if (papersprite != null)
    papersprite.Delete();
  papersprite = null;
  ttdraw.Clear();
  oPaper.Y = paper_original_pos;
}

void StartTypewriter()
{
  ClearTypewriter();
  SayCustom("Launch the big typewriter!");
  
  papersprite = DynamicSprite.CreateFromExistingSprite(28);
  oPaper.Graphic = papersprite.Graphic;
  
  //Display("paper size = %d x %d", papersprite.Width, papersprite.Height);
  ttdraw.X = 4;
  ttdraw.Y = 4;
  ttdraw.Width = papersprite.Width - 8;
  ttdraw.Height = papersprite.Height - 8;
  ttdraw.Font = eFontFont3;
  ttdraw.BkgColor = Game.GetColorFromRGB(255, 255, 255);
  ttdraw.TextColor = Game.GetColorFromRGB(66, 44, 123);
  ttdraw.TextAlign = eAlignCenter;
  ttdraw.CaretSprite = 29;
  ttdraw.TypeDelayMin = 4;
  ttdraw.TypeDelayMax = 7;
  ttdraw.TypeDelayStyle = eTypedDelay_Mixed;
  ttdraw.CaretFlashOnTime = 9;
  ttdraw.CaretFlashOffTime = 9;
  ttdraw.CaretStyle = eTypedCaret_Explicit;
  ttdraw.TextReadTime = 3;
  
  AudioClip *type_clips[] = new AudioClip[3];
  type_clips[0] = aType;
  type_clips[1] = aType2;
  type_clips[2] = aType3;
  ttdraw.SetRandomTypeSounds(type_clips, 3);
  ttdraw.CaretSound = aCaret;
  
  ttdraw.Start("Thank you Crimson Wizard [ !!!!!!!!!!!");
  AddPage("You are the bestest!!!! THANK YOU!!!!!!!!!!");
  AddPage("Best Module of all time! 700,000 Views Baby!!!");
}

void UpdateTypewriter()
{
  if (ttdraw.IsActive && !ttdraw.IsIdle)
  {
    ttdraw.Tick();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ttdraw.Draw(ds);
    ds.Release();
    //oPaper.Y = paper_original_pos - ttdraw.LinesDisplayed * (ttdraw.LineHeight + ttdraw.LineSpacing);
    oPaper.Graphic = papersprite.Graphic;
    Label1.Text = String.Format("ttdraw active: %d, idle %d, wait %d", ttdraw.IsActive, ttdraw.IsIdle, ttdraw.IsWaitingForReader);
  }
  if (ttdraw.IsActive && ttdraw.IsIdle)
  {
    Wait(60);
    ttdraw.Clear();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ds.Clear(65535);
    ds.Release();
    oPaper.Graphic = papersprite.Graphic;
     
    StartTypeNextPage();
  }
}

function room_Load()
{
  paper_original_pos = oPaper.Y;
  cGuybrush.ManualScaling = true;
  cGuybrush.Scaling = 200;
  cGuybrush.FaceLocation(cGuybrush.x + 100, cGuybrush.y, eNoBlock);
}

function oTypewriter_AnyClick()
{
    StartTypewriter();
}

function oPaper_AnyClick()
{
  if (ttdraw.IsActive && !ttdraw.IsIdle)
  {
    ttdraw.Skip();
    //oPaper.Y = paper_original_pos - ttdraw.LinesDisplayed * (ttdraw.LineHeight + ttdraw.LineSpacing);
  }
}

function room_RepExec()
{
  UpdateTypewriter();
}



#6
IT WORKS!! I added some Waits and and a little bit of TextReaderType to make it work buttery smooth. Clicking on the typewriter now starts it. Clicking on the page will skip to the next page. This demo can print out books now!!! :)

Check it out here is the code for all that need it!!!

Code: ags
// room script file
// Compatibility macros

#ifndef SCRIPT_API_v350
  #define eAlignCenter eAlignCentre
#endif

#define MAX_PAGES 100

String PageStrings[MAX_PAGES];
int TotalPages = 0; // remember how many pages scheduled
int CurrentPage = -1; // remember which is the current page

TypedTextDrawing ttdraw;
DynamicSprite *papersprite;
int paper_original_pos;

function ClearPages()
{
    TotalPages = 0;
    CurrentPage = -1;
}

function AddPage(String text)
{
    if (TotalPages == MAX_PAGES)
        return; // no more place to store pages
    PageStrings[TotalPages] = text;
    TotalPages++;
}

function StartTypeNextPage()
{   if (CurrentPage < TotalPages - 1) // has more pages to display?
    {
        CurrentPage++;
        ttdraw.Start(PageStrings[CurrentPage]);
    }
}

void ClearTypewriter()
{
  if (papersprite != null)
    papersprite.Delete();
  papersprite = null;
  ttdraw.Clear();
  oPaper.Y = paper_original_pos;
}

void StartTypewriter()
{
  ClearTypewriter();
  SayCustom("Launch the big typewriter!");
  
  papersprite = DynamicSprite.CreateFromExistingSprite(28);
  oPaper.Graphic = papersprite.Graphic;
  
  //Display("paper size = %d x %d", papersprite.Width, papersprite.Height);
  ttdraw.X = 4;
  ttdraw.Y = 4;
  ttdraw.Width = papersprite.Width - 8;
  ttdraw.Height = papersprite.Height - 8;
  ttdraw.Font = eFontFont3;
  ttdraw.BkgColor = Game.GetColorFromRGB(255, 255, 255);
  ttdraw.TextColor = Game.GetColorFromRGB(66, 44, 123);
  ttdraw.TextAlign = eAlignCenter;
  ttdraw.CaretSprite = 29;
  ttdraw.TypeDelayMin = 4;
  ttdraw.TypeDelayMax = 7;
  ttdraw.TypeDelayStyle = eTypedDelay_Mixed;
  ttdraw.CaretFlashOnTime = 9;
  ttdraw.CaretFlashOffTime = 9;
  ttdraw.CaretStyle = eTypedCaret_Explicit;
  ttdraw.TextReadTime = 3;
  
  AudioClip *type_clips[] = new AudioClip[3];
  type_clips[0] = aType;
  type_clips[1] = aType2;
  type_clips[2] = aType3;
  ttdraw.SetRandomTypeSounds(type_clips, 3);
  ttdraw.CaretSound = aCaret;
  
  ttdraw.Start("Thank you Crimson Wizard [ !!!!!!!!!!!");
  AddPage("You are the bestest!!!! THANK YOU!!!!!!!!!!");
  AddPage("Best Module of all time! 700,000 Views Baby!!!");
}

void UpdateTypewriter()
{
  if (ttdraw.IsActive && !ttdraw.IsIdle)
  {
    ttdraw.Tick();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ttdraw.Draw(ds);
    ds.Release();
    //oPaper.Y = paper_original_pos - ttdraw.LinesDisplayed * (ttdraw.LineHeight + ttdraw.LineSpacing);
    oPaper.Graphic = papersprite.Graphic;
    Label1.Text = String.Format("ttdraw active: %d, idle %d, wait %d", ttdraw.IsActive, ttdraw.IsIdle, ttdraw.IsWaitingForReader);
  }
  if (ttdraw.IsActive && ttdraw.IsIdle)
  {
    Wait(60);
    ttdraw.Clear();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ds.Clear(65535);
    ds.Release();
    oPaper.Graphic = papersprite.Graphic;
     
    StartTypeNextPage();
  }
}

function room_Load()
{
  paper_original_pos = oPaper.Y;
  cGuybrush.ManualScaling = true;
  cGuybrush.Scaling = 200;
  cGuybrush.FaceLocation(cGuybrush.x + 100, cGuybrush.y, eNoBlock);
}

function oTypewriter_AnyClick()
{
    StartTypewriter();
}

function oPaper_AnyClick()
{
  if (ttdraw.IsActive && !ttdraw.IsIdle)
  {
    ttdraw.Skip();
    //oPaper.Y = paper_original_pos - ttdraw.LinesDisplayed * (ttdraw.LineHeight + ttdraw.LineSpacing);
  }
}

function room_RepExec()
{
  UpdateTypewriter();
}



I truly appreciate your help Crimson Wizard!

"Thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you, thank you."

-Kielbasa, thanking the DS-86 crew
#7
I was able to get the page to clear by changing the void UpdateTypewriter() by using your code:

Code: ags
void UpdateTypewriter()
{
  if (ttdraw.IsActive && !ttdraw.IsIdle)
  {
    ttdraw.Tick();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ttdraw.Draw(ds);
    ds.Release();
    //oPaper.Y = paper_original_pos - ttdraw.LinesDisplayed * (ttdraw.LineHeight + ttdraw.LineSpacing);
    oPaper.Graphic = papersprite.Graphic;
    Label1.Text = String.Format("ttdraw active: %d, idle %d, wait %d", ttdraw.IsActive, ttdraw.IsIdle, ttdraw.IsWaitingForReader);
  }
  if (ttdraw.IsActive && ttdraw.IsIdle)
  {
    ttdraw.Tick();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ds.Clear(65535);
    ds.Release();
    oPaper.Graphic = papersprite.Graphic;
  }
}

However now I want to be able to display two strings back to back, so it looks like two different pages of text are being typed. I tried using this code, but it just ignores the first string and prints only the second:

Code: ags

  void StartTypewriter()
{
  ClearTypewriter();
  SayCustom("Launch the big typewriter!");
  
  papersprite = DynamicSprite.CreateFromExistingSprite(28);
  oPaper.Graphic = papersprite.Graphic;
  
  //Display("paper size = %d x %d", papersprite.Width, papersprite.Height);
  ttdraw.X = 4;
  ttdraw.Y = 4;
  ttdraw.Width = papersprite.Width - 8;
  ttdraw.Height = papersprite.Height - 8;
  ttdraw.Font = eFontFont3;
  ttdraw.BkgColor = Game.GetColorFromRGB(255, 255, 255);
  ttdraw.TextColor = Game.GetColorFromRGB(66, 44, 123);
  ttdraw.TextAlign = eAlignCenter;
  ttdraw.CaretSprite = 29;
  ttdraw.TypeDelayMin = 4;
  ttdraw.TypeDelayMax = 7;
  ttdraw.TypeDelayStyle = eTypedDelay_Mixed;
  ttdraw.CaretFlashOnTime = 9;
  ttdraw.CaretFlashOffTime = 9;
  ttdraw.CaretStyle = eTypedCaret_Explicit;
  
  AudioClip *type_clips[] = new AudioClip[3];
  type_clips[0] = aType;
  type_clips[1] = aType2;
  type_clips[2] = aType3;
  ttdraw.SetRandomTypeSounds(type_clips, 3);
  ttdraw.CaretSound = aCaret;
  
  String big_string = "The TypedTextDrawing prints TypedText on the provided DrawingSurface. Therefore";
  String big_string2 = "Furthermore, you may assign sprite number to CaretSprite property, and it will be used to draw caret position.";
  
  ttdraw.Start(big_string);
  ttdraw.Start(big_string2);
}


I tried looking at string arrays and looked over footlines and guybrushlines but I can't figure it out. :(
#8
I used your line of code and it does indeed idle!!! I still can't get it clear the page by using it's idle status.

I have changed the void UpdateTypewriter() line to reflect if the typewriter is idle or !idle since it's only inactive once before use which isn't really helpful.
It also never enters a "wait for reader" status, although I'm not sure if that is an issue or not.

Here is what I changed it to, although it doesn't work:

Code: ags
void UpdateTypewriter()
{
  if (!ttdraw.IsIdle)
  {
    ttdraw.Tick();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ttdraw.Draw(ds);
    ds.Release();
    //oPaper.Y = paper_original_pos - ttdraw.LinesDisplayed * (ttdraw.LineHeight + ttdraw.LineSpacing);
    oPaper.Graphic = papersprite.Graphic;
    Label1.Text = String.Format("ttdraw active: %d, idle %d, wait %d", ttdraw.IsActive, ttdraw.IsIdle, ttdraw.IsWaitingForReader);
  }
  
  else
  {
    ttdraw.Clear();
  }
}

Doesn't seem like ttdraw.Clear isn't doing what it needs to do here? I've tried a couple of different things, but I'm stumped! This is the code for ttdraw.Clear but I can't seem to figure out if it maybe needs changing?

Code: ags
//===========================================================================
//
// TypedTextDrawing::Clear
//
//===========================================================================
void TypedTextDrawing::Clear()
{
  this._RenderClear();
  this._lineCount = 0;
}

I appreciate your time and help!
#9
Thanks Crimson Wizard for the quick response and thank you for creating such a great module! This module has over 700,000 views which shows you how desired this feature is to people! The # 1 most viewed module!

Is there any way to get the typewriter to be in a "Waiting for user" or "IsIdle" state? I have used Display commands to see if it ever goes in a Idle status and it does not. If the typewriter would idle, i could simply say if typewriter idle, then clear, and start typing new string.

Another possible method maybe uses the "[" character. Is there way to say "if typewriter typed "[", then clear typewriter, and type new string? I believe there is a ttdraw.LastChar parameter that maybe useful?

#10
Hello! I am complete noob and this is my first post! I have been messing around with the TypedText1.00 demo and module for a few days and struggling to figure out a few things.

I have been able to successfully get words to type on a object (dynamic sprite that looks like a piece of paper) just like in the demo. However the typewriter always seems "active" and ttdraw is never in a "waiting for reader" or "idle" stage. I can't figure out how to get it to stop! I understand it's being repeatedly executed to create the typing effect with ttdraw.tick.

I have tried using ClearTypewriter (usually get error messages with this since it deletes the sprite), ttdraw.Clear (which does clear the text but doesn't allow time for the ttdraw.Start(String) to finish. I have tried using timers to get around this with no success. I have also tried messing with ttdraw.TextReadTime which doesn't seem to have any effect.

I basically want to :

- Look at an hotspot or object.
- Typewriter starts typing word description on paper.
- If the words are too many for the text box: stop, let user click when done reading, user clicks, text clears, and typewriter continues writing from top.
- Click on paper to skip to the next text section.

I am sticking with TypedTextDrawing since it's the only feature that supports caret sprites. I have it working near perfectly, but just need to figure out this one final part. Any help is greatly appreciated!!! Here is my code. This code does not produce any errors, but doesn't do what I want either :) It's mostly the same from the demo. I have tried incorporating some of the PhylactereTypewriter code (since I believe it also uses dynamic sprites) which maybe has the solution to the problem there, but I couldn't figure it out. I think getting the typewriter to idle is the first step.

Code: ags
// room script file

// Compatibility macros
#ifndef SCRIPT_API_v350
  #define eAlignCenter eAlignCentre
#endif

TypedTextDrawing ttdraw;
DynamicSprite *papersprite;
int paper_original_pos;

void ClearTypewriter()
{
if (papersprite != null)
   papersprite.Delete();
  papersprite = null;
  ttdraw.Clear();
  oPaper.Y = paper_original_pos;
 }

void StartTypewriter()
{ oPaper.Visible=true;
 ClearTypewriter();
  
  papersprite = DynamicSprite.CreateFromExistingSprite(369);
  oPaper.Graphic = papersprite.Graphic;
 
  ttdraw.X = 2;
  ttdraw.Y = 4;
  ttdraw.LineSpacing = 5;
  ttdraw.Width = papersprite.Width;
  ttdraw.Height = papersprite.Height;
  ttdraw.Font = eFontPressStart2P;
  ttdraw.BkgColor = Game.GetColorFromRGB(226,175,143);
  ttdraw.TextColor = Game.GetColorFromRGB(0, 0, 0);
  ttdraw.TextAlign = eAlignLeft;
  ttdraw.CaretSprite = 79;
  ttdraw.TypeDelayMin = 2;
  ttdraw.TypeDelayMax = 4;
  ttdraw.TypeDelayStyle = eTypedDelay_Mixed;
  ttdraw.CaretFlashOnTime = 9;
  ttdraw.CaretFlashOffTime = 9;
  ttdraw.CaretStyle = eTypedCaret_Explicit;
  
  AudioClip *type_clips[] = new AudioClip[3];
  type_clips[0] = aType;
  type_clips[1] = aType2;
  type_clips[2] = aType3;
  ttdraw.SetRandomTypeSounds(type_clips, 3);
  ttdraw.CaretSound = aCaret;
}

void UpdateTypewriter()
{
  if (ttdraw.IsActive)
  {
    ttdraw.Tick();
    DrawingSurface *ds = papersprite.GetDrawingSurface();
    ttdraw.Draw(ds);
    ds.Release();
    // oPaper.Y = paper_original_pos -  * (ttdraw.LineHeight + ttdraw.LineSpacing);
    oPaper.Graphic = papersprite.Graphic;
  }
  }

void PaperLines()
{
gGuiLine1.Visible=true;
gGuiLine2.Visible=true;
}

function room_Load()
{
  paper_original_pos = oPaper.Y;
  gGuiIntro.Visible=false;
  Verbs.HideGui();
  StartTypewriter();
  ttdraw.Start("Your sister's kids are here to celebrate your birthday!");
  aHaunted_House.Play();
}

function oPaper_AnyClick()
{
  if (ttdraw.IsActive && !ttdraw.IsIdle)
  {
    ttdraw.Skip();
    // oPaper.Y = paper_original_pos - ttdraw.LinesDisplayed * (ttdraw.LineHeight + ttdraw.LineSpacing);
  }
  else
  {
    oPaper.Visible=false;
      gGuiLine1.Visible=false;
    gGuiLine2.Visible=false;
    Verbs.ShowGui();
  }
}

function room_RepExec()
{
  UpdateTypewriter();
}

function hHotspotBabyEmmie_Look(Hotspot *theHotspot, CursorMode mode)
{
Verbs.HideGui();
  PaperLines();
  StartTypewriter();
ttdraw.Start("Look it's Baby Emmie! Awwww! How cute! Blah blah blah blah blah blah blah blah blah blah blah");
}



SMF spam blocked by CleanTalk