How can i show only a certain number of members of an Array?

Hi,

I have always been bad with Arrays, maybe someone can help me out.
I am trying to create an interactive Processing sketch, where I send OSC messages into Processing, which I have worked out.

I took one of the examples from the vectors chapter of the Nature of Code book and I am altering it /building upon it.

When I run my sketch you can see a bunch of boxes, which are part of an Array, randomly appear on the screen and start floating off screen. What I want to happen is that when a variable, say “ramp1.” = 1, 1 box will be randomly generated and float off screen, when ramp1 = 2, 2 boxes will float off screen.

Right now the boxes are generated from this:

  for (int i = 0; i < movers.length; i++) {
    movers[i].update();
    movers[i].display();

Which creates all the boxes in the array. If I take my incoming OSC value, ramp1, and convert it to an int, when I first run the sketch, it will appear, float offscreen, and I’m wondering the best way to get it back to the screen to float off again.

i’m doing this to get the box to initially float off screen?

int r1 = int(ramp1);

  movers[r1].update();
    movers[r1].display();

What would be a good way to reset a box back onto the screen, and control the number of boxes showing?

I realize this is kind of a basic question, any help is appreciated.

tHank you and I put my code + one tab below.



Mover[] movers = new Mover[100];

float ramp1;

import oscP5.*;

OscP5 oscP5;

void setup() {
 
  size(800,800);
  smooth();
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(); 
  }
    oscP5 = new OscP5(this, 12000);
}



void oscEvent(OscMessage theOscMessage) {    

  float value = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp1")) {
    if (value > -1000) {
      ramp1 = value;
    } else {
      ramp1 = 0.0;
    }
  }
}


void draw() {
  
    background(255);
    
  
  strokeWeight(2);
  stroke(0);
  fill(50,50,180);
  ellipse(width/2, height/2, 500,500);
  
println(ramp1);


  for (int i = 0; i < movers.length; i++) {
    movers[i].update();
    movers[i].display(); 
    
    // need to figure out how to show/hide these

  }
  


}

next tab for Object




class Mover {

  // The Mover tracks location, velocity, and acceleration 
  PVector location;
  PVector velocity;
  PVector acceleration;
  // The Mover's maximum speed
  float topspeed;
  float xrange;
  float yrange;
float destx, desty;

  Mover() {
    
    xrange = random(width);
    if ( xrange > 300 && xrange < 500 ){
      yrange = random(height);
    }
    
      else { yrange = random(100)+height/2-50;
      }
    // Start in the center
    location = new PVector(xrange,yrange);
    velocity = new PVector(0,0);
    topspeed = 5;
  }

  void update() {
    
    if (xrange < width/2-250){
      destx = 0-200;
      desty = height/2;
    }
    
      if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2-250 && yrange < height/2 ){
      destx = width/2;
      desty =0-200;
    }
    
      if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2 && yrange < height/2+250 ){
      destx = width/2;
      desty = height+200;
    }
    
    
    
      if (xrange >  width/2+250){
      destx = width+200;
      desty = height/2;
    }
    
       if (yrange < height/2-250){
      desty = 0-200;
      destx = width/2;
    }
    
     //   if (yrange > height/2-250 && yrange < height/2+250){
 //     desty = height/2;
  //  }
    
      if (yrange >  height/2+250){
      desty = height + 200;
      destx = width/2;
    }
    
    // Compute a vector that points from location to mouse
    PVector dest = new PVector(destx,desty);
    PVector acceleration = PVector.sub(dest,location);
    // Set magnitude of acceleration
    acceleration.setMag(0.2);
    acceleration.normalize();
    acceleration.mult(0.2);
    
    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Limit the velocity by topspeed
    velocity.limit(topspeed);
    // Location changes by velocity
    location.add(velocity);
  }

  void display() {
    rectMode(CENTER);
    stroke(0);
    strokeWeight(2);
    //fill(127,200);
    rect(location.x,location.y,48,48);
    if (location.x > width/2-250 && location.x < width/2+250 && location.y > height/2-250 && location.y < height/2+250){
      fill(255,200);
    }
    else { fill(100, 200,180,100);
    }
  }

}

This would be instead of

i < movers.length; 

now

i < ramp1; 

Reset a box

basically, when they fall down and leave the screen, you need to reset their y-value to -10.

OR in your case, repeat the init process from the constructor when they leave the screen:

    /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if (dist(location.x, location.y, width/2, height/2) > width/2) {

      xrange = random(width);
      if ( xrange > 300 && xrange < 500 ) {
        yrange = random(height);
      } else { 
        yrange = random(100)+height/2-50;
      }
      // Start in the center
      location = new PVector(xrange, yrange);
      velocity = new PVector(0, 0);
      topspeed = 5;

      //location.x=width/2;
      //location.y=height/2;
    }

