• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML Dynamic dialoge system. Problems with making text effects

S

STANN.co

Guest
First off, i'm new to the forum, and Gamemaker as well, and coding in this is a bit new to me, but i think i'm on the right path. I'm trying to create a dialoge system, i can easily call and put a text file into.

When interacting with objects, or talking with people in the game i'm making.

This is my dialoge box.

In rough terms, each letter of the message is written one at a time. With the majority of the code, making sure the next letter is offset the right amount from the previous one, as well as checking if the current word is gonna go out of bounds, and if so it goes to a new line.

In-between that. The rough text, has modifiers. Like /s /w

Ideally i'd want to be able to place these modifiers inside of each-other in the rough text. Say so i can have shaky text, and one word in that text be a different color.
Something like this as input text:

"Jon, you /sabsolutte abormination of /(red)wasted/(red) life/s"


I'll post all the code here. It currently doesn't work like the gif above though. Because i'm stumped trying to remake the modifiers to work inside each-other.

It might be quite a comprehensive thing to go through. But i'd appreciate any help, or general feedback on other parts if applicable

This puts some sprites, and strings into 2 arrays. And then calls a script using those arrays.
Code:
portrait[0] = jon_confused;
text[0] = "Garfield, d- /sdo you think it will/s go well on the date???"

portrait[1] = garfield_bored;
text[1] = "Jon, you /whave as much charisma /was an ingrown toenail..."

portrait[2] = garfield_bored;
text[2] = "I'd be impressed /wif you /scould make it /sthrough the /wapetiser"

portrait[3] = jon_pissed;
text[3] = "I DON'T NEED YOU'R SARCASM"

portrait[4] = garfield_bored;
text[4] = "..."

portrait[5] = garfield_bored;
text[5] = ".............."

portrait[6] = garfield_dread;
text[6] = "/0Jon..."

portrait[7] = garfield_dread;
text[7] = "/1You will die alone, and i am forced to stay with you, till that happens..."

portrait[8] = garfield_cool;
text[8] = "/0So why don't you go ahead and cook me some /2Delicious Lasaga!"

portrait[9] = "none";
text[9] = "/0Thank you for playing my game, this is only a demo -Hideo Kojima"

text_box(text,portrait);

This is the script being called. It creates the dialoge box object. And writes the previous arrays to it.
Code:
///@func text_box(array, array)
///@desc takes message arrays, and portrait arrays, and sends em to the text box
var sent = argument[0];
var portrait = argument[1];

var text = instance_create_layer(0,0,"Instances",obj_dialogue);

for (i = 0; i < array_length_1d(portrait); i++)
{
    text.portrait[i] = portrait[i];   
}
for (i = 0; i < array_length_1d(sent); i++)
{
    text.message[i] = sent[i];   
}

This is the objects create event. A 💩💩💩💩-ton of variables. Take note of the modifierShaky, as that was my previous attempt at being able to have modifiers inside other modifiers and exiting out again
Code:
message[0] = "something went wrong 💩💩💩💩o";
message_current = 0;

initialDelay = 1;
delay = initialDelay;
cutoffSpeed = 1;

modifierShaky = false;
modifierWavey = false;
modifierRed = false;


letters = 0;
i = 1;

timer = 0;
cutoff = 0;

t = 0;
amplitude = 1;
freq = 0.08;

done = false;

//portrait
portrait[0] = garfield_bored;
portrait_current = 0;
portTime = 0;
portDuration = 40;
portStart = -100;
portDest = 54;

portYTime = 0;
portYDuration = 60;
portYStart = view_hport[0]- 48;
portYDest = portYStart + 5;

portFrame = 0;

//dialouge box
boxTime = 0;
boxDuration = 30;
boxStart = view_hport[0];
boxDest = (view_hport[0] - 100);
boxFrame = 0;
boxFrameTime = 1;

boxPopupRemove = false;


Here's all the happenings. It's a gui draw event, so it goes through it all each frame of the game. It's a hefty sum, so i appreciate anyone who goes through it.
Code:
//draw dialouge box
if (boxTime <= boxDuration) {
    boxY = ease_in_out(boxTime++,boxStart,boxDest-boxStart,boxDuration)
}

//removes the popup reminder again
if (boxPopupRemove == true)
{
    boxFrame = boxFrame - min(sprite_anim(boxFrameTime,6),sprite_get_number(spr_dialouge_box)-2);
    boxFrameTime++;
}
if (boxFrame <= 0)
    {
    boxPopupRemove = false;
    boxFrameTime = 1;
    }

//When the message is done writing. A tiny popup, will appear reminding that you can skip to the next page
if (i >= string_length(message[message_current]))
{   
    boxFrame = min(sprite_anim(boxFrameTime,15),sprite_get_number(spr_dialouge_box)-1);
    boxFrameTime++;
}
draw_sprite(spr_dialouge_box,boxFrame,x,boxY);
    
