Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: LeChuck on Wed 01/08/2007 00:54:37

Title: Making small / thin characters catch clicks more easily [SOLVED]
Post by: LeChuck on Wed 01/08/2007 00:54:37
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"?
Title: Re: Making small / thin characters catch clicks more easily
Post by: Khris on Wed 01/08/2007 02:16:04
Yeah, something like this should work:

// 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.
Title: Re: Making small / thin characters catch clicks more easily
Post by: monkey0506 on Wed 01/08/2007 02:42:48
It's not necessary to use a DynamicSprite to grab a sprite's height/width...

    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.
Title: Re: Making small / thin characters catch clicks more easily
Post by: Khris on Wed 01/08/2007 02:47:36
Oh, thanks for pointing that out.
Title: Re: Making small / thin characters catch clicks more easily
Post by: Play_Pretend on Sun 05/08/2007 12:08:13
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?
Title: Re: Making small / thin characters catch clicks more easily
Post by: Ashen on Sun 05/08/2007 13:07:24
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):


  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.
Title: Re: Making small / thin characters catch clicks more easily
Post by: LeChuck on Wed 08/08/2007 08:06:40
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:


// 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!