User prompt
Battle music should loop
User prompt
All power ups that Drops from zombies should give health
User prompt
And dont make it only edges make it full screen efect and when efect comes a text should come that says(You Need To Heal Up!!) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
İf player health is above from the 60 again the edge effect goes slightly ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The power up should up to health 10
User prompt
The edges lookşng very Far apart, ends should touch each other ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Not the main of the screen bro the edgeds should be in the effect ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
And make it a bit more red or black (Crimson) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the healt is lower than 60 the screen sides go A little bit of red like the players eye is It was filling with blood ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
No make it %24
User prompt
No make them %29
User prompt
And lower the chance of dropping poverups to the default enemys
User prompt
Elite enemys shouldnt drop a poverup
User prompt
You playing the wrong sound it playing (greeting sound) it should play(health greeting) okay?
User prompt
İts playing when the game starts bro its not a greeting its a character sfx that our warrior meaninf characters healts is low
User prompt
And When our character's health drops below 65, he should leave a blood Trace behind him while walking. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the characters health is above 65 the character should say somthing so add a asset and the asset will play when our character health is above 65
User prompt
Ok nevermind the pistol shouldnt turn to enemy
User prompt
Are you deadass you make it the opposite and i am telling to you that exact opposite of the pistol asset should turn to where we firing to
User prompt
Noo the other Side of pistol Should turn
User prompt
It is a little wrong because the tip of the gun does not point to the opponent, so the left side of the gun should turn in the direction it is shooting, that is, the left side of the weapon should turn to where it is fired.
User prompt
When player using the def. Weapon the pistol asset should be in the right of the player
User prompt
İki silah türü de oyuncunun biraz daha sağında dursun
User prompt
Karakter elinde bir silah olsun shotgun aldığında elinde shotgun olsun ve karakter nerye sıkıyorsa oraya yönlensin shotgun
User prompt
Pover ups doesnt have any color they should be always classic color
/**** * 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 = 0.8; 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; } } } } ; 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; } } // Track previous position for direction detection var prevX = self.x; self.x += moveX; self.y += moveY; // Flip boss asset based on movement direction var deltaX = self.x - prevX; if (Math.abs(deltaX) > 0.1) { // Only flip if there's significant horizontal movement if (deltaX > 0) { // Moving right - show normal version self.children[0].scaleX = Math.abs(self.children[0].scaleX); } else { // Moving left - show mirrored (flipped) version self.children[0].scaleX = -Math.abs(self.children[0].scaleX); } } } // 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.isDead = false; self.magazine = 7; self.maxMagazine = 7; self.reloadTime = 72; // 1.2 seconds at 60fps self.isReloading = false; self.weaponType = 'basic'; // Track current weapon type self.hasShotgun = false; self.update = function () { // Stop all actions if character is dead if (self.isDead) { return; } if (self.fireCooldown > 0) { self.fireCooldown--; } if (self.comboTimer > 0) { self.comboTimer--; } else { self.comboMultiplier = 1; self.comboCount = 0; } // Handle reloading if (self.isReloading) { self.reloadTime--; if (self.reloadTime <= 0) { if (self.weaponType === 'shotgun') { self.magazine = 5; self.maxMagazine = 5; self.reloadTime = 90; // Reset reload time for shotgun } else { self.magazine = self.maxMagazine; self.reloadTime = 72; // Reset reload time } self.isReloading = false; } } // Auto-fire at nearest enemy with weapon-specific bullets if (self.fireCooldown <= 0 && enemies.length > 0 && !self.isReloading) { var nearestEnemy = self.findNearestEnemy(); if (nearestEnemy && self.magazine > 0) { if (self.weaponType === 'shotgun') { // Fire shotgun pellets in cone pattern var dx = nearestEnemy.x - self.x; var dy = nearestEnemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var baseAngle = Math.atan2(dy, dx); // Fire 5 pellets in cone for (var p = 0; p < 5; p++) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; // Spread pellets in 30-degree cone var angleOffset = (p - 2) * (Math.PI / 12); // 15 degrees each side var pelletAngle = baseAngle + angleOffset; bullet.velocityX = Math.cos(pelletAngle) * 15; bullet.velocityY = Math.sin(pelletAngle) * 15; bullet.damage = Math.floor(50 * 0.75); // 75% of basic enemy health (50) bullets.push(bullet); game.addChild(bullet); } } else { // Create simple bullet var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var dx = nearestEnemy.x - self.x; var dy = nearestEnemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); bullet.velocityX = dx / distance * 15; bullet.velocityY = dy / distance * 15; bullet.damage = 25; // Basic damage bullets.push(bullet); game.addChild(bullet); } LK.getSound('shoot').play(); self.fireCooldown = self.fireRate; self.magazine--; // Start reloading if magazine is empty if (self.magazine <= 0) { self.isReloading = true; if (self.weaponType === 'shotgun') { self.reloadTime = 90; // 1.5 seconds at 60fps } else { self.reloadTime = 72; // 1.2 seconds at 60fps } } } } // 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; }; self.findNearestEnemy = function () { var nearest = null; var nearestDistance = Infinity; var maxRange = self.weaponType === 'shotgun' ? 550 : Infinity; // Shotgun has limited range for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance && distance <= maxRange) { nearestDistance = distance; nearest = enemy; } } return nearest; }; self.fireAt = function (target) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var dx = target.x - self.x; var dy = target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); bullet.velocityX = dx / distance * 15; bullet.velocityY = dy / distance * 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; self.die(); } 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); } }; self.die = function () { self.isDead = true; self.alpha = 0.5; // Make character semi-transparent createExplosion(self.x, self.y, 120); LK.getSound('explosion').play(); LK.showGameOver(); }; self.switchToShotgun = function () { self.weaponType = 'shotgun'; self.hasShotgun = true; self.magazine = 5; self.maxMagazine = 5; self.reloadTime = 90; // 1.5 seconds at 60fps self.isReloading = false; }; 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 = 1.5; 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; } } // Track previous position for direction detection var prevX = self.x; self.x += moveX; self.y += moveY; // Flip elite enemy asset based on movement direction var deltaX = self.x - prevX; if (Math.abs(deltaX) > 0.1) { // Only flip if there's significant horizontal movement if (deltaX > 0) { // Moving right - show normal version self.children[0].scaleX = Math.abs(self.children[0].scaleX); } else { // Moving left - show mirrored (flipped) version self.children[0].scaleX = -Math.abs(self.children[0].scaleX); } } } // 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 = 1; 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; } } // Track previous position for direction detection var prevX = self.x; self.x += moveX; self.y += moveY; // Flip enemy asset based on movement direction var deltaX = self.x - prevX; if (Math.abs(deltaX) > 0.1) { // Only flip if there's significant horizontal movement if (deltaX > 0) { // Moving right - show normal version self.children[0].scaleX = Math.abs(self.children[0].scaleX); } else { // Moving left - show mirrored (flipped) version self.children[0].scaleX = -Math.abs(self.children[0].scaleX); } } } // 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 // Keep power-ups in classic color (no tinting) 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); player.health = Math.min(player.health + 10, 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; }); var ShotgunPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('shotgunPowerup', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 900; // 15 seconds at 60fps self.bobTimer = 0; self.initialY = 0; self.update = function () { self.lifetime--; self.bobTimer++; // Bobbing animation if (self.initialY === 0) self.initialY = self.y; self.y = self.initialY + Math.sin(self.bobTimer * 0.1) * 10; // Fade out near end of lifetime if (self.lifetime < 180) { powerupGraphics.alpha = self.lifetime / 180; } // Remove if expired if (self.lifetime <= 0) { self.destroy(); for (var i = 0; i < shotgunPowerups.length; i++) { if (shotgunPowerups[i] === self) { shotgunPowerups.splice(i, 1); break; } } return; } // Check collision with player if (self.intersects(player)) { player.switchToShotgun(); LK.getSound('powerupCollect').play(); self.destroy(); for (var j = 0; j < shotgunPowerups.length; j++) { if (shotgunPowerups[j] === self) { shotgunPowerups.splice(j, 1); 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 shotgunPowerups = []; 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 = 1600; // 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: 0xFFFFFF }); 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; var magazineText = new Text2('7/7', { size: 80, fill: 0xFFFFFF, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); magazineText.anchor.set(0.5, 1); magazineText.x = player.x; magazineText.y = player.y - 120; game.addChild(magazineText); // 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 = 1200; 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(); LK.getSound('characterGreeting').play(); } }); }, 2000); // Touch controls var isDragging = false; var dragOffsetX = 0; var dragOffsetY = 0; var gameStarted = false; // Player speed limiting var maxPlayerSpeed = 10; var targetX = 0; var targetY = 0; 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) { // Set target position instead of direct movement targetX = x + dragOffsetX; targetY = 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; } // Apply speed-limited movement to player if (isDragging) { var dx = targetX - player.x; var dy = targetY - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { var moveX = dx / distance * maxPlayerSpeed; var moveY = dy / distance * maxPlayerSpeed; // Track previous position for direction detection var prevX = player.x; // Don't overshoot the target if (distance < maxPlayerSpeed) { player.x = targetX; player.y = targetY; } else { player.x += moveX; player.y += moveY; } // Flip warrior asset based on movement direction var deltaX = player.x - prevX; if (Math.abs(deltaX) > 0.1) { // Only flip if there's significant horizontal movement if (deltaX > 0) { // Moving right - show normal version player.children[0].scaleX = Math.abs(player.children[0].scaleX); } else { // Moving left - show mirrored (flipped) version player.children[0].scaleX = -Math.abs(player.children[0].scaleX); } } } } 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; } // Spawn shotgun powerup occasionally (every 20 seconds if none exist) if (gameTime % 1200 === 0 && shotgunPowerups.length === 0 && !player.hasShotgun) { var shotgunPowerup = new ShotgunPowerup(); // Spawn in random location within arena 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; shotgunPowerup.x = arenaLeft + Math.random() * (arenaRight - arenaLeft); shotgunPowerup.y = arenaTop + Math.random() * (arenaBottom - arenaTop); shotgunPowerups.push(shotgunPowerup); game.addChild(shotgunPowerup); } // 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 magazine UI if (player.isReloading) { magazineText.setText('RELOADING...'); magazineText.tint = 0xFF4444; } else { magazineText.setText(player.magazine + '/' + player.maxMagazine); if (player.weaponType === 'shotgun') { // Shotgun has orange/yellow color scheme if (player.magazine <= 1) { magazineText.tint = 0xFF4444; } else if (player.magazine <= 2) { magazineText.tint = 0xFFAA00; } else { magazineText.tint = 0xFFA500; // Orange for shotgun } } else { // Default weapon color scheme if (player.magazine <= 2) { magazineText.tint = 0xFF4444; } else if (player.magazine <= 4) { magazineText.tint = 0xFFAA00; } else { magazineText.tint = 0xFFFFFF; } } } magazineText.x = player.x; magazineText.y = player.y - 120; // Update combo text color if (player.comboMultiplier > 2) { comboText.tint = 0xFF4444; } else if (player.comboMultiplier > 1.5) { comboText.tint = 0xFFAA00; } else { comboText.tint = 0xFFEB3B; } };
/****
* 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 = 0.8;
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;
}
}
}
}
;
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;
}
}
// Track previous position for direction detection
var prevX = self.x;
self.x += moveX;
self.y += moveY;
// Flip boss asset based on movement direction
var deltaX = self.x - prevX;
if (Math.abs(deltaX) > 0.1) {
// Only flip if there's significant horizontal movement
if (deltaX > 0) {
// Moving right - show normal version
self.children[0].scaleX = Math.abs(self.children[0].scaleX);
} else {
// Moving left - show mirrored (flipped) version
self.children[0].scaleX = -Math.abs(self.children[0].scaleX);
}
}
}
// 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.isDead = false;
self.magazine = 7;
self.maxMagazine = 7;
self.reloadTime = 72; // 1.2 seconds at 60fps
self.isReloading = false;
self.weaponType = 'basic'; // Track current weapon type
self.hasShotgun = false;
self.update = function () {
// Stop all actions if character is dead
if (self.isDead) {
return;
}
if (self.fireCooldown > 0) {
self.fireCooldown--;
}
if (self.comboTimer > 0) {
self.comboTimer--;
} else {
self.comboMultiplier = 1;
self.comboCount = 0;
}
// Handle reloading
if (self.isReloading) {
self.reloadTime--;
if (self.reloadTime <= 0) {
if (self.weaponType === 'shotgun') {
self.magazine = 5;
self.maxMagazine = 5;
self.reloadTime = 90; // Reset reload time for shotgun
} else {
self.magazine = self.maxMagazine;
self.reloadTime = 72; // Reset reload time
}
self.isReloading = false;
}
}
// Auto-fire at nearest enemy with weapon-specific bullets
if (self.fireCooldown <= 0 && enemies.length > 0 && !self.isReloading) {
var nearestEnemy = self.findNearestEnemy();
if (nearestEnemy && self.magazine > 0) {
if (self.weaponType === 'shotgun') {
// Fire shotgun pellets in cone pattern
var dx = nearestEnemy.x - self.x;
var dy = nearestEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var baseAngle = Math.atan2(dy, dx);
// Fire 5 pellets in cone
for (var p = 0; p < 5; p++) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
// Spread pellets in 30-degree cone
var angleOffset = (p - 2) * (Math.PI / 12); // 15 degrees each side
var pelletAngle = baseAngle + angleOffset;
bullet.velocityX = Math.cos(pelletAngle) * 15;
bullet.velocityY = Math.sin(pelletAngle) * 15;
bullet.damage = Math.floor(50 * 0.75); // 75% of basic enemy health (50)
bullets.push(bullet);
game.addChild(bullet);
}
} else {
// Create simple bullet
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = nearestEnemy.x - self.x;
var dy = nearestEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * 15;
bullet.velocityY = dy / distance * 15;
bullet.damage = 25; // Basic damage
bullets.push(bullet);
game.addChild(bullet);
}
LK.getSound('shoot').play();
self.fireCooldown = self.fireRate;
self.magazine--;
// Start reloading if magazine is empty
if (self.magazine <= 0) {
self.isReloading = true;
if (self.weaponType === 'shotgun') {
self.reloadTime = 90; // 1.5 seconds at 60fps
} else {
self.reloadTime = 72; // 1.2 seconds at 60fps
}
}
}
}
// 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;
};
self.findNearestEnemy = function () {
var nearest = null;
var nearestDistance = Infinity;
var maxRange = self.weaponType === 'shotgun' ? 550 : Infinity; // Shotgun has limited range
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance && distance <= maxRange) {
nearestDistance = distance;
nearest = enemy;
}
}
return nearest;
};
self.fireAt = function (target) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = target.x - self.x;
var dy = target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * 15;
bullet.velocityY = dy / distance * 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;
self.die();
}
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);
}
};
self.die = function () {
self.isDead = true;
self.alpha = 0.5; // Make character semi-transparent
createExplosion(self.x, self.y, 120);
LK.getSound('explosion').play();
LK.showGameOver();
};
self.switchToShotgun = function () {
self.weaponType = 'shotgun';
self.hasShotgun = true;
self.magazine = 5;
self.maxMagazine = 5;
self.reloadTime = 90; // 1.5 seconds at 60fps
self.isReloading = false;
};
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 = 1.5;
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;
}
}
// Track previous position for direction detection
var prevX = self.x;
self.x += moveX;
self.y += moveY;
// Flip elite enemy asset based on movement direction
var deltaX = self.x - prevX;
if (Math.abs(deltaX) > 0.1) {
// Only flip if there's significant horizontal movement
if (deltaX > 0) {
// Moving right - show normal version
self.children[0].scaleX = Math.abs(self.children[0].scaleX);
} else {
// Moving left - show mirrored (flipped) version
self.children[0].scaleX = -Math.abs(self.children[0].scaleX);
}
}
}
// 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 = 1;
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;
}
}
// Track previous position for direction detection
var prevX = self.x;
self.x += moveX;
self.y += moveY;
// Flip enemy asset based on movement direction
var deltaX = self.x - prevX;
if (Math.abs(deltaX) > 0.1) {
// Only flip if there's significant horizontal movement
if (deltaX > 0) {
// Moving right - show normal version
self.children[0].scaleX = Math.abs(self.children[0].scaleX);
} else {
// Moving left - show mirrored (flipped) version
self.children[0].scaleX = -Math.abs(self.children[0].scaleX);
}
}
}
// 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
// Keep power-ups in classic color (no tinting)
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);
player.health = Math.min(player.health + 10, 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;
});
var ShotgunPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('shotgunPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifetime = 900; // 15 seconds at 60fps
self.bobTimer = 0;
self.initialY = 0;
self.update = function () {
self.lifetime--;
self.bobTimer++;
// Bobbing animation
if (self.initialY === 0) self.initialY = self.y;
self.y = self.initialY + Math.sin(self.bobTimer * 0.1) * 10;
// Fade out near end of lifetime
if (self.lifetime < 180) {
powerupGraphics.alpha = self.lifetime / 180;
}
// Remove if expired
if (self.lifetime <= 0) {
self.destroy();
for (var i = 0; i < shotgunPowerups.length; i++) {
if (shotgunPowerups[i] === self) {
shotgunPowerups.splice(i, 1);
break;
}
}
return;
}
// Check collision with player
if (self.intersects(player)) {
player.switchToShotgun();
LK.getSound('powerupCollect').play();
self.destroy();
for (var j = 0; j < shotgunPowerups.length; j++) {
if (shotgunPowerups[j] === self) {
shotgunPowerups.splice(j, 1);
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 shotgunPowerups = [];
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 = 1600;
// 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: 0xFFFFFF
});
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;
var magazineText = new Text2('7/7', {
size: 80,
fill: 0xFFFFFF,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
magazineText.anchor.set(0.5, 1);
magazineText.x = player.x;
magazineText.y = player.y - 120;
game.addChild(magazineText);
// 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 = 1200;
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();
LK.getSound('characterGreeting').play();
}
});
}, 2000);
// Touch controls
var isDragging = false;
var dragOffsetX = 0;
var dragOffsetY = 0;
var gameStarted = false;
// Player speed limiting
var maxPlayerSpeed = 10;
var targetX = 0;
var targetY = 0;
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) {
// Set target position instead of direct movement
targetX = x + dragOffsetX;
targetY = 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;
}
// Apply speed-limited movement to player
if (isDragging) {
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * maxPlayerSpeed;
var moveY = dy / distance * maxPlayerSpeed;
// Track previous position for direction detection
var prevX = player.x;
// Don't overshoot the target
if (distance < maxPlayerSpeed) {
player.x = targetX;
player.y = targetY;
} else {
player.x += moveX;
player.y += moveY;
}
// Flip warrior asset based on movement direction
var deltaX = player.x - prevX;
if (Math.abs(deltaX) > 0.1) {
// Only flip if there's significant horizontal movement
if (deltaX > 0) {
// Moving right - show normal version
player.children[0].scaleX = Math.abs(player.children[0].scaleX);
} else {
// Moving left - show mirrored (flipped) version
player.children[0].scaleX = -Math.abs(player.children[0].scaleX);
}
}
}
}
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;
}
// Spawn shotgun powerup occasionally (every 20 seconds if none exist)
if (gameTime % 1200 === 0 && shotgunPowerups.length === 0 && !player.hasShotgun) {
var shotgunPowerup = new ShotgunPowerup();
// Spawn in random location within arena
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;
shotgunPowerup.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
shotgunPowerup.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
shotgunPowerups.push(shotgunPowerup);
game.addChild(shotgunPowerup);
}
// 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 magazine UI
if (player.isReloading) {
magazineText.setText('RELOADING...');
magazineText.tint = 0xFF4444;
} else {
magazineText.setText(player.magazine + '/' + player.maxMagazine);
if (player.weaponType === 'shotgun') {
// Shotgun has orange/yellow color scheme
if (player.magazine <= 1) {
magazineText.tint = 0xFF4444;
} else if (player.magazine <= 2) {
magazineText.tint = 0xFFAA00;
} else {
magazineText.tint = 0xFFA500; // Orange for shotgun
}
} else {
// Default weapon color scheme
if (player.magazine <= 2) {
magazineText.tint = 0xFF4444;
} else if (player.magazine <= 4) {
magazineText.tint = 0xFFAA00;
} else {
magazineText.tint = 0xFFFFFF;
}
}
}
magazineText.x = player.x;
magazineText.y = player.y - 120;
// Update combo text color
if (player.comboMultiplier > 2) {
comboText.tint = 0xFF4444;
} else if (player.comboMultiplier > 1.5) {
comboText.tint = 0xFFAA00;
} else {
comboText.tint = 0xFFEB3B;
}
};
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