//draw Portrait
switch(portrait[portrait_current])
{
    case "none":
    {
        break;
    }
    default:
    {
        if (portTime <= portDuration) {
            portX = ease_out(++portTime,portStart,portDest-portStart,portDuration)
        }
        
        //Makes portrait bop up n' down
        if (portYTime < portYDuration) {
            portY = ease_in_out(++portYTime,portYStart,portYDest-portYStart,portYDuration)
        } else {
            var tempStart = portYStart;
            portYStart = portYDest;
            portYDest = tempStart;
            portYTime = 0;
        }
        
        draw_sprite(portrait[portrait_current], sprite_anim(portFrame++,15), portX, portY)
        break;
    }
}
    
draw_set_font(f_action_man);
draw_set_colour(c_white);   
    
//How many messages are in the array
message_end = array_length_1d(message);


//variables
var line = 0;
var space = 0;
var charWidth = 0;
var line = 0;
var lineShift = string_height(message[message_current])+2
var lineEnd = 280;

//Typewriter
if (cutoff < string_length(message[message_current]) && boxY == boxDest)
{
    if (timer >= delay)
    {
        cutoff += cutoffSpeed;
        timer = 0;
    }
    else timer++;
}

//text position
var tY = view_hport[0]-78;
if (portrait[portrait_current] == "none")
{
    var tX = 50;
    lineEnd += 50;
}
else var tX = 100;
    
//Next message
if ((keyboard_check_pressed(ord("X")) || keyboard_check_pressed(vk_enter) || keyboard_check_pressed(vk_space)) && done == false)
{
    delay = 0;
    cutoffSpeed = 5;
    if (i >= string_length(message[message_current]))
    {
        if (message_current < message_end-1)
        {
            delay = initialDelay;
            message_current++;
            portrait_current++;
            cutoff = 0;
            cutoffSpeed = 1;
                        
            //removes the popup
            boxPopupRemove = true;
            boxFrameTime = 1;
            boxFrame = 5;
        }
        //If we don't, we're done
        else
        {
            done = true;
            
            delay = initialDelay;
            cutoff = 0;
            
            //Removes the popup
            boxPopupRemove = true;
            boxFrameTime = 1;
            boxFrame = 5;
            
            //Changes the animation parameters of the box, making it lower again
            var boxStartTemp = boxStart;
            boxStart = boxDest;
            boxDest = boxStartTemp;
            boxTime = 1;
            
            //Changes the animation parameters of the portrait, making it go left again
            var portStartTemp = portStart;
            portStart = portDest;
            portDest = portStartTemp;
            portTime = 1;
        }
    }
}

i = 1;

//Draw text
while(i <= string_length (message[message_current]) && i <= cutoff && done == false && boxY == boxDest)
{
    
    //check for modifier
    if (string_char_at(message[message_current], i) == "/" && i <= string_length (message[message_current]))
    {
        
        var modifier = string_char_at(message[message_current], ++i); ++i;
        
        switch (modifier)
        {
            //toggles modifier Shaky on/off
            case "s": if (modifierShaky == false) modifierShaky = true; else modifierShaky = false; break;
            
            case "w": if (modifierWavey == false) modifierWavey = true; else modifierWavey = false; break;
            
            case "c": break;
        }       
    }
    
    //Go to next line
    var length = 0;
    var wordWidth = 0;

    //Reads the width of the current word
    while (string_char_at(message[message_current], i) != " " && i <= string_length(message[message_current]))
    {
        wordWidth += string_width(string_char_at(message[message_current], i));
        i++;
        length++;
    }

    //if the current word exedes the lineEnd we go to a new line
    if (wordWidth+charWidth > lineEnd)
    {
        charWidth = 0;
        line++;
    }
    wordWidth = 0;
    i -= length;
    

    //Text
    
    //Shaky modifier
    if (modifierShaky == true)
    {
        var shakeX = random_range(-1,1);
        var shakeY = random_range(-1,1);
    }
    else
    {
        var shakeX = 0;
        var shakeY = 0;
    }
    //Wavey modifier
    t++;
    if (modifierWavey == true)
    {
        var so = t + i*100;
        shift = sin(so*pi*freq/room_speed)*amplitude;
    }
    else
    {
        var shift = 0;
    }
    
    //draws the actual text
    draw_set_colour(c_white);
    draw_text(tX+charWidth + shakeX, tY+(lineShift*line) + shift + shakeY, string_char_at(message[message_current], i));
    
    charWidth += string_width(string_char_at(message[message_current], i++));
}

//Destroys the objects once all objects are offscreen.
if (done = true && portX == portDest && boxY == boxDest)
{
instance_destroy(self);
}

You should be able to take all this create an object, script. And call them with some test dialoge yourself, if you wanna test out on your end. I appreciate any help.

Also first post on the forum, hurray...
 
Top