composer newbie problem with transition

Hi,

For understand the composer, i have made a simple app with each basic function possible :

  • transition
  • timer
  • listener
  • physics
  • objects

I have my main.lua with redirect to menu.lua and menu.lua redirect to scene1.lua

when i access to my level.lua it’s said that my character are a nill value but i don’t understand why…could you help me ?  Thanks.

--scene1.lua local composer = require( "composer" ) local scene = composer.newScene() local params -- -- Start the composer event handlers -- function scene:create( event ) local sceneGroup = self.view params = event.params local background=display.newRect(0,0,3000,3000) -- background:setFillColor(1,1,1) local function createcharacter() local character=display.newCircle(800,250,20) character:setFillColor(0,0,0)--black end local circle=display.newCircle(240,500,20) circle:setFillColor(0,0,1)--black physics.start() physics.setGravity( 0, 6 ) physics.addBody( circle, "dynamic" ) local button={} for i=1,2 do button[i]=display.newCircle(600,500,40) button[i].myId=(i) button[i]:setFillColor(1,0,0) end button[1].x=100--pause button[2].x=450--restart the game button[1]:setFillColor(1,1,0) local cntSwipe=0 local cnt=1 local textCntSwipe= display.newText("Level", 50,410,native.systemFontBold, 35) textCntSwipe:setFillColor(1,1,1) local function countTimer() --count the time cnt=cnt+1 textCntSwipe.text = cntSwipe end --function countTimer local function displacement(character) local function displacementEnd(character) character.transition=transition.to(character, {time=1500,x=250, onComplete=function() displacement(character) end}) end character.transition=transition.to(character, {time=1500,x=50, onComplete=function() displacementEnd(character) end}) end--displacement -- displacement(character) local function testPosition() print(character.x) end Runtime:addEventListener("enterFrame", function() testPosition(character) end) local function touchCharacter(event) if event.phase =="ended" then target = event.target if target.myId ==1 then print("cela") composer.gotoScene( "menu", { time = 2500, effect = "fade", params = params } ) elseif target.myId == 2 then composer.gotoScene( "menu", { time = 2500, effect = "fade", params = params } ) print("aussu") end--if end--if end--touchCharacter -- setup a page background, really not that important though composer -- crashes out if there isn't a display object in the view. -- sceneGroup:insert(background,character,circle,button) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if phase == "will" then -- Called when the scene is off screen and is about to move on screen elseif phase == "did" then createcharacter() displacement(character) for i=1,#button do button[i]:addEventListener("touch",touchCharacter) end mytimer=timer.performWithDelay( 1000, countTimer,-1) -- Called when the scene is now on screen -- -- INSERT code here to make the scene come alive -- e.g. start timers, begin animation, play audio, etc end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if event.phase == "will" then timer.cancel(mytimer) Runtime:removeEventListener("touch",touchCharacter) Runtime:removeEventListener("enterFrame",testPosition) transition.cancel(character.transition) -- Called when the scene is on screen and is about to move off screen -- -- INSERT code here to pause the scene -- e.g. stop timers, stop animation, unload sounds, etc.) elseif phase == "did" then -- Called when the scene is now off screen end end function scene:destroy( event ) local sceneGroup = self.view -- Called prior to the removal of scene's "view" (sceneGroup) -- -- INSERT code here to cleanup the scene -- e.g. remove display objects, remove touch listeners, save state, etc end ------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) ------------------------------------------------------------------------------- return scene

You have several problems going on.  Please read these two tutorials and work really hard to understand the concepts.  Your code is poorly formatted it making it hard to read. If your code is formatted like this in your editor, you’re going to have a very hard time trying to figure out what functions are inside of other functions.  This code makes it very hard for your to “see” the scope of your objects.  Scope is “what variables and functions are visible” from various parts of code.

https://coronalabs.com/blog/2015/06/09/tutorial-the-value-of-well-formatted-code/

https://coronalabs.com/blog/2015/06/16/tutorial-scope-for-beginners/

I know many new programmers want the answers given to them, but believe me, it’s in your best interest to spend the time figuring the two topics above so you can see your code better (and when you ask for help, people will be able to better help you).

One thing not covered in those tutorials (but in previous ones) is you cannot do this:

Runtime:addEventListener("enterFrame", function() testPosition(character) end)

if you have any desire to remove it later. You cannot use anonymous functions to feed “addEventListener”.  You have to use a named function:

