more ui fixes

This commit is contained in:
Demetri Pirpiris 2025-03-15 12:33:29 -06:00
parent f88acb2182
commit e7623335d3
3 changed files with 258 additions and 113 deletions

View File

@ -7,16 +7,17 @@
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- Wrap canvas in a scalable container -->
<div id="simCanvasWrapper">
<canvas id="simCanvas"></canvas>
</div>
<!-- Loading Overlay -->
<div id="loadingOverlay">
<div class="sinewave">Fast Forwarding...</div>
</div>
<!-- Small "?" Help Button -->
<button id="helpButton" class="help-button">?</button>
<!-- Help Modal (Hidden By Default) -->
<div id="helpModal" class="help-modal">
<div class="help-content">
@ -45,6 +46,8 @@
<div id="controlPanel" class="control-panel">
<div class="header">
Simulation Controls
<!-- Move the help button here -->
<button id="helpButton" class="help-button">?</button>
<button class="minimize"></button>
</div>
<div class="content">
@ -54,8 +57,8 @@
<button class="tabBtn active" data-tab="rewardTab">Reward</button>
<button class="tabBtn" data-tab="foodTab">Food</button>
<button class="tabBtn" data-tab="snakesTab">Snakes</button>
<button class="tabBtn" data-tab="evolutionTab">Evolution</button>
<button class="tabBtn" data-tab="environmentTab">Environment</button>
<!-- Combine Evolution + Environment => 'World' main tab -->
<button class="tabBtn" data-tab="worldTab">World</button>
</div>
<!-- REWARD TAB (with 2 sub-tabs) -->
@ -159,10 +162,17 @@
</div>
</div>
<!-- SNAKES TAB -->
<!-- SNAKES TAB (now subdivided) -->
<div id="snakesTab" class="tab-content">
<div class="tab-buttons snakes-subtabs">
<button class="tabBtn active" data-subtab="snakesGeneralSubTab">General</button>
<button class="tabBtn" data-subtab="snakesBoostSubTab">Boost &amp; Turn</button>
</div>
<!-- Sub-tab 1: General -->
<div id="snakesGeneralSubTab" class="snakes-sub-content active">
<div class="tab-description">
Control the number of snakes and their intelligence or speed.
Control the basic snake population, speed, and brain size.
</div>
<div class="control-group">
<label for="snakeCountSlider">Snake Count:</label>
@ -180,37 +190,6 @@
Snakes turn at a rate up to 0.15 / (lengthFactor) * speed; higher is more agile.
</div>
</div>
<!-- New Slider: Base Turn Rate -->
<div class="control-group">
<label for="turnRateSlider">Base Turn Rate:</label>
<input type="range" id="turnRateSlider" min="0.01" max="0.3" step="0.01" value="0.15">
<span id="turnRateVal">0.15</span>
<div class="setting-description">
Controls how sharply snakes can turn (before factoring in size).
</div>
</div>
<!-- New Slider: Boost Cost (length/sec) -->
<div class="control-group">
<label for="boostCostSlider">Boost Cost (length/sec):</label>
<input type="range" id="boostCostSlider" min="0" max="5" step="0.1" value="1">
<span id="boostCostVal">1</span>
<div class="setting-description">
How many body length units are spent per second while boosting.
</div>
</div>
<!-- New Slider: Boost Speed Multiplier -->
<div class="control-group">
<label for="boostMultiplierSlider">Boost Speed Multiplier:</label>
<input type="range" id="boostMultiplierSlider" min="1" max="3" step="0.1" value="2">
<span id="boostMultiplierVal">2</span>
<div class="setting-description">
How much faster the snake goes when boosting.
</div>
</div>
<div class="control-group">
<label for="brainSizeSlider">Brain Size:</label>
<input type="range" id="brainSizeSlider" min="5" max="50" value="15" step="1">
@ -221,8 +200,70 @@
</div>
</div>
<!-- EVOLUTION TAB -->
<div id="evolutionTab" class="tab-content">
<!-- Sub-tab 2: Boost & Turn -->
<div id="snakesBoostSubTab" class="snakes-sub-content">
<div class="tab-description">
Manage the base turn rate and boosting parameters.
</div>
<div class="control-group">
<label for="turnRateSlider">Base Turn Rate:</label>
<input type="range" id="turnRateSlider" min="0.01" max="0.3" step="0.01" value="0.15">
<span id="turnRateVal">0.15</span>
<div class="setting-description">
Controls how sharply snakes can turn (before factoring in size).
</div>
</div>
<div class="control-group">
<label for="boostCostSlider">Boost Cost (length/sec):</label>
<input type="range" id="boostCostSlider" min="0" max="5" step="0.1" value="1">
<span id="boostCostVal">1</span>
<div class="setting-description">
How many body length units are spent per second while boosting.
</div>
</div>
<div class="control-group">
<label for="boostMultiplierSlider">Boost Speed Multiplier:</label>
<input type="range" id="boostMultiplierSlider" min="1" max="3" step="0.1" value="2">
<span id="boostMultiplierVal">2</span>
<div class="setting-description">
How much faster the snake goes when boosting.
</div>
</div>
</div>
</div>
<!-- COMBINED "WORLD" TAB with 2 sub-tabs (Environment + Evolution) -->
<div id="worldTab" class="tab-content">
<div class="tab-buttons world-subtabs">
<button class="tabBtn active" data-subtab="worldEnvSubTab">Environment</button>
<button class="tabBtn" data-subtab="worldEvoSubTab">Evolution</button>
</div>
<!-- Sub-tab 1: Environment (old environmentTab content) -->
<div id="worldEnvSubTab" class="world-sub-content active">
<div class="tab-description">
Adjust environmental parameters that affect food and snake respawning.
</div>
<div class="control-group">
<label for="foodDecayTimeSlider">Food Decay Time:</label>
<input type="range" id="foodDecayTimeSlider" min="500" max="5000" value="2000" step="100">
<span id="foodDecayTimeVal">2000</span>
<div class="setting-description">
Time (ms) before dropped food disappears.
</div>
</div>
<div class="control-group">
<label for="respawnDelaySlider">Respawn Delay:</label>
<input type="range" id="respawnDelaySlider" min="0" max="5" value="0" step="0.5">
<span id="respawnDelayVal">0</span>
<div class="setting-description">
Delay (sec) before a new snake spawns after one dies.
</div>
</div>
</div>
<!-- Sub-tab 2: Evolution (old evolutionTab content) -->
<div id="worldEvoSubTab" class="world-sub-content">
<div class="tab-description">
Adjust evolutionary parameters to influence genetic changes.
</div>
@ -243,28 +284,6 @@
</div>
</div>
</div>
<!-- ENVIRONMENT TAB -->
<div id="environmentTab" class="tab-content">
<div class="tab-description">
Adjust environmental parameters that affect food and snake respawning.
</div>
<div class="control-group">
<label for="foodDecayTimeSlider">Food Decay Time:</label>
<input type="range" id="foodDecayTimeSlider" min="500" max="5000" value="2000" step="100">
<span id="foodDecayTimeVal">2000</span>
<div class="setting-description">
Time (ms) before dropped food disappears.
</div>
</div>
<div class="control-group">
<label for="respawnDelaySlider">Respawn Delay:</label>
<input type="range" id="respawnDelaySlider" min="0" max="5" value="0" step="0.5">
<span id="respawnDelayVal">0</span>
<div class="setting-description">
Delay (sec) before a new snake spawns after one dies.
</div>
</div>
</div>
<div class="control-buttons">

