Preventing Touch/Tap Propogation through Display Objects

I’ve nearly finished building the classic Minesweeper game.
the board in the screenshot is 10x10 tiles - level easy/smallest board size.
But I’ve boards that go as large as 50x50 tiles. These boards are then too large for the screen, so the boards are draggable, allowing the player to move them about to access all parts of the board.

You can see the top 1/3 of the screen is the games controls, timer, home button etc.
When a large board is dragged, so you can see its bottom edge, the top of the board then passes behind the control panel. The board is in a middle layer/group foreground. The control panel and its background/group are in the upper layer/group user interface.

The problem is, any tap or touch action, that takes place in that control panel area of the screen, propagates the tap/touch through all display objects and the board tiles underneath react, despite not being able to see them.

I essentially want to prevent tap/touch propagation through the control panel group, or its background display object, whilst still allowing its own buttons to respond.

I’ve no clue how to do this.
The only guide I have found, talks about touch/tap propagation, when two buttons overlap and returning true to function calls. I’ve tried turning my control panel code into a function to be able to return true, and hopefully prevent propagation - but it failed.

Any strategy advice welcome.
There is no broken code, or a bug, its a development strategy I’m stuck with and need help with.

Sounds like you could use an invisible rectangle to catch and stop the propagation. It needs to sit between the control panel and the game board in terms of drawing order, and it can be positioned and sized the same as the control panel area.

Just set the ‘.isHitTestable’ property to true and return true in its touch/tap listener.

If the control panel area has it’s own background then you try to use that instead.

I’ve managed it, I don’t think the code is particularly elegant, so if you’ve advice, it is welcome.

    local function fakeListener()
        return true

    local function controlBackground()
        local mask = display.newImageRect( grpGameControls, "Images/controlPanelMask.png", 500, 250 )
        mask.x = display.contentCenterX
        mask.y = gameLogo.y + 205
        mask.isVisible = false
        mask.isHitTestable = true
        mask:addEventListener("tap", fakeListener)
        local imgGameControlsBG = display.newRect( grpGameControls, display.contentCenterX, gameLogo.y + 205, 500, 250 )
        imgGameControlsBG.strokeWidth = 1
        imgGameControlsBG:setFillColor( unpack(modColor.ZetaDarkBlueGrey) )
        imgGameControlsBG:setStrokeColor( 0, 0, 0 )
**strong text**

I’m not really sure i understand what the problem is

In General, if objects are over each other, one way to stop them from responding to tap or touch is by hiding them

so if button 3 as in the attached image is above buttons 2 and 1, then if only 3 is visible or alpha =1 and buttons 2 and 1 has alpha set to 0 then they will not respond to tap

and after tapping button 3, you can set alpha of button 3 to 0 and alpha of either button 1 or 2 to 1

Sorry if my answer seems funny, but this is what i understood

@kakula , yes, hiding them would be one way and it wouldn’t be a problem as-is (in the OP’s scenario) with just returning true when a button in the control panel is touched. However, as I understood, the issue is trying to avoid touch events on the game board when any part of the control panel area is touched while a portion of the game board is underneath, especially when the location of the tap/touch is not on one of the buttons.

@AngelaMcCall , that looks fine. If the mask is meant to be visible then no need to set mask.isHitTestable = true; this is only used when the object is fully transparent or not visible and we’d still want tap/touch to be triggered.

If by any chance the gameboard uses a touch listener instead of a tap listener then you’ll also need to match the type of listener on the mask object.

You could also just add a touch listener directly to imgGameControlsBG:

imgGameControlsBG:addEventListener( "touch", fakeListener )

That’s what I do in situations where I’ve got menus popping over the game board. I like it because it doesn’t require adding invisible objects or masks.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.