Problem with array of objects from a class

Hi everyone!
I found some issue in declaring an array of objects from a class which I wrote in the code. I’m trying to make a Snake-like minigame, and I’m trying to declare an array of objects which should contain its coordinates and some functions I’m using further in the code… but even if I checked every single line of the code, comparing with some tutorial around the Internet, it keeps to give me a NullPointerException fail when I’m about to execute the whole code. Anyone who could explain me the reason why it doesn’t find an array? Thanks!

Here’s the code I wrote until now:

static int dimStart=3;
int dim=dimStart;
Snake.sDir dir;
Snake[] nPiece;

static class Snake {

  public int x;
  public int y;

  enum sDir {
    Up, Left, Down, Right
  }
  public void move(int a, int b) {

    x=a;
    y=b;
  }
  public void reset(int a, int b) {

    x=a;
    y=b;
  }
};

void sSetup(Snake[] s) {
  
  s[0].x=width/2;
  s[0].y=height/2;
  for (int a=1; a<s.length; a++) {
    s[a].x=s[a-1].x-10;
    s[a].y=s[a-1].y;
  }
}

void sMove() {

  switch(key) {

  case 'w':
    dir=Snake.sDir.Up;
    break;
  case 'a':
    dir=Snake.sDir.Left;
    break;
  case 's':
    dir=Snake.sDir.Down;
    break;
  case 'd':
    dir=Snake.sDir.Right;
    break;
  }
}

void setup() {

  nPiece=new Snake[dimStart];
  sSetup(nPiece);
  size(1080, 720);
}

void draw() {

  background(0);
  for (int a=0; a<nPiece.length; a++) {
    rect(nPiece[a].x, nPiece[a].y, 10, 10);
  }
}

PS if it can help in helping me finding the issue (sorry for the bad words game :stuck_out_tongue:), it underlines the line s[0].x=width/2; when it gives me the error as output, so I think the problem could be in that function…

1 Like

OK I have changed the setup() method to

void setup() {
  size(1080, 720);
  nPiece=new Snake[dimStart];
  for(int i = 0; i < nPiece.length; i++){
    nPiece[i] = new Snake();
  }
  sSetup(nPiece);
}

the call to size() must be the first statement in setup so it can initialise the sketch and set important variables such as width and height which you use later to setup the snake pieces.

The statement
nPiece=new Snake[dimStart];
reserves memory to store a number of Snake objects but it does not create them. In my code these are created in the loop that follows. :smile:

1 Like

I think you’ve initialised your array incorrectly.

check this video if you want to confirm how to initialize an array. Timestamp is 3:48.

static int dimStart=3;
int dim=dimStart;
Snake.sDir dir;
Snake[] nPiece = new Snake[dim];

static class Snake {

  public int x;
  public int y;

  enum sDir {
    Up, Left, Down, Right
  }
  public void move(int a, int b) {

    x=a;
    y=b;
  }
  public void reset(int a, int b) {

    x=a;
    y=b;
  }
};

void sSetup(Snake[] s) {
  
  s[0].x=width/2;
  s[0].y=height/2;
  for (int a=1; a<s.length; a++) {
    s[a].x=s[a-1].x-10;
    s[a].y=s[a-1].y;
  }
}

void sMove() {

  switch(key) {

  case 'w':
    dir=Snake.sDir.Up;
    break;
  case 'a':
    dir=Snake.sDir.Left;
    break;
  case 's':
    dir=Snake.sDir.Down;
    break;
  case 'd':
    dir=Snake.sDir.Right;
    break;
  }
}

void setup() {

  for(int i=0;i<nPiece.length;i++){
  
  nPiece[i] = new Snake();
  }
    sSetup(nPiece);
  size(1080, 720);
}

void draw() {

  background(0);
  for (int a=0; a<nPiece.length; a++) {
    rect(nPiece[a].x, nPiece[a].y, 10, 10);
  }
}
1 Like

@paulgoux although you have solved the NPE error message you must place the call to size() as the first statement inside the setup() method

The code worked fine with size at the bottom though…

No it doesn’t because the initialisation of the snake pieces use the width and the height variables and these are ONLY set once the size() statement has been executed. Also the reference for size makes it quite clear that it should be the first line in setup

So why does it still run and place the snakes starting position at w/2 h/2?

I tried this code

 void setup(){
  println(width, height);
  size(400,300);
  println(width, height);
}  

and it produced the following

400 300
400 300

so your code would work. Interesting because in earlier versions of Processing this was not the case. I tried it in Processing 2.2.1 and got the result

100 100
400 300

So your code will not work correctly in all versions of Processing. It might seem a small thing but it is important to follow the Processing reference if you want code to behave consistenetly.

1 Like

true,

Defines the dimension of the display window width and height in units of pixels. In a program that has the setup() function, the size() function must be the first line of code inside setup(), and the setup() function must appear in the code tab with the same name as your sketch folder.

reference from processing.org
https://processing.org/reference/size_.html

I’m currently using processing beta, this might be something that they are looking to change in the future.

Hello,

For Processing 3.5.3 this is what is generated (removed class and other code) and run and can be found in the %temp% folder:

public void setup() {

  for(int i=0;i<nPiece.length;i++){
  
  nPiece[i] = new Snake();
  }
    sSetup(nPiece);
  
}

public void draw() {

  background(0);
  for (int a=0; a<nPiece.length; a++) {
    rect(nPiece[a].x, nPiece[a].y, 10, 10);
  }
}
  public void settings() {  size(1080, 720); }
	
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "sketch_191013b" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

https://processing.org/reference/size_.html

  • In a program that has the setup() function, the size() function must be the first line of code inside setup() , and the setup() function must appear in the code tab with the same name as your sketch folder.

https://processing.org/reference/settings_.html
The settings() method runs before the sketch has been set up, so other Processing functions cannot be used at that point.

https://processing.org/reference/setup_.html

  • If the sketch is a different dimension than the default, the size() function or fullScreen() function must be the first line in setup() .

P5JS reference:
http://processingjs.org/reference/size_/

  • The size() function must be the first line in setup() . If size() is not called, the default size of the window is 100x100 pixels. The system variables width and height are set by the parameters passed to the size() function.

  • Again, the size() method must be the first line of the code (or first item inside setup). Any code that appears before the size() command may run more than once, which can lead to confusing results.

There may be more references.
I posted these for the benefit of the community reading this post.

It does work in Processing 3.5.3 in this example since size() ends up in settings() which is run before the sketch has been set up.

:slight_smile:

2 Likes

The word “must” MUST be banished from all Processing’s reference and tutorials! :stuck_out_tongue:

2 Likes

Should vs Must:

https://tools.ietf.org/html/rfc2119

:slight_smile:

1 Like

OK, I could not work to my project until now. I actually tried out this one and it came out you’re right, I added that for cycle and it worked… really thank you! I never worked with arrays of objects, so I needed work, and now that I know how to declare them I can go on working!

Also, thanks also for your explanation of why it didn’t work, pretty clear… now I know why it didn’t work and I think that’s the most important thing! Thanks another time!

2 Likes