Text issue

Hi everyone,

I’m realy new to Panda3d and to Python. I’m trying to make a animation at the beginning of my game saying “blablabla entertainment presents”.

I want the text to be black(invisible on the black background) and slowly become white. Also, I want the text to become bigger or smaller. And also a starting point and a ending point.

I know it’s a lot of things at the same time so I started with the color change.

Here is my code, I don’t know if I use the good way to do this kind of things but anyway it doesn’t work. (See error below code)

Code:

import direct.directbase.DirectStart 
from direct.task import Task 
from pandac.PandaModules import *     
from direct.gui.DirectGui import *    
                                      
import sys

class World:                          
  def __init__(self):                 
    text = TextNode('company') 
    text.setText("blablabla Entertainment Presents") 
    textNodePath = aspect2d.attachNewNode(text) 
    textNodePath.setScale(0.1) 
    #text color
    text.setTextColor(1, 1, 1, 1) 
    #text shadow
    text.setShadow(0.1, 0.1) 
    text.setShadowColor(1, 0, 0, 1)
    #text centered
    text.setAlign(TextNode.ACenter) 
    #text position
    #???
    indice = 0
  
    base.setBackgroundColor(0, 0, 0)
    base.disableMouse()

    #Task to move the camera 
    def ChangeColorTask(task): 
        indice = indice + 0.01
 
        text.setTextColor(1,1,1,1) 
        if task.time < 2.0: 
            return Task.cont 
        print 'Done'
        return Task.done 

    taskMgr.add(ChangeColorTask, "ChangeColorTask") 


w = World()
run()

The error is:
File “welcome.py”, line 30, in ChangeColorTask
indice = indice + 0.01
UnboundLocalError: local variable ‘indice’ referenced before assignment

So, maybe the method I use is not the right one! Please help me :slight_smile:

Thanks!!

Jaff

Panda has powerful interval classes, why don’t you use them ?

from pandac.PandaModules import *
import direct.directbase.DirectStart
from direct.interval.IntervalGlobal import *
from direct.gui.OnscreenText import OnscreenText
import sys

def pingpongIval(ival,wait=0):
    return Sequence(
              ival,  # play interval normally (forward)
              Wait(wait),  # delay it for a while before playing it backward
              Func(ival.start,0,ival.getDuration(),-1),  # play interval backward
              Wait(ival.getDuration())  # wait until the backward playback finishes
              )

def playIntroMovie():
    OnscreenText( 'Where is your movie ?\nPlay it !', fg=(1,1,1,1), shadow=(1, 0, 0, 1) )

base.setBackgroundColor(0, 0, 0)
dev = OnscreenText( 'XYZ  Entertainment\npresents',
                    scale=.1, fg=(1,1,1,1), shadow=(1, 0, 0, 1),
                    )
duration=2
devFadeIval = dev.colorScaleInterval(duration,Vec4(1,1,1,1),startColorScale=Vec4(1,1,1,0),blendType='easeOut')
devGrowIval = dev.scaleInterval(duration,1.2,blendType='easeOut')
devAllIvals = Parallel( devFadeIval,devGrowIval )  # change SCALE and COLOR SCALE concurently

# now play the Parallel forward and backward (pingpong), and then I'd like to play a movie
Sequence(
         pingpongIval(devAllIvals,wait=.5),  # do pingpong play with .5 second delay
         Func(playIntroMovie),
         ).start()

    
run()

In there, I change the alpha instead. I also add a delayed pingpong method, since there is no built-in one.

About your indice, it belongs locally to init, not ChangeColorTask.

Thanks man!

I will try that during the weekend!

Do you have a suggestion to get the text moving?(Because as I can see, in your code you can change the scale and the color, but not the position).

Thanks again!

Jaff

Sure, try out the posInterval.
Or, if that does not give you enough control, you can always try the LerpPosInterval.

Ok so I try your code, it works perfect and I think I understand 95% of it. Now I want to do a big beginning with like the producer, actor, etc… So a lot of text, each with a animation. I try with 2 text, as you will see in my code below. It works but I was wondering if there was a way to create a “general function” so that I don’t need to create 99999 variables like texte1 and texte2, etc… I tried to reasign a value in texte1 but it doesn’t work. Also, when I start the code below, the second text appear in front of the first … Please help :slight_smile:

from pandac.PandaModules import *
import direct.directbase.DirectStart
from direct.interval.IntervalGlobal import *
from direct.gui.OnscreenText import OnscreenText
import sys


