Weitere Anpassungen bezüglich der Voxel und des Zoning Systems
This commit is contained in:
@@ -222,7 +222,8 @@ public class JmeConsole extends BaseAppState {
|
||||
|
||||
private BitmapText makeLine(BitmapFont font, ColorRGBA color, float x, float y) {
|
||||
BitmapText t = new BitmapText(font);
|
||||
t.setSize(LINE_H - 2f);
|
||||
t.setSize((LINE_H - 2f) * 2f);
|
||||
t.setLocalScale(0.5f, 0.5f, 1f);
|
||||
t.setColor(color);
|
||||
t.setLocalTranslation(x, y, 0f);
|
||||
return t;
|
||||
|
||||
@@ -102,6 +102,7 @@ public class WorldScene extends BaseAppState {
|
||||
private float spawnYaw = 0f;
|
||||
private de.blight.game.state.OceanSoundState oceanSound;
|
||||
private de.blight.game.state.AmbientSoundSystem ambientSounds;
|
||||
private de.blight.game.state.MusicSystem musicSystem;
|
||||
private de.blight.game.audio.FootstepSystem footstepSystem;
|
||||
private de.blight.game.state.DrownState drownState;
|
||||
private WaterInteractionState waterInteractionState;
|
||||
@@ -430,8 +431,12 @@ public class WorldScene extends BaseAppState {
|
||||
app.getListener().setRotation(app.getCamera().getRotation());
|
||||
if (oceanSound != null) oceanSound.setPlayerPosition(pos);
|
||||
if (ambientSounds != null) ambientSounds.setPlayerPosition(pos);
|
||||
if (musicSystem != null) musicSystem.setPlayerPosition(pos);
|
||||
}
|
||||
|
||||
if (musicSystem != null && dayNight != null)
|
||||
musicSystem.setDaytime(dayNight.getSunElevation() >= 0f);
|
||||
|
||||
if (terrainMaterial != null && dayNight != null && dayNight.getSunLight() != null) {
|
||||
terrainMaterial.setVector3("LightDir", dayNight.getSunDirection().negate());
|
||||
ColorRGBA sc = dayNight.getSunLight().getColor();
|
||||
@@ -945,6 +950,9 @@ public class WorldScene extends BaseAppState {
|
||||
|
||||
ambientSounds = new de.blight.game.state.AmbientSoundSystem();
|
||||
app.getStateManager().attach(ambientSounds);
|
||||
|
||||
musicSystem = new de.blight.game.state.MusicSystem();
|
||||
app.getStateManager().attach(musicSystem);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
@@ -285,6 +285,14 @@ public class DayNightState extends BaseAppState implements TimeListener {
|
||||
}
|
||||
cc.a = 1f;
|
||||
cloudMat.setColor("CloudColor", cc);
|
||||
|
||||
// Abendrot-Glut auf Wolkenunterseite (sunElevation: +1=Zenit, 0=Horizont, −1=Nadir)
|
||||
// Sichtbar: Sonne bis +8.6° über Horizont (elev=+0.15) bis −5.7° darunter (Afterglow)
|
||||
float glowCeil = FastMath.clamp(1f - sunElevation / 0.45f, 0f, 1f); // blendet über ~26° aus
|
||||
float glowFade = FastMath.clamp((sunElevation + 0.10f) / 0.06f, 0f, 1f); // blendet unter −5.7° aus
|
||||
float sunsetT = glowCeil * glowFade;
|
||||
sunsetT = sunsetT * sunsetT; // weichere Kurve
|
||||
cloudMat.setVector3("SunsetGlow", new Vector3f(0.42f * sunsetT, 0.13f * sunsetT, 0f));
|
||||
}
|
||||
|
||||
// Sonnenlicht + Schatten: Okklusion durch CloudDome bestimmt beides
|
||||
|
||||
@@ -867,7 +867,8 @@ public class DialogHudState extends BaseAppState {
|
||||
|
||||
private BitmapText makeTxt(String s, float size, ColorRGBA color) {
|
||||
BitmapText t = new BitmapText(font);
|
||||
t.setSize(size);
|
||||
t.setSize(size * 2f);
|
||||
t.setLocalScale(0.5f, 0.5f, 1f);
|
||||
t.setColor(color);
|
||||
t.setText(s);
|
||||
return t;
|
||||
|
||||
@@ -264,7 +264,8 @@ public class HotbarState extends BaseAppState {
|
||||
|
||||
private BitmapText txt(String s, int size, ColorRGBA col) {
|
||||
BitmapText t = new BitmapText(font);
|
||||
t.setSize(size);
|
||||
t.setSize(size * 2f);
|
||||
t.setLocalScale(0.5f, 0.5f, 1f);
|
||||
t.setColor(col);
|
||||
t.setText(s);
|
||||
t.setQueueBucket(RenderQueue.Bucket.Gui);
|
||||
|
||||
@@ -43,7 +43,8 @@ public class InteractionHudState extends BaseAppState {
|
||||
|
||||
BitmapFont font = app.getAssetManager().loadFont("Interface/Fonts/Default.fnt");
|
||||
labelText = new BitmapText(font);
|
||||
labelText.setSize(font.getCharSet().getRenderedSize() * 1.2f);
|
||||
labelText.setSize(font.getCharSet().getRenderedSize() * 1.2f * 2f);
|
||||
labelText.setLocalScale(0.5f, 0.5f, 1f);
|
||||
labelText.setColor(new ColorRGBA(1f, 0.95f, 0.6f, 1f));
|
||||
labelText.setCullHint(Spatial.CullHint.Always);
|
||||
guiNode.attachChild(labelText);
|
||||
|
||||
@@ -6,63 +6,107 @@ import com.jme3.app.state.BaseAppState;
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.audio.AudioData;
|
||||
import com.jme3.audio.AudioNode;
|
||||
import com.jme3.audio.AudioSource;
|
||||
import com.jme3.font.BitmapFont;
|
||||
import com.jme3.font.BitmapText;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.Node;
|
||||
import de.blight.common.AreaDefinition;
|
||||
import de.blight.common.AreaDefinitionIO;
|
||||
import de.blight.common.AreaIO;
|
||||
import de.blight.common.PlacedArea;
|
||||
import de.blight.lang.TextResolver;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Proximity-based ambient music per polygon area.
|
||||
* Three parallel tracks (day / night / combat) play when the player is inside.
|
||||
* All three are attached + played on entry and detached on exit.
|
||||
* Which one is actually audible is controlled via volume (wiring to day/night deferred).
|
||||
* Area-based music system.
|
||||
*
|
||||
* Track priority: combat (not yet implemented) > night > day (fallback).
|
||||
* On area entry the appropriate track fades in.
|
||||
* On day/night change the running track finishes its current loop,
|
||||
* then the next track starts (no abrupt cut).
|
||||
* Day track is always the fallback when no other track is configured.
|
||||
*/
|
||||
public class MusicSystem extends BaseAppState {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MusicSystem.class);
|
||||
private static final float CHECK_INTERVAL = 0.25f;
|
||||
private static final float FADE_DURATION = 3f;
|
||||
private static final float MUSIC_VOLUME = 0.7f;
|
||||
private static final Logger log = LoggerFactory.getLogger(MusicSystem.class);
|
||||
private static final float CHECK_INTERVAL = 0.25f;
|
||||
private static final float FADE_DURATION = 3f;
|
||||
private static final float AREA_NAME_SHOW = 10f;
|
||||
private static final float AREA_NAME_FADE = 1.5f;
|
||||
private static final float AREA_NAME_SIZE = 24f;
|
||||
|
||||
private enum FadeState { INACTIVE, FADING_IN, ACTIVE, FADING_OUT }
|
||||
private static final int SLOT_DAY = 0;
|
||||
private static final int SLOT_NIGHT = 1;
|
||||
|
||||
private SimpleApplication app;
|
||||
private AssetManager assets;
|
||||
private Node rootNode;
|
||||
private enum Phase { INACTIVE, FADING_IN, ACTIVE, FINISHING, FADING_OUT }
|
||||
|
||||
private final List<PlacedArea> data = new ArrayList<>();
|
||||
// three nodes per area: [0]=day, [1]=night, [2]=combat; element may be null
|
||||
private final List<AudioNode[]> tracks = new ArrayList<>();
|
||||
private final List<FadeState> fadeStates = new ArrayList<>();
|
||||
private SimpleApplication app;
|
||||
private AssetManager assets;
|
||||
private Node rootNode;
|
||||
private AudioSettingsState audioSettings;
|
||||
|
||||
private final List<PlacedArea> data = new ArrayList<>();
|
||||
private final List<String> areaNameKeys = new ArrayList<>();
|
||||
private final List<String> areaShortIds = new ArrayList<>();
|
||||
// index [area][slot]: slot 0 = day, slot 1 = night
|
||||
private final List<AudioNode[]> nodes = new ArrayList<>();
|
||||
private final List<Phase> phases = new ArrayList<>();
|
||||
private final List<Integer> activeSlot = new ArrayList<>();
|
||||
private final List<Integer> pendingSlot = new ArrayList<>();
|
||||
|
||||
private Vector3f playerPos = new Vector3f();
|
||||
private float checkTimer = 0f;
|
||||
private boolean isDaytime = true;
|
||||
|
||||
private BitmapText areaNameText;
|
||||
private float areaNameTimer = 0f;
|
||||
|
||||
// ── Lifecycle ─────────────────────────────────────────────────────────────
|
||||
|
||||
@Override
|
||||
protected void initialize(Application application) {
|
||||
app = (SimpleApplication) application;
|
||||
assets = app.getAssetManager();
|
||||
rootNode = app.getRootNode();
|
||||
audioSettings = app.getStateManager().getState(AudioSettingsState.class);
|
||||
|
||||
BitmapFont font = assets.loadFont("Interface/Fonts/Default.fnt");
|
||||
areaNameText = new BitmapText(font);
|
||||
areaNameText.setSize(AREA_NAME_SIZE * 2f);
|
||||
areaNameText.setLocalScale(0.5f, 0.5f, 1f);
|
||||
areaNameText.setColor(new ColorRGBA(1f, 0.95f, 0.8f, 0f));
|
||||
app.getGuiNode().attachChild(areaNameText);
|
||||
|
||||
try {
|
||||
Map<String, AreaDefinition> defs = new java.util.HashMap<>();
|
||||
try {
|
||||
for (AreaDefinition d : AreaDefinitionIO.load()) defs.put(d.id(), d);
|
||||
} catch (IOException e) {
|
||||
log.warn("[MusicSystem] Area-Definitions nicht ladbar: {}", e.getMessage());
|
||||
}
|
||||
for (PlacedArea area : AreaIO.load()) {
|
||||
AudioNode[] arr = {
|
||||
loadAmbient(area.dayTrack()),
|
||||
loadAmbient(area.nightTrack()),
|
||||
loadAmbient(area.combatTrack())
|
||||
};
|
||||
boolean hasAny = false;
|
||||
for (AudioNode n : arr) if (n != null) { hasAny = true; break; }
|
||||
if (!hasAny) continue;
|
||||
AreaDefinition def = defs.get(area.areaId());
|
||||
if (def == null) continue;
|
||||
AudioNode day = loadTrack(def.dayTrack());
|
||||
AudioNode night = loadTrack(def.nightTrack());
|
||||
if (day == null && night == null) continue;
|
||||
String rawId = def.id();
|
||||
String shortId = rawId.startsWith("area.") ? rawId.substring("area.".length()) : rawId;
|
||||
data.add(area);
|
||||
tracks.add(arr);
|
||||
fadeStates.add(FadeState.INACTIVE);
|
||||
areaNameKeys.add(def.nameKey());
|
||||
areaShortIds.add(shortId);
|
||||
nodes.add(new AudioNode[]{day, night});
|
||||
phases.add(Phase.INACTIVE);
|
||||
activeSlot.add(-1);
|
||||
pendingSlot.add(-1);
|
||||
}
|
||||
if (!data.isEmpty()) log.info("[MusicSystem] {} Musik-Bereiche geladen.", data.size());
|
||||
} catch (IOException e) {
|
||||
@@ -72,88 +116,212 @@ public class MusicSystem extends BaseAppState {
|
||||
|
||||
@Override
|
||||
protected void cleanup(Application application) {
|
||||
for (int i = 0; i < tracks.size(); i++) {
|
||||
if (fadeStates.get(i) != FadeState.INACTIVE) {
|
||||
for (AudioNode n : tracks.get(i)) {
|
||||
if (n != null) { n.stop(); rootNode.detachChild(n); }
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
if (phases.get(i) != Phase.INACTIVE) stopAll(i);
|
||||
}
|
||||
data.clear();
|
||||
tracks.clear();
|
||||
fadeStates.clear();
|
||||
areaNameKeys.clear();
|
||||
areaShortIds.clear();
|
||||
nodes.clear();
|
||||
phases.clear();
|
||||
activeSlot.clear();
|
||||
pendingSlot.clear();
|
||||
if (areaNameText != null) app.getGuiNode().detachChild(areaNameText);
|
||||
}
|
||||
|
||||
@Override protected void onEnable() {}
|
||||
@Override protected void onDisable() {}
|
||||
|
||||
public void setPlayerPosition(Vector3f pos) {
|
||||
playerPos.set(pos);
|
||||
public void setPlayerPosition(Vector3f pos) { playerPos.set(pos); }
|
||||
|
||||
public void setDaytime(boolean day) {
|
||||
if (isDaytime == day) return;
|
||||
isDaytime = day;
|
||||
// trigger track switch for all active areas
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Phase ph = phases.get(i);
|
||||
if (ph == Phase.INACTIVE || ph == Phase.FADING_OUT) continue;
|
||||
int desired = desiredSlot(i);
|
||||
if (desired != activeSlot.get(i)) {
|
||||
startFinishing(i, desired);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Update ────────────────────────────────────────────────────────────────
|
||||
|
||||
@Override
|
||||
public void update(float tpf) {
|
||||
if (data.isEmpty()) return;
|
||||
|
||||
for (int i = 0; i < tracks.size(); i++) {
|
||||
FadeState fs = fadeStates.get(i);
|
||||
if (fs == FadeState.INACTIVE || fs == FadeState.ACTIVE) continue;
|
||||
|
||||
AudioNode[] arr = tracks.get(i);
|
||||
if (fs == FadeState.FADING_IN) {
|
||||
boolean done = true;
|
||||
for (AudioNode n : arr) {
|
||||
if (n == null) continue;
|
||||
float nv = Math.min(n.getVolume() + MUSIC_VOLUME * tpf / FADE_DURATION, MUSIC_VOLUME);
|
||||
n.setVolume(nv);
|
||||
if (nv < MUSIC_VOLUME) done = false;
|
||||
}
|
||||
if (done) fadeStates.set(i, FadeState.ACTIVE);
|
||||
} else { // FADING_OUT
|
||||
boolean done = true;
|
||||
for (AudioNode n : arr) {
|
||||
if (n == null) continue;
|
||||
float nv = Math.max(n.getVolume() - MUSIC_VOLUME * tpf / FADE_DURATION, 0f);
|
||||
n.setVolume(nv);
|
||||
if (nv > 0f) done = false;
|
||||
}
|
||||
if (done) {
|
||||
for (AudioNode n : arr) {
|
||||
if (n != null) { n.stop(); rootNode.detachChild(n); }
|
||||
}
|
||||
fadeStates.set(i, FadeState.INACTIVE);
|
||||
}
|
||||
// area name display timer
|
||||
if (areaNameTimer > 0f) {
|
||||
areaNameTimer -= tpf;
|
||||
if (areaNameTimer <= 0f) {
|
||||
areaNameText.setColor(new ColorRGBA(1f, 0.95f, 0.8f, 0f));
|
||||
areaNameTimer = 0f;
|
||||
} else if (areaNameTimer < AREA_NAME_FADE) {
|
||||
float alpha = areaNameTimer / AREA_NAME_FADE;
|
||||
areaNameText.setColor(new ColorRGBA(1f, 0.95f, 0.8f, alpha));
|
||||
}
|
||||
}
|
||||
|
||||
if (data.isEmpty()) return;
|
||||
|
||||
// per-area fade/finish handling + live volume update for active tracks
|
||||
float vol = musicVol();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Phase ph = phases.get(i);
|
||||
switch (ph) {
|
||||
case FADING_IN -> tickFadeIn(i, tpf, vol);
|
||||
case FINISHING -> tickFinishing(i);
|
||||
case FADING_OUT -> tickFadeOut(i, tpf, vol);
|
||||
case ACTIVE -> {
|
||||
AudioNode n = activeNode(i);
|
||||
if (n != null) n.setVolume(vol);
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
// proximity check
|
||||
checkTimer += tpf;
|
||||
if (checkTimer < CHECK_INTERVAL) return;
|
||||
checkTimer = 0f;
|
||||
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
PlacedArea area = data.get(i);
|
||||
boolean inside = pointInPolygon(playerPos.x, playerPos.z, area.pointsX(), area.pointsZ());
|
||||
FadeState fs = fadeStates.get(i);
|
||||
boolean inside = pointInPolygon(playerPos.x, playerPos.z, area.pointsX(), area.pointsZ());
|
||||
Phase ph = phases.get(i);
|
||||
|
||||
if (inside && (fs == FadeState.INACTIVE || fs == FadeState.FADING_OUT)) {
|
||||
if (fs == FadeState.INACTIVE) {
|
||||
log.info("[MusicSystem] Bereich {} betreten → starte Tracks", i);
|
||||
for (AudioNode n : tracks.get(i)) {
|
||||
if (n != null) { n.setVolume(0f); rootNode.attachChild(n); n.play(); }
|
||||
}
|
||||
}
|
||||
fadeStates.set(i, FadeState.FADING_IN);
|
||||
} else if (!inside && (fs == FadeState.ACTIVE || fs == FadeState.FADING_IN)) {
|
||||
log.info("[MusicSystem] Bereich {} verlassen → fade out", i);
|
||||
fadeStates.set(i, FadeState.FADING_OUT);
|
||||
if (inside && (ph == Phase.INACTIVE || ph == Phase.FADING_OUT)) {
|
||||
startArea(i);
|
||||
} else if (!inside && (ph == Phase.ACTIVE || ph == Phase.FADING_IN || ph == Phase.FINISHING)) {
|
||||
beginFadeOut(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AudioNode loadAmbient(String path) {
|
||||
// ── State transitions ─────────────────────────────────────────────────────
|
||||
|
||||
private void startArea(int i) {
|
||||
int slot = desiredSlot(i);
|
||||
AudioNode n = nodes.get(i)[slot];
|
||||
if (n == null) return;
|
||||
n.setVolume(0f);
|
||||
n.setLooping(true);
|
||||
rootNode.attachChild(n);
|
||||
n.play();
|
||||
activeSlot.set(i, slot);
|
||||
pendingSlot.set(i, -1);
|
||||
phases.set(i, Phase.FADING_IN);
|
||||
log.info("[MusicSystem] Area {} → slot {} gestartet", i, slot == SLOT_DAY ? "Tag" : "Nacht");
|
||||
showAreaName(i);
|
||||
}
|
||||
|
||||
private void startFinishing(int i, int desired) {
|
||||
// let current track play to end, then switch
|
||||
AudioNode cur = activeNode(i);
|
||||
if (cur != null) cur.setLooping(false);
|
||||
pendingSlot.set(i, desired);
|
||||
phases.set(i, Phase.FINISHING);
|
||||
log.info("[MusicSystem] Area {} → Slot wechsel nach {}, warte auf Loop-Ende", i, desired == SLOT_DAY ? "Tag" : "Nacht");
|
||||
}
|
||||
|
||||
private void beginFadeOut(int i) {
|
||||
phases.set(i, Phase.FADING_OUT);
|
||||
}
|
||||
|
||||
private void stopAll(int i) {
|
||||
for (AudioNode n : nodes.get(i)) {
|
||||
if (n != null && n.getParent() != null) { n.stop(); rootNode.detachChild(n); }
|
||||
}
|
||||
activeSlot.set(i, -1);
|
||||
pendingSlot.set(i, -1);
|
||||
phases.set(i, Phase.INACTIVE);
|
||||
}
|
||||
|
||||
// ── Tick helpers ──────────────────────────────────────────────────────────
|
||||
|
||||
private void tickFadeIn(int i, float tpf, float vol) {
|
||||
AudioNode n = activeNode(i);
|
||||
if (n == null) { phases.set(i, Phase.ACTIVE); return; }
|
||||
float nv = Math.min(n.getVolume() + vol * tpf / FADE_DURATION, vol);
|
||||
n.setVolume(nv);
|
||||
if (nv >= vol) phases.set(i, Phase.ACTIVE);
|
||||
}
|
||||
|
||||
private void tickFinishing(int i) {
|
||||
AudioNode cur = activeNode(i);
|
||||
// wait until the current (non-looping) track finishes
|
||||
if (cur != null && cur.getStatus() != AudioSource.Status.Stopped) return;
|
||||
|
||||
// detach old
|
||||
if (cur != null && cur.getParent() != null) { cur.stop(); rootNode.detachChild(cur); }
|
||||
activeSlot.set(i, -1);
|
||||
|
||||
int next = pendingSlot.get(i);
|
||||
pendingSlot.set(i, -1);
|
||||
if (next < 0 || nodes.get(i)[next] == null) {
|
||||
// fallback to day
|
||||
next = SLOT_DAY;
|
||||
}
|
||||
AudioNode n = nodes.get(i)[next];
|
||||
if (n == null) { phases.set(i, Phase.INACTIVE); return; }
|
||||
n.setVolume(0f);
|
||||
n.setLooping(true);
|
||||
rootNode.attachChild(n);
|
||||
n.play();
|
||||
activeSlot.set(i, next);
|
||||
phases.set(i, Phase.FADING_IN);
|
||||
log.info("[MusicSystem] Area {} → nächster Slot {} gestartet", i, next == SLOT_DAY ? "Tag" : "Nacht");
|
||||
}
|
||||
|
||||
private void tickFadeOut(int i, float tpf, float vol) {
|
||||
AudioNode n = activeNode(i);
|
||||
if (n == null) { stopAll(i); return; }
|
||||
float nv = Math.max(n.getVolume() - vol * tpf / FADE_DURATION, 0f);
|
||||
n.setVolume(nv);
|
||||
if (nv <= 0f) stopAll(i);
|
||||
}
|
||||
|
||||
// ── Area-Name-Anzeige ─────────────────────────────────────────────────────
|
||||
|
||||
private void showAreaName(int i) {
|
||||
String key = i < areaNameKeys.size() ? areaNameKeys.get(i) : "";
|
||||
String shortId = i < areaShortIds.size() ? areaShortIds.get(i) : key;
|
||||
String resolved = TextResolver.get().resolveOrId(key);
|
||||
String name = resolved.equals(key) ? shortId : resolved;
|
||||
if (name.isBlank()) return;
|
||||
|
||||
areaNameText.setText(name);
|
||||
float tw = areaNameText.getLineWidth() * 0.5f;
|
||||
float sw = app.getCamera().getWidth();
|
||||
float sh = app.getCamera().getHeight();
|
||||
areaNameText.setLocalTranslation((sw - tw) / 2f, sh - 40f, 0f);
|
||||
areaNameText.setColor(new ColorRGBA(1f, 0.95f, 0.8f, 1f));
|
||||
areaNameTimer = AREA_NAME_SHOW;
|
||||
}
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||
|
||||
private float musicVol() {
|
||||
return audioSettings != null ? audioSettings.effectiveMusic() : 0.7f;
|
||||
}
|
||||
|
||||
private int desiredSlot(int i) {
|
||||
AudioNode[] arr = nodes.get(i);
|
||||
if (!isDaytime && arr[SLOT_NIGHT] != null) return SLOT_NIGHT;
|
||||
return SLOT_DAY;
|
||||
}
|
||||
|
||||
private AudioNode activeNode(int i) {
|
||||
int slot = activeSlot.get(i);
|
||||
if (slot < 0) return null;
|
||||
return nodes.get(i)[slot];
|
||||
}
|
||||
|
||||
private AudioNode loadTrack(String path) {
|
||||
if (path == null || path.isEmpty()) return null;
|
||||
try {
|
||||
// Use Stream for music (files are large), Buffer for short sfx
|
||||
AudioNode n = new AudioNode(assets, path, AudioData.DataType.Stream);
|
||||
n.setLooping(true);
|
||||
n.setPositional(false);
|
||||
|
||||
Reference in New Issue
Block a user