Identifying click target

Started by WHAM, Fri 15/08/2008 20:42:03

Previous topic - Next topic

WHAM

How do I identify what the player is clicking on?

For example: If I use a mouse mode "normal" as the default cursor, and want it to talk to characters when it is clicked on a character, use when it is clicked on a hotspot/object and walk to when none of the earlier apply?

How would I do this?
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Matti

#1
Code: ags

if (GetLocationType(mouse.x,mouse.y) == eLocationCharacter) {
    mouse.Mode = eModeTalk; 
}
if (GetLocationType(mouse.x,mouse.y) == eLocationNothing) {
    mouse.Mode = eModeWalkTo;
}
else {
    mouse.Mode = eModeInteract;
}


Edit: Ah well, this changes the mousemode but you want to have only one.. but now you know how to locate the clicked area.

Take a look here, this should help.

olafmoriarty

#2
If you never have more than one available mouse mode, I would suggest that you put them all in the same kind of interaction to make the whole thing easier. I've been fiddling with a similar concept myself, and my on_mouse_click() function looks a little bit like this:

Code: ags
function on_mouse_click(MouseButton button) {
  // called when a mouse button is clicked. button is either LEFT or RIGHT
  if (IsGamePaused() == 1) {
    // GAME IS PAUSED:
    // Nothing happens when the mouse button is clicked
  }
  else if (button == eMouseLeft) {
    // LEFT BUTTON IS CLICKED:

    // In my game it is theoretically impossible to select other
    // mouse modes than "Interact", but just in case I need
    // other mouse modes, e.g. for minigames, or there's
    // a bug somewhere, I check it to be certain.

    if (mouse.Mode == eModeInteract) {

      // Next: Check if the mouse cursor is in a location where
      // the "Interact" mode is AVAILABLE.

      if (IsInteractionAvailable(mouse.x, mouse.y, eModeInteract) == 1) {

        // If it is, interact with whatever is here.

        ProcessClick(mouse.x, mouse.y, eModeInteract);
      }
      else {

        // If we can't interact with anything here:
        // walk to this location

        ProcessClick(mouse.x, mouse.y, eModeWalkto);
      }
    }
    else {

      // If the cursor mode for some bizarre reason
      // is NOT Interact, then do whatever the cursor
      // wants to do.

      ProcessClick(mouse.x, mouse.y, mouse.Mode);
    }
  }
  // Here you put commands for what to do if the player
  // presses right button or uses mouse wheel. For
  // instance, if you want to examine things with the
  // right button. Just make sure to REMOVE the default
  // "flip through cursors with right button" function,
  // as there aren't any cursors to flip through here
}


Then I put ALL available interactions in the game in the "Interact" mode, regardless of what they do: using something, picking it up, talking to it, fighting it, mooning it or whatever else you may have in your game. When the player enters the start room, I set the cursor mode to Interact, and I have disabled all other cursor modes (not that it really matters, since I have disabled right button rotation and I have no GUI buttons anywhere to change cursor mode). Now, whenever I'm mousing over a hotspot, object or character, I will perform the only available interaction with them when I click the mouse button. If there's nothing there, I will simply walk to that location instead.

I'm aware that one drawback of this solution is that the cursor image won't change, but that's just because I haven't coded it yet; not because it's not possible to implement. I'm pretty confident that it is.

WHAM

#3
After reading you'r codes and trying them out a bit, I ended up with the following and it seems to be working well.

In the code, as you can see, I use other mouse modes (to keep the code clearer in other places) but only in a quick flash so that the player never realizes he used another mouse cursor at all! This way I can still use the "talk" function on characters and "interact" with objects and hotspots.

Code: ags

function on_mouse_click(MouseButton button) // called when a mouse button is clicked. button is either LEFT or RIGHT
  {
  if (IsGamePaused() == 1) // Game is paused, so do nothing (ie. don't allow mouse click)
    {
    }
  else if (button == eMouseLeft) 
    {
      if (GetLocationType(mouse.x,mouse.y) == eLocationCharacter) {
        if (Mouse.Mode == 8) {
          ProcessClick(mouse.x,mouse.y, mouse.Mode);
        } else {
        Mouse.Mode = 3; 
        ProcessClick(mouse.x,mouse.y, mouse.Mode);
        Mouse.Mode = 2;
        }
      } else if (GetLocationType(mouse.x,mouse.y) == eLocationHotspot) {
        Mouse.Mode = 2; 
        ProcessClick(mouse.x,mouse.y, mouse.Mode);
      } else if (GetLocationType(mouse.x,mouse.y) == eLocationObject) {
        Mouse.Mode = 2;
        ProcessClick(mouse.x,mouse.y, mouse.Mode);
      } else if (GetLocationType(mouse.x,mouse.y) == eLocationNothing) {
        Mouse.Mode = 0;
        ProcessClick(mouse.x,mouse.y, mouse.Mode);
        Mouse.Mode = 2;
      }
   }
  else if (button == eMouseRight) {
    if (Mouse.Mode == 8) {
      Mouse.Mode = 2;
      } else {
        Mouse.Mode = 1;
        ProcessClick(mouse.x,mouse.y, mouse.Mode);
        Mouse.Mode = 2;
        }
    }
}
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

olafmoriarty

Just a thought if you want a tidier code:

Instead of going through the trouble of writing
Code: ags
        Mouse.Mode = 3; 
        ProcessClick(mouse.x,mouse.y, mouse.Mode);
        Mouse.Mode = 2;


I think it would be easier to just use
Code: ags
        ProcessClick(mouse.x,mouse.y, 3);
        Mouse.Mode = 2;


The same simplification can be done other places in your script. No need to set value A to value B, use value A in a function and then reset value A when you can just use value B in the function in the first place.

Khris

Additionally, you can use the mode names to increase readability:

Mouse.Mode = 3;
Mouse.Mode = eModeInteract;

WHAM

Moriarty: Thanks for the tip!

Khris: I found that out too, but I dont know if that's so necessary, as I only really use the code here and once it's written, there's no need to change it anymore. (I hope...) I only use three different mouse modes in the game amyway, so they shouldn't be too hard to remember, especially when I have them all documented.
Wrongthinker and anticitizen one. Utterly untrustworthy. Pending removal to memory hole.

Khris

That's like putting the burger and fries in a blender before eating them because they'll end up that way in the stomach anyway ;)
Well, to each his own :)

SMF spam blocked by CleanTalk