Processing beginner unable to fix NPE

Hi everyone,

As a preface, I’m a complete beginner to all forms of programming before my university unit I’m currently working taking part in.

I’m working on a game design for a university project, but my progress is currently halted as I cannot for the life of me figure out how to fix a NullPointerException issue in my code. I can’t test if the array i’ve established works as I want, and then do the other following steps in the creation of the game, until I can overcome this. Therefore, if anyone could tell me what adjustments I need to make to my code to fix up this issue, it would be very much appreciated!

I tried to attach my code from processing but it doesn’t allow that, so sorry but this is a copy-paste of the code:

int x;
float y;
//int type;
float angle = 0.0; 
float offset = 350; 
float scalar = 15; 
int yPos = 0;
float speed = -1; 
float direction = 1;

class Floor // Defining the class of objects that make up the landscape
{
  int xpos;
  int ypos;
  int yspeed;
  int yaccel;
  int size;
  int type;

  Floor (int tempxpos, int tempypos, int tempyspeed, int tempyaccel, int temptype) // Defining the construct function for this class
  {
    xpos = tempxpos;
    ypos = tempypos;
    yspeed = tempyspeed;
    yaccel = tempyaccel;
    type = temptype;
  }

  /*  Floor (int y) // Defining the construct function for this class
   {
   y = height;
   } */
   
   Floor[] Floortype = new Floor[7]; // Declaring an array of 7 objects (of class 'Floor')
   
  void display ()
  {
    if (type == 0) {
      fill (245, 181, 62);
      rect(0, yPos, 300, 20);
      rect (450, yPos, 800, 20);
      yPos += speed * direction;
    }
    if (type == 1) {
      fill (245, 181, 62);
      rect(150, yPos, 450, 20);
      yPos += speed * direction;
    }
    if (type == 2) {
      fill (245, 181, 62);
      rect(300, yPos, 400, 20);
      rect(0, yPos, 150, 20);
      yPos += speed * direction;
    }
    if (type == 3) {
      fill (245, 181, 62);
      rect(200, yPos, 600, 20);
      yPos += speed * direction;
    }
    if (type == 4) {
      fill (245, 181, 62);
      rect(0, yPos, 500, 20);
      rect(650, yPos, 150, 20);
      yPos += speed * direction;
    }
    if (type == 5) {
      fill (245, 181, 62);
      rect(0, yPos, 200, 20);
      rect (325, yPos, 125, 20);
      rect (600, yPos, 200, 20);
      yPos += speed * direction;
    }
    if (type == 6) {
      fill (245, 181, 62);
      rect(0, yPos, 600, 20);
      yPos += speed * direction;
    }
  }

  void ascend ()
  {
    {
      yPos = 800 - yspeed;
      if (tick % (750-yaccel) == 0)
      {
        yspeed = yspeed + 1;
      }
      {
        for (int i = 0; i < Floortype.length; i++)
      if (yPos <= height - 150)
      {
        //    xpos = floor(random(width));
    //  Floortype[i] = new Floor();
       // ypos = floor(random(-500, -150));
      }
    }
    }
  }
  void hitcheck ()
  {
    float xdif = (mouseX);
    float ydif = (y - yPos);
    if ((xdif + ydif) == 0) 
    {
      health = health - 10;
    }
    if (y == 0) {
      health = 0;
    }
    if (health <= 0)
    {
      readiness = "finished";
    }
  }

  void reset ()
  {
    xpos = floor(random(width));
    ypos = floor(random((-height-100), -100));
    yspeed = floor(random(3, 10));
  }
}

void Clancey(int x, float y) // Creating a function to describe the character 'Clancey'
{
  {
    fill(255);
    beginShape();
    vertex(x+20, y+20);
    vertex(x-10, y+20);
    bezierVertex(x-31, y+19, x-27, y+5, x-18, y+3);
    bezierVertex(x-18, y-5, x-11, y-8, x-6, y-6);
    bezierVertex(x-6, y-6, x+5, y-20, x+12, y-6);
    bezierVertex(x+12, y-5, x+21, y-7, x+22, y+3);
    bezierVertex(x+28, y+5, x+40, y+20, x+20, y+20);
    endShape();
  }
  {
    fill(0);
    beginShape();
    vertex(x-4, y+2);
    bezierVertex(x-4, y+2, x-3, y-2, x-2, y+2);
    vertex(x-2, y+2);
    bezierVertex(x-2, y+2, x-3, y, x-4, y+2);
    endShape();

    beginShape();
    vertex(x+7, y+2);
    bezierVertex(x+7, y+2, x+8, y-2, x+9, y+2);
    vertex(x+9, y+2);
    bezierVertex(x+9, y+2, x+8, y, x+7, y+2);
    endShape();
  }
  {
    fill(0);
    beginShape();
    vertex(x-7, y+7);
    vertex(x+11, y+7);
    bezierVertex(x+11, y+7, x+2, y+22, x-7, y+7);
    endShape();

    fill(240, 31, 7);
    beginShape();
    vertex(x-3, y+11);
    bezierVertex(x-3, y+11, x+2, y+16, x+7, y+11);
    vertex(x-3, y+11);
    endShape();
  }
}

Floor[] Floortype = new Floor[7]; // Declaring an array of 7 objects (of class 'Floor')

void setup()
{
  size(1000, 800);
}

int tick = 0; // Time/score variable
int health = 0;
String readiness = "ready"; // The readiness variable determines which specific part of the 'void draw()' function gets excecuted
String title1 = "CLOUD NINE";
String title2 = "Help Clancey get back home!\nClick to start";
String intromessage1 = "Having been blown into the upper atmosphere,\nClancey the Cloud needs to make his way back down";
String intromessage2 = "Move the mouse to move Clancey sideways\n and help him find gaps he can fall through.\nIf he's too slow, he will be stuck forever!";
String intromessage3 = "Start by pressing SHIFT\nand help Clancey!";

void draw() // There are 4 different modes depending on the part of the game being played
{
  if (readiness == "open") // Mode 0: Title screen
  {    
    x = 480;
    float speed = 0.03;
    float y = offset + sin(angle) * scalar;
    angle+=speed;
    {
      background(129, 209, 245);
      fill(255);
      strokeWeight(1.5);
      beginShape();
      vertex(x+200, y+200);
      vertex(x-100, y+200);
      bezierVertex(x-310, y+190, x-270, y+50, x-180, y+30);
      bezierVertex(x-180, y-50, x-110, y-80, x-60, y-60);
      bezierVertex(x-60, y-60, x+50, y-200, x+120, y-60);
      bezierVertex(x+120, y-50, x+210, y-70, x+220, y+30);
      bezierVertex(x+280, y+50, x+400, y+200, x+200, y+200);
      endShape();
    }
    {
      fill(0);
      beginShape();
      vertex(x-40, y+20);
      bezierVertex(x-40, y+20, x-30, y-20, x-20, y+20);
      vertex(x-20, y+20);
      bezierVertex(x-20, y+20, x-30, y, x-40, y+20);
      endShape();

      beginShape();
      vertex(x+70, y+20);
      bezierVertex(x+70, y+20, x+80, y-20, x+90, y+20);
      vertex(x+90, y+20);
      bezierVertex(x+90, y+20, x+80, y, x+70, y+20);
      endShape();
    }
    {
      fill(0);
      beginShape();
      vertex(x-70, y+70);
      vertex(x+110, y+70);
      bezierVertex(x+110, y+70, x+20, y+220, x-70, y+70);
      endShape();

      fill(240, 31, 7);
      beginShape();
      vertex(x-30, y+110);
      bezierVertex(x-30, y+110, x+20, y+160, x+70, y+110);
      vertex(x-30, y+110);
      endShape();
    }
    fill(255);
    textSize(80);
    textAlign(CENTER, CENTER);
    text(title1, width/2, height/8);
    textSize(50);
    text(title2, width/2, 5*height/6);
  } else if (readiness == "notready") // Mode 1: Instructions screen
  {
    background(129, 209, 245);
    strokeWeight(1);
    Clancey(370, 460);

    fill(255);
    textSize(35);
    textAlign(CENTER, CENTER);
    text(intromessage1, width/2, height/8);
    text(intromessage2, width/2, 3*height/8);
    textSize(50);
    text(intromessage3, width/2, 13*height/16);

    fill (245, 181, 62);
    rect(0, 500, 300, 20); //Left floor
    rect (450, 500, 800, 20); //Right floor

    fill(0); //Arrow
    rect(365, 485, 15, 20);
    triangle(355, 500, 390, 500, 372.5, 520);
  } else if (readiness == "ready") // Mode 2: Playing the game
  { clear();
    println("The game should be playing now");
    for (int i = 0; i < Floortype.length; i = i ++)
    {
      Floortype[i].display(); // Responsible for drawing the object every time the void draw() function runs
      Floortype[i].ascend(); // Function applied to an individual object, responsible for movement and resetting of position when it reaches the bottom of the screen
      Floortype[i].hitcheck(); // Responsible for checking if the cursor collides with any of the objects
    } 

    noCursor();
    strokeWeight (1);
    Clancey(mouseX, y);

    fill(0, 82, 118);
    strokeWeight(0);
    rect(800, 0, 200, height); // Dashboard

    fill(255);
    textSize(25);
    textAlign(CENTER, TOP);
    text( "Score: " + tick, 900, 35); // Score counter
  } else if (readiness == "finished") // Mode 3: After the player loses
  {
    cursor(ARROW);
    fill(255);
    textSize(40);
    textAlign(CENTER, CENTER);
    String endmessage = "You achieved a score of " + tick + ".\nBut Clancey couldn't make it home.\nClick or press R to retry at this difficulty level.\nPress Q to exit.";
    text(endmessage, width/2, height/2);
  }
}

void keyPressed()
{
  if (keyCode == 16 && readiness == "notready") //Mode 1
    readiness = "ready"; // Starts the game
  println("this is working");
  {
    for (int i = 0; i < Floortype.length; i = i++)
    {
      Floortype[i] = new Floor(floor(random(width)), floor(random(1350, 900)), floor(random(3, 10)), floor(random(70, 200)), floor(random(10))); // Initialisation of the floor array
    }
  }
  /* { 
   if (keyCode == 16) {
   readiness = "ready";
   println("this is working too");
   }
   } */

  if (readiness == "finished") // Mode 3
  {
    for (int i = 0; i < 7; i = i++)
    {
      Floortype[i].reset(); // Randomises the positions and speeds of the objects again
    }
    tick = 0;
    health = 1;
    readiness = "ready";
  }
  if (keyCode == 82 && readiness == "finished") // Mode 3
  {
    readiness = "ready";
  }
  if (keyCode == 81 && readiness == "finished") // Mode 3
  {
    exit();
  }
}
void mousePressed()
{
  if (readiness == "open") // Mode 0
  {
    readiness = "notready"; // Mode 1
  }  
  if (readiness == "ready") // Mode 2
  {
    for (int i = 0; i < Floortype.length; i = i++)
    {
      Floortype[i].reset(); // Randomises the positions and speeds of the objects again. Note: The 'difficulty' variable stays the same
    }
    tick = 0;
    health = 1;
    readiness = "ready";
  }
}
1 Like

You got this line twice, in the class and outside of it. Bad.
Remove the occurence inside the class

In setup you should have a for loop to setup each element of floor array with … [i]

Since the class represents only ONE floor, remember never to use the array inside the class or for loop over it

1 Like

Thanks for the reply - I’ve removed the duplicate line, thanks for pointing it out. How would you recommend I structure the for loops for each element of the floor loop? Like I did when establishing the different types in display, or otherwise?

some basic stuff:

your order of code should:

  • ALL global vars and objects

  • setup and draw

  • Input functions

  • all other functions

  • all classes

then use ctrl-t before posting and general often

After copy and paste in the forum: select the entire code section with the mouse and hit ctrl-shift-C

Remark:

Shouldn’t this be in setup() :

 // Initialisation of the floor array
  for (int i = 0; i < Floortype.length; i = i++)
  {
    Floortype[i] = new Floor(floor(random(width)), floor(random(1350, 900)), floor(random(3, 10)), floor(random(70, 200)), floor(random(10)));
  }

No. Either

i++; 

OR

i = i +1;

this occurs very often

Questions

What does one Floortype represent?

All items in the current floor? Or does list Floortype[] represent different floors? Then we should only display one at a time?

Is a floor a scene?

Oh

