User prompt
Faça o chefe 3 vir para baixo e voltar para o topo do cenário como padrão de ataque ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Retire a transparência dos chefes, e quando eles chegarem ao segundo estágio de ataque, faça-os piscar de forma intermitente com efeito fade in e fade out entre tons de amarelo e vermelho ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
no chefe numero 3, ele não deve vir para baixo e tocar o fundo da tela
User prompt
Os inimigos possuem mais vida, tornando os ataques menos eficazes
User prompt
Faça com que cada chefe tenha 2 padrões de ataque, que irão mudar quando o chefe chegar a 50% de energia
User prompt
iniciar o jogo automaticamente após 4 segundos da tela inicial ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Iniciar o jogo quando eu clicar em "start game"
User prompt
Retire o texto "boss battle" da tela inicial
User prompt
Crie uma cena de introdução com uma logo do jogo e um botão "Start Game" ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
adicione uma musica de fundo de batalha épica medieval
User prompt
Transforme a saúde do chefe em uma barra de energia horizontal que fica no campo do background do jogo
User prompt
Coloque o texto de saúde dos personagens e o nome do chefe na própria tela do jogo, com uma fonte estilo pixel art
User prompt
adicione um power up para tiro duplo do personagem principal. O power up vem descendo aleatoriamente e verticalmente da tela ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
remova o asset do player quando ele está parado, ele sempre estará virado pra esquerda ou pra direita
User prompt
Aumente mais um asset do personagem, pois agora ele irá virar para a esquerda e para a direita
Code edit (1 edits merged)
Please save this source code
User prompt
Boss Pattern Battle
Initial prompt
um jogo onde enfrentamos apenas inimigos como se fossem chefes no estilo Megaman ou Rockman X. Ou seja, cada chefe tem um padrão de ataque, e precisamos aprender a sequência para poder atacar nos tempos livres.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Boss = Container.expand(function () { var self = Container.call(this); self.maxHealth = 300; self.health = self.maxHealth; self.patternIndex = 0; self.patternTimer = 0; self.isVulnerable = false; self.vulnerabilityTimer = 0; self.attackPatterns = []; self.attackPatternsPhase2 = []; self.currentPhase = 1; self.lastHealthPercentage = 1.0; self.takeDamage = function (damage) { if (self.isVulnerable) { self.health -= damage; LK.effects.flashObject(self, 0xffffff, 200); LK.getSound('bossHit').play(); if (self.health <= 0) { self.health = 0; self.onDefeat(); } } }; self.onDefeat = function () { LK.getSound('bossDefeat').play(); // Make boss vanish and stop attacking self.visible = false; self.alpha = 0; // Stop player shooting when boss is defeated if (player) { player.canShoot = false; player.health = player.maxHealth; } console.log("Boss defeated. Current index:", currentBossIndex, "Total bosses:", bossConfigs.length); // Check if this is the final boss (Boss4 at index 3) if (currentBossIndex === 3) { console.log("All 4 bosses defeated - showing win screen"); LK.showYouWin(); } else { // Show Next Stage button instead of auto-progressing showNextStageButton(); } }; self.executePattern = function () { // Override in specific boss classes }; self.update = function () { // Stop all attacks and patterns if health is 0 if (self.health <= 0) { return; } self.patternTimer++; if (self.vulnerabilityTimer > 0) { self.vulnerabilityTimer--; if (self.vulnerabilityTimer <= 0) { self.isVulnerable = false; } } // Check for phase transition at 50% health var currentHealthPercentage = self.health / self.maxHealth; if (self.currentPhase === 1 && currentHealthPercentage <= 0.5 && self.lastHealthPercentage > 0.5) { self.currentPhase = 2; self.patternIndex = 0; self.patternTimer = 0; LK.effects.flashObject(self, 0xffffff, 1000); // Start phase 2 flashing effect self.startPhase2Flash(); } self.lastHealthPercentage = currentHealthPercentage; self.executePattern(); }; return self; }); var Boss4 = Boss.expand(function () { var self = Boss.call(this); var bossGraphics = self.attachAsset('boss4', { anchorX: 0.5, anchorY: 0.5, alpha: 1.0 }); self.maxHealth = 600; self.health = self.maxHealth; self.attackPatterns = [{ duration: 120, action: 'ultimate_sweep' }, { duration: 100, action: 'chaos_storm' }, { duration: 150, action: 'teleport_barrage' }, { duration: 120, action: 'gravity_pull' }, { duration: 80, action: 'laser_grid' }, { duration: 90, action: 'vulnerable' }]; self.attackPatternsPhase2 = [{ duration: 80, action: 'apocalypse_sweep' }, { duration: 60, action: 'death_spiral' }, { duration: 100, action: 'final_barrage' }, { duration: 120, action: 'dimensional_rift' }, { duration: 70, action: 'omega_grid' }, { duration: 60, action: 'vulnerable' }]; self.executePattern = function () { var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2; var currentPattern = patterns[self.patternIndex]; if (self.patternTimer >= currentPattern.duration) { self.patternTimer = 0; self.patternIndex = (self.patternIndex + 1) % patterns.length; } switch (currentPattern.action) { case 'ultimate_sweep': if (self.patternTimer % 8 === 0) { self.ultimateSweep(); } break; case 'chaos_storm': if (self.patternTimer % 4 === 0) { self.chaosStorm(); } break; case 'teleport_barrage': if (self.patternTimer % 25 === 0) { self.teleportBarrage(); } break; case 'gravity_pull': if (self.patternTimer === 1) { self.gravityPull(); } break; case 'laser_grid': if (self.patternTimer % 15 === 0) { self.laserGrid(); } break; case 'vulnerable': self.isVulnerable = true; self.vulnerabilityTimer = 90; tween(bossGraphics, { alpha: 0.4 }, { duration: 200 }); break; case 'apocalypse_sweep': if (self.patternTimer % 5 === 0) { self.apocalypseSweep(); } break; case 'death_spiral': if (self.patternTimer % 6 === 0) { self.deathSpiral(); } break; case 'final_barrage': if (self.patternTimer % 3 === 0) { self.finalBarrage(); } break; case 'dimensional_rift': if (self.patternTimer % 20 === 0) { self.dimensionalRift(); } break; case 'omega_grid': if (self.patternTimer % 10 === 0) { self.omegaGrid(); } break; } }; self.ultimateSweep = function () { for (var i = 0; i < 7; i++) { var bullet = new BossBullet(); bullet.x = self.x + (i - 3) * 40; bullet.y = self.y + 50; bullet.direction = { x: (i - 3) * 0.2, y: 1 }; bullet.speed = 7; bossBullets.push(bullet); game.addChild(bullet); } }; self.chaosStorm = function () { for (var i = 0; i < 4; i++) { var bullet = new BossBullet(); bullet.x = self.x + (Math.random() - 0.5) * 400; bullet.y = self.y + 50; bullet.direction = { x: (Math.random() - 0.5) * 4, y: 0.8 + Math.random() * 0.4 }; bullet.speed = 6 + Math.random() * 3; bossBullets.push(bullet); game.addChild(bullet); } }; self.teleportBarrage = function () { var teleportPositions = [{ x: arenaLeft + 200, y: arenaTop + 250 }, { x: arenaRight - 200, y: arenaTop + 250 }, { x: 1024, y: arenaTop + 150 }, { x: arenaLeft + 300, y: arenaTop + 400 }, { x: arenaRight - 300, y: arenaTop + 400 }]; var randomPos = teleportPositions[Math.floor(Math.random() * teleportPositions.length)]; tween(self, { x: randomPos.x, y: randomPos.y }, { duration: 200 }); // Massive bullet spread after teleport LK.setTimeout(function () { for (var i = 0; i < 12; i++) { var angle = i / 12 * Math.PI * 2; var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; bullet.direction = { x: Math.cos(angle), y: Math.sin(angle) }; bullet.speed = 5; bossBullets.push(bullet); game.addChild(bullet); } }, 300); }; self.gravityPull = function () { // Pull effect - move towards player position over time var targetX = Math.max(arenaLeft + 200, Math.min(arenaRight - 200, player.x)); var targetY = Math.max(arenaTop + 200, Math.min(arenaBottom - 300, player.y - 150)); tween(self, { x: targetX, y: targetY }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Explosion of bullets in all directions for (var i = 0; i < 16; i++) { var angle = i / 16 * Math.PI * 2; var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; bullet.direction = { x: Math.cos(angle), y: Math.sin(angle) }; bullet.speed = 6; bossBullets.push(bullet); game.addChild(bullet); } } }); }; self.laserGrid = function () { // Create grid pattern of bullets for (var row = 0; row < 3; row++) { for (var col = 0; col < 5; col++) { var bullet = new BossBullet(); bullet.x = arenaLeft + 200 + col * 300; bullet.y = self.y + row * 80; bullet.direction = { x: 0, y: 1 }; bullet.speed = 4 + row; bossBullets.push(bullet); game.addChild(bullet); } } }; self.apocalypseSweep = function () { // Even more intense sweep for phase 2 for (var i = 0; i < 9; i++) { var bullet = new BossBullet(); bullet.x = self.x + (i - 4) * 35; bullet.y = self.y + 50; bullet.direction = { x: (i - 4) * 0.25, y: 1 }; bullet.speed = 8; bossBullets.push(bullet); game.addChild(bullet); } }; self.deathSpiral = function () { // Rotating spiral pattern var spiralCount = 6; for (var i = 0; i < spiralCount; i++) { var angle = (self.patternTimer * 0.3 + i * Math.PI * 2 / spiralCount) % (Math.PI * 2); var bullet = new BossBullet(); bullet.x = self.x + Math.cos(angle) * 100; bullet.y = self.y + Math.sin(angle) * 50 + 50; bullet.direction = { x: Math.cos(angle + Math.PI / 4) * 0.8, y: Math.sin(angle + Math.PI / 4) * 0.8 + 0.6 }; bullet.speed = 7; bossBullets.push(bullet); game.addChild(bullet); } }; self.finalBarrage = function () { // Overwhelming bullet hell for (var i = 0; i < 6; i++) { var bullet = new BossBullet(); bullet.x = self.x + (Math.random() - 0.5) * 500; bullet.y = self.y + Math.random() * 100; var angleToPlayer = Math.atan2(player.y - bullet.y, player.x - bullet.x); bullet.direction = { x: Math.cos(angleToPlayer + (Math.random() - 0.5) * 0.8), y: Math.sin(angleToPlayer + (Math.random() - 0.5) * 0.8) }; bullet.speed = 5 + Math.random() * 4; bossBullets.push(bullet); game.addChild(bullet); } }; self.dimensionalRift = function () { // Teleport to multiple positions rapidly var positions = [{ x: arenaLeft + 150, y: arenaTop + 200 }, { x: arenaRight - 150, y: arenaTop + 200 }, { x: 1024, y: arenaTop + 350 }, { x: arenaLeft + 300, y: arenaTop + 500 }, { x: arenaRight - 300, y: arenaTop + 500 }]; for (var p = 0; p < 3; p++) { var pos = positions[Math.floor(Math.random() * positions.length)]; LK.setTimeout(function () { tween(self, { x: pos.x, y: pos.y }, { duration: 150 }); // Shoot bullets from each position for (var j = 0; j < 8; j++) { var angle = j / 8 * Math.PI * 2; var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; bullet.direction = { x: Math.cos(angle), y: Math.sin(angle) }; bullet.speed = 6; bossBullets.push(bullet); game.addChild(bullet); } }, p * 200); } }; self.omegaGrid = function () { // Ultimate grid attack for (var row = 0; row < 4; row++) { for (var col = 0; col < 7; col++) { var bullet = new BossBullet(); bullet.x = arenaLeft + 150 + col * 250; bullet.y = self.y + row * 60; bullet.direction = { x: (col - 3) * 0.1, y: 1 }; bullet.speed = 5 + row; bossBullets.push(bullet); game.addChild(bullet); } } }; self.startPhase2Flash = function () { var flashToGold = function flashToGold() { tween(bossGraphics, { tint: 0xFFD700 }, { duration: 600, easing: tween.easeInOut, onFinish: flashToWhite }); }; var flashToWhite = function flashToWhite() { tween(bossGraphics, { tint: 0xFFFFFF }, { duration: 600, easing: tween.easeInOut, onFinish: flashToGold }); }; flashToGold(); }; return self; }); var Boss3 = Boss.expand(function () { var self = Boss.call(this); var bossGraphics = self.attachAsset('boss3', { anchorX: 0.5, anchorY: 0.5, alpha: 1.0 }); self.maxHealth = 250; self.health = self.maxHealth; self.attackPatterns = [{ duration: 60, action: 'laser_sweep' }, { duration: 50, action: 'bullet_hell' }, { duration: 80, action: 'dash_attack' }, { duration: 100, action: 'dive_attack' }, { duration: 70, action: 'horizontal_sweep' }, { duration: 80, action: 'diagonal_attack' }, { duration: 80, action: 'vulnerable' }]; self.attackPatternsPhase2 = [{ duration: 50, action: 'mega_laser_sweep' }, { duration: 40, action: 'chaos_bullets' }, { duration: 70, action: 'triple_dash' }, { duration: 80, action: 'power_dive' }, { duration: 50, action: 'spiral_sweep' }, { duration: 60, action: 'diagonal_barrage' }, { duration: 60, action: 'vulnerable' }]; self.executePattern = function () { var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2; var currentPattern = patterns[self.patternIndex]; if (self.patternTimer >= currentPattern.duration) { self.patternTimer = 0; self.patternIndex = (self.patternIndex + 1) % patterns.length; } switch (currentPattern.action) { case 'laser_sweep': if (self.patternTimer % 15 === 0) { self.shootLaser(); } break; case 'bullet_hell': if (self.patternTimer % 8 === 0) { self.shootRandomBullets(); } break; case 'dash_attack': if (self.patternTimer === 1) { var targetY = Math.min(player.y, arenaBottom - 150); tween(self, { y: targetY }, { duration: 500 }); } break; case 'dive_attack': if (self.patternTimer === 1) { self.diveAttack(); } break; case 'vulnerable': self.isVulnerable = true; self.vulnerabilityTimer = 60; tween(bossGraphics, { alpha: 0.5 }, { duration: 200 }); break; case 'mega_laser_sweep': if (self.patternTimer % 10 === 0) { self.shootMegaLaser(); } break; case 'chaos_bullets': if (self.patternTimer % 6 === 0) { self.shootChaosBullets(); } break; case 'triple_dash': if (self.patternTimer % 30 === 0) { self.tripleDash(); } break; case 'power_dive': if (self.patternTimer === 1) { self.powerDive(); } break; case 'horizontal_sweep': if (self.patternTimer % 20 === 0) { self.horizontalSweep(); } break; case 'diagonal_attack': if (self.patternTimer % 15 === 0) { self.diagonalAttack(); } break; case 'spiral_sweep': if (self.patternTimer % 12 === 0) { self.spiralSweep(); } break; case 'diagonal_barrage': if (self.patternTimer % 8 === 0) { self.diagonalBarrage(); } break; } }; self.shootLaser = function () { for (var i = 0; i < 3; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 50 + i * 20; bullet.direction = { x: 0, y: 1 }; bullet.speed = 6; bossBullets.push(bullet); game.addChild(bullet); } }; self.shootRandomBullets = function () { var bullet = new BossBullet(); bullet.x = self.x + (Math.random() - 0.5) * 200; bullet.y = self.y + 50; bullet.direction = { x: (Math.random() - 0.5) * 2, y: 1 }; bossBullets.push(bullet); game.addChild(bullet); }; self.shootMegaLaser = function () { for (var i = 0; i < 5; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 50 + i * 15; bullet.direction = { x: 0, y: 1 }; bullet.speed = 8; bossBullets.push(bullet); game.addChild(bullet); } }; self.shootChaosBullets = function () { for (var i = 0; i < 3; i++) { var bullet = new BossBullet(); bullet.x = self.x + (Math.random() - 0.5) * 300; bullet.y = self.y + 50; bullet.direction = { x: (Math.random() - 0.5) * 3, y: 1 }; bullet.speed = 7; bossBullets.push(bullet); game.addChild(bullet); } }; self.tripleDash = function () { var dashTargets = [player.y - 100, player.y, player.y + 100]; for (var j = 0; j < dashTargets.length; j++) { dashTargets[j] = Math.min(dashTargets[j], arenaBottom - 150); } for (var i = 0; i < dashTargets.length; i++) { tween(self, { y: dashTargets[i] }, { duration: 200, delay: i * 100 }); } }; self.diveAttack = function () { tween(self, { y: arenaBottom - 100 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { LK.setTimeout(function () { tween(self, { y: arenaTop + 200 }, { duration: 600, easing: tween.easeOut }); }, 300); } }); }; self.powerDive = function () { tween(self, { y: arenaBottom - 80 }, { duration: 600, easing: tween.easeIn, onFinish: function onFinish() { for (var i = 0; i < 5; i++) { var bullet = new BossBullet(); bullet.x = self.x + (i - 2) * 40; bullet.y = self.y; bullet.direction = { x: (i - 2) * 0.3, y: -1 }; bullet.speed = 5; bossBullets.push(bullet); game.addChild(bullet); } LK.setTimeout(function () { tween(self, { y: arenaTop + 200 }, { duration: 400, easing: tween.easeOut }); }, 200); } }); }; self.horizontalSweep = function () { var targetX = self.x < 1024 ? arenaRight - 200 : arenaLeft + 200; tween(self, { x: targetX }, { duration: 1000, easing: tween.easeInOut }); for (var i = 0; i < 2; i++) { var bullet = new BossBullet(); bullet.x = self.x + (i - 0.5) * 60; bullet.y = self.y + 50; bullet.direction = { x: 0, y: 1 }; bullet.speed = 5; bossBullets.push(bullet); game.addChild(bullet); } }; self.diagonalAttack = function () { var targetX = self.x < 1024 ? arenaRight - 150 : arenaLeft + 150; var targetY = Math.min(self.y + 100, arenaBottom - 200); tween(self, { x: targetX, y: targetY }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: 1024, y: arenaTop + 200 }, { duration: 600, easing: tween.easeOut }); } }); for (var i = 0; i < 3; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 40; bullet.direction = { x: (i - 1) * 0.5, y: 1 }; bullet.speed = 6; bossBullets.push(bullet); game.addChild(bullet); } }; self.spiralSweep = function () { var targetX = self.x < 1024 ? arenaRight - 150 : arenaLeft + 150; tween(self, { x: targetX }, { duration: 600, easing: tween.easeInOut }); for (var i = 0; i < 4; i++) { var angle = (self.patternTimer * 0.2 + i * Math.PI / 2) % (Math.PI * 2); var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 50; bullet.direction = { x: Math.cos(angle) * 0.8, y: Math.sin(angle) * 0.8 + 0.5 }; bullet.speed = 6; bossBullets.push(bullet); game.addChild(bullet); } }; self.diagonalBarrage = function () { var targets = [{ x: arenaLeft + 200, y: arenaTop + 300 }, { x: arenaRight - 200, y: arenaTop + 300 }, { x: 1024, y: arenaTop + 150 }]; var targetIndex = Math.floor(self.patternTimer / 30) % targets.length; var target = targets[targetIndex]; tween(self, { x: target.x, y: target.y }, { duration: 400, easing: tween.easeInOut }); for (var i = 0; i < 5; i++) { var bullet = new BossBullet(); bullet.x = self.x + (i - 2) * 30; bullet.y = self.y + 50; var angleToPlayer = Math.atan2(player.y - bullet.y, player.x - bullet.x); bullet.direction = { x: Math.cos(angleToPlayer + (i - 2) * 0.3), y: Math.sin(angleToPlayer + (i - 2) * 0.3) }; bullet.speed = 7; bossBullets.push(bullet); game.addChild(bullet); } }; self.startPhase2Flash = function () { var flashToYellow = function flashToYellow() { tween(bossGraphics, { tint: 0xFFFF00 }, { duration: 800, easing: tween.easeInOut, onFinish: flashToRed }); }; var flashToRed = function flashToRed() { tween(bossGraphics, { tint: 0xFF0000 }, { duration: 800, easing: tween.easeInOut, onFinish: flashToYellow }); }; flashToYellow(); }; return self; }); var Boss2 = Boss.expand(function () { var self = Boss.call(this); var bossGraphics = self.attachAsset('boss2', { anchorX: 0.5, anchorY: 0.5, alpha: 1.0 }); self.maxHealth = 400; self.health = self.maxHealth; self.attackPatterns = [{ duration: 90, action: 'circle_pattern' }, { duration: 60, action: 'rapid_fire' }, { duration: 120, action: 'teleport' }, { duration: 80, action: 'vulnerable' }]; self.attackPatternsPhase2 = [{ duration: 70, action: 'double_circle' }, { duration: 45, action: 'homing_barrage' }, { duration: 90, action: 'shadow_teleport' }, { duration: 60, action: 'vulnerable' }]; self.executePattern = function () { var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2; var currentPattern = patterns[self.patternIndex]; if (self.patternTimer >= currentPattern.duration) { self.patternTimer = 0; self.patternIndex = (self.patternIndex + 1) % patterns.length; } switch (currentPattern.action) { case 'circle_pattern': if (self.patternTimer % 15 === 0) { self.shootCircle(); } break; case 'rapid_fire': if (self.patternTimer % 8 === 0) { self.shootAtPlayer(); } break; case 'teleport': if (self.patternTimer === 1) { var newX = arenaLeft + 200 + Math.random() * (arenaRight - arenaLeft - 400); tween(self, { x: newX }, { duration: 300 }); } break; case 'vulnerable': self.isVulnerable = true; self.vulnerabilityTimer = 80; tween(bossGraphics, { alpha: 0.6 }, { duration: 200 }); break; case 'double_circle': if (self.patternTimer % 12 === 0) { self.shootDoubleCircle(); } break; case 'homing_barrage': if (self.patternTimer % 6 === 0) { self.shootHomingBarrage(); } break; case 'shadow_teleport': if (self.patternTimer % 20 === 0) { self.shadowTeleport(); } break; } }; self.shootCircle = function () { for (var i = 0; i < 8; i++) { var angle = i / 8 * Math.PI * 2; var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; bullet.direction = { x: Math.cos(angle), y: Math.sin(angle) }; bossBullets.push(bullet); game.addChild(bullet); } }; self.shootAtPlayer = function () { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 50; var dx = player.x - self.x; var dy = player.y - self.y; var length = Math.sqrt(dx * dx + dy * dy); bullet.direction = { x: dx / length, y: dy / length }; bossBullets.push(bullet); game.addChild(bullet); }; self.shootDoubleCircle = function () { for (var ring = 0; ring < 2; ring++) { for (var i = 0; i < 6; i++) { var angle = i / 6 * Math.PI * 2 + ring * Math.PI / 6; var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; bullet.direction = { x: Math.cos(angle), y: Math.sin(angle) }; bullet.speed = 4 + ring * 2; bossBullets.push(bullet); game.addChild(bullet); } } }; self.shootHomingBarrage = function () { for (var i = 0; i < 2; i++) { var bullet = new BossBullet(); bullet.x = self.x + (i - 0.5) * 40; bullet.y = self.y + 50; var dx = player.x - bullet.x; var dy = player.y - bullet.y; var length = Math.sqrt(dx * dx + dy * dy); bullet.direction = { x: dx / length, y: dy / length }; bullet.speed = 6; bossBullets.push(bullet); game.addChild(bullet); } }; self.shadowTeleport = function () { var teleportPositions = [{ x: arenaLeft + 150, y: self.y }, { x: arenaRight - 150, y: self.y }, { x: 1024, y: arenaTop + 150 }]; var randomPos = teleportPositions[Math.floor(Math.random() * teleportPositions.length)]; tween(self, { x: randomPos.x, y: randomPos.y }, { duration: 250 }); }; self.startPhase2Flash = function () { var flashToYellow = function flashToYellow() { tween(bossGraphics, { tint: 0xFFFF00 }, { duration: 800, easing: tween.easeInOut, onFinish: flashToRed }); }; var flashToRed = function flashToRed() { tween(bossGraphics, { tint: 0xFF0000 }, { duration: 800, easing: tween.easeInOut, onFinish: flashToYellow }); }; flashToYellow(); }; return self; }); var Boss1 = Boss.expand(function () { var self = Boss.call(this); var bossGraphics = self.attachAsset('boss1', { anchorX: 0.5, anchorY: 0.5, alpha: 1.0 }); self.attackPatterns = [{ duration: 120, action: 'move_left' }, { duration: 60, action: 'shoot_spread' }, { duration: 120, action: 'move_right' }, { duration: 60, action: 'shoot_spread' }, { duration: 90, action: 'vulnerable' }]; self.attackPatternsPhase2 = [{ duration: 80, action: 'speed_dash' }, { duration: 40, action: 'rapid_spread' }, { duration: 80, action: 'speed_dash' }, { duration: 40, action: 'rapid_spread' }, { duration: 70, action: 'vulnerable' }]; self.executePattern = function () { var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2; var currentPattern = patterns[self.patternIndex]; if (self.patternTimer >= currentPattern.duration) { self.patternTimer = 0; self.patternIndex = (self.patternIndex + 1) % patterns.length; } switch (currentPattern.action) { case 'move_left': if (self.x > arenaLeft + 100) { self.x -= 2; } break; case 'move_right': if (self.x < arenaRight - 100) { self.x += 2; } break; case 'shoot_spread': if (self.patternTimer % 20 === 0) { self.shootSpread(); } break; case 'vulnerable': self.isVulnerable = true; self.vulnerabilityTimer = 90; tween(bossGraphics, { alpha: 0.7 }, { duration: 200 }); break; case 'speed_dash': if (self.x > arenaLeft + 100 && self.patternTimer < 40) { self.x -= 4; } else if (self.x < arenaRight - 100 && self.patternTimer >= 40) { self.x += 4; } break; case 'rapid_spread': if (self.patternTimer % 10 === 0) { self.shootRapidSpread(); } break; } }; self.shootSpread = function () { for (var i = -2; i <= 2; i++) { var bullet = new BossBullet(); bullet.x = self.x + i * 30; bullet.y = self.y + 50; bullet.direction = { x: i * 0.3, y: 1 }; bossBullets.push(bullet); game.addChild(bullet); } }; self.shootRapidSpread = function () { for (var i = -3; i <= 3; i++) { var bullet = new BossBullet(); bullet.x = self.x + i * 25; bullet.y = self.y + 50; bullet.direction = { x: i * 0.4, y: 1 }; bullet.speed = 6; bossBullets.push(bullet); game.addChild(bullet); } }; self.startPhase2Flash = function () { var flashToYellow = function flashToYellow() { tween(bossGraphics, { tint: 0xFFFF00 }, { duration: 800, easing: tween.easeInOut, onFinish: flashToRed }); }; var flashToRed = function flashToRed() { tween(bossGraphics, { tint: 0xFF0000 }, { duration: 800, easing: tween.easeInOut, onFinish: flashToYellow }); }; flashToYellow(); }; return self; }); var BossBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bossBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.damage = 15; self.direction = { x: 0, y: 1 }; self.update = function () { self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; }; return self; }); var BossIntroScreen = Container.expand(function () { var self = Container.call(this); self.showIntro = function (bossName, introAssetId) { var introGraphics = self.attachAsset(introAssetId, { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, alpha: 0 }); tween(introGraphics, { alpha: 1 }, { duration: 800, easing: tween.easeInOut }); LK.setTimeout(function () { tween(self, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { self.destroy(); } }); }, 4000); }; return self; }); var DoubleShotPowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('doubleShotPowerUp', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.collected = false; self.update = function () { self.y += self.speed; }; return self; }); var HealthPowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('healthPowerUp', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.collected = false; self.update = function () { self.y += self.speed; }; return self; }); var IntroScreen = Container.expand(function () { var self = Container.call(this); var logoGraphics = self.attachAsset('gameLogo', { anchorX: 0.5, anchorY: 0.5 }); logoGraphics.x = 0; logoGraphics.y = -200; logoGraphics.alpha = 0; tween(logoGraphics, { alpha: 1 }, { duration: 800 }); return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerLeftGraphics = self.attachAsset('playerLeft', { anchorX: 0.5, anchorY: 0.5, visible: true, alpha: 1.0 }); var playerRightGraphics = self.attachAsset('playerRight', { anchorX: 0.5, anchorY: 0.5, visible: true, alpha: 1.0 }); self.maxHealth = 150; self.health = self.maxHealth; self.speed = 8; self.canShoot = false; self.shootCooldown = 0; self.lastX = 0; self.facing = 'left'; self.hasDoubleShot = false; self.doubleShotTimer = 0; self.power = 10; self.updateFacing = function () { var newFacing = self.facing; if (self.x < self.lastX - 5) { newFacing = 'left'; } else if (self.x > self.lastX + 5) { newFacing = 'right'; } if (newFacing !== self.facing) { self.facing = newFacing; playerLeftGraphics.visible = newFacing === 'left'; playerRightGraphics.visible = newFacing === 'right'; } self.lastX = self.x; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; LK.showGameOver(); } LK.effects.flashObject(self, 0xff0000, 500); LK.getSound('playerHit').play(); }; self.shoot = function () { if (self.canShoot && self.shootCooldown <= 0) { if (self.hasDoubleShot) { var bullet1 = new PlayerBullet(); bullet1.x = self.x - 20; bullet1.y = self.y - 50; bullet1.damage = self.power; playerBullets.push(bullet1); game.addChild(bullet1); var bullet2 = new PlayerBullet(); bullet2.x = self.x + 20; bullet2.y = self.y - 50; bullet2.damage = self.power; playerBullets.push(bullet2); game.addChild(bullet2); } else { var bullet = new PlayerBullet(); bullet.x = self.x; bullet.y = self.y - 50; bullet.damage = self.power; playerBullets.push(bullet); game.addChild(bullet); } // Keep constant power for all shots self.shootCooldown = 9; LK.getSound('playerShoot').play(); } }; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } if (self.doubleShotTimer > 0) { self.doubleShotTimer--; if (self.doubleShotTimer <= 0) { self.hasDoubleShot = false; } } // Auto-shoot very fast - every 3 frames instead of every frame if (LK.ticks % 3 === 0) { self.shoot(); } self.updateFacing(); }; self.collectDoubleShotPowerUp = function () { self.hasDoubleShot = true; self.doubleShotTimer = 600; LK.effects.flashObject(self, 0x00ff00, 300); }; self.collectHealthPowerUp = function () { var recoveryAmount = Math.ceil(self.maxHealth * 0.2); if (self.health >= self.maxHealth) { self.maxHealth += recoveryAmount; self.health = self.maxHealth; } else { self.health = Math.min(self.maxHealth, self.health + recoveryAmount); } LK.effects.flashObject(self, 0x00ff00, 500); }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -12; self.damage = 10; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ var gameStarted = false; var introScreen = null; var arena = game.attachAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, visible: false }); 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; var player = null; var playerBullets = []; var bossBullets = []; var doubleShotPowerUps = []; var healthPowerUps = []; var powerUpSpawnTimer = 0; var currentBoss = null; var currentBossIndex = 0; var bossConfigs = [{ "class": Boss1, name: "ZombiEagle" }, { "class": Boss2, name: "Cursed Ghost" }, { "class": Boss3, name: "Stone Gargoyle" }, { "class": Boss4, name: "Grey Dragon" }]; var playerHealthBar = null; var bossHealthBarContainer = null; var bossHealthBarBg = null; var bossHealthBarFill = null; var bossNameText = null; var nextStageButton = null; function showNextStageButton() { // If button already exists, just show it if (nextStageButton) { nextStageButton.visible = true; return; } // Create Next Stage button as clickable asset nextStageButton = game.attachAsset('nextStageButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); // Add button text overlay var buttonText = new Text2('Next Stage', { size: 60, fill: '#FFFF00', font: 'monospace', stroke: '#000000', strokeThickness: 4 }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 0; buttonText.y = 0; nextStageButton.addChild(buttonText); // Add button functionality nextStageButton.down = function (x, y, obj) { // Progress to next boss currentBossIndex++; console.log("Progressing to boss index:", currentBossIndex); // Hide the button instead of destroying it if (nextStageButton) { nextStageButton.visible = false; } // Spawn next boss with delay LK.setTimeout(function () { try { spawnNextBoss(); } catch (error) { console.error("Error spawning next boss:", error); } }, 500); }; } // Show intro screen introScreen = game.addChild(new IntroScreen()); introScreen.x = 1024; introScreen.y = 1366; // Start music when game logo appears LK.playMusic('epicboss'); // Auto-start game after 4 seconds LK.setTimeout(function () { if (!gameStarted) { startMainGame(); if (introScreen) { introScreen.destroy(); introScreen = null; } } }, 4000); function startMainGame() { gameStarted = true; arena.visible = true; game.setChildIndex(arena, 0); player = game.addChild(new Player()); player.x = 1024; player.y = 1366; player.lastX = player.x; game.setChildIndex(player, game.children.length - 1); playerHealthBar = new Text2('Health: 100', { size: 48, fill: '#FFFFFF', font: 'monospace', stroke: '#000000', strokeThickness: 6 }); playerHealthBar.x = arenaLeft + 50; playerHealthBar.y = arenaTop + 100; game.addChild(playerHealthBar); bossHealthBarContainer = new Container(); bossHealthBarContainer.x = 1024; bossHealthBarContainer.y = arenaTop + 50; game.addChild(bossHealthBarContainer); bossHealthBarBg = bossHealthBarContainer.attachAsset('bossHealthBarBg', { anchorX: 0.5, anchorY: 0.5 }); bossHealthBarFill = bossHealthBarContainer.attachAsset('bossHealthBarFill', { anchorX: 0.5, anchorY: 0.5 }); bossNameText = new Text2('ZombiEagle', { size: 56, fill: '#FFFF00', font: 'monospace', stroke: '#000000', strokeThickness: 6 }); bossNameText.anchor.set(0.5, 0); bossNameText.x = 1024; bossNameText.y = arenaTop + 10; game.addChild(bossNameText); spawnNextBoss(); } function spawnNextBoss() { console.log("Attempting to spawn boss at index", currentBossIndex, "of", bossConfigs.length, "total bosses"); if (currentBossIndex >= bossConfigs.length) { console.log("All bosses defeated in spawnNextBoss, currentBossIndex:", currentBossIndex); // Only show win if we've actually defeated all 4 bosses (indices 0,1,2,3) if (currentBossIndex >= 4) { LK.showYouWin(); } return; } if (!bossConfigs[currentBossIndex]) { console.error("Invalid boss index:", currentBossIndex, "available bosses:", bossConfigs.length); return; } if (currentBoss) { currentBoss.destroy(); currentBoss = null; } for (var i = bossBullets.length - 1; i >= 0; i--) { bossBullets[i].destroy(); bossBullets.splice(i, 1); } var bossConfig = bossConfigs[currentBossIndex]; var bossIntroScreen = game.addChild(new BossIntroScreen()); bossIntroScreen.x = 1024; bossIntroScreen.y = 1366; var introAssetId = 'boss' + (currentBossIndex + 1) + 'Intro'; bossIntroScreen.showIntro(bossConfig.name, introAssetId); LK.setTimeout(function () { try { var arenaAssetName = 'arena'; if (currentBossIndex === 1) { arenaAssetName = 'arena2'; } else if (currentBossIndex === 2) { arenaAssetName = 'arena3'; } else if (currentBossIndex === 3) { arenaAssetName = 'arena4'; } if (arena) { arena.destroy(); arena = null; } arena = game.attachAsset(arenaAssetName, { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, visible: true }); game.setChildIndex(arena, 0); arenaLeft = arena.x - arena.width / 2; arenaRight = arena.x + arena.width / 2; arenaTop = arena.y - arena.height / 2; arenaBottom = arena.y + arena.height / 2; currentBoss = game.addChild(new bossConfig["class"]()); currentBoss.x = 1024; currentBoss.y = arenaTop + 200; bossNameText.setText(bossConfig.name); if (player) { player.x = 1024; player.y = 1366; player.lastX = player.x; } if (bossHealthBarContainer) { bossHealthBarContainer.y = arenaTop + 50; } if (bossNameText) { bossNameText.y = arenaTop + 10; } if (playerHealthBar) { playerHealthBar.x = arenaLeft + 50; playerHealthBar.y = arenaTop + 100; } // Enable player shooting when boss intro ends and boss spawns if (player) { player.canShoot = true; } console.log("Successfully spawned boss", currentBossIndex + 1); } catch (error) { console.error("Error during boss spawn:", error); } }, 4000); } var dragActive = false; game.down = function (x, y, obj) { if (gameStarted) { dragActive = true; player.shoot(); } }; game.up = function (x, y, obj) { if (gameStarted) { dragActive = false; } }; game.move = function (x, y, obj) { if (gameStarted && dragActive) { var localPos = game.toLocal({ x: x, y: y }); player.x = Math.max(arenaLeft + 60, Math.min(arenaRight - 60, localPos.x)); player.y = Math.max(arenaTop + 60, Math.min(arenaBottom - 60, localPos.y)); } }; game.update = function () { if (!gameStarted) { return; } for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; if (bullet.y < arenaTop - 50) { bullet.destroy(); playerBullets.splice(i, 1); continue; } if (currentBoss && bullet.intersects(currentBoss)) { currentBoss.takeDamage(bullet.damage); bullet.destroy(); playerBullets.splice(i, 1); continue; } } for (var i = bossBullets.length - 1; i >= 0; i--) { var bullet = bossBullets[i]; if (bullet.x < arenaLeft - 50 || bullet.x > arenaRight + 50 || bullet.y < arenaTop - 50 || bullet.y > arenaBottom + 50) { bullet.destroy(); bossBullets.splice(i, 1); continue; } if (bullet.intersects(player)) { player.takeDamage(bullet.damage); bullet.destroy(); bossBullets.splice(i, 1); continue; } } powerUpSpawnTimer++; if (powerUpSpawnTimer >= 900 && Math.random() < 0.04) { var powerUpType = Math.random() < 0.5 ? 'double' : 'health'; if (powerUpType === 'double') { var powerUp = new DoubleShotPowerUp(); powerUp.x = arenaLeft + 100 + Math.random() * (arenaRight - arenaLeft - 200); powerUp.y = arenaTop - 50; doubleShotPowerUps.push(powerUp); game.addChild(powerUp); } else { var healthPowerUp = new HealthPowerUp(); healthPowerUp.x = arenaLeft + 100 + Math.random() * (arenaRight - arenaLeft - 200); healthPowerUp.y = arenaTop - 50; healthPowerUps.push(healthPowerUp); game.addChild(healthPowerUp); } powerUpSpawnTimer = 0; } for (var i = doubleShotPowerUps.length - 1; i >= 0; i--) { var powerUp = doubleShotPowerUps[i]; if (powerUp.y > arenaBottom + 50) { powerUp.destroy(); doubleShotPowerUps.splice(i, 1); continue; } if (!powerUp.collected && powerUp.intersects(player)) { player.collectDoubleShotPowerUp(); powerUp.collected = true; tween(powerUp, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, onFinish: function onFinish() { powerUp.destroy(); } }); doubleShotPowerUps.splice(i, 1); continue; } } for (var i = healthPowerUps.length - 1; i >= 0; i--) { var healthPowerUp = healthPowerUps[i]; if (healthPowerUp.y > arenaBottom + 50) { healthPowerUp.destroy(); healthPowerUps.splice(i, 1); continue; } if (!healthPowerUp.collected && healthPowerUp.intersects(player)) { player.collectHealthPowerUp(); healthPowerUp.collected = true; tween(healthPowerUp, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, onFinish: function onFinish() { healthPowerUp.destroy(); } }); healthPowerUps.splice(i, 1); continue; } } playerHealthBar.setText('Health: ' + player.health); if (currentBoss) { var healthPercentage = currentBoss.health / currentBoss.maxHealth; bossHealthBarFill.width = 400 * healthPercentage; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
self.maxHealth = 300;
self.health = self.maxHealth;
self.patternIndex = 0;
self.patternTimer = 0;
self.isVulnerable = false;
self.vulnerabilityTimer = 0;
self.attackPatterns = [];
self.attackPatternsPhase2 = [];
self.currentPhase = 1;
self.lastHealthPercentage = 1.0;
self.takeDamage = function (damage) {
if (self.isVulnerable) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
LK.getSound('bossHit').play();
if (self.health <= 0) {
self.health = 0;
self.onDefeat();
}
}
};
self.onDefeat = function () {
LK.getSound('bossDefeat').play();
// Make boss vanish and stop attacking
self.visible = false;
self.alpha = 0;
// Stop player shooting when boss is defeated
if (player) {
player.canShoot = false;
player.health = player.maxHealth;
}
console.log("Boss defeated. Current index:", currentBossIndex, "Total bosses:", bossConfigs.length);
// Check if this is the final boss (Boss4 at index 3)
if (currentBossIndex === 3) {
console.log("All 4 bosses defeated - showing win screen");
LK.showYouWin();
} else {
// Show Next Stage button instead of auto-progressing
showNextStageButton();
}
};
self.executePattern = function () {
// Override in specific boss classes
};
self.update = function () {
// Stop all attacks and patterns if health is 0
if (self.health <= 0) {
return;
}
self.patternTimer++;
if (self.vulnerabilityTimer > 0) {
self.vulnerabilityTimer--;
if (self.vulnerabilityTimer <= 0) {
self.isVulnerable = false;
}
}
// Check for phase transition at 50% health
var currentHealthPercentage = self.health / self.maxHealth;
if (self.currentPhase === 1 && currentHealthPercentage <= 0.5 && self.lastHealthPercentage > 0.5) {
self.currentPhase = 2;
self.patternIndex = 0;
self.patternTimer = 0;
LK.effects.flashObject(self, 0xffffff, 1000);
// Start phase 2 flashing effect
self.startPhase2Flash();
}
self.lastHealthPercentage = currentHealthPercentage;
self.executePattern();
};
return self;
});
var Boss4 = Boss.expand(function () {
var self = Boss.call(this);
var bossGraphics = self.attachAsset('boss4', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1.0
});
self.maxHealth = 600;
self.health = self.maxHealth;
self.attackPatterns = [{
duration: 120,
action: 'ultimate_sweep'
}, {
duration: 100,
action: 'chaos_storm'
}, {
duration: 150,
action: 'teleport_barrage'
}, {
duration: 120,
action: 'gravity_pull'
}, {
duration: 80,
action: 'laser_grid'
}, {
duration: 90,
action: 'vulnerable'
}];
self.attackPatternsPhase2 = [{
duration: 80,
action: 'apocalypse_sweep'
}, {
duration: 60,
action: 'death_spiral'
}, {
duration: 100,
action: 'final_barrage'
}, {
duration: 120,
action: 'dimensional_rift'
}, {
duration: 70,
action: 'omega_grid'
}, {
duration: 60,
action: 'vulnerable'
}];
self.executePattern = function () {
var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2;
var currentPattern = patterns[self.patternIndex];
if (self.patternTimer >= currentPattern.duration) {
self.patternTimer = 0;
self.patternIndex = (self.patternIndex + 1) % patterns.length;
}
switch (currentPattern.action) {
case 'ultimate_sweep':
if (self.patternTimer % 8 === 0) {
self.ultimateSweep();
}
break;
case 'chaos_storm':
if (self.patternTimer % 4 === 0) {
self.chaosStorm();
}
break;
case 'teleport_barrage':
if (self.patternTimer % 25 === 0) {
self.teleportBarrage();
}
break;
case 'gravity_pull':
if (self.patternTimer === 1) {
self.gravityPull();
}
break;
case 'laser_grid':
if (self.patternTimer % 15 === 0) {
self.laserGrid();
}
break;
case 'vulnerable':
self.isVulnerable = true;
self.vulnerabilityTimer = 90;
tween(bossGraphics, {
alpha: 0.4
}, {
duration: 200
});
break;
case 'apocalypse_sweep':
if (self.patternTimer % 5 === 0) {
self.apocalypseSweep();
}
break;
case 'death_spiral':
if (self.patternTimer % 6 === 0) {
self.deathSpiral();
}
break;
case 'final_barrage':
if (self.patternTimer % 3 === 0) {
self.finalBarrage();
}
break;
case 'dimensional_rift':
if (self.patternTimer % 20 === 0) {
self.dimensionalRift();
}
break;
case 'omega_grid':
if (self.patternTimer % 10 === 0) {
self.omegaGrid();
}
break;
}
};
self.ultimateSweep = function () {
for (var i = 0; i < 7; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (i - 3) * 40;
bullet.y = self.y + 50;
bullet.direction = {
x: (i - 3) * 0.2,
y: 1
};
bullet.speed = 7;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.chaosStorm = function () {
for (var i = 0; i < 4; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (Math.random() - 0.5) * 400;
bullet.y = self.y + 50;
bullet.direction = {
x: (Math.random() - 0.5) * 4,
y: 0.8 + Math.random() * 0.4
};
bullet.speed = 6 + Math.random() * 3;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.teleportBarrage = function () {
var teleportPositions = [{
x: arenaLeft + 200,
y: arenaTop + 250
}, {
x: arenaRight - 200,
y: arenaTop + 250
}, {
x: 1024,
y: arenaTop + 150
}, {
x: arenaLeft + 300,
y: arenaTop + 400
}, {
x: arenaRight - 300,
y: arenaTop + 400
}];
var randomPos = teleportPositions[Math.floor(Math.random() * teleportPositions.length)];
tween(self, {
x: randomPos.x,
y: randomPos.y
}, {
duration: 200
});
// Massive bullet spread after teleport
LK.setTimeout(function () {
for (var i = 0; i < 12; i++) {
var angle = i / 12 * Math.PI * 2;
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.direction = {
x: Math.cos(angle),
y: Math.sin(angle)
};
bullet.speed = 5;
bossBullets.push(bullet);
game.addChild(bullet);
}
}, 300);
};
self.gravityPull = function () {
// Pull effect - move towards player position over time
var targetX = Math.max(arenaLeft + 200, Math.min(arenaRight - 200, player.x));
var targetY = Math.max(arenaTop + 200, Math.min(arenaBottom - 300, player.y - 150));
tween(self, {
x: targetX,
y: targetY
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Explosion of bullets in all directions
for (var i = 0; i < 16; i++) {
var angle = i / 16 * Math.PI * 2;
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.direction = {
x: Math.cos(angle),
y: Math.sin(angle)
};
bullet.speed = 6;
bossBullets.push(bullet);
game.addChild(bullet);
}
}
});
};
self.laserGrid = function () {
// Create grid pattern of bullets
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 5; col++) {
var bullet = new BossBullet();
bullet.x = arenaLeft + 200 + col * 300;
bullet.y = self.y + row * 80;
bullet.direction = {
x: 0,
y: 1
};
bullet.speed = 4 + row;
bossBullets.push(bullet);
game.addChild(bullet);
}
}
};
self.apocalypseSweep = function () {
// Even more intense sweep for phase 2
for (var i = 0; i < 9; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (i - 4) * 35;
bullet.y = self.y + 50;
bullet.direction = {
x: (i - 4) * 0.25,
y: 1
};
bullet.speed = 8;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.deathSpiral = function () {
// Rotating spiral pattern
var spiralCount = 6;
for (var i = 0; i < spiralCount; i++) {
var angle = (self.patternTimer * 0.3 + i * Math.PI * 2 / spiralCount) % (Math.PI * 2);
var bullet = new BossBullet();
bullet.x = self.x + Math.cos(angle) * 100;
bullet.y = self.y + Math.sin(angle) * 50 + 50;
bullet.direction = {
x: Math.cos(angle + Math.PI / 4) * 0.8,
y: Math.sin(angle + Math.PI / 4) * 0.8 + 0.6
};
bullet.speed = 7;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.finalBarrage = function () {
// Overwhelming bullet hell
for (var i = 0; i < 6; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (Math.random() - 0.5) * 500;
bullet.y = self.y + Math.random() * 100;
var angleToPlayer = Math.atan2(player.y - bullet.y, player.x - bullet.x);
bullet.direction = {
x: Math.cos(angleToPlayer + (Math.random() - 0.5) * 0.8),
y: Math.sin(angleToPlayer + (Math.random() - 0.5) * 0.8)
};
bullet.speed = 5 + Math.random() * 4;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.dimensionalRift = function () {
// Teleport to multiple positions rapidly
var positions = [{
x: arenaLeft + 150,
y: arenaTop + 200
}, {
x: arenaRight - 150,
y: arenaTop + 200
}, {
x: 1024,
y: arenaTop + 350
}, {
x: arenaLeft + 300,
y: arenaTop + 500
}, {
x: arenaRight - 300,
y: arenaTop + 500
}];
for (var p = 0; p < 3; p++) {
var pos = positions[Math.floor(Math.random() * positions.length)];
LK.setTimeout(function () {
tween(self, {
x: pos.x,
y: pos.y
}, {
duration: 150
});
// Shoot bullets from each position
for (var j = 0; j < 8; j++) {
var angle = j / 8 * Math.PI * 2;
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.direction = {
x: Math.cos(angle),
y: Math.sin(angle)
};
bullet.speed = 6;
bossBullets.push(bullet);
game.addChild(bullet);
}
}, p * 200);
}
};
self.omegaGrid = function () {
// Ultimate grid attack
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 7; col++) {
var bullet = new BossBullet();
bullet.x = arenaLeft + 150 + col * 250;
bullet.y = self.y + row * 60;
bullet.direction = {
x: (col - 3) * 0.1,
y: 1
};
bullet.speed = 5 + row;
bossBullets.push(bullet);
game.addChild(bullet);
}
}
};
self.startPhase2Flash = function () {
var flashToGold = function flashToGold() {
tween(bossGraphics, {
tint: 0xFFD700
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: flashToWhite
});
};
var flashToWhite = function flashToWhite() {
tween(bossGraphics, {
tint: 0xFFFFFF
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: flashToGold
});
};
flashToGold();
};
return self;
});
var Boss3 = Boss.expand(function () {
var self = Boss.call(this);
var bossGraphics = self.attachAsset('boss3', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1.0
});
self.maxHealth = 250;
self.health = self.maxHealth;
self.attackPatterns = [{
duration: 60,
action: 'laser_sweep'
}, {
duration: 50,
action: 'bullet_hell'
}, {
duration: 80,
action: 'dash_attack'
}, {
duration: 100,
action: 'dive_attack'
}, {
duration: 70,
action: 'horizontal_sweep'
}, {
duration: 80,
action: 'diagonal_attack'
}, {
duration: 80,
action: 'vulnerable'
}];
self.attackPatternsPhase2 = [{
duration: 50,
action: 'mega_laser_sweep'
}, {
duration: 40,
action: 'chaos_bullets'
}, {
duration: 70,
action: 'triple_dash'
}, {
duration: 80,
action: 'power_dive'
}, {
duration: 50,
action: 'spiral_sweep'
}, {
duration: 60,
action: 'diagonal_barrage'
}, {
duration: 60,
action: 'vulnerable'
}];
self.executePattern = function () {
var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2;
var currentPattern = patterns[self.patternIndex];
if (self.patternTimer >= currentPattern.duration) {
self.patternTimer = 0;
self.patternIndex = (self.patternIndex + 1) % patterns.length;
}
switch (currentPattern.action) {
case 'laser_sweep':
if (self.patternTimer % 15 === 0) {
self.shootLaser();
}
break;
case 'bullet_hell':
if (self.patternTimer % 8 === 0) {
self.shootRandomBullets();
}
break;
case 'dash_attack':
if (self.patternTimer === 1) {
var targetY = Math.min(player.y, arenaBottom - 150);
tween(self, {
y: targetY
}, {
duration: 500
});
}
break;
case 'dive_attack':
if (self.patternTimer === 1) {
self.diveAttack();
}
break;
case 'vulnerable':
self.isVulnerable = true;
self.vulnerabilityTimer = 60;
tween(bossGraphics, {
alpha: 0.5
}, {
duration: 200
});
break;
case 'mega_laser_sweep':
if (self.patternTimer % 10 === 0) {
self.shootMegaLaser();
}
break;
case 'chaos_bullets':
if (self.patternTimer % 6 === 0) {
self.shootChaosBullets();
}
break;
case 'triple_dash':
if (self.patternTimer % 30 === 0) {
self.tripleDash();
}
break;
case 'power_dive':
if (self.patternTimer === 1) {
self.powerDive();
}
break;
case 'horizontal_sweep':
if (self.patternTimer % 20 === 0) {
self.horizontalSweep();
}
break;
case 'diagonal_attack':
if (self.patternTimer % 15 === 0) {
self.diagonalAttack();
}
break;
case 'spiral_sweep':
if (self.patternTimer % 12 === 0) {
self.spiralSweep();
}
break;
case 'diagonal_barrage':
if (self.patternTimer % 8 === 0) {
self.diagonalBarrage();
}
break;
}
};
self.shootLaser = function () {
for (var i = 0; i < 3; i++) {
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y + 50 + i * 20;
bullet.direction = {
x: 0,
y: 1
};
bullet.speed = 6;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.shootRandomBullets = function () {
var bullet = new BossBullet();
bullet.x = self.x + (Math.random() - 0.5) * 200;
bullet.y = self.y + 50;
bullet.direction = {
x: (Math.random() - 0.5) * 2,
y: 1
};
bossBullets.push(bullet);
game.addChild(bullet);
};
self.shootMegaLaser = function () {
for (var i = 0; i < 5; i++) {
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y + 50 + i * 15;
bullet.direction = {
x: 0,
y: 1
};
bullet.speed = 8;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.shootChaosBullets = function () {
for (var i = 0; i < 3; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (Math.random() - 0.5) * 300;
bullet.y = self.y + 50;
bullet.direction = {
x: (Math.random() - 0.5) * 3,
y: 1
};
bullet.speed = 7;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.tripleDash = function () {
var dashTargets = [player.y - 100, player.y, player.y + 100];
for (var j = 0; j < dashTargets.length; j++) {
dashTargets[j] = Math.min(dashTargets[j], arenaBottom - 150);
}
for (var i = 0; i < dashTargets.length; i++) {
tween(self, {
y: dashTargets[i]
}, {
duration: 200,
delay: i * 100
});
}
};
self.diveAttack = function () {
tween(self, {
y: arenaBottom - 100
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(self, {
y: arenaTop + 200
}, {
duration: 600,
easing: tween.easeOut
});
}, 300);
}
});
};
self.powerDive = function () {
tween(self, {
y: arenaBottom - 80
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
for (var i = 0; i < 5; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (i - 2) * 40;
bullet.y = self.y;
bullet.direction = {
x: (i - 2) * 0.3,
y: -1
};
bullet.speed = 5;
bossBullets.push(bullet);
game.addChild(bullet);
}
LK.setTimeout(function () {
tween(self, {
y: arenaTop + 200
}, {
duration: 400,
easing: tween.easeOut
});
}, 200);
}
});
};
self.horizontalSweep = function () {
var targetX = self.x < 1024 ? arenaRight - 200 : arenaLeft + 200;
tween(self, {
x: targetX
}, {
duration: 1000,
easing: tween.easeInOut
});
for (var i = 0; i < 2; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (i - 0.5) * 60;
bullet.y = self.y + 50;
bullet.direction = {
x: 0,
y: 1
};
bullet.speed = 5;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.diagonalAttack = function () {
var targetX = self.x < 1024 ? arenaRight - 150 : arenaLeft + 150;
var targetY = Math.min(self.y + 100, arenaBottom - 200);
tween(self, {
x: targetX,
y: targetY
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: 1024,
y: arenaTop + 200
}, {
duration: 600,
easing: tween.easeOut
});
}
});
for (var i = 0; i < 3; i++) {
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y + 40;
bullet.direction = {
x: (i - 1) * 0.5,
y: 1
};
bullet.speed = 6;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.spiralSweep = function () {
var targetX = self.x < 1024 ? arenaRight - 150 : arenaLeft + 150;
tween(self, {
x: targetX
}, {
duration: 600,
easing: tween.easeInOut
});
for (var i = 0; i < 4; i++) {
var angle = (self.patternTimer * 0.2 + i * Math.PI / 2) % (Math.PI * 2);
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y + 50;
bullet.direction = {
x: Math.cos(angle) * 0.8,
y: Math.sin(angle) * 0.8 + 0.5
};
bullet.speed = 6;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.diagonalBarrage = function () {
var targets = [{
x: arenaLeft + 200,
y: arenaTop + 300
}, {
x: arenaRight - 200,
y: arenaTop + 300
}, {
x: 1024,
y: arenaTop + 150
}];
var targetIndex = Math.floor(self.patternTimer / 30) % targets.length;
var target = targets[targetIndex];
tween(self, {
x: target.x,
y: target.y
}, {
duration: 400,
easing: tween.easeInOut
});
for (var i = 0; i < 5; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (i - 2) * 30;
bullet.y = self.y + 50;
var angleToPlayer = Math.atan2(player.y - bullet.y, player.x - bullet.x);
bullet.direction = {
x: Math.cos(angleToPlayer + (i - 2) * 0.3),
y: Math.sin(angleToPlayer + (i - 2) * 0.3)
};
bullet.speed = 7;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.startPhase2Flash = function () {
var flashToYellow = function flashToYellow() {
tween(bossGraphics, {
tint: 0xFFFF00
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashToRed
});
};
var flashToRed = function flashToRed() {
tween(bossGraphics, {
tint: 0xFF0000
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashToYellow
});
};
flashToYellow();
};
return self;
});
var Boss2 = Boss.expand(function () {
var self = Boss.call(this);
var bossGraphics = self.attachAsset('boss2', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1.0
});
self.maxHealth = 400;
self.health = self.maxHealth;
self.attackPatterns = [{
duration: 90,
action: 'circle_pattern'
}, {
duration: 60,
action: 'rapid_fire'
}, {
duration: 120,
action: 'teleport'
}, {
duration: 80,
action: 'vulnerable'
}];
self.attackPatternsPhase2 = [{
duration: 70,
action: 'double_circle'
}, {
duration: 45,
action: 'homing_barrage'
}, {
duration: 90,
action: 'shadow_teleport'
}, {
duration: 60,
action: 'vulnerable'
}];
self.executePattern = function () {
var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2;
var currentPattern = patterns[self.patternIndex];
if (self.patternTimer >= currentPattern.duration) {
self.patternTimer = 0;
self.patternIndex = (self.patternIndex + 1) % patterns.length;
}
switch (currentPattern.action) {
case 'circle_pattern':
if (self.patternTimer % 15 === 0) {
self.shootCircle();
}
break;
case 'rapid_fire':
if (self.patternTimer % 8 === 0) {
self.shootAtPlayer();
}
break;
case 'teleport':
if (self.patternTimer === 1) {
var newX = arenaLeft + 200 + Math.random() * (arenaRight - arenaLeft - 400);
tween(self, {
x: newX
}, {
duration: 300
});
}
break;
case 'vulnerable':
self.isVulnerable = true;
self.vulnerabilityTimer = 80;
tween(bossGraphics, {
alpha: 0.6
}, {
duration: 200
});
break;
case 'double_circle':
if (self.patternTimer % 12 === 0) {
self.shootDoubleCircle();
}
break;
case 'homing_barrage':
if (self.patternTimer % 6 === 0) {
self.shootHomingBarrage();
}
break;
case 'shadow_teleport':
if (self.patternTimer % 20 === 0) {
self.shadowTeleport();
}
break;
}
};
self.shootCircle = function () {
for (var i = 0; i < 8; i++) {
var angle = i / 8 * Math.PI * 2;
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.direction = {
x: Math.cos(angle),
y: Math.sin(angle)
};
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.shootAtPlayer = function () {
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y + 50;
var dx = player.x - self.x;
var dy = player.y - self.y;
var length = Math.sqrt(dx * dx + dy * dy);
bullet.direction = {
x: dx / length,
y: dy / length
};
bossBullets.push(bullet);
game.addChild(bullet);
};
self.shootDoubleCircle = function () {
for (var ring = 0; ring < 2; ring++) {
for (var i = 0; i < 6; i++) {
var angle = i / 6 * Math.PI * 2 + ring * Math.PI / 6;
var bullet = new BossBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.direction = {
x: Math.cos(angle),
y: Math.sin(angle)
};
bullet.speed = 4 + ring * 2;
bossBullets.push(bullet);
game.addChild(bullet);
}
}
};
self.shootHomingBarrage = function () {
for (var i = 0; i < 2; i++) {
var bullet = new BossBullet();
bullet.x = self.x + (i - 0.5) * 40;
bullet.y = self.y + 50;
var dx = player.x - bullet.x;
var dy = player.y - bullet.y;
var length = Math.sqrt(dx * dx + dy * dy);
bullet.direction = {
x: dx / length,
y: dy / length
};
bullet.speed = 6;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.shadowTeleport = function () {
var teleportPositions = [{
x: arenaLeft + 150,
y: self.y
}, {
x: arenaRight - 150,
y: self.y
}, {
x: 1024,
y: arenaTop + 150
}];
var randomPos = teleportPositions[Math.floor(Math.random() * teleportPositions.length)];
tween(self, {
x: randomPos.x,
y: randomPos.y
}, {
duration: 250
});
};
self.startPhase2Flash = function () {
var flashToYellow = function flashToYellow() {
tween(bossGraphics, {
tint: 0xFFFF00
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashToRed
});
};
var flashToRed = function flashToRed() {
tween(bossGraphics, {
tint: 0xFF0000
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashToYellow
});
};
flashToYellow();
};
return self;
});
var Boss1 = Boss.expand(function () {
var self = Boss.call(this);
var bossGraphics = self.attachAsset('boss1', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1.0
});
self.attackPatterns = [{
duration: 120,
action: 'move_left'
}, {
duration: 60,
action: 'shoot_spread'
}, {
duration: 120,
action: 'move_right'
}, {
duration: 60,
action: 'shoot_spread'
}, {
duration: 90,
action: 'vulnerable'
}];
self.attackPatternsPhase2 = [{
duration: 80,
action: 'speed_dash'
}, {
duration: 40,
action: 'rapid_spread'
}, {
duration: 80,
action: 'speed_dash'
}, {
duration: 40,
action: 'rapid_spread'
}, {
duration: 70,
action: 'vulnerable'
}];
self.executePattern = function () {
var patterns = self.currentPhase === 1 ? self.attackPatterns : self.attackPatternsPhase2;
var currentPattern = patterns[self.patternIndex];
if (self.patternTimer >= currentPattern.duration) {
self.patternTimer = 0;
self.patternIndex = (self.patternIndex + 1) % patterns.length;
}
switch (currentPattern.action) {
case 'move_left':
if (self.x > arenaLeft + 100) {
self.x -= 2;
}
break;
case 'move_right':
if (self.x < arenaRight - 100) {
self.x += 2;
}
break;
case 'shoot_spread':
if (self.patternTimer % 20 === 0) {
self.shootSpread();
}
break;
case 'vulnerable':
self.isVulnerable = true;
self.vulnerabilityTimer = 90;
tween(bossGraphics, {
alpha: 0.7
}, {
duration: 200
});
break;
case 'speed_dash':
if (self.x > arenaLeft + 100 && self.patternTimer < 40) {
self.x -= 4;
} else if (self.x < arenaRight - 100 && self.patternTimer >= 40) {
self.x += 4;
}
break;
case 'rapid_spread':
if (self.patternTimer % 10 === 0) {
self.shootRapidSpread();
}
break;
}
};
self.shootSpread = function () {
for (var i = -2; i <= 2; i++) {
var bullet = new BossBullet();
bullet.x = self.x + i * 30;
bullet.y = self.y + 50;
bullet.direction = {
x: i * 0.3,
y: 1
};
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.shootRapidSpread = function () {
for (var i = -3; i <= 3; i++) {
var bullet = new BossBullet();
bullet.x = self.x + i * 25;
bullet.y = self.y + 50;
bullet.direction = {
x: i * 0.4,
y: 1
};
bullet.speed = 6;
bossBullets.push(bullet);
game.addChild(bullet);
}
};
self.startPhase2Flash = function () {
var flashToYellow = function flashToYellow() {
tween(bossGraphics, {
tint: 0xFFFF00
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashToRed
});
};
var flashToRed = function flashToRed() {
tween(bossGraphics, {
tint: 0xFF0000
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashToYellow
});
};
flashToYellow();
};
return self;
});
var BossBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bossBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.damage = 15;
self.direction = {
x: 0,
y: 1
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
return self;
});
var BossIntroScreen = Container.expand(function () {
var self = Container.call(this);
self.showIntro = function (bossName, introAssetId) {
var introGraphics = self.attachAsset(introAssetId, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
alpha: 0
});
tween(introGraphics, {
alpha: 1
}, {
duration: 800,
easing: tween.easeInOut
});
LK.setTimeout(function () {
tween(self, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
}, 4000);
};
return self;
});
var DoubleShotPowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('doubleShotPowerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.collected = false;
self.update = function () {
self.y += self.speed;
};
return self;
});
var HealthPowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('healthPowerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.collected = false;
self.update = function () {
self.y += self.speed;
};
return self;
});
var IntroScreen = Container.expand(function () {
var self = Container.call(this);
var logoGraphics = self.attachAsset('gameLogo', {
anchorX: 0.5,
anchorY: 0.5
});
logoGraphics.x = 0;
logoGraphics.y = -200;
logoGraphics.alpha = 0;
tween(logoGraphics, {
alpha: 1
}, {
duration: 800
});
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerLeftGraphics = self.attachAsset('playerLeft', {
anchorX: 0.5,
anchorY: 0.5,
visible: true,
alpha: 1.0
});
var playerRightGraphics = self.attachAsset('playerRight', {
anchorX: 0.5,
anchorY: 0.5,
visible: true,
alpha: 1.0
});
self.maxHealth = 150;
self.health = self.maxHealth;
self.speed = 8;
self.canShoot = false;
self.shootCooldown = 0;
self.lastX = 0;
self.facing = 'left';
self.hasDoubleShot = false;
self.doubleShotTimer = 0;
self.power = 10;
self.updateFacing = function () {
var newFacing = self.facing;
if (self.x < self.lastX - 5) {
newFacing = 'left';
} else if (self.x > self.lastX + 5) {
newFacing = 'right';
}
if (newFacing !== self.facing) {
self.facing = newFacing;
playerLeftGraphics.visible = newFacing === 'left';
playerRightGraphics.visible = newFacing === 'right';
}
self.lastX = self.x;
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
}
LK.effects.flashObject(self, 0xff0000, 500);
LK.getSound('playerHit').play();
};
self.shoot = function () {
if (self.canShoot && self.shootCooldown <= 0) {
if (self.hasDoubleShot) {
var bullet1 = new PlayerBullet();
bullet1.x = self.x - 20;
bullet1.y = self.y - 50;
bullet1.damage = self.power;
playerBullets.push(bullet1);
game.addChild(bullet1);
var bullet2 = new PlayerBullet();
bullet2.x = self.x + 20;
bullet2.y = self.y - 50;
bullet2.damage = self.power;
playerBullets.push(bullet2);
game.addChild(bullet2);
} else {
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y - 50;
bullet.damage = self.power;
playerBullets.push(bullet);
game.addChild(bullet);
}
// Keep constant power for all shots
self.shootCooldown = 9;
LK.getSound('playerShoot').play();
}
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.doubleShotTimer > 0) {
self.doubleShotTimer--;
if (self.doubleShotTimer <= 0) {
self.hasDoubleShot = false;
}
}
// Auto-shoot very fast - every 3 frames instead of every frame
if (LK.ticks % 3 === 0) {
self.shoot();
}
self.updateFacing();
};
self.collectDoubleShotPowerUp = function () {
self.hasDoubleShot = true;
self.doubleShotTimer = 600;
LK.effects.flashObject(self, 0x00ff00, 300);
};
self.collectHealthPowerUp = function () {
var recoveryAmount = Math.ceil(self.maxHealth * 0.2);
if (self.health >= self.maxHealth) {
self.maxHealth += recoveryAmount;
self.health = self.maxHealth;
} else {
self.health = Math.min(self.maxHealth, self.health + recoveryAmount);
}
LK.effects.flashObject(self, 0x00ff00, 500);
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.damage = 10;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
var gameStarted = false;
var introScreen = null;
var arena = game.attachAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
visible: false
});
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;
var player = null;
var playerBullets = [];
var bossBullets = [];
var doubleShotPowerUps = [];
var healthPowerUps = [];
var powerUpSpawnTimer = 0;
var currentBoss = null;
var currentBossIndex = 0;
var bossConfigs = [{
"class": Boss1,
name: "ZombiEagle"
}, {
"class": Boss2,
name: "Cursed Ghost"
}, {
"class": Boss3,
name: "Stone Gargoyle"
}, {
"class": Boss4,
name: "Grey Dragon"
}];
var playerHealthBar = null;
var bossHealthBarContainer = null;
var bossHealthBarBg = null;
var bossHealthBarFill = null;
var bossNameText = null;
var nextStageButton = null;
function showNextStageButton() {
// If button already exists, just show it
if (nextStageButton) {
nextStageButton.visible = true;
return;
}
// Create Next Stage button as clickable asset
nextStageButton = game.attachAsset('nextStageButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
// Add button text overlay
var buttonText = new Text2('Next Stage', {
size: 60,
fill: '#FFFF00',
font: 'monospace',
stroke: '#000000',
strokeThickness: 4
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 0;
buttonText.y = 0;
nextStageButton.addChild(buttonText);
// Add button functionality
nextStageButton.down = function (x, y, obj) {
// Progress to next boss
currentBossIndex++;
console.log("Progressing to boss index:", currentBossIndex);
// Hide the button instead of destroying it
if (nextStageButton) {
nextStageButton.visible = false;
}
// Spawn next boss with delay
LK.setTimeout(function () {
try {
spawnNextBoss();
} catch (error) {
console.error("Error spawning next boss:", error);
}
}, 500);
};
}
// Show intro screen
introScreen = game.addChild(new IntroScreen());
introScreen.x = 1024;
introScreen.y = 1366;
// Start music when game logo appears
LK.playMusic('epicboss');
// Auto-start game after 4 seconds
LK.setTimeout(function () {
if (!gameStarted) {
startMainGame();
if (introScreen) {
introScreen.destroy();
introScreen = null;
}
}
}, 4000);
function startMainGame() {
gameStarted = true;
arena.visible = true;
game.setChildIndex(arena, 0);
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
player.lastX = player.x;
game.setChildIndex(player, game.children.length - 1);
playerHealthBar = new Text2('Health: 100', {
size: 48,
fill: '#FFFFFF',
font: 'monospace',
stroke: '#000000',
strokeThickness: 6
});
playerHealthBar.x = arenaLeft + 50;
playerHealthBar.y = arenaTop + 100;
game.addChild(playerHealthBar);
bossHealthBarContainer = new Container();
bossHealthBarContainer.x = 1024;
bossHealthBarContainer.y = arenaTop + 50;
game.addChild(bossHealthBarContainer);
bossHealthBarBg = bossHealthBarContainer.attachAsset('bossHealthBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
bossHealthBarFill = bossHealthBarContainer.attachAsset('bossHealthBarFill', {
anchorX: 0.5,
anchorY: 0.5
});
bossNameText = new Text2('ZombiEagle', {
size: 56,
fill: '#FFFF00',
font: 'monospace',
stroke: '#000000',
strokeThickness: 6
});
bossNameText.anchor.set(0.5, 0);
bossNameText.x = 1024;
bossNameText.y = arenaTop + 10;
game.addChild(bossNameText);
spawnNextBoss();
}
function spawnNextBoss() {
console.log("Attempting to spawn boss at index", currentBossIndex, "of", bossConfigs.length, "total bosses");
if (currentBossIndex >= bossConfigs.length) {
console.log("All bosses defeated in spawnNextBoss, currentBossIndex:", currentBossIndex);
// Only show win if we've actually defeated all 4 bosses (indices 0,1,2,3)
if (currentBossIndex >= 4) {
LK.showYouWin();
}
return;
}
if (!bossConfigs[currentBossIndex]) {
console.error("Invalid boss index:", currentBossIndex, "available bosses:", bossConfigs.length);
return;
}
if (currentBoss) {
currentBoss.destroy();
currentBoss = null;
}
for (var i = bossBullets.length - 1; i >= 0; i--) {
bossBullets[i].destroy();
bossBullets.splice(i, 1);
}
var bossConfig = bossConfigs[currentBossIndex];
var bossIntroScreen = game.addChild(new BossIntroScreen());
bossIntroScreen.x = 1024;
bossIntroScreen.y = 1366;
var introAssetId = 'boss' + (currentBossIndex + 1) + 'Intro';
bossIntroScreen.showIntro(bossConfig.name, introAssetId);
LK.setTimeout(function () {
try {
var arenaAssetName = 'arena';
if (currentBossIndex === 1) {
arenaAssetName = 'arena2';
} else if (currentBossIndex === 2) {
arenaAssetName = 'arena3';
} else if (currentBossIndex === 3) {
arenaAssetName = 'arena4';
}
if (arena) {
arena.destroy();
arena = null;
}
arena = game.attachAsset(arenaAssetName, {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
visible: true
});
game.setChildIndex(arena, 0);
arenaLeft = arena.x - arena.width / 2;
arenaRight = arena.x + arena.width / 2;
arenaTop = arena.y - arena.height / 2;
arenaBottom = arena.y + arena.height / 2;
currentBoss = game.addChild(new bossConfig["class"]());
currentBoss.x = 1024;
currentBoss.y = arenaTop + 200;
bossNameText.setText(bossConfig.name);
if (player) {
player.x = 1024;
player.y = 1366;
player.lastX = player.x;
}
if (bossHealthBarContainer) {
bossHealthBarContainer.y = arenaTop + 50;
}
if (bossNameText) {
bossNameText.y = arenaTop + 10;
}
if (playerHealthBar) {
playerHealthBar.x = arenaLeft + 50;
playerHealthBar.y = arenaTop + 100;
}
// Enable player shooting when boss intro ends and boss spawns
if (player) {
player.canShoot = true;
}
console.log("Successfully spawned boss", currentBossIndex + 1);
} catch (error) {
console.error("Error during boss spawn:", error);
}
}, 4000);
}
var dragActive = false;
game.down = function (x, y, obj) {
if (gameStarted) {
dragActive = true;
player.shoot();
}
};
game.up = function (x, y, obj) {
if (gameStarted) {
dragActive = false;
}
};
game.move = function (x, y, obj) {
if (gameStarted && dragActive) {
var localPos = game.toLocal({
x: x,
y: y
});
player.x = Math.max(arenaLeft + 60, Math.min(arenaRight - 60, localPos.x));
player.y = Math.max(arenaTop + 60, Math.min(arenaBottom - 60, localPos.y));
}
};
game.update = function () {
if (!gameStarted) {
return;
}
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.y < arenaTop - 50) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
if (currentBoss && bullet.intersects(currentBoss)) {
currentBoss.takeDamage(bullet.damage);
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
}
for (var i = bossBullets.length - 1; i >= 0; i--) {
var bullet = bossBullets[i];
if (bullet.x < arenaLeft - 50 || bullet.x > arenaRight + 50 || bullet.y < arenaTop - 50 || bullet.y > arenaBottom + 50) {
bullet.destroy();
bossBullets.splice(i, 1);
continue;
}
if (bullet.intersects(player)) {
player.takeDamage(bullet.damage);
bullet.destroy();
bossBullets.splice(i, 1);
continue;
}
}
powerUpSpawnTimer++;
if (powerUpSpawnTimer >= 900 && Math.random() < 0.04) {
var powerUpType = Math.random() < 0.5 ? 'double' : 'health';
if (powerUpType === 'double') {
var powerUp = new DoubleShotPowerUp();
powerUp.x = arenaLeft + 100 + Math.random() * (arenaRight - arenaLeft - 200);
powerUp.y = arenaTop - 50;
doubleShotPowerUps.push(powerUp);
game.addChild(powerUp);
} else {
var healthPowerUp = new HealthPowerUp();
healthPowerUp.x = arenaLeft + 100 + Math.random() * (arenaRight - arenaLeft - 200);
healthPowerUp.y = arenaTop - 50;
healthPowerUps.push(healthPowerUp);
game.addChild(healthPowerUp);
}
powerUpSpawnTimer = 0;
}
for (var i = doubleShotPowerUps.length - 1; i >= 0; i--) {
var powerUp = doubleShotPowerUps[i];
if (powerUp.y > arenaBottom + 50) {
powerUp.destroy();
doubleShotPowerUps.splice(i, 1);
continue;
}
if (!powerUp.collected && powerUp.intersects(player)) {
player.collectDoubleShotPowerUp();
powerUp.collected = true;
tween(powerUp, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
powerUp.destroy();
}
});
doubleShotPowerUps.splice(i, 1);
continue;
}
}
for (var i = healthPowerUps.length - 1; i >= 0; i--) {
var healthPowerUp = healthPowerUps[i];
if (healthPowerUp.y > arenaBottom + 50) {
healthPowerUp.destroy();
healthPowerUps.splice(i, 1);
continue;
}
if (!healthPowerUp.collected && healthPowerUp.intersects(player)) {
player.collectHealthPowerUp();
healthPowerUp.collected = true;
tween(healthPowerUp, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
healthPowerUp.destroy();
}
});
healthPowerUps.splice(i, 1);
continue;
}
}
playerHealthBar.setText('Health: ' + player.health);
if (currentBoss) {
var healthPercentage = currentBoss.health / currentBoss.maxHealth;
bossHealthBarFill.width = 400 * healthPercentage;
}
};
Uma águia zumbi, vista aérea, estilo pixel art. In-Game asset. 2d. High contrast. No shadows
gota de sangue com contorno branco, pixel art, fundo transparente. In-Game asset. 2d. High contrast. No shadows
Um fantasma zumbi voador, arte pixel, vista aerea frontal. In-Game asset. 2d. High contrast. No shadows
um gárgula voador com olhos brilhantes, pixel 32bits art style, vista aerea frontal. In-Game asset. 2d. High contrast. No shadows
uma caverna escura estilo jogo de rpg, arte pixel, background game arena. In-Game asset. 2d. High contrast. No shadows
O telhado de um castelo medieval abandonado com suas torres. arte pixel 32 bits, vista aerea frontal. In-Game asset. 2d. High contrast. No shadows
um conjunto de montanhas de gelo, arte pixel 32bits, arena battle background. In-Game asset. 2d. High contrast. No shadows
MUDE A COR DA POÇÃO PARA AZUL
Escreva abaixo da poção o texto "HEALTH", ARTE PIXEL 32BITS
Make this dragon with 3 heads and a gray color scale
add details on left and right image to enlarge it