Code sequence fails

In code example I created three objects and if you touch combo of either 1 and 2 or 1 and 3 long enough and fast enough at some point code sequence fails, it messes up. One timer overruns other. For fast touch I used “fast clicker”.

So this is the simplest code example where I see code sequence fail. My original code is more complex and it fails by just touching manually on the phone screen.

This is incredible annoying problem. Before downloading “fast clicker” I used my fingers. :man_facepalming:

local state = "one"
local duration = 700

local show1
local hide1Show2
local hide2

local obj1 = display.newRect(150, 100, 200, 100)
local obj2 = display.newRect(50, 120, 100, 100)
local obj3 = display.newRect(250, 120, 100, 100)
obj1.alpha = 1
obj2.alpha = 0
obj3.alpha = 0

local function manageObj(event)
	if event.phase == "ended" then
		local obj = event.target
		local modeName = obj.name

		if state == "one" then
			state = "two"
			show1(obj1, obj2, manageObj)
		elseif state == "two" then 
			state = "three"
			hide1Show2(obj1, obj2, obj3, manageObj)
		elseif state == "three" then
			state = "one"
			hide2(obj1, obj3, manageObj)
		end

	end
	return true
end


obj1:addEventListener("touch", manageObj)
obj2:addEventListener("touch", manageObj)
obj3:addEventListener("touch", manageObj)



function show1(obj1, obj2, manageObj)
	obj1:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj1:addEventListener("touch", manageObj); end)
	
	obj2:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj2:addEventListener("touch", manageObj); end)
	transition.to(obj2, {time = duration, alpha = 1})
end


function hide1Show2(obj1, obj2, obj3, manageObj)
	obj1:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj1:addEventListener("touch", manageObj); end)

	obj2:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj2:addEventListener("touch", manageObj); end)
	transition.to(obj2, {time = duration, alpha = 0})

	obj3:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj3:addEventListener("touch", manageObj); end)
	transition.to(obj3, {time = duration, alpha = 1})
end


function hide2(obj1, obj3, manageObj)
	obj1:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj1:addEventListener("touch", manageObj); end)

	obj3:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj3:addEventListener("touch", manageObj); end)
	transition.to(obj3, {time = duration, alpha = 0})
end

Not sure whether it would help, but if what you’re trying to accomplish is time sensitive then I would not change the ‘state’ value until the timer is completed.

Your touch function would look like so:

local function manageObj(event)
	if event.phase == "ended" then
		local obj = event.target
		local modeName = obj.name

		if state == "one" then
			show1(obj1, obj2, manageObj)
		elseif state == "two" then 
			hide1Show2(obj1, obj2, obj3, manageObj)
		elseif state == "three" then
			hide2(obj1, obj3, manageObj)
		end
	end
	return true
end

and on your function calls to toggle the objects you would do:

function show1(obj1, obj2, manageObj)
	obj1:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj1:addEventListener("touch", manageObj); end)
	
	obj2:removeEventListener("touch", manageObj)
	timer.performWithDelay(duration, function() obj2:addEventListener("touch", manageObj); end)
	transition.to(obj2, {time = duration, alpha = 1, onComplete=function() state = "two" end})
end

Notice the ‘state’ value is changed on the onComplete of the transition.

EDIT:
And another alternative way:

function show1(obj1, obj2, manageObj)
	obj1:removeEventListener("touch", manageObj)
	obj2:removeEventListener("touch", manageObj)
	
	timer.performWithDelay(duration, function() 
		obj1:addEventListener("touch", manageObj)
		obj2:addEventListener("touch", manageObj)
		state = "two" 
	end)

	transition.to(obj2, {time = duration, alpha = 1})
end
1 Like

First removing all event listeners and then adding them back with one timer did the work. I somehow had false understanding that timers that starts in the same block with the same time duration ends in the one and same block, so they become active at the same time. It was convenient to think so because I had a lot of tables with groups and group childrens that I was working with and code was more compact this way. But now, I have even more compact code.

I was working on this problem for two long days, I even thought I have tried option you showed me. It’s incredible how deep rabbit hole sometimes can be. Thanks for showing me the right way.

You’re very welcome!
Glad that’s working for you, even if it took 2 days. :slightly_smiling_face:

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