How do I implement push() and pop() to multiple objects of a class?

There are 2 jellybean objects.

I want each to:

1. appear in a different location.
2. spin at a different rate

(I know how to do this via non-OOP coding. But once I reformat as OOP I can’t figure out how to implement push() and pop() to each iteration of the object. I tried to add push() and pop() to the main sketch but that didn’t work. I also tried adding push() and pop() to the display function in the class code – still no success.)

Any guidance is most welcome.
Code as follows:

Jellybean j1;
Jellybean j2;

void setup() {
  size(400, 400);
  j1 = new Jellybean(50, 50, 50);
  j2 = new Jellybean(150, 150, 25);
}
void draw() {
  background(255);
 
  j1.display();
  j1.spin();

  j2.display();
  j2.spin();
}
class Jellybean {

  float x;
  float y;
  float r;
  float angle;

  Jellybean(float tempX, float tempY, float tempR) {
    x = tempX;
    y = tempY;
    r = tempR;
    angle = 0;
  }
  void display() {
    stroke(0);
    noFill();
    smooth();
    strokeWeight(3);
    
    translate(x, y);
    rotate(angle);
    ellipse(x, y, r*2, r);
    }

  void spin() {
   angle = angle + .1;
  }
}
1 Like

Use pushMatrix and popMatrix

in this function display().

  • pushMatrix at the beginning (or before translate),

  • popMatrix at its end

1 Like

Pro-Tipp:

When you say x,y in translate, it would be enough to use ellipse with 0,0 as parameters…

(that might actually be the real issue here)

Chrisir

The sketch did change, however not to the desired result, The 2 objects are still in sync.

Well, they now rotate around their own center instead of around another point.

That’s a progress. (because we now use ellipse with 0,0)

Their positions also don’t add up, that’s also good. That’s because of pushMatrix and popMatrix.

Sync

They are in sync because they both start at angle = 0 and have the same speed for rotation, + .1.

You might want to change this.

You could give them random() values in the constructor (for angle and a new variable angleSpeed that replaces .1)

I think I could have stated my initial question better. My apologies.

I would like each ellipse to have it’s own position (point of origin?) on the screen.

Each ellipse is to spin from it’s center / ellipseMode (CENTER)

For example,
object j1 is at x,y (50, 50)
object j2 is at x.y(150,150)
Eventually, I will add more Jellybean objects at random locations (each with their own point of origin).

I understand what you’re saying about syncing and changing the angle to achieve a different spin rate for ea object, however my main question lies with making each object a distinctly separate entity.

Currently j2 revolves around j1. I do not want objects to be linked in such a way that they revolve around each other as though they are paired.

I want each object to spin in place around its own center (x,y)

did you apply the changes I said?

Post your entire code

  • Did you use pushMatrix and popMatrix?

  • Did you use ellipse with 0,0, because the position is taken care of by translate already?

1 Like

Thank you so much @Chrisir!!
:):joy:
Attaching the code below including your changes.

Jellybean j1;
Jellybean j2;

void setup() {
  size(400, 400);
  j1 = new Jellybean(50, 50, 50, 0, .1);
  j2 = new Jellybean(300, 150, 25, 2, .5);
}
void draw() {
  background(255);
 
  j1.display();
  j1.spin();

  j2.display();
  j2.spin();
}
class Jellybean {

  float x;
  float y;
  float r;
  float angle;
  float angleSpeed;

  Jellybean(float tempX, float tempY, float tempR, float tempAngle, float tempAngleSpeed) {
    x = tempX;
    y = tempY;
    r = tempR;
    angle = tempAngle;
    angleSpeed = tempAngleSpeed;
  }
  void display() {
    stroke(0);
    noFill();
    smooth();
    strokeWeight(3);

    pushMatrix();
    translate(x, y);
    rotate(angle);
    ellipse(0, 0, r*2, r);
    popMatrix();
  }
  void spin() {
    angle = angle + angleSpeed;
  }
}
2 Likes

my version

I use more empty lines between sections and also use ctrl-t in processing to auto-format

I also format the code when posting


// test for 2 objects and 1 class 

Jellybean j1, j2;

void setup() {
  size(400, 400);

  j1 = new Jellybean(266, 66, 50);
  j2 = new Jellybean(150, 150, 25);
}

void draw() {
  background(255);

  j1.display();
  j1.spin();

  j2.display();
  j2.spin();
}

// =====================================================

class Jellybean {

  float x;
  float y;

  float r;

  // we want the objects to rotate a little different
  float angle = random(0.99);
  float angleSpeed = random(.031, .102);

  // constructor
  Jellybean(float tempX, float tempY, 
    float tempR) {
    x = tempX;
    y = tempY;
    r = tempR;
  }// constr 

  void display() {
    stroke(0);
    noFill();
    smooth();
    strokeWeight(3);

    pushMatrix();
    translate(x, y);
    rotate(angle);
    ellipse(0, 0, 
      r*2, r);
    popMatrix();
  }

  void spin() {
    angle += angleSpeed; // add angleSpeed to angle
    angle %= TWO_PI;
    fill(0); 
    text(angle, x-r*3, y);
  }
  //
}//class
//

try to use a different fill / stroke color for each object

When using many jellyBeans, better use an array of them

See tutorials

Using an array is my next step. I wanted to make sure I could get 2 objects to work before applying an array to the mix.
The goal with this project is a very simple game. I will likely have additional questions.

Thank you for posting your code above! It’s very helpful as a novice to see.
I did copy /paste and run it.
I got a blank screen until I commented out the last 2 lines:

//fill (0);
//text(angle, x-r*3, y);

then it ran.

Was that supposed to be there?

Also, what does the line below mean in your code?

angle %= TWO_PI

2 Likes

The last 2 lines (with text()) were there to show the angle as text

The %= line keeps the angle between 0 and two PI (which is the max angle in radians). See % in the reference. When the angle is greater than two PI it gets reset to 0.

the expression %= is a short form similar to +=.
Long form is angle = angle % TWO_PI;

Chrisir

2 Likes

Thank you for the explanation @Chrisir!
I read the reference and I think I understand.

1 Like

One small warning about push/pop, or pushMatrix/popMatrix. This is the correct way to do it with limited objects – say tens, or hundreds.

However, you are going to have 10,000 or 100,000 jellybeans, then pushing and popping for each one 60 times a second will be a huge performance hit. At the point where you experience performance issues / lag, you may want to do something like this:

  1. Use either an Animation class or the Sprites library to pre-render a few animations or sprites – one for each jellybean color, with a good number of frames.

  2. create jellybean objects that contain pointers to these animations / sprites – e.g. Animation myAni= redAni, or blueAni. The jellybean class also has a frame index that determines the current angle (e.g. currently pointing at frame 3, frame 3 is 45 degrees) and a frame step counter that determines the spin rate (e.g. advance 1 frame at a time, or 3, or 10).

  3. Replace this:

    pushMatrix();
    translate(x, y);
    rotate(angle);
    ellipse(0, 0, r*2, r);
    popMatrix();
    

    with this:

    animation.display(x, y);
    currentFrame += spinRate;
    

Get rid of your “spin()”, as it is now automatic and controlled by spinRate. To stop spinning, set spinRate to 0;

2 Likes

Thank you for this additional information @jeremydouglass!