Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

Sign up now!

Resource Make Rainbow mouse

red

Joined
Nov 17, 2013
Messages
259
Well I got bored and made this mouse and thought it was kinda cool.
GIF of this:
8c4c6b15982e15cf2a8799a83e79c4dd.gif

Variables:
Code:
    public Color targetColor;
    public Color currentColor;
    long t = -1;
    long timePerTick = 0;
    private Runnable MOUSE_THREAD = new Runnable() {
        @Override
        public void run() {
            while (true) {
                if (t == -1 || t + timePerTick < System.currentTimeMillis()) {
                    t = System.currentTimeMillis();
                    int tr = targetColor.getRed(), tg = targetColor.getGreen(), tb = targetColor.getBlue();
                    int cr = currentColor.getRed(), cg = currentColor.getGreen(), cb = currentColor.getBlue();
                    int dr = tr - cr, dg = tg - cg, db = tb - cb;
                    currentColor = new Color(getColorFrom(dr, cr), getColorFrom(dg, cg), getColorFrom(db, cb));
                    if (currentColor.getRGB() == targetColor.getRGB()) {
                        targetColor = new Color(Random.nextInt(255), Random.nextInt(255), Random.nextInt(255));
                    }
                }
            }
        }

    };

Mouse.PathRenderer render = new PathRenderer() {
        @Override
        public void render(Graphics2D g) {
            g.setColor(currentColor);
            g.drawLine(Mouse.getPosition().x, 0, Mouse.getPosition().x, 3000);
            g.drawLine(0, Mouse.getPosition().y, 3000, Mouse.getPosition().y);
        }
    };
    public Thread thread = new Thread(MOUSE_THREAD);
Methods:
Code:
private int getColorFrom(int d, int c) {
        return c + (d / (Math.abs(d) == 0 ? 1 : Math.abs(d)));
}
Add to onStart():
Code:
targetColor = new Color(Random.nextInt(255), Random.nextInt(255), Random.nextInt(255));
currentColor = new Color(Random.nextInt(255), Random.nextInt(255), Random.nextInt(255));
Mouse.setPathRenderer(render);
thread.start();
Add to onStop():
Code:
thread.stop();
 
Last edited:
Joined
Mar 14, 2015
Messages
24
You should add a sleep into the while loop, it really isn't efficient to be constantly picking a random colour.
 

red

Joined
Nov 17, 2013
Messages
259
t + timePerTick < System.currentTimeMillis()
Im checking each tick, and i am not randomly doing it each tick, it approches the target in increments of 1 so it needs to be fast, if you make it increments of 2 you could probably get away with slower timing.
 
Joined
Mar 14, 2015
Messages
24
t + timePerTick < System.currentTimeMillis()
Im checking each tick, and i am not randomly doing it each tick, it approches the target in increments of 1 so it needs to be fast, if you make it increments of 2 you could probably get away with slower timing.
You are constantly checking if the time is correct for you to change the colour. Im sure if you had a counter you would see that that is run millions of times a second, which just isn't efficient at all. You can achieve the same thing just by sleeping every time for even just a small amount of time and then changing the colour while being much more efficient. Currently that thread will, to my knowledge, take up a whole processor while it is active.
 

red

Joined
Nov 17, 2013
Messages
259
You are constantly checking if the time is correct for you to change the colour. Im sure if you had a counter you would see that that is run millions of times a second, which just isn't efficient at all. You can achieve the same thing just by sleeping every time for even just a small amount of time and then changing the colour while being much more efficient. Currently that thread will, to my knowledge, take up a whole processor while it is active.
A simple if statement will do nothing to the processor and the calculations that I am performing are very minimal, so there should be a huge problem, unless of course you are running Windows 97. Not saying that sleeping is not the best approach, it just looks better to not use it.
 
Joined
Mar 14, 2015
Messages
24
A simple if statement will do nothing to the processor and the calculations that I am performing are very minimal, so there should be a huge problem, unless of course you are running Windows 97. Not saying that sleeping is not the best approach, it just looks better to not use it.
Even a simple if statement if run a million times will cause issues.
 
