rendering problem

So I’m making a 2D sprite based isometric game in java without any libraries. It go well so far but I have encountered a problem with my rendering. My levels consist of a 3D array of a abstract class called Tile, but now I want to be able to render entities on the map too. So what would be a good way of doing that? Since the Entity class is in a ArrayList i can’t simply loop through it. I have been thinking of having an ArrayList that consists of WeakReferences to a class called LevelComponent that only contains x, y, z, and sprite. While the update method loops through the Tile, and Entity class respectively

Here is some made up code on how I thinking of doing it.


public class Map{
	List<WeakReference<Entity>> render = new ArrayList<>();

	public void update(float alpha){
		for(int i=0; i<entities.size(); i++){
			Entity e = entities.get(i);
			if(e.isDead()){
				entities.remove(i); i--;
				continue;
			}
			
			e.update(alpha);
		}
		
		for(int x=0; x<SIZE_WIDTH; x++)
			for(int y=0; y<SIZE_HEIGHT; y++)
				for(int z=0; z<SIZE_TOP; z++)
					if(t != null)
						t.update(alpha);
						
	}

	public void render(Graphics2D g2, int offetX, int offsetY){
		for(int i=0; i<levelComp.size(); i++){
			LevelComponent l = levelComp.get(i).get();
			if(l == null){
				levelComp.remove(i); i--;
				continue;
			}
			
			l.render(g2, offetX, offetY);
		}
	}
}

Is there a better way I don’t see?

You don’t need to use WeakReferences or anything like that.
Why can’t you simply iterate through your List of Entities?

Cas :slight_smile:

Because the Tiles and Entities will end up overlapping each other. Like if I render the entities first, and then the tiles all entities will be under the level, and if I do it in the reverse order all entities wouldn’t be able to be behind terrain.

I use WeakReferences so I don’t need to check in the rendering if the tile or entity exists, because then the garbage collector will take care of that.

Since no one have protested against this, I take this is an okay idea. I really did one change, I made “LevelComponent” into an interface.

public interface RenderComponent {
    public void render(Graphics2D g2, int offsetX, int offsetY, int offsetZ);
    public int getRenderPriority();
}

This is what the rendering method ended up looking like.

public void render(Graphics2D g2, int offsetX, int offsetY, int offsetZ){
        //Sort everything that is going to get rendered
        render.sort((w1, w2) -> {
            int renderScore1 = w1.get() != null ? ((RenderComponent)w1.get()).getRenderPriority() : -1;
            int renderScore2 = w2.get() != null ? ((RenderComponent)w2.get()).getRenderPriority() : -1;
            return renderScore2 - renderScore1;
        });
        
        //Check everything that's going to get rendered, and remove garbage data.
        for(int i=0; i<render.size(); i++){
            RenderComponent r = render.get(i).get();
            if(r == null){
                render.remove(i); i--;
                continue;
            }
            
            //Render
            r.render(g2, offsetX, offsetY, offsetZ);
        }
    }