Solved: Mouse moves over hotspot - how to reset!

Started by johanvepa, Mon 05/10/2015 20:42:04

Previous topic - Next topic

johanvepa

I'm toying with the idea of adding a feature to my pet project.

It's Sierra-style, but instead of the usual walk-look-use-talk icons rotating by right click, I'd like to make the cursor change into the appropriate mouse.Mode when the mouse is moved onto a select hotspot.

This is very easy using the "Mouse moves over hotspot" event for a hotspot. Then, using the "Any click on hotspot" event, I can execute a command that's appropriate for the particular hotspot.

However, this only works one way. The mouse moves over the hotspot and the cursor changes. I'd like the cursor to change back to default once the mouse moves away from the hotspot again.

I have the feeling this might be accomplished easily using and "if" in repeatedly_execute and mouse.UseDefaultGraphic, but I need to tell the script what event to look for, i.e. something like this in the main script:

Code: ags

function repeatedly_execute()
{
    if (OnTheEventOfTheMouseLeavingAHotspot)
  {
  mouse.UseDefaultGraphic;
  }
}


Now, typing OnTheEventOfTheMouseLeavingAHotspot is rather silly of course, but what should I type in its stead?


Slasher

Use the Hotspot.GetAtScreenXY(..) function

Code: ags

if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hotspot[1]) {
  //Change cursor graphic for Hotspot 1
}
else if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hotspot[2]) {
  //Change cursor graphic for Hotspot 2
}
//Etc for other hotspots
else {
  //Set default cursor graphic for No Hotspot
}


also check out: http://www.adventuregamestudio.co.uk/forums/index.php?topic=25645.msg323172#msg323172





johanvepa

If this is put into repeatedly_execute, won't it give performance issues, like a blinking mouse cursor, when the mouse mode updates 40 times a second?


Slasher

#3
Why don't you just try it?

Quotewhen the mouse mode updates 40 times a second?
at 40 times a second you'de never notice (faster than the eye) ;)

Crimson Wizard

#4
I think it should not redraw cursor if the graphic is the same.

johanvepa

Quote from: Crimson Wizard on Tue 06/10/2015 15:48:12
I think it should not redraw cursor if the graphic is the same.

That's sort of what I thought. Why redraw 40 times a second?
But then again, Slasher is right, I didn't try it yet (stuck at the office and too eager to wait until I get home :grin:)

Snarky

Quote from: slasher on Tue 06/10/2015 15:27:59
Why don't you just try it?

Quotewhen the mouse mode updates 40 times a second?
at 40 times a second you'de never notice (faster than the eye) ;)

This is not true. If the cursor were to change shape (or disappear) for one frame, it would certainly be noticeable at 40 fps, unless the change was very subtle. You'd probably see it as a brief flicker.

johanvepa

Then again, perhaps I could simply use an "if" statement to determine if the cursor is still on the hotspot, and only "if" this is no longer true should it return to default. I'll try it out.


johanvepa

Tested and working. Thank you slasher  ;)

Code: ags



function room_RepExec()
{

  if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hotspot[1])
  {
    if (mouse.Mode != eModeLookat)
    {
      mouse.Mode = eModeLookat;
    }
  }
  else if (mouse.Mode != eModeWalkto)
  {
    mouse.Mode = eModeWalkto;
  }    

}


johanvepa

Thank you for that too, Khris. I was wondering how to avoid clashes with active inventory items, your solution will solve that.

But another idea popped up: Can I use custom properties of hotspots to determine which cursor should be applicable to that hotspot? The ideal result would be to have one hotspot, with custom property "1", activate the eye cursor, and another hotspot, with custom property "2", activate the hand cursor. In order to make this work on game level, I figure I would have to use properties. But I lack for the words to put into AGS to let it know whe're looking for properties.

Let's say I make a custom property called CursorProperty (number type). And then something along the lines of:
Code: ags

 if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == "HotspotHasProperty1")
    {
      mouse.Mode = eModeLookat;
    }
 else if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == "HotspotHasProperty2")
    {
      mouse.Mode = eModeInteract;
    }



Snarky

Yes, your thinking is more or less right, that's how you'd want to do it. You wouldn't have different properties for each hotspot, though. Rather, you'd have one property with different VALUES depending on which cursor you want.

The AGS syntax for this looks something like:

Code: ags
// Here's how you get the "Cursor" property of the current hotspot
Hotspot* activeHotspot = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
int hotspotCursor = -1;
if(activeHotspot != null)
  hotspotCursor = activeHotspot.GetProperty("Cursor");

// And here's how you use it to set the cursor
if(hotspotCursor == 1)
  mouse.Mode = eModeLookAt;
else if(hotspotCursor == 2)
  mouse.Mode = eModeInteract;
// etc.

johanvepa

Wait, sorry for taking your time all, I think what I'm looking for is included in IsInteractionAvailable, which I've just found out about. I'll have to check it out and see if it works as well as I suspect  ;)

And thank you, Snarky, for your quick and helpful reply.

johanvepa

This works a treat   :)
At the time only for LookAt, but it should be easy to extend to other interactions. Also, I have a bit of trouble with my inventory items, I'll have to figure out a way to "turn it off" when viewing inventory, but that should be a piece of cake.

And so simple. I like simple   :)

Code: ags

  if (IsInteractionAvailable(mouse.x,mouse.y, eModeLookat) == 1)
  {
    if (mouse.Mode != eModeLookat)
    {
      mouse.Mode = eModeLookat;
    }
  }
  else if (mouse.Mode != eModeWalkto)
  {
    mouse.Mode = eModeWalkto;
  }    

Khris

There's no need to compare boolean return values to 1, you can remove "== 1" and it will still work, since IsInteractionAvailabe() already returns "true" or "false" which "true == 1" and "false == 1" will evaluate to anyway.

johanvepa

But the manual says to use "== 1" and here I went and thought I had it   :~(


I shouldn't go and read such stuff :-\





(Just kidding, thank you for this point, Khris)

SMF spam blocked by CleanTalk