From e7623335d3dc67724950c1bf84fcd64fb5f8304b Mon Sep 17 00:00:00 2001 From: Demetri Pirpiris Date: Sat, 15 Mar 2025 12:33:29 -0600 Subject: [PATCH] more ui fixes --- index.html | 205 +++++++++++++++++++++++++++++------------------------ script.js | 70 ++++++++++++++++-- styles.css | 96 ++++++++++++++++++++----- 3 files changed, 258 insertions(+), 113 deletions(-) diff --git a/index.html b/index.html index 55b5aac..a926820 100644 --- a/index.html +++ b/index.html @@ -7,16 +7,17 @@ - + + +
+ +
Fast Forwarding...
- - -
@@ -45,6 +46,8 @@
Simulation Controls + +
@@ -54,8 +57,8 @@ - - + +
@@ -159,110 +162,126 @@
- +
-
- Control the number of snakes and their intelligence or speed. +
+ +
-
- - - 30 -
- Increase or decrease the total population of snakes. + + +
+
+ Control the basic snake population, speed, and brain size.
-
-
- - - 3.5 -
- Snakes turn at a rate up to 0.15 / (lengthFactor) * speed; higher is more agile. +
+ + + 30 +
+ Increase or decrease the total population of snakes. +
+
+
+ + + 3.5 +
+ Snakes turn at a rate up to 0.15 / (lengthFactor) * speed; higher is more agile. +
+
+
+ + + 15 +
+ The bigger the brain, the more complex the snake's decision-making. +
- -
- - - 0.15 -
- Controls how sharply snakes can turn (before factoring in size). + +
+
+ Manage the base turn rate and boosting parameters.
-
- - -
- - - 1 -
- How many body length units are spent per second while boosting. +
+ + + 0.15 +
+ Controls how sharply snakes can turn (before factoring in size). +
-
- - -
- - - 2 -
- How much faster the snake goes when boosting. +
+ + + 1 +
+ How many body length units are spent per second while boosting. +
-
- -
- - - 15 -
- The bigger the brain, the more complex the snake's decision-making. +
+ + + 2 +
+ How much faster the snake goes when boosting. +
- -
-
- Adjust evolutionary parameters to influence genetic changes. + +
+
+ +
-
- - - 0.1 -
- Probability that a brain's bit will flip during mutation. -
-
-
- - - 0.5 -
- Likelihood of choosing a gene from the first parent during crossover. -
-
-
- -
-
- Adjust environmental parameters that affect food and snake respawning. -
-
- - - 2000 -
- Time (ms) before dropped food disappears. + +
+
+ Adjust environmental parameters that affect food and snake respawning. +
+
+ + + 2000 +
+ Time (ms) before dropped food disappears. +
+
+
+ + + 0 +
+ Delay (sec) before a new snake spawns after one dies. +
-
- - - 0 -
- Delay (sec) before a new snake spawns after one dies. + + +
+
+ Adjust evolutionary parameters to influence genetic changes. +
+
+ + + 0.1 +
+ Probability that a brain's bit will flip during mutation. +
+
+
+ + + 0.5 +
+ Likelihood of choosing a gene from the first parent during crossover. +
diff --git a/script.js b/script.js index 51577d1..8cd3876 100644 --- a/script.js +++ b/script.js @@ -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(); diff --git a/styles.css b/styles.css index 6394b2a..08833a5 100644 --- a/styles.css +++ b/styles.css @@ -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; @@ -247,7 +310,7 @@ canvas { width: 100%; height: 100%; background: rgba(0,0,0,0.8); - display: none; + display: none; z-index: 9999; align-items: center; justify-content: center; /* center horizontally */ @@ -295,6 +358,7 @@ canvas { left: 50%; transform: translateX(-50%); } + /* Stack the leaderboards vertically in mobile to avoid overflow */ .leaderboardColumn { width: 100% !important;