GUI and speech text placement issues when scripting dialog

Started by codinginquarantine, Sun 10/07/2022 03:03:08

Previous topic - Next topic

codinginquarantine

I'm attempting to implement a speech bubble for LucasArts style speech using a GUI called through some basic scripting. I'm using cCharacter.SayAt with the X and Y being script variables (textx and texty). Normally, it looks as such:



I have some else if statements below in case the bubble would go off screen in the corner:



However, for some reason I've been able to replicate an issue where if the character is in the far left of the screen screen it renders the text and the speech bubble GUI not quite right:



For the scripting involved: I'm using a handful of small functions in the global script to turn on and off the GUIs, in addition to placing the GUI in the correct location based on the character:

Code: ags

function FindCharLoc()
{
  Charx = player.x;
  Chary = player.y;
  
}

function FindSpeechLoc()
{
  Bubblex = (Charx - 25);
 // Bubblex = (Charx);
  Bubbley = (Chary - 525);
}

function FindTextLoc()
{
  Textx = (Bubblex + 25);
  Texty = (Bubbley + 150);
}


And this is the main speech bubble function (all the commenting out in the first if function are me troubleshooting the issue):

Code: ags

function SpeechGui()
{
FindCharLoc();
FindSpeechLoc();
FindTextLoc();


if (player.x < 350) {
 // Bubblex = Bubblex;
 // Bubbley = Bubbley;

 // FindTextLoc();
  Textx = (Bubblex-10);
  
 // Bubblex = (Charx-50);
  gSpeech.SetPosition(Bubblex, Bubbley);
  
  
  
  gSpeech.Visible=true;
}
else if ((player.x > 1100) && (player.y < 510)) {
  Bubblex = (Charx - 275);
  Bubbley = (Chary - 250);
  FindTextLoc();
  gSpeech4.SetPosition(Bubblex, Bubbley);
  gSpeech4.Visible=true;
}

else if (player.x > 1100){
  Bubblex = (Charx - 175);
  FindTextLoc();
  gSpeech2.SetPosition(Bubblex, Bubbley);
  gSpeech2.Visible=true;
}
else  if (player.y < 510) {
  Bubbley = (Chary - 250);
  Bubblex = (Charx + 50);
  FindTextLoc();
  gSpeech3.SetPosition(Bubblex, Bubbley);
  gSpeech3.Visible=true;
}

else {gSpeech.SetPosition(Bubblex, Bubbley);


//Display("Bubblex is %d", Bubblex);
gSpeech.Visible=true;
}
}



The first if statement was written in response to this issue in an attempt to resolve it. As best I can tell, the line
Code: ags

Textx = (Bubblex-10);

has some control over it, since if I change that to, say Bubblex-50 the text shifts further to the left. But trying to give it a positive value (or even just setting it to =(Bubblex)) renders the speech like this:



It's like there's something else impacting that but I cannot figure out where. I tried adding a breakpoint but nothing stood out at me. Any help or feedback would be much appreciated.

eri0o

Since you mention you are achieving this bubble using a GUI, you could use a label in the GUI to display the text, and then the text placement should naturally follow the GUI.

You can then use a transparent font for speech if you just want to use the character Say function for handling input in a blocking way.

codinginquarantine

Quote from: eri0o on Sun 10/07/2022 13:18:11
Since you mention you are achieving this bubble using a GUI, you could use a label in the GUI to display the text, and then the text placement should naturally follow the GUI.

You can then use a transparent font for speech if you just want to use the character Say function for handling input in a blocking way.

So looking into this, I see there's some built in tokens like @SCORE@ that will auto replace in GUI labels. Is there one I would need to use in order to get the text to populate the label? Not able to find one when I do research on GUI labels

Crimson Wizard

#3
Quote from: codinginquarantine on Mon 11/07/2022 03:13:09
So looking into this, I see there's some built in tokens like @SCORE@ that will auto replace in GUI labels. Is there one I would need to use in order to get the text to populate the label? Not able to find one when I do research on GUI labels

You need to call your custom function instead of calling "player.Say", passing text as an argument. Inside that function set a label, make gui visible, position it as you prefer. Then use "WaitMouseKey" function to block the game until player presses or clicks something. The function may be created as a "extender", to make its use more pretty.
(See this topic in the manual for extender functions: https://adventuregamestudio.github.io/ags-manual/ExtenderFunctions.html)

Example:
Code: ags

// in a script header, such as GlobalScript.ash:
function SpeechGui(this Character*, String text);

Code: ags

// in a script body, such as GlobalScript.asc:
function SpeechGui(this Character*, String text)
{
     //... find necessary position, like you do now

     SpeechLabel.Text = text; // set text to a label on gui
     gSpeech.Visible=true; // turn gui on

     // wait for player input
     WaitMouseKey(TIMEOUT);

     // cleanup
     gSpeech.Visible = false;
}


Then you may call such function as:
Code: ags

player.SpeechGui("Yadda yadda");



For Dialog scripts, configure "Custom Say function in dialog scripts" (General Settings -> Dialog), and input your function's name there. Then whenever you write dialog scripts your function will also be used for speech lines instead of standard "Say".


If you want "timeout" based on text length, then it may be calculated inside this function like:
Code: ags

    int timeout = (text.Length / Game.TextReadingSpeed) / GetGameSpeed(); // number of game loops to read this text
    WaitMouseKey(timeout);


If you want an infinite timeout (no skip by timer), then, if you are using 3.6.0 simply do "WaitMouseKey(-1);", if not then following code:
Code: ags

    while (WaitMouseKey(1) == 0); // wait until something is pressed or clicked





PS. Also I might mention that there's a SpeechBubble module that may save you time, unless you prefer to code everything yourself:
https://www.adventuregamestudio.co.uk/forums/index.php?topic=55542.0

Khris

Quote from: codinginquarantine on Mon 11/07/2022 03:13:09
So looking into this, I see there's some built in tokens like @SCORE@ that will auto replace in GUI labels. Is there one I would need to use in order to get the text to populate the label? Not able to find one when I do research on GUI labels

This: https://adventuregamestudio.github.io/ags-manual/Label.html#labeltext

SMF spam blocked by CleanTalk