Chrisir

Full Sketch



import oscP5.*;

OscP5 oscP5;

Mover[] movers = new Mover[100];

float ramp1=13;


void setup() {
  size(800, 800);
  smooth();

  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover();
  }
  oscP5 = new OscP5(this, 12000);
}

void draw() {
  background(255);

  strokeWeight(2);
  stroke(0);
  fill(50, 50, 180);
  ellipse(width/2, height/2, 500, 500);

  println(ramp1);

  for (int i = 0; i < ramp1; i++) {
    movers[i].update();
    movers[i].display(); 
    // need to figure out how to show/hide these
  }
}

void oscEvent(OscMessage theOscMessage) {    

  float value = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp1")) {
    if (value > -1000) {
      ramp1 = value;
    } else {
      ramp1 = 0.0;
    }
  }
}

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

class Mover {

  // The Mover tracks location, velocity, and acceleration 
  PVector location;
  PVector velocity;
  PVector acceleration;
  // The Mover's maximum speed
  float topspeed;
  float xrange;
  float yrange;
  float destx, desty;

  //constr
  Mover() {
    xrange = random(width);
    if ( xrange > 300 && xrange < 500 ) {
      yrange = random(height);
    } else { 
      yrange = random(100)+height/2-50;
    }
    // Start in the center
    location = new PVector(xrange, yrange);
    velocity = new PVector(0, 0);
    topspeed = 5;
  }//constr

  void update() {

    if (xrange < width/2-250) {
      destx = 0-200;
      desty = height/2;
    }

    if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2-250 && yrange < height/2 ) {
      destx = width/2;
      desty =0-200;
    }

    if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2 && yrange < height/2+250 ) {
      destx = width/2;
      desty = height+200;
    }



    if (xrange >  width/2+250) {
      destx = width+200;
      desty = height/2;
    }

    if (yrange < height/2-250) {
      desty = 0-200;
      destx = width/2;
    }

    //   if (yrange > height/2-250 && yrange < height/2+250){
    //     desty = height/2;
    //  }

    if (yrange >  height/2+250) {
      desty = height + 200;
      destx = width/2;
    }

    /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if (dist(location.x, location.y, width/2, height/2) > width/2) {

      xrange = random(width);
      if ( xrange > 300 && xrange < 500 ) {
        yrange = random(height);
      } else { 
        yrange = random(100)+height/2-50;
      }
      // Start in the center
      location = new PVector(xrange, yrange);
      velocity = new PVector(0, 0);
      topspeed = 5;

      //location.x=width/2;
      //location.y=height/2;
    }

    // Compute a vector that points from location to mouse
    PVector dest = new PVector(destx, desty);
    PVector acceleration = PVector.sub(dest, location);
    // Set magnitude of acceleration
    acceleration.setMag(0.2);
    acceleration.normalize();
    acceleration.mult(0.2);

    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Limit the velocity by topspeed
    velocity.limit(topspeed);
    // Location changes by velocity
    location.add(velocity);
  }

  void display() {
    rectMode(CENTER);
    stroke(0);
    strokeWeight(2);
    //fill(127,200);
    rect(location.x, location.y, 48, 48);
    if (location.x > width/2-250 && 
      location.x < width/2+250 &&
      location.y > height/2-250 &&
      location.y < height/2+250) {
      fill(255, 200);
    } else { 
      fill(100, 200, 180, 100);
    }
  }
}
//

2 Likes

Hi Chrisir.

This works very well. I am going to tweak it to my needs but you answered or resolved what I was trying to put into code.

Thank you so much for the help!

1 Like

Hey Chrisir,

I don’t know if you have a sec maybe you can provide some further input.

With the solution you provided when one of the boxes appears it floats off screen, then it’s immediately back in the center of the screen and floats off again, sort of on and on forever.

What I am trying to achieve is to have some control over the boxes. So when I send an OSC message one (or more) boxes will appear, then stop till i send another message. This is actually what happens when I first start the sketch. If ramp1 = 1 one box will appear, then i make ramp1 = 2 and another box will appear. And if i increment by 2, 2 boxes will appear, etc. But once I get to 30 ( the size of the array) i can’t get any more boxes to generate, as they are all off the screen I believe.

I came up with a solution that looks cool in a glitchy kind of way, but I’m pretty sure it’s not the right way.

I Introduced a new variable, ramp2. When I want a box or boxes to appear I make ramp2 = 3 for a millisecond, then go less than 3. This makes a box reappear on screen.

Here’s that bit of code:

   if (ramp2 >=3) {

      xrange = random(width);
      if ( xrange > 300 && xrange < 500 ) {
        yrange = random(height);
      } else { 
        yrange = random(100)+height/2-50;
      }
     
      location = new PVector(xrange, yrange);
      velocity = new PVector(0, 0);
      topspeed = 5;

But I wonder if there is a way to re-set my sketch to it’s initial state, when all the boxes locations are not yet generated, and they appear one at a time. If there was a way, after all the members of the array have appeared and are out of the bounds of the screen, that the sketch could go back to it’s initial state that would be what I think I am trying to achieve. Does this make sense? Thank you for your input.

Here’s the whole sketch again

float ramp1;
float ramp2 = 1;

import oscP5.*;

OscP5 oscP5;

Mover[] movers = new Mover[100];

//float ramp1=13;


void setup() {
  size(800, 800);
  smooth();

  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover();
  }
  oscP5 = new OscP5(this, 12000);
}

void oscEvent(OscMessage theOscMessage) {    

  float value = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp1")) {
    if (value > -1000) {
      ramp1 = value;
    } else {
      ramp1 = 0.0;
    }
  }
    float value2 = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp2")) {
    if (value2 > -1000) {
      ramp2 = value2;
    } else {
      ramp2 = 0.0;
    }
  }
  
  
}

void draw() {
  background(255);

  strokeWeight(2);
  stroke(0);
  fill(50, 50, 180);
  ellipse(width/2, height/2, 500, 500);

  println(ramp1);

  for (int i = 0; i < ramp1; i++) {
    movers[i].update();
    movers[i].display(); 
    // need to figure out how to show/hide these
  }
}


And the object tab

class Mover {

  // The Mover tracks location, velocity, and acceleration 
  PVector location;
  PVector velocity;
  PVector acceleration;
  // The Mover's maximum speed
  float topspeed;
  float xrange;
  float yrange;
  float destx, desty;

  //constr
  Mover() {
    xrange = random(width);
    if ( xrange > 300 && xrange < 500 ) {
      yrange = random(height);
    } else { 
      yrange = random(100)+height/2-50;
    }
    // Start in the center
    location = new PVector(xrange, yrange);
    velocity = new PVector(0, 0);
    topspeed = 5;
  }//constr

  void update() {

    if (xrange < width/2-250) {
      destx = 0-200;
      desty = height/2;
    }

    if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2-250 && yrange < height/2 ) {
      destx = width/2;
      desty =0-200;
    }

    if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2 && yrange < height/2+250 ) {
      destx = width/2;
      desty = height+200;
    }



    if (xrange >  width/2+250) {
      destx = width+200;
      desty = height/2;
    }

    if (yrange < height/2-250) {
      desty = 0-200;
      destx = width/2;
    }

    //   if (yrange > height/2-250 && yrange < height/2+250){
    //     desty = height/2;
    //  }

    if (yrange >  height/2+250) {
      desty = height + 200;
      destx = width/2;
    }

    /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if (ramp2 >=3) {

      xrange = random(width);
      if ( xrange > 300 && xrange < 500 ) {
        yrange = random(height);
      } else { 
        yrange = random(100)+height/2-50;
      }
     
      location = new PVector(xrange, yrange);
      velocity = new PVector(0, 0);
      topspeed = 5;

      //location.x=width/2;
      //location.y=height/2;
    }

    // Compute a vector that points from location to mouse
    PVector dest = new PVector(destx, desty);
    PVector acceleration = PVector.sub(dest, location);
    // Set magnitude of acceleration
    acceleration.setMag(0.2);
    acceleration.normalize();
    acceleration.mult(0.2);

    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Limit the velocity by topspeed
    velocity.limit(topspeed);
    // Location changes by velocity
    location.add(velocity);
  }

  void display() {
    rectMode(CENTER);
    stroke(0);
    strokeWeight(2);
    //fill(127,200);
    rect(location.x, location.y, 48, 48);
    if (location.x > width/2-250 && 
      location.x < width/2+250 &&
      location.y > height/2-250 &&
      location.y < height/2+250) {
      fill(255, 200);
    } else { 
      fill(100, 200, 180, 100);
    }
  }
}
//

I understand. My approach was just a quick one.

I would recommend to use an ArrayList, see reference.

Here you can spawn as many rects as you want and you can remove items from the ArrayList when they left the screen. You can add new items when your osc value is bigger 1.

I hope this helps!

Chrisir

1 Like

Chrisir,

