Generate 60 randomly placed trees across full scrollable world, varying size and sway speed
This commit is contained in:
@@ -543,7 +543,40 @@ class Game {
|
|||||||
.catch(()=>this.toast('❌ Could not load questions.json'));
|
.catch(()=>this.toast('❌ Could not load questions.json'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── MAP ──────────────────────────────────────────────── */
|
/* Generate randomly placed trees across the full scrollable world */
|
||||||
|
_generateTrees() {
|
||||||
|
const container = document.getElementById('map-trees');
|
||||||
|
if (!container || container.childElementCount > 0) return; /* only once */
|
||||||
|
|
||||||
|
const world = document.getElementById('map-inner');
|
||||||
|
const worldW = world ? world.offsetWidth : 1680;
|
||||||
|
const viewH = world ? world.parentElement.offsetHeight : 300;
|
||||||
|
|
||||||
|
/* Trees live in the top 52% of the world (above the path) */
|
||||||
|
const treeTopMax = viewH * 0.52;
|
||||||
|
const treeBottomMin = viewH * 0.04;
|
||||||
|
const TYPES = ['🌲','🌳','🌲','🌳','🌲','🌲','🌳'];
|
||||||
|
const COUNT = 60;
|
||||||
|
|
||||||
|
/* Use a seeded-ish spread: divide world into zones and place 1-2 trees per zone */
|
||||||
|
const zoneW = worldW / COUNT;
|
||||||
|
for (let i = 0; i < COUNT; i++) {
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.className = 'tree';
|
||||||
|
const emoji = TYPES[Math.floor(Math.random() * TYPES.length)];
|
||||||
|
const size = 24 + Math.random() * 18; /* 24–42px */
|
||||||
|
const x = i * zoneW + Math.random() * zoneW * 0.85;
|
||||||
|
const y = treeBottomMin + Math.random() * (treeTopMax - treeBottomMin - size);
|
||||||
|
const delay = (Math.random() * 3).toFixed(2);
|
||||||
|
span.textContent = emoji;
|
||||||
|
span.style.fontSize = size + 'px';
|
||||||
|
span.style.left = x + 'px';
|
||||||
|
span.style.top = y + 'px';
|
||||||
|
span.style.animationDelay = delay + 's';
|
||||||
|
span.style.animationDuration = (2.5 + Math.random() * 2).toFixed(1) + 's';
|
||||||
|
container.appendChild(span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
showMap() {
|
showMap() {
|
||||||
this.show('map');
|
this.show('map');
|
||||||
@@ -551,6 +584,7 @@ class Game {
|
|||||||
|
|
||||||
/* We need the viewport size — defer a tick so the DOM is laid out */
|
/* We need the viewport size — defer a tick so the DOM is laid out */
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
|
this._generateTrees();
|
||||||
const world = document.getElementById('map-inner');
|
const world = document.getElementById('map-inner');
|
||||||
const viewW = world ? world.parentElement.offsetWidth : 420;
|
const viewW = world ? world.parentElement.offsetWidth : 420;
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -102,11 +102,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="overworld-bg map-world" id="map-world">
|
<div class="overworld-bg map-world" id="map-world">
|
||||||
<div class="map-inner" id="map-inner">
|
<div class="map-inner" id="map-inner">
|
||||||
<div class="map-trees">
|
<div class="map-trees" id="map-trees"></div>
|
||||||
<span class="tree">🌲</span><span class="tree">🌳</span>
|
|
||||||
<span class="tree">🌲</span><span class="tree">🌳</span><span class="tree">🌲</span>
|
|
||||||
<span class="tree">🌳</span><span class="tree">🌲</span><span class="tree">🌳</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Path stays fixed to the viewport — does not scroll -->
|
<!-- Path stays fixed to the viewport — does not scroll -->
|
||||||
<div class="map-ground"></div>
|
<div class="map-ground"></div>
|
||||||
|
|||||||
@@ -397,18 +397,19 @@ html, body {
|
|||||||
will-change: transform;
|
will-change: transform;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
.map-trees {
|
.map-trees {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 12%;
|
inset: 0;
|
||||||
left: 0; right: 0;
|
pointer-events: none;
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
padding: 0 2%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
.tree { font-size:clamp(24px,7vw,36px); display:inline-block; animation:treeSway 3s ease-in-out infinite; filter:drop-shadow(1px 2px 0 rgba(0,0,0,.3)); }
|
.tree {
|
||||||
.tree:nth-child(2){animation-delay:.5s;} .tree:nth-child(3){animation-delay:1s;} .tree:nth-child(4){animation-delay:1.5s;} .tree:nth-child(5){animation-delay:2s;}
|
position: absolute;
|
||||||
.tree:nth-child(6){animation-delay:2.5s;} .tree:nth-child(7){animation-delay:.8s;} .tree:nth-child(8){animation-delay:1.8s;}
|
display: inline-block;
|
||||||
|
animation: treeSway 3s ease-in-out infinite;
|
||||||
|
filter: drop-shadow(1px 2px 0 rgba(0,0,0,.3));
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.tree:nth-child(even) { animation-direction: reverse; }
|
||||||
.map-ground {
|
.map-ground {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0; left: 0; right: 0;
|
bottom: 0; left: 0; right: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user