From ffa3dc076b859c0115a700e20d8c80ea63451303 Mon Sep 17 00:00:00 2001 From: eldek Date: Tue, 31 Mar 2026 23:02:52 -0300 Subject: [PATCH] CameraUI sprites positions configurable via cameras.json --- assets/data/config/cameras.json | 126 +++++++++++ assets/data/{ => sprites}/battery.json | 0 assets/data/{ => sprites}/cameras.json | 0 assets/data/{ => sprites}/custom_night.json | 0 assets/data/{ => sprites}/cutscenes.json | 0 assets/data/{ => sprites}/jumpscares.json | 0 assets/data/{ => sprites}/mask.json | 0 assets/data/{ => sprites}/menu.json | 0 assets/data/{ => sprites}/minigames.json | 0 assets/data/{ => sprites}/misc.json | 0 assets/data/{ => sprites}/monitor.json | 0 assets/data/{ => sprites}/numbers.json | 0 assets/data/{ => sprites}/office.json | 0 .../github/eldek0/asset/GameAssetManager.java | 2 +- .../github/eldek0/asset/group/AssetBase.java | 6 +- .../eldek0/asset/group/BatteryAssets.java | 1 + .../eldek0/asset/group/CameraAssets.java | 1 + .../eldek0/asset/group/CustomNightAssets.java | 1 + .../eldek0/asset/group/CutsceneAssets.java | 1 + .../eldek0/asset/group/JumpscareAssets.java | 1 + .../github/eldek0/asset/group/MaskAssets.java | 1 + .../github/eldek0/asset/group/MenuAssets.java | 1 + .../eldek0/asset/group/MinigameAssets.java | 1 + .../eldek0/asset/group/MonitorAssets.java | 1 + .../eldek0/asset/group/NumbersAssets.java | 1 + .../eldek0/asset/group/OfficeAssets.java | 1 + .../io/github/eldek0/config/CameraConfig.java | 10 + .../eldek0/config/CameraConfigFile.java | 8 + .../eldek0/config/CameraSpriteType.java | 9 + .../io/github/eldek0/config/FrameRange.java | 6 + .../io/github/eldek0/config/RangeLong.java | 6 + .../io/github/eldek0/config/SpriteConfig.java | 11 + .../eldek0/config/SpritePositionData.java | 11 + .../java/io/github/eldek0/game/Camera.java | 205 ++++++++++-------- .../io/github/eldek0/ui/SpriteLayout.java | 85 ++++++++ 35 files changed, 396 insertions(+), 100 deletions(-) create mode 100644 assets/data/config/cameras.json rename assets/data/{ => sprites}/battery.json (100%) rename assets/data/{ => sprites}/cameras.json (100%) rename assets/data/{ => sprites}/custom_night.json (100%) rename assets/data/{ => sprites}/cutscenes.json (100%) rename assets/data/{ => sprites}/jumpscares.json (100%) rename assets/data/{ => sprites}/mask.json (100%) rename assets/data/{ => sprites}/menu.json (100%) rename assets/data/{ => sprites}/minigames.json (100%) rename assets/data/{ => sprites}/misc.json (100%) rename assets/data/{ => sprites}/monitor.json (100%) rename assets/data/{ => sprites}/numbers.json (100%) rename assets/data/{ => sprites}/office.json (100%) create mode 100644 core/src/main/java/io/github/eldek0/config/CameraConfig.java create mode 100644 core/src/main/java/io/github/eldek0/config/CameraConfigFile.java create mode 100644 core/src/main/java/io/github/eldek0/config/CameraSpriteType.java create mode 100644 core/src/main/java/io/github/eldek0/config/FrameRange.java create mode 100644 core/src/main/java/io/github/eldek0/config/RangeLong.java create mode 100644 core/src/main/java/io/github/eldek0/config/SpriteConfig.java create mode 100644 core/src/main/java/io/github/eldek0/config/SpritePositionData.java create mode 100644 core/src/main/java/io/github/eldek0/ui/SpriteLayout.java diff --git a/assets/data/config/cameras.json b/assets/data/config/cameras.json new file mode 100644 index 0000000..dc8e754 --- /dev/null +++ b/assets/data/config/cameras.json @@ -0,0 +1,126 @@ +{ + "inCameraId": 1, + "wideRandomMov": { + "min": 5000, + "max": 7000 + }, + "sprites": [ + { "type": "BORDER", "x": 0, "y": 0, "zIndex": 0 }, + + { "type": "MAP", "x": 550, "y": 310, "fromTop": true, "zIndex": 1 }, + + { "type": "LABEL", "x": 550, "y": 280, "fromTop": true, "zIndex": 2 }, + + { "type": "REC", "x": 40, "y": 40, "fromTop": true, "zIndex": 3 }, + + { "type": "REC", "x": 90, "y": 130, "fromTop": true, "zIndex": 3 }, + + { "type": "SIGNAL_INTERRUPTED", "x": 0, "y": 80, "fromTop": true, "centerX": true, "zIndex": 10 } + ], + "cameras": [ + { + "id": 1, + "name": "PartyRoom1", + "labelPathId": 0, + "buttonX": 595, + "buttonY": 496, + "wide": false + }, + { + "id": 2, + "name": "PartyRoom2", + "labelPathId": 1, + "buttonX": 710, + "buttonY": 496, + "wide": false + }, + { + "id": 3, + "name": "PartyRoom3", + "labelPathId": 2, + "buttonX": 595, + "buttonY": 431, + "wide": false + }, + { + "id": 4, + "name": "PartyRoom4", + "labelPathId": 3, + "buttonX": 710, + "buttonY": 431, + "wide": false + }, + { + "id": 5, + "name": "LeftAirVent", + "labelPathId": 4, + "buttonX": 585, + "buttonY": 595, + "wide": false + }, + { + "id": 6, + "name": "RightAirVent", + "labelPathId": 5, + "buttonX": 695, + "buttonY": 595, + "wide": false + }, + { + "id": 7, + "name": "MainHall", + "labelPathId": 6, + "buttonX": 734, + "buttonY": 367, + "wide": true + }, + { + "id": 8, + "name": "PartsnService", + "labelPathId": 7, + "buttonX": 575, + "buttonY": 356, + "wide": true + }, + { + "id": 9, + "name": "ShowStage", + "labelPathId": 8, + "buttonX": 895, + "buttonY": 331, + "wide": true + }, + { + "id": 10, + "name": "GameArea", + "labelPathId": 9, + "buttonX": 820, + "buttonY": 455, + "wide": true + }, + { + "id": 11, + "name": "PrizeCorner", + "labelPathId": 10, + "buttonX": 929, + "buttonY": 405, + "wide": true + }, + { + "id": 12, + "name": "KidsCove", + "labelPathId": 11, + "buttonX": 920, + "buttonY": 503, + "wide": true + }, + { + "id": 13, + "name": "ShowStage", + "labelPathId": 1, + "buttonX": 120, + "buttonY": 503, + "wide": true + } + ] +} diff --git a/assets/data/battery.json b/assets/data/sprites/battery.json similarity index 100% rename from assets/data/battery.json rename to assets/data/sprites/battery.json diff --git a/assets/data/cameras.json b/assets/data/sprites/cameras.json similarity index 100% rename from assets/data/cameras.json rename to assets/data/sprites/cameras.json diff --git a/assets/data/custom_night.json b/assets/data/sprites/custom_night.json similarity index 100% rename from assets/data/custom_night.json rename to assets/data/sprites/custom_night.json diff --git a/assets/data/cutscenes.json b/assets/data/sprites/cutscenes.json similarity index 100% rename from assets/data/cutscenes.json rename to assets/data/sprites/cutscenes.json diff --git a/assets/data/jumpscares.json b/assets/data/sprites/jumpscares.json similarity index 100% rename from assets/data/jumpscares.json rename to assets/data/sprites/jumpscares.json diff --git a/assets/data/mask.json b/assets/data/sprites/mask.json similarity index 100% rename from assets/data/mask.json rename to assets/data/sprites/mask.json diff --git a/assets/data/menu.json b/assets/data/sprites/menu.json similarity index 100% rename from assets/data/menu.json rename to assets/data/sprites/menu.json diff --git a/assets/data/minigames.json b/assets/data/sprites/minigames.json similarity index 100% rename from assets/data/minigames.json rename to assets/data/sprites/minigames.json diff --git a/assets/data/misc.json b/assets/data/sprites/misc.json similarity index 100% rename from assets/data/misc.json rename to assets/data/sprites/misc.json diff --git a/assets/data/monitor.json b/assets/data/sprites/monitor.json similarity index 100% rename from assets/data/monitor.json rename to assets/data/sprites/monitor.json diff --git a/assets/data/numbers.json b/assets/data/sprites/numbers.json similarity index 100% rename from assets/data/numbers.json rename to assets/data/sprites/numbers.json diff --git a/assets/data/office.json b/assets/data/sprites/office.json similarity index 100% rename from assets/data/office.json rename to assets/data/sprites/office.json diff --git a/core/src/main/java/io/github/eldek0/asset/GameAssetManager.java b/core/src/main/java/io/github/eldek0/asset/GameAssetManager.java index 1033c16..df389cf 100644 --- a/core/src/main/java/io/github/eldek0/asset/GameAssetManager.java +++ b/core/src/main/java/io/github/eldek0/asset/GameAssetManager.java @@ -9,7 +9,7 @@ import io.github.eldek0.asset.group.*; public class GameAssetManager { - private static final String DATA = "data/"; + private static final String DATA = "data/sprites/"; private final AssetManager manager = new AssetManager(); private final Json json = new Json(); diff --git a/core/src/main/java/io/github/eldek0/asset/group/AssetBase.java b/core/src/main/java/io/github/eldek0/asset/group/AssetBase.java index 41c1b11..6107481 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/AssetBase.java +++ b/core/src/main/java/io/github/eldek0/asset/group/AssetBase.java @@ -2,15 +2,11 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public abstract class AssetBase { public abstract static class Data {} - public static class FrameRange { - public String base; - public int start, end; - } - protected void queueRange(AssetManager m, FrameRange r) { for (int i = r.start; i <= r.end; i++) m.load(r.base + i + ".png", Texture.class); } diff --git a/core/src/main/java/io/github/eldek0/asset/group/BatteryAssets.java b/core/src/main/java/io/github/eldek0/asset/group/BatteryAssets.java index 059dc84..99cc6a1 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/BatteryAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/BatteryAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class BatteryAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/CameraAssets.java b/core/src/main/java/io/github/eldek0/asset/group/CameraAssets.java index f6bafbb..4cc08a0 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/CameraAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/CameraAssets.java @@ -3,6 +3,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.utils.Array; +import io.github.eldek0.config.FrameRange; import java.util.LinkedHashMap; import java.util.Map; diff --git a/core/src/main/java/io/github/eldek0/asset/group/CustomNightAssets.java b/core/src/main/java/io/github/eldek0/asset/group/CustomNightAssets.java index 88bb287..bfdc4b8 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/CustomNightAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/CustomNightAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class CustomNightAssets extends AssetBase implements AssetBundle{ diff --git a/core/src/main/java/io/github/eldek0/asset/group/CutsceneAssets.java b/core/src/main/java/io/github/eldek0/asset/group/CutsceneAssets.java index 1bdbf1b..ed18220 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/CutsceneAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/CutsceneAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class CutsceneAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/JumpscareAssets.java b/core/src/main/java/io/github/eldek0/asset/group/JumpscareAssets.java index 4be6c29..6e76739 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/JumpscareAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/JumpscareAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class JumpscareAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/MaskAssets.java b/core/src/main/java/io/github/eldek0/asset/group/MaskAssets.java index 6c6e3da..58b6fcc 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/MaskAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/MaskAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class MaskAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/MenuAssets.java b/core/src/main/java/io/github/eldek0/asset/group/MenuAssets.java index 83205cc..551a133 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/MenuAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/MenuAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class MenuAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/MinigameAssets.java b/core/src/main/java/io/github/eldek0/asset/group/MinigameAssets.java index dd300e5..92b0cec 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/MinigameAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/MinigameAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class MinigameAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/MonitorAssets.java b/core/src/main/java/io/github/eldek0/asset/group/MonitorAssets.java index cb24613..d69fa33 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/MonitorAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/MonitorAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class MonitorAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/NumbersAssets.java b/core/src/main/java/io/github/eldek0/asset/group/NumbersAssets.java index 04fd3b6..428ba7a 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/NumbersAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/NumbersAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class NumbersAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/asset/group/OfficeAssets.java b/core/src/main/java/io/github/eldek0/asset/group/OfficeAssets.java index a7b7937..9a30cde 100644 --- a/core/src/main/java/io/github/eldek0/asset/group/OfficeAssets.java +++ b/core/src/main/java/io/github/eldek0/asset/group/OfficeAssets.java @@ -2,6 +2,7 @@ package io.github.eldek0.asset.group; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.config.FrameRange; public class OfficeAssets extends AssetBase implements AssetBundle { diff --git a/core/src/main/java/io/github/eldek0/config/CameraConfig.java b/core/src/main/java/io/github/eldek0/config/CameraConfig.java new file mode 100644 index 0000000..0c0a9b5 --- /dev/null +++ b/core/src/main/java/io/github/eldek0/config/CameraConfig.java @@ -0,0 +1,10 @@ +package io.github.eldek0.config; + +public class CameraConfig { + public int id; + public String name; + public int labelPathId; + public float buttonX; + public float buttonY; + public boolean wide; +} diff --git a/core/src/main/java/io/github/eldek0/config/CameraConfigFile.java b/core/src/main/java/io/github/eldek0/config/CameraConfigFile.java new file mode 100644 index 0000000..9c43f51 --- /dev/null +++ b/core/src/main/java/io/github/eldek0/config/CameraConfigFile.java @@ -0,0 +1,8 @@ +package io.github.eldek0.config; + +public class CameraConfigFile { + public int inCameraId; + public RangeLong wideRandomMov; + public SpritePositionData[] sprites; + public CameraConfig[] cameras; +} diff --git a/core/src/main/java/io/github/eldek0/config/CameraSpriteType.java b/core/src/main/java/io/github/eldek0/config/CameraSpriteType.java new file mode 100644 index 0000000..84a3d3a --- /dev/null +++ b/core/src/main/java/io/github/eldek0/config/CameraSpriteType.java @@ -0,0 +1,9 @@ +package io.github.eldek0.config; + +public enum CameraSpriteType { + BORDER, + MAP, + LABEL, + REC, + SIGNAL_INTERRUPTED +} diff --git a/core/src/main/java/io/github/eldek0/config/FrameRange.java b/core/src/main/java/io/github/eldek0/config/FrameRange.java new file mode 100644 index 0000000..cee1053 --- /dev/null +++ b/core/src/main/java/io/github/eldek0/config/FrameRange.java @@ -0,0 +1,6 @@ +package io.github.eldek0.config; + +public class FrameRange { + public String base; + public int start, end; +} diff --git a/core/src/main/java/io/github/eldek0/config/RangeLong.java b/core/src/main/java/io/github/eldek0/config/RangeLong.java new file mode 100644 index 0000000..356f8eb --- /dev/null +++ b/core/src/main/java/io/github/eldek0/config/RangeLong.java @@ -0,0 +1,6 @@ +package io.github.eldek0.config; + +public class RangeLong { + public long min; + public long max; +} diff --git a/core/src/main/java/io/github/eldek0/config/SpriteConfig.java b/core/src/main/java/io/github/eldek0/config/SpriteConfig.java new file mode 100644 index 0000000..3c6231b --- /dev/null +++ b/core/src/main/java/io/github/eldek0/config/SpriteConfig.java @@ -0,0 +1,11 @@ +package io.github.eldek0.config; + +public record SpriteConfig>( + T type, + float x, + float y, + boolean active, + boolean fromTop, + boolean centerX, + int zIndex +) {} diff --git a/core/src/main/java/io/github/eldek0/config/SpritePositionData.java b/core/src/main/java/io/github/eldek0/config/SpritePositionData.java new file mode 100644 index 0000000..ecd23a3 --- /dev/null +++ b/core/src/main/java/io/github/eldek0/config/SpritePositionData.java @@ -0,0 +1,11 @@ +package io.github.eldek0.config; + +public class SpritePositionData { + public String type; + public int x, y; + + public boolean active = true; + public boolean fromTop = false; + public boolean centerX = false; + public int zIndex = 0; +} diff --git a/core/src/main/java/io/github/eldek0/game/Camera.java b/core/src/main/java/io/github/eldek0/game/Camera.java index 5da1bde..3e34fc2 100644 --- a/core/src/main/java/io/github/eldek0/game/Camera.java +++ b/core/src/main/java/io/github/eldek0/game/Camera.java @@ -7,65 +7,88 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Json; import io.github.eldek0.App; +import io.github.eldek0.config.*; import io.github.eldek0.screen.GameScene; +import io.github.eldek0.ui.SpriteLayout; + +import java.util.*; import static io.github.eldek0.App.assets; -import static io.github.eldek0.asset.GameAssetManager.*; public class Camera { - private static final int CAM_COUNT = 12; private static final float CAMERA_SPEED = 5f * 60f; // px/s + private static final String CONFIG = "data/config/cameras.json"; - private final float[][] BTN_POS = new float[][] { - { 620 - 25, 621 - 125 }, { 735 - 25, 621 - 125 }, - { 620 - 25, 556 - 125 }, { 735 - 25, 556 - 125 }, - { 600 - 15, 700 - 105 }, { 710 - 15, 700 - 105 }, - { 769 - 35, 482 - 115 }, { 612 - 37, 471 - 115 }, - { 920 - 25, 441 - 110 }, { 830 - 10, 570 - 115 }, - { 954 - 25, 515 - 110 }, { 945 - 25, 608 - 105 } - };; + private CameraConfig[] cameraConfigs; /** 1-based room index currently shown on the monitor. */ - private int inCameraRoom = 10; + private int inCameraRoom; - private final Rectangle[] buttonScreenRects = new Rectangle[CAM_COUNT]; + private Rectangle[] buttonScreenRects; - // Wide-camera panning (indices 6-11 → rooms 7-12) - private final float[] camerasXPosition = new float[CAM_COUNT]; - private final int[] wideCameraMovDirection = new int[CAM_COUNT]; - private final long[] timerCheckpoints = new long[CAM_COUNT]; - private final long[] timerWaitTimeMs = new long[CAM_COUNT]; + // Wide-camera panning + private float[] camerasXPosition; + private int[] wideCameraMovDirection; + private long[] timerCheckpoints; + private long[] timerWaitTimeMs; + private RangeLong wideRandomMov; - private final boolean[] occupiedCamera = new boolean[CAM_COUNT]; + private boolean[] occupiedCamera; private float recBlinkTimer = 0f; private boolean recVisible = true; + SpriteLayout layout; + private GameScene gameScene; public Camera(GameScene gameScene) { this.gameScene = gameScene; + + loadCameraConfig(); + initializeArrays(); + java.util.Random rng = new java.util.Random(); - for (int i = 0; i < CAM_COUNT; i++) { - timerWaitTimeMs[i] = 5000 + (long) rng.nextInt(2001); // [5000,7000] ms + for (int i = 0; i < cameraConfigs.length; i++) { + timerWaitTimeMs[i] = wideRandomMov.min + (long) rng.nextInt((int) (wideRandomMov.max - wideRandomMov.min)); } + this.initButtonScreenRects(); } + private void initializeArrays() { + int camCount = cameraConfigs.length; + + buttonScreenRects = new Rectangle[camCount]; + camerasXPosition = new float[camCount]; + wideCameraMovDirection = new int[camCount]; + timerCheckpoints = new long[camCount]; + timerWaitTimeMs = new long[camCount]; + occupiedCamera = new boolean[camCount]; + } + private void initButtonScreenRects(){ Texture btnUnsel = assets.cameras.roomButtonUnselected; - for (int i = 0; i < CAM_COUNT; i++) { - float[] btnPos = BTN_POS[i]; - float worldY = App.SCREEN_HEIGHT - btnPos[1] - btnUnsel.getHeight(); - buttonScreenRects[i] = new Rectangle(btnPos[0], worldY, btnUnsel.getWidth() , btnUnsel.getHeight()); + for (int i = 0; i < cameraConfigs.length; i++) { + CameraConfig cameraConfig = cameraConfigs[i]; + + float worldY = App.SCREEN_HEIGHT - cameraConfig.buttonY - btnUnsel.getHeight(); + buttonScreenRects[i] = new Rectangle( + cameraConfig.buttonX, + worldY, + btnUnsel.getWidth(), + btnUnsel.getHeight()); } } public void update(float delta) { - for (int i = 6; i < CAM_COUNT; i++) { - updateCameraTimer(i, delta); + for (int i = 0; i < cameraConfigs.length; i++) { + if (cameraConfigs[i].wide) { + updateCameraTimer(i, delta); + } } recBlinkTimer += delta; @@ -73,6 +96,7 @@ public class Camera { recBlinkTimer -= 1f; recVisible = !recVisible; } + this.onTouchDown(); } @@ -83,7 +107,7 @@ public class Camera { public void onTouchDown() { Vector2 position = App.convertPosToWorldPos(new Vector2(Gdx.input.getX(), Gdx.input.getY())); - for (int i = 0; i < CAM_COUNT; i++) { + for (int i = 0; i < this.cameraConfigs.length; i++) { if (buttonScreenRects[i].contains(position)) { if (Gdx.input.isButtonJustPressed(Input.Buttons.LEFT)) { inCameraRoom = i + 1; @@ -105,57 +129,71 @@ public class Camera { } } + private void loadCameraConfig(){ + Json json = new Json(); + String raw = Gdx.files.internal(CONFIG).readString(); + CameraConfigFile configFile = json.fromJson(CameraConfigFile.class, raw); + this.inCameraRoom = configFile.inCameraId; + this.cameraConfigs = configFile.cameras; + this.wideRandomMov = configFile.wideRandomMov; + + this.layout = new SpriteLayout<>( + configFile.sprites, // 👈 directo + CameraSpriteType::valueOf + ); + + } + private Texture getFrame(int room, int index) { - Texture[] textures = switch (room) { - case 1 -> assets.cameras.getLocationFrames("PartyRoom1"); - case 2 -> assets.cameras.getLocationFrames("PartyRoom2"); - case 3 -> assets.cameras.getLocationFrames("PartyRoom3"); - case 4 -> assets.cameras.getLocationFrames("PartyRoom4"); - case 5 -> assets.cameras.getLocationFrames("LeftAirVent"); - case 6 -> assets.cameras.getLocationFrames("RightAirVent"); - case 7 -> assets.cameras.getLocationFrames("MainHall"); - case 8 -> assets.cameras.getLocationFrames("PartsnService"); - case 9 -> assets.cameras.getLocationFrames("ShowStage"); - case 10 -> assets.cameras.getLocationFrames("GameArea"); - case 11 -> assets.cameras.getLocationFrames("PrizeCorner"); - case 12 -> assets.cameras.getLocationFrames("KidsCove"); - default -> null; - }; - assert textures != null; + CameraConfig config = cameraConfigs[room - 1]; + Texture[] textures = assets.cameras.getLocationFrames(config.name); + + if (textures == null || index < 0 || index >= textures.length) { + return null; + } + return textures[index]; } + private Texture getRoomLabel(int room) { + CameraConfig config = cameraConfigs[room - 1]; + return assets.cameras.locationLabels.get(config.name); + } + public void renderUI(SpriteBatch batch) { - if (!gameScene.hud.isInsideCamera()) {return;} + if (!gameScene.hud.isInsideCamera()) return; - // Border overlay - Texture border = assets.cameras.borderline; - batch.draw(border, 0, 0); + for (SpriteConfig config : layout.getSortedSprites()) { + if (!config.active()) continue; - // Map - Texture map = assets.cameras.map; - batch.draw(map, 550, App.SCREEN_HEIGHT - 310 - map.getHeight()); + Texture texture = getTextureForSprite(config.type()); + if (config.type() == CameraSpriteType.LABEL) { + texture = getRoomLabel(inCameraRoom); + } - // Room label - Texture label = getRoomLabel(inCameraRoom); - if (label != null) { - batch.draw(label, 550, App.SCREEN_HEIGHT - 280 - label.getHeight()); + if (texture == null) continue; + + if (config.type() == CameraSpriteType.REC && !recVisible) continue; + if (config.type() == CameraSpriteType.SIGNAL_INTERRUPTED && !occupiedCamera[inCameraRoom - 1]) continue; + + batch.draw( + texture, + layout.resolveX(config, texture), + layout.resolveY(config, texture) + ); } drawCameraButtons(batch); + } - // REC sprite - if (recVisible) { - Texture rec = assets.cameras.recordSprite; - batch.draw(rec, 40, App.SCREEN_HEIGHT - 40 - rec.getHeight()); - } - - // Signal interrupted banner - if (occupiedCamera[inCameraRoom - 1]) { - Texture sig = assets.cameras.signalInterrupted; - float sx = Gdx.graphics.getWidth() / 2f - sig.getWidth() / 2f; - batch.draw(sig, sx, App.SCREEN_HEIGHT - 80 - sig.getHeight()); - } + private Texture getTextureForSprite(CameraSpriteType type) { + return switch (type) { + case BORDER -> assets.cameras.borderline; + case MAP -> assets.cameras.map; + case REC -> assets.cameras.recordSprite; + case SIGNAL_INTERRUPTED -> assets.cameras.signalInterrupted; + case LABEL -> null; + }; } public void renderHitboxes(ShapeRenderer shapeRenderer) { @@ -167,40 +205,19 @@ public class Camera { private void drawCameraButtons(SpriteBatch batch) { Texture btnUnsel = assets.cameras.roomButtonUnselected; - Texture btnSel = assets.cameras.roomButtonSelected; + Texture btnSel = assets.cameras.roomButtonSelected; - for (int i = 0; i < CAM_COUNT; i++) { - Texture btn = (i + 1 == inCameraRoom) ? btnSel : btnUnsel; + for (CameraConfig config : cameraConfigs) { + Texture btn = (config.id == inCameraRoom) ? btnSel : btnUnsel; - float pyX = BTN_POS[i][0]; - float pyY = BTN_POS[i][1]; + float worldY = App.SCREEN_HEIGHT - config.buttonY - btnUnsel.getHeight(); + batch.draw(btn, config.buttonX, worldY); - float worldY = App.SCREEN_HEIGHT - pyY - btnUnsel.getHeight(); - batch.draw(btn, pyX, worldY); - - Texture lbl = assets.cameras.roomLabels[i]; - batch.draw(lbl, pyX + 5, worldY + 7); + Texture lbl = assets.cameras.roomLabels[config.labelPathId]; + batch.draw(lbl, config.buttonX + 5, worldY + 7); } } - private Texture getRoomLabel(int room) { - return switch (room) { - case 1 -> assets.cameras.getLocationLabel("PartyRoom1/label.png"); - case 2 -> assets.cameras.getLocationLabel("PartyRoom2/label.png"); - case 3 -> assets.cameras.getLocationLabel("PartyRoom3/label.png"); - case 4 -> assets.cameras.getLocationLabel("PartyRoom4/label.png"); - case 5 -> assets.cameras.getLocationLabel("LeftAirVent/label.png"); - case 6 -> assets.cameras.getLocationLabel("RightAirVent/label.png"); - case 7 -> assets.cameras.getLocationLabel("MainHall/label.png"); - case 8 -> assets.cameras.getLocationLabel("PartsnService/label.png"); - case 9 -> assets.cameras.getLocationLabel("ShowStage/label.png"); - case 10 -> assets.cameras.getLocationLabel("GameArea/label.png"); - case 11 -> assets.cameras.getLocationLabel("PrizeCorner/label.png"); - case 12 -> assets.cameras.getLocationLabel("KidsCove/label.png"); - default -> null; - }; - } - private void updateCameraTimer(int index, float delta) { if (index < 6) return; diff --git a/core/src/main/java/io/github/eldek0/ui/SpriteLayout.java b/core/src/main/java/io/github/eldek0/ui/SpriteLayout.java new file mode 100644 index 0000000..2f08a0c --- /dev/null +++ b/core/src/main/java/io/github/eldek0/ui/SpriteLayout.java @@ -0,0 +1,85 @@ +package io.github.eldek0.ui; + +import com.badlogic.gdx.graphics.Texture; +import io.github.eldek0.App; +import io.github.eldek0.config.SpriteConfig; +import io.github.eldek0.config.SpritePositionData; + +import java.util.*; +import java.util.function.Function; + +public class SpriteLayout> { + + private final Map spritesMap; + private final SpriteConfig[] sortedSprites; + + public SpriteLayout(SpritePositionData[] rawSprites, Function enumResolver) { + if (rawSprites == null) { + throw new IllegalArgumentException("rawSprites no puede ser null"); + } + if (enumResolver == null) { + throw new IllegalArgumentException("enumResolver no puede ser null"); + } + + List parsed = new ArrayList<>(); + + for (SpritePositionData raw : rawSprites) { + if (raw == null || raw.type == null) continue; + + T enumType = enumResolver.apply(raw.type); + + SpriteConfig config = new SpriteConfig( + enumType, + raw.x, + raw.y, + raw.active, + raw.fromTop, + raw.centerX, + raw.zIndex + ); + + parsed.add(config); + } + + Map> temp = new HashMap<>(); + for (SpriteConfig sprite : parsed) { + temp.computeIfAbsent((T) sprite.type(), k -> new ArrayList<>()).add(sprite); + } + + Map builtMap = new HashMap<>(); + for (Map.Entry> entry : temp.entrySet()) { + builtMap.put(entry.getKey(), entry.getValue().toArray(new SpriteConfig[0])); + } + this.spritesMap = builtMap; + + SpriteConfig[] ordered = parsed.toArray(new SpriteConfig[0]); + Arrays.sort(ordered, Comparator.comparingInt(SpriteConfig::zIndex)); + this.sortedSprites = ordered; + } + + public SpriteConfig[] getSprites(T type) { + return spritesMap.getOrDefault(type, new SpriteConfig[0]); + } + + public SpriteConfig[] getSortedSprites() { + return sortedSprites; + } + + public float resolveX(SpriteConfig config, Texture texture) { + float x = config.x(); + + if (config.centerX()) { + x += App.SCREEN_WIDTH / 2f - texture.getWidth() / 2f; + } + + return x; + } + + public float resolveY(SpriteConfig config, Texture texture) { + if (config.fromTop()) { + return App.SCREEN_HEIGHT - config.y() - texture.getHeight(); + } + + return config.y(); + } +}