I’m having a problem using touch events to collect squares in a grid. The idea is the player drags their finger over squares in a grid, each square has a touch listener attached to it (table listener). On every “moved” phase the code will check the square it is over and highlight it if it’s not.
This works fine for most of the time. Although we encountered some problems early on where the player would drag their finger fast in one direction and the code would miss a square or two. We found out that the touch event “moved” wasn’t updating fast enough to “land” on those squares.
So we came up with a function that would calculate the direction the drag is going, knowing the direction the code will back check the square in the opposite direction and make sure it’s highlighted, then repeat as necessary. This fixed our issue dramatically. Untill we started experiencing the problem when the player would drag around corners. But with simply tweaking the back checking code we managed to fix that aswell, at least we thought we did.
The problem now stems down to that the ‘back checking’ function is only operable if it knows which direction the player is dragging in. We attached an example image to illustrate this issue.
As the player starts his drag downwards each square is being highlighted via the touch “moved” phase (blue dots), also the angle between each phase is being calculated in reference to the x-axis to determine the direction( [lua] if angle > 45 and angle <= 135 then direction = “down” end[/lua] ). So the ‘back check’ function will trigger every time a square is highlighted, then using the direction will check the previous square (in this case the square above). Now if the players finger went along the path that covers ‘B’ along the dotted yellow line, and the drag was fast, the touch event may not register until they reach the ‘end’ square. So in this case the angle between the current “moved” phase and the last “moved” phase would create a roughly 130Deg angle, which the code will mark as “down”, causing the ‘back check’ code to check the square above, which would be ‘A’ not ‘B’, causing ‘B’ to remain unhighlighted.
I may add, we attempted to cancel touches when the angle was close to a 45 degree, although this caused issues elsewhere in the game where 50% of other legit drags create a 45 degree angle. Also, we don’t want diagonal drag collecting in the game, only the squares immediately next to each other.
So at this point we are wondering if there’s any other ways to go about collecting squares in a grid, other than using a touch listener. Or perhaps we are just implementing this all wrong.
Any help will be greatly appreciated!
P.S. Here’s some code
And we are running this game at 60 FPS.
[lua]
local function getDirection( angle )
if angle > 45 and angle <= 135 then
var.direction = “down”
elseif angle > 135 and angle <= 225 then
var.direction = “left”
elseif angle > 225 and angle < 315 then
var.direction = “up”
elseif angle >= 315 and angle <= 360 or angle >= 0 and angle <= 45 then
var.direction = “right”
end
end
local function cornerFix(check, gridPlace, checkBorder, squareID)
if squares[check].alpha >= 0.9 and checkBorder <= 8 and checkBorder >= 1 and squares[check].id == squareID then
squares[check].alpha = 0.6
if var.direction == “up” then
cornerFix(check, gridPlace, var.checkP, squares[check+1].id)
elseif var.direction == “down” then
cornerFix(check, gridPlace, var.checkP, squares[check+1].id)
elseif var.direction == “left” then
cornerFix(check, gridPlace, var.checkP, squares[check-7].id)
elseif var.direction == “right” then
cornerFix(check, gridPlace, var.checkP, squares[check+7].id)
end
end
end
local function fixSelect(place, gridPlace)
if var.direction == “up” then --up
local check = place+7
if check >= 1 and check <= 49 then
if squares[check].gridPlace[1] <= gridPlace[1] and gridPlace[1] ~= 0 then
var.checkI = squares[check].gridPlace[1]
var.checkI = var.checkI + 1
if squares[check].alpha >= 0.9 and var.checkI <= 8 and squares[check].id == squares[check-7].id then
squares[check].alpha = 0.6
if squares[check].gridPlace[1] == gridPlace[1] then
if squares[check].gridPlace[2] < gridPlace[2] then
check = check + 1
cornerFix(check, gridPlace, var.checkP, squares[check+1].id)
elseif squares[check].gridPlace[2] > gridPlace[2] then
check = check - 1
cornerFix(check, gridPlace, var.checkP, squares[check+1].id)
end
end
fixSelect( check, gridPlace) --check again
end
end
end
elseif var.direction == “down” then – down
local check = place-7
if check >= 1 and check <= 49 then
if squares[check].gridPlace[1] >= gridPlace[1] and gridPlace[1] ~= 0 then
var.checkI = squares[check].gridPlace[1]
var.checkI = var.checkI - 1
if squares[check].alpha >= 0.9 and var.checkI >= 0 and squares[check].id == squares[check+7].id then
squares[check].alpha = 0.6
if squares[check].gridPlace[1] == gridPlace[1] then
if squares[check].gridPlace[2] < gridPlace[2] then
check = check + 1
cornerFix(check, gridPlace, var.checkP, squares[check+1].id)
elseif squares[check].gridPlace[2] > gridPlace[2] then
check = check - 1
cornerFix(check, gridPlace, var.checkP, squares[check+1].id)
end
end
fixSelect( check, gridPlace) --check again
end
end
end
elseif var.direction == “left” then --left
local check = place+1
if check >= 1 and check <= 49 then
if squares[check].gridPlace[2] <= gridPlace[2] and gridPlace[1] ~= 0 then
var.checkP = squares[check].gridPlace[2]
var.checkP = var.checkP + 1
if squares[check].alpha >= 0.9 and var.checkP <= 8 and squares[check].id == squares[check-1].id then
squares[check].alpha = 0.6
if squares[check].gridPlace[2] == gridPlace[2] then
if squares[check].gridPlace[1] < gridPlace[1] then
check = check + 7
cornerFix(check, gridPlace, var.checkP, squares[check-7].id)
elseif squares[check].gridPlace[1] > gridPlace[1] then
check = check - 7
cornerFix(check, gridPlace, var.checkP, squares[check+7].id)
end
end
fixSelect( check, gridPlace) --check again
end
end
end
elseif var.direction == “right” then – right
local check = place-1
if check >= 1 and check <= 49 then
if squares[check].gridPlace[2] >= gridPlace[2] and gridPlace[1] ~= 0 then
var.checkP = squares[check].gridPlace[2]
var.checkP = var.checkP - 1
if squares[check].alpha >= 0.9 and var.checkP >= 0 and squares[check].id == squares[check+1].id then
squares[check].alpha = 0.6
if squares[check].gridPlace[2] == gridPlace[2] then
if squares[check].gridPlace[1] < gridPlace[1] then
check = check + 7
cornerFix(check, gridPlace, var.checkP, squares[check-7].id)
elseif squares[check].gridPlace[1] > gridPlace[1] then
check = check - 7
cornerFix(check, gridPlace, var.checkP, squares[check+7].id)
end
end
fixSelect( check, gridPlace) --check again
end
end
end
end
end
local function slideCollect( self, e)
if e.phase == “began” then
var.firstSquare = self
var.firstSquareid = self.id
var.curSquare = self
lastPlace[1] = self.gridPlace[1]; lastPlace[2] = self.gridPlace[2]
end
if e.phase == “moved” then
--------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------
if moveT.x[1] ~= nil then
local disY = e.y - moveT.y[1] --Calculate the distance between ‘moved’ phases
local disX = e.x - moveT.x[1]
if disX >= 3 or disX <= -3 then
local angle = atan2(disY, disX) * 180/pi
if angle < 0 then
angle = angle + 360
end
getDirection( angle )
elseif disY >= 3 or disY <= -3 then
local angle = atan2(disY, disX) * 180/pi
if angle < 0 then
angle = angle + 360
end
getDirection( angle )
end
end
moveT.x[1] = e.x; moveT.y[1] = e.y – store the ‘moved’ phase x and y
--------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------
if var.firstSquareid == self.id and self.state == “unlocked” then
--Highlight if colours match
if self.alpha > 0.6 and self ~= var.firstSquare then
if var.firstSquare.alpha > 0.6 then
var.firstSquare.alpha = 0.6
end
fixSelect(self.place, lastPlace)
lastPlace[1] = self.gridPlace[1]; lastPlace[2] = self.gridPlace[2]
self.alpha = 0.6
var.curSquare = self
end
end
--------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------
end
if e.phase == “ended” or e.phase == “stop” then
moveT.x[1] = nil; moveT.y[1] = nil
--Some code
end
return true
end
[/lua]
Thanks.