Awesome thanks for the tip. I’ll look into that. It seems promising.

1 Like

here is an example

you can click 0…9 to simulate OSC events



float ramp1 = 9;
float ramp2 = 1;

import oscP5.*;

OscP5 oscP5;

ArrayList<Mover> movers = new ArrayList();

//float ramp1=13;


void setup() {
  size(800, 800);
  smooth();

  for (int i = 0; i < 3; i++) {
    movers.add ( new Mover()  );
  }
  oscP5 = new OscP5(this, 12000);
}

void draw() {
  background(255);

  strokeWeight(2);
  stroke(0);
  fill(50, 50, 180);
  ellipse(width/2, height/2, 500, 500);

  println(ramp1);

  for (int i = 0; i < movers.size(); i++) {
    movers.get(i).update();
    movers.get(i).display(); 
    // need to figure out how to show/hide these
  }

  // remove !!!! backwards!
  for (int i = movers.size()-1; i>=0; i--) {
    if (! movers.get(i).isAlive ) 
      movers.remove(i);
  }//for
}

void keyPressed() {
  if (key>='0'&&key<='9') 
  {
    for (int i = 0; i < int(key+""); i++) {
      movers.add ( new Mover()  );
    }
  }
}

void oscEvent(OscMessage theOscMessage) {    

  float value = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp1")) {
    if (value > -1000) {
      ramp1 = value;
    } else {
      ramp1 = 0.0;
    }
  }
  float value2 = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp2")) {
    if (value2 > -1000) {
      ramp2 = value2;
    } else {
      ramp2 = 0.0;
    }
  }
}

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

class Mover {

  // The Mover tracks location, velocity, and acceleration 
  PVector location;
  PVector velocity;
  PVector acceleration;
  // The Mover's maximum speed
  float topspeed;
  float xrange;
  float yrange;
  float destx, desty;

  boolean isAlive = true; 

  //constr
  Mover() {
    xrange = random(width);
    if ( xrange > 300 && xrange < 500 ) {
      yrange = random(height);
    } else { 
      yrange = random(100)+height/2-50;
    }
    // Start in the center
    location = new PVector(xrange, yrange);
    velocity = new PVector(0, 0);
    topspeed = 5;
  }//constr

  void update() {

    if (xrange < width/2-250) {
      destx = 0-200;
      desty = height/2;
    }

    if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2-250 && yrange < height/2 ) {
      destx = width/2;
      desty =0-200;
    }

    if (xrange > width/2-250 && xrange < width/2+250 && yrange > height/2 && yrange < height/2+250 ) {
      destx = width/2;
      desty = height+200;
    }



    if (xrange >  width/2+250) {
      destx = width+200;
      desty = height/2;
    }

    if (yrange < height/2-250) {
      desty = 0-200;
      destx = width/2;
    }

    //   if (yrange > height/2-250 && yrange < height/2+250){
    //     desty = height/2;
    //  }

    if (yrange >  height/2+250) {
      desty = height + 200;
      destx = width/2;
    }

    /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if (ramp2 >=3) {

      xrange = random(width);
      if ( xrange > 300 && xrange < 500 ) {
        yrange = random(height);
      } else { 
        yrange = random(100)+height/2-50;
      }

      location = new PVector(xrange, yrange);
      velocity = new PVector(0, 0);
      topspeed = 5;

      //location.x=width/2;
      //location.y=height/2;
    }

    if (location.dist(new PVector (width/2, height/2)) > width)
      isAlive = false; 

    // Compute a vector that points from location to mouse
    PVector dest = new PVector(destx, desty);
    PVector acceleration = PVector.sub(dest, location);
    // Set magnitude of acceleration
    acceleration.setMag(0.2);
    acceleration.normalize();
    acceleration.mult(0.2);

    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Limit the velocity by topspeed
    velocity.limit(topspeed);
    // Location changes by velocity
    location.add(velocity);
  }

  void display() {
    rectMode(CENTER);
    stroke(0);
    strokeWeight(2);
    //fill(127,200);
    rect(location.x, location.y, 48, 48);
    if (location.x > width/2-250 && 
      location.x < width/2+250 &&
      location.y > height/2-250 &&
      location.y < height/2+250) {
      fill(255, 200);
    } else { 
      fill(100, 200, 180, 100);
    }
  }
}
//

It’s amazing how you didn’t change much, but it works exactly as it’s supposed to.

I see the Array list, plus the boolean statement.
I am still learning object oriented programing, and this is a really valuable method, because often I just one to control a few object and don’t need all of them.

thank you so much for the valuable input and lesson!

Nick

1 Like