if (readiness == "open")

won’t work!

you need if (readiness.equals("open"))

again in every code section where you use a String with == , it’s wrong.

For String use always .equals("open")


OR use switch instead of if…else if…

// The readiness variable determines which specific part of the ‘draw()’ function gets excecuted
String readiness = "ready"; 

size(222, 222);

switch (readiness) {
case "open":
  println("is open");
  break; 

case "ready":
  println("is ready");
  break; 

default:
  println("is ERROR");
  break; 
  //
}//switch

My intention is for the list Floortype[] to represent 7 different floors, and for there to be an array of the 7 different floor designs I made (types 0-6) that randomly generates a floor whenever yPos reduces by 150 indefinitely (until the player loses the game). I want to then be able to apply hitcheck() to prevent the character, Clancey, from being able to overlap with / pass through the floors, such that the floors make up the landscape of the game. Am I approaching this in the right way?

No, definitely not.

the list Floortype[] to represent 7 different floors

You want to display 7 different floors / scenes.

Then you should not use a for loop to show the floors. Instead make a variable int currentFloor = 0; that shows you which floor you show. This is the variable you must control.

Instead of using a for loop you display only the current floor :

Floortype[currentFloor ].display(); // Responsible for drawing the object every time the void draw() function runs
Floortype[currentFloor ].ascend(); // Function applied to an individual object, responsible for movement and resetting of

Chrisir

Sketch:


// use equals instead of == with strings

int x;
float y;

//int type;
float angle = 0.0;
float offset = 350;
float scalar = 15;
int yPos = 0;
float speed = -1;
float direction = 1;



Floor[] Floortype = new Floor[7]; // Declaring an array of 7 objects (of class ‘Floor’)

int currentFloor = 0; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

int health = 0;
String readiness = "ready"; // The readiness variable determines which specific part of the ‘draw()’ function gets excecuted

String title1 = "CLOUD NINE";
String title2 = "Help Clancey get back home!\nClick to start";

String intromessage1 = "Having been blown into the upper atmosphere,\nClancey the Cloud needs to make his way back down";
String intromessage2 = "Move the mouse to move Clancey sideways\n and help him find gaps he can fall through.\nIf he’s too slow, he will be stuck forever!";
String intromessage3 = "Start by pressing SHIFT\nand help Clancey!";

int tick = 0; // Time/score variable

// -------------------------------------------------------------------------------------------------

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

  // Initialisation of the floor array
  for (int i = 0; i < Floortype.length; i++)
  {
    Floortype[i] = new Floor(floor(random(width)), floor(random(1350, 900)), floor(random(3, 10)), floor(random(70, 200)), floor(random(10)));
  }
}

void draw() // There are 4 different modes depending on the part of the game being played
{
  if (readiness.equals( "open")) // Mode 0: Title screen
  {
    x = 480;
    float speed = 0.03;
    float y = offset + sin(angle) * scalar;
    angle+=speed;
    {
      background(129, 209, 245);
      fill(255);
      strokeWeight(1.5);
      beginShape();
      vertex(x+200, y+200);
      vertex(x-100, y+200);
      bezierVertex(x-310, y+190, x-270, y+50, x-180, y+30);
      bezierVertex(x-180, y-50, x-110, y-80, x-60, y-60);
      bezierVertex(x-60, y-60, x+50, y-200, x+120, y-60);
      bezierVertex(x+120, y-50, x+210, y-70, x+220, y+30);
      bezierVertex(x+280, y+50, x+400, y+200, x+200, y+200);
      endShape();
    }
    {
      fill(0);
      beginShape();
      vertex(x-40, y+20);
      bezierVertex(x-40, y+20, x-30, y-20, x-20, y+20);
      vertex(x-20, y+20);
      bezierVertex(x-20, y+20, x-30, y, x-40, y+20);
      endShape();

      beginShape();
      vertex(x+70, y+20);
      bezierVertex(x+70, y+20, x+80, y-20, x+90, y+20);
      vertex(x+90, y+20);
      bezierVertex(x+90, y+20, x+80, y, x+70, y+20);
      endShape();
    }
    {
      fill(0);
      beginShape();
      vertex(x-70, y+70);
      vertex(x+110, y+70);
      bezierVertex(x+110, y+70, x+20, y+220, x-70, y+70);
      endShape();

      fill(240, 31, 7);
      beginShape();
      vertex(x-30, y+110);
      bezierVertex(x-30, y+110, x+20, y+160, x+70, y+110);
      vertex(x-30, y+110);
      endShape();
    }
    fill(255);
    textSize(80);
    textAlign(CENTER, CENTER);
    text(title1, width/2, height/8);
    textSize(50);
    text(title2, width/2, 5*height/6);
  } else if (readiness .equals(  "notready")) // Mode 1: Instructions screen
  {
    background(129, 209, 245);
    strokeWeight(1);
    Clancey(370, 460);

    fill(255);
    textSize(35);
    textAlign(CENTER, CENTER);
    text(intromessage1, width/2, height/8);
    text(intromessage2, width/2, 3*height/8);
    textSize(50);
    text(intromessage3, width/2, 13*height/16);

    fill (245, 181, 62);
    rect(0, 500, 300, 20); //Left floor
    rect (450, 500, 800, 20); //Right floor

    fill(0); //Arrow
    rect(365, 485, 15, 20);
    triangle(355, 500, 390, 500, 372.5, 520);
  } else if (readiness .equals(  "ready")) // Mode 2: Playing the game
  { 
    clear();
    println("The game should be playing now");
    //for (int i = 0; i < Floortype.length; i++)
    {
      Floortype[currentFloor ].display(); // Responsible for drawing the object every time the void draw() function runs
      Floortype[currentFloor ].ascend(); // Function applied to an individual object, responsible for movement and resetting of position when it reaches the bottom of the screen
      Floortype[currentFloor ].hitcheck(); // Responsible for checking if the cursor collides with any of the objects
    }

    noCursor();
    strokeWeight (1);
    Clancey(mouseX, y);

    fill(0, 82, 118);
    strokeWeight(0);
    rect(800, 0, 200, height); // Dashboard

    fill(255);
    textSize(25);
    textAlign(CENTER, TOP);
    text( "Score: " + tick, 900, 35); // Score counter
  } else if (readiness .equals(  "finished")) // Mode 3: After the player loses
  {
    cursor(ARROW);
    fill(255);
    textSize(40);
    textAlign(CENTER, CENTER);
    String endmessage = "You achieved a score of "
      + tick 
      + ".\nBut Clancey couldn’t make it home.\nClick or press R to retry at this difficulty level.\nPress Q to exit.";
    text(endmessage, width/2, height/2);
  }
}

void keyPressed()
{
  if (keyCode == 16 && readiness .equals( "notready")) //Mode 1
    readiness = "ready"; // Starts the game

  println("this is working");

  {
    for (int i = 0; i < Floortype.length; i++)
    {
      Floortype[i] = new Floor(floor(random(width)), floor(random(1350, 900)), floor(random(3, 10)), floor(random(70, 200)), floor(random(10))); // Initialisation of the floor array
    }
  }
  /* {
   if (keyCode == 16) {
   readiness = “ready”;
   println(“this is working too”);
   }
   } */

  if (readiness .equals( "finished")) // Mode 3
  {
    for (int i = 0; i < 7; i++)
    {
      Floortype[i].reset(); // Randomises the positions and speeds of the objects again
    }
    tick = 0;
    health = 1;
    readiness = "ready";
  }
  if (keyCode == 82 && readiness .equals( "finished")) // Mode 3
  {
    readiness = "ready";
  }
  if (keyCode == 81 && readiness .equals( "finished")) // Mode 3
  {
    exit();
  }
}

void mousePressed()
{
  //use equals instead of == with strings
  if (readiness .equals("open")) // Mode 0
  {
    readiness = "notready"; // Mode 1
  }
  if (readiness .equals( "ready")) // Mode 2
  {
    for (int i = 0; i < Floortype.length; i++)
    {
      Floortype[i].reset(); // Randomises the positions and speeds of the objects again. Note: The ‘difficulty’ variable stays the same
    }
    tick = 0;
    health = 1;
    readiness = "ready";
  }
}

// ---------------------------------------------------------------------------------------------

