Mouse over woes

Started by Pet Terry, Sun 07/08/2005 12:48:33

Previous topic - Next topic

Pet Terry

Hello.

I've gotten myself a neat interface including transparent GUI that follows the mouse cursor and displays hotspot's name on it. I managed to make it so that the GUI doesn't go off the screen, when the hotspot is close to the screen edge, by using simple code as if(gOverhotspot.X>219) blah de blah. But I was wondering if there is a way to restrict the GUI from going off the screen according the hotspot's name's width?

I was thinking something like:

Code: ags

int width = GetTextWidth(*Get the width of the text on label x here?*)

if(gOverhotspot.X>(320-width)) {
  gOverhotspot.X=(320-width);
}


Obviously the code isn't exactly correct, but is it possible to do that way? I am not exactly sure how to get the width of the text on label x...

Cheers.
<SSH> heavy pettering
Screen 7

Pumaman

string buffer;
lblLabelName.GetText(buffer);

int width = GetTextWidth(buffer, lblLabelName.Font);

if(gOverhotspot.X>(320-width)) {
  gOverhotspot.X=(320-width);
}

Pet Terry

#2
Whoo, I managed to get it to work. Thanks CJ!

I had to use...

Code: ags
if(gOverhotspot.X>(318-width/2)) {
  gOverhotspot.X=(318-width/2);


...because otherwise the mouseover text stopped too far away from the screen edge.

I also noticed that using 'lblOVERHP' (OVERHP being the script name of the label) gave me an 'undefined token' error, but removing the 'lbl' did the trick.

EDIT: Uh, I noticed that if the name of the hotspot is long, it goes off the edge of the screen, and if it's very short it leaves a gap between the name and edge of the screen. Well duh.

EDITEDIT: If the GUI position is set from the top left corner of the GUI, '320-width' should work just fine...

EDITEDITEDIT: Could it be that it takes the width from @OVERHOTSPOT@ instead of the name of the hotspot?
<SSH> heavy pettering
Screen 7

Pumaman

Ah yes, if you're using @OVERHOTSPOT@ then you'll be getting that back as the text for the label.

In that case, you'd need to use GetLocationName to simulate what the label is actually displaying. Your original 320-width calculation should be fine.

Pet Terry

Hah! Of course, that did it. Thanks for the help, I will have to buy you a drink or something at Mittens (I owe you one drink anyways, you bought me a Dr. Pepper at Victoria Station last summer and I forgot to pay you back).
<SSH> heavy pettering
Screen 7

Ishmael

If anyone else needs it:

Code: ags
string buffer;
int width;

function UpdateStatus() {
 Ã, GetLocationName(mouse.x, mouse.y, buffer);
 Ã, Overhp.SetText(buffer);
 Ã, width = GetTextWidth(buffer, Overhp.Font);
 Ã, Overhp.Width = width + 1;
 Ã, gOverhotspot.Width = width + 1;
 Ã, gOverhotspot.X = mouse.x;
 Ã, gOverhotspot.Y = mouse.y;
 Ã, if(gOverhotspot.X>(320-width)) {
 Ã,  Ã, gOverhotspot.X=(320-width);
 Ã, }
}


Just put UpdateStatus into the repeadetly_exectute.
I used to make games but then I took an IRC in the knee.

<Calin> Ishmael looks awesome all the time
\( Ö)/ ¬(Ö ) | Ja minähän en keskellä kirkasta päivää lähden minnekään juoksentelemaan ilman housuja.

monkey0506

Hey, thanks!  This will help with something that I will be working on...eventually...once I get around to working with the rest of my GUIs instead of just the dialog system... ::)

rossito

Hi guys. I'm trying to fix the game crash when the @overhotspot@ label goes off the edge of the screen.

I have my @overhotspot@ label working.
The GUI script name is gGui3
and my games resolution is 640 x 400.

