diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java index dc60f9b..ee5be74 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/G2DRenderer.java @@ -43,6 +43,8 @@ public class G2DRenderer implements Renderer { private static final Logger LOGGER = LoggerFactory.getLogger(G2DRenderer.class); private static final long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(2); + + private static final short ZINDEX_STEPS = RenderingBoLayer.UI_TOP - RenderingBoLayer.UI_BGR + 1; private final RingBuffer fpsHistory = new RingBuffer<>(90); @@ -175,7 +177,7 @@ public class G2DRenderer implements Renderer { this.drawStatistics(); this.rendererData.getRendererWorkingSet().commit(this.rendererModuleId, true); this.rendererData.getRendererWorkingSet().getLiveSet(this.renderingBOs, this.rendererData.getModuleService()::isDisplayed); - this.renderingBOs.sort((bo0, bo1) -> Short.compare(bo0.getLayer(), bo1.getLayer())); + this.renderingBOs.sort((bo0, bo1) -> Integer.compare(this.getEffectiveLayer(bo0), this.getEffectiveLayer(bo1))); Graphics2D screenGraphics = null; try { @@ -204,7 +206,7 @@ public class G2DRenderer implements Renderer { for (final RenderingBo bo : usedRenderingBoTypes.values()) { bo.staticCleanupAfterFrame(); } - + this.rendererData.getRenderingBoPool().releasePending(); // @@ -329,6 +331,14 @@ public class G2DRenderer implements Renderer { } } + private int getEffectiveLayer(final RenderingBo bo) { + final var layer = bo.getLayer(); + if (layer >= RenderingBoLayer.UI_BGR && layer <= RenderingBoLayer.UI_TOP) { + return layer + (bo.getZIndex() * ZINDEX_STEPS); + } + return layer; + } + public G2DMainFrame getMainFrame() { return this.mainFrame; } diff --git a/src/main/java/de/extio/game_engine/renderer/model/AbstractRenderingBo.java b/src/main/java/de/extio/game_engine/renderer/model/AbstractRenderingBo.java index 797d159..b319c8d 100644 --- a/src/main/java/de/extio/game_engine/renderer/model/AbstractRenderingBo.java +++ b/src/main/java/de/extio/game_engine/renderer/model/AbstractRenderingBo.java @@ -33,6 +33,8 @@ public abstract class AbstractRenderingBo implements RenderingBo { private final short defaultLayer; + protected short zIndex; + public AbstractRenderingBo(final short layer) { this.layer = layer; this.defaultLayer = layer; @@ -224,6 +226,7 @@ public abstract class AbstractRenderingBo implements RenderingBo { this.width = 0; this.height = 0; this.layer = this.defaultLayer; + this.zIndex = 0; } @Override @@ -238,6 +241,7 @@ public abstract class AbstractRenderingBo implements RenderingBo { this.width = abstractRenderingBo.width; this.height = abstractRenderingBo.height; this.layer = abstractRenderingBo.layer; + this.zIndex = abstractRenderingBo.zIndex; } } @@ -298,6 +302,17 @@ public abstract class AbstractRenderingBo implements RenderingBo { return this; } + @Override + public short getZIndex() { + return this.zIndex; + } + + @Override + public RenderingBo setZIndex(final short zIndex) { + this.zIndex = zIndex; + return this; + } + public int getWidth() { return this.width; } diff --git a/src/main/java/de/extio/game_engine/renderer/model/RenderingBo.java b/src/main/java/de/extio/game_engine/renderer/model/RenderingBo.java index 750dea0..967628f 100644 --- a/src/main/java/de/extio/game_engine/renderer/model/RenderingBo.java +++ b/src/main/java/de/extio/game_engine/renderer/model/RenderingBo.java @@ -35,6 +35,16 @@ public interface RenderingBo extends AutoCloseable { short getLayer(); + /** + * Gets the z-index for fine-grained ordering within UI layers (UI_BGR to UI_TOP). + */ + short getZIndex(); + + /** + * Sets the z-index for fine-grained ordering within UI layers (UI_BGR to UI_TOP). + */ + RenderingBo setZIndex(short zIndex); + /** * Positions this bo with an absolute position on the viewport. x0 y0 coordinates are at the top left. Call RendererControl#getEffectiveViewportDimension to get the absolute dimension of the viewport. */ diff --git a/src/test/java/de/extio/game_engine/renderer/work/RendererWorkingSetImplTest.java b/src/test/java/de/extio/game_engine/renderer/work/RendererWorkingSetImplTest.java index a7b7e75..4e93a71 100644 --- a/src/test/java/de/extio/game_engine/renderer/work/RendererWorkingSetImplTest.java +++ b/src/test/java/de/extio/game_engine/renderer/work/RendererWorkingSetImplTest.java @@ -426,6 +426,16 @@ public class RendererWorkingSetImplTest { public short getLayer() { return RenderingBoLayer.UI0; } + + @Override + public short getZIndex() { + return 0; + } + + @Override + public RenderingBo setZIndex(short zIndex) { + return this; + } @Override public RenderingBo withPositionAbsoluteAnchorTopLeft(final int x, final int y) { diff --git a/src/test/java/de/extio/game_engine/renderer/work/RenderingBoPoolImplTest.java b/src/test/java/de/extio/game_engine/renderer/work/RenderingBoPoolImplTest.java index 1ea4bf8..c26d349 100644 --- a/src/test/java/de/extio/game_engine/renderer/work/RenderingBoPoolImplTest.java +++ b/src/test/java/de/extio/game_engine/renderer/work/RenderingBoPoolImplTest.java @@ -343,6 +343,16 @@ public class RenderingBoPoolImplTest { return 0; } + @Override + public short getZIndex() { + return 0; + } + + @Override + public RenderingBo setZIndex(short zIndex) { + return this; + } + @Override public RenderingBo withPositionAbsoluteAnchorTopLeft(final int x, final int y) { return this; @@ -492,6 +502,16 @@ public class RenderingBoPoolImplTest { return 0; } + @Override + public short getZIndex() { + return 0; + } + + @Override + public RenderingBo setZIndex(short zIndex) { + return this; + } + @Override public RenderingBo withPositionAbsoluteAnchorTopLeft(final int x, final int y) { return this;