Skip to content

Repository files navigation

Cool Custom Text (MonoGame)

Visual example

A small project that shows a cool way to use SpriteFont in MonoGame.
Features:

  • Render text inside a configurable box (dimension and padding) with both affected by a scale
  • Apply special FX tags to style or animate parts of your text
  • Customizable text shadow (color and offset)
  • Handle text overflow seamlessly, with support for line-by-line or page-by-page display modes
  • Text alignment: Left, Center or Right

Changelog

  1. Overflow managing (page by page or line by line)
  2. Side Step effect
  3. Text alignment (left, center or right)
  4. Text is now affected by scaling (previously only the box was)

Important

To run the project, make sure to install the .tff font in Content folder.

This font was made by Zacchary Dempsey-Plante: https://www.dafont.com/fr/pixellari.font.


Syntax and Application

To apply an effect to a specific part of the text, we use XML-like tag called 'fx'.
In the visual example above, the input text looks like this :

string text = "Hello stranger, are you <fx 2,0,0,1,0>good</fx> ?\n<fx 1,1,0,0,0>*************************************</fx><fx 6,0,1,0,0>This line is scared</fx> <fx 6,1,0,0,0>></fx><fx 7,0,0,0,0>0123456789</fx><fx 6,1,0,0,0><</fx>";

As you can see, one fx tag contains 5 numbers that define a profile for the effect:
<fx Color Palette, Wave, Shake, Hang, Side Step>

Effects visual example

Effects can be combine or can be ignored with 0.

Custom texts support newlines (\n) and consecutives spaces.

Here, an example to know everything about custom texts:

SpriteFont font = Content.Load<SpriteFont>("PixellariFont");
_customText = new(_spriteBatch, font)
{
    Text = """
    Hello stranger, are you <fx 2,0,0,1,0>good</fx> <fx 0,1,0,0,0>?</fx>
    <fx 1,1,0,0,0>**********************************</fx>
    <fx 6,0,1,0,0>This is scary</fx>    <fx 6,0,0,0,1>></fx> <fx 7,0,0,0,0>0123456789</fx> <fx 6,0,0,0,2><</fx>
    """,
    Position = new(25f),
    Padding = new(5f, 0f),
    Dimension = new(284f, 60f),
    Scale = new(4f), // Scale the dimension, the padding and the font
    Color = new(255, 244, 196),
    ShadowColor = new(128, 85, 111), // Color.Transparent to disable it
    ShadowOffset = new(-1f, 1f),
    AllowOverflow = false, // Should the text overflows outside the box vertically ?
    Alignment = TextAlignment.Center
};

// If overflow is not allowed, use the following methods/properties to display the text:
// Page by page
_customText.CurrentPageIdx = 0;
_customText.NextPage();
_customText.PreviousPage();

// Line by line
_customText.StartingLineIdx = 0;
_customText.NextStartingLine();
_customText.PreviousStartingLine();

/* Another example where we copy the style of the last custom text */

font = Content.Load<SpriteFont>("PixellariFont");
_infoCustomText = new(_spriteBatch, font, _customText)
{
    Text = """
    The gray box represents the scaled text dimension.
    The text itself is rendered inside the green box because padding is applied.
    Overflow is enabled here, allowing the text to exceed the vertical bounds.
    All lines in this example are centered.
    Both of these behaviors can be changed.
    Newlines work as expected, and so do      consecutive spaces.
    To apply a <fx 5,1,0,1,0>special effect</fx> to part of the text, use the fx tag
    and configure the desired effect profiles (use zero to ignore an effect).
    FX tag syntax:
    <fx Color Palette profile, Wave profile, Shake p., Hang p., Side Step p.>text</fx>
    <fx 3,0,0,0,0>See README.md to learn everything about custom texts.</fx>
    """,
    Position = new(10f, 280f),
    Dimension = new(660f, 92f),
    Scale = new(1.9f),
    Padding = new(0f, 10f),
    AllowOverflow = true,
};

Add new profiles

Profiles are stored in static readonly dictionnaries in the nested class FxText in the class CustomText.

To add a new profile for a specific effect, just follow the syntax.

Here, what it looks like:

// Palette color profiles
private readonly static Dictionary<int, Tuple<ColorPalette, float>> ColorProfiles = new()
{
    // Color Palette, Rotation Speed 
    [1] = new(ColorPalette.Rainbow, 0.075f),
    // New profile ! [2] = ...
}

// Wave profiles
private readonly static Dictionary<int, Tuple<float, float>> WaveProfils = new()
{
    // Wave Frequency, Wave Amplitude
    [1] = new(8f, 2f),
    // New profile ! [2] = ...
};

// Shake profiles
private readonly static Dictionary<int, Tuple<float, float>> ShakeProfils = new()
{
    // Shake Interval, Shake Strength
    [1] = new(0.06f, 0.75f),
    // New profile ! [2] = ...
};

// Hang profiles
private readonly static Dictionary<int, Tuple<float, float>> HangProfils = new()
{
    // Hang Frequency, Hang Amplitude
    [1] = new(6f, 9f),
    // New profile ! [2] = ....
};

// Side Step profiles
private readonly static Dictionary<int, Tuple<float, float>> SideStepProfils = new()
{
    // Side Step Frequency, Side Step Amplitude
    [1] = new(6f, 3f),
    [2] = new(6f, -3f)
};

The same applied to a new color palette.
Profiles are stored in the class PaletteRotator, don't forget to add the name of the new color palette in the enum ColorPalette.


License

You are free to use, modify, and distribute this code for any purpose.

About

A small project that shows a cool way to use SpriteFont in MonoGame.

Resources

Stars

19 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages