zeroed-some/cob / 16abfe2

Browse files

store state, balloon distribution

Authored by espadonne
SHA
16abfe29116079fc5d297d756e61d8502f12fdc5
Parents
a16082e
Tree
a36f163

2 changed files

StatusFile+-
M js/entities.js 17 5
M js/game.js 103 43
js/entities.jsmodified
@@ -34,7 +34,6 @@ class Spider {
3434
         return
3535
       }
3636
       jumpStamina -= jumpCost
37
-      stats.totalJumps++
3837
       // Delay stamina regen after each jump during DAWN
3938
       staminaRegenCooldown = 60 // 1s at 60fps
4039
     }
@@ -67,6 +66,10 @@ class Spider {
6766
     this.vel = direction
6867
     this.isAirborne = true
6968
     this.canJump = false
69
+    // Count every successful jump (lifetime stat)
70
+    if (typeof stats !== 'undefined') {
71
+      stats.totalJumps++
72
+    }
7073
 
7174
     // FIX: Ensure lastAnchorPoint is set to edge, not center
7275
     if (!this.lastAnchorPoint) {
@@ -139,7 +142,7 @@ class Spider {
139142
         if (fly.type === 'queen') munchPoints = 10
140143
         if (fly.type === 'moth') munchPoints = 6
141144
         playerPoints += munchPoints
142
-        totalFliesCaught++ // Add to lifetime counter
145
+        // totalFliesCaught++ // Add to lifetime counter
143146
 
144147
         webSilk = min(webSilk + 15, maxWebSilk)
145148
 
@@ -284,8 +287,8 @@ class Spider {
284287
 
285288
         // The branch is drawn centered at branch.y; compute top/bottom with rotation
286289
         let rotationOffset = this.pos.x * branch.angle
287
-        let branchTopY = (branch.y - visualThickness) + rotationOffset
288
-        let branchBottomY = (branch.y + visualThickness) + rotationOffset
290
+        let branchTopY = branch.y - visualThickness + rotationOffset
291
+        let branchBottomY = branch.y + visualThickness + rotationOffset
289292
 
290293
         // Check collision
291294
         let prevY = this.pos.y - this.vel.y
@@ -605,7 +608,8 @@ class Spider {
605608
 }
606609
 
607610
 class Fly {
608
-  constructor () {
611
+  constructor (type = 'regular') {
612
+    this.type = type
609613
     if (random() < 0.5) {
610614
       this.pos = createVector(
611615
         random() < 0.5 ? -20 : width + 20,
@@ -642,6 +646,14 @@ class Fly {
642646
         fliesCaught++
643647
         totalFliesCaught++ // Add to lifetime counter
644648
 
649
+        if (typeof stats !== 'undefined') {
650
+          stats.totalFliesCaught++
651
+          if (this.type === 'golden') stats.goldenCaught++
652
+          else if (this.type === 'queen') stats.queensCaught++
653
+          else if (this.type === 'moth') stats.mothsCaught++
654
+          else stats.regularCaught++
655
+        }
656
+
645657
         // POINTS: Award points for catching fly
646658
         let catchPoints = 2 // Base points for catch
647659
         if (this.type === 'golden') catchPoints = 4
js/game.jsmodified
@@ -59,6 +59,7 @@ let notifications = []
5959
 // PHASE 3: Upgrade System
6060
 let playerPoints = 0
6161
 let shopOpen = false
62
+let spentPoints = 0
6263
 
6364
 // PHASE 4: Dawn Exhaustion System
6465
 let jumpStamina = 100
@@ -476,48 +477,99 @@ function setup () {
476477
   let numObstacles = Math.floor((width * height) / 60000) // More obstacles
477478
   numObstacles = constrain(numObstacles, 15, 25)
478479
 
479
-  // Create ant balloons
480
-  let numBalloons = Math.floor(random(15, 21))
481
-  for (let i = 0; i < numBalloons; i++) {
482
-    let attempts = 0
483
-    let placed = false
484
-
485
-    while (!placed && attempts < 30) {
486
-      // Distribute balloons more evenly across the screen
487
-      let gridX = (i % 3) * (width / 3) + random(50, width / 3 - 50)
488
-      let gridY = Math.floor(i / 3) * (height / 4) + random(40, height / 4)
489
-
490
-      let x = constrain(gridX, 80, width - 80)
491
-      let y = constrain(gridY, 60, height * 0.6) // Balloons in upper 60% of screen
492
-      let radius = random(35, 50) // Varied sizes for visual interest
493
-
494
-      let valid = true
495
-      // Check distance from other obstacles
496
-      for (let obstacle of obstacles) {
497
-        if (
498
-          dist(x, y, obstacle.x, obstacle.y) <
499
-          radius + obstacle.radius + 40
500
-        ) {
501
-          valid = false
502
-          break
480
+// Create ant balloons
481
+let numBalloons = Math.floor(random(15, 21))
482
+for (let i = 0; i < numBalloons; i++) {
483
+  let attempts = 0
484
+  let placed = false
485
+
486
+  while (!placed && attempts < 30) {
487
+    // FIX: True random distribution with better spread
488
+    let x, y
489
+    
490
+    // Use different strategies for better distribution
491
+    let strategy = random()
492
+    
493
+    if (strategy < 0.3) {
494
+      // 30% - Truly random across upper area
495
+      x = random(80, width - 80)
496
+      y = random(60, height * 0.5)
497
+    } else if (strategy < 0.6) {
498
+      // 30% - Radial distribution from center
499
+      let angle = random(TWO_PI)
500
+      let radius = random(100, min(width, height) * 0.35)
501
+      x = width / 2 + cos(angle) * radius
502
+      y = height * 0.35 + sin(angle) * radius * 0.7  // Elliptical, flatter
503
+      x = constrain(x, 80, width - 80)
504
+      y = constrain(y, 60, height * 0.6)
505
+    } else if (strategy < 0.8) {
506
+      // 20% - Edge preference for variety
507
+      if (random() < 0.5) {
508
+        x = random() < 0.5 ? random(80, 150) : random(width - 150, width - 80)
509
+        y = random(60, height * 0.5)
510
+      } else {
511
+        x = random(80, width - 80)
512
+        y = random(60, 120)
513
+      }
514
+    } else {
515
+      // 20% - Poisson disk sampling attempt (avoid clusters)
516
+      let bestX = random(80, width - 80)
517
+      let bestY = random(60, height * 0.6)
518
+      let bestMinDist = 0
519
+      
520
+      // Try a few positions and pick the one furthest from existing balloons
521
+      for (let j = 0; j < 5; j++) {
522
+        let testX = random(80, width - 80)
523
+        let testY = random(60, height * 0.6)
524
+        let minDist = Infinity
525
+        
526
+        for (let obstacle of obstacles) {
527
+          if (obstacle.type === 'balloon') {
528
+            let d = dist(testX, testY, obstacle.x, obstacle.y)
529
+            minDist = min(minDist, d)
530
+          }
531
+        }
532
+        
533
+        if (minDist > bestMinDist) {
534
+          bestMinDist = minDist
535
+          bestX = testX
536
+          bestY = testY
503537
         }
504538
       }
539
+      
540
+      x = bestX
541
+      y = bestY
542
+    }
505543
 
506
-      // Check distance from home branch
507
-      if (valid && window.homeBranch) {
508
-        let branchY = window.homeBranch.y
509
-        if (Math.abs(y - branchY) < radius + 40) {
510
-          valid = false
511
-        }
544
+    let radius = random(35, 50) // Varied sizes for visual interest
545
+
546
+    let valid = true
547
+    // Check distance from other obstacles
548
+    for (let obstacle of obstacles) {
549
+      if (
550
+        dist(x, y, obstacle.x, obstacle.y) <
551
+        radius + obstacle.radius + 40
552
+      ) {
553
+        valid = false
554
+        break
512555
       }
556
+    }
513557
 
514
-      if (valid) {
515
-        obstacles.push(new Obstacle(x, y, radius, 'balloon'))
516
-        placed = true
558
+    // Check distance from home branch
559
+    if (valid && window.homeBranch) {
560
+      let branchY = window.homeBranch.y
561
+      if (Math.abs(y - branchY) < radius + 40) {
562
+        valid = false
517563
       }
518
-      attempts++
519564
     }
565
+
566
+    if (valid) {
567
+      obstacles.push(new Obstacle(x, y, radius, 'balloon'))
568
+      placed = true
569
+    }
570
+    attempts++
520571
   }
572
+}
521573
 
522574
   // Create beetles
523575
   let numBeetles = Math.floor(random(9, 15))
@@ -1599,7 +1651,9 @@ function saveGame () {
15991651
     upgrades: upgrades,
16001652
     playerPoints: playerPoints,
16011653
     nightsSurvived: nightsSurvived,
1602
-    currentNight: currentNight
1654
+    currentNight: currentNight,
1655
+    playerPoints: playerPoints,
1656
+    spentPoints: spentPoints,
16031657
   }
16041658
 
16051659
   localStorage.setItem('cobGameSave', JSON.stringify(saveData))
@@ -1617,6 +1671,8 @@ function loadGame () {
16171671
     playerPoints = data.playerPoints || 0
16181672
     nightsSurvived = data.nightsSurvived || 0
16191673
     currentNight = data.currentNight || 1
1674
+    playerPoints = data.playerPoints || 0
1675
+    spentPoints = data.spentPoints || 0
16201676
 
16211677
     // Apply upgrades
16221678
     applyUpgradeEffects()
@@ -1742,11 +1798,11 @@ function openUpgradeShop () {
17421798
   noLoop() // Pause the game
17431799
 
17441800
   // Calculate points from flies caught this session
1745
-  playerPoints = totalFliesCaught
1801
+  // playerPoints = totalFliesCaught
17461802
 
17471803
   // Update shop UI
17481804
   document.getElementById('upgrade-shop').style.display = 'block'
1749
-  document.getElementById('available-points').textContent = playerPoints
1805
+  document.getElementById('available-points').textContent = playerPoints - spentPoints
17501806
 
17511807
   // Populate upgrade lists
17521808
   updateShopDisplay()
@@ -1773,6 +1829,9 @@ function updateShopDisplay () {
17731829
   let tier2HTML = ''
17741830
   let tier1Count = 0
17751831
 
1832
+  // Calculate available points
1833
+  let availablePoints = playerPoints - spentPoints
1834
+
17761835
   // Count tier 1 upgrades
17771836
   for (let key in upgrades) {
17781837
     if (upgrades[key].tier === 1 && upgrades[key].level > 0) {
@@ -1784,7 +1843,7 @@ function updateShopDisplay () {
17841843
   for (let key in upgrades) {
17851844
     let upgrade = upgrades[key]
17861845
     if (upgrade.tier === 1) {
1787
-      let canAfford = playerPoints >= upgrade.cost
1846
+      let canAfford = availablePoints >= upgrade.cost
17881847
       let maxed = upgrade.level >= upgrade.maxLevel
17891848
       let buttonText = maxed ? 'MAXED' : `Buy (${upgrade.cost} pts)`
17901849
       let buttonDisabled = maxed || !canAfford ? 'disabled' : ''
@@ -1825,7 +1884,7 @@ function updateShopDisplay () {
18251884
     let upgrade = upgrades[key]
18261885
     if (upgrade.tier === 2) {
18271886
       let unlocked = tier1Count >= upgrade.requires
1828
-      let canAfford = playerPoints >= upgrade.cost && unlocked
1887
+      let canAfford = availablePoints >= upgrade.cost && unlocked
18291888
       let maxed = upgrade.level >= upgrade.maxLevel
18301889
       let buttonText = maxed
18311890
         ? 'MAXED'
@@ -1890,15 +1949,16 @@ window.buyUpgrade = function (upgradeKey) {
18901949
   }
18911950
 
18921951
   // Check if can afford and not maxed
1893
-  if (playerPoints >= upgrade.cost && upgrade.level < upgrade.maxLevel) {
1894
-    playerPoints -= upgrade.cost
1952
+  let availablePoints = playerPoints - spentPoints  // Calculate available points
1953
+  if (availablePoints >= upgrade.cost && upgrade.level < upgrade.maxLevel) {
1954
+    spentPoints += upgrade.cost  // Track spent points
18951955
     upgrade.level++
18961956
 
18971957
     // Apply upgrade effects immediately
18981958
     applyUpgradeEffects()
18991959
 
1900
-    // Update display
1901
-    document.getElementById('available-points').textContent = playerPoints
1960
+    // Update display with available points
1961
+    document.getElementById('available-points').textContent = playerPoints - spentPoints
19021962
     updateShopDisplay()
19031963
 
19041964
     // Show notification