Need help with classes and passing variables!

Hello all!

I’m making a game where the player moves a character left and right and it touches candies. I have three classes - game, candy and player. In the player class - touchCandy() method, it says that some of the variables do not exist - even though I’ve declared them and made them public in the candy class. I think I’m missing something (passing the variables in maybe?) and need help to figure out how to fix it.

Here’s the relevant code:

Game class:

//main class - used to play the game - calls objects?
//setup menu

//define variables
PFont title, main, dead;
PImage heart, bkgrd;
PrintWriter highScore;

String current = "menu"; //what they'll see when game is first loaded
int menuBut1x, menuBut1y;
int menuBut2x, menuBut2y;
int menuBut3x, menuBut3y;
int backButx, backButy;
int points;

//creating objects (to reference when calling methods)
Player pandaObj = new Player();
Candy candyObj = new Candy();

//functions
void setup() {
  size(1200,700);
  frameRate(30);
  title = loadFont("Gabriola-150.vlw");
  textFont(title);
  main = loadFont("SegoeUI-Light-60.vlw");
  textFont(main);
  dead = loadFont("Stencil-200.vlw");
  textFont(dead);
  
  points = 0;
  
  highScore = createWriter("HighScore.txt");
   
  menuBut1x = width/3-70;
  menuBut1y = height/2-100;
  menuBut2x = width/3-70;
  menuBut2y = height/2+40;
  menuBut3x = width/3-70;
  menuBut3y = height/2+180;
  backButx = 1030;
  backButy = 10;
  
  
  //panda.loadImages();
}
void loadImages(){
  heart = loadImage("heart.png");
  bkgrd = loadImage("floatClouds.jpg");
}

  void draw(){
   //call other methods 
   //ex. if __ then panda.method
   
  background(#bfefff);
  fill(255);
  rect(menuBut1x, menuBut1y, 520, 100); //first button
  rect(menuBut2x, menuBut2y, 520, 100); //second button
  rect(menuBut3x, menuBut3y, 520, 100); //third button
  textSize(100);
  fill(#000000);
  textFont(title);
  text("Candy Dash!", 300, 180);
  textSize(200);
  fill(#000000);
  textFont(main);
  text("PLAY", 530, 320);
  textSize(65);
  fill(#000000);
  textFont(main);
  text("INSTRUCTIONS", 400, 465);
  textSize(65);
  fill(#000000);
  textFont(main);
  text("HIGH SCORES", 415, 600);
  
  if (current=="menu") {
    //background(#F0D5E2); DON'T HAVE BACKGROUND COLOUR HERE OR WILL COVER EVERYTHING - BKGRD TOP OF VOID DRAW
    if (mouseX >= menuBut1x && mouseX <= menuBut1x+520 && mouseY >= menuBut1y && mouseY <= menuBut1y+100 && mousePressed) {
          current="play";   //clicked play button     
  }
  if (mouseX >= menuBut2x && mouseX <= menuBut2x+520 && mouseY >= menuBut2y && mouseY <= menuBut2y+100 && mousePressed) {
          current="instructions";   //clicked instructions button     
  }
  if (mouseX >= menuBut3x && mouseX <= menuBut3x+520 && mouseY >= menuBut3y && mouseY <= menuBut3y+100 && mousePressed) {
          current="high scores";   //clicked high scores button     
  }
     pandaObj.resetPosition(); //resets panda's coordinates when exiting game
  }
  
  if (current=="instructions") {
    background(#e8f0f7);
    textSize(80);
    text("INSTRUCTIONS", 360, 140);
    textSize(35);
    text("Use the arrow keys to move left and right.", 100,240);
    text("Your goal is to collect all the yummy candies, and avoid the bad foods!", 100, 300);
    text("Watch out! Touch a bad food and YOU ARE DEAD!", 100, 360);
    fill(#F0FFF0); //back button
    rect(backButx, backButy, 160, 100); //back button
    textSize(50); 
    fill(#000000);
    text("MENU", 1040, 75);
    textSize(35); 
    fill(#000000);
    text("COLLECT THESE:", 180, 450);
    candyObj.loadImgInstr(); //calling method to load candy & badFood images
    
    if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
          current="menu";   //clicked menu button     
  }
  }
  
    if (current=="high scores") {
    background(#e8f0f7);
    fill(#F0FFF0);
    rect(backButx, backButy, 160, 100); //back button
    textSize(50);
    fill(#000000);
    text("MENU", 1040, 75);
    textSize(100);
    text("HIGH SCORE: " + points, 300, height/2);
    
    if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
          current="menu";   //clicked menu button      
  }
  }
  
  if (current=="play") {
    image(bkgrd, 0, 0, 1200, 700);
    //background(#cfe1e1);
    fill(#F0FFF0);
    rect(backButx, backButy, 160, 100); //back button
    textSize(50);
    fill(#000000);
    text("MENU", 1040, 75);
    
    //call methods - from Candy class
    candyObj.loadImages();
    candyObj.candyFall();
    candyObj.badFoodFall();
    candyObj.newCandy();
    //call methods - from Player class
    pandaObj.loadImages();
    pandaObj.keyPressed();
    pandaObj.touchCandy();
    
    
    
    if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
          current="menu";   //clicked menu button  
  }
  }
  
  if (current=="gameOver") {
    background(#7B0B1F);
    textFont(dead);
    textSize(150);
    text("YOU ARE DEAD", 70, height/2);
    
    textFont(main);
    fill(#fbfbfb);
    rect(200, 500, 300, 150); //replay button
    textSize(80);
    fill(#000000);
    noStroke();
    text("REPLAY", 220, 600);
    
    fill(#fbfbfb);
    rect(700, 500, 300, 150); //menu button
    textSize(80);
    fill(#000000);
    noStroke();
    text("MENU", 745, 600);
    highScore.println("High Score: " + points); // Write the points to the file

    points=0; //reset points to 0 when dead
    pandaObj.resetPosition();
   
  if (mouseX >= 200 && mouseX <= 200+300 && mouseY >= 500 && mouseY <= 500+150 && mousePressed) {
          current="play";   //clicked replay
  }
  if (mouseX >= 700 && mouseX <= 700+300 && mouseY >= 500 && mouseY <= 500+150 && mousePressed) {
          current="menu";   //clicked menu button 
  }
}
  }

Candy class:

class Candy {
  
  //define variables
  PImage candy, lollipop, cottonCandy;
  PImage badApple, bananaPeel, pepper;
  PImage [] goodCandy = new PImage [3];
  PImage [] badFood = new PImage [3];
  public int candySpeed, foodSpeed;
  public int yDirCandy, yDirFood;
  public int candyY, candyX, candyW, candyH;
  public int randCandyW, randCandyH, badAppleX;
  public int rand, randX, randY, randX2, lolliX, lolliY;
  
  //constructor
  Candy() {
    
    candySpeed = 10;
    foodSpeed = 5;
    yDirCandy = 1;
    yDirFood = 1;
    candyY = 10;
    candyX = 200;
    candyW = 187;
    candyH = 121;
    randCandyW = 100;
    randCandyH = 100;
    badAppleX = 700;
    
    randY = -200;
    lolliY = -600;
    
    rand=(int) (2*Math.random()) +1;
    randX = (int) (1100*Math.random())+20; 
    randX2 = (int) (1100*Math.random())+20; 
    lolliX = (int) (1100*Math.random())+20;
  }
  
  //functions
  
  void loadImages(){
  candy = loadImage("goodCandy0.png");
  cottonCandy = loadImage("goodCandy1.png");
  lollipop = loadImage("goodCandy2.png");
  badApple = loadImage("badFood0.png");
  bananaPeel = loadImage("badFood1.png");
  pepper = loadImage("badFood2.png");
  
  for (int i=0; i<goodCandy.length; i++) {
  goodCandy[i] = loadImage("goodCandy" + i + ".png"); //loading goodCandy imgs via array
}
  for (int i=0; i<badFood.length; i++) {
  badFood[i] = loadImage("badFood" + i + ".png"); //loading badFood imgs via array
}
}

void loadImgInstr(){ //display candy and badfood on instructions
  image(candy, 80, 480, 120, 80);
    image(lollipop, 220, 480, 100, 170);
    image(cottonCandy, 350, 480, 100, 180);
    text("AVOID THESE:", 800, 450);
    image(badApple, 720, 480, 100, 140);
    image(bananaPeel, 830, 480, 180, 170);
    image(pepper, 1030, 470, 100, 170);
}
void candyFall() {
  
  //image(panda, pandaX, pandaY, pandaW, pandaH); //HOW TO GET VARIABLES HERE?
  fill(#000000);
  text("Points: " + points, 20, 70);
  pandaObj.touchCandy();
  candyObj.newCandy();
  
  image(candy, candyX, candyY, candyW, candyH);  //original candy
  candyY = candyY + (candySpeed * yDirCandy);
  
  image(goodCandy[rand], randX, randY, randCandyW, randCandyH); //rand candy
  randY = randY + (candySpeed * yDirCandy);
  
  image(lollipop, lolliX, lolliY, randCandyW, randCandyH); //lolli candy
  lolliY = lolliY + (candySpeed * yDirCandy);

//highScore.println("High Score: " + points); // Write the points to the file
}

void badFoodFall(){
  image(badFood[rand], randX2, randY, randCandyW, randCandyH);  //rand food
  randY = randY + (candySpeed * yDirCandy);
  
  image(badApple, badAppleX, randY, randCandyW, randCandyH);  //rand food
  randY = randY + (candySpeed * yDirFood);
}

void newCandy() {
  if (candyY>=850) {
    candyY=0;  //resetting the original candy to top
  }
  if (lolliY>=850) {
    lolliY=0; //resetting lolli to top
  }
  if (randY>=850) {
    randY=0;
  }
}

}

Player class:

class Player {

  //define variables
  public PImage panda;
  public int pandaX;
  int pandaY;
  int pandaW;
  int pandaH;
  
  //constructor
  Player () {
    pandaX = 550;
    pandaY = 580;
    pandaW = 80;
    pandaH = 112;
    
  }
  
  //functions
  void loadImages(){
    panda = loadImage("panda.png");
  }
  void resetPosition() { //resets panda's position when going out of game back to menu or dead
  pandaX = 550; //resets the panda to starting position 
  pandaY = 580; //RESET EVERYTHING WHEN EXIT
  points = 0;
  }
  
    void keyPressed() { 
  if (key==CODED) {
    if (keyCode==LEFT) {
      pandaX = pandaX-20; 
    }
    if (keyCode==RIGHT) {
      pandaX = pandaX+20;
    }
   if (pandaX<=5) {
     pandaX=5; //if hit into wall panda won't go off screen
   }
   if (pandaX>=1120) {
     pandaX=1120;
   }
   //highScore.flush(); // Writes the remaining data to the file
   //highScore.close(); // Finishes the file
  }
    }
  
  **void touchCandy()** {
  if (  (pandaX + pandaW > candyX && //original candy //HOW TO GET VARIABLES HERE?
        pandaX < candyX + candyW &&
        pandaY + pandaH > candyY &&
        pandaY < candyY + candyH) ||
        (pandaX + pandaW > randX && //rand candy
        pandaX < randX + randCandyW &&
        pandaY + pandaH > randY &&
        pandaY < randY + randCandyH) ||
        (pandaX + pandaW > lolliX && //lollipop
        pandaX < lolliX + randCandyW &&
        pandaY + pandaH > lolliY &&
        pandaY < lolliY + randCandyH)
        )
        {
          textSize(60);
          text("YUM! You get points!", 370, 300);
          points = points + 1; //if panda touches candy, get points!
          image(heart, pandaX+20, pandaY-50, 50, 50);
        }
  if ((pandaX + pandaW > randX2 && //rand food
        pandaX < randX2 + randCandyW &&
        pandaY + pandaH > randY &&
        pandaY < randY + randCandyH) ||
        (pandaX + pandaW > badAppleX && //apple
        pandaX < badAppleX + randCandyW &&
        pandaY + pandaH > randY &&
        pandaY < randY + randCandyH))
        {
          current="gameOver";
        }
          
}
  
}

Where it says void touchCandy() in the Player class is where I’m having problems.

This feeling that you have is a good pointer. I didn’t look at your code but I put a quick example as a reference and hopefully you can apply it to your code. I kept it minimal for this demo. I am accessing the info of a Candy object from the player object. Check it out below.

One more thing. Adding public to a member variable in your classes doesn’t mean that other classes can see it. You can check few tutorials about OOP and check also definitions of access modifiers. I pick this one from my search (probly not the best) as it has the basic info that you might find useful:https://www.javatpoint.com/access-modifiers. For OOP, check this Objects / Processing.org


//===========================================================================
// GLOBAL VARIABLES:

Player p1;
Candy c1;

//===========================================================================
// PROCESSING DEFAULT FUNCTIONS:

void setup() {
  size(400, 600);
  textAlign(CENTER, CENTER);
  rectMode(CENTER);

  fill(255);
  strokeWeight(2);

  p1=new Player();
  c1=new Candy();
  
  noLoop();
}



void draw() {
  background(0);
  p1.self_report();
  p1.candy_report(c1);
}



//===========================================================================
// OTHER FUNCTIONS:


class Player {

  String name;

  //constructor
  Player() {
    name="I am a Player with an internal reference " + this;
  }

  void self_report() {
    println(name);
  }

  void candy_report(Candy aCandy) {
    println(aCandy.name);
  }
}


class Candy {

  String name;

  //constructor
  Candy() {
    name="I am a Candy with an internal reference " + this;
  }
}

Your Player class doesn’t have an object of Candy to work with.

How about making the Player constructor take a Candy as a parameter. When you instantiate your Candy, pass that along to your Player when creating the Player object.

class Player{
    Player(Candy c){
        c.candyfield
    }
}

class Candy{
    //candy stuff
}

candyObj = new Candy();
playerObj = new Player(candyObj);

Which field am I supposed to reference here?

I did this

Player pandaObj = new Player(candyObj);
But I get an error saying “cannot reference a field before it is defined.”

that was just to refer to whatever references you want to make to your Candy object once your Player object has a way to get to it.

In your main code, where you are creating your Player and Candy classes, first create a Candy object, then pass that object to your Player constructor, that way it has access to the memory holding your Candy object.

class Candy{
    String name;
    Candy(){
        name = "Candylicious";
    }
}

class Player{
    Player(Candy c){
        println(c.name);
    }
}

Candy candy;
Player player;
void setup() {
   size(400, 400);
   candy = new Candy();
   player = new Player(candy);
}

See how the Player now has access to the name field of the Candy object?

So in your case, in your player class, if your constructor was written as Player(Candy candyObj) then in your code where your reference things like candyX inside your Player class you would instead use candyObj.candyX

edit

I have just skimmed through your code. Admittedly, I didn’t take much of a look before because I could see right away that you had no Candy object reference for your Player class to work with and made the suggestions I did based on that. And now I can see a problem with what I have suggested, it doesn’t fit well here because your Player object will need to interact with many Candy objects so you can’t pass them along like that. I would probably create another class that takes care of interactions between the Player and the Candy objects, a Controller class, that way you can create Candy objects as you need them and store them in a list which your Controller class can iterate through and process the required logic.

Or. You could just pass candy objects to your touchCandy() function instead of passing them into your Player class if that is the only place where you need to access your Candy objects from.

void touchCandy(Candy candyObj){
    //candyObj.candyX or whatever field inside the Candy object you need to reference,
    // you just prefix it with candyObj.
}

Either way, you still needed to understand that for an object to access the fields of another object, it needs a reference to it. I find that thinking about it in terms of physical objects in memory helps build a mental model of the connections between objects and their internal state.

1 Like

Thanks for all your help @MilesWilliams . I updated my code to include candy and player objects. I got the instructions and high score pages to display (so I’m doing something right!) but there’s something wrong with displaying the ‘game’ page which is the most important part. I get an error saying NullPointerException with it highlighting this part in the touchCandy() method in the player class:

if ( (pandaX + pandaW > objCandy.candyX && //original candy

Any idea how to fix this? It’s probably still an error with objects or something like that. I’ll post my updated code.

Game (main) class:

//define variables
PFont title, main, dead;
PImage heart, bkgrd;
PrintWriter highScore;

String current = "menu"; //what they'll see when game is first loaded
int menuBut1x, menuBut1y;
int menuBut2x, menuBut2y;
int menuBut3x, menuBut3y;
int backButx, backButy;
int points;

//creating objects (to reference when calling methods)
Candy candyObj = new Candy();
Player pandaObj = new Player();


//functions
void setup() {
  
  size(1200,700);
  frameRate(30);
  title = loadFont("Gabriola-150.vlw");
  textFont(title);
  main = loadFont("SegoeUI-Light-60.vlw");
  textFont(main);
  dead = loadFont("Stencil-200.vlw");
  textFont(dead);
  
  points = 0;
  
  highScore = createWriter("HighScore.txt");
   
  menuBut1x = width/3-70;
  menuBut1y = height/2-100;
  menuBut2x = width/3-70;
  menuBut2y = height/2+40;
  menuBut3x = width/3-70;
  menuBut3y = height/2+180;
  backButx = 1030;
  backButy = 10;
  
}
void loadImages(){
  heart = loadImage("heart.png");
  bkgrd = loadImage("floatClouds.jpg");
}

  void draw(){
   //call other methods 
   
  background(#bfefff);
  fill(255);
  rect(menuBut1x, menuBut1y, 520, 100); //first button
  rect(menuBut2x, menuBut2y, 520, 100); //second button
  rect(menuBut3x, menuBut3y, 520, 100); //third button
  textSize(100);
  fill(#000000);
  textFont(title);
  text("Candy Dash!", 300, 180);
  textSize(200);
  fill(#000000);
  textFont(main);
  text("PLAY", 530, 320);
  textSize(65);
  fill(#000000);
  textFont(main);
  text("INSTRUCTIONS", 400, 465);
  textSize(65);
  fill(#000000);
  textFont(main);
  text("HIGH SCORES", 415, 600);
  
  if (current=="menu") {
    //background(#F0D5E2); DON'T HAVE BACKGROUND COLOUR HERE OR WILL COVER EVERYTHING - BKGRD TOP OF VOID DRAW
    if (mouseX >= menuBut1x && mouseX <= menuBut1x+520 && mouseY >= menuBut1y && mouseY <= menuBut1y+100 && mousePressed) {
          current="play";   //clicked play button     
  }
  if (mouseX >= menuBut2x && mouseX <= menuBut2x+520 && mouseY >= menuBut2y && mouseY <= menuBut2y+100 && mousePressed) {
          current="instructions";   //clicked instructions button     
  }
  if (mouseX >= menuBut3x && mouseX <= menuBut3x+520 && mouseY >= menuBut3y && mouseY <= menuBut3y+100 && mousePressed) {
          current="high scores";   //clicked high scores button     
  }
     pandaObj.resetPosition(); //resets panda's coordinates when exiting game
  }
  
  if (current=="instructions") {
    background(#e8f0f7);
    textSize(80);
    text("INSTRUCTIONS", 360, 140);
    textSize(35);
    text("Use the arrow keys to move left and right.", 100,240);
    text("Your goal is to collect all the yummy candies, and avoid the bad foods!", 100, 300);
    text("Watch out! Touch a bad food and YOU ARE DEAD!", 100, 360);
    fill(#F0FFF0); //back button
    rect(backButx, backButy, 160, 100); //back button
    textSize(50); 
    fill(#000000);
    text("MENU", 1040, 75);
    textSize(35); 
    fill(#000000);
    text("COLLECT THESE:", 180, 450);
    candyObj.loadImgInstr(); //calling method to load candy & badFood images
    
    if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
          current="menu";   //clicked menu button     
  }
  }
  
    if (current=="high scores") {
    background(#e8f0f7);
    fill(#F0FFF0);
    rect(backButx, backButy, 160, 100); //back button
    textSize(50);
    fill(#000000);
    text("MENU", 1040, 75);
    textSize(100);
    text("HIGH SCORE: " + points, 300, height/2);
    
    if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
          current="menu";   //clicked menu button      
  }
  }
  
  if (current=="play") {
    loadImages();
    image(bkgrd, 0, 0, 1200, 700);
    //background(#cfe1e1);
    fill(#F0FFF0);
    rect(backButx, backButy, 160, 100); //back button
    textSize(50);
    fill(#000000);
    text("MENU", 1040, 75);
    
    //call methods - from Candy class
    candyObj.loadImages();
    candyObj.candyFall();
    candyObj.badFoodFall();
    candyObj.newCandy();
    //call methods - from Player class
    pandaObj.loadImages();
    pandaObj.keyPressed();
    pandaObj.touchCandy();
    
    
    if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
          current="menu";   //clicked menu button  
  }
  }
  
  if (current=="gameOver") {
    background(#7B0B1F);
    textFont(dead);
    textSize(150);
    text("YOU ARE DEAD", 70, height/2);
    
    textFont(main);
    fill(#fbfbfb);
    rect(200, 500, 300, 150); //replay button
    textSize(80);
    fill(#000000);
    noStroke();
    text("REPLAY", 220, 600);
    
    fill(#fbfbfb);
    rect(700, 500, 300, 150); //menu button
    textSize(80);
    fill(#000000);
    noStroke();
    text("MENU", 745, 600);
    highScore.println("High Score: " + points); // Write the points to the file

    points=0; //reset points to 0 when dead
    pandaObj.resetPosition();
   
  if (mouseX >= 200 && mouseX <= 200+300 && mouseY >= 500 && mouseY <= 500+150 && mousePressed) {
          current="play";   //clicked replay
  }
  if (mouseX >= 700 && mouseX <= 700+300 && mouseY >= 500 && mouseY <= 500+150 && mousePressed) {
          current="menu";   //clicked menu button 
  }
}
  }

Candy class:

//candy coordinates, falling, collision
class Candy {
  
  //define variables
  PImage candy, lollipop, cottonCandy;
  PImage badApple, bananaPeel, pepper;
  PImage [] goodCandy = new PImage [3];
  PImage [] badFood = new PImage [3];
  public int candySpeed, foodSpeed;
  public int yDirCandy, yDirFood;
  public int candyY, candyX, candyW, candyH;
  public int randCandyW, randCandyH, badAppleX;
  public int rand, randX, randY, randX2, lolliX, lolliY;
  
     Player objPlayer;
  
  public void setPlayerObj(Player objPlayer){ 
    this.objPlayer = objPlayer;
  }
  
  //constructor
  Candy() {
    
    candySpeed = 10;
    foodSpeed = 5;
    yDirCandy = 1;
    yDirFood = 1;
    candyY = 10;
    candyX = 200;
    candyW = 187;
    candyH = 121;
    randCandyW = 100;
    randCandyH = 100;
    badAppleX = 700;
    
    randY = -200;
    lolliY = -600;
    
    rand=(int) (2*Math.random()) +1;
    randX = (int) (1100*Math.random())+20; 
    randX2 = (int) (1100*Math.random())+20; 
    lolliX = (int) (1100*Math.random())+20;
  }
    
  //functions
  
  void loadImages(){
  candy = loadImage("goodCandy0.png");
  cottonCandy = loadImage("goodCandy1.png");
  lollipop = loadImage("goodCandy2.png");
  badApple = loadImage("badFood0.png");
  bananaPeel = loadImage("badFood1.png");
  pepper = loadImage("badFood2.png");
  
  for (int i=0; i<goodCandy.length; i++) {
  goodCandy[i] = loadImage("goodCandy" + i + ".png"); //loading goodCandy imgs via array
}
  for (int i=0; i<badFood.length; i++) {
  badFood[i] = loadImage("badFood" + i + ".png"); //loading badFood imgs via array
}
}

void loadImgInstr(){ //display candy and badfood on instructions
  loadImages();
  image(candy, 80, 480, 120, 80);
    image(lollipop, 220, 480, 100, 170);
    image(cottonCandy, 350, 480, 100, 180);
    text("AVOID THESE:", 800, 450);
    image(badApple, 720, 480, 100, 140);
    image(bananaPeel, 830, 480, 180, 170);
    image(pepper, 1030, 470, 100, 170);
}
void candyFall() {
  
  //image(objPlayer.panda, objPlayer.pandaX, objPlayer.pandaY, objPlayer.pandaW, objPlayer.pandaH); //HOW TO GET VARIABLES HERE?
  fill(#000000);
  text("Points: " + points, 20, 70);
  //candyObj.newCandy();
  newCandy();
  
  image(candy, candyX, candyY, candyW, candyH);  //original candy
  candyY = candyY + (candySpeed * yDirCandy);
  
  image(goodCandy[rand], randX, randY, randCandyW, randCandyH); //rand candy
  randY = randY + (candySpeed * yDirCandy);
  
  image(lollipop, lolliX, lolliY, randCandyW, randCandyH); //lolli candy
  lolliY = lolliY + (candySpeed * yDirCandy);

//highScore.println("High Score: " + points); // Write the points to the file
}

void badFoodFall(){
  image(badFood[rand], randX2, randY, randCandyW, randCandyH);  //rand food
  randY = randY + (candySpeed * yDirCandy);
  
  image(badApple, badAppleX, randY, randCandyW, randCandyH);  //rand food
  randY = randY + (candySpeed * yDirFood);
}

void newCandy() {
  if (candyY>=850) {
    candyY=0;  //resetting the original candy to top
  }
  if (lolliY>=850) {
    lolliY=0; //resetting lolli to top
  }
  if (randY>=850) {
    randY=0;
  }
}

}

Player class:

//panda settings, collision, points 

class Player {

  //define variables
  public PImage panda;
  public int pandaX;
  int pandaY;
  int pandaW;
  int pandaH;
  
  //Candy candyObj = new Candy();
  private Candy objCandy;
  
  public void setCandyObj(Candy objCandy){ //making new candy object so player class can access it
    this.objCandy = objCandy;
  }
  
  //constructor
  Player (){
    pandaX = 550;
    pandaY = 580;
    pandaW = 80;
    pandaH = 112;
  }
  
  
  //functions
  void loadImages(){
    panda = loadImage("panda.png");
  }
  void resetPosition() { //resets panda's position when going out of game back to menu or dead
  pandaX = 550; //resets the panda to starting position 
  pandaY = 580; //RESET EVERYTHING WHEN EXIT
  points = 0;
  }
  
    void keyPressed() { 
  if (key==CODED) {
    if (keyCode==LEFT) {
      pandaX = pandaX-20; 
    }
    if (keyCode==RIGHT) {
      pandaX = pandaX+20;
    }
   if (pandaX<=5) {
     pandaX=5; //if hit into wall panda won't go off screen
   }
   if (pandaX>=1120) {
     pandaX=1120;
   }
   //highScore.flush(); // Writes the remaining data to the file
   //highScore.close(); // Finishes the file
  }
    }
  
  void touchCandy() {
  if (  (pandaX + pandaW > objCandy.candyX && //original candy 
        pandaX < objCandy.candyX + objCandy.candyW &&
        pandaY + pandaH > objCandy.candyY &&
        pandaY < objCandy.candyY + objCandy.candyH) ||
        (pandaX + pandaW > objCandy.randX && //rand candy
        pandaX < objCandy.randX + objCandy.randCandyW &&
        pandaY + pandaH > objCandy.randY &&
        pandaY < objCandy.randY + objCandy.randCandyH) ||
        (pandaX + pandaW > objCandy.lolliX && //lollipop
        pandaX < objCandy.lolliX + objCandy.randCandyW &&
        pandaY + pandaH > objCandy.lolliY &&
        pandaY < objCandy.lolliY + objCandy.randCandyH)
        )
        {
          textSize(60);
          text("YUM! You get points!", 370, 300);
          points = points + 1; //if panda touches candy, get points!
          image(heart, pandaX+20, pandaY-50, 50, 50);
        }
  if ((pandaX + pandaW > objCandy.randX2 && //rand food
        pandaX < objCandy.randX2 + objCandy.randCandyW &&
        pandaY + pandaH > objCandy.randY &&
        pandaY < objCandy.randY + objCandy.randCandyH) ||
        (pandaX + pandaW > objCandy.badAppleX && //apple
        pandaX < objCandy.badAppleX + objCandy.randCandyW &&
        pandaY + pandaH > objCandy.randY &&
        pandaY < objCandy.randY + objCandy.randCandyH))
        {
          current="gameOver";
        
         }
  
}
  }

Unfortunately we don’t have the resources to run your code. You need to remove access to fonts and provide image resources. Related to if ( (pandaX + pandaW > objCandy.candyX && part, what does it do? I bet this can be rewritten to make it easier to read.

Kf

You never executed setCandyObj, thus the objCandy.candy that you are referencing is equal to Null.candy, which doesn’t give much to work with… You need to setCandyobj when you make that new candy object. Just the method to create/set it doesn’t do much, if it is never executed. Try adding in your setup method pandaObj.setCandyObj(candyObj);