Pass an array to a new instance of my class

How would I go about passing an array of images to a class? My endgame is to have one class that creates an animation, so when I create multiple instances of this class they build a 3x3 grid of animations with each instance playing a different animation. So, I want to pass a different array of images to each instance of my class.

I think I also need to know how to push multiple arrays into one array as well.

let imgs = [], const NUM_IMAGES = 13;
let myClass = [];
let arrayOfArrays = [];

function preload() {
  for (let i = 0; i < NUM_IMAGES; i++) {
    imgs[i] = loadImages('');
  }
}

function setup() {
  createCanvas();

//something like this
  for (let i = 0; i<6; i++) {
    arrayOfArrays[i] = new Array(imgs);
  }

  for (let i = 0; i < 6; i++) {
    let mc = new myClass(arrayOfArrays[i]); //<---?
    myClass.push(mc);
  }
}

function draw() {
  background(51);
  
  myClass.forEach(panel => {
    panel.run();
  })
}

class myClass {
constructor(_imgs) {
  this.imgs = [_imgs]; //<---?
  this.index = 0;
}

  run() {
    image(this.imgs[this.index],0,0);
    this.index = (this.index+1) % imgs.length;
  }
}

Dunno exactly what you’re asking. But is it anything like this: :man_shrugging:

const IMAGES = 13, imgs = Array(IMAGES),
      ANIMS = 2, anims = Array(ANIMS);

function setup() {
  anims[0] = new Anim(imgs[2], imgs[3], imgs[1], imgs[4], imgs[10], imgs[0]);
  anims[1] = new Anim(imgs[1], imgs[5], imgs[7], imgs[13], imgs[9], imgs[6]);
}

class Anim {
  constructor(...imgs) {
    this.imgs = imgs;
    this.idx = 0;
  }

  display() {
    image(this.imgs[this.idx], 0, 0);
    this.idx = (this.idx + 1) % imgs.length;
  }
}

Not sure, I just want to make a 2d array where each index in that array contains an array of images that I can pass to a class so each instance plays a different set of images.

I tried to rework my code example to better describe what I am trying to accomplish.

let imgs1 = [];
let imgs2 = [];
const NUM_IMAGES = 13;
let my2dArray = [];

let anim = [];;

function preload() {
  for (let i = 0; i<NUM_IMAGES; i++) { 
    imgs1[i] = loadImages('');
  }

  for (let i = 0; i<NUM_IMAGES; i++) { 
    imgs2[i] = loadImages('');
  }
}

function setup() {
  my2dArray[0] = new Array(imgs1);//<---?
  my2dArray[1] = new Array(imgs2);//<---?

  for (let i = 0; i < 6; i++) {
    let a = new Anim(my2dArray[i]);
    anim.push(a);
  }
}

class Anim {
  constructor(_my2dArray) {
    this.arr = _my2dArray; //<---?
    this.index = 0;
  }

 run() {
    image(this.arr[this.index],0,0);
    this.index = (this.index+1) % NUM_IMAGES;
  }
}

So I think I have my 2d array filling up properly, i logged it in draw() as well as this.arr and it seems to filled, but it’s obviously not being passed correctly or something bc I get …

Uncaught TypeError: Cannot read property 'width' of undefined
const NUM_IMAGES = 13;
let my2dArr = [];

let anim = [];

function preload() {
  for (let i = 0; i < 6; i++) {
    my2dArr[i] = new Array();
      for (let j = 0; j<NUM_IMAGES; j++) { 
        my2dArr[i][j] = loadImages('');
    }
  }
}

function setup() {
  for (let i = 0; i < 6; i++) {
    let a = new Anim(my2dArr[i]);
    anim.push(a);
  }
}

class Anim {
  constructor(_my2dArr) {
    this.arr = _my2dArr; //<---?
    this.index = 0;
  }

 run() {
    image(this.arr[this.index],0,0);
    this.index = (this.index+1) % NUM_IMAGES;
  }
}

All the code you’ve been posting aren’t actually runnable. :running_man:
Obviously loadImages('') won’t work! :crazy_face:
And neither name labels 2dArray nor 2dArr are JS valid, b/c they start w/ a digit character.
BtW, why aren’t they the same variable name? :dizzy_face:
Consider hosting your sketch at OpenProcessing.org/sketch/create
It accepts image uploads there. :sunglasses:

I wasn’t necessarily posting it to be runnable … just descriptive.

I left loadImages blank since I can’t upload images here, and used 2dArray to be explicit in what I want.

difference in var name was a typo, all fixed now.

is what I am asking not being described well enough?

By quickly reading your sketch I can’t pinpoint what would cause undefined for p5::width. :thinking:

As I understand, you’re now creating a 2D array w/ 6 rows and 13 columns.
Each 1D row array is a container of 13 loaded p5.Image objects.
For each instance of Anim a 1D row array is passed to its constructor.

That’s why an actual runnable code would be nice. :smiley_cat:

Actually not all fixed! Within setup(): let a = new Anim(2dArr[i]); :space_invader:

1 Like

lol … sry bout that last typo not being caught.

i uploaded it here … https://www.openprocessing.org/sketch/621313

yes, it sounds like you understand what i am going for.
basically in the end I want what would look like a 3x3 story board, each board playing a different animation.

my example only has enough images for one animated board … but i plan to upload more once I get the functionality down.

Hey! I’ve forked and made some changes to your sketch till I’ve got it working: :partying_face:

// https://Discourse.Processing.org/t/pass-an-array-to-a-new-instance-of-my-class/5183/10
// 2018-Nov-04

