Object duplicates when using transition

Hello, I am trying to create an UI that slides from top of the screen when pause button is tapped (event listener on pause button calls  “showUpperUI” function) and hide the UI, when play button is tapped. Transiton in “showUpperUI” function works fine, but when I press “playButton” to hide the UI, then the playButton display object somehow duplicates. One stays on its position and the second gets trasitioned (as shown on picture).

Screenshot_2.png

Here is the code.

local function hideUpperUIAfterAnimation ( event ) pauseButton.isVisible = true --display.remove( playButton ) end local function hideUpperUI( event ) transition.to( playButton, { time=800, alpha=1, x=map.designedWidth/2 + 150, y=-100, onComplete=hideUpperUIAfterAnimation } ) end local function showUpperUIAfterAnimation ( event ) playButton:addEventListener( "tap", hideUpperUI ) print("something") end local function showUpperUI( event ) pauseButton.isVisible = false playButton = display.newImageRect( uiGroup, "texture/ui/play.PNG", 80 ,80 ) playButton.x = map.designedWidth/2 + 150 playButton.y = -85 playButton.alpha = 0.2 transition.to( playButton, { time=800, alpha=1, x=map.designedWidth/2 + 150, y=10, onComplete=showUpperUIAfterAnimation } ) end

Text in “showUpperUIAfterAnimation” function is also printed twice and I dont know why.

I will be grateful for any advice.

I am creating so many functions, because for example I dont want to add event listener to play button while it is being transitioned. Is there a better way to achieve this?

Thank you in advance.

What calls showUpperUI()?

Rob

It is called by tapping on pauseButton

pauseButton = display.newImageRect( uiGroup, "texture/ui/pause.PNG", 60, 60) pauseButton.x = map.designedWidth/2 + 300 pauseButton.y = 20

function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then map.isVisible = true elseif ( phase == "did" ) physics.start() backGroup:addEventListener ( "touch", stroke ) -- Set listener for ball stroke Runtime:addEventListener( "collision", onCollision ) pauseButton:addEventListener( "tap", showUpperUI ) end end

Try changing your showUpperUI function to this…

local function showUpperUI( event ) if event.phase=="ended" then pauseButton.isVisible = false playButton = display.newImageRect( uiGroup, "texture/ui/play.PNG", 80 ,80 ) playButton.x = map.designedWidth/2 + 150 playButton.y = -85 playButton.alpha = 0.2 transition.to( playButton, { time=800, alpha=1, x=map.designedWidth/2 + 150, y=10, onComplete=showUpperUIAfterAnimation } ) return true end end

(at work at the moment so can’t test it)

The button is based on a tap handler, so it won’t have phases like a touch handler would. This is what I was checking, it seems like the showUpperUI() function was getting called twice, which is symptomatic of a touch handler that isn’t checking it’s phase.

Rob

Oh yeah, I didn’t notice that.

I have managed to find the solution. The problem was in another file that featured the main menu of the game and I have putted the composer.gotoScene() function directly into function scene:create()  so I should not have to click on a button that loads the game level every time I restart the corona simulator. Then the game level probably has somehow loaded twice.

I have a variable either at the top of main.lua or a config module that determines which scene to load on startup. I then use this in the first composer.gotoScene call and don’t have to traverse through various screens to get to the one I’m working on, or hunt for the gotoScene call to change it.

I also ignore this setting if running on device to avoid accidentally making a production build that skips to the wrong scene.

What calls showUpperUI()?

Rob

It is called by tapping on pauseButton

pauseButton = display.newImageRect( uiGroup, "texture/ui/pause.PNG", 60, 60) pauseButton.x = map.designedWidth/2 + 300 pauseButton.y = 20

function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then map.isVisible = true elseif ( phase == "did" ) physics.start() backGroup:addEventListener ( "touch", stroke ) -- Set listener for ball stroke Runtime:addEventListener( "collision", onCollision ) pauseButton:addEventListener( "tap", showUpperUI ) end end

Try changing your showUpperUI function to this…

local function showUpperUI( event ) if event.phase=="ended" then pauseButton.isVisible = false playButton = display.newImageRect( uiGroup, "texture/ui/play.PNG", 80 ,80 ) playButton.x = map.designedWidth/2 + 150 playButton.y = -85 playButton.alpha = 0.2 transition.to( playButton, { time=800, alpha=1, x=map.designedWidth/2 + 150, y=10, onComplete=showUpperUIAfterAnimation } ) return true end end

(at work at the moment so can’t test it)

The button is based on a tap handler, so it won’t have phases like a touch handler would. This is what I was checking, it seems like the showUpperUI() function was getting called twice, which is symptomatic of a touch handler that isn’t checking it’s phase.

Rob

Oh yeah, I didn’t notice that.

I have managed to find the solution. The problem was in another file that featured the main menu of the game and I have putted the composer.gotoScene() function directly into function scene:create()  so I should not have to click on a button that loads the game level every time I restart the corona simulator. Then the game level probably has somehow loaded twice.

I have a variable either at the top of main.lua or a config module that determines which scene to load on startup. I then use this in the first composer.gotoScene call and don’t have to traverse through various screens to get to the one I’m working on, or hunt for the gotoScene call to change it.

I also ignore this setting if running on device to avoid accidentally making a production build that skips to the wrong scene.