MTE Capturing Touch events outside of map display area

Hi dyson,

My map is in a container that takes up the left half of the screen in landscape.No matter where I touch the screen on the right half, I am getting a tap event.  Am I doing something wrong with my map setup?

mte.setScreenBounds(display.contentWidth / -3, display.contentHeight/-2, display.contentWidth/3, display.contentHeight / 2)

    local mapObj = mte.getMapObj()
    newGroup1 = display.newContainer(display.contentWidth *.6, display.contentHeight*.88)
    newGroup1.x =display.contentWidth / 3.5
    newGroup1.y = display.contentHeight / 2.2
    newGroup1:insert(mapObj)
 

Runtime:addEventListener(“tap”, mtemove)

*** Ok, I solved the problem with:

mapObj = mte.getMapObj()

mapObj:addEventListener(“tap”, mtemove)

Thanks, Greg

Almost in the clear,

if I use a touch listener to move my player to a point on the map, it interferes with the map scroll touch (they both happen).  Is there any way to keep these events separate?

Thanks, Greg

Are you using your own map scroll event? If so can you post both your map scroll event and your player move event here? The solution depends entirely on how you’re handling your events and the gameplay mechanics. If you’re touching and dragging your player sprite it may be as simple as adding ‘true’ to the end of the player’s touch event. In other cases you may have to use another flag to keep track of what you’re using touch for at any given moment.

I am currently using the built in touch scroll.

    mte.enableTouchScroll()
    mte.enablePinchZoom()

and for player moves: newGroup1:addEventListener(“tap”, mtemove)

if I setup my player using Tap, I can move to a spot on the map without interfering with the touch events.

if I use Touch for my player, the touchscroll and move player touch event bother get executed.

the problem I am having is that I can’t use tap because of other issues, I need to use touch.

Apologies, I meant that I needed to see the event listener function mtemove. How do you determine whether a touch is meant to move the player instead of the map? Does the user touch the player sprite first and then touch a destination, or is the user touching where the sprite is and dragging, or something to that effect?

Hi dyson,

When you tap any tile of the map, the player tries to move there:

 mte.moveSpriteTo({sprite = player, levelPosX = px, levelPosY = py, time =
1500, transition = easing.inOutSine, onComplete = mte.setCameraFocus(player),
})

The tap works great, it’s if I try to use a touch event the events  gets confused between moveto / scroll map.

Thanks, Greg

Part of the problem is that you aren’t programmatically determining which you want to do. If you touch a place on the screen with no other input, the app has no way to decide on it’s own which to run. If you assigned the touch events to different objects you could intercept the touch in one by returning true- but again, without any way to tell what the user is trying to do, all you’ll end up doing is forever disabling one of the two actions. 

In this situation the touchScroll routine is always going to run, but you can use timers to decide whether the user is moving the character or moving the camera. A tap is just a really short touch. 

local timer local tap = function(event) if event.phase == "began" then timer = system.getTimer() elseif event.phase == "ended" then local time = system.getTimer() - timer if time \< 100 then print("tap") --move the player else print("touch") --do nothing end end end mapObj:addEventListener("touch", tap)

You may have to fiddle with the time threshold a little. I chose 100 ms because it was a nice round, short number.

That just leaves the touchScroll code to take care of. The same basic principle applies; we want the touchScroll routine to ignore a short touch and obey a long touch. You’ll have to make a small modification to mte.lua:

Go to line 190, just above “local touchScrollPinchZoom = function(event)” and add:

local timer

Go to line 204 or so. It should read “if “began” == phase then” 

Beneath it, add:

timer = system.getTimer()

Go to line 8975, the update2 function. You’ll see this code block:

if touchScroll[1] and touchScroll[6] then local velX = (touchScroll[2] - touchScroll[4]) / masterGroup.xScale local velY = (touchScroll[3] - touchScroll[5]) / masterGroup.yScale --print(velX, velY) M.moveCamera(velX, velY) touchScroll[2] = touchScroll[4] touchScroll[3] = touchScroll[5] end 

Replace it with this:

if touchScroll[1] and touchScroll[6] then local velX = (touchScroll[2] - touchScroll[4]) / masterGroup.xScale local velY = (touchScroll[3] - touchScroll[5]) / masterGroup.yScale local time = system.getTimer() - timer if time \>= 100 then --print(velX, velY) M.moveCamera(velX, velY) end touchScroll[2] = touchScroll[4] touchScroll[3] = touchScroll[5] end 

