Overhotspot label text goes off screen when mouse cursor is inventory item

Started by ManicMatt, Thu 17/05/2018 14:54:35

Previous topic - Next topic

ManicMatt

Okay folks, I didn't realise I had this problem until last night. I have some code in my global script that keeps the text on hotspots etc from dissappearing off the sides of the screen. However, when going to the inventory screen and clicking once on an inventory item and going back to the game, the hotspot text isn't affected by my code and goes off the screen. Is it not a part of gOverhotspot? If it's called something else, I should be able to add it to my script, but I don't know what it is.

It's important to note I am using the Scumm Verb Coin template.

Cheers!

Code: ags
function repeatedly_execute()
{


gOverhotspot.Visible = true;
gOverhotspot.SetPosition(mouse.x-198, mouse.y-90);
if (mouse.x<70) gOverhotspot.SetPosition(mouse.x-90, mouse.y-90);
if (mouse.x>540) gOverhotspot.SetPosition(mouse.x-260, mouse.y-90);

if (mouse.y<70){
if (mouse.x<50)
gOverhotspot.SetPosition(mouse.x-90, mouse.y+20);

if (mouse.y<70){
if (mouse.x>540)
gOverhotspot.SetPosition(mouse.x-260, mouse.y+20);

if (mouse.y<70){
if (mouse.x<540)
if (mouse.x>50)
gOverhotspot.SetPosition(mouse.x-198, mouse.y+20);

}
}
}
}

Khris

Here's your code with proper indentation:

Code: ags
function repeatedly_execute() {


  gOverhotspot.Visible = true;
  gOverhotspot.SetPosition(mouse.x - 198, mouse.y - 90);
  if (mouse.x < 70) gOverhotspot.SetPosition(mouse.x - 90, mouse.y - 90);
  if (mouse.x > 540) gOverhotspot.SetPosition(mouse.x - 260, mouse.y - 90);

  if (mouse.y < 70) {
    if (mouse.x < 50)
      gOverhotspot.SetPosition(mouse.x - 90, mouse.y + 20);

    if (mouse.y < 70) {
      if (mouse.x > 540)
        gOverhotspot.SetPosition(mouse.x - 260, mouse.y + 20);

      if (mouse.y < 70) {
        if (mouse.x < 540)
          if (mouse.x > 50)
            gOverhotspot.SetPosition(mouse.x - 198, mouse.y + 20);

      }
    }
  }
}


(In case it's not immediately clear: your code does not do what you think it does, at all.)

Edit:
A better strategy is to start with the position of the GUI:
Code: ags
  int x = mouse.x - 198; int y = mouse.y - 90;


Now ignore the mouse position and just check the GUI bounds v screen bounds:
Code: ags
  if (x < 0) x = 0;
  if (x + gOverhotspot.Width > System.ViewportWidth) x = System.ViewportWidth - gOverhotspot.Width);

Same for y, done.

ManicMatt

Hey,

I think that my code makes the text move over to the sides when the mouse cursor reaches the co-ordinates I entered. Which it does. Except where I mentioned. I previously tried using ViewPortWidth, and while it looked a lot better, I could only make it work when the mouse was over something, not when the verb coin was displayed to select interactions. But your code looks different, so I gave it a try, but I can't get it to work.

First it said x is already defined, so I changed that to Posx, but then I get:

GlobalScript.asc(41): Error (line 41): Expected integer value after '='

If I remove the values and just have mouse.x, just to see what happens, I get a parser error on your line 2. However I'm not sure what is the variable and what is actually just a normal x for co-ordiantes?

Crimson Wizard

Quote from: ManicMatt on Thu 17/05/2018 17:32:22
I think that my code makes the text move over to the sides when the mouse cursor reaches the co-ordinates I entered. Which it does.

Only to elaborate, that code could actually work, but it was written in a syntactically messy way.

The thing was that you had several nested identical conditions. It went like:
Code: ags

if (mouse.y<70)
{
   // something
   if (mouse.y<70)
   {
     // more code
     if (mouse.y<70)
     {
       // more code
     }
   }
}


While you probably rather have only one "if (mouse.y < 70)" check, and the rest inside:
Code: ags

  if (mouse.y < 70) {
    if (mouse.x < 50)
      gOverhotspot.SetPosition(mouse.x - 90, mouse.y + 20);
 
    if (mouse.x > 540)
      gOverhotspot.SetPosition(mouse.x - 260, mouse.y + 20);
 
    if (mouse.x < 540)
      if (mouse.x > 50)
        gOverhotspot.SetPosition(mouse.x - 198, mouse.y + 20);
  }


Note, that the last condition could be simplified to one liner:
Code: ags

