So I am making an overly complicated that uses "LoadingZone" and "Room"objects. Room objects are a series of actors that it adds in, and sets the background image to something new. LoadingZone objects sit in rooms, and hold other room objects. (So a LoadingZone in Room1 might hold the Room object for Room2. Whenever the player collides with a loading zone, it loads the Room2 object by clearing the world and adding all of the actors in Room2's storage.) In order to prevent memory heap errors (for example, creating a Room2 object requires creating all the actors within Room2, which includes a LoadingZone to Room1 -> we need to create a Room1 object -> creating a Room1 object requires creating all the actors within Room1, which includes a LoadingZone to Room2 -> we need to create a Room2 object -> creating a Room2 object requires creating all the actors within Room2, which includes a LoadingZone to Room1 -> we need to create a Room1 object... you get the point), I implemented that every room is static and final, and only created once in the room class. It reads as this:
(SoudRoom and JohnRoom are unused right now, that's why they're not final.)
The constructor of a LoadingZone reads as follows:
As you can see, it takes the Room object when it is created, ensuring there is no way to accidentally not initialize it.
Creating the RoboticsRoom (the first static final object) looks like this:
As you can see, it fills the room with various collision boxes, but those are not important. The important part is at the end:
You can see here is makes a new LoadingZone, and for what room to load should the player collide with it, I enter "Room.roboticsBackroom"(an adjoining room). The first time this room is loaded, everything is tootsy dandy, and walking through it sets the room to the roboticsBackroom. The creation of the robotics back room looks something like this:
Once again, it just creates a bunch of collision boxes, but also it makes a new loading zone with the robotics room as its location to send you to (because the player can walk between these rooms):
So, the player walks in the roboticsBackroom, and walks back successfully. However, despite being the exact same room and loaded using the exact same code, the original loading zone which should hold "Room.roboticsBackroom" now has a null variable.
I am very confused, because it has no constructors that allow the room object to be null, and the only variable ever put into it is a static and final variable, meaning the JVM should literally stop it from trying to modify the object to make it null.
So in short, I am very confused, and would love to hear anything about why this might be happening.
Also, here are some images that show the problem a little better (the loadingZones are light blue and semitransparent):
If anyone has any idea why this happens, or how to fix it, or you need more information to fix it, please let me know. I am desperate.
public class Room extends Actor { public ArrayList<ActorPoint> actors=new ArrayList<>(); public GreenfootImage background; final static Room roboticsRoom = new RoboticsRoom(); final static Room roboticsBackroom = new RoboticsBackroom(); static Room soudRoom = new SoudRoom(); static Room roboticsHall = new RoboticsHall(); public Room(GreenfootImage b, ActorPoint[] a) { background=b; java.util.Collections.addAll(actors,a); } public Room(){} }
public LoadingZone(int w, int h,int ro, Room r) { GreenfootImage g = new GreenfootImage(w,h); if (Player.DEBUG_MODE) { g.setColor(new Color(0,255,255,100)); g.fill(); } setImage(g); loaded=r; setRotation(ro); }
public RoboticsRoom() { super(new GreenfootImage("RoboticsRoom2.png"),new ActorPoint[]{new ActorPoint(new CollisionBox(575,70),548,569),new ActorPoint(new CollisionBox(131,30),1035,364),new ActorPoint(new CollisionBox(16,41),975,397),new ActorPoint(new CollisionBox(14,35),1092,394),new ActorPoint(new CollisionBox(14,34),967,165),new ActorPoint(new CollisionBox(141,29),1030,134),new ActorPoint(new CollisionBox(10,32),1094,162),new ActorPoint(new CollisionBox(250,59),737,221),new ActorPoint(new CollisionBox(15,30),853,261),new ActorPoint(new CollisionBox(15,36),615,262),new ActorPoint(new CollisionBox(230,66),734,291),new ActorPoint(new CollisionBox(92,16),709,252),new ActorPoint(new CollisionBox(34,33),648,332),new ActorPoint(new CollisionBox(36,35),826,330),new ActorPoint(new CollisionBox(215,60),380,225),new ActorPoint(new CollisionBox(18,38),482,271),new ActorPoint(new CollisionBox(15,30),278,270),new ActorPoint(new CollisionBox(20,299),10,287),new ActorPoint(new CollisionBox(1097,19),548,9),new ActorPoint(new LoadingZone(40,170,90,Room.roboticsHall),981,679),new ActorPoint(new LoadingZone(40,170,0,Room.roboticsBackroom,777,583),21,564)}); }
new LoadingZone(40,170,0,Room.roboticsBackroom)
public RoboticsBackroom() { super(new GreenfootImage("RoboticsBackroom.png"),new ActorPoint[]{new ActorPoint(new CollisionBox(419,533),889,266),new ActorPoint(new CollisionBox(389,528),194,264),new ActorPoint(new CollisionBox(142,40),470,48),new ActorPoint(new CollisionBox(15,27),532,78),new ActorPoint(new CollisionBox(12,24),405,80),new ActorPoint(new CollisionBox(67,129),634,88),new ActorPoint(new CollisionBox(20,110),598,97),new ActorPoint(new CollisionBox(73,21),623,161),new ActorPoint(new LoadingZone(40,170,0,Room.soudRoom),198,615),new ActorPoint(new LoadingZone(40,170,0,Room.roboticsRoom,105,541),872,620)}); }
LoadingZone(40,170,0,Room.roboticsRoom,105,541)