Changing color of a new text displayed after collision occoured/ removing text displayed from scene

Hello everyone!

I have two problems with the same displayed text.

I set a text to appear after a collision occured which works fine.

Problem 1 = I can’t change the fill color of the text

Problem 2 = the text stays onscrene even after switching to other scenes

Here my code:

local myTextBox = display.newText( “Go…”, 100 ,50, 125, 25, robotoFont, 25 )

myTextBox:setFillColor( 1, 0, 0 )

physics.addBody(myTextBox, “dynamic”,{density=1, friction =.3})

physics.setGravity( 1, 10 )

myTextBox.name = “myTextBox”

local function onLocalCollision (self, event)

        if event.phase == “began” then

            display.remove (myTextBox)

            myTextBox = nil

            display.newText ( “…again!”, 200 ,200, 350, 25, robotoFont, 25)

                                            --I cannot change default color of the text

                                            --This text stays on screen even if changing scenes

            score = score +1

            updateText();

           elseif ( “moved” == phase ) then

           elseif event.phase == “ended” then

           display.remove (newText) --This doesn’t work

           newText = nil; --this doesn’t work either

           end

end

myTextBox.collision = onLocalCollision

myTextBox:addEventListener(“collision”, myTextBox)

I also tried to remove newText in “hide or distroy” phase without any luck.

I appreciate any help

Thanks

Patricia

Hey!

The line: “display.newText ( “…again!”, 200 ,200, 350, 25, robotoFont, 25)” calls the display.newText functon and creates a new text object. However, since you don’t assign it to any variable, you cannot control it (easily at least) after creating it.

You assign it to a variable by adding the “local someText = display.newText ( “…again!”, 200 ,200, 350, 25, robotoFont, 25)” in the beginning. Currently you do not assign a variable to it and the reference is therefore lost as soon as you create it. So when you are later trying to delete and set “newText” to nil, it doesn’t do anything because the code can’t find what you mean.

You may also want to read this about scope: https://docs.coronalabs.com/tutorial/basics/scope/index.html

Because of the scope, even if you created a local text object within that if statement, you couldn’t access it outside of it because of scope.

Finally, you can’t change the text colour for the same reason, i.e. there is no reference. The reason why it stays on screen even after you leave the scene is because you don’t add it to a display group. Corona will automatically remove only those display objects that are a part of the scene group. For that, you may want to read: https://docs.coronalabs.com/guide/system/composer/index.html

Thank you XeDuR for coming back to me!

By assigning it to a group (I changed the name as well) -

       congratsText = display.newText (uiGroup, "...again!", 200 ,200, 350, 25, robotoFont, 25)           congratsText:setFillColor (1,1,0)

I managed to change the color and it won’t show on other scenes. 

Yet, I encountered the next problem - the text “…again!”, which should only appear after the collision occurred is there from starters (like any object assigned to a fixed position, I suppose) and “assumes” the same function as the text “Go…!” , meaning, it disappears when the player catches the go.

What I want to achieve is:

                                   player collides/catches “Go”…

                                   player gets 1 point

                                   text “Again” appears and fades away…

I tried it this way, but, obviously, I am still missing something:

                                 

 local function onLocalCollision (self, event)  if event.phase == "began" then      display.remove (myTextBox)      myTextBox = nil      score = score +1;      updateText();      congratsText.isVisible = false;          elseif ( "moved" == phase ) then         congratsText.isVisible = true;                                               elseif event.phase == "ended" then           display.remove (congratsText)            congratsText = nil;  end myTextBox.collision = onLocalCollision myTextBox:addEventListener("collision", myTextBox)

Tks in advance for any help,

Patricia

No problem, patriCiaFlink :stuck_out_tongue:

When you are posting code to the forums, please insert it by using the code formatting tool < >.

Also, you don’t need to add “;” to the end of your lines in lua.

Now, I am slightly puzzled as to why you add a collision listener to text. This new problem of yours is most likely occurring because when the collision event starts, you begin by removing myTextBox which is a part of the collision and you set it to nil. This means that one of the two colliding objects is removed as soon as the event begins, so it cannot reach the ended phase. If you want to remove it, then wait until the collision ends.

Speaking of which, collision events do not have a “moved” phase and the line

elseif ( "moved" == phase ) then

may actually result in crashing your code.

hi again!

Sorry for not using the formatting tool before.

I added the collision listener to a text because the idea is to catch words roaming the screen. 

Attaching a text to a rect and make the text and rect disappear after collision seems harder to achieve. 

