Pinch Zoom Lag

Hi dyson,

Device testing using Samsung Tab 3, Motoroal Razr HD, I notice my pinch zoom is laggy.  Is there anything I can do to remove any of the lag?

Thanks, Greg

Quickly zooming in or out can necessitate the spawning or culling of a very large number of tiles, which can slow things down quite a bit. There’s no way to get around the demands of creating or removing that much of the map as such, but something you could do is modify the touchScrollPinchZoom code to put a limit on how quickly the scale changes, so only a limited number of tiles will spawn/cull at a time. 

Add this parameter near the rest of MTE’s variables around line 100:

M.maxPinchZoomDelta = 0.025

Insert the following code immediately after line 278:

if math.abs(newScaleX - masterGroup.xScale) \> M.maxPinchZoomDelta then if newScaleX \> masterGroup.xScale then newScaleX = masterGroup.xScale + M.maxPinchZoomDelta elseif newScaleX \< masterGroup.xScale then newScaleX = masterGroup.xScale - M.maxPinchZoomDelta end end if math.abs(newScaleY - masterGroup.yScale) \> M.maxPinchZoomDelta then if newScaleY \> masterGroup.yScale then newScaleY = masterGroup.yScale + M.maxPinchZoomDelta elseif newScaleY \< masterGroup.yScale then newScaleY = masterGroup.yScale - M.maxPinchZoomDelta end end

The code block should now look like this:

if ( dx and dy ) then if pinchZoom then local newDistance = math.sqrt( dx\*dx + dy\*dy ) local scale = newDistance / masterGroup.distance --print( "newDistance(" ..newDistance .. ") / distance(" .. masterGroup.distance .. ") = scale(".. scale ..")" ) if ( scale \> 0 ) then local newScaleX = masterGroup.xScaleOriginal \* scale local newScaleY = masterGroup.yScaleOriginal \* scale if newScaleX \< M.minZoom then newScaleX = M.minZoom elseif newScaleX \> M.maxZoom then newScaleX = M.maxZoom end if newScaleY \< M.minZoom then newScaleY = M.minZoom elseif newScaleY \> M.maxZoom then newScaleY = M.maxZoom end if math.abs(newScaleX - masterGroup.xScale) \> M.maxPinchZoomDelta then if newScaleX \> masterGroup.xScale then newScaleX = masterGroup.xScale + M.maxPinchZoomDelta elseif newScaleX \< masterGroup.xScale then newScaleX = masterGroup.xScale - M.maxPinchZoomDelta end end if math.abs(newScaleY - masterGroup.yScale) \> M.maxPinchZoomDelta then if newScaleY \> masterGroup.yScale then newScaleY = masterGroup.yScale + M.maxPinchZoomDelta elseif newScaleY \< masterGroup.yScale then newScaleY = masterGroup.yScale - M.maxPinchZoomDelta end end masterGroup.xScale = newScaleX masterGroup.yScale = newScaleY end end end

You’ll be able to set how quickly the map zoom changes by changing the maxPinchZoomDelta parameter. This will only effect pinchZoom, not mte.zoom(). 

My map is 128x128 (32pixel tiles) .  I’m pinch zooming slowly and have to stop and let the devices catch up.  Thanks for the hint, I’ll report back.

That’s better, but still some lag… could it be related to the number of sprites? (I have about 200 on the map)

Thanks, Greg

Oh yes, 200 sprites is a good many sprites to be running simultaneously. Ultimately the hardware will only do so much, and the Galaxy Tab 3 is not a high-performance tablet. You might want to investigate whether you really need all those sprites. For example, you could spawn sprites only as you need them and remove them when they move far offscreen.

Quickly zooming in or out can necessitate the spawning or culling of a very large number of tiles, which can slow things down quite a bit. There’s no way to get around the demands of creating or removing that much of the map as such, but something you could do is modify the touchScrollPinchZoom code to put a limit on how quickly the scale changes, so only a limited number of tiles will spawn/cull at a time. 

Add this parameter near the rest of MTE’s variables around line 100:

M.maxPinchZoomDelta = 0.025

Insert the following code immediately after line 278:

if math.abs(newScaleX - masterGroup.xScale) \> M.maxPinchZoomDelta then if newScaleX \> masterGroup.xScale then newScaleX = masterGroup.xScale + M.maxPinchZoomDelta elseif newScaleX \< masterGroup.xScale then newScaleX = masterGroup.xScale - M.maxPinchZoomDelta end end if math.abs(newScaleY - masterGroup.yScale) \> M.maxPinchZoomDelta then if newScaleY \> masterGroup.yScale then newScaleY = masterGroup.yScale + M.maxPinchZoomDelta elseif newScaleY \< masterGroup.yScale then newScaleY = masterGroup.yScale - M.maxPinchZoomDelta end end

The code block should now look like this:

if ( dx and dy ) then if pinchZoom then local newDistance = math.sqrt( dx\*dx + dy\*dy ) local scale = newDistance / masterGroup.distance --print( "newDistance(" ..newDistance .. ") / distance(" .. masterGroup.distance .. ") = scale(".. scale ..")" ) if ( scale \> 0 ) then local newScaleX = masterGroup.xScaleOriginal \* scale local newScaleY = masterGroup.yScaleOriginal \* scale if newScaleX \< M.minZoom then newScaleX = M.minZoom elseif newScaleX \> M.maxZoom then newScaleX = M.maxZoom end if newScaleY \< M.minZoom then newScaleY = M.minZoom elseif newScaleY \> M.maxZoom then newScaleY = M.maxZoom end if math.abs(newScaleX - masterGroup.xScale) \> M.maxPinchZoomDelta then if newScaleX \> masterGroup.xScale then newScaleX = masterGroup.xScale + M.maxPinchZoomDelta elseif newScaleX \< masterGroup.xScale then newScaleX = masterGroup.xScale - M.maxPinchZoomDelta end end if math.abs(newScaleY - masterGroup.yScale) \> M.maxPinchZoomDelta then if newScaleY \> masterGroup.yScale then newScaleY = masterGroup.yScale + M.maxPinchZoomDelta elseif newScaleY \< masterGroup.yScale then newScaleY = masterGroup.yScale - M.maxPinchZoomDelta end end masterGroup.xScale = newScaleX masterGroup.yScale = newScaleY end end end

You’ll be able to set how quickly the map zoom changes by changing the maxPinchZoomDelta parameter. This will only effect pinchZoom, not mte.zoom(). 

My map is 128x128 (32pixel tiles) .  I’m pinch zooming slowly and have to stop and let the devices catch up.  Thanks for the hint, I’ll report back.

That’s better, but still some lag… could it be related to the number of sprites? (I have about 200 on the map)

Thanks, Greg

Oh yes, 200 sprites is a good many sprites to be running simultaneously. Ultimately the hardware will only do so much, and the Galaxy Tab 3 is not a high-performance tablet. You might want to investigate whether you really need all those sprites. For example, you could spawn sprites only as you need them and remove them when they move far offscreen.