the game
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: update level system

+56 -37
+13 -11
src/enemy.ts
··· 116 116 k.color(255, 0, 0), 117 117 k.z(1), 118 118 ]); 119 - 119 + 120 120 // Handle collisions with sword 121 121 this.onCollide("sword", (sword) => { 122 122 if (sword.isAttacking && !isHit) { ··· 151 151 this.flipX = normalizedDir.x < 0; 152 152 } 153 153 } 154 - 154 + 155 155 // Check for collision with player and apply damage if in contact 156 156 // Only apply damage if cooldown has passed 157 157 if (k.time() - lastDamageTime > DAMAGE_COOLDOWN) { 158 158 const playerObj = k.get("player")[0]; 159 159 if (playerObj && this.isColliding(playerObj)) { 160 160 lastDamageTime = k.time(); 161 - 161 + 162 162 // Damage player 163 163 if (playerObj.damage) { 164 164 playerObj.damage(5); 165 165 } 166 - 166 + 167 167 // Knockback effect 168 168 const knockback = 200; 169 - const knockbackDir = k.vec2( 170 - playerObj.pos.x - this.pos.x, 171 - playerObj.pos.y - this.pos.y 172 - ).unit(); 173 - 174 - playerObj.move(knockbackDir.x * knockback, knockbackDir.y * knockback); 169 + const knockbackDir = k 170 + .vec2(playerObj.pos.x - this.pos.x, playerObj.pos.y - this.pos.y) 171 + .unit(); 172 + 173 + playerObj.move( 174 + knockbackDir.x * knockback, 175 + knockbackDir.y * knockback, 176 + ); 175 177 } 176 178 } 177 179 ··· 206 208 enemy(k, target), 207 209 "enemy", // Add tag for collision detection 208 210 ]); 209 - 211 + 210 212 return newEnemy; 211 213 } 212 214
+31 -20
src/main.ts
··· 45 45 let spawnInterval = initialSpawnInterval; 46 46 let gameTime = 0; // Track game time in seconds 47 47 let difficultyLevel = 1; 48 - let spawnLoopId: any = null; 48 + let score = 0; 49 + 50 + const scoreText = k.add([k.text(`Score: ${score}`), k.pos(16, 16)]); 49 51 50 52 // Difficulty scaling 51 53 function updateDifficulty() { 52 54 gameTime += 1; // Increment game time by 1 second 53 - 55 + 54 56 // Every 30 seconds, increase difficulty 55 - if (gameTime % 30 === 0) { 57 + if (score != 0 && score % (50 * difficultyLevel) === 0) { 56 58 difficultyLevel += 1; 57 - 59 + 58 60 // Increase max enemies (cap at 15) 59 - maxEnemies = Math.min(initialMaxEnemies + difficultyLevel, 15); 60 - 61 + maxEnemies = Math.min(initialMaxEnemies + difficultyLevel * 3, 15); 62 + 61 63 // Decrease spawn interval (minimum 0.5 seconds) 62 - spawnInterval = Math.max(initialSpawnInterval - (difficultyLevel * 0.3), 0.5); 63 - 64 - console.log(`Difficulty increased to level ${difficultyLevel}. Max enemies: ${maxEnemies}, Spawn interval: ${spawnInterval}s`); 65 - 64 + spawnInterval = Math.max(initialSpawnInterval - difficultyLevel * 0.3, 0.5); 65 + 66 + console.log( 67 + `Difficulty increased to level ${difficultyLevel}. Max enemies: ${maxEnemies}, Spawn interval: ${spawnInterval}s`, 68 + ); 69 + 66 70 // Cancel previous spawn loop and start a new one with updated interval 67 - if (spawnLoopId !== null) { 68 - k.cancel(spawnLoopId); 69 - } 70 - spawnLoopId = k.loop(spawnInterval, spawnEnemy); 71 - 71 + k.cancel(); 72 + k.loop(spawnInterval, spawnEnemy); 73 + 72 74 // Visual feedback for difficulty increase 73 75 const screenCenter = k.vec2(k.width() / 2, k.height() / 2); 74 76 if (k.addConfetti) { 75 77 k.addConfetti(screenCenter); 76 78 } 77 - 79 + 78 80 // Add difficulty level text 79 81 const levelText = k.add([ 80 82 k.text(`Difficulty Level ${difficultyLevel}!`, { size: 32 }), ··· 85 87 k.z(100), 86 88 k.opacity(1), 87 89 ]); 88 - 90 + 89 91 // Fade out and destroy the text 90 92 k.tween( 91 93 1, ··· 96 98 }, 97 99 k.easings.easeInQuad, 98 100 ); 99 - 101 + 100 102 k.wait(2, () => { 101 103 levelText.destroy(); 102 104 }); ··· 113 115 114 116 // Random position at the edges of the screen 115 117 const side = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left 116 - let x, y; 118 + let x = 0, 119 + y = 0; 117 120 118 121 switch (side) { 119 122 case 0: // top ··· 141 144 // Remove from array when destroyed 142 145 newEnemy.on("destroy", () => { 143 146 enemies = enemies.filter((e) => e !== newEnemy); 147 + 148 + // Increase score when enemy is destroyed 149 + score += 10 + Math.pow(difficultyLevel, 0.75); 150 + 151 + // Update score display 152 + scoreText.text = `Score: ${score}`; 153 + 154 + if (Math.random() < 0.5) spawnEnemy(); 144 155 }); 145 156 } 146 157 147 158 // Start spawning enemies 148 - spawnLoopId = k.loop(spawnInterval, spawnEnemy); 159 + k.loop(spawnInterval, spawnEnemy); 149 160 150 161 // Game loop 151 162 k.onUpdate(() => {
+12 -6
src/player.ts
··· 222 222 enemies.forEach((enemy) => { 223 223 const dist = k.vec2(enemy.pos).dist(clampedPos); 224 224 if (dist < explosionRadius) { 225 - // Calculate damage based on distance from center 226 - // At center (dist = 0): 70 damage (70% of enemy health) 227 - // At edge (dist = explosionRadius): 20 damage (20% of enemy health) 228 - const damagePercent = 0.7 - (0.5 * dist) / explosionRadius; 229 - const damage = Math.floor(100 * damagePercent); // 100 is enemy max health 225 + // Normalize distance to 0-1 range 226 + const normalizedDist = dist / explosionRadius; 227 + 228 + const maxDamage = 80; 229 + const minDamage = 10; 230 + const logFalloff = Math.log(10 * normalizedDist) / Math.log(20); 231 + const damagePercent = 1 - logFalloff; 232 + const damage = Math.max( 233 + Math.floor(maxDamage * damagePercent), 234 + minDamage, 235 + ); 230 236 231 237 console.log( 232 - `Direct damage to enemy: ${damage}, distance: ${dist}, percent: ${damagePercent}`, 238 + `Explosion damage to enemy: ${damage}, distance: ${dist}, normalized: ${normalizedDist}, falloff: ${logFalloff}`, 233 239 ); 234 240 // Add type assertion to tell TypeScript that enemy has a damage method 235 241 (enemy as any).damage(damage);