Resource Make Rainbow mouse

Discussion in 'Tutorials & Resources' started by red, Apr 8, 2015.

  1. Well I got bored and made this mouse and thought it was kinda cool.
    GIF of this:
    [​IMG]
    Variables:
    Code (Text):
    1.  
    2.     public Color targetColor;
    3.     public Color currentColor;
    4.     long t = -1;
    5.     long timePerTick = 0;
    6.     private Runnable MOUSE_THREAD = new Runnable() {
    7.         @Override
    8.         public void run() {
    9.             while (true) {
    10.                 if (t == -1 || t + timePerTick < System.currentTimeMillis()) {
    11.                     t = System.currentTimeMillis();
    12.                     int tr = targetColor.getRed(), tg = targetColor.getGreen(), tb = targetColor.getBlue();
    13.                     int cr = currentColor.getRed(), cg = currentColor.getGreen(), cb = currentColor.getBlue();
    14.                     int dr = tr - cr, dg = tg - cg, db = tb - cb;
    15.                     currentColor = new Color(getColorFrom(dr, cr), getColorFrom(dg, cg), getColorFrom(db, cb));
    16.                     if (currentColor.getRGB() == targetColor.getRGB()) {
    17.                         targetColor = new Color(Random.nextInt(255), Random.nextInt(255), Random.nextInt(255));
    18.                     }
    19.                 }
    20.             }
    21.         }
    22.  
    23.     };
    24.  
    25. Mouse.PathRenderer render = new PathRenderer() {
    26.         @Override
    27.         public void render(Graphics2D g) {
    28.             g.setColor(currentColor);
    29.             g.drawLine(Mouse.getPosition().x, 0, Mouse.getPosition().x, 3000);
    30.             g.drawLine(0, Mouse.getPosition().y, 3000, Mouse.getPosition().y);
    31.         }
    32.     };
    33.     public Thread thread = new Thread(MOUSE_THREAD);
    34.  
    Methods:
    Code (Text):
    1. private int getColorFrom(int d, int c) {
    2.         return c + (d / (Math.abs(d) == 0 ? 1 : Math.abs(d)));
    3. }
    Add to onStart():
    Code (Text):
    1. targetColor = new Color(Random.nextInt(255), Random.nextInt(255), Random.nextInt(255));
    2. currentColor = new Color(Random.nextInt(255), Random.nextInt(255), Random.nextInt(255));
    3. Mouse.setPathRenderer(render);
    4. thread.start();
    Add to onStop():
    Code (Text):
    1. thread.stop();
     
    #1 red, Apr 8, 2015
    Last edited: Apr 8, 2015
    Arbiter likes this.
  2. Can you show a video of what it looks like? :p
     
  3. I wish, gyazo isnt working rite now ><
     
    Factionless likes this.
  4. You should add a sleep into the while loop, it really isn't efficient to be constantly picking a random colour.
     
  5. 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.
     
  6. 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.
     
  7. 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.
     
  8. Even a simple if statement if run a million times will cause issues.
     
  9. 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 (Text):
    1. import java.awt.*;
    2.  
    3. /**
    4. * Author: Tom
    5. * Date: 13/04/2015
    6. * Time: 16:38
    7. */
    8. public class CyclicColorMouse {
    9.  
    10.     public static final CyclicColorMouse RAINBOW;
    11.  
    12.     private final Color[] colorCycle;
    13.     private final int cycleSpeed;
    14.  
    15.  
    16.     public CyclicColorMouse(Color[] colorCycle, int cycleSpeed) {
    17.         this.colorCycle = colorCycle;
    18.         this.cycleSpeed = Math.max(cycleSpeed, 1);
    19.     }
    20.  
    21.     public void renderMouse(int mouseX, int mouseY, int width, int height, Graphics2D g) {
    22.         g.setColor(colorCycle[(int) ((System.currentTimeMillis() / cycleSpeed) % colorCycle.length)]);
    23.         g.drawLine(mouseX, 0, mouseX, height);
    24.         g.drawLine(0, mouseY, width, mouseY);
    25.     }
    26.  
    27.     static {
    28.         Color[] cycle = new Color[360];
    29.         for (int i = 0; i < 360; i++) {
    30.             double rads = Math.toRadians(i);
    31.             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);
    32.         }
    33.         RAINBOW = new CyclicColorMouse(cycle, 3);
    34.     }
    35.  
    36. }
     
  10. 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.
     
  11. Yes its slightly different but the end result is virtually the same

    [​IMG]
     

Share This Page

Loading...