Joined
Mar 26, 2014
Messages
33
A simple if statement will do nothing to the processor and the calculations that I am performing are very minimal, so there should be a huge problem, unless of course you are running Windows 97. Not saying that sleeping is not the best approach, it just looks better to not use it.

Its still unnecessary CPU usage, not too mention the additional garbage collection time as your creating a lot of color instances.

If it was me i would create and cache the array of colors and use the system time to cycle through them, this will stop the stupid amount of objects being created forcing the garbage collector to run more often as well as the requirement for a separate thread using unnecessary CPU cycles.

Try something like this
Code:
import java.awt.*;

/**
* Author: Tom
* Date: 13/04/2015
* Time: 16:38
*/
public class CyclicColorMouse {

    public static final CyclicColorMouse RAINBOW;

    private final Color[] colorCycle;
    private final int cycleSpeed;


    public CyclicColorMouse(Color[] colorCycle, int cycleSpeed) {
        this.colorCycle = colorCycle;
        this.cycleSpeed = Math.max(cycleSpeed, 1);
    }

    public void renderMouse(int mouseX, int mouseY, int width, int height, Graphics2D g) {
        g.setColor(colorCycle[(int) ((System.currentTimeMillis() / cycleSpeed) % colorCycle.length)]);
        g.drawLine(mouseX, 0, mouseX, height);
        g.drawLine(0, mouseY, width, mouseY);
    }

    static {
        Color[] cycle = new Color[360];
        for (int i = 0; i < 360; i++) {
            double rads = Math.toRadians(i);
            cycle[i] = new Color((int) (Math.sin(rads + 0) * 127) + 128, (int) (Math.sin(rads + 2) * 127) + 128, (int) (Math.sin(rads + 4) * 127) + 128);
        }
        RAINBOW = new CyclicColorMouse(cycle, 3);
    }

}
 

red

Joined
Nov 17, 2013
Messages
259
Its still unnecessary CPU usage, not too mention the additional garbage collection time as your creating a lot of color instances.

If it was me i would create and cache the array of colors and use the system time to cycle through them, this will stop the stupid amount of objects being created forcing the garbage collector to run more often as well as the requirement for a separate thread using unnecessary CPU cycles.

Try something like this
Code:
import java.awt.*;

/**
* Author: Tom
* Date: 13/04/2015
* Time: 16:38
*/
public class CyclicColorMouse {

    public static final CyclicColorMouse RAINBOW;

    private final Color[] colorCycle;
    private final int cycleSpeed;


    public CyclicColorMouse(Color[] colorCycle, int cycleSpeed) {
        this.colorCycle = colorCycle;
        this.cycleSpeed = Math.max(cycleSpeed, 1);
    }

    public void renderMouse(int mouseX, int mouseY, int width, int height, Graphics2D g) {
        g.setColor(colorCycle[(int) ((System.currentTimeMillis() / cycleSpeed) % colorCycle.length)]);
        g.drawLine(mouseX, 0, mouseX, height);
        g.drawLine(0, mouseY, width, mouseY);
    }

    static {
        Color[] cycle = new Color[360];
        for (int i = 0; i < 360; i++) {
            double rads = Math.toRadians(i);
            cycle[i] = new Color((int) (Math.sin(rads + 0) * 127) + 128, (int) (Math.sin(rads + 2) * 127) + 128, (int) (Math.sin(rads + 4) * 127) + 128);
        }
        RAINBOW = new CyclicColorMouse(cycle, 3);
    }

}
Whoops didn't think about me constantly making a new color object, I can quickly change that to change the colors rgb value. but your approach isn't exactly the same as what i am trying todo. I am trying to cycle through the color range to the target color, not go trough it like you are doing in yours.
 
Joined
Mar 26, 2014
Messages
33
Whoops didn't think about me constantly making a new color object, I can quickly change that to change the colors rgb value. but your approach isn't exactly the same as what i am trying todo. I am trying to cycle through the color range to the target color, not go trough it like you are doing in yours.

Yes its slightly different but the end result is virtually the same

XbYmTW8.gif
 
Top