Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

touch propagation?

edited July 2013 in Questions Posts: 502

Assume I have two overlapping shapes. The upper one receives a touch event, but the second, underneath, receives it also. How can I stop such touch propagation to objects that are beneath others?

Tagged:

Comments

  • edited July 2013 Posts: 391

    When assigning the shapes their position, use vec3 so that you can then utilize z to determine which is on top. Then have it select the one with the higher z value.

    I think you will have to let both the touched functions be called, but you could add a test at the beginning that only allows the rest of the code to be read if it succeeds. Store the touches in a table and then compare them in each touched function of the shapes. Only continue on the highest z.

  • edited July 2013 Posts: 502

    This is a very uncommon / inconvenient solution for 2d, isn't it? I mean some frameworks do it much easier, by just returning false inside the touch event listener. Could this be done similarly here? Something like:

    function touched(touch)
         --handle touches...
    
         return false --stops propagation to objects being covered by this one!
    end
    
  • Posts: 391

    Yep, simply having it return will stop it early.

    I'm sure there is a better solution, best I could come up with quickly though, lol. Maybe a Codea pro will provide the correct solution soon.

  • Posts: 502

    I hope so, because returning doesn't help here... unless I'm doing it wrong?.

  • Posts: 175

    @se24vad, if you hook up touched to an event with my events framework AppEvents you can stop the propagation of the event from within its handlers. Take a look, I hope it helps :)
    http://twolivesleft.com/Codea/Talk/discussion/2966/appevents-an-easy-to-use-events-framework/p1

  • The solution of return boolean is that i use in my menu library

    On the other hand, all object know if the focus have already catched by an other object.

    function touched(touch)
        local focusCatched = false
        for _, v in pairs(arrayOfObject) do -- arrayOfObject is ordered by "z-index"
            focusCatched = v:touched(touch, focusCatched)
        end
    end
  • Posts: 2,161

    This is where a touch handler comes in handy. Mine works as follows:

    1. The touch handler gathers all of the touches to itself.
    2. It also has a list of objects that can accept touches.
    3. When it gets a new touch (touch.state == BEGAN) then it queries its objects one by one asking "Were you touched?". The first one to answer "yes" is assigned the touch.
    4. When it gets an old touch, it knows which object it is assigned to so it sends it to that object. In fact, it gathers all of the touches assigned to that object together and sends them en masse. This makes it easier for objects to handle multiple touches, and also deal with touches that are still active but haven't been updated on that particular round.
  • edited July 2013 Posts: 502

    @Andrew_Stacey So how to use your Touch class correctly? I tried, but it wont work

    --Main
    function setup()
         touches = Touches()
         example = exampleClass()
    end
    function draw()
         touches:draw()
         example:draw()
    end
    function touched(touch)
         example:touched(touch)
    end
    
    --exampleClass
    [...]
    function exampleClass:touched(touch)
         if touch.x > x and
              touch.x > x + width and
              touch.y > y and
              touch.y < y + height
         then
              touches:addTouch()
         end
    end
    
  • Posts: 2,161

    I put a tutorial up on my website at http://loopspace.mathforge.org/discussion/10/touch-tutorial. Loading it does depend slightly on how you get hold of my library as I've recently switched to toadkick's cmodule method. But if you get it from somewhere other than my library gists then the tutorial is valid, and once it is loaded then the rest of the tutorial still holds.

    What I would do in your code is:

    --Main
    function setup()
         touches = Touches()
         example = exampleClass()
         touches:pushHandler(example)
    end
    
    function draw()
         touches:draw()
         example:draw()
    end
    function touched(touch)
         touches:addTouch(touch)
    end
    
    --exampleClass
    [...]
    function exampleClass:isTouchedBy(touch)
         if touch.x > x and
              touch.x < x + width and
              touch.y > y and
              touch.y < y + height
         then
              return true
         end
         return false
    end
    
    function exampleClass:processTouches(g)
        -- do something with the touch data
    end
    

    I noticed that the line touch.x < x + width was originally touch.x > x + width which seemed the wrong logic so I changed it.

  • Posts: 502

    thank you ver much. I'll try

  • Jmv38Jmv38 Mod
    edited July 2013 Posts: 3,295

    If you want touch event not to propagate you have either to.
    -Manage the object order. I've done it in my new windows library (unshared) and it is really difficult if you want to make something general,
    Or
    -use @ignatz trick for 3d, that you can apply to 2d.

Sign In or Register to comment.