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?
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.
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
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.
I hope so, because returning doesn’t help here… unless I’m doing it wrong?.
@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
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 ```
This is where a touch handler comes in handy. Mine works as follows:
- The touch handler gathers all of the touches to itself.
- It also has a list of objects that can accept touches.
- 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.
- 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.
@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
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.
thank you ver much. I’ll try
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,
-use @ignatz trick for 3d, that you can apply to 2d.