Now the camera won’t move unless the touch lasts longer than 100 ms. The touchScroll event will still fire, it just won’t do anything. You may have to modify the code here and there to your need, by changing the threshold time for example, or making it so that a second touch on the screen doesn’t reset the timer, but this is a good starting point.

Almost in the clear,

if I use a touch listener to move my player to a point on the map, it interferes with the map scroll touch (they both happen).  Is there any way to keep these events separate?

Thanks, Greg

Are you using your own map scroll event? If so can you post both your map scroll event and your player move event here? The solution depends entirely on how you’re handling your events and the gameplay mechanics. If you’re touching and dragging your player sprite it may be as simple as adding ‘true’ to the end of the player’s touch event. In other cases you may have to use another flag to keep track of what you’re using touch for at any given moment.

I am currently using the built in touch scroll.

    mte.enableTouchScroll()
    mte.enablePinchZoom()

and for player moves: newGroup1:addEventListener(“tap”, mtemove)

if I setup my player using Tap, I can move to a spot on the map without interfering with the touch events.

if I use Touch for my player, the touchscroll and move player touch event bother get executed.

the problem I am having is that I can’t use tap because of other issues, I need to use touch.

Apologies, I meant that I needed to see the event listener function mtemove. How do you determine whether a touch is meant to move the player instead of the map? Does the user touch the player sprite first and then touch a destination, or is the user touching where the sprite is and dragging, or something to that effect?

Hi dyson,

When you tap any tile of the map, the player tries to move there:

 mte.moveSpriteTo({sprite = player, levelPosX = px, levelPosY = py, time =
1500, transition = easing.inOutSine, onComplete = mte.setCameraFocus(player),
})

The tap works great, it’s if I try to use a touch event the events  gets confused between moveto / scroll map.

Thanks, Greg

Part of the problem is that you aren’t programmatically determining which you want to do. If you touch a place on the screen with no other input, the app has no way to decide on it’s own which to run. If you assigned the touch events to different objects you could intercept the touch in one by returning true- but again, without any way to tell what the user is trying to do, all you’ll end up doing is forever disabling one of the two actions. 

In this situation the touchScroll routine is always going to run, but you can use timers to decide whether the user is moving the character or moving the camera. A tap is just a really short touch. 

local timer local tap = function(event) if event.phase == "began" then timer = system.getTimer() elseif event.phase == "ended" then local time = system.getTimer() - timer if time \< 100 then print("tap") --move the player else print("touch") --do nothing end end end mapObj:addEventListener("touch", tap)

You may have to fiddle with the time threshold a little. I chose 100 ms because it was a nice round, short number.

That just leaves the touchScroll code to take care of. The same basic principle applies; we want the touchScroll routine to ignore a short touch and obey a long touch. You’ll have to make a small modification to mte.lua:

Go to line 190, just above “local touchScrollPinchZoom = function(event)” and add:

local timer

Go to line 204 or so. It should read “if “began” == phase then” 

Beneath it, add:

timer = system.getTimer()

Go to line 8975, the update2 function. You’ll see this code block:

if touchScroll[1] and touchScroll[6] then local velX = (touchScroll[2] - touchScroll[4]) / masterGroup.xScale local velY = (touchScroll[3] - touchScroll[5]) / masterGroup.yScale --print(velX, velY) M.moveCamera(velX, velY) touchScroll[2] = touchScroll[4] touchScroll[3] = touchScroll[5] end 

Replace it with this:

if touchScroll[1] and touchScroll[6] then local velX = (touchScroll[2] - touchScroll[4]) / masterGroup.xScale local velY = (touchScroll[3] - touchScroll[5]) / masterGroup.yScale local time = system.getTimer() - timer if time \>= 100 then --print(velX, velY) M.moveCamera(velX, velY) end touchScroll[2] = touchScroll[4] touchScroll[3] = touchScroll[5] end 

Now the camera won’t move unless the touch lasts longer than 100 ms. The touchScroll event will still fire, it just won’t do anything. You may have to modify the code here and there to your need, by changing the threshold time for example, or making it so that a second touch on the screen doesn’t reset the timer, but this is a good starting point.