Initialising a global array: this works, but WHY?

I made some simple test code for setting up and using an array of colours that worked fine as a straight through thing (i.e. no setup, no draw). Then I modified it for use with a setup and frame loop and eventually got it to work, but I am confused about what went wrong.

It didn’t work to declare the array as a global variable, and try to initialise the values outside of setup and draw:

int palettesize = 3;
color[] palette = new color [palettesize];   // I get an error flagged that it wants a left curly
palette[0] = color(209, 54, 39, 25);
palette[1] = color(209, 54, 39, 100);
palette[2] = color(209, 54, 39, 200);

It didn’t work to declare the whole thing inside of setup as then the variable wasn’t possible to reference from within draw. What did work was to set up the empty array outside of setup and draw, and fill its values within setup, like so:

int palettesize = 3;
int howtall = 20;
color[] palette = new color [palettesize];


void setup() {
  frameRate(1);
  palette[0] = color(209, 54, 39, 25);  
  palette[1] = color(209, 54, 39, 100);
  palette[2] = color(209, 54, 39, 200);
}

void draw() {
  
  if (frameCount < palettesize+1) {
    color usecolor = palette[frameCount-1];
    fill(usecolor);

    rect(0,frameCount*howtall, 10, howtall);
  }
}

Can someone explain to me what’s going on here? What is puzzling is why I can’t initialise the array values outside of the setup loop, when I can initialise an integer variable outside the setup loop, and, in fact need to do so.

Thanks!

(Not familiar with Java except via learning Processing right now - but have used a variety of other languages)

palette[0] = color(209, 54, 39, 25);
palette[1] = color(209, 54, 39, 100);
palette[2] = color(209, 54, 39, 200);

These statements can only be executed inside a method / function, in this case we put it inside setup(). The reason being are that they are assignment statements i.e. something = something_else

Unless you are familiar with Java classes and Processing preprocessor then you just have to accept it.

The only thing you can have outside a method are declarations with/without initializers.

The following codes works because it declares a color array of length 3 and populates it, i.e. has an initializer

int palettesize = 3;
int howtall = 20;
color[] palette = new color[] {
  color(209, 54, 39, 25), 
  color(209, 54, 39, 100), 
  color(209, 54, 39, 200)
};

void setup() {
  frameRate(1);
}

void draw() {
  if (frameCount < palettesize+1) {
    color usecolor = palette[frameCount-1];
    fill(usecolor);

    rect(0, frameCount*howtall, 10, howtall);
  }
}

Thanks… that’s what the syntax checker was hinting, wasn’t it? I didn’t go there because I didn’t want to use the curly braces syntax for assignment.

I was wanting to avoid curly brace way of assignment because later (when I develop the design more fully) I may want to be assigning values programmatically in a way that exploits the use numeric indices, and can scale gracefully i.e. automatically across increases in the number of colours in the palette. So I wanted to start with a form that’s close to what I think I will need later, for where I’m heading.

To me, the key statement in what you said seems to be “the only thing you can have outside a method are declarations”.

Just unpacking this a bit - does this mean, then, that the curly brace syntax does count as a declaration, but the (declare-empty-array then fill-by-index) way of doing “the same thing” does not count as a declaration, because it’s not done in one statement?

I guess that makes sense to me, as it’s a declaration (which is ok) plus an assignment in a different statement (which is not ok). But if you can smush them into one statement, it’s all fine. i.e. in the integer example and the curly braces syntax example, you can do a declaration and an assignment in one statement - and that’s fine, because although it’s a declaration-and-an-assignment in one, it’s treated as a declaration?

Thanks for your help on this. Seems like something I can just accept for the moment, then understand better later…!

2 valid Processing/Java ways to initialize variables and containers outside functions: :coffee:

final color[] palette = {
  #FF0000, 
  #008000, 
  #0000FF
};

void setup() {
  frameRate(1);
}

void draw() {
  background(palette[frameCount % palette.length]);
}
static final int COLORS = 3;
final color[] palette = new color[COLORS];

{
  palette[0] = #FF0000; 
  palette[1] = #008000; 
  palette[2] = #0000FF;
}

void setup() {
  frameRate(1);
}

void draw() {
  background(palette[frameCount % COLORS]);
}
1 Like