local function testPostionWrapper()     testPosition(character) end Runtime:addEventListener("enterFrame", testPositionWrapper )

Rob

Thanks Rob,

I have read both links effectively i have problem with local and global.

I searched a lot a good example of composer example but i have not found complete exept this by you :

https://github.com/coronalabs/sample-game-project

but there is no transition, no physics…  where is the good place for finding a basic example template ?

my code is updated with your comments.

I don’t understand very well the difference between scene:destroy and scene:hide

when the function scene:destroy is used ?

and finally with composer we must use a lot of global variable instead of local …?what it is inevitable

local composer = require( "composer" ) local scene = composer.newScene() local params -- -- Start the composer event handlers -- function scene:create( event )     local sceneGroup = self.view     params = event.params function createasset()     background=display.newRect(0,0,3000,3000)    --     background:setFillColor(1,1,1)     character=display.newCircle(800,250,20)     character:setFillColor(1,0,0)--black     circle=display.newCircle(240,500,20)     circle:setFillColor(0,0,1)--black     physics.start()     physics.setGravity( 0, 6 )     physics.addBody( circle, "dynamic" )     sceneGroup:insert(background,character,circle) end     button={}     for i=1,2 do         button[i]=display.newCircle(600,500,40)         button[i].myId=(i)         button[i]:setFillColor(1,0,0)     end     button[1].x=100--pause     button[2].x=450--restart the game     button[1]:setFillColor(1,1,0)     sceneGroup:insert(button[1], button[2])     function displacement()         function displacementEnd()         character.transition=transition.to(character, {time=1500,x=250, onComplete=displacement})         end         character.transition=transition.to(character, {time=1500,x=50, onComplete=displacementEnd})     end--displacement     local function touchCharacter(event)         if  event.phase =="ended" then             target = event.target                     if target.myId ==1 then                         composer.gotoScene( "level", { time = 250, effect = "fade", params = params } )                     elseif target.myId == 2 then                         composer.gotoScene( "level", { time = 250, effect = "fade", params = params } )                     end--if         end--if     end--touchCharacter             for i=1,#button do                 button[i]:addEventListener("touch",touchCharacter)             end             -- setup a page background, really not that important though composer             -- crashes out if there isn't a display object in the view     end     function scene:show( event )         local sceneGroup = self.view         local phase = event.phase         if phase == "will" then             -- Called when the scene is off screen and is about to move on screen         elseif phase == "did" then             createasset()             displacement()             -- Called when the scene is now on screen            --             -- INSERT code here to make the scene come alive             -- e.g. start timers, begin animation, play audio, etc         end     end     function scene:hide( event )         local sceneGroup = self.view         local phase = event.phase         if event.phase == "will" then             if character.transition then             transition.cancel(character.transition)             character.transition=nill             end             display.remove( circle )             display.remove( character )             display.remove( button[2] )             display.remove( button[1] )             -- Called when the scene is on screen and is about to move off screen             -- INSERT code here to pause the scene             -- e.g. stop timers, stop animation, unload sounds, etc.         elseif phase == "did" then             -- Called when the scene is now off screen         end     end     function scene:destroy( event )         local sceneGroup = self.view         -- Called prior to the removal of scene's "view" (sceneGroup)         -- INSERT code here to cleanup the scene         -- e.g. remove display objects, remove touch listeners, save state, etc     end     -------------------------------------------------------------------------------     -- Listener setup     scene:addEventListener( "create", scene )     scene:addEventListener( "show", scene )     scene:addEventListener( "hide", scene )     scene:addEventListener( "destroy", scene )     -------------------------------------------------------------------------------     return scene

The difference between scene:hide() and scene:destroy() is clearly explained in the Composer guide:

https://docs.coronalabs.com/guide/system/composer/index.html

destroy() gets called when you call composer.removeScene().

hide() gets called when you call composer.gotoScene() for the scene that’s on the screen.

Rob

sorry to bother forum with things such as this one but that’s two hours I seek my mistake …why my character doesn’t go to my scene(create)

when i uncomment sceneGroup:insert(character) . no problem

here is the error :

6je1Zfj.png?1

