1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

Animation Text Reveal - Advanced Typewriter

Discussion in 'Tutorials' started by L0v3, Sep 3, 2016.

  1. L0v3

    L0v3 Guest

    GM Version: Studio v1.4.1750
    Target Platform: ALL
    Download:N/A
    Links: N/A

    Summary:

    Animates a draw_text_ext with a typewriter, alpha and color transition effect for individual chars.
    This causes an effect similar to what you see in this video:




    Tutorial:

    To implement this into your project, simply import given scripts and objects then use it like so:

    Code:
    animation = animation_text_reveal(false, 0, room_seconds(8), 0.2, 0.05, 0.025, c_red, c_white, fnt_arial_68_b, fa_center, fa_middle, room_width / 2, room_height / 2 - 50, "DSEngine#Text Animation Effect", 100, room_width);
    

    It's a fire once and forget animation. If you wish to manipulate it, you can use the user_defined events 0, 1, 3, 5 to pause, unpause, start fadeout and show all text immedieatly. Useful for implementation in systems such as a dialogue engine.

    Code:
    with (animation)
    {
        event_user(0); //Pauses animation.
    }
    
    with (animation)
    {
        event_user(1); //Resumes animation.
    }
    
    with (animation)
    {
        event_user(3); //Starts fadeout.
    }
    
    with (animation)
    {
        event_user(5); //Shows all text.
    }
    

    Here is all the associated code you need to copy into your game:

    Code:
    ///animation_text_reveal(gui, depth, duration, tspd, cspd, aspd, color1, color2, font, halign, valign, x, y, string, sep, width);
    
    // Animates a draw_text_ext with a typewriter, alpha and color transition effect for individual chars.
    // Returns the animation engine object, which can be manipulated by calling it's user_defined events to
    // pause, unpause, start fadeout or show all text immedieatly.
    // Use -1 as duration to have it last forever or until destroyed manually or upon room end.
    
    // gui              = Boolean if draw_gui should be used (True) or normal draw event (False).
    // depth            = Drawing depth to be used.
    // duration         = Total duration for text in steps. -1 to last forever.
    // tspd             = Speed of the text reveal typewriter effect in characters per step.
    // cspd             = Speed of the color transition effect in decimals per step.
    // aspd             = Speed of the alpha transition effect in decimals per step.
    // color1           = Initial starting color of text. Usually short for cinematic effect.
    // color2           = Final end color of text. Resting color once animation complete.
    // font             = Font resource to be used for drawing.
    // halign           = The horizontal drawing alignment for drawing.
    // valign           = The vertical drawin alignment for drawing.
    // x                = The x coordinate of the drawn string.
    // y                = The y coordinate of the drawn string.
    // string           = The string to draw.
    // sep              = The distance in pixels between lines of text.
    // width            = The maximum width in pixels of the string before a line break.
    
    // Dependencies: eng_animation_text_reveal, string_array_page_parser
    
    // @Return: Instance of eng_animation_text_reveal.
    
    //Converts arguments to locals.
    var gui = argument0;
    var draw_depth = argument1;
    var duration = argument2;
    var tspd = argument3;
    var cspd = argument4;
    var aspd = argument5;
    var color1 = argument6;
    var color2 = argument7;
    var font = argument8;
    var halign = argument9;
    var valign = argument10;
    var xx = argument11;
    var yy = argument12;
    var text = argument13;
    var sep = argument14;
    var width = argument15;
    
    //Creates engine object.
    var obj = instance_create(xx, yy, eng_animation_text_reveal);
    
    //Sends over variables.
    with (obj)
    {
        depth = draw_depth;
        self.gui = gui;
        self.duration = duration;
        self.tspd = tspd;
        self.cspd = cspd;
        self.aspd = aspd;
        self.color1 = color1;
        self.color2 = color2;
        self.font = font;
        self.halign = halign;
        self.valign = valign;
        self.xx = xx;
        self.yy = yy;
        self.text = text;
        self.sep = sep;
        self.width = width;
    }
    
    //Delayed creation code.
    with (obj)
    {
        event_user(2);
    }
    
    //Returns object.
    return obj;
    

    Code:
    ///string_array_page_parser(string, array, width, height, font, halign, valign, [sep])
    
    // Parses the given string into an array. Each index in the array will contain all associated text for the page.
    // Note: Array should be empty as will overwrite any elements in it. Index 0 will contain the first page, and so on.
    // Returns the total amount of pages in the array.
    
    // string           = String to be parsed and stored into the array.
    // array            = Array for string to be stored in.
    // width            = Maximum width of the string, before a new line is to be created.
    // height           = Maximum height of a page, before a new page is to be created.
    // font             = Font to do calculations with. Should be same as potiental draw font.
    // halign           = Horizontal alignment to do drawing calcuations with.
    // valign           = Vertical alignment to do drawing calcuations with.
    // sep              = Optional argument. Distance between new lines of text. Default font size / 2.
    
    // @Return: Amount of pages that have been created.
    
    //Converts arguments to locals.
    var text = argument[0];
    var array = argument[1];
    var page_width = argument[2];
    var page_height = argument[3];
    var font = argument[4];
    var halign = argument[5];
    var valign = argument[6];
    var sep = font_get_size(font) / 2;
    
    //Optional Arguments
    if (argument_count = 8)
    {
        sep = argument[7]
    }
    
    //Setups variables for loop.
    draw_set_font(font);
    draw_set_halign(halign);
    draw_set_valign(valign);
    var current = 1;
    var total = 1;
    var length = string_length(text) + 1;
    var page_count = 0;
    
    //Enters a loop for each letter.
    while (total < length)
    {  
        //Makes a copy for current page.
        var copy = string_copy(text, 1, current);
     
        //Stores the page.
        array[@page_count] = copy;
     
        //Checks for line break.
        if (string_char_at(copy, current) = "#" and string_char_at(copy, current-1) != "\")
        {
            //Clears the main text string, to calculate for new page.
            text = string_delete(text, 1, current);
            current = 0;
         
            //Increments Page Count.
            page_count += 1;
        }
     
        //Calcuates the height of current copy.
        var height = string_height_ext(copy, sep, page_width);
     
        //Checks to see if new page.
        if (height >= page_height)
        {                  
            //Checks ahead for word completion.
            var skip = 0;
            for (var i = current; i < length; i++)
            {
                //Checks for space.
                if (string_char_at(text, i) = " ")
                {
                    skip = i;
                    break;
                }
            }
    
            //If word completion ahead.
            if (skip != 0)
            {
                //Checks behind for word start.
                var start = 0;
                for (var i = current; i > 1; i--)
                {
                    //Checks for space.
                    if (string_char_at(text, i) = " ")
                    {
                        start = i;
                        break;
                    }
                }
             
                //Checks if word start.
                if (start != 0)
                {
                    //Updates copy for current page.
                    copy = string_copy(text, 1, start);
                    array[@page_count] = copy;
                }
            }
         
            //Decrements Strings.
            var delta = start - current;
            current += delta;
            total += delta;
         
            //Clears the main text string, to calculate for new page.
            text = string_delete(text, 1, current);
            current = 0;
         
            //Increments Page Count.
            page_count += 1;
        }
     
        //Increments Strings.
        current += 1;
        total += 1;
    }
    
    //Returns final page count.
    return page_count;
    

    Code:
    Information about object: eng_animation_text_reveal
    Sprite:
    Solid: false
    Visible: true
    Depth: 0
    Persistent: false
    Parent:
    Children:
    Mask:
    No Physics Object
    Create Event:
    execute code:
    
    ///Creation Code
    
    //Data Variables
    gui = noone;
    duration = noone;
    tspd = noone;
    cspd = noone;
    aspd = noone;
    color1 = noone;
    color2 = noone;
    font = noone;
    halign = noone;
    valign = noone;
    xx = noone;
    yy = noone;
    text = noone;
    sep = noone;
    width = noone;
    
    //Instance Variables
    chars = ds_list_create();
    lines[0] = noone;
    hoffset = noone;
    voffset = noone;
    fadeout = false;
    paused = false;
    total = 0;
    count = 0;
    step = 0;
    line = 0;
    
    Destroy Event:
    execute code:
    
    ///Cleans-Up Leaks
    for (var i = 0; i < ds_list_size(chars); i++)
    {
        var data = ds_list_find_value(chars, i);
        ds_list_destroy(data);
    }
    ds_list_destroy(chars);
    
    Step Event:
    execute code:
    
    ///Animation Update
    
    //Checks if paused.
    if (paused) exit;
    
    //Typewriter Effect
    if (count < string_length(text))
    {
        //Increments count.
        count += tspd;
        total = clamp(ceil(count), 0, ds_list_size(chars));
    }
    
    //Color Effect
    for (var i = 0; i < total; i++)
    {
        //Updates color value for char.
        var data = ds_list_find_value(chars, i);
        var color = ds_list_find_value(data, 0);
        color = clamp(color + cspd, 0, 1);
        ds_list_replace(data, 0, color);
    }
    
    //Alpha Effect
    for (var i = 0; i < total; i++)
    {
        //Checks for fadeout.
        if (!fadeout)
        {
            //Updates alpha value for char.
            var data = ds_list_find_value(chars, i);
            var alpha = ds_list_find_value(data, 1);
            alpha = clamp(alpha + aspd, 0, 1);
            ds_list_replace(data, 1, alpha);
        }
    }
    
    //Checks if infinite duration.
    if (duration = -1) exit;
    
    //Increments step for alarm.
    step++;
    
    //Check for fadeout start.
    if (!fadeout and step > fadeout_start)
    {
        fadeout = true;
    }
    
    //Checks if fadeout.
    if (fadeout)
    {
        //Fadeout Alpha Effect
        for (var i = 0; i < ds_list_size(chars); i++)
        {
            //Updates alpha value for char.
            var data = ds_list_find_value(chars, i);
            var alpha = ds_list_find_value(data, 1);
            alpha = clamp(alpha - aspd, 0, 1);
            ds_list_replace(data, 1, alpha);
        }
     
        //Check for fadeout complete.
        if (step = duration)
        {
            //Suicide
            instance_destroy();
        }
    }
    
    Other Event: Room End:
    execute code:
    
    ///Calls Destroy Event
    instance_destroy();
    
    Other Event: User Defined 0:
    execute code:
    
    ///Pauses Animation
    paused = true;
    
    Other Event: User Defined 1:
    execute code:
    
    ///Resumes Animation
    paused = false;
    
    Other Event: User Defined 2:
    execute code:
    
    ///Delayed Creation Code
    
    //Calculates fadeout start.
    if (duration != -1)
    {
        fadeout_start = duration - (1 / aspd);
    }
    
    //Setup line array.
    draw_set_font(font);
    var height = string_height("Height String") + 1;
    string_array_page_parser(text, lines, width, height, font, halign, valign, sep);
    
    //Enters a loop for each line.
    for (var i1 = 0; i1 < array_length_1d(lines); i1++)
    {
        //Determines offset for line.
        line = i1;
        event_user(4);
        var line_width = 0;
     
        //Enters a loop for each char.
        for (var i2 = 1; i2 < string_length(lines[i1]) + 1; i2++)
        {
            //Determins variables.
            var char = string_char_at(lines[i1], i2);
            var x1 = xx - hoffset + line_width;
            var y1 = yy - voffset + sep * i1;
         
            //Creates character data.
            var data = ds_list_create();
            ds_list_add(data, 0); //Color
            ds_list_add(data, 0); //Alpha
            ds_list_add(data, char); //Char
            ds_list_add(data, x1); //x-pos
            ds_list_add(data, y1); //y-pos
         
            //Updates variables.
            ds_list_add(chars, data);
            line_width += string_width(char);
        }
    
    }
    
    Other Event: User Defined 3:
    execute code:
    
    ///Starts Fadeout
    
    //Checks if infinite duration.
    if (duration = -1) exit;
    
    //Updates variables.
    fadeout = true;
    step = fadeout_start;
    
    Other Event: User Defined 4:
    execute code:
    
    ///Updates offset for line.
    
    //Setups drawing font.
    draw_set_font(font);
    
    //Determines the line.
    var line_text = lines[line];
    
    //Determines horizontal alignment offset.
    switch (halign)
    {
        case fa_left:
            hoffset = 0;
            break;
         
        case fa_center:
            hoffset = string_width_ext(line_text, sep, width) / 2;
            break;
         
        case fa_right:
            hoffset = string_width_ext(line_text, sep, width);
            break;
    }
    
    //Determines vertical alignment offset.
    switch (valign)
    {
        case fa_top:
            voffset = 0;
            break;
         
        case fa_middle:
            voffset = string_height_ext(text, sep, width) / 2;
            break;
         
        case fa_bottom:
            voffset = string_height_ext(text, sep, width);
            break;
    }
    
    Other Event: User Defined 5:
    execute code:
    
    ///Show all text.
    
    //Skips to the end and shows all text, but does not start the fadeout.
    
    //Color Effect
    for (var i = 0; i < ds_list_size(chars); i++)
    {
        //Updates color value for char.
        var data = ds_list_find_value(chars, i);
        var color = ds_list_find_value(data, 0);
        color = 1;
        ds_list_replace(data, 0, color);
    }
    
    //Alpha Effect
    for (var i = 0; i < ds_list_size(chars); i++)
    {
        //Checks for fadeout.
        if (!fadeout)
        {
            //Updates alpha value for char.
            var data = ds_list_find_value(chars, i);
            var alpha = ds_list_find_value(data, 1);
            alpha = 1;
            ds_list_replace(data, 1, alpha);
        }
    }
    
    Draw Event:
    execute code:
    
    ///Handles Drawing
    
    //Checks if correct draw event.
    if (gui) exit;
    
    //Setups drawing.
    draw_set_font(font);
    draw_set_halign(fa_left);
    draw_set_valign(fa_top);
    
    //Enters a loop for each character.
    for (var i = 0; i < ds_list_size(chars); i++)
    {
        //Retrives the char data.
        var data = ds_list_find_value(chars, i);
        var color = ds_list_find_value(data, 0);
        var alpha = ds_list_find_value(data, 1);
        var char = ds_list_find_value(data, 2);
        var x1 = ds_list_find_value(data, 3);
        var y1 = ds_list_find_value(data, 4);
     
        //Setups drawing.
        draw_set_color(merge_color(color1, color2, color));
        draw_set_alpha(alpha);
     
        //Draws character.
        draw_text(x1, y1, char);
    }
    
    //Resets drawing alpha.
    draw_set_alpha(1);
    
    Draw GUI Event:
    execute code:
    
    ///Handles Drawing
    
    //Checks if correct draw event.
    if (!gui) exit;
    
    //Setups drawing.
    draw_set_font(font);
    draw_set_halign(fa_left);
    draw_set_valign(fa_top);
    
    //Enters a loop for each character.
    for (var i = 0; i < ds_list_size(chars); i++)
    {
        //Retrives the char data.
        var data = ds_list_find_value(chars, i);
        var color = ds_list_find_value(data, 0);
        var alpha = ds_list_find_value(data, 1);
        var char = ds_list_find_value(data, 2);
        var x1 = ds_list_find_value(data, 3);
        var y1 = ds_list_find_value(data, 4);
     
        //Setups drawing.
        draw_set_color(merge_color(color1, color2, color));
        draw_set_alpha(alpha);
     
        //Draws character.
        draw_text(x1, y1, char);
    }
    
    //Resets drawing alpha.
    draw_set_alpha(1);
    
    
     
  2. donsoyer

    donsoyer Member

    Joined:
    Feb 9, 2017
    Posts:
    4
    good
     
    Last edited: Feb 14, 2017
    Rukola likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice