toy_freddy basic movement and camera adjust to the animatronics on it

This commit is contained in:
2026-04-01 15:09:34 -03:00
parent f40831c3c2
commit 8e85745222
31 changed files with 674 additions and 80 deletions

View File

@@ -1,5 +1,5 @@
{ {
"animatronics": [ "animatronics": [
"freddy" "toy_freddy"
] ]
} }

View File

@@ -1,6 +1,6 @@
{ {
"id": "freddy", "id": "toy_freddy",
"displayName": "Freddy Fazbear", "displayName": "Freddy Fazbear (Toy)",
"inRoom": 9, "inRoom": 9,
"restRoom": 9, "restRoom": 9,
@@ -9,14 +9,14 @@
"movement": { "movement": {
"type": "SEQUENTIAL", "type": "SEQUENTIAL",
"path": [9], "path": [9, 10, -2, -3],
"moveIntervalSeconds": 30, "moveIntervalSeconds": 12,
"aiSpeedMultiplier": true "aiSpeedMultiplier": true
}, },
"attackType": { "attackType": {
"kind": "LIGHT", "kind": "IN_OFFICE",
"lightLevel": 3 "officeSprite": 3
}, },
"jumpscare": { "jumpscare": {

View File

@@ -4,18 +4,18 @@
"min": 5000, "min": 5000,
"max": 7000 "max": 7000
}, },
"lightHitbox": {
"x": 100,
"y": 200,
"width": 400,
"height": 350
},
"sprites": [ "sprites": [
{ "type": "BORDER", "x": 0, "y": 0, "zIndex": 0 }, { "type": "BORDER", "group": "cameras", "key": "borderline", "frame": 0, "x": 0, "y": 0, "zIndex": 0 },
{ "type": "MAP", "group": "cameras", "key": "map", "frame": 0, "x": 550, "y": 310, "fromTop": true, "zIndex": 1 },
{ "type": "MAP", "x": 550, "y": 310, "fromTop": true, "zIndex": 1 },
{ "type": "LABEL", "x": 550, "y": 280, "fromTop": true, "zIndex": 2 }, { "type": "LABEL", "x": 550, "y": 280, "fromTop": true, "zIndex": 2 },
{ "type": "REC", "group": "cameras", "key": "recordSprite", "frame": 0, "x": 40, "y": 40, "fromTop": true, "zIndex": 3 },
{ "type": "REC", "x": 40, "y": 40, "fromTop": true, "zIndex": 3 }, { "type": "SIGNAL_INTERRUPTED", "group": "cameras", "key": "signalInterrupted", "frame": 0, "x": 0, "y": 80, "fromTop": true, "centerX": true, "zIndex": 10 }
{ "type": "REC", "x": 90, "y": 130, "fromTop": true, "zIndex": 3 },
{ "type": "SIGNAL_INTERRUPTED", "x": 0, "y": 80, "fromTop": true, "centerX": true, "zIndex": 10 }
], ],
"cameras": [ "cameras": [
{ {
@@ -24,7 +24,12 @@
"labelPathId": 0, "labelPathId": 0,
"buttonX": 595, "buttonX": 595,
"buttonY": 496, "buttonY": 496,
"wide": false "wide": false,
"variants": [
{ "animatronics": ["toy_chica"], "indexOff": 0, "indexOn": 3 },
{ "animatronics": ["withered_bonnie"], "indexOff": 0, "indexOn": 2 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 2, "id": 2,
@@ -32,7 +37,12 @@
"labelPathId": 1, "labelPathId": 1,
"buttonX": 710, "buttonX": 710,
"buttonY": 496, "buttonY": 496,
"wide": false "wide": false,
"variants": [
{ "animatronics": ["toy_bonnie"], "indexOff": 0, "indexOn": 2 },
{ "animatronics": ["withered_chica"], "indexOff": 3, "indexOn": 4 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 3, "id": 3,
@@ -40,7 +50,12 @@
"labelPathId": 2, "labelPathId": 2,
"buttonX": 595, "buttonX": 595,
"buttonY": 431, "buttonY": 431,
"wide": false "wide": false,
"variants": [
{ "animatronics": ["toy_bonnie"], "indexOff": 0, "indexOn": 2 },
{ "animatronics": ["withered_freddy"], "indexOff": 3, "indexOn": 4 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 4, "id": 4,
@@ -48,7 +63,13 @@
"labelPathId": 3, "labelPathId": 3,
"buttonX": 710, "buttonX": 710,
"buttonY": 431, "buttonY": 431,
"wide": false "wide": false,
"variants": [
{ "animatronics": ["toy_bonnie"], "indexOff": 2, "indexOn": 3 },
{ "animatronics": ["toy_chica"], "indexOff": 0, "indexOn": 4 },
{ "animatronics": ["withered_chica"], "indexOff": 0, "indexOn": 5 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 5, "id": 5,
@@ -56,7 +77,14 @@
"labelPathId": 4, "labelPathId": 4,
"buttonX": 585, "buttonX": 585,
"buttonY": 595, "buttonY": 595,
"wide": false "wide": false,
"variants": [
{ "animatronics": ["toy_chica"], "indexOff": 0, "indexOn": 4 },
{ "animatronics": ["baloon_boy"], "indexOff": 0, "indexOn": 3 },
{ "animatronics": ["withered_bonnie"], "indexOff": 0, "indexOn": 2 },
{ "animatronics": ["endo"], "indexOff": 0, "indexOn": 5 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 6, "id": 6,
@@ -64,7 +92,13 @@
"labelPathId": 5, "labelPathId": 5,
"buttonX": 695, "buttonX": 695,
"buttonY": 595, "buttonY": 595,
"wide": false "wide": false,
"variants": [
{ "animatronics": ["toy_bonnie"], "indexOff": 0, "indexOn": 2 },
{ "animatronics": ["withered_chica"], "indexOff": 0, "indexOn": 3 },
{ "animatronics": ["mangle"], "indexOff": 0, "indexOn": 4 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 7, "id": 7,
@@ -72,7 +106,13 @@
"labelPathId": 6, "labelPathId": 6,
"buttonX": 734, "buttonX": 734,
"buttonY": 367, "buttonY": 367,
"wide": true "wide": true,
"variants": [
{ "animatronics": ["toy_chica"], "indexOff": 4, "indexOn": 5 },
{ "animatronics": ["withered_freddy"], "indexOff": 0, "indexOn": 3 },
{ "animatronics": ["withered_bonnie"], "indexOff": 0, "indexOn": 2 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 8, "id": 8,
@@ -80,7 +120,16 @@
"labelPathId": 7, "labelPathId": 7,
"buttonX": 575, "buttonX": 575,
"buttonY": 356, "buttonY": 356,
"wide": true "wide": true,
"variants": [
{ "animatronics": ["withered_freddy", "withered_bonnie", "withered_chica"], "indexOff": 0, "indexOn": 1 },
{ "animatronics": ["withered_freddy", "withered_chica"], "indexOff": 0, "indexOn": 2 },
{ "animatronics": ["withered_freddy"], "indexOff": 0, "indexOn": 3 },
{ "animatronics": ["foxy"], "indexOff": 0, "indexOn": 4 },
{ "animatronics": ["TODO"], "condition": "ENDO_1987", "indexOff": 0, "indexOn": 6 },
{ "animatronics": ["TODO"], "condition": "SHADOW_FREDDY", "indexOff": 0, "indexOn": 5 },
{ "animatronics": [], "indexOff": 0, "indexOn": 5 }
]
}, },
{ {
"id": 9, "id": 9,
@@ -88,7 +137,13 @@
"labelPathId": 8, "labelPathId": 8,
"buttonX": 895, "buttonX": 895,
"buttonY": 331, "buttonY": 331,
"wide": true "wide": true,
"variants": [
{ "animatronics": ["toy_bonnie", "toy_freddy", "toy_chica"], "indexOff": 0, "indexOn": 1 },
{ "animatronics": ["toy_freddy", "toy_chica"], "indexOff": 2, "indexOn": 3 },
{ "animatronics": ["toy_freddy"], "indexOff": 4, "indexOn": 5 },
{ "animatronics": [], "indexOff": 6, "indexOn": -1 }
]
}, },
{ {
"id": 10, "id": 10,
@@ -96,7 +151,13 @@
"labelPathId": 9, "labelPathId": 9,
"buttonX": 820, "buttonX": 820,
"buttonY": 455, "buttonY": 455,
"wide": true "wide": true,
"variants": [
{ "animatronics": ["toy_freddy", "baloon_boy"], "indexOff": 0, "indexOn": 4 },
{ "animatronics": ["toy_freddy"], "indexOff": 2, "indexOn": 5 },
{ "animatronics": ["baloon_boy"], "indexOff": 0, "indexOn": 1 },
{ "animatronics": [], "indexOff": 2, "indexOn": 3 }
]
}, },
{ {
"id": 11, "id": 11,
@@ -104,7 +165,15 @@
"labelPathId": 10, "labelPathId": 10,
"buttonX": 929, "buttonX": 929,
"buttonY": 405, "buttonY": 405,
"wide": true "wide": true,
"variants": [
{ "animatronics": ["puppet"], "indexOff": 0, "indexOn": 1 },
{ "animatronics": ["puppet", "TODO"], "condition": "PUPPET_POS_1_TIMEOUT", "indexOff": 0, "indexOn": 2 },
{ "animatronics": ["puppet", "TODO"], "condition": "PUPPET_POS_2_TIMEOUT", "indexOff": 0, "indexOn": 3 },
{ "animatronics": ["puppet", "TODO"], "condition": "PUPPET_POS_3_TIMEOUT", "indexOff": 0, "indexOn": 4 },
{ "animatronics": ["endo"], "indexOff": 0, "indexOn": 5 },
{ "animatronics": [], "indexOff": 0, "indexOn": 1 }
]
}, },
{ {
"id": 12, "id": 12,
@@ -112,15 +181,11 @@
"labelPathId": 11, "labelPathId": 11,
"buttonX": 920, "buttonX": 920,
"buttonY": 503, "buttonY": 503,
"wide": true "wide": true,
}, "variants": [
{ { "animatronics": ["mangle"], "indexOff": 0, "indexOn": 2 },
"id": 13, { "animatronics": [], "indexOff": 0, "indexOn": 1 }
"name": "ShowStage", ]
"labelPathId": 1,
"buttonX": 120,
"buttonY": 503,
"wide": true
} }
] ]
} }

View File

@@ -30,7 +30,7 @@
"endoAnim": { "base": "sprites/minigames/SAVE THEM/", "start": 25, "end": 26 } "endoAnim": { "base": "sprites/minigames/SAVE THEM/", "start": 25, "end": 26 }
}, },
"foxyGoGo": { "foxyGoGo": {
"courtain": "sprites/minigames/Go! Go! Go!/4.png", "curtain": "sprites/minigames/Go! Go! Go!/4.png",
"sadChild": "sprites/minigames/Go! Go! Go!/20.png", "sadChild": "sprites/minigames/Go! Go! Go!/20.png",
"happyChild": "sprites/minigames/Go! Go! Go!/21.png", "happyChild": "sprites/minigames/Go! Go! Go!/21.png",
"arrow": "sprites/minigames/Go! Go! Go!/22.png", "arrow": "sprites/minigames/Go! Go! Go!/22.png",

View File

@@ -15,7 +15,7 @@
"balloonGirl": "sprites/office/inside/8.png", "balloonGirl": "sprites/office/inside/8.png",
"dwarf": "sprites/office/inside/DWARF.png", "dwarf": "sprites/office/inside/DWARF.png",
"plastic": "sprites/office/inside/10.png", "plastic": "sprites/office/inside/10.png",
"bunny": "sprites/office/inside/3.png", "bonnie": "sprites/office/inside/3.png",
"goldenFreddy": "sprites/office/inside/6.png", "goldenFreddy": "sprites/office/inside/6.png",
"mangle": "sprites/office/inside/7.png", "mangle": "sprites/office/inside/7.png",
"balloonBoy": "sprites/office/inside/5.png" "balloonBoy": "sprites/office/inside/5.png"

View File

@@ -3,10 +3,14 @@ package io.github.eldek0.asset;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.Json;
import io.github.eldek0.asset.group.*; import io.github.eldek0.asset.group.*;
import java.util.LinkedHashMap;
import java.util.Map;
public class GameAssetManager { public class GameAssetManager {
private static final String DATA = "data/sprites/"; private static final String DATA = "data/sprites/";
@@ -40,6 +44,8 @@ public class GameAssetManager {
private MinigameAssets.Data minigameData; private MinigameAssets.Data minigameData;
private MenuAssets.Data menuData; private MenuAssets.Data menuData;
private Map<String, AssetBundle<?>> groups;
// ========================================================= // =========================================================
// LOAD ENTRY POINTS // LOAD ENTRY POINTS
// ========================================================= // =========================================================
@@ -90,6 +96,40 @@ public class GameAssetManager {
minigames = new MinigameAssets(); minigames.queue(manager, minigameData); minigames = new MinigameAssets(); minigames.queue(manager, minigameData);
} }
private void initGroups() {
groups = new LinkedHashMap<>();
groups.put("office", office);
groups.put("monitor", monitor);
groups.put("mask", mask);
groups.put("cameras", cameras);
groups.put("battery", battery);
groups.put("numbers", numbers);
groups.put("customNight", customNight);
groups.put("jumpscares", jumpscares);
groups.put("cutscenes", cutscenes);
groups.put("minigames", minigames);
groups.put("menu", menu);
}
/**
* Returns a texture by passing a group a key and a frame
* **/
public Texture resolve(String group, String key, int frame) {
if (group.equals("null")){return null;}
AssetBundle<?> bundle = groups.get(group);
if (bundle == null) throw new IllegalArgumentException(
"Unknown asset group: '" + group + "'. Valid groups: " + groups.keySet()
);
return bundle.resolve(key, frame);
}
/**
* Returns its first texture by passing a group and a key
*/
public Texture resolve(String group, String key) {
return resolve(group, key, 0);
}
// ========================================================= // =========================================================
// GAME LOOP — call in render() // GAME LOOP — call in render()
// ========================================================= // =========================================================
@@ -113,7 +153,7 @@ public class GameAssetManager {
private void fetchAll() { private void fetchAll() {
if (fetched) return; if (fetched) return;
fetched = true; fetched = true;
this.initGroups();
if (menuData != null) menu.fetch(manager, menuData); if (menuData != null) menu.fetch(manager, menuData);
if (monitorData != null) monitor.fetch(manager, monitorData); if (monitorData != null) monitor.fetch(manager, monitorData);
if (officeData != null) office.fetch(manager, officeData); if (officeData != null) office.fetch(manager, officeData);

View File

@@ -1,6 +1,7 @@
package io.github.eldek0.asset.group; package io.github.eldek0.asset.group;
import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Texture;
/** /**
* Common contract for all typed asset groups. * Common contract for all typed asset groups.
@@ -41,4 +42,9 @@ public interface AssetBundle<D> {
* Useful for fine-grained loading checks. * Useful for fine-grained loading checks.
*/ */
boolean isLoaded(AssetManager manager, D data); boolean isLoaded(AssetManager manager, D data);
/**
* Use a texture called from a json (string)
* **/
Texture resolve(String key, int frame);
} }

View File

@@ -4,6 +4,9 @@ import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
import io.github.eldek0.config.FrameRange; import io.github.eldek0.config.FrameRange;
import java.util.LinkedHashMap;
import java.util.Map;
public class BatteryAssets extends AssetBase implements AssetBundle<BatteryAssets.Data> { public class BatteryAssets extends AssetBase implements AssetBundle<BatteryAssets.Data> {
public BatteryAssets(){ public BatteryAssets(){
@@ -45,4 +48,15 @@ public class BatteryAssets extends AssetBase implements AssetBundle<BatteryAsset
if (!manager.isLoaded(data.stages.base + i + ".png")) return false; if (!manager.isLoaded(data.stages.base + i + ".png")) return false;
return true; return true;
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
case "flashlightLabel" -> flashlightLabel;
case "stages" -> stages[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: [flashlightLabel, stages]"
);
};
}
} }

View File

@@ -160,6 +160,56 @@ public class CameraAssets extends AssetBase implements AssetBundle<CameraAssets.
return true; return true;
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
// Utils
case "map" -> map;
case "borderline" -> borderline;
case "recordSprite" -> recordSprite;
case "signalInterrupted" -> signalInterrupted;
// Labels
case "roomButtonUnselected" -> roomButtonUnselected;
case "roomButtonSelected" -> roomButtonSelected;
case "clicknhold" -> clicknhold;
case "musicBoxButtonOff" -> musicBoxButtonOff;
case "musicBoxButtonOn" -> musicBoxButtonOn;
case "musicBoxLabel" -> musicBoxLabel;
case "roomLabels" -> roomLabels[frame];
// Ranges
case "mangle" -> mangle[frame];
case "staticA" -> staticA[frame];
case "staticB" -> staticB[frame];
case "staticStripes" -> staticStripes[frame];
case "musicBoxTimer" -> musicBoxTimer[frame];
default -> {
// Dinamic locations: key = location name
if (locationFrames.containsKey(key))
yield locationFrames.get(key)[frame];
// Location label: key = "label:PartyRoom1" for example
if (key.startsWith("label:")) {
String locName = key.substring(6);
Texture label = locationLabels.get(locName);
if (label != null) yield label;
}
throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[map, borderline, recordSprite, signalInterrupted, " +
"roomButtonUnselected, roomButtonSelected, clicknhold, " +
"musicBoxButtonOff, musicBoxButtonOn, musicBoxLabel, roomLabels, " +
"mangle, staticA, staticB, staticStripes, musicBoxTimer] " +
"or a location name from: " + locationFrames.keySet() +
" (prefix with 'label:' for its label texture)"
);
}
};
}
public Texture[] getLocationFrames(String name) { return locationFrames.get(name); } public Texture[] getLocationFrames(String name) { return locationFrames.get(name); }
public Texture getLocationLabel(String name) { return locationLabels.get(name); } public Texture getLocationLabel(String name) { return locationLabels.get(name); }
} }

View File

@@ -84,5 +84,26 @@ public class CustomNightAssets extends AssetBase implements AssetBundle<CustomNi
&& isRangeLoaded(manager, d.rewards); && isRangeLoaded(manager, d.rewards);
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
case "title" -> title;
case "arrowRight" -> arrowRight;
case "arrowLeft" -> arrowLeft;
case "readyButton" -> readyButton;
case "arrowRight2" -> arrowRight2;
case "arrowLeft2" -> arrowLeft2;
case "levelInfo" -> levelInfo;
case "icons" -> icons[frame];
case "names" -> names[frame];
case "modes" -> modes[frame];
case "rewards" -> rewards[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[title, arrowRight, arrowLeft, readyButton, arrowRight2, arrowLeft2, levelInfo, icons, names, modes, rewards]"
);
};
}
} }

View File

@@ -65,4 +65,23 @@ public class CutsceneAssets extends AssetBase implements AssetBundle<CutsceneAss
&& isRangeLoaded(manager, d.chica) && isRangeLoaded(manager, d.chica)
&& isRangeLoaded(manager, d.bonnie); && isRangeLoaded(manager, d.bonnie);
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
case "freddy" -> freddy;
case "puppet" -> puppet;
case "background" -> background;
case "black" -> black;
case "mask" -> mask;
case "errImg" -> errImg;
case "itsMe" -> itsMe;
case "chica" -> chica[frame];
case "bonnie" -> bonnie[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[freddy, puppet, background, black, mask, errImg, itsMe, chica, bonnie]"
);
};
}
} }

View File

@@ -71,4 +71,24 @@ public class JumpscareAssets extends AssetBase implements AssetBundle<JumpscareA
&& isRangeLoaded(manager, d.mangle) && isRangeLoaded(manager, d.mangle)
&& isRangeLoaded(manager, d.goldenFreddy); && isRangeLoaded(manager, d.goldenFreddy);
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
case "puppet" -> puppet[frame];
case "toyBonnie" -> toyBonnie[frame];
case "toyChica" -> toyChica[frame];
case "toyFreddy" -> toyFreddy[frame];
case "witheredFreddy" -> witheredFreddy[frame];
case "witheredBonnie" -> witheredBonnie[frame];
case "witheredChica" -> witheredChica[frame];
case "foxy" -> foxy[frame];
case "mangle" -> mangle[frame];
case "goldenFreddy" -> goldenFreddy[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[puppet, toyBonnie, toyChica, toyFreddy, witheredFreddy, witheredBonnie, witheredChica, foxy, mangle, goldenFreddy]"
);
};
}
} }

View File

@@ -41,4 +41,15 @@ public class MaskAssets extends AssetBase implements AssetBundle<MaskAssets.Data
if (!manager.isLoaded(data.sprites.base + i + ".png")) return false; if (!manager.isLoaded(data.sprites.base + i + ".png")) return false;
return true; return true;
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
case "button" -> button;
case "sprites" -> sprites[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: [button, sprites]"
);
};
}
} }

View File

@@ -187,4 +187,62 @@ public class MenuAssets extends AssetBase implements AssetBundle<MenuAssets.Data
&& isRangeLoaded(manager, d.ranges.confettiYellow) && isRangeLoaded(manager, d.ranges.confettiYellow)
&& isRangeLoaded(manager, d.ranges.confettiPink); && isRangeLoaded(manager, d.ranges.confettiPink);
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
// Logos
case "title" -> title;
case "scottCredits" -> scottCredits;
case "selScottCredits" -> selScottCredits;
case "optionSelected" -> optionSelected;
case "newGame" -> newGame;
case "continueGame" -> continueGame;
case "deleteData" -> deleteData;
case "version" -> version;
case "nightLabel2" -> nightLabel2;
case "escToReturn" -> escToReturn;
case "extras" -> extras;
case "animatronics" -> animatronics;
case "jumpscares" -> jumpscares;
case "minigames" -> minigames;
case "selSquare" -> selSquare;
case "realTimeButton" -> realTimeButton;
case "loadingIcon" -> loadingIcon;
// Nights
case "nightSixOption" -> nightSixOption;
case "customNightOption" -> customNightOption;
case "lostScreen" -> lostScreen;
case "gameOver" -> gameOver;
case "realTimeNight" -> realTimeNight;
case "night12am" -> night12am[frame];
// Paychecks
case "newspaper" -> newspaper;
case "nightFivePaycheck" -> nightFivePaycheck;
case "nightSixPaycheck" -> nightSixPaycheck;
case "nightSevenPaycheck" -> nightSevenPaycheck;
// Misc
case "star" -> star;
case "blueStar" -> blueStar;
case "background" -> background[frame];
// Confetti
case "confettiBlue" -> confettiBlue[frame];
case "confettiGreen" -> confettiGreen[frame];
case "confettiYellow" -> confettiYellow[frame];
case "confettiPink" -> confettiPink[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[title, scottCredits, selScottCredits, optionSelected, newGame, continueGame, deleteData, " +
"version, nightLabel2, escToReturn, extras, animatronics, jumpscares, minigames, selSquare, " +
"realTimeButton, loadingIcon, nightSixOption, customNightOption, lostScreen, gameOver, " +
"realTimeNight, night12am, newspaper, nightFivePaycheck, nightSixPaycheck, nightSevenPaycheck, " +
"star, blueStar, background, confettiBlue, confettiGreen, confettiYellow, confettiPink]"
);
};
}
} }