class Presentation:
 
    texte1 = OnscreenText('Dark Rage Entertainment', scale=.1, fg=(1,1,1,1), shadow=(0,0,0,1),)
    texte2 = OnscreenText('Presents', scale=.2, fg=(1,1,1,1), shadow=(0,0,0,1),)
    duration = 4 
        
    #Cette fonction exécute une séquence à l'endroit et ensuite à l'envers.
    def pingpongIval(ival, wait=0):
        return Sequence(
                    ival, 
                    Wait(wait),
                    Func(ival.start, 0, ival.getDuration(),-1),
                    Wait(ival.getDuration())
                    )
    
    base.setBackgroundColor(0,0,0)

    texte1FadeIval = texte1.colorScaleInterval(duration, Vec4(1,1,1,1), startColorScale=Vec4(1,1,1,0), blendType='easeOut')
    texte1GrowIval = texte1.scaleInterval(duration, 1.2, blendType='easeOut')
    texte1AllIvals = Parallel(texte1FadeIval, texte1GrowIval)
    
    texte2FadeIval = texte2.colorScaleInterval(duration, Vec4(1,1,1,1), startColorScale=Vec4(1,1,1,0), blendType='easeOut')
    texte2GrowIval = texte2.scaleInterval(duration, 1.2, blendType='easeOut')
    texte2AllIvals = Parallel(texte2FadeIval, texte2GrowIval)
        
    #now play the parallel forward and backward (pingpong) and then I'dlike to play a movie
    Sequence(
                 pingpongIval(texte1AllIvals, wait=1.5),
                 pingpongIval(texte2AllIvals, wait=1.5)
                 ).start()
             
w = Presentation()                

run()

Thank you for your help and you patience!

Jaff

P.S: Sorry for the commentaries, they are in french!

Of course the 2nd appears in front because it’s created later than the 1st. Before playing any of the text interval, each one must be hidden first.
How about this :

from pandac.PandaModules import *
import direct.directbase.DirectStart
from direct.interval.IntervalGlobal import *
from direct.gui.OnscreenText import OnscreenText
import sys


class Presentation:

    def __init__(self):
        base.setBackgroundColor(0,0,0)
        fadeDuration = 2
        texts=(
              OnscreenText('Dark Rage Entertainment', scale=.1, fg=(1,1,1,1), shadow=(0,0,0,1),),
              OnscreenText('Presents', scale=.2, fg=(1,1,1,1), shadow=(0,0,0,1),),
              OnscreenText('TEXT 1', scale=.05, fg=(1,1,1,1), shadow=(0,0,0,1),),
              OnscreenText('TEXT 2', scale=.05, fg=(1,1,1,1), shadow=(0,0,0,1),),
              OnscreenText('TEXT 3', scale=.05, fg=(1,1,1,1), shadow=(0,0,0,1),),
              OnscreenText('END_OF_TEXT', scale=.05, fg=(1,1,1,1), shadow=(0,0,0,1),),
              )
        devIval = self.createFadeInGrowTexts(texts,fadeDuration,textSwitchDelay=.75)
        devIval.start()

    #Cette fonction exécute une séquence à l'endroit et ensuite à l'envers.
    def pingpongIval(self,ival, wait=0):
        return Sequence(
                    ival,
                    Wait(wait),
                    Func(ival.start, 0, ival.getDuration(),-1),
                    Wait(ival.getDuration())
                    )

    def createFadeInGrowTexts(self,texts,fadeDuration,textSwitchDelay=0):
        seq = Sequence()
        for texte in texts:
            texte.hide()
            fadeInGrow = Parallel(
                            texte.colorScaleInterval(fadeDuration, Vec4(1,1,1,1), startColorScale=Vec4(1,1,1,0), blendType='easeOut'),
                            texte.scaleInterval(fadeDuration, 1.2, blendType='easeOut')
                            )
            seq.append( Sequence(
                           Func(texte.show),
                           self.pingpongIval(fadeInGrow, wait=1.5),
                           Func(texte.destroy),
                           Wait(textSwitchDelay),  # <---- give some delay between text
                           )
                      )
        return seq


w = Presentation()

run()

You could use any number of text by adding them to texts.

Thanks again!

That’s exactly what I was looking for being an oriented object freak and reusability fanatic! This simple example will help me a lot understand the python and panda3d.

Have a great day!

Jaff