User prompt
karakter öldüğünde game over olacak sonra tekrardan play denince başlanabilecek
User prompt
1500 den 3000 e kadar main3 çalacak 3000 puandan sonra random olarak her 2000 puanda bir muzikler çalacak main1, main, main2, main3 gibi
User prompt
her canımız %25 in altına düştüğünde health pack ramdom yerlerde spawnlansın 1000 puan geçilince can tam olarak 1 defa dolacak ondan sonra her 1000 puanda bir dolacak şekilde ayarla
User prompt
main2 müziği 500 ile 1500 arasında çalacak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ateş etme sistemi de vampire survivals gibi olacak. Canlar da o sisteme göre şekillendirilecek ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
düşmanlar biraz daha birbirlerine yakınlaşabilir
User prompt
düşmanların doğmasını vampire survivals gibi yap
User prompt
bu hata düşmanların biribirine çok yakın olmasına izin vermediğimden kaynaklanıyor fixle illa doğacaksa dokunma doğsunlar birbirlerinin yakınlarında
User prompt
karakterler ölünce ortada biriken karakterlerin birden yerlerinin değişmesinin bugunu çöz
User prompt
yeni doğacak düşmanlar mapin içinde doğmayacak kenerlardan ve köşelerden gelecekler
User prompt
düşmanlar birbirine çok aşırı yakın kovalıyor karakteri
User prompt
karakterin dibinde doğmasınlar ama düşmanlar
User prompt
düşmanlar karaktere yakın yerlerde random olarak doğacaklar ve böyle de devam edecek
User prompt
düşmanlar tek vuruşta ölsün ama ateş hız değişimi çok aşırı azalt
User prompt
düşman hızı çok fazla oluyor 100 den sonra biraz daha sistematik bir düzen koy
User prompt
mermi atış artış hızını biraz daha artır az kalmış
User prompt
main müzik 100 skora kadar çalacak main1 müzik 100 den 500 e kadar çalacak
User prompt
can yenileme şeyi karakterin canı her %25 in altına düşünce çıkacak
User prompt
50 den 100 e kadar main1 çalacak
User prompt
50 skora kadar çalsın main
User prompt
main müzik oyun başladıktan sonra 20 skora kadar çalacak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('attackEffect', { anchorX: 0.5, anchorY: 0.5 }); bulletGraphics.scaleX = 0.5; bulletGraphics.scaleY = 0.5; // Set bullet speed based on boost status self.speed = bulletSpeedBoostTimer > 0 ? baseBulletSpeed * 1.5 : baseBulletSpeed; self.targetX = 0; self.targetY = 0; self.damage = 0; self.isPlayerBullet = true; self.targetEnemy = null; // Specific enemy this bullet is targeting self.update = function () { // Check for direct collision with enemies/player regardless of distance if (self.isPlayerBullet) { // Only check collision with the specific target enemy if (self.targetEnemy && !self.targetEnemy.isRespawning && !self.targetEnemy.destroyed && self.intersects(self.targetEnemy)) { self.targetEnemy.takeDamage(self.damage); self.destroy(); return; } } else { // Enemy bullet hitting player if (!player.isRespawning && self.intersects(player)) { player.takeDamage(self.damage); self.destroy(); return; } } var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // If reached target position, destroy bullet if (distance < self.speed) { self.destroy(); return; } // Move towards target var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; self.x += moveX; self.y += moveY; // Remove if out of bounds if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) { self.destroy(); } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); var healthBarBg = self.attachAsset('healthBarBg', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -60 }); var healthBar = self.attachAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -60 }); self.maxHealth = 100; self.health = 100; self.speed = 2; self.attackRange = 120; self.attackDamage = 5; self.attackCooldown = 0; self.isRespawning = false; self.respawnTimer = 0; self.aiTimer = 0; self.spawnImmunityTimer = 0; // Prevents attacking immediately after spawn self.targetX = 0; self.targetY = 0; self.takeDamage = function (damage) { if (self.isRespawning || self.health <= 0) return; // Don't take damage if already dead // Each bullet hit kills enemy instantly (100% of max health) self.health -= self.maxHealth; if (self.health < 0) self.health = 0; self.updateHealthBar(); // Flash red when taking damage tween(enemyGraphics, { tint: 0xFF0000 }, { duration: 200, onFinish: function onFinish() { tween(enemyGraphics, { tint: 0xFFFFFF }, { duration: 200 }); } }); if (self.health <= 0) { self.die(); } LK.getSound('hit').play(); }; self.updateHealthBar = function () { var healthPercent = self.health / self.maxHealth; healthBar.scaleX = healthPercent; if (healthPercent > 0.6) { healthBar.tint = 0x00FF00; } else if (healthPercent > 0.3) { healthBar.tint = 0xFFFF00; } else { healthBar.tint = 0xFF0000; } }; self.die = function () { self.isRespawning = true; self.respawnTimer = 180; // 3 seconds at 60fps enemyGraphics.visible = false; healthBar.visible = false; healthBarBg.visible = false; // Move enemy far off-screen during respawn to prevent collision issues self.x = -1000; self.y = -1000; // Increment killed count and spawn new enemy only if under limit enemiesKilled++; score++; scoreText.setText('Score: ' + score); if (enemies.length < maxEnemies) { spawnNewEnemy(); } }; self.respawn = function () { self.health = self.maxHealth; // Set position first before making visible self.x = 300 + Math.random() * 1400; self.y = 400 + Math.random() * 1800; // Reset spawn immunity self.spawnImmunityTimer = 60; // 1 second of spawn immunity // Then update state and make visible self.isRespawning = false; self.respawnTimer = 0; enemyGraphics.visible = true; enemyGraphics.alpha = 1; healthBar.visible = true; healthBarBg.visible = true; self.updateHealthBar(); LK.getSound('respawn').play(); }; self.attack = function () { if (self.attackCooldown > 0 || self.isRespawning || self.spawnImmunityTimer > 0) return; self.attackCooldown = 120; // 2 second cooldown if (!player.isRespawning) { // Create bullet projectile towards player var bullet = game.addChild(new Bullet()); bullet.x = self.x; bullet.y = self.y; bullet.targetX = player.x; bullet.targetY = player.y; bullet.damage = self.attackDamage; bullet.isPlayerBullet = false; bullets.push(bullet); } // Create attack effect var attackEffect = LK.getAsset('attackEffect', { anchorX: 0.5, anchorY: 0.5 }); attackEffect.x = self.x; attackEffect.y = self.y; attackEffect.alpha = 0.7; attackEffect.tint = 0xFF4444; attackEffect.scaleX = 0.8; attackEffect.scaleY = 0.8; game.addChild(attackEffect); // Scale and fade out attack effect tween(attackEffect, { scaleX: 1.2, scaleY: 1.2, alpha: 0 }, { duration: 200, onFinish: function onFinish() { attackEffect.destroy(); } }); LK.getSound('attack').play(); }; self.update = function () { if (self.attackCooldown > 0) { self.attackCooldown--; } if (self.spawnImmunityTimer > 0) { self.spawnImmunityTimer--; // Flash during spawn immunity period if (self.spawnImmunityTimer % 10 < 5) { enemyGraphics.alpha = 0.7; } else { enemyGraphics.alpha = 1; } } if (self.isRespawning) { self.respawnTimer--; if (self.respawnTimer <= 0) { self.respawn(); } return; } // Chase player AI - move towards player and attack when close if (!player.isRespawning) { var dx = player.x - self.x; var dy = player.y - self.y; var playerDistance = Math.sqrt(dx * dx + dy * dy); // Move towards player with speed multiplier var currentSpeed = self.speed * enemySpeedMultiplier; if (playerDistance > currentSpeed) { // Create a formation around the player instead of direct chase // Update AI timer for random movement changes self.aiTimer++; if (self.aiTimer >= 60) { // Change direction every second self.aiTimer = 0; // Calculate a preferred distance from player (spread enemies out) var preferredDistance = 180 + Math.random() * 120; // 180-300 pixels from player // If too close to preferred distance, move in a circular pattern if (playerDistance < preferredDistance + 50) { // Move in circular pattern around player var circleAngle = Math.atan2(dy, dx) + (Math.random() - 0.5) * Math.PI; // Add large random offset var moveX = Math.cos(circleAngle) * currentSpeed * 0.7; // Slower circular movement var moveY = Math.sin(circleAngle) * currentSpeed * 0.7; } else { // Generate random offset angle (-60 to +60 degrees) for wider spread var offsetAngle = (Math.random() - 0.5) * Math.PI / 1.5; // ±60 degrees in radians var baseAngle = Math.atan2(dy, dx); var newAngle = baseAngle + offsetAngle; var moveX = Math.cos(newAngle) * currentSpeed * 0.8; // Slightly slower approach var moveY = Math.sin(newAngle) * currentSpeed * 0.8; } } else { // Use stored movement direction with slight randomness var moveX = dx / playerDistance * currentSpeed * 0.9; var moveY = dy / playerDistance * currentSpeed * 0.9; } self.x += moveX; self.y += moveY; } // Attack if close enough to player if (playerDistance <= self.attackRange) { self.attack(); } } // Check collision with other enemies and push away if overlapping for (var e = 0; e < enemies.length; e++) { var otherEnemy = enemies[e]; if (otherEnemy !== self && !otherEnemy.isRespawning && !self.isRespawning) { var dx = otherEnemy.x - self.x; var dy = otherEnemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var minDistance = 250; // Much larger minimum distance between enemies if (distance < minDistance && distance > 0) { // Calculate push direction (away from other enemy) with much stronger force var pushStrength = (minDistance - distance) * 2.5; // Much stronger push force var pushX = -(dx / distance) * pushStrength; var pushY = -(dy / distance) * pushStrength; // Apply strong push force to separate enemies self.x += pushX; self.y += pushY; // Also apply counter-force to the other enemy for better separation otherEnemy.x += dx / distance * pushStrength * 0.8; otherEnemy.y += dy / distance * pushStrength * 0.8; } } } // Keep enemy in bounds if (self.x < 150) self.x = 150; if (self.x > 1898) self.x = 1898; if (self.y < 150) self.y = 150; if (self.y > 2582) self.y = 2582; }; return self; }); var HealthPack = Container.expand(function () { var self = Container.call(this); var healthPackGraphics = self.attachAsset('healthPack', { anchorX: 0.5, anchorY: 0.5 }); self.healAmount = 150; // Heal amount (50% of max health) self.lifetime = 600; // 10 seconds at 60fps // Pulse animation for visibility var pulseDirection = 1; var pulseSpeed = 0.02; self.update = function () { // Pulse animation healthPackGraphics.scaleX += pulseDirection * pulseSpeed; healthPackGraphics.scaleY += pulseDirection * pulseSpeed; if (healthPackGraphics.scaleX > 1.3 || healthPackGraphics.scaleX < 0.8) { pulseDirection *= -1; } // Reduce lifetime self.lifetime--; if (self.lifetime <= 0) { self.destroy(); } // Check collision with player if (!player.isRespawning && self.intersects(player)) { // Heal player var oldHealth = player.health; player.health = Math.min(player.maxHealth, player.health + self.healAmount); player.updateHealthBar(); // Give immunity for 2 seconds player.immunityTimer = 120; // Increase bullet speed for 3 seconds bulletSpeedBoostTimer = 180; // 3 seconds at 60fps // Visual effect tween(healthPackGraphics, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.destroy(); } }); LK.getSound('heal').play(); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); var healthBarBg = self.attachAsset('healthBarBg', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -60 }); var healthBar = self.attachAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -60 }); self.maxHealth = 100; self.health = 100; self.speed = 8; self.attackRange = 100; self.attackDamage = 25; self.attackCooldown = 0; self.isRespawning = false; self.respawnTimer = 0; self.immunityTimer = 0; // Immunity period after respawn self.takeDamage = function (damage, source) { if (self.isRespawning || self.immunityTimer > 0) return; // Prevent damage from explosions and enemy spawning if (source === 'explosion' || source === 'spawn') { return; } self.health -= damage; if (self.health < 0) self.health = 0; self.updateHealthBar(); // Flash red when taking damage tween(playerGraphics, { tint: 0xFF0000 }, { duration: 200, onFinish: function onFinish() { tween(playerGraphics, { tint: 0xFFFFFF }, { duration: 200 }); } }); if (self.health <= 0) { self.die(); } LK.getSound('hit').play(); }; self.updateHealthBar = function () { var healthPercent = self.health / self.maxHealth; healthBar.scaleX = healthPercent; if (healthPercent > 0.6) { healthBar.tint = 0x00FF00; } else if (healthPercent > 0.3) { healthBar.tint = 0xFFFF00; } else { healthBar.tint = 0xFF0000; } }; self.die = function () { self.isRespawning = true; self.respawnTimer = 180; // 3 seconds at 60fps playerGraphics.alpha = 0.3; healthBar.visible = false; healthBarBg.visible = false; // Reset score when player dies score = 0; scoreText.setText('Score: ' + score); // Reset difficulty scaling difficultyLevel = 0; lastDifficultyScore = 0; enemySpeedMultiplier = 1.0; // Reset speed multiplier // Reset map - clear all enemies for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].destroy(); } enemies = []; // Clear all bullets for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].destroy(); } bullets = []; // Clear all health packs for (var i = healthPacks.length - 1; i >= 0; i--) { healthPacks[i].destroy(); } healthPacks = []; // Reset other game state enemiesKilled = 0; bulletSpeedBoostTimer = 0; lastHealthPackSpawn = 0; fireRateBoostLevel = 0; // Reset fire rate progression enemySpawnTimer = 0; // Reset spawn timer }; self.respawn = function () { self.health = self.maxHealth; self.isRespawning = false; self.respawnTimer = 0; playerGraphics.alpha = 1; healthBar.visible = true; healthBarBg.visible = true; self.updateHealthBar(); // Respawn at center position since map is reset self.x = 500; self.y = 1000; // Add brief immunity period after respawn self.immunityTimer = 180; // 3 seconds of immunity // Spawn initial enemies after map reset for (var i = 0; i < 3; i++) { spawnNewEnemy(); } LK.getSound('respawn').play(); }; self.attack = function () { if (self.attackCooldown > 0 || self.isRespawning) return; // Fire rate proportional to enemy count - more enemies = faster firing var activeEnemies = 0; for (var e = 0; e < enemies.length; e++) { if (!enemies[e].isRespawning) activeEnemies++; } var dynamicFireRate = Math.max(40, baseFireRate - activeEnemies * 3); // Slower and more controlled firing // Apply fire rate boost - reduce cooldown by 3 frames per boost level (max 30% reduction) var fireRateReduction = Math.min(fireRateBoostLevel * 3, dynamicFireRate * 0.3); self.attackCooldown = dynamicFireRate - fireRateReduction; // Find closest enemy var closestEnemy = null; var closestDistance = Infinity; for (var i = 0; i < enemies.length; i++) { if (!enemies[i].isRespawning) { var distance = Math.sqrt(Math.pow(enemies[i].x - self.x, 2) + Math.pow(enemies[i].y - self.y, 2)); if (distance < closestDistance) { closestDistance = distance; closestEnemy = enemies[i]; } } } if (closestEnemy) { // Create bullet projectile var bullet = game.addChild(new Bullet()); bullet.x = self.x; bullet.y = self.y; bullet.targetX = closestEnemy.x; bullet.targetY = closestEnemy.y; bullet.damage = self.attackDamage; bullet.isPlayerBullet = true; bullet.targetEnemy = closestEnemy; // Set specific target enemy bullets.push(bullet); // Create muzzle flash effect var attackEffect = LK.getAsset('attackEffect', { anchorX: 0.5, anchorY: 0.5 }); attackEffect.x = self.x; attackEffect.y = self.y; attackEffect.alpha = 0.7; attackEffect.tint = 0x4499FF; attackEffect.scaleX = 0.8; attackEffect.scaleY = 0.8; game.addChild(attackEffect); // Scale and fade out attack effect tween(attackEffect, { scaleX: 1.2, scaleY: 1.2, alpha: 0 }, { duration: 200, onFinish: function onFinish() { attackEffect.destroy(); } }); LK.getSound('attack').play(); } }; self.update = function () { if (self.attackCooldown > 0) { self.attackCooldown--; } if (self.immunityTimer > 0) { self.immunityTimer--; // Flash during immunity period if (self.immunityTimer % 10 < 5) { playerGraphics.alpha = 0.5; } else { playerGraphics.alpha = 1; } } if (self.isRespawning) { self.respawnTimer--; if (self.respawnTimer <= 0) { self.respawn(); } return; } // Auto-attack enemies regardless of distance if (self.attackCooldown <= 0) { for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (!enemy.isRespawning) { self.attack(); break; // Only attack one enemy per frame } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2C3E50 }); /**** * Game Code ****/ // Create arena background var arena = game.addChild(LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5 })); arena.x = 2048 / 2; arena.y = 2732 / 2; // Game variables var player; var enemies = []; var bullets = []; var moveUp = false; var moveDown = false; var moveLeft = false; var moveRight = false; var targetX = 0; var targetY = 0; var isMovingToTarget = false; var enemiesKilled = 0; var score = 0; var baseFireRate = 90; // Base attack cooldown - slower firing var currentFireRate = 60; var fireRateBoostLevel = 0; // Tracks fire rate improvements var maxEnemies = 8; // Base maximum number of enemies allowed var enemySpeedMultiplier = 1.0; // Gradually increases enemy speed var explosionRadius = 150; // Radius for chain explosions var difficultyLevel = 0; // Current difficulty level var lastDifficultyScore = 0; // Score at last difficulty increase var healthPacks = []; var lastHealthPackSpawn = 0; var bulletSpeedBoostTimer = 0; // Timer for bullet speed boost var baseBulletSpeed = 15; // Base bullet speed var enemySpawnTimer = 0; // Timer for continuous enemy spawning var baseSpawnInterval = 120; // Base spawn interval (2 seconds at 60fps) // Start main music LK.playMusic('Main'); // Initialize music state tracking game.main1Playing = false; // Create player player = game.addChild(new Player()); player.x = 500; player.y = 1000; // Function to spawn new enemy from off-screen edges (Vampire Survivors style) function spawnNewEnemy() { var enemy = game.addChild(new Enemy()); // Choose random edge to spawn from (off-screen) var spawnSide = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left var spawnOffset = Math.random(); // Random position along edge (0% to 100%) // Spawn outside visible area for true Vampire Survivors effect var offScreenDistance = 100; // Distance outside visible area switch (spawnSide) { case 0: // Top edge - spawn above screen enemy.x = spawnOffset * 2048; enemy.y = -offScreenDistance; break; case 1: // Right edge - spawn to the right of screen enemy.x = 2048 + offScreenDistance; enemy.y = spawnOffset * 2732; break; case 2: // Bottom edge - spawn below screen enemy.x = spawnOffset * 2048; enemy.y = 2732 + offScreenDistance; break; case 3: // Left edge - spawn to the left of screen enemy.x = -offScreenDistance; enemy.y = spawnOffset * 2732; break; } // Give new enemies a brief spawn immunity to prevent instant collision damage enemy.spawnImmunityTimer = 60; // 1 second of spawn immunity enemy.targetX = enemy.x; enemy.targetY = enemy.y; enemies.push(enemy); } // Initial enemies will be spawned by the continuous spawning system // No need for initial spawn - let the timer handle it // UI Elements var instructionText = new Text2('Tap to move - Auto attack enemies nearby', { size: 40, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0); LK.gui.top.addChild(instructionText); instructionText.y = 100; // Score display var scoreText = new Text2('Score: 0', { size: 50, fill: 0xFFD700 }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); scoreText.y = 150; var dragNode = null; var lastTouchTime = 0; // Touch controls game.down = function (x, y, obj) { if (player.isRespawning) return; // Keep target position in bounds targetX = Math.max(150, Math.min(1898, x)); targetY = Math.max(150, Math.min(2582, y)); // Stop any current movement tween tween.stop(player, { x: true, y: true }); // Calculate distance for duration (closer = faster) var distance = Math.sqrt(Math.pow(targetX - player.x, 2) + Math.pow(targetY - player.y, 2)); var duration = Math.max(200, Math.min(1000, distance * 2)); // 200ms to 1000ms based on distance isMovingToTarget = true; // Tween player to target position tween(player, { x: targetX, y: targetY }, { duration: duration, easing: tween.easeOut, onFinish: function onFinish() { isMovingToTarget = false; } }); }; game.move = function (x, y, obj) { // No drag movement needed - player moves via tween to clicked position }; game.up = function (x, y, obj) { // No action needed - player auto-attacks when moving }; // Main game loop game.update = function () { // Vampire Survivors style continuous enemy spawning enemySpawnTimer++; var currentSpawnInterval = Math.max(30, baseSpawnInterval - Math.floor(score / 50) * 10); // Faster spawning as score increases if (enemySpawnTimer >= currentSpawnInterval && enemies.length < maxEnemies + difficultyLevel) { spawnNewEnemy(); enemySpawnTimer = 0; // Reset spawn timer } // Music transitions based on score if (score >= 100 && score < 500) { // Play main1 music from score 100 to 500 if (!game.main1Playing) { LK.stopMusic(); LK.playMusic('main1'); game.main1Playing = true; } } else if (score >= 500) { // Stop music when score reaches 500 if (game.main1Playing) { LK.stopMusic(); game.main1Playing = false; } } // Update bullet speed boost timer if (bulletSpeedBoostTimer > 0) { bulletSpeedBoostTimer--; } // Check for fire rate boost every 100 kills var newFireRateBoostLevel = Math.floor(enemiesKilled / 100); if (newFireRateBoostLevel > fireRateBoostLevel) { fireRateBoostLevel = newFireRateBoostLevel; // Visual feedback for fire rate increase LK.effects.flashScreen(0x0099FF, 300); // Blue flash to indicate fire rate boost } // Check for difficulty increase every 25 points if (score - lastDifficultyScore >= 25) { difficultyLevel++; lastDifficultyScore = score; // Systematic enemy speed progression based on score ranges if (score <= 100) { // Early game: minimal speed increase enemySpeedMultiplier = 1.0 + score * 0.005; // Max 1.5x at score 100 } else if (score <= 200) { // Mid game: moderate increase enemySpeedMultiplier = 1.5 + (score - 100) * 0.003; // 1.5x to 1.8x } else if (score <= 400) { // Late game: controlled increase enemySpeedMultiplier = 1.8 + (score - 200) * 0.002; // 1.8x to 2.2x } else { // End game: capped maximum speed enemySpeedMultiplier = Math.min(2.5, 2.2 + (score - 400) * 0.001); // Max 2.5x speed } // Spawn additional enemies based on difficulty level var enemiesToSpawn = Math.min(2, difficultyLevel); // Spawn 1-2 enemies per difficulty increase for (var d = 0; d < enemiesToSpawn && enemies.length < maxEnemies + difficultyLevel; d++) { spawnNewEnemy(); } // Visual feedback for difficulty increase LK.effects.flashScreen(0x00FF00, 500); // Green flash to indicate difficulty increase } // Spawn health pack when player health is low (below 25%) if (player.health < player.maxHealth * 0.25 && LK.ticks - lastHealthPackSpawn > 300 && // 5 second cooldown healthPacks.length === 0) { // Only one health pack at a time var healthPack = game.addChild(new HealthPack()); // Spawn at random location away from enemies var attempts = 0; var maxAttempts = 20; var minSafeDistance = 200; do { healthPack.x = 300 + Math.random() * 1400; healthPack.y = 400 + Math.random() * 1800; var isSafe = true; for (var e = 0; e < enemies.length; e++) { if (!enemies[e].isRespawning) { var dx = healthPack.x - enemies[e].x; var dy = healthPack.y - enemies[e].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < minSafeDistance) { isSafe = false; break; } } } attempts++; } while (!isSafe && attempts < maxAttempts); healthPacks.push(healthPack); lastHealthPackSpawn = LK.ticks; } // Update all game objects player.update(); for (var i = 0; i < enemies.length; i++) { enemies[i].update(); } // Update health packs and clean up destroyed ones for (var i = healthPacks.length - 1; i >= 0; i--) { var healthPack = healthPacks[i]; if (healthPack.destroyed) { healthPacks.splice(i, 1); } else { healthPack.update(); } } // Update bullets and clean up destroyed ones for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.destroyed === true || !bullet.parent) { bullets.splice(i, 1); } else { bullet.update(); } } };
===================================================================
--- original.js
+++ change.js
@@ -435,8 +435,9 @@
enemiesKilled = 0;
bulletSpeedBoostTimer = 0;
lastHealthPackSpawn = 0;
fireRateBoostLevel = 0; // Reset fire rate progression
+ enemySpawnTimer = 0; // Reset spawn timer
};
self.respawn = function () {
self.health = self.maxHealth;
self.isRespawning = false;
@@ -591,60 +592,56 @@
var healthPacks = [];
var lastHealthPackSpawn = 0;
var bulletSpeedBoostTimer = 0; // Timer for bullet speed boost
var baseBulletSpeed = 15; // Base bullet speed
+var enemySpawnTimer = 0; // Timer for continuous enemy spawning
+var baseSpawnInterval = 120; // Base spawn interval (2 seconds at 60fps)
// Start main music
LK.playMusic('Main');
// Initialize music state tracking
game.main1Playing = false;
// Create player
player = game.addChild(new Player());
player.x = 500;
player.y = 1000;
-// Function to spawn new enemy from map edges and corners
+// Function to spawn new enemy from off-screen edges (Vampire Survivors style)
function spawnNewEnemy() {
var enemy = game.addChild(new Enemy());
- var attempts = 0;
- var maxAttempts = 30;
- var enemySafeDistance = 200; // Minimum distance from other enemies
- do {
- // Choose random edge/corner to spawn from
- var spawnSide = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
- var spawnOffset = Math.random() * 0.8 + 0.1; // Random position along edge (10% to 90%)
- switch (spawnSide) {
- case 0:
- // Top edge
- enemy.x = 150 + spawnOffset * (1898 - 150);
- enemy.y = 150;
- break;
- case 1:
- // Right edge
- enemy.x = 1898;
- enemy.y = 150 + spawnOffset * (2582 - 150);
- break;
- case 2:
- // Bottom edge
- enemy.x = 150 + spawnOffset * (1898 - 150);
- enemy.y = 2582;
- break;
- case 3:
- // Left edge
- enemy.x = 150;
- enemy.y = 150 + spawnOffset * (2582 - 150);
- break;
- }
- attempts++;
- } while (false && attempts < maxAttempts); // Allow enemies to spawn close to each other
+ // Choose random edge to spawn from (off-screen)
+ var spawnSide = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
+ var spawnOffset = Math.random(); // Random position along edge (0% to 100%)
+ // Spawn outside visible area for true Vampire Survivors effect
+ var offScreenDistance = 100; // Distance outside visible area
+ switch (spawnSide) {
+ case 0:
+ // Top edge - spawn above screen
+ enemy.x = spawnOffset * 2048;
+ enemy.y = -offScreenDistance;
+ break;
+ case 1:
+ // Right edge - spawn to the right of screen
+ enemy.x = 2048 + offScreenDistance;
+ enemy.y = spawnOffset * 2732;
+ break;
+ case 2:
+ // Bottom edge - spawn below screen
+ enemy.x = spawnOffset * 2048;
+ enemy.y = 2732 + offScreenDistance;
+ break;
+ case 3:
+ // Left edge - spawn to the left of screen
+ enemy.x = -offScreenDistance;
+ enemy.y = spawnOffset * 2732;
+ break;
+ }
// Give new enemies a brief spawn immunity to prevent instant collision damage
enemy.spawnImmunityTimer = 60; // 1 second of spawn immunity
enemy.targetX = enemy.x;
enemy.targetY = enemy.y;
enemies.push(enemy);
}
-// Create initial enemies from random edge positions
-for (var i = 0; i < 3; i++) {
- spawnNewEnemy();
-}
+// Initial enemies will be spawned by the continuous spawning system
+// No need for initial spawn - let the timer handle it
// UI Elements
var instructionText = new Text2('Tap to move - Auto attack enemies nearby', {
size: 40,
fill: 0xFFFFFF
@@ -696,8 +693,15 @@
// No action needed - player auto-attacks when moving
};
// Main game loop
game.update = function () {
+ // Vampire Survivors style continuous enemy spawning
+ enemySpawnTimer++;
+ var currentSpawnInterval = Math.max(30, baseSpawnInterval - Math.floor(score / 50) * 10); // Faster spawning as score increases
+ if (enemySpawnTimer >= currentSpawnInterval && enemies.length < maxEnemies + difficultyLevel) {
+ spawnNewEnemy();
+ enemySpawnTimer = 0; // Reset spawn timer
+ }
// Music transitions based on score
if (score >= 100 && score < 500) {
// Play main1 music from score 100 to 500
if (!game.main1Playing) {
bullet. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Face. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
face. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
green hearth. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Grey gound . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat