Trouble with transition.cancel

I want the user to be able to touch an object and have the character move to that object. If the user touches a different object, I want the first transition.to to be cancelled and the character to move to the new object. I have gotten this to work, but where my code breaks down is if the user touches an object twice, the transition.cancel doesn’t seem to work if you then touch the other object… the “onComplete” functions are still firing even though the character never satisfies the condition to make it happen (in this case end up at a certain x position).

Can anyone help explain to me why double-touching causes these problems?

Below is some plug and play code that demonstrates my issue (touch the lower left or right side of the screen to set character in motion):

[lua]
– main.lua


display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()
physics.setDrawMode( “hybrid” )

local ground = display.newRect( 0, 300, 480, 50 )
ground:setFillColor( 0, 255, 0 )
physics.addBody(ground, “static”, { density=1.0, friction=0.4, bounce=0})

local hero = display.newRect( 150, 300, 15, 50 )
hero:setFillColor( 255, 0, 0 )
physics.addBody(hero, “dynamic”, { density=1.0, friction=0.4, bounce=0})
hero.isFixedRotation = true

local forwardBtnPressed = false
local backBtnPressed = false

local function moveFunctionRight()
print(“right complete”)
end

local function moveFunctionLeft()
print(“left complete”)
end

function forwardBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDL then
transition.cancel(hero.transitionIDL)
print(“left move cancelled”)
end
local transitionTimeR = math.abs((400-hero.x)/.1)
hero.transitionIDR = transition.to(hero, {time=transitionTimeR, x = 400, onComplete=moveFunctionRight})
end
end

function backBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDR then
transition.cancel(hero.transitionIDR)
print(“right move cancelled”)
end
local transitionTimeL = math.abs((20-hero.x)/.1)
hero.transitionIDL = transition.to(hero, {time=transitionTimeL, x = 20, onComplete=moveFunctionLeft})
end
end

local forwardBtn = display.newRect(display.contentWidth/2,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
forwardBtn:setFillColor(0, 0)
local backBtn = display.newRect(0,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
backBtn:setFillColor(0, 0)

forwardBtn:addEventListener( “touch”, forwardBtnPressed )
backBtn:addEventListener(“touch”, backBtnPressed )
[/lua] [import]uid: 146966 topic_id: 36251 reply_id: 336251[/import]

Any takers? :slight_smile: [import]uid: 146966 topic_id: 36251 reply_id: 144618[/import]

I’m still don’t completely understand why the “onComplete” executes when I cancel the transition, but I figured out a work around. When you press a button, check to see if your transition ID is nil.

[lua]
– main.lua


display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()
physics.setDrawMode( “hybrid” )

local ground = display.newRect( 0, 300, 480, 50 )
ground:setFillColor( 0, 255, 0 )
physics.addBody(ground, “static”, { density=1.0, friction=0.4, bounce=0})

local hero = display.newRect( 150, 300, 15, 50 )
hero:setFillColor( 255, 0, 0 )
physics.addBody(hero, “dynamic”, { density=1.0, friction=0.4, bounce=0})
hero.isFixedRotation = true

local forwardBtnPressed = false
local backBtnPressed = false

local function moveFunctionRight()
print(“right complete”)
end

local function moveFunctionLeft()
print(“left complete”)
end

function forwardBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDR == nil then --Check to see if hero is already in motion here
if hero.transitionIDL then
transition.cancel(hero.transitionIDL)
hero.transitionIDL = nil
print(“left move cancelled”)
end
local transitionTimeR = math.abs((400-hero.x)/.1)
hero.transitionIDR = transition.to(hero, {time=transitionTimeR, x = 400, onComplete=moveFunctionRight})
end
end
end

function backBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDL == nil then --Check to see if hero is already in motion here
if hero.transitionIDR then
transition.cancel(hero.transitionIDR)
hero.transitionIDR = nil
print(“right move cancelled”)
end
local transitionTimeL = math.abs((20-hero.x)/.1)
hero.transitionIDL = transition.to(hero, {time=transitionTimeL, x = 20, onComplete=moveFunctionLeft})
end
end
end

local forwardBtn = display.newRect(display.contentWidth/2,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
forwardBtn:setFillColor(0, 0)
local backBtn = display.newRect(0,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
backBtn:setFillColor(0, 0)

forwardBtn:addEventListener( “touch”, forwardBtnPressed )
backBtn:addEventListener(“touch”, backBtnPressed )
[/lua] [import]uid: 146966 topic_id: 36251 reply_id: 144677[/import]

You say you were having problems when you touch an object twice. It looks like you just keep adding transitions of the same direction to the object because you never cancel the previous transition in that same direction; you cancel the transition in the other direction, but not the same direction. So perhaps, that is why you see these extra transition events.

No idea what is supposed to happen if you have two concurrent transitions trying to change the same property.

Since it seems you only need to keep track of one transition, maybe get rid of the .transitionIDR and .transitionIDL and just use one property?

Maybe. [import]uid: 94868 topic_id: 36251 reply_id: 144682[/import]

Thanks Screaming Leaf, I think the one thing I was getting tripped up on is that the onComplete fires when the hero.x == a given x value … watching the “character” on the screen, that never seemed to occur. [import]uid: 146966 topic_id: 36251 reply_id: 145016[/import]

Any takers? :slight_smile: [import]uid: 146966 topic_id: 36251 reply_id: 144618[/import]

I’m still don’t completely understand why the “onComplete” executes when I cancel the transition, but I figured out a work around. When you press a button, check to see if your transition ID is nil.

[lua]
– main.lua


display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()
physics.setDrawMode( “hybrid” )

local ground = display.newRect( 0, 300, 480, 50 )
ground:setFillColor( 0, 255, 0 )
physics.addBody(ground, “static”, { density=1.0, friction=0.4, bounce=0})

local hero = display.newRect( 150, 300, 15, 50 )
hero:setFillColor( 255, 0, 0 )
physics.addBody(hero, “dynamic”, { density=1.0, friction=0.4, bounce=0})
hero.isFixedRotation = true

local forwardBtnPressed = false
local backBtnPressed = false

local function moveFunctionRight()
print(“right complete”)
end

local function moveFunctionLeft()
print(“left complete”)
end

function forwardBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDR == nil then --Check to see if hero is already in motion here
if hero.transitionIDL then
transition.cancel(hero.transitionIDL)
hero.transitionIDL = nil
print(“left move cancelled”)
end
local transitionTimeR = math.abs((400-hero.x)/.1)
hero.transitionIDR = transition.to(hero, {time=transitionTimeR, x = 400, onComplete=moveFunctionRight})
end
end
end

function backBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDL == nil then --Check to see if hero is already in motion here
if hero.transitionIDR then
transition.cancel(hero.transitionIDR)
hero.transitionIDR = nil
print(“right move cancelled”)
end
local transitionTimeL = math.abs((20-hero.x)/.1)
hero.transitionIDL = transition.to(hero, {time=transitionTimeL, x = 20, onComplete=moveFunctionLeft})
end
end
end

local forwardBtn = display.newRect(display.contentWidth/2,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
forwardBtn:setFillColor(0, 0)
local backBtn = display.newRect(0,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
backBtn:setFillColor(0, 0)

forwardBtn:addEventListener( “touch”, forwardBtnPressed )
backBtn:addEventListener(“touch”, backBtnPressed )
[/lua] [import]uid: 146966 topic_id: 36251 reply_id: 144677[/import]

You say you were having problems when you touch an object twice. It looks like you just keep adding transitions of the same direction to the object because you never cancel the previous transition in that same direction; you cancel the transition in the other direction, but not the same direction. So perhaps, that is why you see these extra transition events.

No idea what is supposed to happen if you have two concurrent transitions trying to change the same property.

Since it seems you only need to keep track of one transition, maybe get rid of the .transitionIDR and .transitionIDL and just use one property?

Maybe. [import]uid: 94868 topic_id: 36251 reply_id: 144682[/import]

Thanks Screaming Leaf, I think the one thing I was getting tripped up on is that the onComplete fires when the hero.x == a given x value … watching the “character” on the screen, that never seemed to occur. [import]uid: 146966 topic_id: 36251 reply_id: 145016[/import]

Any takers? :slight_smile: [import]uid: 146966 topic_id: 36251 reply_id: 144618[/import]

I’m still don’t completely understand why the “onComplete” executes when I cancel the transition, but I figured out a work around. When you press a button, check to see if your transition ID is nil.

[lua]
– main.lua


display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()
physics.setDrawMode( “hybrid” )

local ground = display.newRect( 0, 300, 480, 50 )
ground:setFillColor( 0, 255, 0 )
physics.addBody(ground, “static”, { density=1.0, friction=0.4, bounce=0})

local hero = display.newRect( 150, 300, 15, 50 )
hero:setFillColor( 255, 0, 0 )
physics.addBody(hero, “dynamic”, { density=1.0, friction=0.4, bounce=0})
hero.isFixedRotation = true

local forwardBtnPressed = false
local backBtnPressed = false

local function moveFunctionRight()
print(“right complete”)
end

local function moveFunctionLeft()
print(“left complete”)
end

function forwardBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDR == nil then --Check to see if hero is already in motion here
if hero.transitionIDL then
transition.cancel(hero.transitionIDL)
hero.transitionIDL = nil
print(“left move cancelled”)
end
local transitionTimeR = math.abs((400-hero.x)/.1)
hero.transitionIDR = transition.to(hero, {time=transitionTimeR, x = 400, onComplete=moveFunctionRight})
end
end
end

function backBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDL == nil then --Check to see if hero is already in motion here
if hero.transitionIDR then
transition.cancel(hero.transitionIDR)
hero.transitionIDR = nil
print(“right move cancelled”)
end
local transitionTimeL = math.abs((20-hero.x)/.1)
hero.transitionIDL = transition.to(hero, {time=transitionTimeL, x = 20, onComplete=moveFunctionLeft})
end
end
end

local forwardBtn = display.newRect(display.contentWidth/2,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
forwardBtn:setFillColor(0, 0)
local backBtn = display.newRect(0,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
backBtn:setFillColor(0, 0)

forwardBtn:addEventListener( “touch”, forwardBtnPressed )
backBtn:addEventListener(“touch”, backBtnPressed )
[/lua] [import]uid: 146966 topic_id: 36251 reply_id: 144677[/import]

You say you were having problems when you touch an object twice. It looks like you just keep adding transitions of the same direction to the object because you never cancel the previous transition in that same direction; you cancel the transition in the other direction, but not the same direction. So perhaps, that is why you see these extra transition events.

No idea what is supposed to happen if you have two concurrent transitions trying to change the same property.

Since it seems you only need to keep track of one transition, maybe get rid of the .transitionIDR and .transitionIDL and just use one property?

Maybe. [import]uid: 94868 topic_id: 36251 reply_id: 144682[/import]

Thanks Screaming Leaf, I think the one thing I was getting tripped up on is that the onComplete fires when the hero.x == a given x value … watching the “character” on the screen, that never seemed to occur. [import]uid: 146966 topic_id: 36251 reply_id: 145016[/import]

Any takers? :slight_smile: [import]uid: 146966 topic_id: 36251 reply_id: 144618[/import]

I’m still don’t completely understand why the “onComplete” executes when I cancel the transition, but I figured out a work around. When you press a button, check to see if your transition ID is nil.

[lua]
– main.lua


display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()
physics.setDrawMode( “hybrid” )

local ground = display.newRect( 0, 300, 480, 50 )
ground:setFillColor( 0, 255, 0 )
physics.addBody(ground, “static”, { density=1.0, friction=0.4, bounce=0})

local hero = display.newRect( 150, 300, 15, 50 )
hero:setFillColor( 255, 0, 0 )
physics.addBody(hero, “dynamic”, { density=1.0, friction=0.4, bounce=0})
hero.isFixedRotation = true

local forwardBtnPressed = false
local backBtnPressed = false

local function moveFunctionRight()
print(“right complete”)
end

local function moveFunctionLeft()
print(“left complete”)
end

function forwardBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDR == nil then --Check to see if hero is already in motion here
if hero.transitionIDL then
transition.cancel(hero.transitionIDL)
hero.transitionIDL = nil
print(“left move cancelled”)
end
local transitionTimeR = math.abs((400-hero.x)/.1)
hero.transitionIDR = transition.to(hero, {time=transitionTimeR, x = 400, onComplete=moveFunctionRight})
end
end
end

function backBtnPressed(event)
if event.phase == “began” then
if hero.transitionIDL == nil then --Check to see if hero is already in motion here
if hero.transitionIDR then
transition.cancel(hero.transitionIDR)
hero.transitionIDR = nil
print(“right move cancelled”)
end
local transitionTimeL = math.abs((20-hero.x)/.1)
hero.transitionIDL = transition.to(hero, {time=transitionTimeL, x = 20, onComplete=moveFunctionLeft})
end
end
end

local forwardBtn = display.newRect(display.contentWidth/2,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
forwardBtn:setFillColor(0, 0)
local backBtn = display.newRect(0,display.contentHeight/2,display.contentWidth/2,display.contentHeight)
backBtn:setFillColor(0, 0)

forwardBtn:addEventListener( “touch”, forwardBtnPressed )
backBtn:addEventListener(“touch”, backBtnPressed )
[/lua] [import]uid: 146966 topic_id: 36251 reply_id: 144677[/import]

You say you were having problems when you touch an object twice. It looks like you just keep adding transitions of the same direction to the object because you never cancel the previous transition in that same direction; you cancel the transition in the other direction, but not the same direction. So perhaps, that is why you see these extra transition events.

No idea what is supposed to happen if you have two concurrent transitions trying to change the same property.

Since it seems you only need to keep track of one transition, maybe get rid of the .transitionIDR and .transitionIDL and just use one property?

Maybe. [import]uid: 94868 topic_id: 36251 reply_id: 144682[/import]

Thanks Screaming Leaf, I think the one thing I was getting tripped up on is that the onComplete fires when the hero.x == a given x value … watching the “character” on the screen, that never seemed to occur. [import]uid: 146966 topic_id: 36251 reply_id: 145016[/import]