Having a Problem with ArrayLists and Objects

I have been trying to come up with a way to have a fluid spread out in a 2d top down game. I came up with several different ways but kept on running into concurrency issues and the biggest issue of it wanting to make a bazzillion water tiles over a 6 x 6 area. I have a room where the wall tiles are surrounding a 4 x 4 block of floor tiles which are represented in another z level. There is one water tile with a density of 100 that should spread out and diminish which is located on the same z level as the walls. The latest one I feel should work but still it ends up creating thousands of objects. What I’m doing here is just going ahead and adding the new water objects into the fluid objects array. Then getting the index of the ones that won’t be moved to the bigger list, then removing them. I hate coming for help but I spent maybe 6 -10 hours setting up for fluids and probably 5 of it on the problem coming up with all kinds of ways of doing it. For some reason the integer array i’s size is getting into the thousands for reason, I have no idea since i should be at max 8.

	public void flow(Objects fluid, ArrayList<Objects> worldObjects)
	{
		fluidObjects.add(new Fluids(fluid.x - 1, fluid.y - 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		fluidObjects.add(new Fluids(fluid.x, fluid.y - 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		fluidObjects.add(new Fluids(fluid.x + 1, fluid.y - 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		fluidObjects.add(new Fluids(fluid.x - 1, fluid.y, fluid.z, fluid.id, (fluid.density / 2) / 8));
		fluidObjects.add(new Fluids(fluid.x + 1, fluid.y, fluid.z, fluid.id, (fluid.density / 2) / 8));
		fluidObjects.add(new Fluids(fluid.x - 1, fluid.y + 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		fluidObjects.add(new Fluids(fluid.x, fluid.y + 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		fluidObjects.add(new Fluids(fluid.x + 1, fluid.y + 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		
		fluid.density = fluid.density - (fluid.density / 2);
		
		ArrayList<Integer> i = new ArrayList<Integer>();
		
		int count = 0;
		
		for(Objects obj: worldObjects) // Goes through all objects in  10 x 10 world
		{
			for(Objects fObj: fluidObjects) // 8 new water objects
			{
				if((fObj.x == obj.x && fObj.y == obj.y && fObj.z == obj.z) && 
					(obj.stopsFluid == true || fObj.id == obj.id || fObj.density < 5)) // Tests to see if any should be deleted do to, walls other water
				{
					i.add(count); // Adds the objects index into a integer array list for later
				}
				count++;
			}
		
		} count = 0;
		
		for(Integer j: i) // Goes through the integer index array list
		{	
			fluidObjects.remove(j); // Removes the fluid from the 8 that shouldn't be
		}
		
		i.clear(); // Clears the other int array list.
		
		objects.addAll(fluidObjects); // Adds the working fluids from the 8 to a list that gets stuck into the master list 
		fluidObjects.clear(); // in the other class.
	}

Hi

Well the concurrency issues are an easy fix.


for(int i = 0; i < worldObjects.size(); i++){
  Objects obj = worldObjects.get(i);
}


for(int j = 0; j < fluidObjects.size(); j++){
  Objects obj = fluidObjects.get(j);
}


for(int k = 0; k < i.size(); k++){
  Integer j = i.get(k);
}

I know this doesn’t solve the total issue, but I thought it would help :slight_smile:

CopyableCougar4

Instead of storing the objects’ index for later, you could loop backwards from your fluidObjects array and remove the objects right then and there.

ex.


for(int i = 0; i < worldObjects.size(); i++) {
    for(int j = fluidObjects.size() - 1; j >= 0; j--) {
        if(shouldRemove) {
            fluidObjects.remove(j);
            continue;
        }
    }
}

I’m not sure why your code creates thousands of objects. Maybe worldObjects contains a ton of fluidObjects arrays for some reason?

I’d also avoid confusing variable names such as naming an ArrayList i because it’s easier to forget the objects’ purpose. :smiley:

I was really hoping that was gonna work but it still creates a ton of objects. I’m guessing it has something to do with how I have the objects set up cause I realized that none of the sprites for any of the water tiles, except for the starting one, are being drawn. I have the water class, extend the fluids class, that extends the objects class. One thing I noticed is that j equals zero alot after the if statement making me thing its deleting all the objects as they decrease in the list. Stopped it by putting a if j != 0 but then it just creates a ton of objects again. Without the j != 0 no objects are created… what a headache.

		objects.add(new Fluids(fluid.x - 1, fluid.y - 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		objects.add(new Fluids(fluid.x, fluid.y - 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		objects.add(new Fluids(fluid.x + 1, fluid.y - 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		objects.add(new Fluids(fluid.x - 1, fluid.y, fluid.z, fluid.id, (fluid.density / 2) / 8));
		objects.add(new Fluids(fluid.x + 1, fluid.y, fluid.z, fluid.id, (fluid.density / 2) / 8));
		objects.add(new Fluids(fluid.x - 1, fluid.y + 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		objects.add(new Fluids(fluid.x, fluid.y + 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		objects.add(new Fluids(fluid.x + 1, fluid.y + 1, fluid.z, fluid.id, (fluid.density / 2) / 8));
		
		fluid.density = fluid.density - (fluid.density / 2);
		
		for(int i = 0; i < worldObjects.size(); i++)
			for(int j = objects.size() - 1; j >= 0; j--)
				if((objects.get(j).x == worldObjects.get(i).x && objects.get(j).y == worldObjects.get(i).y && objects.get(j).z == worldObjects.get(i).z) && 
						(worldObjects.get(i).stopsFluid == true ||objects.get(j).id == worldObjects.get(i).id || objects.get(j).density < 5))
				{
						objects.remove(j);
				}

Where are you clearing the fluidObjects before adding 8 new ones?

I changed the code since I don’t really need to worry about the concurrency problems. This is the FluidHandler class and the method is called from a different class that has the whole worlds object and when its done doing this it adds them hen clears em. I’m not at home but I pretty sure I had it like this



public void update()
{
for(Objects obj: objects) // Had all the world objects
{
obj.update(); // Updates them
if(obj.isFluid) // If its a fluid its going into the flow method
{
fluidHandler.flow(obj, objects); // The method that I have shown
}

objects.add(fluidHandler.objects); // Adds the objects that were created from the flow method
fluidHandler.clear(); // And then they are cleared 
}



Ohhhh! man… I finally got it working right just to realize just how many factors go into making realistic water sim. I’m off a ways but getting closer.