How to make an object to follow the mouse... with a delay

edited November 2013 in How To...

Hey there, Althouhg I'm new into Processing, I really like the versatility of the software. However, since I'm a graphic designer, it is not easy to came up with the right formula to achieve a particular effect for my animation. That's the main reason to post here, I would like to learn and improve my knoweledge with the help of other members.

On to the point. I can make a circle follow the mouse, but in this occasion I need that the object have a delay so the mouse moves first and then the object. This is the code I already have:

==============================

PVector theBallPosition;
PVector theBallVelocity;

void setup(){
  smooth();
  frameRate(30);
  size(400,400);

  theBallPosition = new PVector(width/2,height/2); 
  theBallVelocity = new PVector(1.3,1); 
}

void draw(){
  noStroke();
  background(100,0,200); // Background color
  ellipseMode(CENTER);
  ellipse(mouseX,mouseY,30,30); // Placing the circle
}

==============================

Any ideas how to solve this little problem?

Answers

  • Answer ✓

    The PVector tutorial already provides a fairly good example of what (I think) you want.

  • edited November 2013 Answer ✓

    Perhaps something like this 1 too? :D
    http://studio.processingtogether.com/sp/pad/export/ro.9GTDpA6dp4tH1/latest

    /**
     * Chase-Shadow Circles (v3.2)
     * Regular Array Edition (2013/Feb)
     *
     * Modded by GoToLoop (2013/Nov)
     *
     * forum.processing.org/topic/newbie-question-understandig-problems-with-arrays
     * studio.processingtogether.com/sp/pad/export/ro.9GTDpA6dp4tH1/latest
     * www.creativecoding.org/lesson/basics/processing/arrays
     */
    
    final static int NUM = 0100, NEWEST = NUM - 1;
    final int[] x = new int[NUM], y = new int[NUM];
    
    void setup() {
      size(1000, 400);
      frameRate(60);
    
      smooth();
      noStroke();
      noCursor();
      ellipseMode(CENTER);
    
      fill(0100<<030);
    
      mouseX = width>>1;
      mouseY = height>>1;
    
      for ( int i = NUM; i-- != 0; 
        x[i] = mouseX, y[i] = mouseY );
    }
    
    void draw() {
      background(-1);
    
      for ( int i = 0; i != NEWEST;
        ellipse(x[i] = x[i + 1], y[i] = y[i + 1], i, i++) );
    
      ellipse(x[NEWEST] = mouseX, y[NEWEST] = mouseY, NEWEST, NEWEST);
    }
    
  • edited November 2013

    Thanks a lot for you prompt response. I will try to use the information and then I will get back with my solution (if I find one).

  • Almost there:

    //New PVector elements
    PVector theMouse; 
    PVector thePrevMouse; 
    //New variables
    float theVelocity = 0;
    float thePrevVelocity;
    float theEasing = 10;
    int ballSize = 20;
    
    void setup(){
      size(400,400);
      frameRate(30);
      smooth();
      fill(0,200,0);
      noStroke();
    
      theMouse = new PVector(); //PVector location
      thePrevMouse = new PVector(); //PVector location
    }
    
    void draw(){
      background(255,0,200); //Background color
    
      //Setting the values of PVectors
      theMouse.set(mouseX,mouseY); 
      thePrevMouse.set(pmouseX,pmouseY);
    
      thePrevVelocity = theEasing * theMouse.dist(thePrevMouse);
      theVelocity -= (theVelocity - thePrevVelocity) / theEasing;
    
      ellipseMode(CENTER); 
      ellipse(theMouse.x-theVelocity,theMouse.y-theVelocity,ballSize,ballSize); // Placing the circle
    }
    

    But I don't want the ball to be pushed. I need that the ball follow the mouse with some delay. Any ideas?

  • Try using GoToLoop's code with PVector. He uses an array for a reason, it introduces the delay you want, memorizing each step of the mouse (or at least a number of them).

  • OK, here is a version of GoToLoop's code, without tricks, with PVector.

    final int NUM = 12;
    final PVector[] trail = new PVector[NUM];
    
    void setup() 
    {
      size(1000, 400);
      smooth();
      noStroke();
      ellipseMode(CENTER);
    
      fill(#0055FF);
    }
    
    void draw() 
    {
      background(255);
    
      trail[NUM - 1] = new PVector(mouseX, mouseY); 
      for (int i = 0; i < NUM - 1; i++)
      {
        trail[i] = trail[i + 1];
      }
    
      if (trail[0] != null)
      {
        ellipse(trail[0].x, trail[0].y, 40, 40);
      }
    }
    
  • Sounds good, but I need to present the result with the most simple solution possible. Is there any way to change something in my code to make it work?

  • Do you understand the idea of the implementation, particularly what the for loop does? And why it is necessary?

  • edited November 2013

    Just updating my example to ellipse() oldest entry only: <):)

    /**
     * Chase-Cursor Circle (v1.02)
     * Modded by GoToLoop (2013/Nov)
     *
     * forum.processing.org/two/discussion/1186/
     * how-to-make-an-object-to-follow-the-mouse-with-a-delay
     *
     * forum.processing.org/topic/one/
     * newbie-question-understandig-problems-with-arrays
     */
    
    final static int DIM = 050, NUM = 020, POS = NUM - 1;
    final int[] x = new int[NUM], y = new int[NUM];
    
    void setup() {
      size(800, 600);
      frameRate(60);
    
      smooth();
      noStroke();
      cursor(CROSS);
      ellipseMode(CENTER);
    
      fill(#0050F0);
    
      mouseX = width>>1;
      mouseY = height>>1;
    
      for ( int i = NUM; i-- != 0; x[i] = mouseX, y[i] = mouseY );
    }
    
    void draw() {
      background(-1);
    
      for ( int i = 0; i != POS; x[i] = x[i + 1], y[i] = y[++i] );
    
      x[POS] = mouseX;
      y[POS] = mouseY;
    
      ellipse(x[0], y[0], DIM, DIM);
    }
    
  • I have some vague idea of what the code does... However, I don;t think I could explain it properly. GoToLoop code is really nice and is exactly what I want but I'm not sure what is going on in there!

  • edited November 2013

    Arrays x & y memorizes latest NUM mouseX & mouseY values.
    At each draw() iteration, those mouse coordinates enter those arrays from their tail. That is, their POS index.

    Of course, we gotta get rid of oldest entry to make room for newest coordinates!
    In order to achieve that, the for loop block rotates everything to left, towards the head.

    So oldest entry, which is the head index 0, is lost. And it's replaced by following index 1.
    In the end, latest POS index, which is tail index, becomes vacant.

    And thus we got room to store current mouseX & mouseY coordinates! :P
    And finally, an ellipse() is drawn using oldest entry, which is the head index 0! (*)

    As you can see, we got an emulated queue structure using array.
    That is, values get in from tail and get out from head. This is called FIFO. :ar!

    https://en.wikipedia.org/wiki/FIFO

Sign In or Register to comment.