Trying to make an array of 'positions' draw from an array of images at random

I’m really struggling with something that I think has got to be obvious. In a sketch I’m making, once you click in a certain area, 20 PNGs will fall down the screen, from random starting positions along the X axis, going at random speeds. I tested the behaviour with a drawn ellipse, that works fine, I get 20 little ellipses dropping at random locations. What I can’t do now is replace those 20 ellipses with a random selection of five images.

At the top, I’ve got my array of positions and my array of images:

Drop[] drops = new Drop[20]; //array of 20 'positions' from which to fall

String[] spiceNames = {"ginger.png", "cardamom.png", "chili.png", "corianderleaf.png", "garlic.png"};
Spice[] spices = new Spice[spiceNames.length]; //loads all 5 

Then where I’m dealing with the behaviour, I’ve got:

class Drop {
  //variables within the scope of the class
  float xPos;
  float yPos;
  float fallSpeed;

  //start just by getting falling ellipses; behaviour, then images
  
    //<constructor>
  Drop (float xPos_, float yPos_, float fallSpeed_)
  {
    xPos = xPos_;
    yPos = yPos_;
    fallSpeed = fallSpeed_;
  }
  
  
  void show()  {      //function to create the object
   
    image (spiceNames random, xPos, yPos, 60, 60); //this is the line I can't get working
  }
  
  void fall()  {    //function to animate the object
    yPos = yPos + fallSpeed;
    if (yPos > height)  {
      yPos = 0;    //when object reaches bottom, reset to top
    }
  }
}

I know that ‘spiceNames random’ is obviously not going to cut it. What I’m trying to do is have each of my 20 ‘drop positions’ use at random one of the five images (i.e. it’s determined randomly for each position). My impulse with ‘image’ is to have that be the start, and then selecting from the ‘spiceNames’ class at random will fill in the filename, but I’m starting to think I’ve got that backwards.

Do I instead create a class of strings - ie the variable names of my images that I have in setup:

 ginger = loadImage ("ginger.png");
  cardamom = loadImage ("cardamom.png");
  chili = loadImage ("chili.png");
  corianderLeaf = loadImage ("corianderleaf.png");
  garlic = loadImage ("garlic.png");

And use those?

1 Like

Hi, welcome to the community!

The image() and loadImage() functions expect a PImage object, not a filename string. Thus, directly passing spiceNames or its elements (which are strings) won’t work.

Have another look at the reference and see if you can get it to run.

To kick it off, this is how you can preload your images during setup().

PImage[] spices = new PImage[5];

void setup() {
  size(800, 600);
  
  String[] spiceNames = {
    "ginger.png", 
    "cardamom.png", 
    "chili.png", 
    "corianderleaf.png", 
    "garlic.png"
  };

  for (int i = 0; i < spiceNames.length; i++) {
    spices[i] = loadImage(spiceNames[i]);
  }
}

You can then randomly pick an image from that PImage array.

    PImage randomSpice = spices[(int)random(spices.length)];