User prompt
Please add automatic bullet firing to the player character with a simple default bullet that deals basic damage.
User prompt
KARAKTER OYUNCUNUN YÖNLENDİRMESİNE GÖRE DEĞİL NERYEE BAKIYORSA ORAYA ATEŞ ETSİN
User prompt
Karekter hangi yöne doğru bakıyorsa o yöne doğru ateş etsin
User prompt
Otomatik ateş etmeyi kaldır oyuncu sadece baktığı yöne ateş etsin
User prompt
Please modify the character shooting system as follows: - The character should always fire bullets in the same direction it is currently moving or being controlled toward. - Add a directional arrow indicator in front of the character to show the current aiming direction, similar to how it is displayed in games like snake.io. - The arrow should smoothly rotate to match the player's facing direction and move with the player, providing a clear visual indicator of the current firing direction. - Ensure that while the player moves in one direction, the bullets are continuously fired in that same direction, matching the direction shown by the arrow. - Test to confirm the arrow and bullet direction stay consistent with the player's movement input. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mermilerimiz hepsi tutmasın rakiplerimiz mermilerden kaçınabilsğn
User prompt
Please upgrade the survivor battle arena game with the following advanced features: 1. Add a skill upgrade system where players can choose from random skills after each wave, such as attack speed, health regeneration, or area damage. 2. Include multiple unique characters with different starting weapons and stats, giving players strategic variety. 3. Introduce elite enemies and boss fights every 5 waves, with special attack patterns. 4. Create a combo multiplier mechanic that rewards players for quickly defeating enemies without getting hit. 5. Add a dynamic soundtrack that intensifies as waves progress, increasing the adrenaline and sense of urgency. 6. Include visual particle effects for explosions, skills, and critical hits to make combat feel more impactful. 7. Make sure the game supports smooth performance on mobile devices by optimizing all assets and keeping frame rates stable. 8. Test the entire gameplay loop after these additions to confirm no bugs and enjoyable flow. Implement these advanced features to create a highly engaging, replayable, and polished survivor battle arena experience. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Hayır sadece başta gelen yazıyı rengarenk yap geri kalan herşey geri kendi haline gelsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make it rainbow ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyun başlarken "Move by dragging" yazısı gözüksün yazı 2sn durup fade efekti ile yok olsun sonra rakipler gelemue başlasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Karalterimiz dokunduğumuz yere ışınlanmasın dokunduğumuz yerden sürükleyelim neryee sürüklüyorsak oraya yönlensin karakter
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'healthText.style.fill = "#4CAF50";' Line Number: 399
Code edit (1 edits merged)
Please save this source code
User prompt
Survivor Arena
Initial prompt
Create a 2D top-down survivor arena game where the player fights endless waves of enemies, collects powerups, and upgrades weapons to survive as long as possible.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Boss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 500; self.maxHealth = 500; self.speed = 1.5; self.damage = 30; self.lastPlayerDistance = 0; self.attackCooldown = 0; self.attackPhase = 0; self.isBoss = true; self.update = function () { // Check for nearby bullets and evade (bosses have moderate evasion) var evadeX = 0; var evadeY = 0; var shouldEvade = false; for (var i = 0; i < bullets.length; i++) { var bullet = bullets[i]; var bulletDx = bullet.x - self.x; var bulletDy = bullet.y - self.y; var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy); // Bosses detect bullets from medium range if (bulletDistance < 100) { var bulletSpeed = Math.sqrt(bullet.velocityX * bullet.velocityX + bullet.velocityY * bullet.velocityY); if (bulletSpeed > 0) { // Calculate if bullet is heading towards enemy var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX); var enemyDirection = Math.atan2(bulletDy, bulletDx); var angleDiff = Math.abs(bulletDirection - enemyDirection); if (angleDiff > Math.PI) angleDiff = 2 * Math.PI - angleDiff; // Bosses have narrow detection angle but good reaction if (angleDiff < Math.PI / 6) { shouldEvade = true; // Calculate perpendicular evasion direction evadeX += -bulletDy / bulletDistance * (100 - bulletDistance) / 100; evadeY += bulletDx / bulletDistance * (100 - bulletDistance) / 100; } } } } // Move towards player slowly var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 100) { var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; // Apply evasion if needed (bosses have moderate dodge chance) if (shouldEvade) { // 50% chance to successfully evade if (Math.random() < 0.5) { moveX += evadeX * 1.5; moveY += evadeY * 1.5; } } self.x += moveX; self.y += moveY; } // Attack patterns if (self.attackCooldown > 0) { self.attackCooldown--; } else { self.performAttack(); self.attackCooldown = 120; // 2 seconds } // Check collision with player var currentPlayerDistance = distance; if (self.lastPlayerDistance > 80 && currentPlayerDistance <= 80) { player.takeDamage(self.damage); } self.lastPlayerDistance = currentPlayerDistance; }; self.performAttack = function () { switch (self.attackPhase) { case 0: self.circularAttack(); break; case 1: self.chargeAttack(); break; case 2: self.areaAttack(); break; } self.attackPhase = (self.attackPhase + 1) % 3; }; self.circularAttack = function () { for (var i = 0; i < 8; i++) { var angle = i * Math.PI / 4; var projectile = new EnemyProjectile(); projectile.x = self.x; projectile.y = self.y; projectile.velocityX = Math.cos(angle) * 8; projectile.velocityY = Math.sin(angle) * 8; enemyProjectiles.push(projectile); game.addChild(projectile); } }; self.chargeAttack = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { tween(self, { x: self.x + dx / distance * 200, y: self.y + dy / distance * 200 }, { duration: 500, easing: tween.easeOut }); } }; self.areaAttack = function () { createExplosion(self.x, self.y, 150); LK.getSound('explosion').play(); var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { player.takeDamage(self.damage); } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } else { LK.effects.flashObject(self, 0xFFFFFF, 100); } }; self.die = function () { createExplosion(self.x, self.y, 200); LK.getSound('explosion').play(); LK.setScore(LK.getScore() + 200); player.addCombo(); // Boss defeated - show upgrade screen showUpgradeScreen(); // Remove from enemies array for (var i = 0; i < enemies.length; i++) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } self.destroy(); }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.damage = 25; self.isCritical = false; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Check collision with enemies for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (self.intersects(enemy)) { var finalDamage = self.damage; if (self.isCritical) { finalDamage *= 2; createExplosion(self.x, self.y, 50); } enemy.takeDamage(finalDamage); player.addCombo(); self.destroy(); // Remove from bullets array for (var j = 0; j < bullets.length; j++) { if (bullets[j] === self) { bullets.splice(j, 1); break; } } return; } } // Remove if out of bounds if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) { self.destroy(); for (var k = 0; k < bullets.length; k++) { if (bullets[k] === self) { bullets.splice(k, 1); break; } } } }; return self; }); var Character = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'warrior'; var characterGraphics = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5 }); // Set stats based on character type switch (self.type) { case 'warrior': self.health = 120; self.maxHealth = 120; self.damage = 30; self.fireRate = 18; self.speed = 7; self.weaponType = 'sword'; break; case 'archer': self.health = 80; self.maxHealth = 80; self.damage = 20; self.fireRate = 10; self.speed = 10; self.weaponType = 'bow'; break; case 'mage': self.health = 60; self.maxHealth = 60; self.damage = 35; self.fireRate = 25; self.speed = 8; self.weaponType = 'staff'; break; } self.fireCooldown = 0; self.comboMultiplier = 1; self.comboTimer = 0; self.comboCount = 0; self.lastX = 0; self.lastY = 0; self.aimDirection = 0; self.movementDirection = 0; // Create arrow indicator self.arrowIndicator = self.attachAsset('arrow', { anchorX: 0.5, anchorY: 0.5 }); self.arrowIndicator.x = 0; self.arrowIndicator.y = -50; self.update = function () { // Track movement direction var deltaX = self.x - self.lastX; var deltaY = self.y - self.lastY; var movementSpeed = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Update aim direction based on movement if (movementSpeed > 0.5) { self.movementDirection = Math.atan2(deltaY, deltaX); self.aimDirection = self.movementDirection; } // Smoothly rotate arrow to match aim direction tween(self.arrowIndicator, { rotation: self.aimDirection }, { duration: 100, easing: tween.easeOut }); // Update last position self.lastX = self.x; self.lastY = self.y; if (self.fireCooldown > 0) { self.fireCooldown--; } if (self.comboTimer > 0) { self.comboTimer--; } else { self.comboMultiplier = 1; self.comboCount = 0; } // Manual firing - fire continuously in aim direction if (self.fireCooldown <= 0) { self.fireAt(null); // Fire in aim direction, no target needed self.fireCooldown = self.fireRate; } // Keep player within arena bounds var arenaLeft = arena.x - arena.width / 2; var arenaRight = arena.x + arena.width / 2; var arenaTop = arena.y - arena.height / 2; var arenaBottom = arena.y + arena.height / 2; if (self.x < arenaLeft + 40) self.x = arenaLeft + 40; if (self.x > arenaRight - 40) self.x = arenaRight - 40; if (self.y < arenaTop + 40) self.y = arenaTop + 40; if (self.y > arenaBottom - 40) self.y = arenaBottom - 40; }; // findNearestEnemy method removed - no longer needed for manual firing self.fireAt = function (target) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; // Fire in the current aim direction instead of towards target bullet.velocityX = Math.cos(self.aimDirection) * 15; bullet.velocityY = Math.sin(self.aimDirection) * 15; bullet.damage = self.damage * self.comboMultiplier; bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); }; self.takeDamage = function (damage) { self.health -= damage; self.comboMultiplier = 1; self.comboCount = 0; self.comboTimer = 0; if (self.health <= 0) { self.health = 0; LK.showGameOver(); } LK.effects.flashObject(self, 0xFF0000, 200); }; self.addCombo = function () { self.comboCount++; self.comboTimer = 180; // 3 seconds if (self.comboCount >= 5) { self.comboMultiplier = Math.min(self.comboMultiplier + 0.1, 3); } }; return self; }); var Player = Character.expand(function (type) { var self = Character.call(this, type); // Add critical hit chance self.criticalChance = 0.1; // Override fireAt to add critical hits var originalFireAt = self.fireAt; self.fireAt = function (target) { originalFireAt.call(self, target); // Add critical hit chance var lastBullet = bullets[bullets.length - 1]; if (lastBullet && Math.random() < self.criticalChance) { lastBullet.isCritical = true; lastBullet.children[0].tint = 0xFF4444; } }; return self; }); var EliteEnemy = Container.expand(function () { var self = Container.call(this); var eliteGraphics = self.attachAsset('eliteEnemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 150; self.maxHealth = 150; self.speed = 3; self.damage = 20; self.lastPlayerDistance = 0; self.specialCooldown = 0; self.isElite = true; self.update = function () { // Check for nearby bullets and evade (elite enemies are better at dodging) var evadeX = 0; var evadeY = 0; var shouldEvade = false; for (var i = 0; i < bullets.length; i++) { var bullet = bullets[i]; var bulletDx = bullet.x - self.x; var bulletDy = bullet.y - self.y; var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy); // Elite enemies detect bullets from further away if (bulletDistance < 150) { var bulletSpeed = Math.sqrt(bullet.velocityX * bullet.velocityX + bullet.velocityY * bullet.velocityY); if (bulletSpeed > 0) { // Calculate if bullet is heading towards enemy var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX); var enemyDirection = Math.atan2(bulletDy, bulletDx); var angleDiff = Math.abs(bulletDirection - enemyDirection); if (angleDiff > Math.PI) angleDiff = 2 * Math.PI - angleDiff; // Elite enemies have wider detection angle if (angleDiff < Math.PI / 3) { shouldEvade = true; // Calculate perpendicular evasion direction evadeX += -bulletDy / bulletDistance * (150 - bulletDistance) / 150; evadeY += bulletDx / bulletDistance * (150 - bulletDistance) / 150; } } } } // Move towards player var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; // Apply evasion if needed (elite enemies are better at dodging) if (shouldEvade) { // 85% chance to successfully evade if (Math.random() < 0.85) { moveX += evadeX * 2.5; moveY += evadeY * 2.5; } } self.x += moveX; self.y += moveY; } // Special ability - dash attack if (self.specialCooldown > 0) { self.specialCooldown--; } else if (distance < 200 && distance > 80) { self.specialCooldown = 300; // 5 seconds self.dashAttack(); } // Check collision with player var currentPlayerDistance = distance; if (self.lastPlayerDistance > 50 && currentPlayerDistance <= 50) { player.takeDamage(self.damage); } self.lastPlayerDistance = currentPlayerDistance; }; self.dashAttack = function () { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { tween(self, { x: self.x + dx / distance * 150, y: self.y + dy / distance * 150 }, { duration: 300, easing: tween.easeOut }); } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } else { LK.effects.flashObject(self, 0xFFFFFF, 100); } }; self.die = function () { createExplosion(self.x, self.y); LK.getSound('explosion').play(); LK.setScore(LK.getScore() + 50); player.addCombo(); // Higher chance for power-up if (Math.random() < 0.6) { var powerup = new PowerUp(); powerup.x = self.x; powerup.y = self.y; powerups.push(powerup); game.addChild(powerup); } // Remove from enemies array for (var i = 0; i < enemies.length; i++) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } 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 }); self.health = 50; self.speed = 2; self.damage = 10; self.lastPlayerDistance = 0; self.update = function () { // Check for nearby bullets and evade var evadeX = 0; var evadeY = 0; var shouldEvade = false; for (var i = 0; i < bullets.length; i++) { var bullet = bullets[i]; var bulletDx = bullet.x - self.x; var bulletDy = bullet.y - self.y; var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy); // If bullet is close (within 120 pixels) and moving towards enemy if (bulletDistance < 120) { var bulletSpeed = Math.sqrt(bullet.velocityX * bullet.velocityX + bullet.velocityY * bullet.velocityY); if (bulletSpeed > 0) { // Calculate if bullet is heading towards enemy var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX); var enemyDirection = Math.atan2(bulletDy, bulletDx); var angleDiff = Math.abs(bulletDirection - enemyDirection); if (angleDiff > Math.PI) angleDiff = 2 * Math.PI - angleDiff; // If bullet is heading towards enemy (within 45 degrees) if (angleDiff < Math.PI / 4) { shouldEvade = true; // Calculate perpendicular evasion direction evadeX += -bulletDy / bulletDistance * (120 - bulletDistance) / 120; evadeY += bulletDx / bulletDistance * (120 - bulletDistance) / 120; } } } } // Move towards player var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; // Apply evasion if needed if (shouldEvade) { // 70% chance to successfully evade if (Math.random() < 0.7) { moveX += evadeX * 2; moveY += evadeY * 2; } } self.x += moveX; self.y += moveY; } // Check collision with player var currentPlayerDistance = distance; if (self.lastPlayerDistance > 50 && currentPlayerDistance <= 50) { player.takeDamage(self.damage); } self.lastPlayerDistance = currentPlayerDistance; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.die(); } else { LK.effects.flashObject(self, 0xFFFFFF, 100); } }; self.die = function () { createExplosion(self.x, self.y); LK.getSound('enemyHit').play(); LK.setScore(LK.getScore() + 10); player.addCombo(); // Chance to drop power-up if (Math.random() < 0.3) { var powerup = new PowerUp(); powerup.x = self.x; powerup.y = self.y; powerups.push(powerup); game.addChild(powerup); } // Remove from enemies array for (var i = 0; i < enemies.length; i++) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } self.destroy(); }; return self; }); var EnemyProjectile = Container.expand(function () { var self = Container.call(this); var projectileGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); projectileGraphics.tint = 0xFF0000; self.velocityX = 0; self.velocityY = 0; self.damage = 15; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Check collision with player if (self.intersects(player)) { player.takeDamage(self.damage); self.destroy(); for (var i = 0; i < enemyProjectiles.length; i++) { if (enemyProjectiles[i] === self) { enemyProjectiles.splice(i, 1); break; } } return; } // Remove if out of bounds if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) { self.destroy(); for (var j = 0; j < enemyProjectiles.length; j++) { if (enemyProjectiles[j] === self) { enemyProjectiles.splice(j, 1); break; } } } }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); var explosionGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 30; explosionGraphics.alpha = 0.8; self.update = function () { self.lifetime--; explosionGraphics.alpha = self.lifetime / 30; explosionGraphics.scaleX = explosionGraphics.scaleY = (30 - self.lifetime) / 30 * 2; if (self.lifetime <= 0) { self.destroy(); } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.type = Math.floor(Math.random() * 4); // 0: health, 1: damage, 2: fire rate, 3: speed self.lifetime = 600; // 10 seconds at 60fps // Color based on type var colors = [0x4CAF50, 0xFF5722, 0x2196F3, 0xFFEB3B]; powerupGraphics.tint = colors[self.type]; self.update = function () { self.lifetime--; // Fade out near end of lifetime if (self.lifetime < 120) { powerupGraphics.alpha = self.lifetime / 120; } // Remove if expired if (self.lifetime <= 0) { self.destroy(); for (var i = 0; i < powerups.length; i++) { if (powerups[i] === self) { powerups.splice(i, 1); break; } } return; } // Check collision with player if (self.intersects(player)) { self.applyEffect(); LK.getSound('powerupCollect').play(); self.destroy(); for (var j = 0; j < powerups.length; j++) { if (powerups[j] === self) { powerups.splice(j, 1); break; } } } }; self.applyEffect = function () { switch (self.type) { case 0: // Health player.health = Math.min(player.health + 30, player.maxHealth); break; case 1: // Damage player.damage += 5; break; case 2: // Fire rate player.fireRate = Math.max(player.fireRate - 2, 5); break; case 3: // Speed player.speed = Math.min(player.speed + 1, 15); break; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2C2C2C }); /**** * Game Code ****/ // Game variables var player; var enemies = []; var bullets = []; var powerups = []; var enemyProjectiles = []; var explosions = []; var arena; var waveNumber = 1; var enemySpawnTimer = 0; var enemySpawnRate = 120; // 2 seconds at 60fps var gameTime = 0; var selectedCharacter = storage.selectedCharacter || 'warrior'; var upgradeScreenActive = false; var currentMusicTrack = 'battleMusic'; var musicIntensity = 0; // Create arena arena = game.addChild(LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 })); // Create player player = game.addChild(new Player(selectedCharacter)); player.x = 1024; player.y = 1366; // Initialize last position for movement tracking player.lastX = player.x; player.lastY = player.y; // UI Elements var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -300; scoreText.y = 50; var healthText = new Text2('Health: 100', { size: 60, fill: 0x4CAF50 }); healthText.anchor.set(0, 0); LK.gui.topRight.addChild(healthText); healthText.x = -300; healthText.y = 120; var waveText = new Text2('Wave: 1', { size: 60, fill: 0xFFFFFF }); waveText.anchor.set(0, 0); LK.gui.topRight.addChild(waveText); waveText.x = -300; waveText.y = 190; var comboText = new Text2('Combo: x1', { size: 50, fill: 0xFFEB3B }); comboText.anchor.set(0, 0); LK.gui.topRight.addChild(comboText); comboText.x = -300; comboText.y = 260; // Tutorial text var tutorialText = new Text2('Move by dragging', { size: 80, fill: 0xFFFFFF }); tutorialText.anchor.set(0.5, 0.5); tutorialText.x = 1024; tutorialText.y = 1366; game.addChild(tutorialText); // Add rainbow cycling to tutorial text var tutorialColors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x9400D3]; var tutorialColorIndex = 0; function cycleTutorialRainbow() { var nextColor = tutorialColors[(tutorialColorIndex + 1) % tutorialColors.length]; tween(tutorialText, { tint: nextColor }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tutorialColorIndex = (tutorialColorIndex + 1) % tutorialColors.length; cycleTutorialRainbow(); } }); } cycleTutorialRainbow(); // Fade out tutorial text after 2 seconds LK.setTimeout(function () { tween(tutorialText, { alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { tutorialText.destroy(); } }); }, 2000); // Touch controls var isDragging = false; var dragOffsetX = 0; var dragOffsetY = 0; var gameStarted = false; game.down = function (x, y, obj) { isDragging = true; // Calculate offset from touch point to player center dragOffsetX = player.x - x; dragOffsetY = player.y - y; }; game.move = function (x, y, obj) { if (isDragging) { // Move player by maintaining the offset from touch point player.x = x + dragOffsetX; player.y = y + dragOffsetY; } }; game.up = function (x, y, obj) { isDragging = false; }; // Utility functions function createExplosion(x, y, size) { var explosion = new Explosion(); explosion.x = x; explosion.y = y; if (size) { explosion.children[0].scaleX = explosion.children[0].scaleY = size / 100; } explosions.push(explosion); game.addChild(explosion); } function showUpgradeScreen() { upgradeScreenActive = true; var upgradePanel = LK.getAsset('skillPanel', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); game.addChild(upgradePanel); var upgradeTitle = new Text2('Choose an Upgrade', { size: 60, fill: 0xFFFFFF }); upgradeTitle.anchor.set(0.5, 0.5); upgradeTitle.x = 1024; upgradeTitle.y = 1200; game.addChild(upgradeTitle); var upgrades = [{ name: 'Attack Speed', desc: 'Faster firing rate' }, { name: 'Health Boost', desc: 'Increase max health' }, { name: 'Critical Hit', desc: 'Higher crit chance' }]; for (var i = 0; i < 3; i++) { var button = LK.getAsset('skillButton', { anchorX: 0.5, anchorY: 0.5, x: 700 + i * 200, y: 1366 }); game.addChild(button); var buttonText = new Text2(upgrades[i].name, { size: 30, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 700 + i * 200; buttonText.y = 1366; game.addChild(buttonText); button.down = function (x, y, obj) { applyUpgrade(i); upgradePanel.destroy(); upgradeTitle.destroy(); for (var j = 0; j < 3; j++) { game.children[game.children.length - 1].destroy(); game.children[game.children.length - 1].destroy(); } upgradeScreenActive = false; }; } } function applyUpgrade(type) { switch (type) { case 0: // Attack Speed player.fireRate = Math.max(player.fireRate - 3, 5); break; case 1: // Health Boost player.maxHealth += 30; player.health = Math.min(player.health + 30, player.maxHealth); break; case 2: // Critical Hit player.criticalChance = Math.min(player.criticalChance + 0.1, 0.5); break; } } // Spawn enemy function function spawnEnemy() { var enemy; // Boss every 5 waves if (waveNumber % 5 === 0 && enemies.length === 0) { enemy = new Boss(); LK.getSound('bossSpawn').play(); LK.playMusic('bossMusic', { fade: { start: 0, end: 1, duration: 1000 } }); } else if (Math.random() < 0.2) { // 20% chance for elite enemy enemy = new EliteEnemy(); } else { enemy = new Enemy(); } // Spawn from arena edges var side = Math.floor(Math.random() * 4); var arenaLeft = arena.x - arena.width / 2; var arenaRight = arena.x + arena.width / 2; var arenaTop = arena.y - arena.height / 2; var arenaBottom = arena.y + arena.height / 2; switch (side) { case 0: // Top enemy.x = arenaLeft + Math.random() * arena.width; enemy.y = arenaTop; break; case 1: // Right enemy.x = arenaRight; enemy.y = arenaTop + Math.random() * arena.height; break; case 2: // Bottom enemy.x = arenaLeft + Math.random() * arena.width; enemy.y = arenaBottom; break; case 3: // Left enemy.x = arenaLeft; enemy.y = arenaTop + Math.random() * arena.height; break; } // Scale enemy stats with wave number if (!enemy.isBoss) { enemy.health += Math.floor(waveNumber * 5); enemy.speed += Math.floor(waveNumber * 0.2); enemy.damage += Math.floor(waveNumber * 2); } enemies.push(enemy); game.addChild(enemy); } // Main game loop game.update = function () { // Start game logic after 3 seconds (tutorial display time) if (gameTime < 180) { // 3 seconds at 60fps gameTime++; return; } if (!gameStarted) { gameStarted = true; LK.playMusic('battleMusic'); } if (upgradeScreenActive) { return; } gameTime++; // Update wave number based on time var newWave = Math.floor(gameTime / 1800) + 1; // New wave every 30 seconds if (newWave > waveNumber) { waveNumber = newWave; enemySpawnRate = Math.max(enemySpawnRate - 10, 30); // Increase spawn rate // Dynamic music intensity musicIntensity = Math.min(waveNumber / 10, 1); if (waveNumber % 5 !== 0) { LK.playMusic('battleMusic', { fade: { start: 0.5, end: 0.5 + musicIntensity * 0.5, duration: 500 } }); } } // Spawn enemies enemySpawnTimer++; if (enemySpawnTimer >= enemySpawnRate) { var enemiesToSpawn = Math.min(waveNumber, 8); for (var i = 0; i < enemiesToSpawn; i++) { spawnEnemy(); } enemySpawnTimer = 0; } // Update explosions for (var e = explosions.length - 1; e >= 0; e--) { var explosion = explosions[e]; if (explosion.lifetime <= 0) { explosions.splice(e, 1); } } // Update UI scoreText.setText('Score: ' + LK.getScore()); healthText.setText('Health: ' + player.health); waveText.setText('Wave: ' + waveNumber); comboText.setText('Combo: x' + player.comboMultiplier.toFixed(1)); // Update health text color based on health percentage var healthPercent = player.health / player.maxHealth; if (healthPercent > 0.6) { healthText.tint = 0x4CAF50; } else if (healthPercent > 0.3) { healthText.tint = 0xFF9800; } else { healthText.tint = 0xF44336; } // Update combo text color if (player.comboMultiplier > 2) { comboText.tint = 0xFF4444; } else if (player.comboMultiplier > 1.5) { comboText.tint = 0xFFAA00; } else { comboText.tint = 0xFFEB3B; } };
===================================================================
--- original.js
+++ change.js
@@ -283,10 +283,10 @@
} else {
self.comboMultiplier = 1;
self.comboCount = 0;
}
- // Manual firing - fire continuously in aim direction when enemies are present
- if (self.fireCooldown <= 0 && enemies.length > 0) {
+ // Manual firing - fire continuously in aim direction
+ if (self.fireCooldown <= 0) {
self.fireAt(null); // Fire in aim direction, no target needed
self.fireCooldown = self.fireRate;
}
// Keep player within arena bounds
An arow white. In-Game asset. 2d. High contrast. No shadows
Post apocalyptic man pixel art less pixel. In-Game asset. 2d. High contrast. No shadows. Pixel art
Kamp ateşi ve etrafındaki taşlar daha küçük olsun ve harita daha büyük olsun(daha da yukarıdan bakıyormuş gibi)
Post apocalyptic zombie pixel art less pixel. In-Game asset. 2d. High contrast. No shadows
Post Apocalyptic boss zombie pixel art less pixel. In-Game asset. 2d. High contrast. No shadows
Pixel art shotgun less pixel. In-Game asset. 2d. High contrast. No shadows. Pixel art
Particles are scattered around scattered particles pixel art less pixel. In-Game asset. 2d. High contrast. No shadows
Pistol post apocalyptic world pixel art less pixel. In-Game asset. 2d. High contrast. No shadows