------------------------------------------------------------------ local composer = require("composer") local scene = composer.newScene() local character={} for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) end -- "scene:create()" function scene:create( event )     local sceneGroup = self.view     sceneGroup:insert(character) end -- "scene:show()" function scene:show( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is still off screen (but is about to come on screen).    elseif ( phase == "did" ) then       -- Called when the scene is now on screen.       -- Insert code here to make the scene come alive.       -- Example: start timers, begin animation, play audio, etc.    end end -- "scene:hide()" function scene:hide( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is on screen (but is about to go off screen).       -- Insert code here to "pause" the scene.       -- Example: stop timers, stop animation, stop audio, etc.    elseif ( phase == "did" ) then       -- Called immediately after scene goes off screen.    end end -- "scene:destroy()" function scene:destroy( event )    local sceneGroup = self.view    -- Called prior to the removal of scene's view ("sceneGroup").    -- Insert code here to clean up the scene.    -- Example: remove display objects, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

This code:

for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) end

should be inside of scene:create().  Next it should read:

for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) sceneGroup:insert(character[a]) end

and remove the other line: sceneGroup:insert(character)

You can only insert display objects (things created with display.* API calls) into the scene.  The variable character is a table, not a display object. It cannot be inserted into a group.  The fixes above will address your issues.

Rob

Gosh i have forgotten that this a table so the snippet below works also. In any case really thank you for your help, you are a beautiful assist on this forum :slight_smile:

Is that it’s better to declare all up for having finally that function calls and groups in the function scene:create(event) ?

local composer = require("composer") local scene = composer.newScene() local character={} for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) end function scene:create( event ) local sceneGroup = self.view for a=1,100 do sceneGroup:insert(character[a]) end end

You create things in scene:create(). 

local composer = require("composer") local scene = composer.newScene() local character={} function scene:create( event ) local sceneGroup = self.view for a=1,100 do character[a] = display.newImageRect("character.png",100,100) sceneGroup:insert(character[a]) end end

You have several problems going on.  Please read these two tutorials and work really hard to understand the concepts.  Your code is poorly formatted it making it hard to read. If your code is formatted like this in your editor, you’re going to have a very hard time trying to figure out what functions are inside of other functions.  This code makes it very hard for your to “see” the scope of your objects.  Scope is “what variables and functions are visible” from various parts of code.

https://coronalabs.com/blog/2015/06/09/tutorial-the-value-of-well-formatted-code/

https://coronalabs.com/blog/2015/06/16/tutorial-scope-for-beginners/

I know many new programmers want the answers given to them, but believe me, it’s in your best interest to spend the time figuring the two topics above so you can see your code better (and when you ask for help, people will be able to better help you).

One thing not covered in those tutorials (but in previous ones) is you cannot do this:

Runtime:addEventListener("enterFrame", function() testPosition(character) end)

if you have any desire to remove it later. You cannot use anonymous functions to feed “addEventListener”.  You have to use a named function:

local function testPostionWrapper()     testPosition(character) end Runtime:addEventListener("enterFrame", testPositionWrapper )

Rob

Thanks Rob,

I have read both links effectively i have problem with local and global.

I searched a lot a good example of composer example but i have not found complete exept this by you :

https://github.com/coronalabs/sample-game-project

but there is no transition, no physics…  where is the good place for finding a basic example template ?

my code is updated with your comments.

I don’t understand very well the difference between scene:destroy and scene:hide

when the function scene:destroy is used ?

and finally with composer we must use a lot of global variable instead of local …?what it is inevitable

