Text typeout effect

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

N_K
Just popping in
Just popping in
Posts: 13
Joined: Thu May 24, 2012 22:38

Text typeout effect

Postby N_K » Sat Aug 11, 2012 04:37

Hello all.

I'm not sure if this has been asked before, I didn't find anything on this forum, but this could be because I have no idea what is this effect supposed to be called...

I'd like to achieve a delayed text output effect, similiar to the system found in visual novels and oldschool RPG games. (Here's a video of a visual novel engine prototype showing this kind of text output.) However, I'm not sure where to start. I know CEGUI has an animation system, but after reading through the wiki and the documentation, it seems that it has no support for text effects yet. How is this supposed to be done? Store the desired string in an array, then tell CEGUI to draw it as a static text, element by element, with a specific delay?

Or even better, has anyone did this before, and willing to share some bits of code to give me some clues about this? :)

Thank you in advance.

MorbidAngel
Just popping in
Just popping in
Posts: 18
Joined: Sat Aug 04, 2012 16:35

Re: Text typeout effect

Postby MorbidAngel » Sat Aug 11, 2012 12:57

You could just create a layout with a DefaultWindow type and a StaticText control. If you want it delayed like in your video then you would need to create some custom class for it with a timer on it.

I haven't looked much into the Animation feature in CEGUI yet, haven't had a need to use it for any of my projects.

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

Re: Text typeout effect

Postby CrazyEddie » Mon Aug 13, 2012 09:04

I believe that text can be animated in that way with the animation system.

See also what Ident is doing here:


Ident's GSoC project is not finished (and so not merged yet), but you can see his code here: https://bitbucket.org/Ident8/cegui-gsoc ... s/GameMenu

HTH

CE.

HeeM
Just popping in
Just popping in
Posts: 1
Joined: Tue Sep 16, 2014 09:14

Re: Text typeout effect

Postby HeeM » Tue Jan 26, 2016 02:46

Hello, I have made a code with making customized text typeout animation in runtime

it's made with lua. and using some global variable for managing created animation instances.

and.. have fun :D

Code: Select all

-- from https://forums.coronalabs.com/topic/42019-split-utf-8-string-word-with-foreign-characters-to-letters/
local UTF8ToCharArray = function(str)
    local charArray = {};
    local iStart = 0;
    local strLen = str:len();
   
    local function bit(b)
        return 2 ^ (b - 1);
    end
 
    local function hasbit(w, b)
        return w % (b + b) >= b;
    end
   
    local checkMultiByte = function(i)
        if (iStart ~= 0) then
            charArray[#charArray + 1] = str:sub(iStart, i - 1);
            iStart = 0;
        end       
    end
   
    for i = 1, strLen do
        local b = str:byte(i);
        local multiStart = hasbit(b, bit(7)) and hasbit(b, bit(8));
        local multiTrail = not hasbit(b, bit(7)) and hasbit(b, bit(8));
 
        if (multiStart) then
            checkMultiByte(i);
            iStart = i;
           
        elseif (not multiTrail) then
            checkMultiByte(i);
            charArray[#charArray + 1] = str:sub(i, i);
        end
    end
   
    -- process if last character is multi-byte
    checkMultiByte(strLen + 1);
 
    return charArray;
end

g_alreadyGenerated = {};
g_typingAnimationID = 0;   -- for unique animation ID
function StartTypingAnimation(win, text, typingSpeed, typingPostfix)
   -- setting
   local typingSpeed = (typingSpeed or 0.1) / 2;   -- by default, it shows out a text per 0.1 sec
   local typingPostfix = typingPostfix or '_';
   -----------------
   
   -- delete previous animation
   local prevInfo = g_alreadyGenerated[win];
   if prevInfo then
      local connection = prevInfo.Connection;
      local prevAnimation = prevInfo.Animation;
      connection:disconnect();
      CEGUI.AnimationManager:getSingleton():destroyAllInstancesOfAnimation(prevAnimation);
      CEGUI.AnimationManager:getSingleton():destroyAnimation(prevAnimation);
      g_alreadyGenerated[win] = nil;
   end
   
   -- make animation
   g_typingAnimationID = g_typingAnimationID + 1;
   local animation = CEGUI.AnimationManager:getSingleton():createAnimation('_TypeoutAnimation'..g_typingAnimationID);
   animation:setReplayMode(CEGUI.Animation.RM_Once);
   animation:setAutoStart(true);
   local affector = animation:createAffector('Text', 'String');
   affector:setApplicationMethod(CEGUI.Affector.AM_Absolute);
   
   local timePos = 0;
   local textInTime = '';
   local skipBrackets = win:isTextParsingEnabled();
   local bracketDepth = 0;
   local remainTextArray = UTF8ToCharArray(text);
   local totalCharCount = #remainTextArray;
   
   affector:createKeyFrame(0, '');   -- first frame;
   for i, c in ipairs(remainTextArray) do
      textInTime = textInTime .. c;
      if c == '[' then
         bracketDepth = bracketDepth + 1;
      elseif c == ']' then
         bracketDepth = math.max(0, bracketDepth - 1);
      end
      if not skipBrackets or bracketDepth == 0 then
         timePos = timePos + typingSpeed;
         local showText = textInTime;
         if i < totalCharCount then
            showText = showText .. typingPostfix;
         end
         affector:createKeyFrame(timePos, showText);
      end
   end
   if skipBrackets and bracketDepth > 0 then   -- ends with backets not matched just add last frame to show text
      timePos = timePos + typingSpeed;
      affector:createKeyFrame(timePos, textInTime);
   end
   animation:setDuration(timePos);
   
   local instance = CEGUI.AnimationManager:getSingleton():instantiateAnimation(animation);
   instance:setTargetWindow(win);
   
   -- subscribe a destruction event for make sure the animation to be deleted with window destroy
   local connection = win:subscribeEvent('DestructionStarted', function(e)
      local we = CEGUI.toWindowEventArgs(e);
      g_alreadyGenerated[we.window] = nil;
      CEGUI.AnimationManager:getSingleton():destroyAllInstancesOfAnimation(animation);
      CEGUI.AnimationManager:getSingleton():destroyAnimation(animation);
      return true;
   end);
   
   -- register global variable
   g_alreadyGenerated[win] = {Connection = connection, Animation = animation};
   
   -- clear up window
   win:setText('');
end


ps. you can just call like 'StartTypingAnimation(window, 'ABCD')' to use this


Return to “Help”

Who is online

Users browsing this forum: No registered users and 2 guests