How to display text by one character per one frame?

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

vroad
Just popping in
Just popping in
Posts: 6
Joined: Sun Sep 12, 2010 12:27

How to display text by one character per one frame?

Postby vroad » Sun Sep 12, 2010 14:52

Even I'm a new user of CEGUI, but I posted this topic to "Advanced Help" because I think this process may require modification of library.

I'm creating visual novel game, so it is needed to displaying text by one character.
Which file I should modify at first?
CEGUI's Animation fucntion may be able to do this animation, but I don't know how to do.

Because of language of video game is Japanese,
Japense hyphenation and displaying ruby character is also needed, but I question them later.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: How to display text by one character per one frame?

Postby CrazyEddie » Mon Sep 13, 2010 08:55

While I think the animation system can do this, I don't think it's really realistic to set that up (because you'd need to provide each stage of that 'animation' in a separate KeyFrame). If this is incorrect, hopefully Kulik will correct me ;)

The 'best' way, I think, would be to have some custom code that sets the text from a given string over time. Meaning, whenever the next text update gets triggered (which I wouldn't do each frame, because it's not a constant time), just append the next character.

CE.

vroad
Just popping in
Just popping in
Posts: 6
Joined: Sun Sep 12, 2010 12:27

Re: How to display text by one character per one frame?

Postby vroad » Mon Sep 13, 2010 12:35

:oops: I messed up! Seems I hit the 'edit' button instead of the 'quote' button.

I see.
First, handle OnTextChanged event and store time that the text was changed, and last text length.
On update, append next character according to elapsed parameter.
Is that right?

Yeah, that's one way, for sure.

However, I also want to use ruby character because difficult kanji appears in game.

http://en.wikipedia.org/wiki/Ruby_character

Seeing the code, I thought that I should add extended class of "RenderedStringComponent" that shows ruby character on text.
If tags are used, It is difficult to use this method.(And I don't know how to write tags for BasicRenderedStringParser...)
In addition, RB and RT(For example, "東京" and "とうきょう") are already parsed on initialization of game.(Scenario of visual novel is written in XML)
I don't want to do parsing after initialization...

Do you need these ruby characters to appear above or beside the character that they relate to? I don't have any experience of this type of thing so I can't realistically be expected to make suggestions. I'd need to investigate this a lot more, though I don't have any time for that at the moment.

CE.

Rincevent
Not too shy to talk
Not too shy to talk
Posts: 22
Joined: Thu Oct 08, 2009 20:42

Re: How to display text by one character per one frame?

Postby Rincevent » Mon Aug 08, 2011 10:17

Hi,

I would also be interested by such a feature like animated scrolling text.
I was wondering if something like this could be integrated to the current animation framework.
I am ready to help with the implementation, all I would need is a bit of help to point me to which
part of the code I should look at and what would be the best way to implement such feature into CEGUI.

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: How to display text by one character per one frame?

Postby Kulik » Mon Aug 08, 2011 14:26

It could be done by making additional string interpolator that would somehow "morph" one string to another, possibly character by character. You would then have keyframe at 0.0s having value "" and keyframe at 20.0s having value "Testing text" and in 20.0s the animation would write that text out. Is that what you want to achieve?

Basically you have to convert the animation's idea into keyframes and interpolators as this is what CEGUI's anim system works with. It can be done for most animations I think, it's just a matter of having special interpolators for some corner cases.

Some introductory material on animations - http://www.cegui.org.uk/wiki/index.php/Animation_System

Rincevent
Not too shy to talk
Not too shy to talk
Posts: 22
Joined: Thu Oct 08, 2009 20:42

Re: How to display text by one character per one frame?

Postby Rincevent » Mon Aug 08, 2011 16:13

Oh I see. You are right what I try to achieve would work by using 2 keyframes, one for the beginning with no text and one for the full text at the end.
Then setting the animation to the "text" property should work.

Now concerning the string interpolator, is it possible to provide custom user made interpolator without touching at CEGUI source code or will I need to modify cegui source?

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: How to display text by one character per one frame?

Postby Kulik » Mon Aug 08, 2011 16:50

You can do it without touching CEGUI source, see http://www.cegui.org.uk/docs/current/cl ... 0d8ca7939d

I would very much like this per character string morpher integrated into CEGUI. If you make it generic (from "abc" to "cba" by doing "cbc", "cbc", "cba") and clean enough I will integrate it to 0.8.

Rincevent
Not too shy to talk
Not too shy to talk
Posts: 22
Joined: Thu Oct 08, 2009 20:42

Re: How to display text by one character per one frame?

Postby Rincevent » Mon Aug 08, 2011 20:45

OK thanks a lot. I am going to have a look into this and play a little bit with it.
Then once I have something running and clean enough I will post the code here.

Rincevent
Not too shy to talk
Not too shy to talk
Posts: 22
Joined: Thu Oct 08, 2009 20:42

Re: How to display text by one character per one frame?

Postby Rincevent » Tue Aug 09, 2011 09:54

Ok so I played with the animation and got something which seem to work quite nicely.
The only part I do not really know how to do is the interpolateRelativeMultiply function as I am not
even sure what this is used for. So I might need some help here.
For the rest here is the created source code. Feel free to integrate it to CEGUI if you whish.

Here is the class declaration

Code: Select all

class StringMorphInterpolator : public Interpolator
{
public:

   virtual ~StringMorphInterpolator(void){}

    virtual const String& getType() const;

    virtual String interpolateAbsolute(const String& value1,
                                       const String& value2,
                                       float position);
    virtual String interpolateRelative(const String& base,
                                       const String& value1,
                                       const String& value2,
                                       float position);
    virtual String interpolateRelativeMultiply(const String& base,
            const String& value1,
            const String& value2,
            float position);

protected:
   String combineStrings(const String& str1, const String& str2, float position);
};


Then the class source:

Code: Select all

/********************************************
* StringMorph interpolator
********************************************/
const String& StringMorphInterpolator::getType() const
{
    static String type = "StringMorph";
    return type;
}

//----------------------------------------------------------------------------//
String StringMorphInterpolator::interpolateAbsolute(const String& value1,
        const String& value2,
        float position)
{
    return combineStrings(value1, value2, position);
}

//----------------------------------------------------------------------------//
String StringMorphInterpolator::interpolateRelative(const String& base,
        const String& value1,
        const String& value2,
        float position)
{
    return base + combineStrings(value1, value2, position);
}

//----------------------------------------------------------------------------//
String StringMorphInterpolator::interpolateRelativeMultiply(const String& base,
        const String& value1,
        const String& value2,
        float position)
{
    // todo: not sure what to do here
    return base;
}

//----------------------------------------------------------------------------//
String StringMorphInterpolator::combineStrings(const String& str1, const String& str2, float position)
{
   String::size_type s1size = str1.size();
   String::size_type s2size = str2.size();

   if(s1size <= s2size)
   {
      // the result string should grow
      String::size_type s2partsize = static_cast<String::size_type>(s2size*position);
      String::size_type ressize = std::max(s1size, s2partsize);

      String res(str1);
      res.resize(ressize);
      for(String::size_type i=0; i< s2partsize; ++i)
         res[i] = str2[i];

      return res;
   }
   else
   {
      //the result string should shrink
      String::size_type s1partsize = static_cast<String::size_type>(s1size*(1-position));
      String::size_type s2partsize = ((s1partsize>s2size)?0:s2size-s1partsize);
      String::size_type ressize = std::max(s1partsize, s2size);

      String res(str1.substr(s1size-s1partsize-s2partsize));
      for(String::size_type i=0; i< s2partsize; ++i)
         res[i] = str2[i];

      return res;
   }
}


And a sample I used to test it:

Code: Select all

      CEGUI::Affector* affector = anim->createAffector("Text", "StringMorph");
      affector->createKeyFrame(0.0f, "Normal string");
      affector->createKeyFrame(5.0f, "A very very very long string");
      affector->createKeyFrame(10.0f, "spdfposdfjopsdjfopsdfopjploupi");
      affector->createKeyFrame(15.0f, "Short test");

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: How to display text by one character per one frame?

Postby Kulik » Tue Aug 09, 2011 11:41

Very nice, the interpolate relative multiply probably doesn't make sense in this case, it multiplies the base by a float.

I would like to integrate this to CEGUI 0.8, could you PM me your name so that I can add you to AUTHORS?


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 6 guests