View File

@@ -23,7 +23,7 @@ public class MinigameAssets extends AssetBase implements AssetBundle<MinigameAss
public FrameRange freddyWalking, endoAnim; public FrameRange freddyWalking, endoAnim;
} }
public static class FoxyGoGo { public static class FoxyGoGo {
public String courtain, sadChild, happyChild, arrow, purpleGuy; public String curtain, sadChild, happyChild, arrow, purpleGuy;
public String getReady, go, hurray; public String getReady, go, hurray;
public FrameRange foxyAnim, confetti; public FrameRange foxyAnim, confetti;
} }
@@ -43,7 +43,7 @@ public class MinigameAssets extends AssetBase implements AssetBundle<MinigameAss
public Texture[] freddyWalking, endoAnim; public Texture[] freddyWalking, endoAnim;
// Foxy Go Go Go // Foxy Go Go Go
public Texture courtain, sadChild, happyChild, arrow, purpleGuy; public Texture curtain, sadChild, happyChild, arrow, purpleGuy;
public Texture getReady, go, hurray; public Texture getReady, go, hurray;
public Texture[] foxyAnim, confetti; public Texture[] foxyAnim, confetti;
@@ -76,7 +76,7 @@ public class MinigameAssets extends AssetBase implements AssetBundle<MinigameAss
queueRange(manager, s.endoAnim); queueRange(manager, s.endoAnim);
Data.FoxyGoGo f = d.foxyGoGo; Data.FoxyGoGo f = d.foxyGoGo;
manager.load(f.courtain, Texture.class); manager.load(f.sadChild, Texture.class); manager.load(f.curtain, Texture.class); manager.load(f.sadChild, Texture.class);
manager.load(f.happyChild, Texture.class); manager.load(f.arrow, Texture.class); manager.load(f.happyChild, Texture.class); manager.load(f.arrow, Texture.class);
manager.load(f.purpleGuy, Texture.class); manager.load(f.getReady, Texture.class); manager.load(f.purpleGuy, Texture.class); manager.load(f.getReady, Texture.class);
manager.load(f.go, Texture.class); manager.load(f.hurray, Texture.class); manager.load(f.go, Texture.class); manager.load(f.hurray, Texture.class);
@@ -122,7 +122,7 @@ public class MinigameAssets extends AssetBase implements AssetBundle<MinigameAss
endoAnim = fetchRange(manager, s.endoAnim); endoAnim = fetchRange(manager, s.endoAnim);
Data.FoxyGoGo f = d.foxyGoGo; Data.FoxyGoGo f = d.foxyGoGo;
courtain = manager.get(f.courtain, Texture.class); curtain = manager.get(f.curtain, Texture.class);
sadChild = manager.get(f.sadChild, Texture.class); sadChild = manager.get(f.sadChild, Texture.class);
happyChild = manager.get(f.happyChild, Texture.class); happyChild = manager.get(f.happyChild, Texture.class);
arrow = manager.get(f.arrow, Texture.class); arrow = manager.get(f.arrow, Texture.class);
@@ -164,7 +164,7 @@ public class MinigameAssets extends AssetBase implements AssetBundle<MinigameAss
disposeRange(manager, s.endoAnim); disposeRange(manager, s.endoAnim);
Data.FoxyGoGo f = d.foxyGoGo; Data.FoxyGoGo f = d.foxyGoGo;
manager.unload(f.courtain); manager.unload(f.sadChild); manager.unload(f.happyChild); manager.unload(f.curtain); manager.unload(f.sadChild); manager.unload(f.happyChild);
manager.unload(f.arrow); manager.unload(f.purpleGuy); manager.unload(f.getReady); manager.unload(f.arrow); manager.unload(f.purpleGuy); manager.unload(f.getReady);
manager.unload(f.go); manager.unload(f.hurray); manager.unload(f.go); manager.unload(f.hurray);
disposeRange(manager, f.foxyAnim); disposeRange(manager, f.foxyAnim);
@@ -203,7 +203,7 @@ public class MinigameAssets extends AssetBase implements AssetBundle<MinigameAss
if (!isRangeLoaded(manager, s.endoAnim)) return false; if (!isRangeLoaded(manager, s.endoAnim)) return false;
Data.FoxyGoGo f = d.foxyGoGo; Data.FoxyGoGo f = d.foxyGoGo;
if (!manager.isLoaded(f.courtain) || !manager.isLoaded(f.sadChild) ) return false; if (!manager.isLoaded(f.curtain) || !manager.isLoaded(f.sadChild) ) return false;
if (!manager.isLoaded(f.happyChild)|| !manager.isLoaded(f.arrow) ) return false; if (!manager.isLoaded(f.happyChild)|| !manager.isLoaded(f.arrow) ) return false;
if (!manager.isLoaded(f.purpleGuy) || !manager.isLoaded(f.getReady) ) return false; if (!manager.isLoaded(f.purpleGuy) || !manager.isLoaded(f.getReady) ) return false;
if (!manager.isLoaded(f.go) || !manager.isLoaded(f.hurray) ) return false; if (!manager.isLoaded(f.go) || !manager.isLoaded(f.hurray) ) return false;
@@ -220,4 +220,73 @@ public class MinigameAssets extends AssetBase implements AssetBundle<MinigameAss
&& isRangeLoaded(manager, d.rare) && isRangeLoaded(manager, d.rare)
&& isRangeLoaded(manager, d.animatronics); && isRangeLoaded(manager, d.animatronics);
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
// Give Gifts Give Life
case "puppet" -> puppet;
case "soul" -> soul;
case "gift" -> gift;
case "giveGifts" -> giveGifts;
case "giveLife" -> giveLife;
case "chicaMask" -> chicaMask;
case "fredMask" -> fredMask;
case "bonnieMask" -> bonnieMask;
case "foxyMask" -> foxyMask;
// Save Them
case "table" -> table;
case "desk" -> desk;
case "scenery" -> scenery;
case "dust" -> dust;
case "floor1" -> floor1;
case "floor2" -> floor2;
case "wasd" -> wasd;
case "suit1" -> suit1;
case "suit2" -> suit2;
case "suit3" -> suit3;
case "suitGr1" -> suitGr1;
case "suitGr2" -> suitGr2;
case "sadSoul" -> sadSoul;
case "blood" -> blood;
case "bigGift" -> bigGift;
case "freddyWalking" -> freddyWalking[frame];
case "endoAnim" -> endoAnim[frame];
// Foxy Go Go Go
case "curtain" -> curtain;
case "sadChild" -> sadChild;
case "happyChild" -> happyChild;
case "arrow" -> arrow;
case "purpleGuy" -> purpleGuy;
case "getReady" -> getReady;
case "go" -> go;
case "hurray" -> hurray;
case "foxyAnim" -> foxyAnim[frame];
case "confetti" -> confetti[frame];
// Take Cake to the Children
case "deadChild" -> deadChild;
case "car" -> car;
case "label" -> label;
case "cakeFreddy" -> cakeFreddy[frame];
case "childCrying" -> childCrying[frame];
case "child" -> child[frame];
// Misc
case "screenshots" -> screenshots[frame];
case "rare" -> rare[frame];
case "animatronics" -> animatronics[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[puppet, soul, gift, giveGifts, giveLife, chicaMask, fredMask, bonnieMask, foxyMask, " +
"table, desk, scenery, dust, floor1, floor2, wasd, suit1, suit2, suit3, suitGr1, suitGr2, sadSoul, blood, bigGift, freddyWalking, endoAnim, " +
"curtain, sadChild, happyChild, arrow, purpleGuy, getReady, go, hurray, foxyAnim, confetti, " +
"deadChild, car, label, cakeFreddy, childCrying, child, " +
"screenshots, rare, animatronics]"
);
};
}
} }