if (mouse.x > 50 && mouse.x < 540)




Crimson Wizard

Alright, in addition to the above, I have to admit that did not pay attention to this fact at first, but now when I do, the coordinates you set seem pretty strange.

For instance:
Code: ags

if (mouse.x < 50)
      gOverhotspot.SetPosition(mouse.x - 90, mouse.y + 20);

This code means, that if mouse cursor, for example, is at X = 0, then the GUI will be set at -90, which is outside the game screen. Is it really intended behavior?




Quote from: ManicMatt on Thu 17/05/2018 17:32:22But your code looks different, so I gave it a try, but I can't get it to work.

First it said x is already defined, so I changed that to Posx, but then I get:

GlobalScript.asc(41): Error (line 41): Expected integer value after '='

If I remove the values and just have mouse.x, just to see what happens, I get a parser error on your line 2. However I'm not sure what is the variable and what is actually just a normal x for co-ordiantes?

Could you post all of your new code please?

Khris

Here's the full example code (which should work as-is):
Code: ags
function repeatedly_execute() {
  gOverhotspot.Visible = true;
  // calculate coordinates assuming for now that GUI doesn't have to be moved
  int x = mouse.x - 198; int y = mouse.y - 90;
  // horizontal check
  if (x < 0) x = 0;
  if (x + gOverhotspot.Width > System.ViewportWidth) x = System.ViewportWidth - gOverhotspot.Width;
  // vertical check
  if (y < 0) y = 0;
  if (y + gOverhotspot.Height > System.ViewportHeight) y = System.ViewportHeight - gOverhotspot.Height;
  // finally, actually move GUI there
  gOverhotspot.SetPosition(x, y);
}


Edit: removed brackets

ManicMatt

