Frame rate drops during a simple tickle animation

I just wrote a small piece of code (part of a project that I want to build) which draws an alien (looks the same as Daniel`s little cute alien! :D ) and tickles around. Basically, it translates the alien randomly within a defined range frame by frame. It works fine in the first few seconds, but then the speed of tickle drops dynamically. I checked the frameRate() for debugging, and as you can see in the attached figure that it indicates the drop of frame rate of draw() function. These are the figures regarding my trouble:

frameRate1

frameRate2

I put the related part of codes in my dropbox and you can find the link here:
https://www.dropbox.com/sh/33dqantk9g3zw5u/AAAGSBWbiAR_fDJpT0fLSBw1a?dl=0

I am also pasting the codes directly to this post:

//Set some constants
color RED = color(255, 0, 0);
color GREEN = color(0, 255, 0);
color BLUE = color(0, 0, 255);
color WHITE = color(255);
color BLACK = color(0);
Alien myAlien;
Tickle tickle;

void setup() {
  size(600, 600);
  background(WHITE);

  //Initialize Alien
  myAlien = new Alien(1); //the value 1 means that there is no scale effect
  //Initialize other components
  tickle = new Tickle(myAlien);
  tickle.setBackground(WHITE);
}

void draw() {
  tickle.agentTickle(5); //tickle in a range between [-5, 5] along x axis and [-5/2, 5/2] along y axis
  println(frameRate); //debugging
}

class Alien {
  float sizeScale;
  float xCenter, yCenter;
  PShape alien, body, head, lefteye, righteye, leftleg, rightleg;
  color leftColor, rightColor;

  Alien(float scale) {
    sizeScale = scale;
    xCenter = width / 2;
    yCenter = height / 2;

    //Initialize the PShape objects
    alien = createShape(GROUP);
    body = createShape();
  }

  PShape drawBody() {
    body.beginShape();
    body.fill(100);
    body.vertex(-25, -100);
    body.vertex(25, -100);
    body.vertex(25, 100);
    body.vertex(-25, 100);
    body.endShape();

    return body;
  }

  PShape drawHead() {
    head = createShape(ELLIPSE, 0, -125, 150, 150);
    head.setFill(255);

    return head;
  }

  PShape drawLefteye(color leftColor) {
    lefteye = createShape(ELLIPSE, -75 / 2 - 10, -125, 50, 75);
    lefteye.setFill(leftColor);

    return lefteye;
  }

  /**
  void setLeftColor(color lc) {
   leftColor = lc;
   }
   */

  PShape drawRighteye(color rightColor) {
    righteye = createShape(ELLIPSE, 75 / 2 + 10, -125, 50, 75);
    righteye.setFill(rightColor);

    return righteye;
  }

  /**
  void setRightColor(color rc) {
   rightColor = rc;
   }

   void setEyesColor(color cl) {
   leftColor = cl;
   rightColor = cl;
   }
   */

  PShape drawLeftleg() {
    leftleg = createShape(LINE, -25, 100, -50, 150);
    leftleg.setStroke(color(0));

    return leftleg;
  }

  PShape drawRightleg() {
    rightleg = createShape(LINE, 25, 100, 50, 150);
    leftleg.setStroke(color(0));

    return rightleg;
  }

  void setScale(float scale) {
    alien.scale(scale);
  }

  float[] getCenterPoint() {
    float[] center = {xCenter, yCenter};

    return center;
  }

  //draw the alien, color of both eyes are set to default color
  void drawAlien() {
    //Add pieces to the alien
    alien.addChild(drawBody());
    alien.addChild(drawHead());
    alien.addChild(drawLefteye(leftColor));
    alien.addChild(drawRighteye(rightColor));
    alien.addChild(drawLeftleg());
    alien.addChild(drawRightleg());

    //Draw the alien
    shape(alien, xCenter, yCenter);
  }

  //Translate to (x, y), color of both eyes are set to default color 
  void drawAlien(float x, float y) {
    //Add pieces to the alien
    alien.addChild(drawBody());
    alien.addChild(drawHead());
    alien.addChild(drawLefteye(leftColor));
    alien.addChild(drawRighteye(rightColor));
    alien.addChild(drawLeftleg());
    alien.addChild(drawRightleg());

    //Draw the alien
    shape(alien, x, y);
  }

  //version of drawAlien which color of left eye and right eye can be set independently
  void drawAlien(color lc, color rc) {
    //Add pieces to the alien
    alien.addChild(drawBody());
    alien.addChild(drawHead());
    alien.addChild(drawLefteye(lc));
    alien.addChild(drawRighteye(rc));
    alien.addChild(drawLeftleg());
    alien.addChild(drawRightleg());

    //Draw the alien
    shape(alien, xCenter, yCenter);
  }

  //Scale myAlien
  void scaleAlien(float scale) {
    myAlien.setScale(scale);
  }
}

class Tickle {
  Alien myAlien;
  float alienX, alienY;
  color backgroundColor;

  Tickle(Alien alien) {
    myAlien = alien; 
    alienX = myAlien.getCenterPoint()[0];
    alienY = myAlien.getCenterPoint()[1];
  }

  void setBackground(color cl) {
    backgroundColor = cl;
  }

  void resetCenter() {
    alienX = myAlien.getCenterPoint()[0];
    alienY = myAlien.getCenterPoint()[1];
  }

  //Without setting color of myAlien's eyes. Return false if it is vibrating.
  void agentTickle(float strength) {
    background(backgroundColor);

    //change the position of myAlien.
    alienX += random(-strength, strength);
    alienY += random(-strength / 2, strength / 2);
    myAlien.drawAlien(alienX, alienY);
  }
}

Thank you very much for your kind advise and help!!

Answers

  • just fixed the code formatting..

  • Answer ✓

    I see that you createShape() a lot. Wouldn't it be less stressful for those Shape objects be created once only for each Alien? :-?

    This following sketch does just that: https://forum.Processing.org/two/discussion/14071/converting-java-code-to-python-for-dataviz#Item_14

  • @GoToLoop Thank you for your kind comment! The code I pasted here is just a part of a project that I want to build. For the purpose of the project, I would like to have fine control of each part of the alien, e.g. head and body, and this is why I created separate Shape objects for each of them. I wish my idea is correct.. :)

  • I have NO experience with Pshape at all, so I'm just wondering, why do it like that? It seems to me that just creating one method in the class alien with rects and ellipses and lines all in one. And then translate that around in another method in the same class or directly in draw..

    But again, I have no experience with pshape, so I'm just wondering what the benefits are..

  • @GoToLoop I think I now get your point! I just revised my code:

    void createAlien() {
        //Add pieces to the alien
        alien.addChild(drawBody());
        alien.addChild(drawHead());
        alien.addChild(drawLefteye(leftColor));
        alien.addChild(drawRighteye(rightColor));
        alien.addChild(drawLeftleg());
        alien.addChild(drawRightleg());
      }
    
    void drawAlien(float x, float y) {
        //Draw the alien
        shape(alien, x, y);
      }
    

    And in setup() function the alien object is just created once:

    void setup() {
      size(600, 600);
      background(WHITE);
    
      //Initialize Alien
      myAlien = new Alien(1); //the value 1 means that there is no scale effect
      myAlien.createAlien();
    
      ...
    }
    

    And problem solved! It works just fine now, no drop of the frame rate! Thank you so much for you help!

  • @Eeyorelife Thank you for your comment! The reason I am doing so is that I would like to further in the project have fine control of each separate components, e.g. head and body, and thus I created them in different PShape objects. Otherwise, it is indeed not necessary to draw the alien like this. I just solved my problem according to @GoToLoop`s advise. I guess it was because that the many PShape objects were created in each of the frame, thus causing my laptop run out of memory.. You can take a look at the above revision I made. :)

Sign In or Register to comment.