View File

@ -9,7 +9,7 @@ let lastFrameTime = null;
/* Updated defaults */
const DEFAULT_BRAIN_SIZE = 15;
const DEFAULT_SNAKE_SPEED = 3.5;
const DEFAULT_SNAKE_SPEED = 1;
const DEFAULT_MAX_FOOD = 120;
const DEFAULT_SPAWN_CHANCE = 3;
const DEFAULT_FOOD_POINTS = 3;
@ -17,9 +17,9 @@ const DEFAULT_DROPPED_FOOD_POINTS = 10;
const DEFAULT_SURVIVAL_BONUS = 2;
const DEFAULT_BODY_LENGTH_INCREMENT = 10;
const DEFAULT_THICKNESS_INCREMENT = 0.05;
const DEFAULT_SNAKE_COUNT = 30;
const DEFAULT_LENGTH_BONUS = 1;
const DEFAULT_KILL_BONUS = 0;
const DEFAULT_SNAKE_COUNT = 15;
const DEFAULT_LENGTH_BONUS = 3;
const DEFAULT_KILL_BONUS = 3;
/* Evolution & Environment Defaults */
const DEFAULT_MUTATION_RATE = 0.1;
@ -188,6 +188,11 @@ function removeDraggable(panel) {
attachMinimizeLogic(clone);
attachTopLevelTabLogic(clone);
attachRewardSubTabLogic(clone);
// new calls for sub-tabs:
attachSnakesSubTabLogic(clone);
attachWorldSubTabLogic(clone);
wireUIEvents();
}
@ -284,6 +289,48 @@ function attachRewardSubTabLogic(panel) {
});
});
}
/* NEW: Attach snakes sub-tab logic */
function attachSnakesSubTabLogic(panel) {
const snakesTab = panel.querySelector('#snakesTab');
if (!snakesTab) return;
const subTabButtons = snakesTab.querySelectorAll('.snakes-subtabs .tabBtn');
subTabButtons.forEach(subBtn => {
subBtn.addEventListener('click', () => {
subTabButtons.forEach(b => b.classList.remove('active'));
const allSubContents = snakesTab.querySelectorAll('.snakes-sub-content');
allSubContents.forEach(s => s.classList.remove('active'));
subBtn.classList.add('active');
const subId = subBtn.getAttribute('data-subtab');
const targetSub = snakesTab.querySelector('#' + subId);
if (targetSub) {
targetSub.classList.add('active');
}
});
});
}
/* NEW: Attach world sub-tab logic */
function attachWorldSubTabLogic(panel) {
const worldTab = panel.querySelector('#worldTab');
if (!worldTab) return;
const subTabButtons = worldTab.querySelectorAll('.world-subtabs .tabBtn');
subTabButtons.forEach(subBtn => {
subBtn.addEventListener('click', () => {
subTabButtons.forEach(b => b.classList.remove('active'));
const allSubContents = worldTab.querySelectorAll('.world-sub-content');
allSubContents.forEach(s => s.classList.remove('active'));
subBtn.classList.add('active');
const subId = subBtn.getAttribute('data-subtab');
const targetSub = worldTab.querySelector('#' + subId);
if (targetSub) {
targetSub.classList.add('active');
}
});
});
}
/* Wire up UI events (sliders, etc.) */
function wireUIEvents() {
@ -1107,8 +1154,23 @@ function init() {
attachTopLevelTabLogic(document.getElementById("controlPanel"));
attachRewardSubTabLogic(document.getElementById("controlPanel"));
attachSnakesSubTabLogic(document.getElementById("controlPanel"));
attachWorldSubTabLogic(document.getElementById("controlPanel"));
attachTopLevelTabLogic(document.getElementById("timeAndLeaderboardPanel"));
wireUIEvents();
// Wire up the help button to open the modal
const helpBtn = document.getElementById('helpButton');
const helpModal = document.getElementById('helpModal');
const helpClose = document.getElementById('helpClose');
if (helpBtn && helpModal && helpClose) {
helpBtn.onclick = () => {
helpModal.style.display = 'flex';
};
helpClose.onclick = () => {
helpModal.style.display = 'none';
};
}
}
init();

View File

@ -10,11 +10,24 @@ html, body {
color: #FFF;
}
/* Canvas covers the entire window */
/* Wrap the canvas so we can scale the entire simulation if desired */
#simCanvasWrapper {
width: 100%;
height: 100%;
/* Default scale for desktop */
transform: scale(1.0);
transform-origin: center center;
}
/* On mobile (below 1000px), scale differently. Adjust as desired. */
@media (max-width: 1000px) {
#simCanvasWrapper {
transform: scale(0.85); /* Or scale(1.2) if you want larger on mobile */
}
}
/* The canvas inside the wrapper */
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: block;
@ -34,7 +47,7 @@ canvas {
background: linear-gradient(135deg, rgba(20,0,40,0.8), rgba(0,0,0,0.6));
}
/* widths: make both 420px to match each other in desktop */
/* widths: make both 420px for desktop */
.control-panel {
width: 420px;
left: 50%;
@ -165,6 +178,60 @@ canvas {
display: block;
}
/* Sub-tabs for Snakes */
.snakes-subtabs {
display: flex;
margin-bottom: 10px;
}
.snakes-subtabs .tabBtn {
flex: 1;
margin: 0 2px;
background: #444;
border: none;
color: #FFF;
cursor: pointer;
padding: 4px 8px;
font-weight: bold;
border-radius: 4px;
}
.snakes-subtabs .tabBtn.active {
background: linear-gradient(90deg, #8000ff 0%, #ff00ff 100%);
box-shadow: 0 0 5px rgba(255,0,255,0.4);
}
.snakes-sub-content {
display: none;
}
.snakes-sub-content.active {
display: block;
}
/* Sub-tabs for 'World' (Environment + Evolution) */
.world-subtabs {
display: flex;
margin-bottom: 10px;
}
.world-subtabs .tabBtn {
flex: 1;
margin: 0 2px;
background: #444;
border: none;
color: #FFF;
cursor: pointer;
padding: 4px 8px;
font-weight: bold;
border-radius: 4px;
}
.world-subtabs .tabBtn.active {
background: linear-gradient(90deg, #8000ff 0%, #ff00ff 100%);
box-shadow: 0 0 5px rgba(255,0,255,0.4);
}
.world-sub-content {
display: none;
}
.world-sub-content.active {
display: block;
}
/* .tab-content is used for top-level content areas */
.tab-content {
display: none; /* hidden by default */
@ -219,21 +286,17 @@ canvas {
animation: sinewave 1s infinite;
}
/* Center the "?" help button on the right edge */
/* Help Button style (no longer absolutely positioned) */
.help-button {
position: absolute;
top: 50%;
right: 10px;
transform: translateY(-50%);
z-index: 3;
margin-left: 8px;
background: #444;
border: 1px solid #555;
color: #FFF;
font-size: 16px;
padding: 4px 8px;
font-size: 14px;
padding: 2px 6px;
cursor: pointer;
border-radius: 50%;
box-shadow: 0 0 8px rgba(255, 0, 255, 0.5);
border-radius: 4px;
box-shadow: 0 0 8px rgba(255,0,255,0.5);
}
.help-button:hover {
background: #666;
@ -295,6 +358,7 @@ canvas {
left: 50%;
transform: translateX(-50%);
}
/* Stack the leaderboards vertically in mobile to avoid overflow */
.leaderboardColumn {
width: 100% !important;