Inneractive ads preventing secondary touchscreen events vertically below them
I have some code that controls swiping and zooming within a game.
One finger swipes, more than 1 finger zooms (based although heavily revised on some sample code I found here - thanks to whoever!).
Today it the zooming mostly broke, and after about 4 hours of testing code, I decided to switch off ads, and it worked!
Then, after that, I re-enabled ads and realised what was happening.
The game is for iPad, and I use the banner ad, placing it in the top right of the screen.
It appears that if both fingers touch the screen directly below the ad, only one will ever register.
If I have one or more of the events triggering anywhere to the left of the left edge of the ad, it works fine.
Here is some code so you can get a general idea of the zoom / scroll code:
[code]--------------------------------------------------------------
– CONTROLS --------------------------------------------------
function touchRect:touch( event ) – The touch event listener for the hidden rectangle that processes scrolling and zooming interaction
– Can only trigger once per frame
touchFrame = gameFrame
– Can’t move or scroll while not in the ‘game’ section or while aiming the weapon
if gameMode.mode ~= “game” then return false; end
if gameMode.sub == “aiming” then return false ; end
– Are we changing the view, or dealing with a weapon’s secondary attack mode?
local phase = event.phase
if gameMode.sub == “follow_secondary” then
if “began” == phase then
gameMode.sub = “follow”
local weapons = weapons.slots[gameMode.throwing]
for i, v in ipairs(weapons) do
if v.effect ~= false then weaponEffect(v, event.x, event.y) ; end
end
end
else
local previousTouches = self.previousTouches
local numTotalTouches = 1
if previousTouches ~= nil then
– add in total from previousTouches, subtract one if event is already in the array
numTotalTouches = numTotalTouches + self.numPreviousTouches
if previousTouches[event.id] then numTotalTouches = numTotalTouches - 1 ; end
end
if “ended” == phase or “cancelled” == phase then
numTotalTouches = numTotalTouches - 1
else
cam.mode = “free”
gameMode.sub = “view”
end
if “began” == phase then
– Very first “began” event
if ( not self.isFocus ) then
– Subsequent touch events will target button even if they are outside the contentBounds of button
display.getCurrentStage():setFocus( self )
self.isFocus = true
previousTouches = {}
self.previousTouches = previousTouches
self.numPreviousTouches = 0
– Store values for scrolling
self.viewX = cam.real.x
self.viewY = cam.real.y
self.startX = event.x
self.startY = event.y
self.counter = gameFrame
self.prevX = {{gameFrame, cam.real.x}}
– This bit sets the start distance between touches, if it hasn’t already been set
– IE on the second or higher touch
elseif self.distance == nil then
local dx,dy
if previousTouches and ( numTotalTouches ) >= 2 then
dx,dy = calculateDelta( previousTouches, event )
end
– initialize to distance between two touches
if ( dx and dy ) then
local d = math.sqrt( dx*dx + dy*dy )
if ( d > 0 ) then
self.distance = d
self.oldZoom = cam.view.zoom – Note I use VIEW zoom here, starting from what can be seen
end
end
end
if previousTouches[event.id] == nil then self.numPreviousTouches = self.numPreviousTouches + 1 ; end
previousTouches[event.id] = event
elseif self.isFocus then
if “moved” == phase then
– Scroll if just one
if numTotalTouches == 1 then
local dX = (event.x - self.startX) / cam.real.zoom / inludo_ui.deviceScale()
cam.real.x = self.viewX - dX
– Store up to a certain number of steps, but only if the frames are different - no idea why they wouldn’t be, but…
if self.prevX[#self.prevX][1] < gameFrame then
if #self.prevX > 5 then table.remove(self.prevX, 1) ; end
table.insert(self.prevX, {gameFrame, cam.real.x})
end
elseif self.distance ~= nil then
local dx,dy
if previousTouches and ( numTotalTouches ) >= 2 then
dx,dy = calculateDelta( previousTouches, event )
end
if ( dx and dy ) then
local newDistance = math.sqrt( dx*dx + dy*dy )
local scale = newDistance / self.distance
if ( scale > 0 ) then
cam.real.zoom = self.oldZoom * scale
end
end
end
– Store this new event, although it should already be in the list - I guess this is some sort of double checking?
if not previousTouches[event.id] then
self.numPreviousTouches = self.numPreviousTouches + 1
end
previousTouches[event.id] = event
elseif “ended” == phase or “cancelled” == phase then
if previousTouches[event.id] then
self.numPreviousTouches = self.numPreviousTouches - 1
previousTouches[event.id] = nil
end
– Only one touch left means you stop zooming and revert to scrolling
– None left means you lifted the last finger
if self.numPreviousTouches == 1 then
self.distance = nil
elseif self.numPreviousTouches == 0 then
– previousTouches is empty so no more fingers are touching the screen
– Allow touch events to be sent normally to the objects they “hit”
display.getCurrentStage():setFocus( nil )
gameMode.sub = false
– Used to determine swipe - note if there was no movement for a few frames then it treats it as doing nothing
local dX = (event.x - self.startX) / cam.view.zoom / inludo_ui.deviceScale()
local speed = 0
local samples = #self.prevX
if samples > 1 then
if self.prevX[samples][1] > gameFrame - 15 then
local dT, dX
for i = 2,samples,1 do
dT = self.prevX[i][1] - self.prevX[i - 1][1]
dX = self.prevX[i][2] - self.prevX[i - 1][2]
speed = speed + dX / dT
end
speed = mathAbs(speed / (self.prevX[samples][1] - self.prevX[1][1]))
end
end
self.isFocus = false
self.distance = nil
self.oldZoom = nil
self.viewX = nil
self.viewY = nil
self.startX = nil
self.startY = nil
self.prevX = nil
– reset array
self.previousTouches = nil
self.numPreviousTouches = nil
– Make camera go to nearest area, or if it was a swipe…
local minSpeed = 5
if speed >= minSpeed then
if dX > 0 then levelGoToArea(cam.limits.left.area, speed, false)
else levelGoToArea(cam.limits.right.area, speed, false) ; end
else
levelGoToArea( levelNearestArea(), minSpeed, false )
end
end
end
end
end
– Event was processed
return true
end
[/code] [import]uid: 46639 topic_id: 19308 reply_id: 319308[/import]