const FILENAME = 'zombie', EXT = '.png',
      FPS = 12, BG = 50,
      ANIMS = 1, IMAGES = 19,
      imgs2d = Array(ANIMS), anims = Array(ANIMS);

let bg;

function preload() {
  for (let row = 0; row < ANIMS; ++row) {
    const imgs1d = imgs2d[row] = Array(IMAGES);
    for (let col = 0; col < IMAGES; ++col)  imgs1d[col] = loadImage(FILENAME + col + EXT);
  }
}

function setup() {
  createCanvas(windowWidth * .95, windowHeight * .95);
  frameRate(FPS).imageMode(CENTER);
  bg = color(BG);
  for (let i = 0; i < ANIMS; ++i)  anims[i] = new Anim(imgs2d[i], width>>1, height>>1);
}

function draw() {
  background(bg);
  for (const anim of anims)  anim.display().update();
}

class Anim {
  constructor(arr1d, x, y) {
    this.arr = arr1d;
    this.idx = 0;
    this.x = x;
    this.y = y;
  }

  display() {
    image(this.arr[this.idx], this.x, this.y);
    return this;
  }

  update() {
    this.idx = (this.idx + 1) % this.arr.length;
    return this;
  }
}
2 Likes

Very nice … thank you so much!!!

I feel I understand mostly what is going on, doesn’t look like I was too far off, but can you explain what this is doing exactly, or give me a term to research? I feel I get it by looking, but would like a deeper understanding …

const imgs1d = imgs2d[row] = Array(IMAGES);

again thank you for your help.

  • The assignment operator = is evaluated from right to left.
  • 1st an Array w/ length = IMAGES is created.
  • Then its reference is stored inside the Array referenced by variable imgs2d @ index = row.
  • And that same reference is also stored in the newly declared local variable imgs1d.
  • Thus imgs1d is an alias to the Array reference stored @ imgs2d[row].
2 Likes

Thanks, that makes sense the way you explained it.

@GoToLoop I see you forked my sketch … i went ahead and broke it down into 3 seperate arrays, but I still want to know how to have just one multidimensional array passing into my class so I can load any amount of panels with a different image sequence. ty.

That’s exactly what I’m trying to pull out right now. :stuck_out_tongue:

This time you’ve got not 1 but 3 FILENAMES: :file_cabinet:
const FILENAMES = [ 'carDefault_', 'carSedan_', 'carYellow_' ].

Therefore you’ve got ANIMS equal to 3: const ANIMS = FILENAMES.length;

That’s the approach I’m following right now. :construction_worker_man:

1 Like

Finished the fork. Here’s what I’ve ended up w/: :fork_and_knife:

OpenProcessing.org/sketch/622494

// https://Discourse.Processing.org/t/pass-an-array-to-a-new-instance-of-my-class/5183/17
// 2018-Nov-04
// Sprite created by https://DevilsWorkshop.Itch.io/low-poly-2d-car-sprites-free
// Thanks to @GoToLoop for the help.

const FILENAMES = [ 'carDefault_', 'carSedan_', 'carYellow_' ], EXT = '.png',
      FPS = 8, BG = 51, SIZE = .9,
      ANIMS = FILENAMES.length, IMAGES = 12, COLS = 3,
      imgs2d = Array(ANIMS), anims = Array(ANIMS);

let bg;

function preload() {
  for (let row = 0; row < ANIMS; ++row) {
    const imgs1d = imgs2d[row] = Array(IMAGES), filename = FILENAMES[row];
    for (let col = 0; col < IMAGES; ++col)  imgs1d[col] = loadImage(filename + col + EXT);
  }
}

function setup() {
  createCanvas(windowWidth * SIZE | 0, windowHeight * SIZE | 0);
  frameRate(FPS).imageMode(CENTER);
  bg = color(BG);
  createAnims();
}

function draw() {
  background(bg);
  for (const anim of anims)  anim.run();
}

function windowResized() {
  resizeCanvas(windowWidth * SIZE | 0, windowHeight * SIZE | 0);
  repositionAnims();
  console.log(width, height);
}

function createAnims() {
  const w = width / COLS | 0, h = height >> 1, offW = w >> 1;
  for (let i = 0; i < ANIMS; anims[i] = new Anim(imgs2d[i], ++i*w - offW, h));
}

function repositionAnims() {
  const w = width / COLS | 0, h = height >> 1, offW = w >> 1;
  for (let i = 0; i < ANIMS; anims[i].setXY(++i*w - offW, h));
}

class Anim {
  constructor(arr1d, x, y) {
    this.frames = arr1d;
    this.idx = 0;
    this.setXY(x, y);
  }

  setXY(x, y) {
    this.x = x;
    this.y = y;
    return this;
  }

  display() {
    image(this.frames[this.idx], this.x, this.y);
    return this;
  }

  update() {
    this.idx = (this.idx + 1) % this.frames.length;
    return this;
  }

  run() {
    return this.display().update();
  }
}
2 Likes

Ahhh … I see. Thank you so much, totally makes sense how you are filling that array now. I greatly appreciate your help!

Can you explain what is going on here? I think this is a bitwise OR operator, which I kind of understand, but not so much in this use case.

| 0 is just a quick trick to truncate (remove the fractional part) the resultant value. :mage:

Equivalent to: const w = int(width / COLS); :nerd_face:
p5js.org/reference/#/p5/int

1 Like

Addendum: All JS’ bitwise operators truncate their result and turn them into a 32bit signed value. :hocho: