Изменить 'wbld/orbits.html'
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Senthara Orbit and Rotation Visualization</title>
|
<title>Senthara Orbit, Rotation & Day/Night Visualization</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; }
|
||||||
@@ -12,13 +12,16 @@
|
|||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
// Function to calculate the current Senthara date from simulationTime (in days)
|
// Function to calculate the current Senthara date from simulationTime (in days)
|
||||||
|
// We add an offset so that simulationTime = 0 corresponds to "Autumn 36"
|
||||||
|
// With a 396-day year divided evenly into 4 seasons, an offset of 134 ensures:
|
||||||
|
// floor(134) mod 99 = 35 so that dayOfSeason becomes 35+1 = 36 and seasonIndex = 1 (Autumn).
|
||||||
function getSentharaDate(simDays) {
|
function getSentharaDate(simDays) {
|
||||||
// Total days per year is 396
|
const offset = 134;
|
||||||
const year = Math.floor(simDays / 396) + 1;
|
const X = Math.floor(simDays + offset);
|
||||||
const dayOfYear = (Math.floor(simDays) % 396) + 1;
|
const year = Math.floor(X / 396) + 1;
|
||||||
// Each season is 99 days.
|
const dayOfYear = (X % 396) + 1;
|
||||||
const seasonIndex = Math.floor((dayOfYear - 1) / 99);
|
const seasonIndex = Math.floor((dayOfYear - 1) / 99);
|
||||||
const dayOfSeason = ((dayOfYear - 1) % 99) + 1;
|
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]} ${dayOfSeason}`;
|
||||||
}
|
}
|
||||||
@@ -44,24 +47,24 @@
|
|||||||
let globalGraphics;
|
let globalGraphics;
|
||||||
let dateText;
|
let dateText;
|
||||||
let simulationTime = 0; // in days (simulation time)
|
let simulationTime = 0; // in days (simulation time)
|
||||||
const simulationSpeed = 10; // Speed multiplier
|
const simulationSpeed = 0.05; // speed multiplier
|
||||||
|
|
||||||
// Orbital periods (in days)
|
// Orbital periods (in days)
|
||||||
const planetPeriod = 396; // Senthara's orbit (year)
|
const planetPeriod = 396; // Senthara's orbital year
|
||||||
const planetRotationPeriod = 1; // Planet rotates fully in 1 day
|
const planetRotationPeriod = 1; // Planet rotates fully in 1 day
|
||||||
const kerielPeriod = 27;
|
const kerielPeriod = 27;
|
||||||
const arkaenPeriod = 82;
|
const arkaenPeriod = 82;
|
||||||
const minianPeriod = 98;
|
const minianPeriod = 98;
|
||||||
|
|
||||||
// Orbital radii (will be computed relative to window size)
|
// Orbital radii (computed relative to window size)
|
||||||
let planetOrbitRadius, kerielOrbitRadius, arkaenOrbitRadius, minianOrbitRadius;
|
let planetOrbitRadius, kerielOrbitRadius, arkaenOrbitRadius, minianOrbitRadius;
|
||||||
|
|
||||||
// Containers for planet and moons
|
// Containers for the planet and the moons
|
||||||
let planetContainer;
|
let planetContainer;
|
||||||
let kerielContainer, arkaenContainer, minianContainer;
|
let kerielContainer, arkaenContainer, minianContainer;
|
||||||
|
|
||||||
function preload() {
|
function preload() {
|
||||||
// No external assets are loaded.
|
// No external assets are needed.
|
||||||
}
|
}
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
@@ -72,43 +75,37 @@
|
|||||||
fill: "#ffffff"
|
fill: "#ffffff"
|
||||||
});
|
});
|
||||||
|
|
||||||
// Calculate orbital radii based on window size.
|
|
||||||
recalcOrbitRadii();
|
recalcOrbitRadii();
|
||||||
|
|
||||||
// Create planet container.
|
// Create a container for Senthara (the planet)
|
||||||
planetContainer = this.add.container(0, 0);
|
planetContainer = this.add.container(0, 0);
|
||||||
|
|
||||||
// Create a Graphics object for the planet body.
|
// Draw the planet body (green circle) with a marker for rotation.
|
||||||
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);
|
||||||
// Add a marker line (pointing to the right, 0 deg) to indicate surface rotation.
|
// Marker line (points to the right)
|
||||||
planetBody.lineStyle(2, 0x000000, 1);
|
planetBody.lineStyle(2, 0x000000, 1);
|
||||||
planetBody.beginPath();
|
planetBody.beginPath();
|
||||||
planetBody.moveTo(0, 0);
|
planetBody.moveTo(0, 0);
|
||||||
planetBody.lineTo(12, 0);
|
planetBody.lineTo(12, 0);
|
||||||
planetBody.closePath();
|
|
||||||
planetBody.strokePath();
|
planetBody.strokePath();
|
||||||
|
|
||||||
// Add the planet body to the container.
|
|
||||||
planetContainer.add(planetBody);
|
planetContainer.add(planetBody);
|
||||||
|
|
||||||
// Create a night overlay that will cover the "dark" half of the planet.
|
// Create a night overlay (semi-transparent dark half-circle)
|
||||||
// Draw a half-circle (180° arc) from 0 to PI.
|
|
||||||
let nightOverlay = this.add.graphics();
|
let nightOverlay = this.add.graphics();
|
||||||
nightOverlay.fillStyle(0x000000, 0.5);
|
nightOverlay.fillStyle(0x000000, 0.5);
|
||||||
// Draw the half circle with radius 12.
|
// Draw a half-circle (180° arc) with radius 12
|
||||||
nightOverlay.slice(0, 0, 12, 0, Math.PI, false);
|
nightOverlay.slice(0, 0, 12, 0, Math.PI, false);
|
||||||
nightOverlay.fillPath();
|
nightOverlay.fillPath();
|
||||||
// Store it as a property for updating later.
|
// Save as a property for updating its rotation later.
|
||||||
planetContainer.nightOverlay = nightOverlay;
|
planetContainer.nightOverlay = nightOverlay;
|
||||||
// Add the overlay on top of the planet.
|
|
||||||
planetContainer.add(nightOverlay);
|
planetContainer.add(nightOverlay);
|
||||||
|
|
||||||
// Create containers for each moon.
|
// Create containers for each moon.
|
||||||
kerielContainer = createMoonContainer(this, 6, 0xFF0000); // Keriel: radius 6, red
|
kerielContainer = createMoonContainer(this, 6, 0xFF0000); // Keriel: red
|
||||||
arkaenContainer = createMoonContainer(this, 5, 0x0000FF); // Arkaen: radius 5, blue
|
arkaenContainer = createMoonContainer(this, 5, 0x0000FF); // Arkaen: blue
|
||||||
minianContainer = createMoonContainer(this, 5, 0xFFFFFF); // Minian: radius 5, white
|
minianContainer = createMoonContainer(this, 5, 0xFFFFFF); // Minian: white
|
||||||
|
|
||||||
// Listen for window resize events.
|
// Listen for window resize events.
|
||||||
this.scale.on('resize', (gameSize) => {
|
this.scale.on('resize', (gameSize) => {
|
||||||
@@ -123,21 +120,20 @@
|
|||||||
let moonBody = scene.add.graphics();
|
let moonBody = scene.add.graphics();
|
||||||
moonBody.fillStyle(color, 1);
|
moonBody.fillStyle(color, 1);
|
||||||
moonBody.fillCircle(0, 0, radius);
|
moonBody.fillCircle(0, 0, radius);
|
||||||
// Draw a marker (line) indicating the "front" of the moon.
|
// Marker line indicating the "front" of the moon.
|
||||||
moonBody.lineStyle(2, 0x000000, 1);
|
moonBody.lineStyle(2, 0x000000, 1);
|
||||||
moonBody.beginPath();
|
moonBody.beginPath();
|
||||||
moonBody.moveTo(0, 0);
|
moonBody.moveTo(0, 0);
|
||||||
moonBody.lineTo(radius, 0);
|
moonBody.lineTo(radius, 0);
|
||||||
moonBody.closePath();
|
|
||||||
moonBody.strokePath();
|
moonBody.strokePath();
|
||||||
moonContainer.add(moonBody);
|
moonContainer.add(moonBody);
|
||||||
return moonContainer;
|
return moonContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate orbital radii based on the window size.
|
// Recalculate orbital radii based on the current 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; // 30% of smaller dimension
|
planetOrbitRadius = minDim * 0.3; // 30% of the smaller dimension
|
||||||
kerielOrbitRadius = planetOrbitRadius * 0.25;
|
kerielOrbitRadius = planetOrbitRadius * 0.25;
|
||||||
arkaenOrbitRadius = planetOrbitRadius * 0.35;
|
arkaenOrbitRadius = planetOrbitRadius * 0.35;
|
||||||
minianOrbitRadius = planetOrbitRadius * 0.45;
|
minianOrbitRadius = planetOrbitRadius * 0.45;
|
||||||
@@ -147,51 +143,49 @@
|
|||||||
// Advance simulation time.
|
// Advance simulation time.
|
||||||
simulationTime += (delta * simulationSpeed) / 1000;
|
simulationTime += (delta * simulationSpeed) / 1000;
|
||||||
|
|
||||||
// Clear global graphics and redraw orbit paths.
|
// Get center of the screen (position of the star).
|
||||||
globalGraphics.clear();
|
|
||||||
|
|
||||||
// Center of the star (sun) at center of screen.
|
|
||||||
const centerX = game.scale.width / 2;
|
const centerX = game.scale.width / 2;
|
||||||
const centerY = game.scale.height / 2;
|
const centerY = game.scale.height / 2;
|
||||||
|
|
||||||
// Draw the star.
|
// Clear global graphics.
|
||||||
|
globalGraphics.clear();
|
||||||
|
|
||||||
|
// Draw the central star.
|
||||||
globalGraphics.fillStyle(0xFFFF00, 1);
|
globalGraphics.fillStyle(0xFFFF00, 1);
|
||||||
globalGraphics.fillCircle(centerX, centerY, 20);
|
globalGraphics.fillCircle(centerX, centerY, 20);
|
||||||
|
|
||||||
// Draw Senthara's orbital path around the star.
|
// Draw Senthara's orbital path (around the star).
|
||||||
globalGraphics.lineStyle(1, 0x555555, 1);
|
globalGraphics.lineStyle(1, 0x555555, 1);
|
||||||
globalGraphics.strokeCircle(centerX, centerY, planetOrbitRadius);
|
globalGraphics.strokeCircle(centerX, centerY, planetOrbitRadius);
|
||||||
|
|
||||||
// Calculate Senthara's (planet's) orbital position.
|
// Calculate Senthara's (the planet's) position along its orbit.
|
||||||
const planetOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % planetPeriod)) / planetPeriod - 90);
|
const planetOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % planetPeriod)) / planetPeriod - 90);
|
||||||
const planetX = centerX + planetOrbitRadius * Math.cos(planetOrbitAngle);
|
const planetX = centerX + planetOrbitRadius * Math.cos(planetOrbitAngle);
|
||||||
const planetY = centerY + planetOrbitRadius * Math.sin(planetOrbitAngle);
|
const planetY = centerY + planetOrbitRadius * Math.sin(planetOrbitAngle);
|
||||||
|
|
||||||
// Update planet container position.
|
// Update the planet container's position.
|
||||||
planetContainer.x = planetX;
|
planetContainer.x = planetX;
|
||||||
planetContainer.y = planetY;
|
planetContainer.y = planetY;
|
||||||
// Planet rotation (self-rotation) on a period of 1 day.
|
// Set the planet's self-rotation (day/night cycle) 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;
|
||||||
|
|
||||||
// Determine the subsolar angle (direction from planet to star).
|
// Update the night overlay so that the dark half covers the side away from the star.
|
||||||
const subsolarAngle = Phaser.Math.Angle.Between(planetX, planetY, centerX, centerY);
|
const subsolarAngle = Phaser.Math.Angle.Between(planetX, planetY, centerX, centerY);
|
||||||
// The terminator line on the planet should be perpendicular to the sun direction.
|
// The night overlay's rotation is adjusted relative to the planet's rotation.
|
||||||
// Update the night overlay's rotation so that its dark half covers the night side.
|
planetContainer.nightOverlay.rotation = subsolarAngle + Math.PI / 2 - planetContainer.rotation;
|
||||||
// Because the nightOverlay is a child of planetContainer, subtract the planet's rotation.
|
|
||||||
planetContainer.nightOverlay.rotation = subsolarAngle + Math.PI/2 - planetContainer.rotation;
|
|
||||||
|
|
||||||
// Calculate positions for each moon relative to Senthara.
|
// Calculate and update moon positions (relative to Senthara).
|
||||||
// Keriel
|
// Keriel:
|
||||||
const kerielOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % kerielPeriod)) / kerielPeriod - 90);
|
const kerielOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % kerielPeriod)) / kerielPeriod - 90);
|
||||||
const kerielX = planetX + kerielOrbitRadius * Math.cos(kerielOrbitAngle);
|
const kerielX = planetX + kerielOrbitRadius * Math.cos(kerielOrbitAngle);
|
||||||
const kerielY = planetY + kerielOrbitRadius * Math.sin(kerielOrbitAngle);
|
const kerielY = planetY + kerielOrbitRadius * Math.sin(kerielOrbitAngle);
|
||||||
kerielContainer.x = kerielX;
|
kerielContainer.x = kerielX;
|
||||||
kerielContainer.y = kerielY;
|
kerielContainer.y = kerielY;
|
||||||
// Tidal locking: set moon's rotation so that its marker points toward Senthara.
|
// Ensure tidal locking: set Keriel's rotation so its marker points toward Senthara.
|
||||||
kerielContainer.rotation = Phaser.Math.Angle.Between(kerielX, kerielY, planetX, planetY);
|
kerielContainer.rotation = Phaser.Math.Angle.Between(kerielX, kerielY, planetX, planetY);
|
||||||
|
|
||||||
// Arkaen
|
// Arkaen:
|
||||||
const arkaenOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % arkaenPeriod)) / arkaenPeriod - 90);
|
const arkaenOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % arkaenPeriod)) / arkaenPeriod - 90);
|
||||||
const arkaenX = planetX + arkaenOrbitRadius * Math.cos(arkaenOrbitAngle);
|
const arkaenX = planetX + arkaenOrbitRadius * Math.cos(arkaenOrbitAngle);
|
||||||
const arkaenY = planetY + arkaenOrbitRadius * Math.sin(arkaenOrbitAngle);
|
const arkaenY = planetY + arkaenOrbitRadius * Math.sin(arkaenOrbitAngle);
|
||||||
@@ -199,7 +193,7 @@
|
|||||||
arkaenContainer.y = arkaenY;
|
arkaenContainer.y = arkaenY;
|
||||||
arkaenContainer.rotation = Phaser.Math.Angle.Between(arkaenX, arkaenY, planetX, planetY);
|
arkaenContainer.rotation = Phaser.Math.Angle.Between(arkaenX, arkaenY, planetX, planetY);
|
||||||
|
|
||||||
// Minian
|
// Minian:
|
||||||
const minianOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % minianPeriod)) / minianPeriod - 90);
|
const minianOrbitAngle = Phaser.Math.DegToRad((360 * (simulationTime % minianPeriod)) / minianPeriod - 90);
|
||||||
const minianX = planetX + minianOrbitRadius * Math.cos(minianOrbitAngle);
|
const minianX = planetX + minianOrbitRadius * Math.cos(minianOrbitAngle);
|
||||||
const minianY = planetY + minianOrbitRadius * Math.sin(minianOrbitAngle);
|
const minianY = planetY + minianOrbitRadius * Math.sin(minianOrbitAngle);
|
||||||
@@ -207,7 +201,7 @@
|
|||||||
minianContainer.y = minianY;
|
minianContainer.y = minianY;
|
||||||
minianContainer.rotation = Phaser.Math.Angle.Between(minianX, minianY, planetX, planetY);
|
minianContainer.rotation = Phaser.Math.Angle.Between(minianX, minianY, planetX, planetY);
|
||||||
|
|
||||||
// Optionally, redraw the orbits of the moons (around Senthara).
|
// Optionally, redraw the moons' orbital paths (around Senthara).
|
||||||
globalGraphics.lineStyle(1, 0x888888, 1);
|
globalGraphics.lineStyle(1, 0x888888, 1);
|
||||||
globalGraphics.strokeCircle(planetX, planetY, kerielOrbitRadius);
|
globalGraphics.strokeCircle(planetX, planetY, kerielOrbitRadius);
|
||||||
globalGraphics.strokeCircle(planetX, planetY, arkaenOrbitRadius);
|
globalGraphics.strokeCircle(planetX, planetY, arkaenOrbitRadius);
|
||||||
|
|||||||
Reference in New Issue
Block a user