Making small / thin characters catch clicks more easily [SOLVED]

Started by LeChuck, Wed 01/08/2007 00:54:37

Previous topic - Next topic

LeChuck

I'm having a few characters that in are like stick figures, with thin arms and legs. These are difficult to hit, sometimes. I cannot simply draw a hotspot over the characters, as they move all over the screen. Is there a way to enlarge the "click zone"?

Khris

Yeah, something like this should work:

Code: ags
// global script, inside on_mouse_click

  if (button==eMouseLeft) {

    int i;
    int found=-1;
    int xd;
    int yd;
    int w;
    int h;
    Character*c;
    ViewFrame*vf;
    DynamicSprite*d;

    while(i<Game.CharacterCount) {
      c=character[i];
      vf=Game.GetViewFrame(c.View, c.Loop, c.Frame);
      d=DynamicSprite.CreateFromExistingSprite(vf.Graphic);
      w=(d.Width*c.Scaling)/200;
      h=(d.Height*c.Scaling)/100;
      d.Delete();

      xd=c.x-(mouse.x+GetViewPortX());
      if (xd<0) xd=-xd;
      yd=c.y-(mouse.y+GetViewPortY());
      if (yd<0) yd=h;

      if (xd<w && yd<h && c.Clickable && c.Room==player.Room) {
        if (found==-1) found=i;
        else if (c.Baseline>character[found].Baseline) found=i;
      }
      i++;
    }
    if (found>=0) character[found].RunInteraction(mouse.Mode);
    else ProcessClick(mouse.x, mouse.y, mouse.Mode);
  }

  ...


This code ignores walkbehinds and objects, and it's not tested!
But it should get you started.

monkey0506

It's not necessary to use a DynamicSprite to grab a sprite's height/width...

Code: ags
    int i;
    int w;
    int h;
    Character* c;
    ViewFrame* vf;

    while(i < Game.CharacterCount) {
      c = character[i];
      vf = Game.GetViewFrame(c.View, c.Loop, c.Frame);
      w = (Game.SpriteWidth[vf.Graphic] * c.Scaling) / 200;
      h = (Game.SpriteHeight[vf.Graphic] * c.Scaling) / 100;


Seeing as you only used the DynamicSprite to grab the height/width, you can use Game.SpriteHeight and Game.SpriteWidth instead.

Khris


Play_Pretend

Isn't there an option in the general settings, where if you turn off Pixel Perfect click detection, it'll just automatically detect clicks in a rectangular area around the character/object?

Ashen

There is, but like you said it'll make ALL Objects and Characters ALL clickable too. If that's what you're after, disabling the 'Pixel perfect click detection' option is probably a lot easier, otherwise Khris' code is probably the way to go. Also, you could use Custom Properties to limit it to Characters / Objects that actually need the extra checking. That said, you could probably use Properties to enable/disable Pixel perfect detection as needed anyway, e.g. (briefly tested):

Code: ags

  else if (button == eMouseLeft) {
    SetGameOption(OPT_PIXELPERFECT, false);
    if (GetLocationType(mouse.x, mouse.y) == eLocationObject) {
      Object *O = Object.GetAtScreenXY(mouse.x, mouse.y);
      SetGameOption(OPT_PIXELPERFECT, O.GetProperty("RectClick"));
    }
    if (GetLocationType(mouse.x, mouse.y) == eLocationCharacter) {
      Character *C = Character.GetAtScreenXY(mouse.x, mouse.y);
      SetGameOption(OPT_PIXELPERFECT, C.GetProperty("RectClick"));
    }
    else SetGameOption(OPT_PIXELPERFECT, true);
    ProcessClick(mouse.x, mouse.y, mouse.Mode );
  }


Where RectClick is a boolean property with a default 'true' value, which you only set to 'false' for the extra-thin Characters/ Objects.
I know what you're thinking ... Don't think that.

LeChuck

Thanks for the feedback everyone! It looks like Ashen came up with the easiest solution - to use the SetGameOption solution. This is what I used in the room's repeatedly execute script:

Code: ags

// remove pixel perfect clicking when hovering over crow
if ((mouse.x > cCrow.x-40) && (mouse.x < cCrow.x+40)) SetGameOption(OPT_PIXELPERFECT,  0);
else SetGameOption(OPT_PIXELPERFECT,  1);


All this really does is detect when the mouse is hovering over the characters' x coordinate and then turn off pixel perfect detection. I guess I could add something about the y coordinate too, but the way the game screen is set up, it doesn't really require me to.

I'm not proud of that code, but damn it works!

SMF spam blocked by CleanTalk