/**** * Classes ****/ // Global counter for Boss spawns var Boss = Container.expand(function () { var self = Container.call(this); bossSpawnCount++; // Increment the counter each time a Boss is spawned var bossGraphics = self.attachAsset('boss1', { anchorX: 0.5, anchorY: 0.5 // Removed tint for the boss }); self.speed = 2 * bossSpawnCount; self.hitpoints = 15 * bossSpawnCount; // High hitpoints for the boss self.update = function () { self.x += Math.sin(LK.ticks / 30) * (5 + bossSpeedIncrement); // Sideways movement self.y += Math.cos(LK.ticks / 50) * 3; // Top-down movement self.x = Math.max(Math.min(self.x, 2048 + self.width * 0.25), -self.width * 0.25); // Allow part of the body outside the screen horizontally self.y = Math.max(Math.min(self.y, 2732 * 0.4), self.height / 2); // Keep within top 40% of the screen if (Math.sin(LK.ticks / 30) < 0) { self.scale.x = -1; // Mirror image when moving left } else { self.scale.x = 1; // Normal image when moving right } // Logic to increase and decrease boss size if (LK.ticks % 120 < 60) { self.scale.x += 0.001; self.scale.y += 0.001; } else { self.scale.x -= 0.001; self.scale.y -= 0.001; } if (LK.ticks % 60 == 0) { LK.getSound('bossbullet').play(); // Play bossbullet sound when Boss shoots BossBullet // Shoot bullets every second var newBullet = new BossBullet(); newBullet.x = self.x; newBullet.y = self.y + self.height / 2; bullets.push(newBullet); game.addChild(newBullet); } }; }); // Global counter for Boss2 spawns var Boss2 = Container.expand(function () { var self = Container.call(this); boss2SpawnCount++; // Increment the counter each time a Boss2 is spawned var bossGraphics = self.attachAsset('boss2', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3 * boss2SpawnCount; self.hitpoints = 25 * boss2SpawnCount; // Higher hitpoints for the second boss self.update = function () { self.x += Math.sin(LK.ticks / 30) * (5 + bossSpeedIncrement); // Sideways movement self.y += Math.cos(LK.ticks / 50) * 3; // Top-down movement self.x = Math.max(Math.min(self.x, 2048 + self.width * 0.25), -self.width * 0.25); // Allow part of the body outside the screen horizontally self.y = Math.max(Math.min(self.y, 2732 * 0.4), self.height / 2); // Keep within top 40% of the screen if (Math.sin(LK.ticks / 30) < 0) { self.scale.x = -1; // Mirror image when moving left } else { self.scale.x = 1; // Normal image when moving right } if (LK.ticks % 120 < 60) { self.scale.x += 0.001; self.scale.y += 0.001; } else { self.scale.x -= 0.001; self.scale.y -= 0.001; } if (LK.ticks % 40 == 0) { LK.getSound('bossbullet').play(); // Play bossbullet sound when Boss2 shoots BossBullet2 var newBullet = new BossBullet2(); newBullet.x = self.x; newBullet.y = self.y + self.height / 2; bullets.push(newBullet); game.addChild(newBullet); } }; }); // Global counter for Boss3 spawns var Boss3 = Container.expand(function () { var self = Container.call(this); boss3SpawnCount++; // Increment the counter each time a Boss3 is spawned var bossGraphics = self.attachAsset('boss3', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4 * boss3SpawnCount; self.hitpoints = 35 * boss3SpawnCount; // Higher hitpoints for the third boss self.update = function () { self.x += Math.sin(LK.ticks / 30) * (5 + bossSpeedIncrement); // Sideways movement self.y += Math.cos(LK.ticks / 50) * 3; // Top-down movement self.x = Math.max(Math.min(self.x, 2048 + self.width * 0.25), -self.width * 0.25); // Allow part of the body outside the screen horizontally self.y = Math.max(Math.min(self.y, 2732 * 0.4), self.height / 2); // Keep within top 40% of the screen if (Math.sin(LK.ticks / 30) < 0) { self.scale.x = -1; // Mirror image when moving left } else { self.scale.x = 1; // Normal image when moving right } if (LK.ticks % 120 < 60) { self.scale.x += 0.001; self.scale.y += 0.001; } else { self.scale.x -= 0.001; self.scale.y -= 0.001; } if (LK.ticks % 45 == 0) { LK.getSound('bossbullet').play(); // Play bossbullet sound when Boss3 shoots BossBullet3 var newBullet = new BossBullet3(); newBullet.x = self.x; newBullet.y = self.y + self.height / 2; bullets.push(newBullet); game.addChild(newBullet); } }; }); var BossBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bossbullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5.5; // Increase speed by 10% self.update = function () { self.y += self.speed; self.rotation += 0.1; // Add rotation to the boss bullet if (self.y > 2732 + 50) { self.destroy(); bullets.splice(bullets.indexOf(self), 1); for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i] instanceof Boss) { enemies[i].hasActiveBullet = false; break; } } } // Logic to increase and decrease boss bullet size if (LK.ticks % 120 < 60) { self.scale.x += 0.001; self.scale.y += 0.001; } else { self.scale.x -= 0.001; self.scale.y -= 0.001; } }; }); var BossBullet2 = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bossbullet2', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.update = function () { self.y += self.speed; self.rotation += 0.1; // Add rotation to the boss bullet if (self.y > 2732 + 50) { self.destroy(); bullets.splice(bullets.indexOf(self), 1); for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i] instanceof Boss2) { enemies[i].hasActiveBullet = false; break; } } } // Logic to increase and decrease boss bullet size if (LK.ticks % 120 < 60) { self.scale.x += 0.001; self.scale.y += 0.001; } else { self.scale.x -= 0.001; self.scale.y -= 0.001; } }; }); var BossBullet3 = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('boss3bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 7; self.update = function () { self.y += self.speed; self.rotation += 0.1; // Add rotation to the boss bullet if (self.y > 2732 + 50) { self.destroy(); bullets.splice(bullets.indexOf(self), 1); for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i] instanceof Boss3) { enemies[i].hasActiveBullet = false; break; } } } if (LK.ticks % 120 < 60) { self.scale.x += 0.001; self.scale.y += 0.001; } else { self.scale.x -= 0.001; self.scale.y -= 0.001; } }; }); // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -5; // Default bullet speed, can be overridden self.update = function () { self.y += self.speed; }; }); // Diamond class var Diamond = Container.expand(function () { var self = Container.call(this); var diamondGraphics = self.attachAsset('diamond', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.update = function () { self.y += self.speed; self.rotation += 0.05; // Add rotation animation if (LK.ticks % 120 < 60) { self.scale.x += 0.002; self.scale.y += 0.002; } else { self.scale.x -= 0.002; self.scale.y -= 0.002; } if (self.y > 2732) { self.destroy(); } }; }); // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5, tint: 0xffffff // Default tint, will be overridden by wave configuration }); self.speed = 3.3; // Increase speed by 10% self.hitpoints = 3; // Add hitpoints to enemies self.update = function () { // Update tint based on hitpoints if (self.hitpoints === 12) { self.children[0].tint = 0x9400D3; // Dark Violet tint for 12 hitpoints } else if (self.hitpoints === 11) { self.children[0].tint = 0x4B0082; // Indigo tint for 11 hitpoints } else if (self.hitpoints === 10) { self.children[0].tint = 0x0000FF; // Blue tint for 10 hitpoints } else if (self.hitpoints === 9) { self.children[0].tint = 0x00FF00; // Green tint for 9 hitpoints } else if (self.hitpoints === 8) { self.children[0].tint = 0x00FFFF; // Cyan tint for 8 hitpoints } else if (self.hitpoints === 7) { self.children[0].tint = 0xFF7F00; // Orange tint for 7 hitpoints } else if (self.hitpoints === 6) { self.children[0].tint = 0xFF0000; // Red tint for 6 hitpoints } else if (self.hitpoints === 5) { self.children[0].tint = 0xFFCC00; // Light Orange tint for 5 hitpoints } else if (self.hitpoints === 4) { self.children[0].tint = 0xFF3333; // Stronger Red tint for 4 hitpoints } else if (self.hitpoints === 3) { self.children[0].tint = 0xFF6666; // Light Red tint for 3 hitpoints } else if (self.hitpoints === 2) { self.children[0].tint = 0xCC66FF; // Light Purple tint for 2 hitpoints } else if (self.hitpoints === 1) { self.children[0].tint = 0xFFE066; // Light Yellow tint for 1 hitpoint } self.y += self.speed; // Logic to increase and decrease block sizes if (LK.ticks % 120 < 60) { self.scale.x += 0.002; self.scale.y += 0.002; } else { self.scale.x -= 0.002; self.scale.y -= 0.002; } // Create and update hitpoints display if (!self.hitpointsDisplay) { self.hitpointsDisplay = new Text2(self.hitpoints.toString(), { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); self.hitpointsDisplay.anchor.set(0.5, 0.5); self.hitpointsDisplay.y = 0; self.addChild(self.hitpointsDisplay); } else if (LK.ticks % 10 === 0) { self.hitpointsDisplay.setText(self.hitpoints.toString()); } }; }); var Enemy2 = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy2', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4.4; // Increase speed by 10% self.hitpoints = 5; // Different hitpoints for Enemy2 self.randomFactorX = Math.random() * 20 + 10; // Ensure a minimum value to reduce shakiness self.randomFactorY = Math.random() * 10 + 5; // Ensure a minimum value to reduce shakiness self.stuck = false; // Initialize stuck property self.stuckTime = 0; // Initialize stuckTime property self.originalRandomFactorX = self.randomFactorX; // Store original random factor self.originalRandomFactorY = self.randomFactorY; // Store original random factor self.spawnTime = LK.ticks; self.update = function () { // Check for collisions with other Enemy2 instances for (var i = 0; i < enemies.length; i++) { if (enemies[i] !== self && enemies[i] instanceof Enemy2 && self.intersects(enemies[i])) { // Adjust position to avoid overlap if (self.x < enemies[i].x) { self.x -= 5; } else { self.x += 5; } if (self.y < enemies[i].y) { self.y -= 5; } else { self.y += 5; } } } var directionX = fairy.x - self.x; var directionY = fairy.y - self.y; var magnitude = Math.sqrt(directionX * directionX + directionY * directionY); self.x += directionX / magnitude * 2; // Move towards the fairy self.scale.x = directionX < 0 ? -1 : 1; // Mirror image when moving left self.y += self.speed + Math.sin(LK.ticks / 20) * 2; // Add small up and down movement // Adjust movement if too close to the borders if (self.x < self.width / 2 + 50) { self.x += 2; // Move right smoothly } else if (self.x > 2048 - self.width / 2 - 50) { self.x -= 2; // Move left smoothly } // Check if Enemy2 is stuck at the side of the screen if (self.x <= self.width / 2 || self.x >= 2048 - self.width / 2 && LK.ticks - self.spawnTime > 120) { if (!self.stuck) { self.stuck = true; self.stuckTime = LK.ticks; self.originalRandomFactorX = self.randomFactorX; self.randomFactorX = 180; // Move to the opposite side for at least 3 seconds } else if (LK.ticks - self.stuckTime > 120) { // 2 seconds at 60FPS self.stuck = false; self.randomFactorX = self.originalRandomFactorX; // Return to original random movement self.randomFactorY = self.originalRandomFactorY; // Return to original random movement } } else { self.stuck = false; } self.x = Math.max(Math.min(self.x, 2048 - self.width / 2), self.width / 2); // Ensure Enemy2 stays within horizontal limits if (self.y > 2732 + self.height / 2) { self.destroy(); } // Logic to increase and decrease size if (LK.ticks % 120 < 60) { self.scale.x += 0.001; self.scale.y += 0.001; } else { self.scale.x -= 0.001; self.scale.y -= 0.001; } if (self.y > 2732) { self.destroy(); } }; }); //<Assets used in the game will automatically appear here> // Fairy class var Fairy = Container.expand(function () { var self = Container.call(this); var fairyGraphics = self.attachAsset('fairy', { anchorX: 0.5, anchorY: 0.5 }); fairyGraphics.hitArea = new Rectangle(-fairyGraphics.width / 3, -fairyGraphics.height / 3, fairyGraphics.width / 1.5, fairyGraphics.height / 1.5); // Increase hitbox margin self.speed = 5; self.particles = []; self.update = function () { // Particle emitter logic if (LK.ticks % 10 === 0) { var particle = LK.getAsset('fairyemitter', { anchorX: 0.5, anchorY: 0.5, alpha: 1, scaleX: 10, scaleY: 10 }); particle.x = self.x + (self.scale.x === -1 ? 30 : -30); particle.y = self.y + self.height / 2; particle.speedX = (Math.random() - 0.5) * 1.5; particle.speedY = Math.random() * 1.5 + 0.5; // Push particles downwards particle.update = function () { this.x += this.speedX; this.y += this.speedY; this.alpha -= 0.02; if (this.alpha <= 0) { this.destroy(); } }; self.particles.push(particle); game.addChild(particle); } // Update existing particles for (var i = self.particles.length - 1; i >= 0; i--) { self.particles[i].update(); if (self.particles[i].alpha <= 0) { self.particles.splice(i, 1); } } // Fairy movement logic }; }); var HeroBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.speed = -5; self.hitpoints = 1; // Add hitpoints property to HeroBullet self.update = function () { self.y += self.speed; self.x += Math.sin(LK.ticks / 10) * 1; // Reduce sideways movement }; }); var HeroBullet2 = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('herobullet2', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -5; // Different speed for HeroBullet2 self.hitpoints = 2; // Different hitpoints for HeroBullet2 self.update = function () { self.y += self.speed; }; }); var HeroBullet3 = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('herobullet3', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -8; // Different speed for HeroBullet3 self.hitpoints = 1; // Set base damage for HeroBullet3 to 1 self.update = function () { self.y += self.speed; self.x += Math.sin(LK.ticks / 10) * 1; // Add slight sideways movement }; }); // Powerup class var Powerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.update = function () { self.y += self.speed; if (self.y > 2732) { self.destroy(); } }; }); var PowerupMenu = Container.expand(function () { var self = Container.call(this); var screenGraphics = self.attachAsset('menu', { anchorX: 0.5, anchorY: 0.5 }); screenGraphics.width = 1024 * 1.5; // Increase width by 50% screenGraphics.height = 1366 * 1.5; // Increase height by 50% screenGraphics.alpha = 0.7; screenGraphics.x = 2048 / 3 + 100; screenGraphics.y = 2732 / 3 + 50; var title = new Text2('', { size: 150, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); title.anchor.set(0.5, 0.5); title.x = screenGraphics.x; title.y = screenGraphics.y - screenGraphics.height / 2 + 150; self.x = 2048 / 2 - screenGraphics.width / 2 - 500; self.y = 2732 / 2 - screenGraphics.height / 2 - 300; self.addChild(title); var powerup1 = LK.getAsset('powerup1', { anchorX: 0.5, anchorY: 0.5 }); powerup1.x = screenGraphics.x - 300; powerup1.y = screenGraphics.y - 400; self.addChild(powerup1); powerup1.down = function (x, y, obj) { if (diamondCount >= powerupCosts.powerup1) { diamondCount -= powerupCosts.powerup1; diamondCounterTxt.setText(diamondCount); heroFireRate = Math.max(5, heroFireRate - 5); // Increase fire rate when the first powerup is selected, but not less than 5 isUsingHeroBullet3 = true; // Switch to HeroBullet3 HeroBullet.prototype.speed -= 0.3; // Increase bullet speed by 1 isUsingHeroBullet2 = false; // Ensure HeroBullet2 is not used HeroBullet2.prototype.speed = -8; // Reset HeroBullet2 speed LK.getSound('yes').play(); // Play yes sound when powerup1 is purchased self.destroy(); // Close powerup menu isPowerupScreenActive = false; if (currentLevelIndex < levels.length - 1) { currentLevelIndex++; currentLevel = levels[currentLevelIndex]; } else { currentLevelIndex = 0; currentLevel = levels[currentLevelIndex]; levels.forEach(function (level) { level.waves.forEach(function (wave) { wave.hitpoints = wave.hitpoints.map(function (hitpoint) { return hitpoint * 2; }); wave.speed = wave.speed ? wave.speed * 2 : 2; // Double the speed of enemies }); }); bullets.forEach(function (bullet) { bullet.speed *= 2; // Double the speed of bullets }); } currentLevel.currentWaveIndex = 0; // Reset the current wave index to start from the first wave } else { LK.getSound('nono').play(); // Play nono sound when player can't purchase powerup1 var message = new Text2("I need ".concat(powerupCosts.powerup1 - diamondCount, " more diamonds for this powerup!"), { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); message.anchor.set(0.5, 1.0); message.x = 2048 / 2; message.y = 2732 - 50; game.addChild(message); LK.setTimeout(function () { message.destroy(); }, 2000); } }; var powerup1DiamondIcon = LK.getAsset('diamond', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); powerup1DiamondIcon.x = powerup1.x; powerup1DiamondIcon.y = powerup1.y + powerup1.height / 2 + 50; self.addChild(powerup1DiamondIcon); var powerup1Cost = new Text2('5', { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); powerup1Cost.anchor.set(0.5, 0); powerup1Cost.x = powerup1.x; powerup1Cost.y = powerup1DiamondIcon.y + powerup1DiamondIcon.height / 2 - 20; self.addChild(powerup1Cost); var powerup2 = LK.getAsset('powerup2', { anchorX: 0.5, anchorY: 0.5 }); powerup2.x = screenGraphics.x; powerup2.y = screenGraphics.y - 400; self.addChild(powerup2); powerup2.down = function (x, y, obj) { if (diamondCount >= powerupCosts.powerup2) { diamondCount -= powerupCosts.powerup2; diamondCounterTxt.setText(diamondCount); // Add action for powerup3 isUsingHeroBullet2 = true; // Switch to HeroBullet2 isUsingHeroBullet3 = false; // Ensure HeroBullet3 is not used // HeroBullet.prototype.speed = -5; // Reset HeroBullet speed heroFireRate = Math.max(5, heroFireRate - 5); // Increase fire rate when the second powerup is selected, but not less than 5 HeroBullet2.prototype.hitpoints *= 1.2; // Increase hit points by 20% LK.getSound('yes').play(); // Play yes sound when powerup2 is purchased self.destroy(); // Close powerup menu isPowerupScreenActive = false; // Increase level when a powerup is selected if (currentLevelIndex < levels.length - 1) { currentLevelIndex++; currentLevel = levels[currentLevelIndex]; } else { currentLevelIndex = 0; currentLevel = levels[currentLevelIndex]; levels.forEach(function (level) { level.waves.forEach(function (wave) { wave.hitpoints = wave.hitpoints.map(function (hitpoint) { return hitpoint * 1.2; // Increase hitpoints by 20% }); wave.speed = wave.speed ? wave.speed * 1.5 : 1.5; // Increase speed by 50% }); }); bullets.forEach(function (bullet) { bullet.speed *= 1.5; // Increase bullet speed by 50% }); } } else { LK.getSound('nono').play(); // Play nono sound when player can't purchase powerup2 var message = new Text2("I need ".concat(powerupCosts.powerup2 - diamondCount, " more diamonds for this powerup!"), { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); message.anchor.set(0.5, 1.0); message.x = 2048 / 2; message.y = 2732 - 50; game.addChild(message); LK.setTimeout(function () { message.destroy(); }, 2000); } }; var powerup2DiamondIcon = LK.getAsset('diamond', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); powerup2DiamondIcon.x = powerup2.x; powerup2DiamondIcon.y = powerup2.y + powerup2.height / 2 + 50; self.addChild(powerup2DiamondIcon); var powerup2Cost = new Text2('5', { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); powerup2Cost.anchor.set(0.5, 0); powerup2Cost.x = powerup2.x; powerup2Cost.y = powerup2DiamondIcon.y + powerup2DiamondIcon.height / 2 - 20; self.addChild(powerup2Cost); var powerup3 = LK.getAsset('powerup3', { anchorX: 0.5, anchorY: 0.5 }); powerup3.x = screenGraphics.x + 300; powerup3.y = screenGraphics.y - 400; self.addChild(powerup3); powerup3.down = function (x, y, obj) { if (diamondCount >= powerupCosts.powerup3) { diamondCount -= powerupCosts.powerup3; diamondCounterTxt.setText(diamondCount); // Add action for powerup3 shield = game.addChild(new Shield()); // Add shield only when powerup3 is selected LK.getSound('yes').play(); // Play yes sound when powerup3 is purchased self.destroy(); // Close powerup menu isPowerupScreenActive = false; // Increase level when a powerup is selected if (currentLevelIndex < levels.length - 1) { currentLevelIndex++; currentLevel = levels[currentLevelIndex]; } else { currentLevelIndex = 0; currentLevel = levels[currentLevelIndex]; } } else { LK.getSound('nono').play(); // Play nono sound when player can't purchase powerup3 var message = new Text2("I need ".concat(powerupCosts.powerup3 - diamondCount, " more diamonds for this powerup!"), { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); message.anchor.set(0.5, 1.0); message.x = 2048 / 2; message.y = 2732 - 50; game.addChild(message); LK.setTimeout(function () { message.destroy(); }, 2000); } }; var powerup3DiamondIcon = LK.getAsset('diamond', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); powerup3DiamondIcon.x = powerup3.x; powerup3DiamondIcon.y = powerup3.y + powerup3.height / 2 + 50; self.addChild(powerup3DiamondIcon); var powerup3Cost = new Text2('10', { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); powerup3Cost.anchor.set(0.5, 0); powerup3Cost.x = powerup3.x; powerup3Cost.y = powerup3DiamondIcon.y + powerup3DiamondIcon.height / 2 - 20; self.addChild(powerup3Cost); var closeButton = new Text2('Maybe next time!', { size: 100, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); closeButton.anchor.set(0.5, 0.5); closeButton.x = screenGraphics.x; closeButton.y = screenGraphics.y + screenGraphics.height / 2 - 300; self.addChild(closeButton); // Add animation to 'Maybe next time!' text closeButton.update = function () { if (LK.ticks % 120 < 60) { closeButton.scale.x += 0.005; closeButton.scale.y += 0.005; } else { closeButton.scale.x -= 0.005; closeButton.scale.y -= 0.005; } }; closeButton.down = function (x, y, obj) { self.destroy(); // Close powerup menu isPowerupScreenActive = false; if (currentLevelIndex < levels.length - 1) { currentLevelIndex++; currentLevel = levels[currentLevelIndex]; } else { // Reset to first level and double enemy hitpoints currentLevelIndex = 0; currentLevel = levels[currentLevelIndex]; levels.forEach(function (level) { level.waves.forEach(function (wave) { wave.hitpoints = wave.hitpoints.map(function (hitpoint) { return hitpoint * 2; }); wave.speed = wave.speed ? wave.speed * 2 : 2; // Double the speed of enemies }); }); bullets.forEach(function (bullet) { bullet.speed *= 2; // Double the speed of bullets }); } }; self.down = function (x, y, obj) { var localPos = self.toLocal(obj.global); if (powerup1.intersects(self.toLocal(obj.global)) || powerup2.intersects(self.toLocal(obj.global)) || powerup3.intersects(self.toLocal(obj.global))) { if (powerup1.intersects(self.toLocal(obj.global)) && diamondCount >= 5) { diamondCount -= 10; diamondCounterTxt.setText(diamondCount); heroFireRate = Math.max(5, heroFireRate - 5); // Increase fire rate when the first powerup is selected, but not less than 5 self.destroy(); // Close powerup menu isPowerupScreenActive = false; } else if (powerup2.intersects(self.toLocal(obj.global)) && diamondCount >= 5) { diamondCount -= 20; diamondCounterTxt.setText(diamondCount); // Add action for powerup2 self.destroy(); // Close powerup menu isPowerupScreenActive = false; } else if (powerup3.intersects(self.toLocal(obj.global)) && diamondCount >= 10) { diamondCount -= 30; diamondCounterTxt.setText(diamondCount); // Add action for powerup3 self.destroy(); // Close powerup menu isPowerupScreenActive = false; } else { var messageText = 'I need more shiny things!'; if (powerup1.intersects(self.toLocal(obj.global)) && diamondCount < 5) { messageText = 'I need 5 diamonds for this powerup!'; } else if (powerup2.intersects(self.toLocal(obj.global)) && diamondCount < 5) { messageText = 'I need 5 diamonds for this powerup!'; } else if (powerup3.intersects(self.toLocal(obj.global)) && diamondCount < 10) { messageText = 'I need 10 diamonds for this powerup!'; } var message = new Text2(messageText, { size: 100, fill: "#ff0000", stroke: "#000000", strokeThickness: 5 }); message.anchor.set(0.5, 0.5); message.x = 2048 / 2; message.y = 2732 / 2; game.addChild(message); LK.setTimeout(function () { message.destroy(); }, 2000); } } else if (closeButton.intersects(self.toLocal(obj.global))) { self.destroy(); // Close powerup menu isPowerupScreenActive = false; if (currentLevelIndex < levels.length) { currentLevelIndex++; currentLevel = levels[currentLevelIndex]; } else { currentLevelIndex = 0; currentLevel = levels[currentLevelIndex]; levels.forEach(function (level) { level.waves.forEach(function (wave) { wave.hitpoints = wave.hitpoints.map(function (hitpoint) { return hitpoint * 2; }); wave.speed = wave.speed ? wave.speed * 2 : 2; // Double the speed of enemies }); }); bullets.forEach(function (bullet) { bullet.speed *= 2; // Double the speed of bullets }); } currentLevel.currentWaveIndex = 0; // Reset the current wave index to start from the first wave } }; }); var Shield = Container.expand(function () { var self = Container.call(this); var shieldGraphics = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.update = function () { self.x = fairy.x; self.y = fairy.y; self.zIndex = fairy.zIndex + 1; // Ensure shield is rendered on top of fairy }; }); // Star class var Star = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.update = function () { if (LK.ticks % 2 === 0) { // Update every 2 ticks self.y += self.speed; if (self.y > 2732) { self.y = -5; self.x = Math.random() * 2048; } } }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x800080 //Init game with purple background }); /**** * Game Code ****/ // Configuration for powerup costs LK.effects.shakeObject = function (object, intensity, duration) { var originalX = object.x; var originalY = object.y; var shakeInterval = LK.setInterval(function () { object.x = originalX + (Math.random() - 0.5) * intensity; object.y = originalY + (Math.random() - 0.5) * intensity; }, 16); // Shake every frame (16ms for 60FPS) LK.setTimeout(function () { LK.clearInterval(shakeInterval); object.x = originalX; object.y = originalY; }, duration); }; var bossSpawnCount = 0; var boss2SpawnCount = 0; var boss3SpawnCount = 0; var bossSpeedIncrement = 0; // Global variable to track boss speed increment var powerupCosts = { powerup1: 5, powerup2: 5, powerup3: 10 }; var Level = function Level(config, levelNumber) { this.waves = config.waves; this.currentWaveIndex = 0; this.boss = config.boss; this.levelNumber = levelNumber; }; Level.prototype.getNextWave = function () { if (this.currentWaveIndex < this.waves.length) { return this.waves[this.currentWaveIndex++]; } else { return null; } }; Level.prototype.hasBoss = function () { return this.boss && this.currentWaveIndex >= this.waves.length; }; var levels = [new Level({ waves: [{ enemies: 6, hitpoints: [1], tints: [0xffe066] }, { enemies: 6, hitpoints: [1, 2], tints: [0xcc66ff, 0xffe066] }, { enemies: 9, hitpoints: [1, 2, 3], tints: [0xcc66ff, 0xffe066] }, { enemies: 9, hitpoints: [2, 3, 4], tints: [0xcc66ff, 0xffe066] }], boss: true }, 1), new Level({ waves: [{ enemies: 6, hitpoints: [3, 4], tints: [0x66ff66] }, { enemies: 9, hitpoints: [3, 4, 5], tints: [0x66ccff, 0x66ff66] }, { enemies: 9, hitpoints: [3, 4, 5], tints: [0x66ccff, 0x66ff66] }, { enemies: 9, hitpoints: [4, 5, 6], tints: [0x66ccff, 0x66ff66] }], boss: true }, 2), new Level({ waves: [{ enemies: 9, hitpoints: [5, 6, 7], tints: [0xff9933] }, { enemies: 9, hitpoints: [6,, 7, 8], tints: [0xffcc00, 0xff9933] }, { enemies: 9, hitpoints: [8, 9, 10], tints: [0xff6600, 0xffcc00, 0xff9933] }, { enemies: 9, hitpoints: [6, 6, 6], tints: [0xff6600, 0xffcc00, 0xff9933] }], boss: true }, 3)]; var currentLevelIndex = 0; var currentLevel = levels[currentLevelIndex]; // Initialize variables var isUsingHeroBullet2 = false; // Flag to track if HeroBullet2 is being used var isUsingHeroBullet3 = false; // Flag to track if HeroBullet3 is being used var fairy; var bullets = []; var enemies = []; var scoreTxt; var score = 0; var dragNode = null; var heroFireRate = 30; // Default fire rate for hero bullets var defaultHeroFireRate = 30; // Store the default fire rate var diamondCount = 0; // Initialize diamond counter with 0 diamonds var diamondCounterTxt; // Declare diamondCounterTxt variable var isFairyHeld = false; // Track if the fairy is being held var shield = null; // Initialize shield variable var isPowerupScreenActive = false; // Track if the powerup screen is active var deathSoundPlayed = false; // Flag to track if the death sound has been played var waveCount = 0; // Track the wave count var waveConfig = [{ enemies: 3, hitpoints: [1], tints: [0xffe066] } /**** , { enemies: 6, hitpoints: [2, 1], tints: [0xcc66ff, 0xffe066] } , { enemies: 9, hitpoints: [3, 2, 1], tints: [0xff6666, 0xcc66ff, 0xffe066] } ****/ // Add more wave configurations as needed ]; // Initialize game elements function initGame() { // Play 'letsgo' sound one second after the game starts LK.setTimeout(function () { LK.getSound('letsgo').play(); }, 1000); // Play background music on loop var backgroundMusic = LK.getSound('backgroundmusic'); backgroundMusic.loop = true; backgroundMusic.play(); // Create and position the fairy fairy = game.addChild(new Fairy()); fairy.particles = []; fairy.x = 2048 / 2; fairy.y = 2732 - 400; // Create score text scoreTxt = new Text2('0', { size: 200, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); scoreTxt.anchor.set(0.5, 0); // Anchor to the top center scoreTxt.x = 2048 / 2; // Position at the top center of the screen scoreTxt.y = 20; // Position with a margin from the top for (var i = 0; i < 30; i++) { var star = game.addChild(new Star()); star.x = Math.random() * 2048; star.y = Math.random() * 2732; star.speed = 3 + Math.random() * 2; // Randomize speed between 3 and 5 } scoreTxt.anchor.set(0.5, 0); // Create coin counter text game.addChild(scoreTxt); // Create coin counter text // Removed menu background from the top of the screen where score and diamonds are var diamondCounterContainer = new Container(); var diamondIcon = LK.getAsset('diamond', { anchorX: 1, anchorY: 0, alpha: 0.8, scaleX: 1.4, scaleY: 1.4 }); diamondIcon.x = 2048 - 100; diamondIcon.y = 20; diamondCounterContainer.addChild(diamondIcon); diamondCounterTxt = new Text2('0', { size: 120, fill: "#ffffff", stroke: "#000000", strokeThickness: 5 }); diamondCounterTxt.anchor.set(0.5, 0.5); diamondCounterTxt.x = diamondIcon.x + diamondIcon.width / 2 - 230; diamondCounterTxt.y = diamondIcon.y + diamondIcon.height / 2 + 15; diamondCounterContainer.addChild(diamondCounterTxt); game.addChild(diamondCounterContainer); // Set up game event listeners game.down = function (x, y, obj) { dragNode = fairy; isFairyHeld = true; // Set isFairyHeld to true when the fairy is held }; game.up = function (x, y, obj) { dragNode = null; isFairyHeld = false; // Set isFairyHeld to false when the fairy is released }; game.move = handleMove; // Update game every tick game.update = updateGame; } // Handle move events function handleMove(x, y, obj) { if (dragNode && fairy.parent) { // Check if the fairy is moving to the right if (x > dragNode.x) { // Mirror the fairy image dragNode.scale.x = -1; } else { // Reset the fairy image dragNode.scale.x = 1; } // Create a ghost image of the fairy when it moves every other frame if (LK.ticks % 4 === 0) { var ghostFairy = LK.getAsset('fairy', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); ghostFairy.x = dragNode.x; ghostFairy.y = dragNode.y; if (dragNode.parent === game) { game.addChildAt(ghostFairy, game.getChildIndex(dragNode)); } else { game.addChild(ghostFairy); } if (dragNode.scale.x === -1) { ghostFairy.scale.x = -1; } // Remove the ghost image after 0.5 seconds LK.setTimeout(function () { ghostFairy.destroy(); }, 250); } dragNode.x += (x - dragNode.x) * 0.1; if (y > 2732 * 0.5) { dragNode.y += (y - dragNode.y) * 0.1; } else { dragNode.y += (2732 * 0.5 - dragNode.y) * 0.1; } } } // Update game logic function updateGame() { // Update 'Maybe next time!' text if it exists if (typeof closeButton !== 'undefined' && closeButton.update) { closeButton.update(); } // Check if background music is playing, if not, play it var backgroundMusic = LK.getSound('backgroundmusic'); if (LK.ticks % 600 === 0) { // Every 10 seconds (600 ticks at 60FPS) backgroundMusic.play(); } if (LK.ticks % 300 === 0) { // Every 5 seconds (300 ticks at 60FPS) bossSpeedIncrement += 1; // Increase boss speed increment } if (currentLevel) {} else {} // Update starfield for (var i = game.children.length - 1; i >= 0; i--) { if (game.children[i] instanceof Star) { game.children[i].update(); } if (game.children[i] instanceof Diamond && game.children[i].intersects(fairy)) { game.children[i].destroy(); diamondCount++; diamondCounterTxt.setText(diamondCount); LK.getSound('diamondcollect').play(); // Play diamondcollect sound when a diamond is collected } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { if (bullets[i] instanceof Bullet) { bullets[i].update(); } bullets[i].update(); if (bullets[i] && bullets[i].y < -50) { bullets[i].destroy(); bullets.splice(i, 1); } } for (var j = enemies.length - 1; j >= 0; j--) { enemies[j].update(); if (enemies[j].y > 2732 + 50) { enemies[j].destroy(); enemies.splice(j, 1); } if (shield && shield.intersects(enemies[j])) { shield.destroy(); LK.getSound('boom').play(); // Play boom sound when shield is destroyed shield = null; enemies[j].destroy(); score += enemies[j].hitpoints * 10; // Add points based on enemy hitpoints scoreTxt.setText(score); // Update score text enemies.splice(j, 1); } else if (fairy.intersects(enemies[j], { margin: 20 })) { var fairyX = fairy.x; var fairyY = fairy.y; // Create particle effect for fairy for (var p = 0; p < 5; p++) { var particle = LK.getAsset('star', { anchorX: 0.5, anchorY: 0.5, alpha: 1, scaleX: 4, scaleY: 4, tint: Math.random() < 0.5 ? 0xffb6c1 : 0x98fb98 // Softer Pink or Green tint }); particle.x = fairyX; particle.y = fairyY; particle.speedX = (Math.random() - 0.5) * 20; particle.speedY = (Math.random() - 0.5) * 20; particle.update = function () { this.x += this.speedX; this.y += this.speedY; this.alpha -= 0.01; if (this.alpha <= 0) { this.destroy(); } }; game.addChild(particle); } // Play death sound and destroy fairy asset when destroyed by enemy if (!deathSoundPlayed) { LK.getSound('death').play(); deathSoundPlayed = true; } fairy.speed = 0; // Stop fairy movement fairy.destroy(); dragNode = null; // Prevent dragging the fairy ghost // Destroy all fairy ghosts for (var i = game.children.length - 1; i >= 0; i--) { if (game.children[i].alpha === 0.3 && game.children[i].width === fairy.width && game.children[i].height === fairy.height) { game.children[i].destroy(); } } LK.setTimeout(function () { LK.showGameOver(); }, 2000); } for (var k = bullets.length - 1; k >= 0; k--) { if ((bullets[k] instanceof HeroBullet || bullets[k] instanceof HeroBullet2 || bullets[k] instanceof HeroBullet3) && bullets[k].intersects(enemies[j])) { if (enemies[j] instanceof Enemy2 || enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) { // Shake effect for Enemy2 and Bosses LK.effects.shakeObject(enemies[j], 5, 100); // Shake with intensity 5 for 100ms } LK.getSound('hit').play(); // Play hit sound when HeroBullet, HeroBullet2, or HeroBullet3 is destroyed bullets[k].destroy(); bullets.splice(k, 1); enemies[j].hitpoints -= bullets[k] instanceof HeroBullet2 ? 2 : bullets[k] instanceof HeroBullet3 ? 3 : 1; if (enemies[j].hitpoints <= 0) { var enemyX = enemies[j].x; var enemyY = enemies[j].y; // Create particle effect for (var p = 0; p < 50; p++) { var particle = LK.getAsset('star', { anchorX: 0.5, anchorY: 0.5, alpha: 1, scaleX: 4, scaleY: 4, tint: enemies[j] instanceof Enemy2 ? 0x000000 : enemies[j].children[0].tint }); particle.x = enemyX; particle.y = enemyY; particle.speedX = (Math.random() - 0.5) * 20; particle.speedY = (Math.random() - 0.5) * 20; particle.update = function () { this.x += this.speedX; this.y += this.speedY; this.alpha -= 0.01; if (this.alpha <= 0) { this.destroy(); } }; game.addChild(particle); } enemies[j].destroy(); LK.getSound('boom').play(); if (enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) { score += 200; // Add 200 points when a boss is destroyed } if (enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) { bossSpeedIncrement = 0; // Reset boss speed increment when a boss is killed LK.effects.flashScreen(0xff0000, 1000); // Flash screen red for 1 second LK.getSound('hooray').play(); // Play hooray sound when a boss is destroyed // Destroy all boss bullets for (var b = bullets.length - 1; b >= 0; b--) { if (bullets[b] instanceof BossBullet || bullets[b] instanceof BossBullet2 || bullets[b] instanceof BossBullet3) { bullets[b].destroy(); bullets.splice(b, 1); } } var powerupMenu = new PowerupMenu(); powerupMenu.x = 2048 / 2 - powerupMenu.width / 2; powerupMenu.y = 2732 / 2 - powerupMenu.height / 2; game.addChild(powerupMenu); isPowerupScreenActive = true; score += 200; // Add 200 points when a boss is destroyed } if (enemies[j] instanceof Enemy2) { score += 50; // Add 50 points when an Enemy2 is destroyed } enemies.splice(j, 1); if (enemies[j]) { if (enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) { score += enemies[j].hitpoints * 10; } else { score += enemies[j].hitpoints * 10; } } scoreTxt.setText(score); var dropChance = Math.random(); if (dropChance < 0.2) { var newDiamond = new Diamond(); newDiamond.x = enemyX; newDiamond.y = enemyY; game.addChild(newDiamond); } else if (dropChance < 0.2) { var newPowerup = new Powerup(); newPowerup.x = enemyX; newPowerup.y = enemyY; game.addChild(newPowerup); } } break; } else if ((bullets[k] instanceof BossBullet || bullets[k] instanceof BossBullet2 || bullets[k] instanceof BossBullet3) && bullets[k].intersects(fairy, { margin: 20 })) { if (shield) { shield.destroy(); LK.getSound('boom').play(); // Play boom sound when shield is destroyed shield = null; } else { var fairyX = fairy.x; var fairyY = fairy.y; // Create particle effect for fairy for (var p = 0; p < 50; p++) { var particle = LK.getAsset('star', { anchorX: 0.5, anchorY: 0.5, alpha: 1, scaleX: 4, scaleY: 4, tint: Math.random() < 0.5 ? 0xffb6c1 : 0x98fb98 // Softer Pink or Green tint }); particle.x = fairyX; particle.y = fairyY; particle.speedX = (Math.random() - 0.5) * 20; particle.speedY = (Math.random() - 0.5) * 20; particle.update = function () { this.x += this.speedX; this.y += this.speedY; this.alpha -= 0.02; if (this.alpha <= 0) { this.destroy(); } }; game.addChild(particle); } // Play death sound and destroy fairy asset when destroyed by BossBullet if (!deathSoundPlayed) { LK.getSound('death').play(); deathSoundPlayed = true; } fairy.speed = 0; // Stop fairy movement fairy.destroy(); dragNode = null; // Prevent dragging the fairy ghost // Destroy all fairy ghosts for (var i = game.children.length - 1; i >= 0; i--) { if (game.children[i].alpha === 0.3 && game.children[i].width === fairy.width && game.children[i].height === fairy.height) { game.children[i].destroy(); } } LK.setTimeout(function () { LK.showGameOver(); }, 2000); } bullets[k].destroy(); bullets.splice(k, 1); } } } // Check for collisions // Check for coin collection for (var i = game.children.length - 1; i >= 0; i--) { if (game.children[i] instanceof Diamond && game.children[i].intersects(fairy)) { game.children[i].destroy(); diamondCount++; diamondCounterTxt.setText('Diamonds: ' + diamondCount); } } for (var k = bullets.length - 1; k >= 0; k--) { for (var l = enemies.length - 1; l >= 0; l--) { if ((bullets[k] instanceof HeroBullet || bullets[k] instanceof HeroBullet3) && bullets[k].intersects(enemies[l])) { LK.getSound('hit').play(); // Play hit sound when HeroBullet or HeroBullet3 is destroyed bullets[k].destroy(); bullets.splice(k, 1); enemies[l].hitpoints -= bullets[k] instanceof HeroBullet3 ? 3 : 1; if (enemies[l].hitpoints <= 0) { var enemyX = enemies[l].x; var enemyY = enemies[l].y; enemies[l].destroy(); LK.getSound('boom').play(); enemies.splice(l, 1); if (enemies[l]) { score += enemies[l].hitpoints * 10; // Add points based on enemy hitpoints } scoreTxt.setText(score); // Update score text // Randomly drop coins or powerups var dropChance = Math.random(); if (dropChance < 0.2) { var newDiamond = new Diamond(); newDiamond.x = enemyX; newDiamond.y = enemyY; game.addChild(newDiamond); } else if (dropChance < 0.2) { var newPowerup = new Powerup(); newPowerup.x = enemyX; newPowerup.y = enemyY; game.addChild(newPowerup); } } break; } } } // Spawn new bullets if (LK.ticks % heroFireRate == 0 && isFairyHeld) { // Only spawn new bullets if the fairy is being held var newBullet; if (isUsingHeroBullet3) { newBullet = new HeroBullet3(); newBullet.attachAsset('herobullet3', { anchorX: 0.5, anchorY: 0.5 }); } else if (isUsingHeroBullet2) { newBullet = new HeroBullet2(); newBullet.attachAsset('herobullet2', { anchorX: 0.5, anchorY: 0.5 }); } else { newBullet = new HeroBullet(); } newBullet.x = fairy.x; newBullet.y = fairy.y - fairy.height / 2; bullets.push(newBullet); game.addChild(newBullet); // Play shoot sound when a HeroBullet is shot LK.getSound('shoot').play(); } // Spawn new enemies in a line if (LK.ticks % 720 == 0 && !isPowerupScreenActive) { if (enemies.length === 0) { waveCount++; } if (currentLevel) { var currentWave = currentLevel.getNextWave(); if (currentWave) { var maxEnemiesPerLine = 3; var enemySpacing = 2048 / (maxEnemiesPerLine + 1); // Adjust spacing to center enemies var totalRows = Math.ceil(currentWave.enemies / maxEnemiesPerLine); for (var i = 0; i < currentWave.enemies; i++) { var newBlock = new Enemy(); var row = Math.floor(i / maxEnemiesPerLine); newBlock.hitpoints = currentWave.hitpoints[row] || currentWave.hitpoints[currentWave.hitpoints.length - 1]; newBlock.x = i % maxEnemiesPerLine * enemySpacing + enemySpacing / 2 - newBlock.width / 2; newBlock.y = -newBlock.height - row * 220; // Spawn offscreen and start appearing down from the top newBlock.children[0].tint = currentWave.tints[row] || currentWave.tints[currentWave.tints.length - 1]; enemies.push(newBlock); game.addChild(newBlock); } // Spawn Enemy2 based on the level number after the wave with a delay of 5 seconds LK.setTimeout(function () { for (var i = 0; i < currentLevel.levelNumber; i++) { var newEnemy2 = new Enemy2(); newEnemy2.x = Math.random() * 2048; newEnemy2.y = -newEnemy2.height - 100; // Spawn offscreen and start appearing down from the top enemies.push(newEnemy2); game.addChild(newEnemy2); } }, 5000); // Center the rows of enemies var totalWidth = (Math.min(currentWave.enemies, maxEnemiesPerLine) - 1) * enemySpacing; var offsetX = (2048 - totalWidth) / 2; for (var j = 0; j < enemies.length; j++) { enemies[j].x += offsetX - enemies[j].width / 2; } } else if (currentLevel.hasBoss() && enemies.length === 0) { var boss; if (currentLevel.levelNumber === 3) { boss = new Boss3(); } else if (currentLevel.levelNumber === 2) { boss = new Boss2(); } else { boss = new Boss(); } boss.x = 2048 / 2; boss.y = -boss.height - 100; // Spawn offscreen and start appearing down from the top boss.hitpoints *= 1.5; // Increase boss hitpoints by 50% boss.speed *= 1.5; // Increase boss speed by 50% enemies.push(boss); game.addChild(boss); LK.getSound('bossappear').play(); // Play bossappear sound when Boss is spawned LK.effects.flashScreen(0xffffff, 500); // Flash screen white for 500ms LK.setTimeout(function () { LK.effects.flashScreen(0xffffff, 500); // Flash screen white again for 500ms }, 600); // Delay the second flash by 600ms to allow a brief pause } } } } // Initialize the game initGame();
/****
* Classes
****/
// Global counter for Boss spawns
var Boss = Container.expand(function () {
var self = Container.call(this);
bossSpawnCount++; // Increment the counter each time a Boss is spawned
var bossGraphics = self.attachAsset('boss1', {
anchorX: 0.5,
anchorY: 0.5
// Removed tint for the boss
});
self.speed = 2 * bossSpawnCount;
self.hitpoints = 15 * bossSpawnCount; // High hitpoints for the boss
self.update = function () {
self.x += Math.sin(LK.ticks / 30) * (5 + bossSpeedIncrement); // Sideways movement
self.y += Math.cos(LK.ticks / 50) * 3; // Top-down movement
self.x = Math.max(Math.min(self.x, 2048 + self.width * 0.25), -self.width * 0.25); // Allow part of the body outside the screen horizontally
self.y = Math.max(Math.min(self.y, 2732 * 0.4), self.height / 2); // Keep within top 40% of the screen
if (Math.sin(LK.ticks / 30) < 0) {
self.scale.x = -1; // Mirror image when moving left
} else {
self.scale.x = 1; // Normal image when moving right
}
// Logic to increase and decrease boss size
if (LK.ticks % 120 < 60) {
self.scale.x += 0.001;
self.scale.y += 0.001;
} else {
self.scale.x -= 0.001;
self.scale.y -= 0.001;
}
if (LK.ticks % 60 == 0) {
LK.getSound('bossbullet').play(); // Play bossbullet sound when Boss shoots BossBullet
// Shoot bullets every second
var newBullet = new BossBullet();
newBullet.x = self.x;
newBullet.y = self.y + self.height / 2;
bullets.push(newBullet);
game.addChild(newBullet);
}
};
});
// Global counter for Boss2 spawns
var Boss2 = Container.expand(function () {
var self = Container.call(this);
boss2SpawnCount++; // Increment the counter each time a Boss2 is spawned
var bossGraphics = self.attachAsset('boss2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3 * boss2SpawnCount;
self.hitpoints = 25 * boss2SpawnCount; // Higher hitpoints for the second boss
self.update = function () {
self.x += Math.sin(LK.ticks / 30) * (5 + bossSpeedIncrement); // Sideways movement
self.y += Math.cos(LK.ticks / 50) * 3; // Top-down movement
self.x = Math.max(Math.min(self.x, 2048 + self.width * 0.25), -self.width * 0.25); // Allow part of the body outside the screen horizontally
self.y = Math.max(Math.min(self.y, 2732 * 0.4), self.height / 2); // Keep within top 40% of the screen
if (Math.sin(LK.ticks / 30) < 0) {
self.scale.x = -1; // Mirror image when moving left
} else {
self.scale.x = 1; // Normal image when moving right
}
if (LK.ticks % 120 < 60) {
self.scale.x += 0.001;
self.scale.y += 0.001;
} else {
self.scale.x -= 0.001;
self.scale.y -= 0.001;
}
if (LK.ticks % 40 == 0) {
LK.getSound('bossbullet').play(); // Play bossbullet sound when Boss2 shoots BossBullet2
var newBullet = new BossBullet2();
newBullet.x = self.x;
newBullet.y = self.y + self.height / 2;
bullets.push(newBullet);
game.addChild(newBullet);
}
};
});
// Global counter for Boss3 spawns
var Boss3 = Container.expand(function () {
var self = Container.call(this);
boss3SpawnCount++; // Increment the counter each time a Boss3 is spawned
var bossGraphics = self.attachAsset('boss3', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4 * boss3SpawnCount;
self.hitpoints = 35 * boss3SpawnCount; // Higher hitpoints for the third boss
self.update = function () {
self.x += Math.sin(LK.ticks / 30) * (5 + bossSpeedIncrement); // Sideways movement
self.y += Math.cos(LK.ticks / 50) * 3; // Top-down movement
self.x = Math.max(Math.min(self.x, 2048 + self.width * 0.25), -self.width * 0.25); // Allow part of the body outside the screen horizontally
self.y = Math.max(Math.min(self.y, 2732 * 0.4), self.height / 2); // Keep within top 40% of the screen
if (Math.sin(LK.ticks / 30) < 0) {
self.scale.x = -1; // Mirror image when moving left
} else {
self.scale.x = 1; // Normal image when moving right
}
if (LK.ticks % 120 < 60) {
self.scale.x += 0.001;
self.scale.y += 0.001;
} else {
self.scale.x -= 0.001;
self.scale.y -= 0.001;
}
if (LK.ticks % 45 == 0) {
LK.getSound('bossbullet').play(); // Play bossbullet sound when Boss3 shoots BossBullet3
var newBullet = new BossBullet3();
newBullet.x = self.x;
newBullet.y = self.y + self.height / 2;
bullets.push(newBullet);
game.addChild(newBullet);
}
};
});
var BossBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bossbullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5.5; // Increase speed by 10%
self.update = function () {
self.y += self.speed;
self.rotation += 0.1; // Add rotation to the boss bullet
if (self.y > 2732 + 50) {
self.destroy();
bullets.splice(bullets.indexOf(self), 1);
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] instanceof Boss) {
enemies[i].hasActiveBullet = false;
break;
}
}
}
// Logic to increase and decrease boss bullet size
if (LK.ticks % 120 < 60) {
self.scale.x += 0.001;
self.scale.y += 0.001;
} else {
self.scale.x -= 0.001;
self.scale.y -= 0.001;
}
};
});
var BossBullet2 = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bossbullet2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.update = function () {
self.y += self.speed;
self.rotation += 0.1; // Add rotation to the boss bullet
if (self.y > 2732 + 50) {
self.destroy();
bullets.splice(bullets.indexOf(self), 1);
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] instanceof Boss2) {
enemies[i].hasActiveBullet = false;
break;
}
}
}
// Logic to increase and decrease boss bullet size
if (LK.ticks % 120 < 60) {
self.scale.x += 0.001;
self.scale.y += 0.001;
} else {
self.scale.x -= 0.001;
self.scale.y -= 0.001;
}
};
});
var BossBullet3 = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('boss3bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 7;
self.update = function () {
self.y += self.speed;
self.rotation += 0.1; // Add rotation to the boss bullet
if (self.y > 2732 + 50) {
self.destroy();
bullets.splice(bullets.indexOf(self), 1);
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] instanceof Boss3) {
enemies[i].hasActiveBullet = false;
break;
}
}
}
if (LK.ticks % 120 < 60) {
self.scale.x += 0.001;
self.scale.y += 0.001;
} else {
self.scale.x -= 0.001;
self.scale.y -= 0.001;
}
};
});
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -5; // Default bullet speed, can be overridden
self.update = function () {
self.y += self.speed;
};
});
// Diamond class
var Diamond = Container.expand(function () {
var self = Container.call(this);
var diamondGraphics = self.attachAsset('diamond', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.update = function () {
self.y += self.speed;
self.rotation += 0.05; // Add rotation animation
if (LK.ticks % 120 < 60) {
self.scale.x += 0.002;
self.scale.y += 0.002;
} else {
self.scale.x -= 0.002;
self.scale.y -= 0.002;
}
if (self.y > 2732) {
self.destroy();
}
};
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xffffff // Default tint, will be overridden by wave configuration
});
self.speed = 3.3; // Increase speed by 10%
self.hitpoints = 3; // Add hitpoints to enemies
self.update = function () {
// Update tint based on hitpoints
if (self.hitpoints === 12) {
self.children[0].tint = 0x9400D3; // Dark Violet tint for 12 hitpoints
} else if (self.hitpoints === 11) {
self.children[0].tint = 0x4B0082; // Indigo tint for 11 hitpoints
} else if (self.hitpoints === 10) {
self.children[0].tint = 0x0000FF; // Blue tint for 10 hitpoints
} else if (self.hitpoints === 9) {
self.children[0].tint = 0x00FF00; // Green tint for 9 hitpoints
} else if (self.hitpoints === 8) {
self.children[0].tint = 0x00FFFF; // Cyan tint for 8 hitpoints
} else if (self.hitpoints === 7) {
self.children[0].tint = 0xFF7F00; // Orange tint for 7 hitpoints
} else if (self.hitpoints === 6) {
self.children[0].tint = 0xFF0000; // Red tint for 6 hitpoints
} else if (self.hitpoints === 5) {
self.children[0].tint = 0xFFCC00; // Light Orange tint for 5 hitpoints
} else if (self.hitpoints === 4) {
self.children[0].tint = 0xFF3333; // Stronger Red tint for 4 hitpoints
} else if (self.hitpoints === 3) {
self.children[0].tint = 0xFF6666; // Light Red tint for 3 hitpoints
} else if (self.hitpoints === 2) {
self.children[0].tint = 0xCC66FF; // Light Purple tint for 2 hitpoints
} else if (self.hitpoints === 1) {
self.children[0].tint = 0xFFE066; // Light Yellow tint for 1 hitpoint
}
self.y += self.speed;
// Logic to increase and decrease block sizes
if (LK.ticks % 120 < 60) {
self.scale.x += 0.002;
self.scale.y += 0.002;
} else {
self.scale.x -= 0.002;
self.scale.y -= 0.002;
}
// Create and update hitpoints display
if (!self.hitpointsDisplay) {
self.hitpointsDisplay = new Text2(self.hitpoints.toString(), {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
self.hitpointsDisplay.anchor.set(0.5, 0.5);
self.hitpointsDisplay.y = 0;
self.addChild(self.hitpointsDisplay);
} else if (LK.ticks % 10 === 0) {
self.hitpointsDisplay.setText(self.hitpoints.toString());
}
};
});
var Enemy2 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4.4; // Increase speed by 10%
self.hitpoints = 5; // Different hitpoints for Enemy2
self.randomFactorX = Math.random() * 20 + 10; // Ensure a minimum value to reduce shakiness
self.randomFactorY = Math.random() * 10 + 5; // Ensure a minimum value to reduce shakiness
self.stuck = false; // Initialize stuck property
self.stuckTime = 0; // Initialize stuckTime property
self.originalRandomFactorX = self.randomFactorX; // Store original random factor
self.originalRandomFactorY = self.randomFactorY; // Store original random factor
self.spawnTime = LK.ticks;
self.update = function () {
// Check for collisions with other Enemy2 instances
for (var i = 0; i < enemies.length; i++) {
if (enemies[i] !== self && enemies[i] instanceof Enemy2 && self.intersects(enemies[i])) {
// Adjust position to avoid overlap
if (self.x < enemies[i].x) {
self.x -= 5;
} else {
self.x += 5;
}
if (self.y < enemies[i].y) {
self.y -= 5;
} else {
self.y += 5;
}
}
}
var directionX = fairy.x - self.x;
var directionY = fairy.y - self.y;
var magnitude = Math.sqrt(directionX * directionX + directionY * directionY);
self.x += directionX / magnitude * 2; // Move towards the fairy
self.scale.x = directionX < 0 ? -1 : 1; // Mirror image when moving left
self.y += self.speed + Math.sin(LK.ticks / 20) * 2; // Add small up and down movement
// Adjust movement if too close to the borders
if (self.x < self.width / 2 + 50) {
self.x += 2; // Move right smoothly
} else if (self.x > 2048 - self.width / 2 - 50) {
self.x -= 2; // Move left smoothly
}
// Check if Enemy2 is stuck at the side of the screen
if (self.x <= self.width / 2 || self.x >= 2048 - self.width / 2 && LK.ticks - self.spawnTime > 120) {
if (!self.stuck) {
self.stuck = true;
self.stuckTime = LK.ticks;
self.originalRandomFactorX = self.randomFactorX;
self.randomFactorX = 180; // Move to the opposite side for at least 3 seconds
} else if (LK.ticks - self.stuckTime > 120) {
// 2 seconds at 60FPS
self.stuck = false;
self.randomFactorX = self.originalRandomFactorX; // Return to original random movement
self.randomFactorY = self.originalRandomFactorY; // Return to original random movement
}
} else {
self.stuck = false;
}
self.x = Math.max(Math.min(self.x, 2048 - self.width / 2), self.width / 2); // Ensure Enemy2 stays within horizontal limits
if (self.y > 2732 + self.height / 2) {
self.destroy();
}
// Logic to increase and decrease size
if (LK.ticks % 120 < 60) {
self.scale.x += 0.001;
self.scale.y += 0.001;
} else {
self.scale.x -= 0.001;
self.scale.y -= 0.001;
}
if (self.y > 2732) {
self.destroy();
}
};
});
//<Assets used in the game will automatically appear here>
// Fairy class
var Fairy = Container.expand(function () {
var self = Container.call(this);
var fairyGraphics = self.attachAsset('fairy', {
anchorX: 0.5,
anchorY: 0.5
});
fairyGraphics.hitArea = new Rectangle(-fairyGraphics.width / 3, -fairyGraphics.height / 3, fairyGraphics.width / 1.5, fairyGraphics.height / 1.5); // Increase hitbox margin
self.speed = 5;
self.particles = [];
self.update = function () {
// Particle emitter logic
if (LK.ticks % 10 === 0) {
var particle = LK.getAsset('fairyemitter', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1,
scaleX: 10,
scaleY: 10
});
particle.x = self.x + (self.scale.x === -1 ? 30 : -30);
particle.y = self.y + self.height / 2;
particle.speedX = (Math.random() - 0.5) * 1.5;
particle.speedY = Math.random() * 1.5 + 0.5; // Push particles downwards
particle.update = function () {
this.x += this.speedX;
this.y += this.speedY;
this.alpha -= 0.02;
if (this.alpha <= 0) {
this.destroy();
}
};
self.particles.push(particle);
game.addChild(particle);
}
// Update existing particles
for (var i = self.particles.length - 1; i >= 0; i--) {
self.particles[i].update();
if (self.particles[i].alpha <= 0) {
self.particles.splice(i, 1);
}
}
// Fairy movement logic
};
});
var HeroBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.speed = -5;
self.hitpoints = 1; // Add hitpoints property to HeroBullet
self.update = function () {
self.y += self.speed;
self.x += Math.sin(LK.ticks / 10) * 1; // Reduce sideways movement
};
});
var HeroBullet2 = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('herobullet2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -5; // Different speed for HeroBullet2
self.hitpoints = 2; // Different hitpoints for HeroBullet2
self.update = function () {
self.y += self.speed;
};
});
var HeroBullet3 = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('herobullet3', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8; // Different speed for HeroBullet3
self.hitpoints = 1; // Set base damage for HeroBullet3 to 1
self.update = function () {
self.y += self.speed;
self.x += Math.sin(LK.ticks / 10) * 1; // Add slight sideways movement
};
});
// Powerup class
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.update = function () {
self.y += self.speed;
if (self.y > 2732) {
self.destroy();
}
};
});
var PowerupMenu = Container.expand(function () {
var self = Container.call(this);
var screenGraphics = self.attachAsset('menu', {
anchorX: 0.5,
anchorY: 0.5
});
screenGraphics.width = 1024 * 1.5; // Increase width by 50%
screenGraphics.height = 1366 * 1.5; // Increase height by 50%
screenGraphics.alpha = 0.7;
screenGraphics.x = 2048 / 3 + 100;
screenGraphics.y = 2732 / 3 + 50;
var title = new Text2('', {
size: 150,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
title.anchor.set(0.5, 0.5);
title.x = screenGraphics.x;
title.y = screenGraphics.y - screenGraphics.height / 2 + 150;
self.x = 2048 / 2 - screenGraphics.width / 2 - 500;
self.y = 2732 / 2 - screenGraphics.height / 2 - 300;
self.addChild(title);
var powerup1 = LK.getAsset('powerup1', {
anchorX: 0.5,
anchorY: 0.5
});
powerup1.x = screenGraphics.x - 300;
powerup1.y = screenGraphics.y - 400;
self.addChild(powerup1);
powerup1.down = function (x, y, obj) {
if (diamondCount >= powerupCosts.powerup1) {
diamondCount -= powerupCosts.powerup1;
diamondCounterTxt.setText(diamondCount);
heroFireRate = Math.max(5, heroFireRate - 5); // Increase fire rate when the first powerup is selected, but not less than 5
isUsingHeroBullet3 = true; // Switch to HeroBullet3
HeroBullet.prototype.speed -= 0.3; // Increase bullet speed by 1
isUsingHeroBullet2 = false; // Ensure HeroBullet2 is not used
HeroBullet2.prototype.speed = -8; // Reset HeroBullet2 speed
LK.getSound('yes').play(); // Play yes sound when powerup1 is purchased
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
if (currentLevelIndex < levels.length - 1) {
currentLevelIndex++;
currentLevel = levels[currentLevelIndex];
} else {
currentLevelIndex = 0;
currentLevel = levels[currentLevelIndex];
levels.forEach(function (level) {
level.waves.forEach(function (wave) {
wave.hitpoints = wave.hitpoints.map(function (hitpoint) {
return hitpoint * 2;
});
wave.speed = wave.speed ? wave.speed * 2 : 2; // Double the speed of enemies
});
});
bullets.forEach(function (bullet) {
bullet.speed *= 2; // Double the speed of bullets
});
}
currentLevel.currentWaveIndex = 0; // Reset the current wave index to start from the first wave
} else {
LK.getSound('nono').play(); // Play nono sound when player can't purchase powerup1
var message = new Text2("I need ".concat(powerupCosts.powerup1 - diamondCount, " more diamonds for this powerup!"), {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
message.anchor.set(0.5, 1.0);
message.x = 2048 / 2;
message.y = 2732 - 50;
game.addChild(message);
LK.setTimeout(function () {
message.destroy();
}, 2000);
}
};
var powerup1DiamondIcon = LK.getAsset('diamond', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
powerup1DiamondIcon.x = powerup1.x;
powerup1DiamondIcon.y = powerup1.y + powerup1.height / 2 + 50;
self.addChild(powerup1DiamondIcon);
var powerup1Cost = new Text2('5', {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
powerup1Cost.anchor.set(0.5, 0);
powerup1Cost.x = powerup1.x;
powerup1Cost.y = powerup1DiamondIcon.y + powerup1DiamondIcon.height / 2 - 20;
self.addChild(powerup1Cost);
var powerup2 = LK.getAsset('powerup2', {
anchorX: 0.5,
anchorY: 0.5
});
powerup2.x = screenGraphics.x;
powerup2.y = screenGraphics.y - 400;
self.addChild(powerup2);
powerup2.down = function (x, y, obj) {
if (diamondCount >= powerupCosts.powerup2) {
diamondCount -= powerupCosts.powerup2;
diamondCounterTxt.setText(diamondCount);
// Add action for powerup3
isUsingHeroBullet2 = true; // Switch to HeroBullet2
isUsingHeroBullet3 = false; // Ensure HeroBullet3 is not used
// HeroBullet.prototype.speed = -5; // Reset HeroBullet speed
heroFireRate = Math.max(5, heroFireRate - 5); // Increase fire rate when the second powerup is selected, but not less than 5
HeroBullet2.prototype.hitpoints *= 1.2; // Increase hit points by 20%
LK.getSound('yes').play(); // Play yes sound when powerup2 is purchased
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
// Increase level when a powerup is selected
if (currentLevelIndex < levels.length - 1) {
currentLevelIndex++;
currentLevel = levels[currentLevelIndex];
} else {
currentLevelIndex = 0;
currentLevel = levels[currentLevelIndex];
levels.forEach(function (level) {
level.waves.forEach(function (wave) {
wave.hitpoints = wave.hitpoints.map(function (hitpoint) {
return hitpoint * 1.2; // Increase hitpoints by 20%
});
wave.speed = wave.speed ? wave.speed * 1.5 : 1.5; // Increase speed by 50%
});
});
bullets.forEach(function (bullet) {
bullet.speed *= 1.5; // Increase bullet speed by 50%
});
}
} else {
LK.getSound('nono').play(); // Play nono sound when player can't purchase powerup2
var message = new Text2("I need ".concat(powerupCosts.powerup2 - diamondCount, " more diamonds for this powerup!"), {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
message.anchor.set(0.5, 1.0);
message.x = 2048 / 2;
message.y = 2732 - 50;
game.addChild(message);
LK.setTimeout(function () {
message.destroy();
}, 2000);
}
};
var powerup2DiamondIcon = LK.getAsset('diamond', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
powerup2DiamondIcon.x = powerup2.x;
powerup2DiamondIcon.y = powerup2.y + powerup2.height / 2 + 50;
self.addChild(powerup2DiamondIcon);
var powerup2Cost = new Text2('5', {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
powerup2Cost.anchor.set(0.5, 0);
powerup2Cost.x = powerup2.x;
powerup2Cost.y = powerup2DiamondIcon.y + powerup2DiamondIcon.height / 2 - 20;
self.addChild(powerup2Cost);
var powerup3 = LK.getAsset('powerup3', {
anchorX: 0.5,
anchorY: 0.5
});
powerup3.x = screenGraphics.x + 300;
powerup3.y = screenGraphics.y - 400;
self.addChild(powerup3);
powerup3.down = function (x, y, obj) {
if (diamondCount >= powerupCosts.powerup3) {
diamondCount -= powerupCosts.powerup3;
diamondCounterTxt.setText(diamondCount);
// Add action for powerup3
shield = game.addChild(new Shield()); // Add shield only when powerup3 is selected
LK.getSound('yes').play(); // Play yes sound when powerup3 is purchased
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
// Increase level when a powerup is selected
if (currentLevelIndex < levels.length - 1) {
currentLevelIndex++;
currentLevel = levels[currentLevelIndex];
} else {
currentLevelIndex = 0;
currentLevel = levels[currentLevelIndex];
}
} else {
LK.getSound('nono').play(); // Play nono sound when player can't purchase powerup3
var message = new Text2("I need ".concat(powerupCosts.powerup3 - diamondCount, " more diamonds for this powerup!"), {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
message.anchor.set(0.5, 1.0);
message.x = 2048 / 2;
message.y = 2732 - 50;
game.addChild(message);
LK.setTimeout(function () {
message.destroy();
}, 2000);
}
};
var powerup3DiamondIcon = LK.getAsset('diamond', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
powerup3DiamondIcon.x = powerup3.x;
powerup3DiamondIcon.y = powerup3.y + powerup3.height / 2 + 50;
self.addChild(powerup3DiamondIcon);
var powerup3Cost = new Text2('10', {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
powerup3Cost.anchor.set(0.5, 0);
powerup3Cost.x = powerup3.x;
powerup3Cost.y = powerup3DiamondIcon.y + powerup3DiamondIcon.height / 2 - 20;
self.addChild(powerup3Cost);
var closeButton = new Text2('Maybe next time!', {
size: 100,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
closeButton.anchor.set(0.5, 0.5);
closeButton.x = screenGraphics.x;
closeButton.y = screenGraphics.y + screenGraphics.height / 2 - 300;
self.addChild(closeButton);
// Add animation to 'Maybe next time!' text
closeButton.update = function () {
if (LK.ticks % 120 < 60) {
closeButton.scale.x += 0.005;
closeButton.scale.y += 0.005;
} else {
closeButton.scale.x -= 0.005;
closeButton.scale.y -= 0.005;
}
};
closeButton.down = function (x, y, obj) {
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
if (currentLevelIndex < levels.length - 1) {
currentLevelIndex++;
currentLevel = levels[currentLevelIndex];
} else {
// Reset to first level and double enemy hitpoints
currentLevelIndex = 0;
currentLevel = levels[currentLevelIndex];
levels.forEach(function (level) {
level.waves.forEach(function (wave) {
wave.hitpoints = wave.hitpoints.map(function (hitpoint) {
return hitpoint * 2;
});
wave.speed = wave.speed ? wave.speed * 2 : 2; // Double the speed of enemies
});
});
bullets.forEach(function (bullet) {
bullet.speed *= 2; // Double the speed of bullets
});
}
};
self.down = function (x, y, obj) {
var localPos = self.toLocal(obj.global);
if (powerup1.intersects(self.toLocal(obj.global)) || powerup2.intersects(self.toLocal(obj.global)) || powerup3.intersects(self.toLocal(obj.global))) {
if (powerup1.intersects(self.toLocal(obj.global)) && diamondCount >= 5) {
diamondCount -= 10;
diamondCounterTxt.setText(diamondCount);
heroFireRate = Math.max(5, heroFireRate - 5); // Increase fire rate when the first powerup is selected, but not less than 5
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
} else if (powerup2.intersects(self.toLocal(obj.global)) && diamondCount >= 5) {
diamondCount -= 20;
diamondCounterTxt.setText(diamondCount);
// Add action for powerup2
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
} else if (powerup3.intersects(self.toLocal(obj.global)) && diamondCount >= 10) {
diamondCount -= 30;
diamondCounterTxt.setText(diamondCount);
// Add action for powerup3
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
} else {
var messageText = 'I need more shiny things!';
if (powerup1.intersects(self.toLocal(obj.global)) && diamondCount < 5) {
messageText = 'I need 5 diamonds for this powerup!';
} else if (powerup2.intersects(self.toLocal(obj.global)) && diamondCount < 5) {
messageText = 'I need 5 diamonds for this powerup!';
} else if (powerup3.intersects(self.toLocal(obj.global)) && diamondCount < 10) {
messageText = 'I need 10 diamonds for this powerup!';
}
var message = new Text2(messageText, {
size: 100,
fill: "#ff0000",
stroke: "#000000",
strokeThickness: 5
});
message.anchor.set(0.5, 0.5);
message.x = 2048 / 2;
message.y = 2732 / 2;
game.addChild(message);
LK.setTimeout(function () {
message.destroy();
}, 2000);
}
} else if (closeButton.intersects(self.toLocal(obj.global))) {
self.destroy(); // Close powerup menu
isPowerupScreenActive = false;
if (currentLevelIndex < levels.length) {
currentLevelIndex++;
currentLevel = levels[currentLevelIndex];
} else {
currentLevelIndex = 0;
currentLevel = levels[currentLevelIndex];
levels.forEach(function (level) {
level.waves.forEach(function (wave) {
wave.hitpoints = wave.hitpoints.map(function (hitpoint) {
return hitpoint * 2;
});
wave.speed = wave.speed ? wave.speed * 2 : 2; // Double the speed of enemies
});
});
bullets.forEach(function (bullet) {
bullet.speed *= 2; // Double the speed of bullets
});
}
currentLevel.currentWaveIndex = 0; // Reset the current wave index to start from the first wave
}
};
});
var Shield = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
self.update = function () {
self.x = fairy.x;
self.y = fairy.y;
self.zIndex = fairy.zIndex + 1; // Ensure shield is rendered on top of fairy
};
});
// Star class
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.update = function () {
if (LK.ticks % 2 === 0) {
// Update every 2 ticks
self.y += self.speed;
if (self.y > 2732) {
self.y = -5;
self.x = Math.random() * 2048;
}
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x800080 //Init game with purple background
});
/****
* Game Code
****/
// Configuration for powerup costs
LK.effects.shakeObject = function (object, intensity, duration) {
var originalX = object.x;
var originalY = object.y;
var shakeInterval = LK.setInterval(function () {
object.x = originalX + (Math.random() - 0.5) * intensity;
object.y = originalY + (Math.random() - 0.5) * intensity;
}, 16); // Shake every frame (16ms for 60FPS)
LK.setTimeout(function () {
LK.clearInterval(shakeInterval);
object.x = originalX;
object.y = originalY;
}, duration);
};
var bossSpawnCount = 0;
var boss2SpawnCount = 0;
var boss3SpawnCount = 0;
var bossSpeedIncrement = 0; // Global variable to track boss speed increment
var powerupCosts = {
powerup1: 5,
powerup2: 5,
powerup3: 10
};
var Level = function Level(config, levelNumber) {
this.waves = config.waves;
this.currentWaveIndex = 0;
this.boss = config.boss;
this.levelNumber = levelNumber;
};
Level.prototype.getNextWave = function () {
if (this.currentWaveIndex < this.waves.length) {
return this.waves[this.currentWaveIndex++];
} else {
return null;
}
};
Level.prototype.hasBoss = function () {
return this.boss && this.currentWaveIndex >= this.waves.length;
};
var levels = [new Level({
waves: [{
enemies: 6,
hitpoints: [1],
tints: [0xffe066]
}, {
enemies: 6,
hitpoints: [1, 2],
tints: [0xcc66ff, 0xffe066]
}, {
enemies: 9,
hitpoints: [1, 2, 3],
tints: [0xcc66ff, 0xffe066]
}, {
enemies: 9,
hitpoints: [2, 3, 4],
tints: [0xcc66ff, 0xffe066]
}],
boss: true
}, 1), new Level({
waves: [{
enemies: 6,
hitpoints: [3, 4],
tints: [0x66ff66]
}, {
enemies: 9,
hitpoints: [3, 4, 5],
tints: [0x66ccff, 0x66ff66]
}, {
enemies: 9,
hitpoints: [3, 4, 5],
tints: [0x66ccff, 0x66ff66]
}, {
enemies: 9,
hitpoints: [4, 5, 6],
tints: [0x66ccff, 0x66ff66]
}],
boss: true
}, 2), new Level({
waves: [{
enemies: 9,
hitpoints: [5, 6, 7],
tints: [0xff9933]
}, {
enemies: 9,
hitpoints: [6,, 7, 8],
tints: [0xffcc00, 0xff9933]
}, {
enemies: 9,
hitpoints: [8, 9, 10],
tints: [0xff6600, 0xffcc00, 0xff9933]
}, {
enemies: 9,
hitpoints: [6, 6, 6],
tints: [0xff6600, 0xffcc00, 0xff9933]
}],
boss: true
}, 3)];
var currentLevelIndex = 0;
var currentLevel = levels[currentLevelIndex];
// Initialize variables
var isUsingHeroBullet2 = false; // Flag to track if HeroBullet2 is being used
var isUsingHeroBullet3 = false; // Flag to track if HeroBullet3 is being used
var fairy;
var bullets = [];
var enemies = [];
var scoreTxt;
var score = 0;
var dragNode = null;
var heroFireRate = 30; // Default fire rate for hero bullets
var defaultHeroFireRate = 30; // Store the default fire rate
var diamondCount = 0; // Initialize diamond counter with 0 diamonds
var diamondCounterTxt; // Declare diamondCounterTxt variable
var isFairyHeld = false; // Track if the fairy is being held
var shield = null; // Initialize shield variable
var isPowerupScreenActive = false; // Track if the powerup screen is active
var deathSoundPlayed = false; // Flag to track if the death sound has been played
var waveCount = 0; // Track the wave count
var waveConfig = [{
enemies: 3,
hitpoints: [1],
tints: [0xffe066]
}
/**** , {
enemies: 6,
hitpoints: [2, 1],
tints: [0xcc66ff, 0xffe066]
}
, {
enemies: 9,
hitpoints: [3, 2, 1],
tints: [0xff6666, 0xcc66ff, 0xffe066]
}
****/
// Add more wave configurations as needed
];
// Initialize game elements
function initGame() {
// Play 'letsgo' sound one second after the game starts
LK.setTimeout(function () {
LK.getSound('letsgo').play();
}, 1000);
// Play background music on loop
var backgroundMusic = LK.getSound('backgroundmusic');
backgroundMusic.loop = true;
backgroundMusic.play();
// Create and position the fairy
fairy = game.addChild(new Fairy());
fairy.particles = [];
fairy.x = 2048 / 2;
fairy.y = 2732 - 400;
// Create score text
scoreTxt = new Text2('0', {
size: 200,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
scoreTxt.anchor.set(0.5, 0); // Anchor to the top center
scoreTxt.x = 2048 / 2; // Position at the top center of the screen
scoreTxt.y = 20; // Position with a margin from the top
for (var i = 0; i < 30; i++) {
var star = game.addChild(new Star());
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.speed = 3 + Math.random() * 2; // Randomize speed between 3 and 5
}
scoreTxt.anchor.set(0.5, 0);
// Create coin counter text
game.addChild(scoreTxt);
// Create coin counter text
// Removed menu background from the top of the screen where score and diamonds are
var diamondCounterContainer = new Container();
var diamondIcon = LK.getAsset('diamond', {
anchorX: 1,
anchorY: 0,
alpha: 0.8,
scaleX: 1.4,
scaleY: 1.4
});
diamondIcon.x = 2048 - 100;
diamondIcon.y = 20;
diamondCounterContainer.addChild(diamondIcon);
diamondCounterTxt = new Text2('0', {
size: 120,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 5
});
diamondCounterTxt.anchor.set(0.5, 0.5);
diamondCounterTxt.x = diamondIcon.x + diamondIcon.width / 2 - 230;
diamondCounterTxt.y = diamondIcon.y + diamondIcon.height / 2 + 15;
diamondCounterContainer.addChild(diamondCounterTxt);
game.addChild(diamondCounterContainer);
// Set up game event listeners
game.down = function (x, y, obj) {
dragNode = fairy;
isFairyHeld = true; // Set isFairyHeld to true when the fairy is held
};
game.up = function (x, y, obj) {
dragNode = null;
isFairyHeld = false; // Set isFairyHeld to false when the fairy is released
};
game.move = handleMove;
// Update game every tick
game.update = updateGame;
}
// Handle move events
function handleMove(x, y, obj) {
if (dragNode && fairy.parent) {
// Check if the fairy is moving to the right
if (x > dragNode.x) {
// Mirror the fairy image
dragNode.scale.x = -1;
} else {
// Reset the fairy image
dragNode.scale.x = 1;
}
// Create a ghost image of the fairy when it moves every other frame
if (LK.ticks % 4 === 0) {
var ghostFairy = LK.getAsset('fairy', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
ghostFairy.x = dragNode.x;
ghostFairy.y = dragNode.y;
if (dragNode.parent === game) {
game.addChildAt(ghostFairy, game.getChildIndex(dragNode));
} else {
game.addChild(ghostFairy);
}
if (dragNode.scale.x === -1) {
ghostFairy.scale.x = -1;
}
// Remove the ghost image after 0.5 seconds
LK.setTimeout(function () {
ghostFairy.destroy();
}, 250);
}
dragNode.x += (x - dragNode.x) * 0.1;
if (y > 2732 * 0.5) {
dragNode.y += (y - dragNode.y) * 0.1;
} else {
dragNode.y += (2732 * 0.5 - dragNode.y) * 0.1;
}
}
}
// Update game logic
function updateGame() {
// Update 'Maybe next time!' text if it exists
if (typeof closeButton !== 'undefined' && closeButton.update) {
closeButton.update();
}
// Check if background music is playing, if not, play it
var backgroundMusic = LK.getSound('backgroundmusic');
if (LK.ticks % 600 === 0) {
// Every 10 seconds (600 ticks at 60FPS)
backgroundMusic.play();
}
if (LK.ticks % 300 === 0) {
// Every 5 seconds (300 ticks at 60FPS)
bossSpeedIncrement += 1; // Increase boss speed increment
}
if (currentLevel) {} else {}
// Update starfield
for (var i = game.children.length - 1; i >= 0; i--) {
if (game.children[i] instanceof Star) {
game.children[i].update();
}
if (game.children[i] instanceof Diamond && game.children[i].intersects(fairy)) {
game.children[i].destroy();
diamondCount++;
diamondCounterTxt.setText(diamondCount);
LK.getSound('diamondcollect').play(); // Play diamondcollect sound when a diamond is collected
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] instanceof Bullet) {
bullets[i].update();
}
bullets[i].update();
if (bullets[i] && bullets[i].y < -50) {
bullets[i].destroy();
bullets.splice(i, 1);
}
}
for (var j = enemies.length - 1; j >= 0; j--) {
enemies[j].update();
if (enemies[j].y > 2732 + 50) {
enemies[j].destroy();
enemies.splice(j, 1);
}
if (shield && shield.intersects(enemies[j])) {
shield.destroy();
LK.getSound('boom').play(); // Play boom sound when shield is destroyed
shield = null;
enemies[j].destroy();
score += enemies[j].hitpoints * 10; // Add points based on enemy hitpoints
scoreTxt.setText(score); // Update score text
enemies.splice(j, 1);
} else if (fairy.intersects(enemies[j], {
margin: 20
})) {
var fairyX = fairy.x;
var fairyY = fairy.y;
// Create particle effect for fairy
for (var p = 0; p < 5; p++) {
var particle = LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1,
scaleX: 4,
scaleY: 4,
tint: Math.random() < 0.5 ? 0xffb6c1 : 0x98fb98 // Softer Pink or Green tint
});
particle.x = fairyX;
particle.y = fairyY;
particle.speedX = (Math.random() - 0.5) * 20;
particle.speedY = (Math.random() - 0.5) * 20;
particle.update = function () {
this.x += this.speedX;
this.y += this.speedY;
this.alpha -= 0.01;
if (this.alpha <= 0) {
this.destroy();
}
};
game.addChild(particle);
}
// Play death sound and destroy fairy asset when destroyed by enemy
if (!deathSoundPlayed) {
LK.getSound('death').play();
deathSoundPlayed = true;
}
fairy.speed = 0; // Stop fairy movement
fairy.destroy();
dragNode = null; // Prevent dragging the fairy ghost
// Destroy all fairy ghosts
for (var i = game.children.length - 1; i >= 0; i--) {
if (game.children[i].alpha === 0.3 && game.children[i].width === fairy.width && game.children[i].height === fairy.height) {
game.children[i].destroy();
}
}
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
for (var k = bullets.length - 1; k >= 0; k--) {
if ((bullets[k] instanceof HeroBullet || bullets[k] instanceof HeroBullet2 || bullets[k] instanceof HeroBullet3) && bullets[k].intersects(enemies[j])) {
if (enemies[j] instanceof Enemy2 || enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) {
// Shake effect for Enemy2 and Bosses
LK.effects.shakeObject(enemies[j], 5, 100); // Shake with intensity 5 for 100ms
}
LK.getSound('hit').play(); // Play hit sound when HeroBullet, HeroBullet2, or HeroBullet3 is destroyed
bullets[k].destroy();
bullets.splice(k, 1);
enemies[j].hitpoints -= bullets[k] instanceof HeroBullet2 ? 2 : bullets[k] instanceof HeroBullet3 ? 3 : 1;
if (enemies[j].hitpoints <= 0) {
var enemyX = enemies[j].x;
var enemyY = enemies[j].y;
// Create particle effect
for (var p = 0; p < 50; p++) {
var particle = LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1,
scaleX: 4,
scaleY: 4,
tint: enemies[j] instanceof Enemy2 ? 0x000000 : enemies[j].children[0].tint
});
particle.x = enemyX;
particle.y = enemyY;
particle.speedX = (Math.random() - 0.5) * 20;
particle.speedY = (Math.random() - 0.5) * 20;
particle.update = function () {
this.x += this.speedX;
this.y += this.speedY;
this.alpha -= 0.01;
if (this.alpha <= 0) {
this.destroy();
}
};
game.addChild(particle);
}
enemies[j].destroy();
LK.getSound('boom').play();
if (enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) {
score += 200; // Add 200 points when a boss is destroyed
}
if (enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) {
bossSpeedIncrement = 0; // Reset boss speed increment when a boss is killed
LK.effects.flashScreen(0xff0000, 1000); // Flash screen red for 1 second
LK.getSound('hooray').play(); // Play hooray sound when a boss is destroyed
// Destroy all boss bullets
for (var b = bullets.length - 1; b >= 0; b--) {
if (bullets[b] instanceof BossBullet || bullets[b] instanceof BossBullet2 || bullets[b] instanceof BossBullet3) {
bullets[b].destroy();
bullets.splice(b, 1);
}
}
var powerupMenu = new PowerupMenu();
powerupMenu.x = 2048 / 2 - powerupMenu.width / 2;
powerupMenu.y = 2732 / 2 - powerupMenu.height / 2;
game.addChild(powerupMenu);
isPowerupScreenActive = true;
score += 200; // Add 200 points when a boss is destroyed
}
if (enemies[j] instanceof Enemy2) {
score += 50; // Add 50 points when an Enemy2 is destroyed
}
enemies.splice(j, 1);
if (enemies[j]) {
if (enemies[j] instanceof Boss || enemies[j] instanceof Boss2 || enemies[j] instanceof Boss3) {
score += enemies[j].hitpoints * 10;
} else {
score += enemies[j].hitpoints * 10;
}
}
scoreTxt.setText(score);
var dropChance = Math.random();
if (dropChance < 0.2) {
var newDiamond = new Diamond();
newDiamond.x = enemyX;
newDiamond.y = enemyY;
game.addChild(newDiamond);
} else if (dropChance < 0.2) {
var newPowerup = new Powerup();
newPowerup.x = enemyX;
newPowerup.y = enemyY;
game.addChild(newPowerup);
}
}
break;
} else if ((bullets[k] instanceof BossBullet || bullets[k] instanceof BossBullet2 || bullets[k] instanceof BossBullet3) && bullets[k].intersects(fairy, {
margin: 20
})) {
if (shield) {
shield.destroy();
LK.getSound('boom').play(); // Play boom sound when shield is destroyed
shield = null;
} else {
var fairyX = fairy.x;
var fairyY = fairy.y;
// Create particle effect for fairy
for (var p = 0; p < 50; p++) {
var particle = LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 1,
scaleX: 4,
scaleY: 4,
tint: Math.random() < 0.5 ? 0xffb6c1 : 0x98fb98 // Softer Pink or Green tint
});
particle.x = fairyX;
particle.y = fairyY;
particle.speedX = (Math.random() - 0.5) * 20;
particle.speedY = (Math.random() - 0.5) * 20;
particle.update = function () {
this.x += this.speedX;
this.y += this.speedY;
this.alpha -= 0.02;
if (this.alpha <= 0) {
this.destroy();
}
};
game.addChild(particle);
}
// Play death sound and destroy fairy asset when destroyed by BossBullet
if (!deathSoundPlayed) {
LK.getSound('death').play();
deathSoundPlayed = true;
}
fairy.speed = 0; // Stop fairy movement
fairy.destroy();
dragNode = null; // Prevent dragging the fairy ghost
// Destroy all fairy ghosts
for (var i = game.children.length - 1; i >= 0; i--) {
if (game.children[i].alpha === 0.3 && game.children[i].width === fairy.width && game.children[i].height === fairy.height) {
game.children[i].destroy();
}
}
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
bullets[k].destroy();
bullets.splice(k, 1);
}
}
}
// Check for collisions
// Check for coin collection
for (var i = game.children.length - 1; i >= 0; i--) {
if (game.children[i] instanceof Diamond && game.children[i].intersects(fairy)) {
game.children[i].destroy();
diamondCount++;
diamondCounterTxt.setText('Diamonds: ' + diamondCount);
}
}
for (var k = bullets.length - 1; k >= 0; k--) {
for (var l = enemies.length - 1; l >= 0; l--) {
if ((bullets[k] instanceof HeroBullet || bullets[k] instanceof HeroBullet3) && bullets[k].intersects(enemies[l])) {
LK.getSound('hit').play(); // Play hit sound when HeroBullet or HeroBullet3 is destroyed
bullets[k].destroy();
bullets.splice(k, 1);
enemies[l].hitpoints -= bullets[k] instanceof HeroBullet3 ? 3 : 1;
if (enemies[l].hitpoints <= 0) {
var enemyX = enemies[l].x;
var enemyY = enemies[l].y;
enemies[l].destroy();
LK.getSound('boom').play();
enemies.splice(l, 1);
if (enemies[l]) {
score += enemies[l].hitpoints * 10; // Add points based on enemy hitpoints
}
scoreTxt.setText(score); // Update score text
// Randomly drop coins or powerups
var dropChance = Math.random();
if (dropChance < 0.2) {
var newDiamond = new Diamond();
newDiamond.x = enemyX;
newDiamond.y = enemyY;
game.addChild(newDiamond);
} else if (dropChance < 0.2) {
var newPowerup = new Powerup();
newPowerup.x = enemyX;
newPowerup.y = enemyY;
game.addChild(newPowerup);
}
}
break;
}
}
}
// Spawn new bullets
if (LK.ticks % heroFireRate == 0 && isFairyHeld) {
// Only spawn new bullets if the fairy is being held
var newBullet;
if (isUsingHeroBullet3) {
newBullet = new HeroBullet3();
newBullet.attachAsset('herobullet3', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (isUsingHeroBullet2) {
newBullet = new HeroBullet2();
newBullet.attachAsset('herobullet2', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
newBullet = new HeroBullet();
}
newBullet.x = fairy.x;
newBullet.y = fairy.y - fairy.height / 2;
bullets.push(newBullet);
game.addChild(newBullet);
// Play shoot sound when a HeroBullet is shot
LK.getSound('shoot').play();
}
// Spawn new enemies in a line
if (LK.ticks % 720 == 0 && !isPowerupScreenActive) {
if (enemies.length === 0) {
waveCount++;
}
if (currentLevel) {
var currentWave = currentLevel.getNextWave();
if (currentWave) {
var maxEnemiesPerLine = 3;
var enemySpacing = 2048 / (maxEnemiesPerLine + 1); // Adjust spacing to center enemies
var totalRows = Math.ceil(currentWave.enemies / maxEnemiesPerLine);
for (var i = 0; i < currentWave.enemies; i++) {
var newBlock = new Enemy();
var row = Math.floor(i / maxEnemiesPerLine);
newBlock.hitpoints = currentWave.hitpoints[row] || currentWave.hitpoints[currentWave.hitpoints.length - 1];
newBlock.x = i % maxEnemiesPerLine * enemySpacing + enemySpacing / 2 - newBlock.width / 2;
newBlock.y = -newBlock.height - row * 220; // Spawn offscreen and start appearing down from the top
newBlock.children[0].tint = currentWave.tints[row] || currentWave.tints[currentWave.tints.length - 1];
enemies.push(newBlock);
game.addChild(newBlock);
}
// Spawn Enemy2 based on the level number after the wave with a delay of 5 seconds
LK.setTimeout(function () {
for (var i = 0; i < currentLevel.levelNumber; i++) {
var newEnemy2 = new Enemy2();
newEnemy2.x = Math.random() * 2048;
newEnemy2.y = -newEnemy2.height - 100; // Spawn offscreen and start appearing down from the top
enemies.push(newEnemy2);
game.addChild(newEnemy2);
}
}, 5000);
// Center the rows of enemies
var totalWidth = (Math.min(currentWave.enemies, maxEnemiesPerLine) - 1) * enemySpacing;
var offsetX = (2048 - totalWidth) / 2;
for (var j = 0; j < enemies.length; j++) {
enemies[j].x += offsetX - enemies[j].width / 2;
}
} else if (currentLevel.hasBoss() && enemies.length === 0) {
var boss;
if (currentLevel.levelNumber === 3) {
boss = new Boss3();
} else if (currentLevel.levelNumber === 2) {
boss = new Boss2();
} else {
boss = new Boss();
}
boss.x = 2048 / 2;
boss.y = -boss.height - 100; // Spawn offscreen and start appearing down from the top
boss.hitpoints *= 1.5; // Increase boss hitpoints by 50%
boss.speed *= 1.5; // Increase boss speed by 50%
enemies.push(boss);
game.addChild(boss);
LK.getSound('bossappear').play(); // Play bossappear sound when Boss is spawned
LK.effects.flashScreen(0xffffff, 500); // Flash screen white for 500ms
LK.setTimeout(function () {
LK.effects.flashScreen(0xffffff, 500); // Flash screen white again for 500ms
}, 600); // Delay the second flash by 600ms to allow a brief pause
}
}
}
}
// Initialize the game
initGame();
8-bit. cartoon. white star.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon 8 bit fairy dust. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Cartoon, 8bit, fireball. Black border. Cicular.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon, 8 bit, shield. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
8bit, cartoon, axe. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
dark electric ball, 8bit, cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
8bit, cartoon, treasure chest frame. very big empty center. only a fine border of chest. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.