View File

@@ -41,4 +41,15 @@ public class MonitorAssets extends AssetBase implements AssetBundle<MonitorAsset
if (!manager.isLoaded(data.sprites.base + i + ".png")) return false; if (!manager.isLoaded(data.sprites.base + i + ".png")) return false;
return true; return true;
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
case "button" -> button;
case "sprites" -> sprites[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: [button, sprites]"
);
};
}
} }

View File

@@ -75,4 +75,25 @@ public class NumbersAssets extends AssetBase implements AssetBundle<NumbersAsset
&& isRangeLoaded(manager, d.fiveAnimation) && isRangeLoaded(manager, d.fiveAnimation)
&& isRangeLoaded(manager, d.sixAnimation); && isRangeLoaded(manager, d.sixAnimation);
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
case "dots" -> dots;
case "nightLabel" -> nightLabel;
case "amLabel" -> amLabel;
case "bigAm" -> bigAm;
case "medium" -> medium[frame];
case "small" -> small[frame];
case "big" -> big[frame];
case "medium2" -> medium2[frame];
case "small2" -> small2[frame];
case "fiveAnimation" -> fiveAnimation[frame];
case "sixAnimation" -> sixAnimation[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[dots, nightLabel, amLabel, bigAm, medium, small, big, medium2, small2, fiveAnimation, sixAnimation]"
);
};
}
} }