local composer = require( "composer" ) local scene = composer.newScene() local params -- -- Start the composer event handlers -- function scene:create( event )     local sceneGroup = self.view     params = event.params function createasset()     background=display.newRect(0,0,3000,3000)    --     background:setFillColor(1,1,1)     character=display.newCircle(800,250,20)     character:setFillColor(1,0,0)--black     circle=display.newCircle(240,500,20)     circle:setFillColor(0,0,1)--black     physics.start()     physics.setGravity( 0, 6 )     physics.addBody( circle, "dynamic" )     sceneGroup:insert(background,character,circle) end     button={}     for i=1,2 do         button[i]=display.newCircle(600,500,40)         button[i].myId=(i)         button[i]:setFillColor(1,0,0)     end     button[1].x=100--pause     button[2].x=450--restart the game     button[1]:setFillColor(1,1,0)     sceneGroup:insert(button[1], button[2])     function displacement()         function displacementEnd()         character.transition=transition.to(character, {time=1500,x=250, onComplete=displacement})         end         character.transition=transition.to(character, {time=1500,x=50, onComplete=displacementEnd})     end--displacement     local function touchCharacter(event)         if  event.phase =="ended" then             target = event.target                     if target.myId ==1 then                         composer.gotoScene( "level", { time = 250, effect = "fade", params = params } )                     elseif target.myId == 2 then                         composer.gotoScene( "level", { time = 250, effect = "fade", params = params } )                     end--if         end--if     end--touchCharacter             for i=1,#button do                 button[i]:addEventListener("touch",touchCharacter)             end             -- setup a page background, really not that important though composer             -- crashes out if there isn't a display object in the view     end     function scene:show( event )         local sceneGroup = self.view         local phase = event.phase         if phase == "will" then             -- Called when the scene is off screen and is about to move on screen         elseif phase == "did" then             createasset()             displacement()             -- Called when the scene is now on screen            --             -- INSERT code here to make the scene come alive             -- e.g. start timers, begin animation, play audio, etc         end     end     function scene:hide( event )         local sceneGroup = self.view         local phase = event.phase         if event.phase == "will" then             if character.transition then             transition.cancel(character.transition)             character.transition=nill             end             display.remove( circle )             display.remove( character )             display.remove( button[2] )             display.remove( button[1] )             -- Called when the scene is on screen and is about to move off screen             -- INSERT code here to pause the scene             -- e.g. stop timers, stop animation, unload sounds, etc.         elseif phase == "did" then             -- Called when the scene is now off screen         end     end     function scene:destroy( event )         local sceneGroup = self.view         -- Called prior to the removal of scene's "view" (sceneGroup)         -- INSERT code here to cleanup the scene         -- e.g. remove display objects, remove touch listeners, save state, etc     end     -------------------------------------------------------------------------------     -- Listener setup     scene:addEventListener( "create", scene )     scene:addEventListener( "show", scene )     scene:addEventListener( "hide", scene )     scene:addEventListener( "destroy", scene )     -------------------------------------------------------------------------------     return scene

The difference between scene:hide() and scene:destroy() is clearly explained in the Composer guide:

https://docs.coronalabs.com/guide/system/composer/index.html

destroy() gets called when you call composer.removeScene().

hide() gets called when you call composer.gotoScene() for the scene that’s on the screen.

Rob

sorry to bother forum with things such as this one but that’s two hours I seek my mistake …why my character doesn’t go to my scene(create)

when i uncomment sceneGroup:insert(character) . no problem

here is the error :

6je1Zfj.png?1

------------------------------------------------------------------ local composer = require("composer") local scene = composer.newScene() local character={} for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) end -- "scene:create()" function scene:create( event )     local sceneGroup = self.view     sceneGroup:insert(character) end -- "scene:show()" function scene:show( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is still off screen (but is about to come on screen).    elseif ( phase == "did" ) then       -- Called when the scene is now on screen.       -- Insert code here to make the scene come alive.       -- Example: start timers, begin animation, play audio, etc.    end end -- "scene:hide()" function scene:hide( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is on screen (but is about to go off screen).       -- Insert code here to "pause" the scene.       -- Example: stop timers, stop animation, stop audio, etc.    elseif ( phase == "did" ) then       -- Called immediately after scene goes off screen.    end end -- "scene:destroy()" function scene:destroy( event )    local sceneGroup = self.view    -- Called prior to the removal of scene's view ("sceneGroup").    -- Insert code here to clean up the scene.    -- Example: remove display objects, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

This code:

for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) end

should be inside of scene:create().  Next it should read:

for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) sceneGroup:insert(character[a]) end

and remove the other line: sceneGroup:insert(character)

You can only insert display objects (things created with display.* API calls) into the scene.  The variable character is a table, not a display object. It cannot be inserted into a group.  The fixes above will address your issues.

Rob

Gosh i have forgotten that this a table so the snippet below works also. In any case really thank you for your help, you are a beautiful assist on this forum :slight_smile:

Is that it’s better to declare all up for having finally that function calls and groups in the function scene:create(event) ?

local composer = require("composer") local scene = composer.newScene() local character={} for a=1,100 do character[a] = display.newImageRect("character.png",100,100,100,100) end function scene:create( event ) local sceneGroup = self.view for a=1,100 do sceneGroup:insert(character[a]) end end

You create things in scene:create(). 

local composer = require("composer") local scene = composer.newScene() local character={} function scene:create( event ) local sceneGroup = self.view for a=1,100 do character[a] = display.newImageRect("character.png",100,100) sceneGroup:insert(character[a]) end end