Изменить 'wbld/orbits.html'

This commit is contained in:
2025-02-26 12:51:36 +01:00
parent 0a20a1151e
commit 372fffd376

View File

@@ -2,12 +2,12 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Senthara Orbit, Rotation, Day/Night & Elliptical Orbits</title> <title>Senthara Orbit, Rotation, Phases & Astronomical Data</title>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.js"></script> <script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.js"></script>
<style> <style>
body { margin: 0; overflow: hidden; } body { margin: 0; overflow: hidden; }
canvas { display: block; } canvas { display: block; }
/* Style for the control panel */ /* Control panel style */
#controlPanel { #controlPanel {
position: absolute; position: absolute;
bottom: 10px; bottom: 10px;
@@ -34,32 +34,88 @@
</head> </head>
<body> <body>
<div id="controlPanel"> <div id="controlPanel">
<button id="playPauseButton">Play</button> <button id="playPauseButton">Play</button>
<button id="rewindButton">Rewind</button> <button id="rewindButton">Rewind</button>
<select id="speedSelect"> <select id="speedSelect">
<option value="1">x1</option> <option value="1">x1</option>
<option value="2">x2</option> <option value="2">x2</option>
<option value="5" selected>x5</option> <option value="5" selected>x5</option>
<option value="10">x10</option> <option value="10">x10</option>
<option value="100">x100</option> <option value="100">x100</option>
<option value="1000">x1000</option> <option value="1000">x1000</option>
<option value="10000">x10000</option> </select>
<option value="100000">x100000</option>
<option value="1000000">x1000000</option>
</select>
</div> </div>
<script> <script>
// Helper: returns {x, y} for an elliptical orbit. /////////////////////////////
// a = semi-major axis, ecc = eccentricity, so semi-minor axis b = a*sqrt(1 - ecc^2). // 1. Geometry and Moon Phases
// theta is a linear parameter based on simulation time (not the true anomaly, but sufficient for visualization). /////////////////////////////
/**
* Returns {x, y} for an elliptical orbit.
* a = semi-major axis, ecc = eccentricity, b = a*sqrt(1-ecc^2).
* Theta is computed linearly from simulation time.
*/
function getEllipticalPosition(simTime, period, a, ecc) { function getEllipticalPosition(simTime, period, a, ecc) {
const theta = Phaser.Math.DegToRad((360 * (simTime % period)) / period - 90); const thetaDeg = (360 * (simTime % period)) / period - 90;
const theta = Phaser.Math.DegToRad(thetaDeg);
const b = a * Math.sqrt(1 - ecc * ecc); const b = a * Math.sqrt(1 - ecc * ecc);
return { x: a * Math.cos(theta), y: b * Math.sin(theta) }; return { x: a * Math.cos(theta), y: b * Math.sin(theta) };
} }
// Function to calculate the current Senthara date from simulationTime (in days), /**
// with an offset so that simulationTime=0 corresponds to "Autumn 36". * Compute the fraction of the moon's disc illuminated as seen from the planet.
* We define vectors:
* M→S = (starX - moonX, starY - moonY)
* M→P = (planetX - moonX, planetY - moonY)
* Then, litFraction = (1 + cos(alpha))/2, where alpha is the angle between M→S and M→P.
* When alpha=0, fraction=1 (full), when alpha=π, fraction=0 (new).
*/
function getMoonLitFraction(moonX, moonY, starX, starY, planetX, planetY) {
const MSx = starX - moonX;
const MSy = starY - moonY;
const MPx = planetX - moonX;
const MPy = planetY - moonY;
const dot = MSx * MPx + MSy * MPy;
const magMS = Math.sqrt(MSx * MSx + MSy * MSy);
const magMP = Math.sqrt(MPx * MPx + MPy * MPy);
if (magMS < 1e-9 || magMP < 1e-9) return 0.0;
let cosAlpha = dot / (magMS * magMP);
cosAlpha = Math.max(-1, Math.min(1, cosAlpha));
return 1 - 0.5 * (1 + cosAlpha);
}
/**
* Given a lit fraction (0 to 1) and whether the moon is waxing, compute a phase emoji.
* We compute an effective phase angle:
* phaseAngle = arccos(2*frac - 1) in degrees.
* If waning, effectivePhase = 360 - phaseAngle.
* Then divide the 360° into eight segments.
*/
function getMoonPhaseEmoji(frac, waxing) {
// Compute phase angle in degrees.
let phaseAngle = Math.acos(2 * frac - 1) * (180 / Math.PI);
if (!waxing) {
phaseAngle = 360 - phaseAngle;
}
// Map phaseAngle to one of eight phases.
if (phaseAngle < 45) return "🌑"; // 0-45: New Moon
else if (phaseAngle < 90) return waxing ? "🌒" : "🌘";
else if (phaseAngle < 135) return waxing ? "🌓" : "🌗";
else if (phaseAngle < 180) return waxing ? "🌔" : "🌖";
else if (phaseAngle < 225) return "🌕"; // 180-225: Full Moon
else if (phaseAngle < 270) return waxing ? "🌔" : "🌖";
else if (phaseAngle < 315) return waxing ? "🌓" : "🌗";
else return waxing ? "🌒" : "🌘";
}
/////////////////////////////
// 2. Senthara Date and Cycle Info
/////////////////////////////
/**
* Returns the Senthara date as "Year X - <Season> Y".
* The epoch is offset so that simulationTime=0 corresponds to "Autumn 36".
*/
function getSentharaDate(simDays) { function getSentharaDate(simDays) {
const offset = 134; const offset = 134;
const X = Math.floor(simDays + offset); const X = Math.floor(simDays + offset);
@@ -68,71 +124,82 @@
const seasonIndex = Math.floor((dayOfYear - 1) / 99); const seasonIndex = Math.floor((dayOfYear - 1) / 99);
const dayOfSeason = dayOfYear - seasonIndex * 99; const dayOfSeason = dayOfYear - seasonIndex * 99;
const seasons = ["Summer", "Autumn", "Winter", "Spring"]; const seasons = ["Summer", "Autumn", "Winter", "Spring"];
return `Year ${year} - ${seasons[seasonIndex]} ${dayOfSeason}`; return `Year ${year} - ${seasons[seasonIndex]} Day ${dayOfSeason}`;
} }
// Phaser configuration (responsive) /////////////////////////////
// 3. Phaser Setup
/////////////////////////////
const config = { const config = {
type: Phaser.AUTO, type: Phaser.AUTO,
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
backgroundColor: "#000000", backgroundColor: "#000000",
scene: { scene: { preload, create, update },
preload: preload, scale: { mode: Phaser.Scale.RESIZE }
create: create,
update: update
},
scale: {
mode: Phaser.Scale.RESIZE
}
}; };
const game = new Phaser.Game(config); const game = new Phaser.Game(config);
let globalGraphics; let globalGraphics;
let dateText; let astroText; // Header text (top-left)
let simulationTime = 0; // in days (simulation time) let simulationTime = 0; // in days
let simulationSpeed = 5; // speed multiplier let simulationSpeed = 5; // speed multiplier
let isPlaying = false; // Start paused let isPlaying = false;
let isRewinding = false; // Control forward/backward let isRewinding = false;
// Orbital periods (in days) // Orbital periods (in days)
const planetPeriod = 396; // Senthara's orbital year around its star const planetPeriod = 396; // Planet's orbit around the star
const planetRotationPeriod = 1; // Planet rotates fully in 1 day const planetRotationPeriod = 1; // Planet rotates once per day
const kerielPeriod = 27; const kerielPeriod = 27;
const arkaenPeriod = 82; const arkaenPeriod = 82;
const minianPeriod = 98; const minianPeriod = 98;
// Eccentricity parameters (0 = circle; higher values = more elliptical) // Eccentricity values (0 = circle)
const planetEcc = 0.2; // Planet's orbit eccentricity const planetEcc = 0.2;
const kerielEcc = 0.05; // Moons tend to have near-circular orbits due to tidal locking const kerielEcc = 0.05;
const arkaenEcc = 0.05; const arkaenEcc = 0.05;
const minianEcc = 0.05; const minianEcc = 0.05;
// Orbital radii (semi-major axes) (computed relative to window size) // Full cycle lengths
const shortCycleLen = 108486; // ~274 years
const longCycleLen = 2386692; // ~6027 years
// Orbital radii (semi-major axes, computed relative to window size)
let planetOrbitRadius, kerielOrbitRadius, arkaenOrbitRadius, minianOrbitRadius; let planetOrbitRadius, kerielOrbitRadius, arkaenOrbitRadius, minianOrbitRadius;
// Containers for the planet and the moons. // Containers for the planet and moons.
let planetContainer; let planetContainer;
let kerielContainer, arkaenContainer, minianContainer; let kerielContainer, arkaenContainer, minianContainer;
function preload() { // Tilt indicator for planet's spin axis.
// No external assets are needed. let tiltIndicator;
} const tiltLength = 30;
const planetTiltDeg = 23.5;
const tiltIndicatorAngle = Phaser.Math.DegToRad(-90 + planetTiltDeg);
// Global star (sun) position.
let starX, starY;
// We'll store previous lit fraction values for waxing/waning detection.
let oldFracKeriel = 0, oldFracArkaen = 0, oldFracMinian = 0;
function preload() {}
function create() { function create() {
globalGraphics = this.add.graphics(); globalGraphics = this.add.graphics();
astroText = this.add.text(10, 10, "", {
dateText = this.add.text(10, game.scale.height - 30, "", {
font: "20px Arial", font: "20px Arial",
fill: "#ffffff" fill: "#ffffff"
}); });
recalcOrbitRadii(); recalcOrbitRadii();
starX = this.cameras.main.width / 2;
starY = this.cameras.main.height / 2;
// Create container for Senthara (the planet) // Create container for the planet.
planetContainer = this.add.container(0, 0); planetContainer = this.add.container(0, 0);
// Planet body (green circle) with a marker line.
let planetBody = this.add.graphics(); let planetBody = this.add.graphics();
planetBody.fillStyle(0x00FF00, 1); planetBody.fillStyle(0x00FF00, 1);
planetBody.fillCircle(0, 0, 12); planetBody.fillCircle(0, 0, 12);
@@ -143,7 +210,7 @@
planetBody.strokePath(); planetBody.strokePath();
planetContainer.add(planetBody); planetContainer.add(planetBody);
// Night overlay for day/night cycle (semi-transparent half-circle) // Planet night overlay.
let nightOverlay = this.add.graphics(); let nightOverlay = this.add.graphics();
nightOverlay.fillStyle(0x000000, 0.5); nightOverlay.fillStyle(0x000000, 0.5);
nightOverlay.slice(0, 0, 12, 0, Math.PI, false); nightOverlay.slice(0, 0, 12, 0, Math.PI, false);
@@ -151,138 +218,200 @@
planetContainer.nightOverlay = nightOverlay; planetContainer.nightOverlay = nightOverlay;
planetContainer.add(nightOverlay); planetContainer.add(nightOverlay);
// Create containers for each moon. // Create moon containers.
kerielContainer = createMoonContainer(this, 6, 0xFF0000); // Keriel: red kerielContainer = createMoonContainer(this, 6, 0xFF0000);
arkaenContainer = createMoonContainer(this, 5, 0x0000FF); // Arkaen: blue arkaenContainer = createMoonContainer(this, 5, 0x0000FF);
minianContainer = createMoonContainer(this, 5, 0xFFFFFF); // Minian: white minianContainer = createMoonContainer(this, 5, 0xFFFFFF);
// UI Control Handlers // Add night overlays for moons.
kerielContainer.add(createMoonNightOverlay(this, 6));
arkaenContainer.add(createMoonNightOverlay(this, 5));
minianContainer.add(createMoonNightOverlay(this, 5));
// Create tilt indicator.
tiltIndicator = this.add.graphics();
// UI event handlers.
const playPauseButton = document.getElementById("playPauseButton"); const playPauseButton = document.getElementById("playPauseButton");
const rewindButton = document.getElementById("rewindButton"); const rewindButton = document.getElementById("rewindButton");
const speedSelect = document.getElementById("speedSelect"); const speedSelect = document.getElementById("speedSelect");
playPauseButton.addEventListener("click", () => { playPauseButton.addEventListener("click", () => {
isPlaying = !isPlaying; isPlaying = !isPlaying;
playPauseButton.textContent = isPlaying ? "Pause" : "Play"; playPauseButton.textContent = isPlaying ? "Pause" : "Play";
if (isPlaying) isRewinding = false; if (isPlaying) isRewinding = false;
}); });
rewindButton.addEventListener("click", () => { rewindButton.addEventListener("click", () => {
isRewinding = !isRewinding; isRewinding = !isRewinding;
rewindButton.textContent = isRewinding ? "Forward" : "Rewind"; rewindButton.textContent = isRewinding ? "Forward" : "Rewind";
if(isRewinding) isPlaying = false; if (isRewinding) isPlaying = false;
playPauseButton.textContent = "Play"; playPauseButton.textContent = "Play";
}); });
speedSelect.addEventListener("change", () => { speedSelect.addEventListener("change", () => {
simulationSpeed = parseFloat(speedSelect.value); simulationSpeed = parseFloat(speedSelect.value);
}); });
this.scale.on('resize', (gameSize) => { this.scale.on('resize', (gameSize) => {
recalcOrbitRadii(); recalcOrbitRadii();
dateText.setPosition(10, gameSize.height - 30); astroText.setPosition(10, 10);
starX = gameSize.width / 2;
starY = gameSize.height / 2;
}); });
} }
// Helper function to create a moon container with a circular body and a marker. // Helper: Create a moon container with a circular body and a marker.
function createMoonContainer(scene, radius, color) { function createMoonContainer(scene, radius, color) {
let moonContainer = scene.add.container(0, 0); let container = scene.add.container(0, 0);
let moonBody = scene.add.graphics(); let body = scene.add.graphics();
moonBody.fillStyle(color, 1); body.fillStyle(color, 1);
moonBody.fillCircle(0, 0, radius); body.fillCircle(0, 0, radius);
moonBody.lineStyle(2, 0x000000, 1); body.lineStyle(2, 0x000000, 1);
moonBody.beginPath(); body.beginPath();
moonBody.moveTo(0, 0); body.moveTo(0, 0);
moonBody.lineTo(radius, 0); body.lineTo(radius, 0);
moonBody.strokePath(); body.strokePath();
moonContainer.add(moonBody); container.add(body);
return moonContainer; return container;
}
// Helper: Create a half-circle night overlay for a moon.
function createMoonNightOverlay(scene, radius) {
let overlay = scene.add.graphics();
overlay.fillStyle(0x000000, 0.5);
overlay.slice(0, 0, radius, 0, Math.PI, false);
overlay.fillPath();
return overlay;
} }
// Recalculate orbital radii based on window size. // Recalculate orbital radii based on window size.
function recalcOrbitRadii() { function recalcOrbitRadii() {
const minDim = Math.min(window.innerWidth, window.innerHeight); const minDim = Math.min(window.innerWidth, window.innerHeight);
planetOrbitRadius = minDim * 0.3; // semi-major axis for planet orbit planetOrbitRadius = minDim * 0.3;
kerielOrbitRadius = planetOrbitRadius * 0.25; kerielOrbitRadius = planetOrbitRadius * 0.25;
arkaenOrbitRadius = planetOrbitRadius * 0.35; arkaenOrbitRadius = planetOrbitRadius * 0.35;
minianOrbitRadius = planetOrbitRadius * 0.45; minianOrbitRadius = planetOrbitRadius * 0.45;
} }
function update(time, delta) { function update(time, delta) {
// Advance or rewind simulation time.
if (isPlaying) { if (isPlaying) {
simulationTime += (delta * simulationSpeed) / 1000; simulationTime += (delta * simulationSpeed) / 1000;
} else if (isRewinding) { } else if (isRewinding) {
simulationTime -= (delta * simulationSpeed) / 1000; simulationTime -= (delta * simulationSpeed) / 1000;
} }
const centerX = game.scale.width / 2;
const centerY = game.scale.height / 2;
globalGraphics.clear(); globalGraphics.clear();
// Draw the central star. // Draw the central star.
globalGraphics.fillStyle(0xFFFF00, 1); globalGraphics.fillStyle(0xFFFF00, 1);
globalGraphics.fillCircle(centerX, centerY, 20); globalGraphics.fillCircle(starX, starY, 20);
// Draw the planet's elliptical orbital path around the star. // Draw planet's elliptical orbit.
const bPlanet = planetOrbitRadius * Math.sqrt(1 - planetEcc * planetEcc); const bPlanet = planetOrbitRadius * Math.sqrt(1 - planetEcc * planetEcc);
globalGraphics.lineStyle(1, 0x555555, 1); globalGraphics.lineStyle(1, 0x555555, 1);
globalGraphics.strokeEllipse(centerX, centerY, 2 * planetOrbitRadius, 2 * bPlanet); globalGraphics.strokeEllipse(starX, starY, 2 * planetOrbitRadius, 2 * bPlanet);
// Get planet's position on its elliptical orbit. // Compute planet's position.
const planetPos = getEllipticalPosition(simulationTime, planetPeriod, planetOrbitRadius, planetEcc); const planetPos = getEllipticalPosition(simulationTime, planetPeriod, planetOrbitRadius, planetEcc);
const planetX = centerX + planetPos.x; const planetX = starX + planetPos.x;
const planetY = centerY + planetPos.y; const planetY = starY + planetPos.y;
// Update planet container position.
planetContainer.x = planetX; planetContainer.x = planetX;
planetContainer.y = planetY; planetContainer.y = planetY;
// Planet rotates about its own axis with a 1-day period. const planetRotationAngle = Phaser.Math.DegToRad(360 * (simulationTime % planetRotationPeriod) / planetRotationPeriod);
const planetRotationAngle = Phaser.Math.DegToRad((360 * (simulationTime % planetRotationPeriod)) / planetRotationPeriod);
planetContainer.rotation = planetRotationAngle; planetContainer.rotation = planetRotationAngle;
const subsolarAnglePlanet = Phaser.Math.Angle.Between(planetX, planetY, starX, starY);
planetContainer.nightOverlay.rotation = subsolarAnglePlanet + Math.PI/2 - planetContainer.rotation;
// Update night overlay so that the dark half covers the hemisphere away from the star. // Draw tilt indicator.
const subsolarAngle = Phaser.Math.Angle.Between(planetX, planetY, centerX, centerY); tiltIndicator.clear();
planetContainer.nightOverlay.rotation = subsolarAngle + Math.PI / 2 - planetContainer.rotation; tiltIndicator.lineStyle(2, 0x00FFFF, 1);
const dx = (tiltLength/2) * Math.cos(tiltIndicatorAngle);
const dy = (tiltLength/2) * Math.sin(tiltIndicatorAngle);
tiltIndicator.strokeLineShape(new Phaser.Geom.Line(
planetX - dx, planetY - dy,
planetX + dx, planetY + dy
));
// Draw moon orbital paths (elliptical) around Senthara. // Draw moon orbits around the planet.
// For each moon, compute semi-minor axis: b = a * sqrt(1 - ecc^2). drawMoonOrbit(planetX, planetY, kerielOrbitRadius, kerielEcc, 0x888888);
const bKeriel = kerielOrbitRadius * Math.sqrt(1 - kerielEcc * kerielEcc); drawMoonOrbit(planetX, planetY, arkaenOrbitRadius, arkaenEcc, 0x888888);
const bArkaen = arkaenOrbitRadius * Math.sqrt(1 - arkaenEcc * arkaenEcc); drawMoonOrbit(planetX, planetY, minianOrbitRadius, minianEcc, 0x888888);
const bMinian = minianOrbitRadius * Math.sqrt(1 - minianEcc * minianEcc);
globalGraphics.lineStyle(1, 0x888888, 1);
globalGraphics.strokeEllipse(planetX, planetY, 2 * kerielOrbitRadius, 2 * bKeriel);
globalGraphics.strokeEllipse(planetX, planetY, 2 * arkaenOrbitRadius, 2 * bArkaen);
globalGraphics.strokeEllipse(planetX, planetY, 2 * minianOrbitRadius, 2 * bMinian);
// Calculate and update moon positions relative to Senthara. // Update each moon.
updateMoon(kerielContainer, kerielOrbitRadius, kerielEcc, kerielPeriod);
updateMoon(arkaenContainer, arkaenOrbitRadius, arkaenEcc, arkaenPeriod);
updateMoon(minianContainer, minianOrbitRadius, minianEcc, minianPeriod);
// Build astronomical header text.
const astroInfo = buildAstronomicalText(planetX, planetY);
astroText.setText(astroInfo);
}
// Draw elliptical orbit centered at (px,py) with semi-major axis a and eccentricity ecc.
function drawMoonOrbit(px, py, a, ecc, color) {
const b = a * Math.sqrt(1 - ecc * ecc);
globalGraphics.lineStyle(1, color, 1);
globalGraphics.strokeEllipse(px, py, 2 * a, 2 * b);
}
// Update a moon's position, tidal locking, and its night overlay.
function updateMoon(moonContainer, a, ecc, period) {
const pos = getEllipticalPosition(simulationTime, period, a, ecc);
const moonX = planetContainer.x + pos.x;
const moonY = planetContainer.y + pos.y;
moonContainer.x = moonX;
moonContainer.y = moonY;
moonContainer.rotation = Phaser.Math.Angle.Between(moonX, moonY, planetContainer.x, planetContainer.y);
const overlay = moonContainer.list[moonContainer.list.length - 1];
const subsolarAngleMoon = Phaser.Math.Angle.Between(moonX, moonY, starX, starY);
overlay.rotation = subsolarAngleMoon + Math.PI/2 - moonContainer.rotation;
}
// Build the astronomical header text.
function buildAstronomicalText(planetX, planetY) {
let info = "Senthara\n";
info += "Date: " + getSentharaDate(simulationTime) + "\n";
// For each moon, compute its lit fraction and determine waxing/waning.
// Keriel: // Keriel:
const kerielPos = getEllipticalPosition(simulationTime, kerielPeriod, kerielOrbitRadius, kerielEcc); const kerielX = kerielContainer.x;
const kerielX = planetX + kerielPos.x; const kerielY = kerielContainer.y;
const kerielY = planetY + kerielPos.y; let fracKeriel = getMoonLitFraction(kerielX, kerielY, starX, starY, planetX, planetY);
kerielContainer.x = kerielX; let waxingKeriel = (fracKeriel >= oldFracKeriel);
kerielContainer.y = kerielY; let emojiKeriel = getMoonPhaseEmoji(fracKeriel, waxingKeriel);
kerielContainer.rotation = Phaser.Math.Angle.Between(kerielX, kerielY, planetX, planetY); let kerielDay = Math.floor(simulationTime % kerielPeriod) + 1;
oldFracKeriel = fracKeriel;
info += `Keriel Day: ${kerielDay} (Illum=${(fracKeriel * 100).toFixed(0)}% ${emojiKeriel})\n`;
// Arkaen: // Arkaen:
const arkaenPos = getEllipticalPosition(simulationTime, arkaenPeriod, arkaenOrbitRadius, arkaenEcc); const arkaenX = arkaenContainer.x;
const arkaenX = planetX + arkaenPos.x; const arkaenY = arkaenContainer.y;
const arkaenY = planetY + arkaenPos.y; let fracArkaen = getMoonLitFraction(arkaenX, arkaenY, starX, starY, planetX, planetY);
arkaenContainer.x = arkaenX; let waxingArkaen = (fracArkaen >= oldFracArkaen);
arkaenContainer.y = arkaenY; let emojiArkaen = getMoonPhaseEmoji(fracArkaen, waxingArkaen);
arkaenContainer.rotation = Phaser.Math.Angle.Between(arkaenX, arkaenY, planetX, planetY); let arkaenDay = Math.floor(simulationTime % arkaenPeriod) + 1;
oldFracArkaen = fracArkaen;
info += `Arkaen Day: ${arkaenDay} (Illum=${(fracArkaen * 100).toFixed(0)}% ${emojiArkaen})\n`;
// Minian: // Minian:
const minianPos = getEllipticalPosition(simulationTime, minianPeriod, minianOrbitRadius, minianEcc); const minianX = minianContainer.x;
const minianX = planetX + minianPos.x; const minianY = minianContainer.y;
const minianY = planetY + minianPos.y; let fracMinian = getMoonLitFraction(minianX, minianY, starX, starY, planetX, planetY);
minianContainer.x = minianX; let waxingMinian = (fracMinian >= oldFracMinian);
minianContainer.y = minianY; let emojiMinian = getMoonPhaseEmoji(fracMinian, waxingMinian);
minianContainer.rotation = Phaser.Math.Angle.Between(minianX, minianY, planetX, planetY); let minianDay = Math.floor(simulationTime % minianPeriod) + 1;
oldFracMinian = fracMinian;
// Update the Senthara calendar date text. info += `Minian Day: ${minianDay} (Illum=${(fracMinian * 100).toFixed(0)}% ${emojiMinian})\n`;
dateText.setText(getSentharaDate(simulationTime));
// Cycle progress.
let shortProg = Math.floor(simulationTime % shortCycleLen);
let longProg = Math.floor(simulationTime % longCycleLen);
info += `Short Cycle: ${shortProg} / ${shortCycleLen} days (~274 years)\n`;
info += `Long Cycle: ${longProg} / ${longCycleLen} days (~6027 years)`;
return info;
} }
</script> </script>
</body> </body>