Novice Coder: failure animating figure whose eyes follow the cursor > figure moves, eyes don't

edited February 2017 in Questions about Code

I've been studying processing for about 3 weeks. This is my first time learning a programming language.

I found an example on the website for creating "eyes" that follow your cursor (https://processing.org/examples/arctangent.html). I used this code as a reference to put two (differently sized) eyes on a figure I created.

Problem -- when I change the location of the figure, the eyes remain in the same location.

//Test Figure
Eye e1, e2;
float es = 2.5;//to determine character size
float ex = 400;//to determine character location
float ey = 250;//to determine character location
float v = 0;
void setup() {
  size(800, 800);
  e1 = new Eye( ex-es*7, ey, es*12);
  e2 = new Eye( ex+es*7, ey, es*8); 
}

//Colors Scheme
//0, 97, 135 dark teal
//0, 153, 213 medium teal
//0, 172, 224 bright teal
//115, 212, 250 light teal

void draw() {
  background(255); 
  stroke(0, 97, 135);
  strokeWeight(2);
  //HEAD
  fill(115, 212, 250);
  quad(ex+es*5, ey+es*15, ex-es*5, ey+es*15, ex-es*2, ey+es*25, ex+es*2, ey+es*25); //neck
  ellipse(ex, ey-es, es*34, es*36);//face
  //LOWER BODY
  fill(0, 172, 224);
  bezier(ex+es*12, ey+es*55.1, ex+es*10, ey+es*30, ex-es*10, ey+es*30, ex-es*12, ey+es*55.1);
  bezier(ex+es*12, ey+es*55, ex-es, ey+es*80, ex+es, ey+es*80, ex-es*12, ey+es*55);
  //MIDSECTION
  fill(255);
  bezier(ex+es*16, ey+es*39.1, ex+es*16, ey+es*20, ex-es*16, ey+es*20, ex-es*16, ey+es*39.1);
  bezier(ex+es*16, ey+es*39, ex-es*2, ey+es*65, ex+es*2, ey+es*65, ex-es*16, ey+es*39);
  //BREASTPLATE
  fill(0, 153, 213);
  bezier(ex+es*20, ey+es*31.1, ex+es*18, ey+es*18, ex-es*18, ey+es*18, ex-es*20, ey+es*31.1);
  bezier(ex+es*20, ey+es*31, ex-es*18, ey+es*45, ex+es*18, ey+es*45, ex-es*20, ey+es*31);

  noFill();
  noStroke();
  e1.update(mouseX, mouseY);
  e2.update(mouseX, mouseY);
  e1.display();
  e2.display();
}
class Eye {
  float x, y;
  float size;
  float angle = 0.0;
  Eye(float tx, float ty, float ts) {
    x = tx;
    y = ty;
    size = ts;
  }
  void update(float mx, float my) {
    angle = atan2(my-y, mx-x);
  }
  void display() {
    pushMatrix();
    translate(x, y);
    fill(0, 104, 152);
    ellipse(0, 0, size, size);
    rotate(angle);
    fill(255, 255, 255);
    ellipse(size/4, 0, size/2, size/2);
    popMatrix();

    //figure 8 movement pattern
    ex = ex+cos(v/10)/2;//move side to side
    ey = ey+cos(v/5)/2;//move up and down

    v = v + .05;//speed

  }
}
Tagged:

Answers

  • edited February 2017 Answer ✓

    @eawai --

    You have a number of organizational problems:

    1. use a class for your Figure -- don't put all that code in draw
    2. create your two Eye objects inside the Figure object -- when you update the location of the Figure, then update the location of the Eyes; when you draw the Figure, then draw the Eyes.
    3. in draw, simplify your motion calculation -- pass the x,y to the Figure (which passes it to the Eyes).

    The code could be further simplified / cleaned up -- for example, using relative distances rather than absolute for the eye locations -- but this gives you an idea of a basic pattern of objects.

    Screen Shot 2017-02-27 at 3.47.07 PM

    Figure fig;
    float fx, fy, v;
    
    void setup() {
      size(800, 800);
      stroke(0, 97, 135);
      strokeWeight(2);
      fig = new Figure(400, 250, 2.5);
    }
    
    void draw() {
      background(255); 
      //figure 8 movement pattern
      v = v + 0.05;
      fig.move( fig.ex + cos(v/10)/2, fig.ey + cos(v/5)/2 );
    
      // draw figure
      fig.display();
    }
    
    class Figure {
      float ex, ey; // location
      float es;     // size
      Eye e1, e2;
      Figure(float x, float y, float size){
        ex = x;
        ey = y;
        es = size;
        e1 = new Eye(ex-es*7, ey, es*12);
        e2 = new Eye(ex+es*7, ey, es*8);
      }
      void move(float x, float y){
        // MOVE FIGURE
        ex = x;
        ey = y;
        // MOVE EYES
        e1.move(ex-es*7, ey, es*12);
        e2.move(ex+es*7, ey, es*8);
      }
      void display(){
        pushStyle();
        //HEAD
        fill(115, 212, 250);
        quad(ex+es*5, ey+es*15, ex-es*5, ey+es*15, ex-es*2, ey+es*25, ex+es*2, ey+es*25); //neck
        ellipse(ex, ey-es, es*34, es*36);//face
        //LOWER BODY
        fill(0, 172, 224);
        bezier(ex+es*12, ey+es*55.1, ex+es*10, ey+es*30, ex-es*10, ey+es*30, ex-es*12, ey+es*55.1);
        bezier(ex+es*12, ey+es*55, ex-es, ey+es*80, ex+es, ey+es*80, ex-es*12, ey+es*55);
        //MIDSECTION
        fill(255);
        bezier(ex+es*16, ey+es*39.1, ex+es*16, ey+es*20, ex-es*16, ey+es*20, ex-es*16, ey+es*39.1);
        bezier(ex+es*16, ey+es*39, ex-es*2, ey+es*65, ex+es*2, ey+es*65, ex-es*16, ey+es*39);
        //BREASTPLATE
        fill(0, 153, 213);
        bezier(ex+es*20, ey+es*31.1, ex+es*18, ey+es*18, ex-es*18, ey+es*18, ex-es*20, ey+es*31.1);
        bezier(ex+es*20, ey+es*31, ex-es*18, ey+es*45, ex+es*18, ey+es*45, ex-es*20, ey+es*31);
        popStyle();
        //EYES
        e1.update(mouseX, mouseY);
        e2.update(mouseX, mouseY);
        e1.display();
        e2.display();
      }
    }
    
    class Eye {
      float x, y;
      float size;
      float angle = 0.0;
      Eye(float tx, float ty, float ts) {
        move(tx,ty,ts);
      }
      void move(float tx, float ty, float ts){
        x = tx;
        y = ty;
        size = ts;
      }
      void update(float mx, float my) {
        angle = atan2(my-y, mx-x);
      }
      void display() {
        pushMatrix();
        translate(x, y);
        fill(0, 104, 152);
        ellipse(0, 0, size, size);
        rotate(angle);
        fill(255, 255, 255);
        ellipse(size/4, 0, size/2, size/2);
        popMatrix();
      }
    }
    
Sign In or Register to comment.