Crimson - I recall the gui was waaaay over to the right hand side for some reason (if I knew, I can't remember now), and you'll see the initial adjustment is minus 198, and when it's less than 50 on x, it's minus 90, which is a less amount than 198. Maybe that's what it was? I mean, if I hover the cursor on something to the edge of the left hand side of the screen (apart from the inventory cursor), the text gui has moved to the right.

Khris - Okay thanks I'll try again. Yeah x is still a declared variable somewhere else, which I cannot find. Oh, you put ) brackets near the end of lines 7 and 10 so I deleted those. I replaced x with Posx.

Okay, so I can get the game to run with Khris' code:

Code: ags
function repeatedly_execute()
{
  
  gOverhotspot.Visible = true;
  // calculate coordinates assuming for now that GUI doesn't have to be moved
  int Posx = mouse.x - 0; int Posy = mouse.y - 0;
  // horizontal check
  if (x < 0) Posx = 0;
  if (Posx + gOverhotspot.Width > System.ViewportWidth) Posx = System.ViewportWidth - gOverhotspot.Width;
  // vertical check
  if (y < 0) Posy = 0;
  if (Posy + gOverhotspot.Height > System.ViewportHeight) Posy = System.ViewportHeight - gOverhotspot.Height;
  // finally, actually move GUI there
  gOverhotspot.SetPosition(Posx, Posy);

}


I think I've messed up my @overhotspot@ properties. I'm going to start a new project and see what its width is for both the label and main gui. Perhaps when I changed my project's resolution from the default, I needed to change this too?

Crimson Wizard

Quote from: ManicMatt on Thu 17/05/2018 19:57:39
I think I've messed up my @overhotspot@ properties. I'm going to start a new project and see what its width is for both the label and main gui. Perhaps when I changed my project's resolution from the default, I needed to change this too?

Width and height for the label should be dynamic, simply make them resize to the text's width and height.
I think we were discussing that very recently? http://www.adventuregamestudio.co.uk/forums/index.php?topic=22152.msg636585537#msg636585537
Were you able to integrate that code?

ManicMatt

Because I couldn't work out how to make your script you gave me work with the verb coin, I didn't look into the text width thing. Oh so AGS needs to dynamically check the size of the text to appear to know how to display it properly? I'll have a look in the manual now haha. Thanks.

Crimson Wizard

Quote from: ManicMatt on Thu 17/05/2018 20:17:16Oh so AGS needs to dynamically check the size of the text to appear to know how to display it properly? I'll have a look in the manual now haha. Thanks.

No, it does not HAVE to. I mean, it probably should be the way in your case.

Quote from: ManicMatt on Thu 17/05/2018 20:17:16
Because I couldn't work out how to make your script you gave me work with the verb coin

Sorry, I did not notice that. But thing is, you never posted the actual code that you tried.

ManicMatt

I've been at this since my last reply, close to throwing my laptop out the window lol.. sob..

Okay I've been confused at the manual's brief example of GetTextWidth that shows "Hello" and displays hello, but doesnt explain what im supposed to put instead of some speech marks. I've looked at Crimson's code in the other thread again about text width, and I don't understand it either. I can't get my head around it. But yeah I might not actually need it anyway..

So let's go back to basics.

As of right now, my label appears below and to the right of the cursor. If I change this with SetPosition, when you move the cursor to the far right, the text doesn't stop at the edge anymore, it stops further left. So this cannot be the solution. I also cannot actually test the far left because it doesn't reach the edge because the text is to the right anyway. So how do I centre it? What am I missing?

Thanks again!

Khris

If you're using exactly what you've posted here, you forgot to replace all instances of x and y with Posx and Posy. Given that you already have x and y, that can lead to weird results. (lines 8 and 11 of your snippet)

As for GetTextWidth, if you're using @OVERHOTSPOT@ as label text, I'm not sure using GetTextWidth will work as expected. A better solution is to do something like this:

Code: ags
  // before calculating the position, set label and GUI width based on text
  String ln = Game.GetLocationName(mouse.x, mouse.y);
  lblOverhotspot.Text = ln;
  lblOverhotspot.Width = GetTextWidth(ln, lblOverhotspot.Font) + 2; // small error margin to ensure text doesn't wrap
  gOverhotspot.Width = lblOverhotspot.Width; // assuming label's x coordinate on GUI is 0
  // gui position calculations here


If you want the GUI to be centered on the mouse cursor horizontally, but the gui's width keeps changing, you cannot use a fixed value.
Instead of
Code: ags
  int Posx = mouse.x - SOME_FIXED_VALUE;


you'll want
Code: ags
  int Posx = mouse.x - gOverhotspot.Width / 2;

Crimson Wizard

EDIT: Now that I think about this, I maybe know why this WILL NOT be working when Verb Coin is shown, because your mouse will be moving above verb coin GUI and getting description of its hotspots instead of room hotspot.

So for that case, you'd probably need to save the location name in a variable before displaying Verb Coin.

ManicMatt

Woohoo, it's centred now, thanks guys for all your help! It's ironic that this morning I realised I hadn't asked for any help for a while which is good, and then.. doh!

That width / 2 did the job. Just so it's not alien code to me and to say I've learned something.. is that / = divided, and 2 = by two?

Crimson: Interesting, because with this new code layout, the verb coin AND the inventory cursor are working the same as with hovering over hotspots, when they didn't before. Is it possible I tinkered with something and I've forgotten I did that??

Crimson Wizard

Quote from: ManicMatt on Thu 17/05/2018 22:22:51
Crimson: Interesting, because with this new code layout, the verb coin AND the inventory cursor are working the same as with hovering over hotspots, when they didn't before. Is it possible I tinkered with something and I've forgotten I did that??

Or I am wrong in my assumptions. It is also possible that Verb Coin modules does something to the label text internally. Sorry, I never tested such code with that module specifically.

ManicMatt

Trust me to choose a module not used very much!

My next challenge - at the bottom of the screen, the text label is now hiding underneath the verb coin, arrghhh!! When I had that previous code as seen at the top of this thread, the label simply jumped above the verb coin, but I'm not sure if putting that in will conflict with the new code (just the if conditions relevant). But it's nearly bedtime where I am, I should switch my brain off for tonight, ha!

(I am however very appreciative to you two, this new code not only works with the inventory cursor, but looks a lot nicer than the label flicking to the sides etc, although if I can make it do that at the bottom, its acceptable.)

Crimson Wizard

Quote from: ManicMatt on Thu 17/05/2018 22:38:37
My next challenge - at the bottom of the screen, the text label is now hiding underneath the verb coin, arrghhh!! When I had that previous code as seen at the top of this thread, the label simply jumped above the verb coin, but I'm not sure if putting that in will conflict with the new code (just the if conditions relevant).

This may help
http://www.adventuregamestudio.co.uk/manual/ags57.htm#gui.zorder

ManicMatt

ooh thanks, this will come in handy! I shall see if making the verb coin semi transparent at the bottom works! (and maybe that tweening thing can make it smoothly transition.. oh boy what am I getting myself in for!)

Khris

Crimson is talking about GUI.ZOrder, a property you can set in scripts or the editor to determine which GUI covers which. Just change your text label GUI's .ZOrder value to a higher one than the VerbCoin GUI's and it will appear on top of the coin.

Crimson Wizard

Yes, sorry, lol, forgot to mention exact property, but then hoped that the name of link will give a hint.

On the other hand, transparency thing may come useful too.

SMF spam blocked by CleanTalk