about summary refs log tree commit diff stats
path: root/html/mountain/game.js
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-12-07 10:44:34 -0500
committerelioat <elioat@tilde.institute>2024-12-07 10:44:34 -0500
commite720cb7f47e74eaef81fa11cef2954d7a566185e (patch)
tree289e33a9ad0261e2ea9427872245bec8a69a2d38 /html/mountain/game.js
parenta50500597fcd2698f86f05c0bb74e8fae6c3ab73 (diff)
downloadtour-e720cb7f47e74eaef81fa11cef2954d7a566185e.tar.gz
*
Diffstat (limited to 'html/mountain/game.js')
-rw-r--r--html/mountain/game.js71
1 files changed, 64 insertions, 7 deletions
diff --git a/html/mountain/game.js b/html/mountain/game.js
index b4fcf3f..a05bdb9 100644
--- a/html/mountain/game.js
+++ b/html/mountain/game.js
@@ -13,7 +13,8 @@ const GAME_STATE = {
 
 const PLATFORM_TYPE = {
     NORMAL: 'normal',
-    DEADLY: 'deadly'
+    DEADLY: 'deadly',
+    FALLING: 'falling'
 };
 
 const PLAYER_SIZE = 20;
@@ -45,6 +46,14 @@ const DEATH_ANIMATION_DURATION = 55;
 
 const ENEMY_SPEED = 2;
 
+const FALLING_PLATFORM_DELAY = 800;
+const FALLING_PLATFORM_GRAVITY = 0.5;
+
+const PLATFORM_PARTICLE_COUNT = 30;
+const PLATFORM_PARTICLE_SPEED = 8;
+const PLATFORM_PARTICLE_SIZE = 4;
+const PLATFORM_PARTICLE_LIFETIME = 40;
+
 let gameState = GAME_STATE.PLAYING;
 let level = 1;
 let platforms = [];
@@ -247,9 +256,15 @@ function generatePlatformsForPartition(partition) {
                     ),
                     width: platformWidth,
                     height: PLATFORM_HEIGHT,
-                    type: (level > 1 && Math.random() < 0.2) ? 
-                        PLATFORM_TYPE.DEADLY : 
-                        PLATFORM_TYPE.NORMAL
+                    type: (() => {
+                        if (level > 1 && Math.random() < 0.2) return PLATFORM_TYPE.DEADLY;
+                        if (level > 1 && Math.random() < 0.3) {
+                            return PLATFORM_TYPE.FALLING;
+                        }
+                        return PLATFORM_TYPE.NORMAL;
+                    })(),
+                    fallTimer: null,
+                    velocityY: 0
                 };
 
                 let overlapping = false;
@@ -424,6 +439,11 @@ function updatePlayer() {
                 if (platform.type === PLATFORM_TYPE.DEADLY) {
                     killPlayer();
                 } else {
+                    if (platform.type === PLATFORM_TYPE.FALLING && !platform.fallTimer) {
+                        platform.fallTimer = setTimeout(() => {
+                            platform.isFalling = true;
+                        }, FALLING_PLATFORM_DELAY);
+                    }
                     player.velocityY = 0;
                     player.isJumping = false;
                     player.jumpsLeft = 2;
@@ -496,9 +516,9 @@ function draw(currentTime) {
     );
     
     for (let platform of platforms) {
-        ctx.fillStyle = platform.type === PLATFORM_TYPE.DEADLY ? 
-            'tomato' : 
-            '#1A1A1A';
+        ctx.fillStyle = platform.type === PLATFORM_TYPE.DEADLY ? 'tomato' :
+                       platform.type === PLATFORM_TYPE.FALLING ? 'rgba(26, 26, 26, 0.75)' :
+                       '#1A1A1A';
         ctx.fillRect(platform.x, platform.y, platform.width, platform.height);
     }
     
@@ -576,6 +596,7 @@ function gameLoop(currentTime) {
         updateEnemies();
         updateParticles();
         updateDeathParticles();
+        updatePlatforms();
         accumulator -= FRAME_TIME;
     }
     
@@ -583,6 +604,42 @@ function gameLoop(currentTime) {
     requestAnimationFrame(gameLoop);
 }
 
+function createPlatformParticles(platform) {
+    for (let i = 0; i < PLATFORM_PARTICLE_COUNT; i++) {
+        const angle = (Math.PI * 2 * i) / PLATFORM_PARTICLE_COUNT;
+        particles.push({
+            x: platform.x + platform.width / 2,
+            y: platform.y + platform.height / 2,
+            velocityX: Math.cos(angle) * PLATFORM_PARTICLE_SPEED * (0.5 + Math.random()),
+            velocityY: Math.sin(angle) * PLATFORM_PARTICLE_SPEED * (0.5 + Math.random()),
+            size: PLATFORM_PARTICLE_SIZE + Math.random() * 2,
+            life: PLATFORM_PARTICLE_LIFETIME,
+            initialOpacity: 0.6 + Math.random() * 0.4
+        });
+    }
+}
+
+function updatePlatforms() {
+    platforms.forEach(platform => {
+        if (platform.type === PLATFORM_TYPE.FALLING && platform.isFalling) {
+            platform.velocityY += FALLING_PLATFORM_GRAVITY * player.gravityMultiplier;
+            platform.y += platform.velocityY;
+            
+            // Create particles when platform goes off screen
+            if ((player.gravityMultiplier > 0 && platform.y > canvas.height + 50) || 
+                (player.gravityMultiplier < 0 && platform.y < -50)) {
+                createPlatformParticles(platform);
+            }
+        }
+    });
+    
+    // Remove platforms that have fallen off screen in either direction
+    platforms = platforms.filter(platform => 
+        platform.type !== PLATFORM_TYPE.FALLING || 
+        (player.gravityMultiplier > 0 ? platform.y < canvas.height + 100 : platform.y > -100)
+    );
+}
+
 document.body.style.margin = '0';
 document.body.style.overflow = 'hidden';
 resizeCanvas();