user5008872
user5008872

Reputation:

Multicolored changing text in java

Id like multicolored changing text, I made a list with all the colors

I have 5 g.drawString(); functions running, each of them should be the next color in the list (one above each other.)

private Color[] colors = new Color[12];

Then in my constructor:

colors[0] = new Color(255, 0, 0);
colors[1] = new Color(255, 127, 0);
colors[2] = new Color(255, 255, 0);
colors[3] = new Color(127, 255, 0);
colors[4] = new Color(0, 255, 0);
colors[5] = new Color(0, 255, 127);
colors[6] = new Color(0, 255, 255);
colors[7] = new Color(0, 127, 255);
colors[8] = new Color(0, 0, 255);
colors[9] = new Color(127, 0, 255);
colors[10] = new Color(255, 0, 255);
colors[11] = new Color(255, 0, 127);

How would I make each each letter a different color?

Set The Color: g.setColor(Color object); 
Example: g.setColor(colors[5]);

Write Text: g.drawString(String, x, y);
Example: g.drawString("S", 200, 300);

So, Id like S to be the color, colors[0], I made a table below:

Starting | First | Second | Fifth

S -- 0      11       10       7
N -- 1       0       11       8
A -- 2       1        0       9
K -- 3       2        1      10
E -- 4       3        2      11

So it would loop around though each color:

I tried making a function for this, I deleted the code because I'm an idiot -_-

In my main class, I have a game loop that calls the tick and render methods, tick first then render.

I have an enum called STATE which contains menu and game, then the variable gameState of the type state is set to STATE.menu

public enum state {
    Menu,
    Game,
}

public state gameState = state.Menu;

When gameState is equal to STATE.menu it will call menu.render(g ( <-- The variable im using for Graphics));

Each class has its own render and tick method. -Tick method, for setting variables etc, if statements, yada yada yada -Render method, anything to do with drawing pixels

Because the tick method is called every 0.0000000000000000001 seconds, the color changes every 9 millionth of a second and it looks very derpy.

So ill need a timer of some sorts that I can configure with a variable

I want each of the letters to be a different color, one after another in the list you can refer to the table above if you don't understand but as an example,

the letter a should be colors[0]
and then b, colors[1]
and c, colors[2]

the colors should alter,

so a would be colors[2]
so b would be colors[0]
so c would be colors[1]

I've probably been unclear on 1001 things, so please shout at me in the comments ^-^

Thanks for reading!

Upvotes: 1

Views: 1790

Answers (1)

Marco13
Marco13

Reputation: 54621

If I understood correctly, there are mainly two issues:

  • Painting the letters in different colors, cycling through the given array
  • Updating the colors (but at a fixed time, not with every "tick")

Cycling through the colors can be achieved by introducing a "colorOffset". You can add this color offset to the index that you use to access the color in the array, and take this modulo the array length to obtain a valid array index:

int colorOffset = ... // Counted up or down all the time

// The index of the color for the i'th letter
int colorIndex = (i+colorOffset)%colors.length;
if (colorIndex < 0) colorIndex += colors.length;
g.setColor(colors[colorIndex]);

The second part, regarding the update: I assume that you have a game loop that is run in an own thread. Then, in thisTickMethodThatYouHaveBeenTalkingAbout, you can check the current system time with System.nanoTime(), and compute the time that has passed since the last update. If the time is larger than the desired interval, you perform an update, by increasing the colorOffset and triggering a repaint() (if necessary - you might cover this already with your render() method).

Cycling colors

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MulticolorTextAnimation
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        MulticolorTextAnimationPanel m = new MulticolorTextAnimationPanel();
        f.getContentPane().add(m);

        Thread thread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                while (true)
                {
                    m.thisTickMethodThatYouHaveBeenTalkingAbout();
                    try
                    {
                        Thread.sleep(1);
                    }
                    catch (InterruptedException e)
                    {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            }
        });
        thread.setDaemon(true);
        thread.start();

        f.setSize(500,200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}


class MulticolorTextAnimationPanel extends JPanel
{
    private String string;
    private Color colors[];
    private int colorOffset = 0;
    private long lastUpdateNs = -1;
    private final long updateIntervalMs = 250;

    public MulticolorTextAnimationPanel()
    {
        setFont(new Font("Dialog", Font.BOLD, 45));

        string = "I am a string!";

        colors = new Color[12];
        colors[0] = new Color(255, 0, 0);
        colors[1] = new Color(255, 127, 0);
        colors[2] = new Color(255, 255, 0);
        colors[3] = new Color(127, 255, 0);
        colors[4] = new Color(0, 255, 0);
        colors[5] = new Color(0, 255, 127);
        colors[6] = new Color(0, 255, 255);
        colors[7] = new Color(0, 127, 255);
        colors[8] = new Color(0, 0, 255);
        colors[9] = new Color(127, 0, 255);
        colors[10] = new Color(255, 0, 255);
        colors[11] = new Color(255, 0, 127);
    }

    public void thisTickMethodThatYouHaveBeenTalkingAbout()
    {
        long ns = System.nanoTime();
        if (lastUpdateNs < 0)
        {
            lastUpdateNs = ns;
        }
        long passedNs = (ns - lastUpdateNs);
        long passedMs = passedNs / 1000000;
        if (passedMs > updateIntervalMs)
        {
            // Increase or decrease the color offset,
            // depending on whether the colors should
            // cycle forward or backward
            colorOffset--;
            repaint();
            lastUpdateNs = ns;
        }

    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());

        FontMetrics fontMetrics = g.getFontMetrics();

        int x = 100;
        int y = 100;
        for (int i=0; i<string.length(); i++)
        {
            char c = string.charAt(i);
            int colorIndex = (i+colorOffset)%colors.length;
            if (colorIndex < 0)
            {
                colorIndex += colors.length;
            }
            g.setColor(colors[colorIndex]);
            g.drawString(String.valueOf(c), x, y);
            x += fontMetrics.charWidth(c); 
        }


    }
}

Upvotes: 2

Related Questions