Actually, I was quite happy to have found out that a text is an object which can collide!

I will try and separate that isolated congrats.text from the function collision and I come back here with either the solution or yet another question

thank you again for your help and patience

Patricia

ok, sadly I wasn’t able to do what I wanted to and probably didn’t explain it clearly before. Hopefully I can do so now.

After collision occurred and “myTextBox” is removed, a score is achieved. After that (and then randomly), I want to display a popup text.

From what I’ve been reading, this is “best” done by fade in (transition). I managed a fade in transition, not when the score increases but with a time delay. So, the text “…again!” fades in after x-seconds and not when a score is achieved:(

How is this done? Can fade in be called when an event occurred through a local function? If so, how? or can it be done just with additional score text? 

I tried everything, but nothing worked. As I couldn’t find any reference code either, any help is appreciated.

Here my code for, hopefully, making my question clearer:

--Popup Text local playerTitle = display.newText ("...again!", 200 ,200, 350, 25, robotoFont, 25) playerTitle:setFillColor (1,1,0) playerTitle.alpha = 0 transition.to(playerTitle, { time=500, delay=2500, alpha=1.0 },onLocalCollision ) --HERE - this should be happening only when score is achieved! --Obejct "eaten" by the player local myTextBox = display.newText("Go...", 100 ,50, 125, 25, robotoFont, 25 ) myTextBox:setFillColor( 1, 0, 0 ) physics.addBody(myTextBox, "dynamic",{density=1, friction =.3}) physics.setGravity( 1, 10 ) myTextBox.name = "myTextBox" --Player eats Go-object local function onLocalCollision (self, event) &nbsp; &nbsp; &nbsp; &nbsp; if event.phase == "began" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; display.remove (myTextBox) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myTextBox = nil score = score +1 updateText() elseif ( "moved" == phase ) then elseif event.phase == "ended" then end end myTextBox.collision = onLocalCollision myTextBox:addEventListener("collision", myTextBox) playerTitle.collision = onLocalCollision playerTitle:addEventListener("collision", playerTitle)

Tks in advance for any help,

 

 

Patricia

You can place the transition within the event phases of the collision. I’m still not 100% sure as to how you want the transition to happen or what should happen after it, but you can simply call it from where you want it to run.

It is also a good practice to assign your transitions to variables, so that you can control them later on, e.g. pause/cancel.

Plus, if you have some functions that you want to call after the transition ends, you can include them via an onComplete listener like in the code below. This could be useful if you want to hide the text again, in which point you could create a “hideText” function that you call, which by itself contains only another transition to turn the text transparent again. 

 

local transition1 --Player eats Go-object local function onLocalCollision (self, event) if event.phase == "began" then display.remove (myTextBox) myTextBox = nil score = score +1 transition1 = transition.to(playerTitle, { time=500, alpha=1, onComplete=updateText } ) end end

Did this answer your question?

tks for all your help!

sorry to say that your suggestion didn’t work.

I tried something like it before.

The purpose is for the text NOT to be there when the scene starts, fade in when score is achieved (randomly every 3 scores or so) and fade out again

E.G.:

scene begins - no text

0 score - no text

1 score - text fades in and out

5 score - text fades in and out

Problem is still that the text fades in by using time.

In any case, this is at this point a learning excercise which I will use in my game scene later on.

what I’ve tried so far:

additional if statement in onLocalColission, I’ve tried to create another local function for it, I’ve tried to include it in the score function…nothing worked so far, hence why I asked again.

tks again, your help is highly appreciated!

cheers

Well in that case you could perhaps create something along the lines of:
 

local transition1 local nextReveal = 1 local function fadeOut() transition1 = transition.to(playerTitle, { time=500, alpha=0 } ) end --Player eats Go-object local function onLocalCollision (self, event) if event.phase == "began" then display.remove (myTextBox) myTextBox = nil score = score +1 updateText() if score \>= nextReveal then nextReveal = nextReveal + math.random(2,4) --set the next reveal 2 to 4 scores from now -- either reveal the text using a brief transition transition1 = transition.to(playerTitle, { time=500, alpha=1, onComplete=fadeOut } ) -- or just reveal it straight away -- playerTitle.alpha = 1 -- fadeOut() end end end

And just keep the playerTitle.alpha = 0 after you’ve created it, so it’s transparent at the start.

It worked!

As I have only 1 point to achieve yet, I twisted your code around a bit though, but it works now!

local transition1 local function fadeOut() transition1 = transition.to(playerTitle, { time=500, delay=1000, alpha=0 } ) end --Player eats Go-object local function onLocalCollision (self, event) if event.phase == "began" then display.remove (myTextBox) myTextBox = nil score = score +1 updateText() if score \>= 0 then&nbsp; transition1 = transition.to(playerTitle, { time=500, delay=1000, alpha=1, onComplete=fadeOut } ) end end end

Thanks again for your patience and help - you taught me a lot!

cheers

Hey!

The line: “display.newText ( “…again!”, 200 ,200, 350, 25, robotoFont, 25)” calls the display.newText functon and creates a new text object. However, since you don’t assign it to any variable, you cannot control it (easily at least) after creating it.

You assign it to a variable by adding the “local someText = display.newText ( “…again!”, 200 ,200, 350, 25, robotoFont, 25)” in the beginning. Currently you do not assign a variable to it and the reference is therefore lost as soon as you create it. So when you are later trying to delete and set “newText” to nil, it doesn’t do anything because the code can’t find what you mean.

You may also want to read this about scope: https://docs.coronalabs.com/tutorial/basics/scope/index.html

Because of the scope, even if you created a local text object within that if statement, you couldn’t access it outside of it because of scope.

Finally, you can’t change the text colour for the same reason, i.e. there is no reference. The reason why it stays on screen even after you leave the scene is because you don’t add it to a display group. Corona will automatically remove only those display objects that are a part of the scene group. For that, you may want to read: https://docs.coronalabs.com/guide/system/composer/index.html

Thank you XeDuR for coming back to me!

By assigning it to a group (I changed the name as well) -

&nbsp; &nbsp; &nbsp; &nbsp;congratsText = display.newText (uiGroup, "...again!", 200 ,200, 350, 25, robotoFont, 25)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;congratsText:setFillColor (1,1,0)

I managed to change the color and it won’t show on other scenes. 

Yet, I encountered the next problem - the text “…again!”, which should only appear after the collision occurred is there from starters (like any object assigned to a fixed position, I suppose) and “assumes” the same function as the text “Go…!” , meaning, it disappears when the player catches the go.

What I want to achieve is:

                                   player collides/catches “Go”…

                                   player gets 1 point

                                   text “Again” appears and fades away…

I tried it this way, but, obviously, I am still missing something:

                                 

 local function onLocalCollision (self, event) &nbsp;if event.phase == "began" then &nbsp; &nbsp; &nbsp;display.remove (myTextBox) &nbsp; &nbsp; &nbsp;myTextBox = nil &nbsp; &nbsp; &nbsp;score = score +1; &nbsp; &nbsp; &nbsp;updateText(); &nbsp; &nbsp; &nbsp;congratsText.isVisible = false; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; elseif ( "moved" == phase ) then &nbsp; &nbsp; &nbsp; &nbsp; congratsText.isVisible = true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elseif event.phase == "ended" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; display.remove (congratsText)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; congratsText = nil; &nbsp;end myTextBox.collision = onLocalCollision myTextBox:addEventListener("collision", myTextBox)

Tks in advance for any help,

Patricia

No problem, patriCiaFlink :stuck_out_tongue:

When you are posting code to the forums, please insert it by using the code formatting tool < >.

Also, you don’t need to add “;” to the end of your lines in lua.

Now, I am slightly puzzled as to why you add a collision listener to text. This new problem of yours is most likely occurring because when the collision event starts, you begin by removing myTextBox which is a part of the collision and you set it to nil. This means that one of the two colliding objects is removed as soon as the event begins, so it cannot reach the ended phase. If you want to remove it, then wait until the collision ends.

Speaking of which, collision events do not have a “moved” phase and the line

elseif ( "moved" == phase ) then

may actually result in crashing your code.

hi again!

Sorry for not using the formatting tool before.

I added the collision listener to a text because the idea is to catch words roaming the screen. 

Attaching a text to a rect and make the text and rect disappear after collision seems harder to achieve. 

Actually, I was quite happy to have found out that a text is an object which can collide!

I will try and separate that isolated congrats.text from the function collision and I come back here with either the solution or yet another question

thank you again for your help and patience

Patricia

ok, sadly I wasn’t able to do what I wanted to and probably didn’t explain it clearly before. Hopefully I can do so now.

After collision occurred and “myTextBox” is removed, a score is achieved. After that (and then randomly), I want to display a popup text.

From what I’ve been reading, this is “best” done by fade in (transition). I managed a fade in transition, not when the score increases but with a time delay. So, the text “…again!” fades in after x-seconds and not when a score is achieved:(

How is this done? Can fade in be called when an event occurred through a local function? If so, how? or can it be done just with additional score text? 

I tried everything, but nothing worked. As I couldn’t find any reference code either, any help is appreciated.

Here my code for, hopefully, making my question clearer:

--Popup Text local playerTitle = display.newText ("...again!", 200 ,200, 350, 25, robotoFont, 25) playerTitle:setFillColor (1,1,0) playerTitle.alpha = 0 transition.to(playerTitle, { time=500, delay=2500, alpha=1.0 },onLocalCollision ) --HERE - this should be happening only when score is achieved! --Obejct "eaten" by the player local myTextBox = display.newText("Go...", 100 ,50, 125, 25, robotoFont, 25 ) myTextBox:setFillColor( 1, 0, 0 ) physics.addBody(myTextBox, "dynamic",{density=1, friction =.3}) physics.setGravity( 1, 10 ) myTextBox.name = "myTextBox" --Player eats Go-object local function onLocalCollision (self, event) &nbsp; &nbsp; &nbsp; &nbsp; if event.phase == "began" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; display.remove (myTextBox) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myTextBox = nil score = score +1 updateText() elseif ( "moved" == phase ) then elseif event.phase == "ended" then end end myTextBox.collision = onLocalCollision myTextBox:addEventListener("collision", myTextBox) playerTitle.collision = onLocalCollision playerTitle:addEventListener("collision", playerTitle)

Tks in advance for any help,

 

 

Patricia

You can place the transition within the event phases of the collision. I’m still not 100% sure as to how you want the transition to happen or what should happen after it, but you can simply call it from where you want it to run.

It is also a good practice to assign your transitions to variables, so that you can control them later on, e.g. pause/cancel.

Plus, if you have some functions that you want to call after the transition ends, you can include them via an onComplete listener like in the code below. This could be useful if you want to hide the text again, in which point you could create a “hideText” function that you call, which by itself contains only another transition to turn the text transparent again. 

 

local transition1 --Player eats Go-object local function onLocalCollision (self, event) if event.phase == "began" then display.remove (myTextBox) myTextBox = nil score = score +1 transition1 = transition.to(playerTitle, { time=500, alpha=1, onComplete=updateText } ) end end

Did this answer your question?

tks for all your help!

sorry to say that your suggestion didn’t work.

I tried something like it before.

The purpose is for the text NOT to be there when the scene starts, fade in when score is achieved (randomly every 3 scores or so) and fade out again

E.G.:

scene begins - no text

0 score - no text

1 score - text fades in and out

5 score - text fades in and out

Problem is still that the text fades in by using time.

In any case, this is at this point a learning excercise which I will use in my game scene later on.

what I’ve tried so far:

additional if statement in onLocalColission, I’ve tried to create another local function for it, I’ve tried to include it in the score function…nothing worked so far, hence why I asked again.

tks again, your help is highly appreciated!

cheers

Well in that case you could perhaps create something along the lines of:
 

local transition1 local nextReveal = 1 local function fadeOut() transition1 = transition.to(playerTitle, { time=500, alpha=0 } ) end --Player eats Go-object local function onLocalCollision (self, event) if event.phase == "began" then display.remove (myTextBox) myTextBox = nil score = score +1 updateText() if score \>= nextReveal then nextReveal = nextReveal + math.random(2,4) --set the next reveal 2 to 4 scores from now -- either reveal the text using a brief transition transition1 = transition.to(playerTitle, { time=500, alpha=1, onComplete=fadeOut } ) -- or just reveal it straight away -- playerTitle.alpha = 1 -- fadeOut() end end end

And just keep the playerTitle.alpha = 0 after you’ve created it, so it’s transparent at the start.

It worked!

As I have only 1 point to achieve yet, I twisted your code around a bit though, but it works now!

local transition1 local function fadeOut() transition1 = transition.to(playerTitle, { time=500, delay=1000, alpha=0 } ) end --Player eats Go-object local function onLocalCollision (self, event) if event.phase == "began" then display.remove (myTextBox) myTextBox = nil score = score +1 updateText() if score \>= 0 then&nbsp; transition1 = transition.to(playerTitle, { time=500, delay=1000, alpha=1, onComplete=fadeOut } ) end end end

Thanks again for your patience and help - you taught me a lot!

cheers