View File

@@ -18,7 +18,7 @@ public class OfficeAssets extends AssetBase implements AssetBundle<OfficeAssets.
public String rightOff, rightOn, leftOff, leftOn; public String rightOff, rightOn, leftOff, leftOn;
} }
public static class EasterEggs { public static class EasterEggs {
public String balloonGirl, dwarf, plastic, bunny, goldenFreddy, mangle, balloonBoy; public String balloonGirl, dwarf, plastic, bonnie, goldenFreddy, mangle, balloonBoy;
} }
public static class Ranges { public static class Ranges {
public FrameRange inside, hallway, rightVents, leftVents, desk, warnBig, warnSmall; public FrameRange inside, hallway, rightVents, leftVents, desk, warnBig, warnSmall;
@@ -29,7 +29,7 @@ public class OfficeAssets extends AssetBase implements AssetBundle<OfficeAssets.
public Texture rightVentButtonOff, rightVentButtonOn; public Texture rightVentButtonOff, rightVentButtonOn;
public Texture leftVentButtonOff, leftVentButtonOn; public Texture leftVentButtonOff, leftVentButtonOn;
public Texture telephoneMute, ctrlAdv; public Texture telephoneMute, ctrlAdv;
public Texture balloonGirl, dwarf, plastic, bunny, goldenFreddy, mangle, balloonBoy; public Texture balloonGirl, dwarf, plastic, bonnie, goldenFreddy, mangle, balloonBoy;
public Texture[] inside, hallway, rightVents, leftVents, desk, warnBig, warnSmall; public Texture[] inside, hallway, rightVents, leftVents, desk, warnBig, warnSmall;
@@ -47,7 +47,7 @@ public class OfficeAssets extends AssetBase implements AssetBundle<OfficeAssets.
manager.load(d.easterEggs.balloonGirl, Texture.class); manager.load(d.easterEggs.balloonGirl, Texture.class);
manager.load(d.easterEggs.dwarf, Texture.class); manager.load(d.easterEggs.dwarf, Texture.class);
manager.load(d.easterEggs.plastic, Texture.class); manager.load(d.easterEggs.plastic, Texture.class);
manager.load(d.easterEggs.bunny, Texture.class); manager.load(d.easterEggs.bonnie, Texture.class);
manager.load(d.easterEggs.goldenFreddy, Texture.class); manager.load(d.easterEggs.goldenFreddy, Texture.class);
manager.load(d.easterEggs.mangle, Texture.class); manager.load(d.easterEggs.mangle, Texture.class);
manager.load(d.easterEggs.balloonBoy, Texture.class); manager.load(d.easterEggs.balloonBoy, Texture.class);
@@ -75,7 +75,7 @@ public class OfficeAssets extends AssetBase implements AssetBundle<OfficeAssets.
balloonGirl = manager.get(d.easterEggs.balloonGirl, Texture.class); balloonGirl = manager.get(d.easterEggs.balloonGirl, Texture.class);
dwarf = manager.get(d.easterEggs.dwarf, Texture.class); dwarf = manager.get(d.easterEggs.dwarf, Texture.class);
plastic = manager.get(d.easterEggs.plastic, Texture.class); plastic = manager.get(d.easterEggs.plastic, Texture.class);
bunny = manager.get(d.easterEggs.bunny, Texture.class); bonnie = manager.get(d.easterEggs.bonnie, Texture.class);
goldenFreddy = manager.get(d.easterEggs.goldenFreddy, Texture.class); goldenFreddy = manager.get(d.easterEggs.goldenFreddy, Texture.class);
mangle = manager.get(d.easterEggs.mangle, Texture.class); mangle = manager.get(d.easterEggs.mangle, Texture.class);
balloonBoy = manager.get(d.easterEggs.balloonBoy, Texture.class); balloonBoy = manager.get(d.easterEggs.balloonBoy, Texture.class);
@@ -103,7 +103,7 @@ public class OfficeAssets extends AssetBase implements AssetBundle<OfficeAssets.
manager.unload(d.easterEggs.balloonGirl); manager.unload(d.easterEggs.balloonGirl);
manager.unload(d.easterEggs.dwarf); manager.unload(d.easterEggs.dwarf);
manager.unload(d.easterEggs.plastic); manager.unload(d.easterEggs.plastic);
manager.unload(d.easterEggs.bunny); manager.unload(d.easterEggs.bonnie);
manager.unload(d.easterEggs.goldenFreddy); manager.unload(d.easterEggs.goldenFreddy);
manager.unload(d.easterEggs.mangle); manager.unload(d.easterEggs.mangle);
manager.unload(d.easterEggs.balloonBoy); manager.unload(d.easterEggs.balloonBoy);
@@ -131,7 +131,7 @@ public class OfficeAssets extends AssetBase implements AssetBundle<OfficeAssets.
if (!manager.isLoaded(d.easterEggs.balloonGirl)) return false; if (!manager.isLoaded(d.easterEggs.balloonGirl)) return false;
if (!manager.isLoaded(d.easterEggs.dwarf)) return false; if (!manager.isLoaded(d.easterEggs.dwarf)) return false;
if (!manager.isLoaded(d.easterEggs.plastic)) return false; if (!manager.isLoaded(d.easterEggs.plastic)) return false;
if (!manager.isLoaded(d.easterEggs.bunny)) return false; if (!manager.isLoaded(d.easterEggs.bonnie)) return false;
if (!manager.isLoaded(d.easterEggs.goldenFreddy)) return false; if (!manager.isLoaded(d.easterEggs.goldenFreddy)) return false;
if (!manager.isLoaded(d.easterEggs.mangle)) return false; if (!manager.isLoaded(d.easterEggs.mangle)) return false;
if (!manager.isLoaded(d.easterEggs.balloonBoy)) return false; if (!manager.isLoaded(d.easterEggs.balloonBoy)) return false;
@@ -144,4 +144,46 @@ public class OfficeAssets extends AssetBase implements AssetBundle<OfficeAssets.
&& isRangeLoaded(manager, d.ranges.warnBig) && isRangeLoaded(manager, d.ranges.warnBig)
&& isRangeLoaded(manager, d.ranges.warnSmall); && isRangeLoaded(manager, d.ranges.warnSmall);
} }
@Override
public Texture resolve(String key, int frame) {
return switch (key) {
// Simple
case "bg" -> bg;
case "telephoneMute"-> telephoneMute;
case "ctrlAdv" -> ctrlAdv;
// Vent buttons
case "rightVentButtonOff" -> rightVentButtonOff;
case "rightVentButtonOn" -> rightVentButtonOn;
case "leftVentButtonOff" -> leftVentButtonOff;
case "leftVentButtonOn" -> leftVentButtonOn;
// Easter eggs
case "balloonGirl" -> balloonGirl;
case "dwarf" -> dwarf;
case "plastic" -> plastic;
case "bonnie" -> bonnie;
case "goldenFreddy" -> goldenFreddy;
case "mangle" -> mangle;
case "balloonBoy" -> balloonBoy;
// Ranges
case "inside" -> inside[frame];
case "hallway" -> hallway[frame];
case "rightVents" -> rightVents[frame];
case "leftVents" -> leftVents[frame];
case "desk" -> desk[frame];
case "warnBig" -> warnBig[frame];
case "warnSmall" -> warnSmall[frame];
default -> throw new IllegalArgumentException(
"Unknown key: '" + key + "'. Valid keys: " +
"[bg, telephoneMute, ctrlAdv, " +
"rightVentButtonOff, rightVentButtonOn, leftVentButtonOff, leftVentButtonOn, " +
"balloonGirl, dwarf, plastic, bonnie, goldenFreddy, mangle, balloonBoy, " +
"inside, hallway, rightVents, leftVents, desk, warnBig, warnSmall]"
);
};
}
} }

