PImages change to null in separate class

I am using Processing core in Eclipse IDE, and I’m currently working on some code where I have many object classes inside of the main class. Recently I decided to move one of those classes (a class called bat) into a separate class file, and use the extends function to connect it with the main class. This way, keeping all the classes in a separate file makes the code much easier to navigate. However, when doing this, when my object class runs image(), it tells me that the image I put in it is null. After examining a little using the debug function, I found that when the main class creates a new bat, ALL PImages in the whole code globally change to null. How do I prevent this from happening, or work around this issue? Also, please inform me if what I’m doing right now is even possible.

Can’t see your code but I suspect that you have duplicated the PImage variables from the main sketch class (extends PApplet) into the bat class but these are not being initialised.

The way I do it is that I have all of the PImages created in the main class, and then initialized with loadImage in setup(). The bat class does not contain any loadImage or creating new PImages so the only thing I can think of is that possibly the extends could be breaking the PImages. And as mentioned before, PImages change to null globally, not just in the bat class.
Here’s some of the code (the whole code is super long) but this may be helpful:

public class redsquare extends PApplet {
	public PImage bat1, bat2;

then,

public void setup() {
	bat1 = loadImage("bat1.png");
	bat2 = loadImage("bat2.png");
}

and this is where I create new bat classes, in a void which gets run in setup:

batlist.add(new bat(1024, 256, 1));
batlist.add(new bat(704, 128, 1));
batlist.add(new bat(1216, 640, 1));
batlist.add(new bat(1344, 320, 1));

and finally, this is the part of the bat class with the images.

image(bat2, xlocation, ylocation);
image(bat1, xlocation, ylocation);

I don’t know if seeing this code helps (I don’t feel like plopping 1000 lines of code on here) but what I suspect is that maybe the PImages don’t know where to load from in the second class, though that doesn’t explain why the PImages COMPLETELY change to null.

This code that you provided is helpful and enough.

You need to do this instead:

public class Redsquare {

       PApplet  p;
	public PImage bat1, bat2;

        //constructor
        Redsquare(PApplet parent){
            p=parent;
            ...
        }

Now you can use any function from Processing by calling it from your PApplet member field like this:

//THIS next is a member function of your class above
//THIS next has no relationship whatsoever to the setup() function in a Processing sketch
//THIS is the setup function that belongs to Redsquare class
public void setup() {
	bat1 = p.loadImage("bat1.png");
	bat2 = p.loadImage("bat2.png");
}

Kf

I don’t know if I understand you incorrectly, but I’ve changed all the code that way like so:

public class redsquare {
	PApplet p;
	redsquare (PApplet parent) {
		p = parent;
	}
	public PImage bat1, bat2;

and added p. before every PApplet method.
But now in the bat class, the bat constructor which is

bat (int x, int y, int elocation) {
	this.xlocation = x;
	this.ylocation = y;
	this.elocation = elocation;
	ogx = xlocation;
	ogy = ylocation;
	}

now complains that “implicit superconstructor redsquare() is undefined. Must explicitly invoke another constructor”. Am I doing something wrong or is something missing, like a super() or something?
Thanks for your patience.

I think kfrajer has mixed up your classes. I suggest you try something like.

public class Redquare extends PApplet {
  public ArrayList<Bat> bats = new ArrayList<Bat>();
  
  void setup(){
    bats.add (new Bat(this, 1024, 256, 1, "bat1.png");
    bats.add (new Bat(this, 704, 128, 1, "bat2.png");
   ...
}

and in draw …

  for(Bat b : bats){
    b.render();
  } 

Then the Bat class

public class Bat {

  PApplet  p;
  public PImage bat;
  int xlocation, ylocation, elocation;
  int ogx, ogy; // I have assumed these are attributes
  
  //constructor
  Bat(PApplet parent, int x, int y, int elocation, String file) {
    p = parent;
    this.xlocation = x;
    this.ylocation = y;
    this.elocation = elocation;
    ogx = xlocation;
    ogy = ylocation;
    bat = p.loadImage(file);
  }

  public void render(){
    p.pushMatrix();
    p.translate(xlocation, ylocation);
    p.image(bat, 0, 0);
    p.popMatrix();
  }
}

By the way it is a convention in Java that class names always start with a capital letter :slight_smile:

I’ve added a PApplet into the bat class and put the loadImage inside of the constructor:

public class bat extends redsquare {
	PApplet p;
	bat (PApplet parent, int x, int y, int elocation) {
		p = parent;
		this.xlocation = x;
		this.ylocation = y;
		this.elocation = elocation;
		ogx = xlocation;
		ogy = ylocation;
		bat1 = p.loadImage("bat1.png");
		bat2 = p.loadImage("bat2.png");
	}

But there seems to be another problem: the PApplets also change to null. It’s not just PImages but I’ve found that every single processing related class (PApplet, font, image, etc.) changes to null, too. So right now when it runs the p.loadImage(), it tells me that p is null as well. Do I need to do anything else to stop that from happening? I’m wondering if it’s a conflict with how the PApplet functions in other classes, but I’m still in the dark about why this affects everything even in the redsquare class.

P.S. Yeah I get the capital letters thing but I’m too lazy to make it that way… :stuck_out_tongue:

Thanks! I made the image work by putting a this in the bat constructor for the PApplet instead of p. However, there’s another problem, somewhat unrelated to the original problem: oddly enough, it won’t let me create object classes in the bat class. I want to create a coin by adding one to an arraylist:

coinlist.add(new coin (xlocation, ylocation, 1, elocation));

but it doesn’t work. There is no error or anything, it’s just that nothing happens- nothing gets added to the arraylist. (just for a little background, a coin object is one that shows a coin on screen that you can pick up). I have tried making a method in the main class that gets called in the bat class, which runs that line of code, but it still doesn’t do anything. Despite this, the coins still seem to work, because if I make a coin somewhere else in the code, it makes a coin. It just doesn’t work when it’s run from the bat class.
What should I do to fix this problem?

Never mind. I fixed it. But I have another issue now, which I opened a new discussion for (since this one is currently dead):
Files must be loaded inside setup() or after it has been called