From 13db7972ebf0fd128a7792f9af0aa66739705a34 Mon Sep 17 00:00:00 2001 From: jzitnik-dev Date: Tue, 23 Sep 2025 12:18:35 +0200 Subject: [PATCH] perf: Significantly improved rendering performance --- src/main/java/cz/jzitnik/game/Game.java | 8 ++++---- .../java/cz/jzitnik/game/sprites/SimpleSprite.java | 2 +- .../game/threads/list/InputHandlerThread.java | 14 ++++++-------- src/main/java/cz/jzitnik/tui/MouseHandler.java | 2 +- src/main/java/cz/jzitnik/tui/ScreenRenderer.java | 6 ++++++ 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/main/java/cz/jzitnik/game/Game.java b/src/main/java/cz/jzitnik/game/Game.java index e138dc7..4c6a0d3 100644 --- a/src/main/java/cz/jzitnik/game/Game.java +++ b/src/main/java/cz/jzitnik/game/Game.java @@ -116,11 +116,11 @@ public class Game { world[cords[1]][cords[0]].remove(player.getPlayerBlock2()); world[cords[1] - 1][cords[0] + 1].add(player.getPlayerBlock1()); world[cords[1] - 1][cords[0]].remove(player.getPlayerBlock1()); - screenRenderer.render(this); + new Thread(() -> screenRenderer.render(this)).start(); stats.setBlocksTraveled(stats.getBlocksTraveled() + 1); - entitySpawnProvider.update(this, terminal); + new Thread(() -> entitySpawnProvider.update(this, terminal)).start(); playMovePlayerSound(cords[0] + 1, cords[1]); @@ -147,11 +147,11 @@ public class Game { world[cords[1]][cords[0]].remove(player.getPlayerBlock2()); world[cords[1] - 1][cords[0] - 1].add(player.getPlayerBlock1()); world[cords[1] - 1][cords[0]].remove(player.getPlayerBlock1()); - screenRenderer.render(this); + new Thread(() -> screenRenderer.render(this)).start(); stats.setBlocksTraveled(stats.getBlocksTraveled() + 1); - entitySpawnProvider.update(this, terminal); + new Thread(() -> entitySpawnProvider.update(this, terminal)).start(); playMovePlayerSound(cords[0] - 1, cords[1]); diff --git a/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java b/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java index ec8e98e..8fba1c4 100644 --- a/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java +++ b/src/main/java/cz/jzitnik/game/sprites/SimpleSprite.java @@ -12,6 +12,6 @@ public class SimpleSprite extends Sprite { } public String getSprite(Enum key) { - throw new RuntimeException("Imposible state"); + throw new RuntimeException("Impossible state"); } } diff --git a/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java b/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java index d94b8b7..a7b10a4 100644 --- a/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java +++ b/src/main/java/cz/jzitnik/game/threads/list/InputHandlerThread.java @@ -8,9 +8,11 @@ import cz.jzitnik.tui.MouseHandler; import cz.jzitnik.tui.ScreenRenderer; import org.jline.terminal.MouseEvent; import org.jline.terminal.Terminal; + import java.io.IOException; import java.nio.BufferUnderflowException; import java.util.Optional; + import cz.jzitnik.game.annotations.ThreadRegistry; /** @@ -58,24 +60,22 @@ public class InputHandlerThread extends Thread { case INVENTORY -> InventoryClickHandler.click(mouseEvent, terminal, screenRenderer, game, Optional.empty(), Optional.empty()); case CRAFTING_TABLE -> - game.getGameStates().craftingTable.click(mouseEvent, terminal, screenRenderer); + game.getGameStates().craftingTable.click(mouseEvent, terminal, screenRenderer); case CHEST -> ((Chest) game.getWorld()[game.getGameStates().clickY][game .getGameStates().clickX].stream().filter(i -> i.getBlockId().equals("chest")) .toList().getFirst().getData()).click(game, mouseEvent, terminal, - screenRenderer); + screenRenderer); case FURNACE -> ((Furnace) game.getWorld()[game.getGameStates().clickY][game .getGameStates().clickX].stream().filter(i -> i.getBlockId().equals("furnace")) .toList().getFirst().getData()).click(game, mouseEvent, terminal, - screenRenderer); + screenRenderer); case ESC -> game.getGameStates().dependencies.escape.mouse(mouseEvent, terminal, screenRenderer); - case SAVE_EXIT -> { - } case OPTIONS -> game.getGameStates().dependencies.options.handleMouse(mouseEvent, terminal, screenRenderer); case DEATH_SCREEN -> game.getGameStates().dependencies.deathScreen .handleMouse(mouseEvent, terminal, screenRenderer, game); - case SAVED -> { + case SAVE_EXIT, SAVED -> { } } } @@ -86,11 +86,9 @@ public class InputHandlerThread extends Thread { case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> game.changeSlot(key - 49, screenRenderer); case 'a' -> { game.movePlayerLeft(screenRenderer, terminal); - screenRenderer.render(game); } case 'd' -> { game.movePlayerRight(screenRenderer, terminal); - screenRenderer.render(game); } case ' ' -> { game.movePlayerUp(screenRenderer); diff --git a/src/main/java/cz/jzitnik/tui/MouseHandler.java b/src/main/java/cz/jzitnik/tui/MouseHandler.java index b484e4c..3bf6aef 100644 --- a/src/main/java/cz/jzitnik/tui/MouseHandler.java +++ b/src/main/java/cz/jzitnik/tui/MouseHandler.java @@ -189,6 +189,6 @@ public class MouseHandler { screenRenderer.setSelectedBlock(Optional.empty()); } - screenRenderer.render(game); + new Thread(() -> screenRenderer.render(game)).start(); } } diff --git a/src/main/java/cz/jzitnik/tui/ScreenRenderer.java b/src/main/java/cz/jzitnik/tui/ScreenRenderer.java index fcaf927..d6ff76f 100644 --- a/src/main/java/cz/jzitnik/tui/ScreenRenderer.java +++ b/src/main/java/cz/jzitnik/tui/ScreenRenderer.java @@ -27,6 +27,7 @@ import java.util.Optional; public class ScreenRenderer { private final SpriteList spriteList; private final Terminal terminal; + private boolean rendering = false; /** * Constructs a {@code ScreenRenderer} with the given sprite list and terminal. @@ -98,6 +99,10 @@ public class ScreenRenderer { * @param game Current game state to render. */ public synchronized void render(Game game) { + if (rendering) { + return; + } + rendering = true; log.debug("Rendering frame"); var world = game.getWorld(); StringBuilder main = new StringBuilder(); @@ -216,6 +221,7 @@ public class ScreenRenderer { log.debug("Frame rendered"); System.out.println(main); + rendering = false; } /**