View File

@@ -7,4 +7,5 @@ public class CameraConfig {
public float buttonX; public float buttonX;
public float buttonY; public float buttonY;
public boolean wide; public boolean wide;
public CameraVariant[] variants;
} }

View File

@@ -3,6 +3,7 @@ package io.github.eldek0.config;
public class CameraConfigFile { public class CameraConfigFile {
public int inCameraId; public int inCameraId;
public RangeLong wideRandomMov; public RangeLong wideRandomMov;
public Rect lightHitbox;
public SpritePositionData[] sprites; public SpritePositionData[] sprites;
public CameraConfig[] cameras; public CameraConfig[] cameras;
} }

View File

@@ -0,0 +1,8 @@
package io.github.eldek0.config;
public class CameraVariant {
public String[] animatronics;
public int indexOff;
public int indexOn = -1;
public String condition = null;
}

View File

@@ -0,0 +1,5 @@
package io.github.eldek0.config;
public class Rect {
public float x, y, width, height;
}

View File

@@ -4,6 +4,11 @@ public record SpriteConfig<T extends Enum<T>>(
T type, T type,
float x, float x,
float y, float y,
String group,
String key,
int frame,
boolean active, boolean active,
boolean fromTop, boolean fromTop,
boolean centerX, boolean centerX,

View File

@@ -4,6 +4,10 @@ public class SpritePositionData {
public String type; public String type;
public int x, y; public int x, y;
public String group = "null";
public String key = "null";
public int frame = 0;
public boolean active = true; public boolean active = true;
public boolean fromTop = false; public boolean fromTop = false;
public boolean centerX = false; public boolean centerX = false;

View File

@@ -5,4 +5,10 @@ public class AnimatronicMovement {
public int[] path; public int[] path;
public int moveIntervalSeconds; public int moveIntervalSeconds;
public boolean aiSpeedMultiplier; public boolean aiSpeedMultiplier;
private int pathIndex = 0;
public int getPathIndex(){return pathIndex;}
public void setPathIndex(int val){pathIndex = val;}
} }

View File

@@ -4,8 +4,8 @@ public class AttackType {
public AttackKind kind; public AttackKind kind;
// If attack kind is IN_OFFICE // If attack kind is IN_OFFICE
public String officeSprite = null; public String officeSprite = null; // Full office sprite
public String inOfficeAnimatronicSprite = null; public String inOfficeAnimatronicSprite = null; // Animatronic sprite over office sprite
// If attack kind is LIGHT // If attack kind is LIGHT
public int lightLevel = 2; public int lightLevel = 2;

View File

@@ -5,13 +5,16 @@ import com.badlogic.gdx.utils.Json;
import io.github.eldek0.config.animatronic.AnimatronicConfig; import io.github.eldek0.config.animatronic.AnimatronicConfig;
import io.github.eldek0.config.animatronic.AnimatronicManifest; import io.github.eldek0.config.animatronic.AnimatronicManifest;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
public class Animatronic { public class Animatronic {
private static final String MANIFEST = "data/config/animatronics.json"; private static final String MANIFEST = "data/config/animatronics.json";
private static final String CONFIG = "data/config/animatronics/"; private static final String CONFIG = "data/config/animatronics/";
private float[] movementsTimer;
private String[] availableAnimatronics; private String[] availableAnimatronics;
private HashMap<String, AnimatronicConfig> data = new HashMap<>(); private HashMap<String, AnimatronicConfig> data = new HashMap<>();
@@ -25,16 +28,57 @@ public class Animatronic {
} }
private void loadConfig(){ private void loadConfig(){
// Global config
Json json = new Json(); Json json = new Json();
String raw = Gdx.files.internal(MANIFEST).readString(); String raw = Gdx.files.internal(MANIFEST).readString();
AnimatronicManifest manifest = json.fromJson(AnimatronicManifest.class, raw); AnimatronicManifest manifest = json.fromJson(AnimatronicManifest.class, raw);
availableAnimatronics = manifest.animatronics; availableAnimatronics = manifest.animatronics;
// Individual config
String rawAnim; String rawAnim;
for (String animatronic : availableAnimatronics){ for (String animatronic : availableAnimatronics){
rawAnim = Gdx.files.internal(CONFIG + animatronic + ".json").readString(); rawAnim = Gdx.files.internal(CONFIG + animatronic + ".json").readString();
data.put(animatronic, data.put(animatronic,
json.fromJson(AnimatronicConfig.class, rawAnim)); json.fromJson(AnimatronicConfig.class, rawAnim));
} }
movementsTimer = new float[availableAnimatronics.length];
}
public void update(float delta){
this.updateTimers(delta);
this.updateAnimatronics();
}
private void updateTimers(float delta){
for (int i = 0; i < movementsTimer.length; i++) {
movementsTimer[i] += delta;
}
}
private void updateAnimatronics(){
List<AnimatronicConfig> values = new ArrayList<>(data.values());
int index;
for (int i = 0; i<values.size(); i++){
AnimatronicConfig animatronic = values.get(i);
if (movementsTimer[i] > animatronic.movement.moveIntervalSeconds){
index = animatronic.movement.getPathIndex() + 1;
if (index >= animatronic.movement.path.length){
index = 0;
}
animatronic.movement.setPathIndex(index);
animatronic.inRoom = animatronic.movement.path[index];
movementsTimer[i] = 0;
}
}
}
public List<String> getAnimatronicsInLocation(int location){
List<String> list = new ArrayList<>();
for (AnimatronicConfig animatronic : data.values()){
if (animatronic.inRoom == location){
list.add(animatronic.id);
}
}
return list;
} }
} }

View File

@@ -29,6 +29,7 @@ public class Camera {
private int inCameraRoom; private int inCameraRoom;
private Rectangle[] buttonScreenRects; private Rectangle[] buttonScreenRects;
private Rectangle lightHitbox;
// Wide-camera panning // Wide-camera panning
private float[] camerasXPosition; private float[] camerasXPosition;
@@ -46,6 +47,8 @@ public class Camera {
private GameScene gameScene; private GameScene gameScene;
private boolean lightOn;
public Camera(GameScene gameScene) { public Camera(GameScene gameScene) {
this.gameScene = gameScene; this.gameScene = gameScene;
@@ -57,6 +60,7 @@ public class Camera {
timerWaitTimeMs[i] = wideRandomMov.min + (long) rng.nextInt((int) (wideRandomMov.max - wideRandomMov.min)); timerWaitTimeMs[i] = wideRandomMov.min + (long) rng.nextInt((int) (wideRandomMov.max - wideRandomMov.min));
} }
this.lightOn = false;
this.initButtonScreenRects(); this.initButtonScreenRects();
} }
@@ -87,6 +91,8 @@ public class Camera {
} }
public void update(float delta) { public void update(float delta) {
debugUpdateCamConfig();
for (int i = 0; i < cameraConfigs.length; i++) { for (int i = 0; i < cameraConfigs.length; i++) {
if (cameraConfigs[i].wide) { if (cameraConfigs[i].wide) {
updateCameraTimer(i, delta); updateCameraTimer(i, delta);
@@ -108,23 +114,50 @@ public class Camera {
} }
public void onTouchDown() { public void onTouchDown() {
Vector2 position = App.convertPosToWorldPos(new Vector2(Gdx.input.getX(), Gdx.input.getY())); Vector2 position = App.convertPosToWorldPos(
for (int i = 0; i < this.cameraConfigs.length; i++) { new Vector2(Gdx.input.getX(), Gdx.input.getY())
);
if (!Gdx.input.isButtonPressed(Input.Buttons.LEFT)) {
return;
}
for (int i = 0; i < cameraConfigs.length; i++) {
if (buttonScreenRects[i].contains(position)) { if (buttonScreenRects[i].contains(position)) {
if (Gdx.input.isButtonJustPressed(Input.Buttons.LEFT)) { inCameraRoom = cameraConfigs[i].id;
inCameraRoom = i + 1; lightOn = false;
return; return;
} }
} }
}
lightOn = lightHitbox.contains(position);
} }
private void renderCurrentRoom(SpriteBatch batch) { private void renderCurrentRoom(SpriteBatch batch) {
int idx = inCameraRoom - 1; int idx = inCameraRoom - 1;
float xOff = camerasXPosition[idx]; float xOff = camerasXPosition[idx];
Texture frame;
if (!occupiedCamera[idx]) { if (!occupiedCamera[idx]) {
Texture frame = getFrame(inCameraRoom, 0); List<String> animatronicsInCam = gameScene.animatronic.getAnimatronicsInLocation(idx + 1);
CameraVariant variant = null;
for (CameraVariant v : cameraConfigs[idx].variants){
System.out.println(animatronicsInCam + ", " + Arrays.toString(v.animatronics));
if (Arrays.equals(v.animatronics, animatronicsInCam.toArray())){
variant = v;
break;
}
}
if (variant == null){
return;
}
if (lightOn && variant.indexOn != -1){
frame = getFrame(inCameraRoom, variant.indexOn);
}
else {
frame = getFrame(inCameraRoom, variant.indexOff);
}
if (frame != null) { if (frame != null) {
batch.draw(frame, xOff, 0); batch.draw(frame, xOff, 0);
} }
@@ -138,6 +171,12 @@ public class Camera {
this.inCameraRoom = configFile.inCameraId; this.inCameraRoom = configFile.inCameraId;
this.cameraConfigs = configFile.cameras; this.cameraConfigs = configFile.cameras;
this.wideRandomMov = configFile.wideRandomMov; this.wideRandomMov = configFile.wideRandomMov;
this.lightHitbox = new Rectangle(
configFile.lightHitbox.x,
configFile.lightHitbox.y,
configFile.lightHitbox.width,
configFile.lightHitbox.height
);
this.layout = new SpriteLayout<>( this.layout = new SpriteLayout<>(
configFile.sprites, configFile.sprites,
@@ -146,6 +185,21 @@ public class Camera {
} }
private void debugUpdateCamConfig(){
Json json = new Json();
String raw = Gdx.files.internal(CONFIG).readString();
CameraConfigFile configFile = json.fromJson(CameraConfigFile.class, raw);
for (int i = 0; i<this.cameraConfigs.length; i++){
this.cameraConfigs[i].variants = configFile.cameras[i].variants;
}
this.lightHitbox = new Rectangle(
configFile.lightHitbox.x,
configFile.lightHitbox.y,
configFile.lightHitbox.width,
configFile.lightHitbox.height
);
}
private Texture getFrame(int room, int index) { private Texture getFrame(int room, int index) {
CameraConfig config = cameraConfigs[room - 1]; CameraConfig config = cameraConfigs[room - 1];
Texture[] textures = assets.cameras.getLocationFrames(config.name); Texture[] textures = assets.cameras.getLocationFrames(config.name);
@@ -168,7 +222,7 @@ public class Camera {
for (SpriteConfig<CameraSpriteType> config : layout.getSortedSprites()) { for (SpriteConfig<CameraSpriteType> config : layout.getSortedSprites()) {
if (!config.active()) continue; if (!config.active()) continue;
Texture texture = getTextureForSprite(config.type()); Texture texture = assets.resolve(config.group(), config.key(), config.frame());
if (config.type() == CameraSpriteType.LABEL) { if (config.type() == CameraSpriteType.LABEL) {
texture = getRoomLabel(inCameraRoom); texture = getRoomLabel(inCameraRoom);
} }
@@ -188,16 +242,6 @@ public class Camera {
drawCameraButtons(batch); drawCameraButtons(batch);
} }
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) { public void renderHitboxes(ShapeRenderer shapeRenderer) {
shapeRenderer.setColor(1, 0, 0, 1); shapeRenderer.setColor(1, 0, 0, 1);
CameraConfig config; CameraConfig config;
@@ -208,21 +252,29 @@ public class Camera {
shapeRenderer.rect(rect.x, rect.y, rect.width, rect.height); shapeRenderer.rect(rect.x, rect.y, rect.width, rect.height);
for (AnimatronicConfig animatronicConfig : gameScene.animatronic.getAnimatronicsData()) {
if (animatronicConfig.inRoom == config.id) {
shapeRenderer.end(); shapeRenderer.end();
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
for (AnimatronicConfig animatronicConfig : gameScene.animatronic.getAnimatronicsData()) {
shapeRenderer.setColor(Color.valueOf(animatronicConfig.color)); shapeRenderer.setColor(Color.valueOf(animatronicConfig.color));
if (animatronicConfig.inRoom == config.id) {
shapeRenderer.rect(rect.x, rect.y, 10, 30); shapeRenderer.rect(rect.x, rect.y, 10, 30);
}
else if (animatronicConfig.inRoom == -2){
shapeRenderer.rect(670, 300, 10, 30);
}
else if (animatronicConfig.inRoom == -3){
shapeRenderer.rect(670, 260, 10, 30);
}
}
shapeRenderer.end(); shapeRenderer.end();
shapeRenderer.begin(ShapeRenderer.ShapeType.Line); shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.setColor(1, 0, 0, 1); shapeRenderer.setColor(1, 0, 0, 1);
} }
}
} // Light hitbox
shapeRenderer.rect(lightHitbox.x, lightHitbox.y, lightHitbox.width, lightHitbox.height);
} }
private void drawCameraButtons(SpriteBatch batch) { private void drawCameraButtons(SpriteBatch batch) {

View File

@@ -62,6 +62,7 @@ public class GameScene implements Screen {
hud.update(v); hud.update(v);
mask.update(v); mask.update(v);
camera.update(v); camera.update(v);
animatronic.update(v);
frameBuffer.begin(); frameBuffer.begin();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

View File

@@ -32,6 +32,9 @@ public class SpriteLayout<T extends Enum<T>> {
enumType, enumType,
raw.x, raw.x,
raw.y, raw.y,
raw.group,
raw.key,
raw.frame,
raw.active, raw.active,
raw.fromTop, raw.fromTop,
raw.centerX, raw.centerX,

17
movement.txt Normal file
View File

@@ -0,0 +1,17 @@
animatronics:
animatronics.json (manifests all the animatronics available)
night_control.json (gets all the nights info with the animatronics ai level per hour)
animatronic:
freddy (example):
- StartRoom
- RestRoom
- Movement
- AtackType (elect from these options)
- InOffice: (enters the office, like withered)
- Office sprite with animatronic or inOfficeAnimatronicSprite
- Light: (have to light em to make him quit)
- Level (will be affected by AI)
- MoveInOffice: (a sprite of the animatronic moves in the office, like toy bonnie)
- Speed
- Normal
- Jumpscare