void Clancey(int x, float y) // Creating a function to describe the character ‘Clancey’
{

  {
    fill(255);
    beginShape();
    vertex(x+20, y+20);
    vertex(x-10, y+20);
    bezierVertex(x-31, y+19, x-27, y+5, x-18, y+3);
    bezierVertex(x-18, y-5, x-11, y-8, x-6, y-6);
    bezierVertex(x-6, y-6, x+5, y-20, x+12, y-6);
    bezierVertex(x+12, y-5, x+21, y-7, x+22, y+3);
    bezierVertex(x+28, y+5, x+40, y+20, x+20, y+20);
    endShape();
  }
  {
    fill(0);
    beginShape();
    vertex(x-4, y+2);
    bezierVertex(x-4, y+2, x-3, y-2, x-2, y+2);
    vertex(x-2, y+2);
    bezierVertex(x-2, y+2, x-3, y, x-4, y+2);
    endShape();

    beginShape();
    vertex(x+7, y+2);
    bezierVertex(x+7, y+2, x+8, y-2, x+9, y+2);
    vertex(x+9, y+2);
    bezierVertex(x+9, y+2, x+8, y, x+7, y+2);
    endShape();
  }
  {
    fill(0);
    beginShape();
    vertex(x-7, y+7);
    vertex(x+11, y+7);
    bezierVertex(x+11, y+7, x+2, y+22, x-7, y+7);
    endShape();

    fill(240, 31, 7);
    beginShape();
    vertex(x-3, y+11);
    bezierVertex(x-3, y+11, x+2, y+16, x+7, y+11);
    vertex(x-3, y+11);
    endShape();
  }
}

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

class Floor // Defining the class of objects that make up the landscape
{
  int xpos;
  int ypos;
  int yspeed;
  int yaccel;
  int size;
  int type;

  Floor (int tempxpos, int tempypos, int tempyspeed, int tempyaccel, int temptype) // Defining the construct function for this class
  {
    xpos = tempxpos;
    ypos = tempypos;
    yspeed = tempyspeed;
    yaccel = tempyaccel;
    type = temptype;
  }

  /* Floor (int y) // Defining the construct function for this class
   {
   y = height;
   } */

  void display ()
  {
    if (type == 0) {
      fill (245, 181, 62);
      rect(0, yPos, 300, 20);
      rect (450, yPos, 800, 20);
      yPos += speed * direction;
    }
    if (type == 1) {
      fill (245, 181, 62);
      rect(150, yPos, 450, 20);
      yPos += speed * direction;
    }
    if (type == 2) {
      fill (245, 181, 62);
      rect(300, yPos, 400, 20);
      rect(0, yPos, 150, 20);
      yPos += speed * direction;
    }
    if (type == 3) {
      fill (245, 181, 62);
      rect(200, yPos, 600, 20);
      yPos += speed * direction;
    }
    if (type == 4) {
      fill (245, 181, 62);
      rect(0, yPos, 500, 20);
      rect(650, yPos, 150, 20);
      yPos += speed * direction;
    }
    if (type == 5) {
      fill (245, 181, 62);
      rect(0, yPos, 200, 20);
      rect (325, yPos, 125, 20);
      rect (600, yPos, 200, 20);
      yPos += speed * direction;
    }
    if (type == 6) {
      fill (245, 181, 62);
      rect(0, yPos, 600, 20);
      yPos += speed * direction;
    }
  }

  void ascend ()
  {
    {
      yPos = 800 - yspeed;
      if (tick % (750-yaccel) == 0)
      {
        yspeed = yspeed + 1;
      }
      {
        for (int i = 0; i < Floortype.length; i++)
          if (yPos <= height - 150)
          {
            // xpos = floor(random(width));
            // Floortype[i] = new Floor();
            // ypos = floor(random(-500, -150));
          }
      }
    }
  }

  void hitcheck ()
  {
    float xdif = (mouseX);
    float ydif = (y - yPos);
    if ((xdif + ydif) == 0)
    {
      health = health - 10;
    }
    if (y == 0) {
      health = 0;
    }
    if (health <= 0)
    {
      readiness = "finished";
    }
  }

  void reset ()
  {
    xpos = floor(random(width));
    ypos = floor(random((-height-100), -100));
    yspeed = floor(random(3, 10));
  }
  //
}//class 

//