I took a piece of the code suggested (I'm not worried about getting the width of the name and all that, just flipping the text and stopping the crash)

String buffer;
int width;

function UpdateStatus() {
if(gGui3.X>(640-width)) {
   gGui3.X=(640-width);
}
}

The game still crashes the same and I get the following error.

Error: GUI.X: co-ordinates specified are out of range. Remember to use 320 res-co-ordinates.

As I'm creating a 640 x 400 game does this mean I can't work this solution?

Gilbert

If your game's screen resolution is 640 x 400 its game resolution is actually 320 x 200.
Read this, which is slightly related.

So, your codes should be:
String buffer;
int width;

function UpdateStatus() {
 if(gGui3.X>(320-width)) {
Ã,  Ã, gGui3.X=(320-width);
 }
}

ManicMatt

Sorry to necro post this, but it's exactly what I needed I believe, except the code is now out of date, and I couldn't find anything more recent. I'm using the curse of monkey island verb and the gOverHotSpot labels. I tried replacing old code with what looks like the new code, but alas to no success.

Crimson Wizard

#10
Quote from: ManicMatt on Fri 04/05/2018 15:45:19
Sorry to necro post this, but it's exactly what I needed I believe, except the code is now out of date, and I couldn't find anything more recent. I'm using the curse of monkey island verb and the gOverHotSpot labels. I tried replacing old code with what looks like the new code, but alas to no success.

What code did you try? And what were the problems/errors with it?

EDIT:
I looked in the above examples, and they should work if you replace "string" with "String", and use corresponding string functions instead.

Searching in the manual for the old function name usually brings related new function article.

ManicMatt

Hey, Okay I don't know why someone said to put the whole thing with  function update status in repeatedly execute, it keeps saying I'm missing braces no matter where I put them. Can you even put a function within a function??

So not in repeatedly execute, it will say

GlobalScript.asc(53): Error (line 53): Type mismatch: cannot convert 'int' to 'string'

For

Code: ags
width = GetTextWidth(100, eFontFont0);



I really don't know what I'm doing there. I threw a random number in because I have no idea. I also don't even know if that's the font thing it wanted. (I've realised this thread is in advanced, I am anything but advanced! Forum searching doesn't let me search just for beginners?)

So if I take that line out for now, I get this:

GlobalScript.asc(54): Error (line 54): '.Width' is not a public member of 'Overlay'. Are you sure you spelt it correctly (remember, capital letters are important)?

For:

Code: ags
Overlay.Width = width + 1;


If i take that out too, the game runs with no visible difference I can see, but I've probably took out the bits needed..

Here's the whole code I have.

Code: ags

String buffer;
  int width;
    
    function UpdateStatus() {
      
      String location = Game.GetLocationName(mouse.x, mouse.y);
     
      width = GetTextWidth(100, eFontFont0);
      Overlay.Width = width + 1;
      gOverhotspot.Width = width + 1;
      gOverhotspot.X = mouse.x;
      gOverhotspot.Y = mouse.y;
      if(gOverhotspot.X>(280-width)) {
        gOverhotspot.X=(280-width);
      }
    }
    


No idea where to put the first two lines..??

Appreciate any help!

Crimson Wizard

#12
Quote from: ManicMatt on Fri 04/05/2018 21:25:47
Hey, Okay I don't know why someone said to put the whole thing with  function update status in repeatedly execute, it keeps saying I'm missing braces no matter where I put them. Can you even put a function within a function??

He meant putting a call to this function in repeatedly_execute, like this:
Code: ags

function repeatedly_execute()
{
    UpdateStatus();
}


Quote from: ManicMatt on Fri 04/05/2018 21:25:47
GlobalScript.asc(53): Error (line 53): Type mismatch: cannot convert 'int' to 'string'

For

Code: ags
width = GetTextWidth(100, eFontFont0);



I really don't know what I'm doing there. I threw a random number in because I have no idea. I also don't even know if that's the font thing it wanted.

Have you tried looking in the manual? It has explanations of these functions, with examples.

Quote
GetTextWidth(string text, FontType font)

Returns the width on the screen that drawing TEXT in FONT on one line would take up.

The first parameter should be your text line, the second font in which your text is drawn, because text width depends on font.


Quote from: ManicMatt on Fri 04/05/2018 21:25:47
GlobalScript.asc(54): Error (line 54): '.Width' is not a public member of 'Overlay'. Are you sure you spelt it correctly (remember, capital letters are important)?

For:

Code: ags
Overlay.Width = width + 1;


Hmm, it was not an Overlay in the examples above (Overlay is the name of the class), it was "Overhp", which is perhaps a name of a label on GUI.
The modern code would be:
Code: ags

YourLabelName.Text = text;
YourLabelName.Width = width + 1;



Besides that, I'd really suggest not using literal coordinates there, but System.ViewportWidth and System.ViewportHeight instead - they are the size of game screen.

So, in the end, perhaps, something like this:

Code: ags

void UpdateStatus()
{
      String location = Game.GetLocationName(mouse.x, mouse.y);     
      int width = GetTextWidth(location, OverhotspotLabel.Font); // Note you are telling your label's font here
      OverhotspotLabel.Text = location;
      OverhotspotLabel.Width = width + 1;
      gOverhotspot.Width = width + 1;
      gOverhotspot.X = mouse.x;
      gOverhotspot.Y = mouse.y;
      if(gOverhotspot.X>(System.ViewportWidth-width)) {
        gOverhotspot.X=(System.ViewportWidth-width);
      }
      // You may add more conditions and fix ups for GUI position here
}

function repeatedly_execute()
{
    UpdateStatus();
}


I have to say, since you already have hint label code, this new one may conflict with the old one, so it's better to find out how to merge them together.

ManicMatt

#13
Thanks for your time and patience!

In the time after posting this, I came up with this:

Code: ags
function repeatedly_execute()
{


gOverhotspot.Visible = true;
gOverhotspot.SetPosition(mouse.x-95, mouse.y-46);
if (gOverhotspot.X>(200)) gOverhotspot.X=(200-width);
if (gOverhotspot.X<(-85)) gOverhotspot.X=(-80-width);

}


But I think I'll have a crack with your code there! Indeed, the co-ordinates thing is very trial and error for me.

UPDATE:

Both this and your script suggestion worked, except I couldn't get the text that appears when you hold down the left mouse button and bring up the verb coin to do the same. I don't understand that. I could have done something wrong and it might not be your script at fault, or like you say, a confliction with something else.

So instead I thought of another way around it, which seems to be work. Can you foresee any problems?

Code: ags
function repeatedly_execute()
{


gOverhotspot.Visible = true;
gOverhotspot.SetPosition(mouse.x-95, mouse.y-46);
if (mouse.x<20) gOverhotspot.SetPosition(mouse.x-60, mouse.y-46);
if (mouse.x>270) gOverhotspot.SetPosition(mouse.x-120, mouse.y-46);

if (mouse.y<35){
if (mouse.x<20)
gOverhotspot.SetPosition(mouse.x-60, mouse.y+20);

if (mouse.y<35){
if (mouse.x>270)
gOverhotspot.SetPosition(mouse.x-120, mouse.y+20);

if (mouse.y<35){
if (mouse.x<270)
if (mouse.x>20)
gOverhotspot.SetPosition(mouse.x-95, mouse.y+20);

}
}
}
}


It behaves okay. Sure it's not as nice to look at when the text moves, as having text not budge past the edges, but at least it seems to work for the verbcoin text too. For some reason!

SMF spam blocked by CleanTalk