1
\$\begingroup\$

I am planing to Write a Text adventure and I don't know how to make the text draw letter by letter in any other way than changing the variable from h to he to hel to hell to hello That would be a terrible amount of work since there are tons of dialogue.

Here is the source code so far

protected override void Update(GameTime gameTime)
{
    //input code removed for clarity

    if (Dialogue == 1)
    {
        Row1 = "Input Text 1 Here.";
        Row2 = "Input Text 2 Here.";
        Row3 = "Input Text 3 Here.";
        Row4 = "Input Text 4 Here.";
    }
    if (Dialogue == 2)
    {
        Row1 = "Text 1";
        Row2 = "Text 2";
        Row3 = "Text 3";
        Row4 = "Text 4";
    }

    base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin();
    spriteBatch.Draw(sampleBG, new Rectangle(0, 0, 800, 600), Color.White);
    spriteBatch.Draw(TextBG, new Rectangle(0, 400, 800, 200), Color.White);
    spriteBatch.DrawString(defaultfont, Row1, new Vector2(10, (textheight + (rowspace * 0))), Color.Black);
    spriteBatch.DrawString(defaultfont, Row2, new Vector2(10, (textheight + (rowspace * 1))), Color.Black);
    spriteBatch.DrawString(defaultfont, Row3, new Vector2(10, (textheight + (rowspace * 2))), Color.Black);
    spriteBatch.DrawString(defaultfont, Row4, new Vector2(10, (textheight + (rowspace * 3))), Color.Black);
    spriteBatch.End();
    base.Draw(gameTime);
}
\$\endgroup\$
  • 4
    \$\begingroup\$ "Write this code for me," type questions don't do well on this forum. What specifically is not happening that you want to have happen? \$\endgroup\$ – michael.bartnett Oct 11 '12 at 20:29
  • 2
    \$\begingroup\$ I agree with Michael. Additionally I disagree that it would be a terrible amount of work. You just have to write a function that takes a string, and amount of time it should take to print. You only have to write that once. Not for every line of dialog. Think a little more about algorithms and how you might accomplish your goals with simple code. \$\endgroup\$ – MichaelHouse Oct 11 '12 at 20:42
  • \$\begingroup\$ Oh im sorry That was not meant to be one of this Questions, Just like How that would be possible, but Byte`s Answer actually helped me and I figuered out how i could do it Thanks \$\endgroup\$ – Evi Oct 11 '12 at 20:52
  • \$\begingroup\$ @Evi I'm glad it was helpful. In the future, do try to only post code that's relevant to the question (see the edits I made). Also make sure to tell us what you've tried already and what about it didn't work. When you've solved this you can come back and answer your own question. Good luck with your game. \$\endgroup\$ – MichaelHouse Oct 11 '12 at 22:03
  • \$\begingroup\$ Type writer effect =) \$\endgroup\$ – Sidar Oct 12 '12 at 16:51
10
\$\begingroup\$

I won't write the code for you, but I can put forth a conceptual path forward.

Assuming your text is displayed in a string, it is possible to iterate through the character array that makes up that string. The goal here is to print each character individually (or however many at a time you want) separated by a delta time.

When you think about it, this isn't really any different than animating a sprite. Instead of moving the index into a spritesheet, you're moving the index into a string and appending that character to the displayed string.

So, for example:

string fullText = "Hello World";
string currentText = "";
int currentTextIndex = 0;
float timeSinceLastIncrement = 0;

update(dt)
{
    timeSinceLastIncrement += dt;

    if(timeSinceLastIncrement >= .5)
    {
         currentText += fullText[currentTextIndex];
         currentTextIndex++;
         timeSinceLastIncrement = 0;
    }
}

draw()
{
    render(currentText);
}

Basically, you're maintaining the full text that will eventually be displayed, the current text that is being rendered, and the current index into the full text. dt is the delta time since the last update and timeSinceLastIncrement is the time that has passed since the last time you moved to the next character in the string. When that time (here in seconds) has gone past half a second, append the character to the current text, increment to the next character, and reset the time.

@ time 0, currentText = "";
@ time .5, currentText = "H";
@ time 1.0, currentText = "He";

And so on...

\$\endgroup\$
  • \$\begingroup\$ It's probably a good idea to use StringBuilder instead of string for the partial string, to avoid unnecessary allocations. SpriteBatch.DrawString is overloaded to take either. \$\endgroup\$ – Andrew Russell Oct 12 '12 at 11:15
  • 1
    \$\begingroup\$ @AndrewRussell My answer is entirely pseudocode, but good note for him when he implements. \$\endgroup\$ – Justin Skiles Oct 12 '12 at 11:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.