Avoid crash preventing mouse-following GUI.X from going out of range

Started by LostTrainDude, Fri 07/10/2016 10:03:31

Previous topic - Next topic

LostTrainDude

I've been playing around with the Description module by SSH in order to achieve this:



In other words: when the cursor reaches the far right end of the screen, invert the position of the Hotspot Name GUI, placing it to the left of the cursor, instead of the right.

To do this I tweaked a specific line in the original module's script, from this:
Code: AGS

// Original code
protected function Descriptions::Update_Position(int font, int width)
{
    // ...

    this.x = mouse.x + this.OffsetX;

    if ((this.x + this.width) > this.MaxX)
    {
	this.x = this.MaxX - this.width;
    }

    // ...
}


To this:
Code: AGS

// My code
protected function Descriptions::Update_Position(int font, int width)
{
    // ...

    this.x = mouse.x + this.OffsetX;

    if ((this.x + this.width) > this.MaxX)
    {
        this.x = mouse.x - this.width - ((this.width/2) - this.OffsetX);
    }
    
    // ...
}


This mostly works but, as soon as I reach the top-right end of the screen (whether it's in windowed or fullscreen mode), the game crashes giving me the error: GUI.X co-ordinates specified are out of range.
I'm pretty sure I'm missing something in the messy "logic" I tried to find out. Maybe it's just the order of the operands in the expression, but I'm not really sure about that.

Does any of you have any advice on how to fix this?
Thanks in advance :-D
"We do not stop playing because we grow old, we grow old because we stop playing."

Gilbert

I don't know what is what in the codes, but one wild guess, what is this.width?
Would it be the width or a sprite or whatever?
In this case there may be a potential problem when the width of a sprite is an odd number, as dividing it by 2 is an integer operation that truncates the decimal part, you may end up subtracting 1 fewer pixel, causing the final coordinate to just hit beyond the screen border.

LostTrainDude

The this in the Description.asc script should ultimately represent the GUI itself.

The function declaration - with the double colon, which a quick research defines me as a "scope resolution operator" - is, I think, a little to advanced for me to understand properly, but as far as the code goes, Descriptions is a struct defined in the script header. My guess is that the scope resolution operator helps to avoid overwriting "accidents" between different "instances" of Description but, again, I'm not really sure about what I'm saying :-\
"We do not stop playing because we grow old, we grow old because we stop playing."

Snarky

Not sure why it's crashing (in particular why you'd get an error with the x-coordinate depending on your y-coordinate: that seems like something that must be caused by code you haven't included here), but to achieve the positioning in that example, I think the expression you want is simply:

Code: ags
    this.x = mouse.x - this.width - this.OffsetX;


I don't know what you're doing with "this.width/2" â€" that's the sort of thing that should only be useful if you're centering the label relative to something, which isn't the case here. You are simply aligning the right edge of the GUI with the cursor (offset slightly).

Retro Wolf

In my RPG I use a GUI (gEmote) for emotes above the player character, in some situations the GUI might try to be drawn off-screen. Perhaps you could take something from it. You probably wouldn't use gx, or gy. That's just where I want to draw the GUI in my game. You wouldn't use Room.Width for scrolling rooms.

Code: ags
// Emote GUI position and safety //
    // GUIs don't like going off screen!
  int gx = (player.x - 8);
  int gy = (player.y - 32);
  
  if (gx < 0) {gx = 0;} // left of screen
  else if (gx > (Room.Width - gEmote.Width)) {gx = (Room.Width - gEmote.Width);} // right of screen
  
  if (gy < 0) {gy = 0;} // top of screen
  else if (gy > (Room.Height - gEmote.Height)) {gy = (Room.Height - gEmote.Height);} // bottom of screen
  
  gEmote.X = gx;
  gEmote.Y = gy;

LostTrainDude

Quote from: Snarky on Fri 07/10/2016 19:25:19
I don't know what you're doing with "this.width/2"

The reason I was using the this.width/2 was because it kept the cursor from hovering the "popup" GUI (which caused a blinking glitch). But I think a could manually subtract another integer value at my leisure.
I'm not sure whether I tried that expression in a previous attempt but still, thanks :) It seems to be working! I'll run just a few tests to see if I'm right, and if I am I'll mark this solved.

Quote from: Retro Wolf on Fri 07/10/2016 19:51:01
In my RPG I use a GUI (gEmote) for emotes above the player character, in some situations the GUI might try to be drawn off-screen. Perhaps you could take something from it.

If not for this purpose, this can actually come really handy later on, for another thing I'm trying!
Thanks a lot to all three of you :)
"We do not stop playing because we grow old, we grow old because we stop playing."

SMF spam blocked by CleanTalk