Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Does Scenesmager not remove the previous sprite? - Gideros Forum

Does Scenesmager not remove the previous sprite?

kinrpgkinrpg Member
edited February 28 in Code snippets
I downloaded a very cool scene management code package that you have here on the site.
He makes the transitions and everything etc ...
But during the tests with the games here I realized that even when you change the scene, the previous scene (and what you have in ENTER_FRAME of it) continues to run. Does the scene manager remove only visually?
Is there a right way or command to permanently remove the previous Sprite / Scene?

Code in main.lua
GerenciadorCenas = SceneManager.new({
	--Cena inicial
	["cSplashScreen"] = cSplashScreen,
	["cHome"] = cHome,
	["cFase1"] = cFase1,
	--["cOpcoes"] = cOpcoes
})
Code call other scene:
bHome:addEventListener("click", 
function() 
	sounds:play("hit")
	GerenciadorCenas:changeScene("cHome", 1, GerenciadorCenas.fade)
end)
Or did I get it wrong and this Scene Manager always leaves all scenes on?

Comments

  • olegoleg Member
    edited February 28
    events need to be removed before changing the scenes
    --main.lua
    GerenciadorCenas = SceneManager.new({
    	--Cena inicial
    	["cSplashScreen"] = cSplashScreen,
    	["cHome"] = cHome,
    	["cFase1"] = cFase1,
    	--["cOpcoes"] = cOpcoes
    })
    GerenciadorCenas:changeScene("cSplashScreen", 1, GerenciadorCenas.fade)
    --cFase1.lua
    cFase1 = Core.class(Sprite)
     
     
    function cFase1:init()
             a=5464
    	self:addEventListener(Event.ENTER_FRAME, cFase1EF, self)
    	self:addEventListener(Event.REMOVED_FROM_STAGE,  onRemovedcFase1 self)
    end
     
     
     
    function onRemovedcFase1(self)
     
    	a=nil
    	self:removeEventListener(Event.ENTER_FRAME, cFase1EF, self)
    	self:removeEventListener(Event.REMOVED_FROM_STAGE,  onRemovedcFase1, self) 
    	collectgarbage()
    end
  • In SM's code (when transion ends):
    self:removeChild(self.scene1)
    self.scene1 = self.scene2
    self.scene2 = nil
    self.tweening = false
     
    collectgarbage()
    I don't know how removeChild works "under the hood" (does it removes attached events? does it removes child?), but usualy i'm using transitionEnd event, where i'm clearing stage "by hands" (just removing events). And it seems like it enough (i asume that garbage collector removes childs, cuz they are not used).
  • The scenemanager has events to let you know when the scene has ended - use these to remove extra events you added at the correct time - eg when the scene starts to end of when it has actually ended.
    Options=gideros.class(Sprite)
    function Options:init(t)
     
    -- use the following built-in events to start and finish things at various stages
    	self:addEventListener("enterBegin",self.onTransitionInBegin,self)
    	self:addEventListener("enterEnd",self.onTransitionInEnd,self)
    	self:addEventListener("exitBegin",self.onTransitionOutBegin,self)
    	self:addEventListener("exitEnd",self.onTransitionOutEnd,self)
    end
     
     
    function Options:onTransitionInBegin()
     -- this will execute once just after the init (you could actually put this at the end of the init)
    	self:addEventListener(Event.ENTER_FRAME,self.onEnterFrame,self)
    	self:addEventListener(Event.MOUSE_UP,self.onMouseUp,self)
    end
     
    function Options:onTransitionInEnd()
      -- this will execute once as soon as the scene has completed appearing
    end
     
    function Options:onTransitionOutBegin()
     -- this will execute once as the scene starts to leave
    	self:removeEventListener(Event.MOUSE_UP,self.onMouseUp,self)
    end
     
    function Options:onTransitionOutEnd()
      -- this will execute once as soon as the scene has fully gone
    	self:removeEventListener(Event.ENTER_FRAME,self.onEnterFrame,self)
    end
     
    function Options:onMouseUp(e)
     -- this has been coded to operate until the scene starts to end
    end
     
    function Options:onEnterFrame(e)
      -- this ad been coded to execute every game frame until the scene has completely ended
    end

    Likes: antix

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    this is a bad way, ENTER_FRAME is better to delete onTransitionOutBegin
    function Options:onTransitionOutEnd()
      -- this will execute once as soon as the scene has fully gone
    	self:removeEventListener(Event.ENTER_FRAME,self.onEnterFrame,self)
    end
  • hgy29hgy29 Maintainer
    @oleg, the scene can still be animated while it transition out, maybe that's what @SinisterSoft actually needs ?

    Likes: SinisterSoft

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    @hgy29 I have in, ENTER_FRAME created new objects that were then not deleted
    if you disable ENTER_FRAME right away, there are no such problems

  • hgy29hgy29 Maintainer
    yes, I understand that, but just because in your case it was better to do it early, it doesn't mean that doing it late is a bad idea generally speaking, as long as the coder knows what it implies and can handle it properly, then it is fine

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    edited February 28
    @hgy29 I am now removing an event through Event.REMOVED_FROM_STAGE this works better than events onTransitionOutEnd
  • Yes, I like things to carry on while the transition is being made - like animations, etc

    But it really depends on the game. I was just showing that there are some built-in events that can be used to turn things on/off at the correct time. :)

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • rrraptor said:

    In SM's code (when transion ends):

    self:removeChild(self.scene1)
    self.scene1 = self.scene2
    self.scene2 = nil
    self.tweening = false
     
    collectgarbage()
    I don't know how removeChild works "under the hood" (does it removes attached events? does it removes child?), but usualy i'm using transitionEnd event, where i'm clearing stage "by hands" (just removing events). And it seems like it enough (i asume that garbage collector removes childs, cuz they are not used).
    Well that's my doubt. Coincidentally, all the demos and studies I did using the Scene Manager used a time loop instead of the Enter_Frame. So before I pressed the fade buttons to change the scenes, I stopped the execution of the loop. So until this current project I had not noticed that the loop event still worked even by unloading Object rs.

    @oleg and @SinisterSoft Thank you for your help. I got it and I'm doing tests here.
    +1 -1 (+2 / -0 ) Share on Facebook
  • kinrpgkinrpg Member
    edited March 1
    I did a test using my friends' tips and it kind of is weird.
    He continues to run the event for a while before stopping.
    See below:
    There are two scenes, one called Menu1 and the other called Game1.
    Each has a button with the function of loading the other scene and an ENTER_FRAME containing a print that identifies the scene and counts.

    Edit: Does it continue to run the event because while it is giving the transition effect the scene is still active?

    Edit 2: I failed miserably.
    Enterframe events continue to run even by placing the suggested codes.
    Too bad I do not have the competence to use something that is already ready and works for everyone.
    I've been messing around for 6 hours and nothing. Failure D:

    Jogo1.lua
    cJogo1 = Core.class(Sprite)
    function cJogo1:init()
    -- Carregando itens visuais
    	local bg0 = Bitmap.new(TextureCeu)
    	bg0:setColorTransform(3, 0.5, 0.6)
    	self:addChild(bg0)
    	local sol = Bitmap.new(TextureSol)
    	sol:setAnchorPoint(0.5, 0.5)
    	sol:setPosition(320/2, 480)
    	self:addChild(sol)
    	local bg0B = Bitmap.new(TexturaEstrela)	
    	bg0B:setAlpha(0)
    	self:addChild(bg0B)
    	local bg1 = eNuvens.new()
    	bg1:setAlpha(0.45)	
    	self:addChild(bg1)
    	local Barra = Bitmap.new(TextureBarra)
    	Barra:setAnchorPoint(0.5, 0.5)
    	Barra:setPosition(320/2, 445 )
    	Barra:setScale(0.8)
    	self:addChild(Barra)
    	local bMenu = Button.new(Bitmap.new(TextureIcoConf2), Bitmap.new(TextureIcoConf1))
    	bMenu:setPosition(42,432)
    	self:addChild(bMenu)
    	local Pausa = cOpcoes.new("cJogo1")
     
    -- Funçoes
    	function MenuConfig()
    		sounds:play("hit")
    		if ativo then
    			ativo =false
    			self:addChild(Pausa)
    		end	
    	end
     
    	function corCeu()
    		local solX, solY = sol:getPosition()				
    		local r, g, b = bg0:getColorTransform()
    		if solY >= -128 and solY < 490 then
    			bg0B:setAlpha(0)
    			if r >= 0.5 then
    				r = r - 0.004
    			end
    			if b <= 1 then
    				b = b + 0.001
    			end
    			sol:setPosition(solX, solY - 0.5)		
    		end
    		if solY > 480 then
    			bg0B:setAlpha(0.3)
    			if r <= 3 then
    				r = r + 0.007
    			end
    			if b >= 0.6 then
    				b = b - 0.001
    			end
    			sol:setPosition(solX, solY - 0.1)
    		end
    		if solY < -128 then
    			sol:setPosition(solX, 832)
    		end
    		bg0:setColorTransform(r , g, b)
    	end	
    -- Eventos
    	bMenu:addEventListener("click", 
    	function() 	
    		MenuConfig()		
    	end)	
     
    	local x = 0
    	local function cJogo1EF()
    			if ativo then
    				bg1:Scroll(1)
    				corCeu()
    			end
    			if remover then				
    				GerenciadorCenas:changeScene("cMenu1", 0, GerenciadorCenas.fade)
    			end
    			x = x +1
    			print("This is game loop number -> "..x)
    	end
    	self:addEventListener(Event.ENTER_FRAME, cJogo1EF, self)		
    	self:removeEventListener(Event.ENTER_FRAME, onRemovedcJogo1EF, self)		
    end
    function onRemovedcJogo1EF(self)
    	self:removeEventListener(Event.ENTER_FRAME, cJogo1EF, self)
    	self:removeEventListener(Event.REMOVED_FROM_STAGE,  onRemovedcJogo1EF, self) 
    	collectgarbage()
    end
    Menu1.lua
    cMenu1 = Core.class(Sprite)
    function cMenu1:init()
    	ativo = true
    	local bMenu = Button.new(Bitmap.new(TextureIcoConf2), Bitmap.new(TextureIcoConf1))
    	bMenu:setPosition(42,432)
    	self:addChild(bMenu)
     
    	bMenu:addEventListener("click", 
    	function() 	
    		GerenciadorCenas:changeScene("cJogo1", 0, GerenciadorCenas.fade)		
    	end)	
     
    	local x = 0
    	local function cMenu1EF()
    		if ativo then
    		x = x +1
    		print("This is MENU loop number -> "..x)
    		end
    	end
    	self:addEventListener(Event.ENTER_FRAME, cMenu1EF, self)		
    	self:removeEventListener(Event.ENTER_FRAME,onRemovedcMenu1EF, self)	
    end
    function onRemovedcMenu1EF(self)
    	print("Removendo")
    	self:removeEventListener(Event.ENTER_FRAME, cMenu1EF, self)
    	self:removeEventListener(Event.REMOVED_FROM_STAGE,  onRemovedcMenu1EF, self) 
    	collectgarbage()
    	print("M"..collectgarbage(count))
    end
    opcoes.lua
    cOpcoes = Core.class(Sprite)
    function cOpcoes:init(Cena)
    	local shape = Shape.new()
    	shape:setFillStyle(Shape.SOLID, 0x000000, 0.95)
    	shape:beginPath()
    	shape:moveTo(0,0)
    	shape:lineTo(320, 0)
    	shape:lineTo(320, 480)
    	shape:lineTo(0, 480)
    	shape:lineTo(0, 0)
    	shape:endPath()
    	shape:setPosition(0, 0)
    	shape:setAlpha(0.75)
    	self:addChild(shape)
     
    	local shape2 = Shape.new()
    	shape2:setFillStyle(Shape.SOLID, 0xFF0000, 0)
    	shape2:beginPath()
    	shape2:moveTo(0,0)
    	shape2:lineTo(270, 0)
    	shape2:lineTo(270, 480)
    	shape2:lineTo(0, 480)
    	shape2:lineTo(0, 0)
    	shape2:endPath()
    	shape2:setPosition(25, 0)
    	self:addChild(shape2)
     
    	function cOpcoes:Remover()
    		sounds:play("hit")
    		ativo = true
    		local parent = self:getParent()
    		if parent ~= nil then
    			parent:removeChild(self)
    		end
    	end
    	local bMenu = Button.new(Bitmap.new(TextureIcoConf2), Bitmap.new(TextureIcoConf1))
    	bMenu:setPosition(42,432)
    	self:addChild(bMenu)
    	bMenu:addEventListener("click", 
    	function() 	
    		sounds:play("hit")
    		ativo = true
    		local parent = self:getParent()
    		if parent ~= nil then
    			parent:removeChild(self)
    		end
    	end)
     
    	local fontP = TTFont.new("Fontes/Hobby-of-night.ttf", 28)
    	local txtPausa = TextField.new(fontP, "Configurar")
    	txtPausa:setTextColor(0xffffff)
    	txtPausa:setAnchorPoint(0.5,0)
    	txtPausa:setPosition(160,40)
    	self:addChild(txtPausa)
     
    	local fontP2 = TTFont.new("Fontes/Hobby-of-night.ttf", 22)
    	local txtSons = TextField.new(fontP2, "Sons")
    	txtSons:setTextColor(0xffee00)
    	txtSons:setPosition(100,140-60)
    	self:addChild(txtSons)	
    	local txtMusicas = TextField.new(fontP2, "Musicas")
    	txtMusicas:setTextColor(0xffee00)
    	txtMusicas:setPosition(100,180-60)
    	self:addChild(txtMusicas)	
    	local SomOFF = Bitmap.new(TextureSomOn)
    	SomOFF:setPosition(40, 116-60)
    	SomOFF:setVisible(sets:get("sounds")==false)
    	self:addChild(SomOFF)	
    	local SomON = Bitmap.new(TextureSomOff)
    	SomON:setPosition(40, 116-60)
    	SomON:setVisible(sets:get("sounds"))
    	self:addChild(SomON)		
    	local MusicOFF = Bitmap.new(TextureMusicOn)
    	MusicOFF:setPosition(40, 156-60)
    	MusicOFF:setVisible(sets:get("music")==false)
    	self:addChild(MusicOFF)	
    	local MusicON = Bitmap.new(TextureMusicOff)
    	MusicON:setPosition(40, 156-60)
    	MusicON:setVisible(sets:get("music"))
    	self:addChild(MusicON)
     
    	local fontP3 = TTFont.new("Fontes/Hobby-of-night.ttf", 10)
    	local bPlay1 = Button.new(Bitmap.new(TextureIcoPlay2), Bitmap.new(TextureIcoPlay1))
    	bPlay1:setPosition(40, 190-40)
    	self:addChild(bPlay1)
    	local txtLegMus1 = TextWrap.new("Endlessorgy - Snabisch \n<a href="http://makeagame.bandcamp.com" target="_blank" rel="nofollow">http://makeagame.bandcamp.com</a>",	190, "left", fontP3)
    	txtLegMus1:setLineSpacing(1)
    	txtLegMus1:setTextColor(0xffffff)
    	txtLegMus1:setPosition(80, bPlay1:getY()+15)
    	self:addChild(txtLegMus1)
     
    	local bPlay2 = Button.new(Bitmap.new(TextureIcoPlay2), Bitmap.new(TextureIcoPlay1))
    	bPlay2:setPosition(40, 230-40)
    	self:addChild(bPlay2)
    	local txtLegMus2 = TextWrap.new("Children games on the beach - Snabisch <a href="http://makeagame.bandcamp.com" target="_blank" rel="nofollow">http://makeagame.bandcamp.com</a>",	190, "left", fontP3)
    	txtLegMus2:setLineSpacing(1)
    	txtLegMus2:setTextColor(0xffffff)
    	txtLegMus2:setPosition(80, bPlay2:getY()+15)
    	self:addChild(txtLegMus2)
     
    	local bPlay3 = Button.new(Bitmap.new(TextureIcoPlay2), Bitmap.new(TextureIcoPlay1))
    	bPlay3:setPosition(40, 270-40)
    	self:addChild(bPlay3)
    	local txtLegMus3 = TextWrap.new("A walk in the sky (130 BPM) - Snabisch \n<a href="http://makeagame.bandcamp.com" target="_blank" rel="nofollow">http://makeagame.bandcamp.com</a>",	190, "left", fontP3)
    	txtLegMus3:setLineSpacing(1)
    	txtLegMus3:setTextColor(0xffffff)
    	txtLegMus3:setPosition(80, bPlay3:getY()+15)
    	self:addChild(txtLegMus3)
     
    	local bPlay4 = Button.new(Bitmap.new(TextureIcoPlay2), Bitmap.new(TextureIcoPlay1))
    	bPlay4:setPosition(40, 310-40)
    	self:addChild(bPlay4)
    	local txtLegMus4 = TextWrap.new("Celta World - Snabisch \n<a href="http://makeagame.bandcamp.com" target="_blank" rel="nofollow">http://makeagame.bandcamp.com</a>",	190, "left", fontP3)
    	txtLegMus4:setLineSpacing(1)
    	txtLegMus4:setTextColor(0xffffff)
    	txtLegMus4:setPosition(80, bPlay4:getY()+15)
    	self:addChild(txtLegMus4)
     
    	local bPlay5 = Button.new(Bitmap.new(TextureIcoPlay2), Bitmap.new(TextureIcoPlay1))
    	bPlay5:setPosition(40, 350-40)
    	self:addChild(bPlay5)
    	local txtLegMus5 = TextWrap.new("Battle RPG Theme - CleytonRX",	190, "left", fontP3)
    	txtLegMus5:setLineSpacing(1)
    	txtLegMus5:setTextColor(0xffffff)
    	txtLegMus5:setPosition(80, bPlay5:getY()+15)
    	self:addChild(txtLegMus5)
     
    	self:addEventListener(Event.MOUSE_DOWN,
    	function(event)
    		if SomON:hitTestPoint(event.x, event.y) or SomOFF:hitTestPoint(event.x, event.y)  then
    			if sets:get("sounds") then
    				sounds:off()				
    			else
    				sounds:on()
    				sounds:play("hit")
    			end
    			SomON:setVisible(sets:get("sounds"))
    			SomOFF:setVisible(sets:get("sounds")==false)
    		end
    		if MusicON:hitTestPoint(event.x, event.y) or MusicOFF:hitTestPoint(event.x, event.y)  then
    			if sets:get("music") then
    				music[sets:get("nmusic")]:off()					
    			else
    				music[sets:get("nmusic")]:on()	
    			end
    			MusicON:setVisible(sets:get("music"))
    			MusicOFF:setVisible(sets:get("music")==false)
    		end		
    	end)
    	bPlay1:addEventListener("click", 
    	function() 		
    		if sets:get("nmusic") <> 1 then
    			local ligado = sets:get("music")
    			music[sets:get("nmusic")]:off()	
    			sets:set("nmusic", 1, true)
    			if ligado then
    				music[sets:get("nmusic")]:on()	
    			end
    		end
    	end)	
    	bPlay2:addEventListener("click", 
    	function() 
    		if sets:get("nmusic") <> 2 then
    			local ligado = sets:get("music")
    			music[sets:get("nmusic")]:off()	
    			sets:set("nmusic", 2, true)
    			if ligado then
    				music[sets:get("nmusic")]:on()	
    			end
    		end
    	end)	
    	bPlay3:addEventListener("click", 
    	function() 	
    		if sets:get("nmusic") <> 3 then
    			local ligado = sets:get("music")
    			music[sets:get("nmusic")]:off()	
    			sets:set("nmusic", 3, true)
    			if ligado then
    				music[sets:get("nmusic")]:on()	
    			end
    		end
    	end)	
    	bPlay4:addEventListener("click", 
    	function() 	
    		if sets:get("nmusic") <> 4 then
    			local ligado = sets:get("music")
    			music[sets:get("nmusic")]:off()	
    			sets:set("nmusic", 4, true)
    			if ligado then
    				music[sets:get("nmusic")]:on()	
    			end
    		end
    	end)	
    	bPlay5:addEventListener("click", 
    	function() 		
    		if sets:get("nmusic") <> 5 then
    			local ligado = sets:get("music")
    			music[sets:get("nmusic")]:off()	
    			sets:set("nmusic", 5, true)
    			if ligado then
    				music[sets:get("nmusic")]:on()	
    			end
    		end
    	end)		
     
    	if (Cena == nil) == false then
    		local bReboot = Button.new(Bitmap.new(TextureIcoReboot2), Bitmap.new(TextureIcoReboot1))
    		bReboot:setPosition(120, 360)
    		self:addChild(bReboot)
     
    		local bHome = Button.new(Bitmap.new(TextureIcoMenu2), Bitmap.new(TextureIcoMenu1))
    		bHome:setPosition(170, 360)
    		self:addChild(bHome)
     
    		bReboot:addEventListener("click", 
    		function() 
    			sounds:play("hit")
    			ativo = true
    			local parent = self:getParent()
    			if parent ~= nil then
    				parent:removeChild(self)
    			end
    			GerenciadorCenas:changeScene(Cena, 0, GerenciadorCenas.fade)
    		end)	
     
    		bHome:addEventListener("click", 
    		function() 
    			sounds:play("hit")
    			ativo = true
    			local parent = self:getParent()
    			if parent ~= nil then
    				parent:removeChild(self)
    			end			
    			GerenciadorCenas:changeScene("cMenu1", 0, GerenciadorCenas.fade)			
    		end)	
    	end	
     
    	self:addEventListener(Event.ENTER_FRAME, function()
    		if sets:get("nmusic") == 1 then
    			txtLegMus1:setTextColor(0xffaaaa)
    		else
    			txtLegMus1:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 2 then
    			txtLegMus2:setTextColor(0xffaaaa)
    		else
    			txtLegMus2:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 3 then
    			txtLegMus3:setTextColor(0xffaaaa)
    		else
    			txtLegMus3:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 4 then
    			txtLegMus4:setTextColor(0xffaaaa)
    		else
    			txtLegMus4:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 5 then
    			txtLegMus5:setTextColor(0xffaaaa)
    		else
    			txtLegMus5:setTextColor(0xffffff)
    		end
    	end)
    end
  • olegoleg Member
    function cOpcoes:init(Cena)
    --  some code --
    function cOpcoesEF(self)
    		if sets:get("nmusic") == 1 then
    			txtLegMus1:setTextColor(0xffaaaa)
    		else
    			txtLegMus1:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 2 then
    			txtLegMus2:setTextColor(0xffaaaa)
    		else
    			txtLegMus2:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 3 then
    			txtLegMus3:setTextColor(0xffaaaa)
    		else
    			txtLegMus3:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 4 then
    			txtLegMus4:setTextColor(0xffaaaa)
    		else
    			txtLegMus4:setTextColor(0xffffff)
    		end
    		if sets:get("nmusic") == 5 then
    			txtLegMus5:setTextColor(0xffaaaa)
    		else
    			txtLegMus5:setTextColor(0xffffff)
    		end
    end
     
    self:addEventListener(Event.ENTER_FRAME,cOpcoesEF, self)	
     
     
    function onRemovedcOpcoesEF(self)
    self:removeEventListener(Event.ENTER_FRAME,cOpcoesEF, self)	
     
    end
     
    self:addEventListener(Event.REMOVED_FROM_STAGE,  onRemovedcOpcoesEF, self) 
    end

    Likes: kinrpg

    +1 -1 (+1 / -0 ) Share on Facebook
  • kinrpgkinrpg Member
    oleg said:


    I must have been very affected by sleep. I swear that at the time I wrote it made perfect sense, but not now.
    Thanks for the help, I used the code the way you showed me and now the events are being eliminated correctly along with the sprites.
    Sorry for the delay in giving feedback but I had to work with other things and I only got back on the pc today.

    Likes: antix

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    edited March 6 Accepted Answer
Sign In or Register to comment.