Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Sprite:hitTestPoint() doesn't ignore hidden children? — Gideros Forum

Sprite:hitTestPoint() doesn't ignore hidden children?

MauMauMauMau Member
edited November 2013 in General questions
It seems that Sprite:hitTestPoint() does not ignore hidden children that have been set to hidden using :setVisible(false).

If I have a sprite (f.e. button) that contains several children and do a :hitTestPoint, I would assume that children whose alpha is 0 are taken into account, whereas children set to hidden ( :setVisible(false) ) are ignored.

Shouldn't this be the usual way?

Comments

  • Yes there are lots of confusion on this one
    setVisible removes the image from the rendering, but still leaves its dimensions to impact the surrounding sprites
    The reason is simple, you can create small tiny buttons with invisible area around them to make them easier to click on smaller screens

    but the drawback is, well what you found out on your own :)

    The solution is to scale them to hide them completely

    You can do something like this, for easier code implementation
    Sprite._setVisible = Sprite.setVisible
    function Sprite:setVisible(visible)
        if not visible then
            self._xScale, self._yScale = self:getScale()
            self:setScale(0, 0)
        else
            self:setScale(self._xScale, self._yScale)
        end
        self:_setVisible(visible)
    end
  • Hm, if I would like to create tiny buttons with an invisible touch area around, I could also use PNG images with transparent margins -or place a transparent rectangle shape behind that button -or any other object with alpha set to 0, so I don't see a real advantage here.

  • Well there are many different solutions, and also other perspectives why visibility behaves how it behaves, the point is, you can modify default behavior to match your needs ;)
  • @ar2rsawseen, I think this starts from the problem with C*SDK where if the alpha == 0 or the sprite not visible, it does not handle touches. So if you wanted an invisible button, the alpha would be 1 so that it responds but not be visible to the user.

    @MauMau, a quick fix rather than scaling, because it might mess up the layout (the sprite might be set to not visible to appear on some other action soon) is when you handle touch, simply check for the visibility along with the
    hitTestPoint
    . That would be the easiest fix for the moment.
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • Most of the other SDKs I used in the past followed the paradigm that hidden objects are excluded from the render chain (and therefore do not receive any user interactions) -and that seems quite reasonable to me. If a user can't see an object, he doesn't interact with it, or not?

    It would make sense if objects (or children) set to alpha = 0 would receive touch events, while objects with visibility = false would be ignored. By doing so, we could decide if we'd like an object to be interactive or not.

    @OZApps: I have a button (sprite) with a tooltip bubble above (child of the button sprite). Most of the time, the tooltip isn't visible -but if the user touches the tooltip area above the button, it still triggers the touch event, although there is just a blank space. hitTestPoint also includes this (hidden) children and returns a true when the user touched the (hidden) tooltip above the button.
  • @MauMau, right, you are using the sprite like a group ...

    If you would use it like a sprite (single object) the workaround might just work for you.
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • john26john26 Maintainer
    edited November 2013
    To set up a button I normally do this:
    button:addEventListener(Event.MOUSE_DOWN,func,button)
    :
    function func(self,event)
      if self:hitTestPoint(event.x,event.y) then
      -- do something
      end
    end
    So to make the button only respond if it is visible
    function func(self,event)
      if self:isVisible() and self:hitTestPoint(event.x,event.y) then
      -- do something
      end
    end
    which is only slightly more verbose than the first one. You could even define your own hitTestPoint function which does this in one go.

    This however raises the question of whether children of invisible parents are themselves invisible according to the isVisible function...?

    Likes: matty47

    +1 -1 (+1 / -0 )Share on Facebook
  • @MauMau, how about using this bit of code
     function setVisible(theObject, visibility)
       -- First make the main object visible as per visibility
       theObject:setVisibile(visibility)
     
       -- Now iterate through the children and change their visibility
       for i = 1, theObject:getNumChildren() do
         tChild = theObject:getChildAt(i)
         -- recursively set the children's children too (if any)
         tChild:setVisible(visibility)
       end
     end
    and if you are using the visibility chcek in the touch events, like suggested earlier and shown in code above by @John26 then you should be able to avoid that issue.
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
Sign In or Register to comment.