/**** * Plugins ****/ var facekit = LK.import("@upit/facekit.v1"); var storage = LK.import("@upit/storage.v1", { GameplayBG: false, CurrentSkin: "faceObject" }); var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Background = Container.expand(function () { var self = Container.call(this); var backgroundGraphics = self.attachAsset('Background', { anchorX: 0.5, anchorY: 0.5 }); self.x = 2048 / 2; // Set the x position to the center of the screen self.y = 2732 / 2; // Set the y position to the center of the screen }); var Button = Container.expand(function (text, x, y, callback) { var self = Container.call(this); self.buttonAsset = self.attachAsset('Buttom', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.buttonAsset.x = x; self.buttonAsset.y = y; var buttonText = new Text2(text, { size: 100, fill: 0xFFFFFF, font: "'Press Start 2P', cursive" }); buttonText.anchor.set(0.5, 0.5); buttonText.x = x; buttonText.y = y; self.addChild(buttonText); self.buttonAsset.down = function (x, y, obj) { LK.getSound('ButtomSound').play(); callback(x, y, obj); }; }); var EnemyArrow = Container.expand(function () { var self = Container.call(this); var bEnemyArrowGraphics = self.attachAsset('EnemyArrow', { anchorX: 0.5, anchorY: 0.5 }); var arrowSound = LK.getSound('ArrowCreated'); arrowSound.pitch = 0.9 + Math.random() * 0.2; // Random pitch between 0.9 and 1.1 arrowSound.play(); enemyLogic(self); var angle = Math.atan2(player.y - self.y, player.x - self.x); var speed = 17.5; // Fixed speed for straight trajectory self.update = function () { if (!gamestart) { return; } self.x += Math.cos(angle) * speed; self.y += Math.sin(angle) * speed; self.rotation = angle; }; }); var EnemyCircle = Container.expand(function () { var self = Container.call(this); var bEnemyCircleGraphics = self.attachAsset('EnemyCircle', { anchorX: 0.5, anchorY: 0.5 }); var circleSound = LK.getSound('CircleCreated'); circleSound.play(); // Add pulsing transparency and size increase animation function addPulsingAnimation(target) { tween(target, { alpha: 0.5, scaleX: 1.1, scaleY: 1.1 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(target, { alpha: 1.0, scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { addPulsingAnimation(target); // Loop the effect } }); } }); } addPulsingAnimation(bEnemyCircleGraphics); enemyLogic(self); // Determine target position based on random chance var randomChance = Math.random(); var targetX, targetY; if (randomChance < 0.33) { // 33% chance to go to the player's last position targetX = player.x; targetY = player.y; } else if (randomChance < 0.66) { // 33% chance to go to a very offset position from the player's last position var offsetX = (Math.random() - 0.5) * 800; // Random offset between -400 and 400 var offsetY = (Math.random() - 0.5) * 800; // Random offset between -400 and 400 targetX = player.x + offsetX; targetY = player.y + offsetY; } else { // 33% chance to go to a random position within the player's movement area var leftBound = (2048 - 1000) / 2; var rightBound = leftBound + 1000; var topBound = (2732 - 1000) / 2; var bottomBound = topBound + 1000; targetX = Math.random() * (rightBound - leftBound) + leftBound; targetY = Math.random() * (bottomBound - topBound) + topBound; } var angle = Math.atan2(targetY - self.y, targetX - self.x); var speed; if (randomChance < 0.33) { speed = 15; // Speed for direct to player } else if (randomChance < 0.66) { speed = 10; // Speed for nearby position } else { var _addPulsingSizeAnimation = function addPulsingSizeAnimation(target) { tween(target, { scaleX: 1.6, scaleY: 1.6 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(target, { scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { _addPulsingSizeAnimation(target); // Loop the effect } }); } }); }; speed = 5; // Speed for random position // Add pulsing size animation for slower EnemyCircle instances _addPulsingSizeAnimation(self); } self.update = function () { if (!gamestart) { return; } self.x += Math.cos(angle) * speed; self.y += Math.sin(angle) * speed; self.rotation += 0.03; // Add rotation to Circle }; }); var EnemyHexagon = Container.expand(function () { var self = Container.call(this); var bEnemyHexagonGraphics = self.attachAsset('EnemyHexagon', { anchorX: 0.5, anchorY: 0.5 }); var hexagonSound = LK.getSound('HexagonCreated'); hexagonSound.play(); enemyLogic(self); // Determine target position based on random chance var randomChance = Math.random(); var targetX, targetY; if (randomChance < 0.5) { // 50% chance to go to a nearby position from the player's last position var offsetX = (Math.random() - 0.5) * 400; // Random offset between -200 and 200 var offsetY = (Math.random() - 0.5) * 400; // Random offset between -200 and 200 targetX = player.x + offsetX; targetY = player.y + offsetY; } else { // 50% chance to go to a random position within the player's movement area var leftBound = (2048 - 1000) / 2; var rightBound = leftBound + 1000; var topBound = (2732 - 1000) / 2; var bottomBound = topBound + 1000; targetX = Math.random() * (rightBound - leftBound) + leftBound; targetY = Math.random() * (bottomBound - topBound) + topBound; } var angle = Math.atan2(targetY - self.y, targetX - self.x); var speed = 10; // Adjusted speed for new movement pattern var zigzagFrequency = 0.1; // Frequency of zig-zag movement var zigzagAmplitude = 12; // Amplitude of zig-zag movement self.update = function () { if (!gamestart) { return; } var zigzagOffset = Math.sin(LK.ticks * zigzagFrequency) * zigzagAmplitude; self.x += Math.cos(angle) * speed + Math.cos(angle + Math.PI / 2) * zigzagOffset; self.y += Math.sin(angle) * speed + Math.sin(angle + Math.PI / 2) * zigzagOffset; self.rotation = angle; }; }); var EnemyNinja = Container.expand(function () { var self = Container.call(this); var bEnemyNinjaGraphics = self.attachAsset('EnemyNinja', { anchorX: 0.5, anchorY: 0.5 }); var ninjaSound = LK.getSound('Ninjacreated'); ninjaSound.play(); enemyLogic(self); var angle = Math.atan2(player.y - self.y, player.x - self.x); self.directionChanges = 0; var speed = 18; // Set speed for Ninja self.cooldown = false; // Initialize cooldown state self.update = function () { if (!gamestart) { return; } self.x += Math.cos(angle) * speed; self.y += Math.sin(angle) * speed; self.rotation += 0.1; // Add rotation to Ninja // Check if Ninja is near the player and not on cooldown var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2)); if (distanceToPlayer <= 600 && !self.cooldown) { self.cooldown = true; // Set cooldown to prevent immediate re-triggering LK.setTimeout(function () { self.cooldown = false; // Reset cooldown after 2 seconds }, 2000); self.cooldown = true; // Set cooldown to prevent immediate re-triggering // Create 4 Ninja Clones at 90-degree angles for (var i = 0; i < 4; i++) { var clone = new EnemyNinjaClone(); clone.x = self.x; clone.y = self.y; var cloneAngle = angle + Math.PI / 2 * i; // 90-degree increments clone.update = function (cloneAngle) { return function () { this.x += Math.cos(cloneAngle) * speed; this.y += Math.sin(cloneAngle) * speed; this.rotation += 0.1; }; }(cloneAngle); game.addChild(clone); // Limit the number of EnemyNinjaClones to 16 if (enemyNinjaClones.length >= 16) { var oldestClone = enemyNinjaClones.shift(); // Remove the oldest clone oldestClone.destroy(); // Destroy the oldest clone } enemyNinjaClones.push(clone); // Play 'Ninjasepare' sound with a slight delay for each clone LK.setTimeout(function () { LK.getSound('Ninjasepare').play(); }, i * 100); } self.destroy(); enemyNinjas.splice(enemyNinjas.indexOf(self), 1); } }; }); var EnemyNinjaClone = Container.expand(function () { var self = Container.call(this); var bEnemyNinjaCloneGraphics = self.attachAsset('EnemyNinja', { anchorX: 0.5, anchorY: 0.5 }); enemyLogic(self); var angle = Math.atan2(player.y - self.y, player.x - self.x); self.directionChanges = 0; var speed = 12; // Set speed for Ninja Clone self.cooldown = false; // Initialize cooldown state self.update = function () { if (!gamestart) { return; } self.x += Math.cos(angle) * speed; self.y += Math.sin(angle) * speed; self.rotation += 0.1; // Add rotation to Ninja Clone }; }); var EnemySaw = Container.expand(function () { var self = Container.call(this); var bEnemySawGraphics = self.attachAsset('EnemySaw', { anchorX: 0.5, anchorY: 0.5 }); var sawSound = LK.getSound('sawcreated'); sawSound.play(); enemyLogic(self); var angle = Math.atan2(player.y - self.y, player.x - self.x); var newAngle = null; var speed = 12.5; self.update = function () { if (!gamestart) { return; } var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2)); if (distanceToPlayer <= 450 && !self.hasPaused) { self.hasPaused = true; // Set the boolean to true to ensure it only happens once var originalSpeed = speed; // Store original speed speed = 0; LK.setTimeout(function () { speed = originalSpeed * 2; newAngle = Math.atan2(player.y - self.y, player.x - self.x); // Assign new angle towards player's position LK.getSound('Sawcharge').play(); // Play 'Sawcharge' sound }, 1000); } var currentAngle = newAngle !== null ? newAngle : angle; // Use new angle if available self.x += Math.cos(currentAngle) * speed; self.y += Math.sin(currentAngle) * speed; self.rotation += 0.05; }; }); var EnemyStar = Container.expand(function () { var self = Container.call(this); var bEnemyStarGraphics = self.attachAsset('EnemyStar', { anchorX: 0.5, anchorY: 0.5 }); var starSound = LK.getSound('StarCreated'); starSound.play(); enemyLogic(self); self.directionChanges = 0; var angle = Math.atan2(player.y - self.y, player.x - self.x); var speed = 10; // Maintain original speed self.cooldown = false; // Initialize cooldown state self.update = function () { if (!gamestart) { return; } var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2)); if (self.directionChanges < 3 && distanceToPlayer < 600 && !self.cooldown) { speed *= 1.2; angle = Math.atan2(player.y - self.y, player.x - self.x); self.directionChanges++; self.cooldown = true; LK.setTimeout(function () { self.cooldown = false; }, 1000); } self.x += Math.cos(angle) * speed; self.y += Math.sin(angle) * speed; self.rotation += 0.05; }; }); var Energy = Container.expand(function () { var self = Container.call(this); var energyGraphics = self.attachAsset('Energy', { anchorX: 0.5, anchorY: 0.5 }); self.value = 100; // Initial energy value self.decrease = function (amount) { self.value = Math.max(0, self.value - amount); }; self.increase = function (amount) { self.value = Math.min(100, self.value + amount); }; }); var Life = Container.expand(function () { var self = Container.call(this); var lifeGraphics = self.attachAsset('Life', { anchorX: 0.5, anchorY: 0.5 }); self.value = 100; // Initial life value self.decrease = function (amount) { self.value = Math.max(0, self.value - amount); if (self.value === 0) { lifeQuantity = Math.max(0, lifeQuantity - 1); updateLifeIcons(); if (lifeQuantity === 0) { self.destroy(); LK.showGameOver(); } } }; self.increase = function (amount) { self.value = Math.min(100, self.value + amount); }; }); var Player = Container.expand(function () { var self = Container.call(this); var faceGraphics = self.attachAsset(CurrentSkin, { anchorX: 0.5, anchorY: 0.5 }); // Update faceGraphics when CurrentSkin changes self.updateSkin = function () { self.removeChild(faceGraphics); faceGraphics = self.attachAsset(CurrentSkin, { anchorX: 0.5, anchorY: 0.5 }); }; self.update = function () { if (!gamestart) { return; } faceGraphics.alpha = inmunidad ? 0.5 : 1.0; var smoothing = 0.075; var targetX = facekit.noseTip.x; var targetY = facekit.noseTip.y; var leftBound = (2048 - 1000) / 2; var rightBound = leftBound + 1000; var topBound = (2732 - 1000) / 2; var bottomBound = topBound + 1000; targetX = Math.max(leftBound, Math.min(rightBound, targetX)); targetY = Math.max(topBound, Math.min(bottomBound, targetY)); self.x += (targetX - self.x) * smoothing; self.y += (targetY - self.y) * smoothing; var allEnemies = enemyArrows.concat(enemySaw, enemyNinjas, enemyNinjaClones, enemyStars, enemyCircles, enemyHexagons); for (var i = 0; i < allEnemies.length; i++) { if (self.intersects(allEnemies[i]) && !allEnemies[i].destroyed && !inmunidad) { lifeQuantity = Math.max(0, lifeQuantity - 1); updateLifeIcons(); allEnemies[i].destroy(); inmunidad = true; LK.setTimeout(function () { inmunidad = false; }, 1000); var enemyArray = [enemyArrows, enemySaw, enemyNinjas, enemyStars, enemyCircles, enemyHexagons, enemyNinjaClones]; for (var j = 0; j < enemyArray.length; j++) { if (enemyArray[j].includes(allEnemies[i])) { enemyArray[j].splice(enemyArray[j].indexOf(allEnemies[i]), 1); break; } } if (lifeQuantity === 0) { self.destroy(); gamestart = false; // Save the time when the game ends var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless']; var currentLevelName = levelNames[levelID]; if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) { arrowRecordTime = elapsedTime; storage.arrowRecordTime = arrowRecordTime; } else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) { sawRecordTime = elapsedTime; storage.sawRecordTime = sawRecordTime; } else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) { ninjaRecordTime = elapsedTime; storage.ninjaRecordTime = ninjaRecordTime; } else if (currentLevelName === 'star' && elapsedTime > starRecordTime) { starRecordTime = elapsedTime; storage.starRecordTime = starRecordTime; } else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) { circleRecordTime = elapsedTime; storage.circleRecordTime = circleRecordTime; } else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) { hexagonRecordTime = elapsedTime; storage.hexagonRecordTime = hexagonRecordTime; } else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) { endlessRecordTime = elapsedTime; storage.endlessRecordTime = endlessRecordTime; } LK.stopMusic(); LK.showGameOver(); } break; } } }; }); var RangedLimiter = Container.expand(function () { var self = Container.call(this); var limiterGraphics = self.attachAsset('RangedLimiter', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); }); var TextElement = Container.expand(function (text, size, color, font, x, y) { var self = Container.call(this); var textElement = new Text2(text, { size: size, fill: color, font: font }); textElement.anchor.set(0.5, 0.5); textElement.x = x; textElement.y = y; self.addChild(textElement); }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Retro red // Retro yellow // Retro light green // Retro dark red // Retro purple // Retro dark purple //{2} // Retro purple //{3} // Retro blue //{4} // Retro teal //{5} // Retro green var CurrentSkin = storage.CurrentSkin || 'faceObject'; // Load CurrentSkin from storage or set default var skins = ['faceObject', 'Skin1', 'Skin2', 'Skin3', 'Skin4', 'Skin5', 'Skin6', 'Skin7', 'Skin8', 'Skin9', 'Skin10', 'Skin11', 'Skin12', 'Skin13', 'Skin14', 'Skin15', 'Skin16', 'Skin17', 'Skin18', 'Skin19', 'Skin20', 'Skin21', 'Skin22', 'Skin23']; function showSkinsPage() { // Create a new container for the skins page var skinsContainer = new Container(); // Add a background to the skins page var skinsBackground = LK.getAsset('BackgroundMenu', { anchorX: 0.5, anchorY: 0.5 }); skinsBackground.x = 2048 / 2; skinsBackground.y = 2732 / 2; skinsContainer.addChild(skinsBackground); // Add a title to the skins page var skinsTitle = new TextElement('Colors', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500); skinsContainer.addChild(skinsTitle); // Add a back button to return to the main menu var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) { skinsContainer.visible = false; // Hide the skins page menuContainer.visible = true; // Show the main menu }); skinsContainer.addChild(backButton); // Add a grid layout for skins var gridColumns = 6; var gridSpacing = 300; var startX = 2048 / 2 - (gridColumns - 1) * gridSpacing / 2; var startY = 1000; skins.forEach(function (skin, index) { var skinAsset = LK.getAsset(skin, { anchorX: 0.5, anchorY: 0.5 }); var column = index % gridColumns; var row = Math.floor(index / gridColumns); skinAsset.x = startX + column * gridSpacing; skinAsset.y = startY + row * gridSpacing; skinAsset.down = function (x, y, obj) { CurrentSkin = skin; // Change the current skin to the selected one storage.CurrentSkin = CurrentSkin; // Save the current skin to storage player.updateSkin(); // Update the player's skin console.log("CurrentSkin changed to:", CurrentSkin); LK.getSound('ButtomSound').play(); // Play sound when a skin is selected skinChangeMessage.setText("Skin changed to: ".concat(skin)); LK.setTimeout(function () { if (skinChangeMessage.text === "Skin changed to: ".concat(skin)) { skinChangeMessage.setText(''); // Reset to empty string } }, 2000); }; skinsContainer.addChild(skinAsset); }); // Add a message display for skin change notification var skinChangeMessage = new Text2('', { size: 60, fill: 0x00FF00, // Green color for the message font: "'Press Start 2P', cursive" }); skinChangeMessage.anchor.set(0.5, 0.5); skinChangeMessage.x = 2048 / 2; skinChangeMessage.y = 2732 - 100; // Position at the bottom of the screen skinsContainer.addChild(skinChangeMessage); // Add the skins page to the game game.addChild(skinsContainer); } var GameplayBG = storage.GameplayBG || false; function showConfigPage() { // Create a new container for the config page var configContainer = new Container(); // Add a background to the config page var configBackground = LK.getAsset('BackgroundMenu', { anchorX: 0.5, anchorY: 0.5 }); configBackground.x = 2048 / 2; configBackground.y = 2732 / 2; configContainer.addChild(configBackground); // Add a title to the config page var configTitle = new TextElement('Settings', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500); configContainer.addChild(configTitle); // Add a back button to return to the main menu var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) { configContainer.visible = false; // Hide the config page menuContainer.visible = true; // Show the main menu }); configContainer.addChild(backButton); // Add a button to toggle GameplayBG var toggleGameplayBGButton = new Button(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off', 2048 / 2, 1000, function (x, y, obj) { GameplayBG = !GameplayBG; // Toggle the boolean value storage.GameplayBG = GameplayBG; // Save the state to storage background.alpha = GameplayBG ? 1 : 0; // Update background transparency toggleGameplayBGButton.children[1].setText(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off'); // Update button text }); configContainer.addChild(toggleGameplayBGButton); // Add the config page to the game game.addChild(configContainer); } var inmunidad = false; function showHowToPlayPage() { // Create a new container for the how to play page var howToPlayContainer = new Container(); // Add the how to play background var howToPlayBackground = LK.getAsset('HowToPlayOne', { anchorX: 0.5, anchorY: 0.5 }); howToPlayBackground.x = 2048 / 2; howToPlayBackground.y = 2732 / 2; howToPlayContainer.addChild(howToPlayBackground); // Add event listener to hide how to play page on touch howToPlayContainer.down = function (x, y, obj) { howToPlayContainer.visible = false; // Hide the how to play page menuContainer.visible = true; // Show the main menu }; // Add the how to play page to the game game.addChild(howToPlayContainer); // Toggle between HowToPlayOne and HowToPlayTwo every second var toggle = true; LK.setInterval(function () { var newBackground = LK.getAsset(toggle ? 'HowToPlayTwo' : 'HowToPlayOne', { anchorX: 0.5, anchorY: 0.5 }); newBackground.x = 2048 / 2; newBackground.y = 2732 / 2; howToPlayContainer.addChild(newBackground); howToPlayContainer.removeChild(howToPlayBackground); howToPlayBackground = newBackground; toggle = !toggle; }, 1000); } var levelCompletedArrow = storage.levelCompletedArrow || false; var levelCompletedSaw = storage.levelCompletedSaw || false; var levelCompletedNinja = storage.levelCompletedNinja || false; var levelCompletedStar = storage.levelCompletedStar || false; var levelCompletedCircle = storage.levelCompletedCircle || false; var levelCompletedHexagon = storage.levelCompletedHexagon || false; // New level 'hexagon' completion tracking // Initialize records for each level var arrowRecordTime = storage.arrowRecordTime || 0; var sawRecordTime = storage.sawRecordTime || 0; var ninjaRecordTime = storage.ninjaRecordTime || 0; var starRecordTime = storage.starRecordTime || 0; var circleRecordTime = storage.circleRecordTime || 0; var hexagonRecordTime = storage.hexagonRecordTime || 0; var endlessRecordTime = storage.endlessRecordTime || 0; function showSelectLevelPage() { // Add pulsing transparency effect to RangedLimiter using tween plugin function addPulsingEffect(target) { tween(target, { alpha: 0.2 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(target, { alpha: 0.5 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { addPulsingEffect(target); // Loop the effect } }); } }); } addPulsingEffect(rangerlimited); var selectLevelContainer = new Container(); // Add a background to the select level page var selectLevelBackground = LK.getAsset('BackgroundMenu', { anchorX: 0.5, anchorY: 0.5 }); selectLevelBackground.x = 2048 / 2; selectLevelBackground.y = 2732 / 2; selectLevelContainer.addChild(selectLevelBackground); // Add a title to the select level page var selectLevelTitle = new TextElement('Select Level', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500); selectLevelContainer.addChild(selectLevelTitle); // Add a back button to return to the main menu var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) { selectLevelContainer.visible = false; // Hide the select level page menuContainer.visible = true; // Show the main menu }); selectLevelContainer.addChild(backButton); // Add 'How to Play' button to the select level page var howToPlayButton = new Button('How to Play', 2048 / 2, 2100, function (x, y, obj) { showHowToPlayPage(); }); selectLevelContainer.addChild(howToPlayButton); var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon']; // Rename '???' to 'hexagon' var endlessModeName = 'endless'; // Endless mode var levelSelectors = []; // Array to store level selectors for (var i = 0; i < levelNames.length + 1; i++) { var levelName = i < levelNames.length ? levelNames[i] : endlessModeName; // Add endless mode after last level var levelSelector; var levelAssets = { 'arrow': levelCompletedArrow ? 'LevelArrowEndless' : 'LevelArrow', 'saw': levelCompletedSaw ? 'LevelSawEndless' : 'LevelSaw', 'star': levelCompletedStar ? 'LevelStarEndless' : 'LevelStar', 'ninja': levelCompletedNinja ? 'LevelNinjaEndless' : 'LevelNinja', 'circle': levelCompletedCircle ? 'LevelCircleEndless' : 'LevelCircle', 'hexagon': levelCompletedHexagon ? 'LevelLaserEndless' : 'LevelHexagon', 'endless': 'LevelEndless' }; levelSelector = LK.getAsset(levelAssets[levelName], { anchorX: 0.5, anchorY: 0.5 }); levelSelector.x = 2048 / 2; levelSelector.y = 1300; // Align vertically levelSelector.levelType = levelName; levelSelector.down = function (index) { // Create a closure to capture the current index return function (x, y, obj) { if (true) { leftArrow.buttonAsset.down = null; // Disable left arrow button rightArrow.buttonAsset.down = null; // Disable right arrow button backButton.buttonAsset.down = null; // Disable back button howToPlayButton.buttonAsset.down = null; // Disable how to play button if (!this.soundPlayed) { LK.getSound('InitialLevel').play(); // Play initial level sound this.soundPlayed = true; // Ensure the sound only plays once LK.setTimeout(function () { LK.setTimeout(function () { LK.playMusic('GameplayMusic', { loop: true }); // Play music after sound }, 2000); // Add 2-second delay before starting music }, 898); // Duration of 'InitialLevel' sound } LK.setTimeout(function () { // Add a 3-second cooldown before starting the level gamestart = true; // Start the game selectLevelContainer.visible = false; levelID = index; console.log("Starting level:", obj.levelType); }, 3000); } else { console.log("Previous level's endless mode not completed. Cannot start this level."); } }; }(i); // Pass the current index to the closure selectLevelContainer.addChild(levelSelector); // Add level text below each level selector var levelTextContent = levelName === 'endless' ? 'endless\nmode' : levelName === 'arrow' && levelCompletedArrow ? 'endless\narrow' : levelName === 'saw' && levelCompletedSaw ? 'endless\nsaw' : levelName === 'ninja' && levelCompletedNinja ? 'endless\nninja' : levelName === 'star' && levelCompletedStar ? 'endless\nstar' : levelName === 'circle' && levelCompletedCircle ? 'endless\ncircle' : levelName === 'hexagon' && levelCompletedHexagon ? 'endless\nhexagon' : levelName; var levelText = new Text2(levelTextContent, { size: 80, fill: 0xFFFFFF, font: "'Press Start 2P', cursive" }); levelText.anchor.set(0.5, 0.5); levelText.x = levelSelector.x; levelText.y = levelSelector.y + 300; // Position text below the selector selectLevelContainer.addChild(levelText); levelSelector.levelText = levelText; // Store levelText in levelSelector levelSelectors.push(levelSelector); // Add to array } // Add arrow buttons for level navigation var currentLevelIndex = 0; function updateLevelSelectors() { for (var i = 0; i < levelSelectors.length; i++) { levelSelectors[i].visible = i === currentLevelIndex; levelSelectors[i].levelText.visible = i === currentLevelIndex; } leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level } var leftArrow = new Button('<', 2048 / 2 - 900, 1300, function (x, y, obj) { if (currentLevelIndex > 0) { currentLevelIndex--; updateLevelSelectors(); } }); selectLevelContainer.addChild(leftArrow); var rightArrow = new Button('>', 2048 / 2 + 900, 1300, function (x, y, obj) { if (currentLevelIndex < levelSelectors.length - 1) { currentLevelIndex++; updateLevelSelectors(); } }); selectLevelContainer.addChild(rightArrow); updateLevelSelectors(); game.addChild(selectLevelContainer); } var levelID = 0; var lifeQuantity = 3; var energyQuantity = 100; var gamestart = false; function enemyLogic(entity) { var spawnPositions = [{ x: Math.random() * 2000, y: 0 }, { x: Math.random() * 2000, y: 3000 }, { x: 0, y: Math.random() * 2000 }, { x: 3000, y: Math.random() * 2000 }]; var position = spawnPositions[Math.floor(Math.random() * spawnPositions.length)]; entity.x = position.x; entity.y = position.y; entity.spawnTime = entity.spawnTime || Math.random() * 2000 + 2000; } var background = game.addChild(new Background()); background.alpha = GameplayBG ? 1 : 0; var timerTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); timerTxt.anchor.set(0.5, 0); timerTxt.visible = false; // Initially hide the timer text LK.gui.top.addChild(timerTxt); var elapsedTime = 0; var timerInterval = LK.setInterval(function () { if (!gamestart) { return; } // Ensure timer only updates when gamestart is true if (gamestart && !timerTxt.visible) { timerTxt.visible = true; // Show timer text when game starts } else if (!gamestart && timerTxt.visible) { timerTxt.visible = false; // Hide timer text when game is not started } elapsedTime++; if (elapsedTime >= 30 && (levelID === 1 && !levelCompletedSaw || levelID === 2 && !levelCompletedNinja || levelID === 3 && !levelCompletedStar || levelID === 0 && !levelCompletedArrow || levelID === 4 && !levelCompletedCircle || levelID === 5 && !levelCompletedHexagon)) { // Check if the current time is greater than the record time for the level var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless']; var currentLevelName = levelNames[levelID]; if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) { arrowRecordTime = elapsedTime; storage.arrowRecordTime = arrowRecordTime; } else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) { sawRecordTime = elapsedTime; storage.sawRecordTime = sawRecordTime; } else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) { ninjaRecordTime = elapsedTime; storage.ninjaRecordTime = ninjaRecordTime; } else if (currentLevelName === 'star' && elapsedTime > starRecordTime) { starRecordTime = elapsedTime; storage.starRecordTime = starRecordTime; } else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) { circleRecordTime = elapsedTime; storage.circleRecordTime = circleRecordTime; } else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) { hexagonRecordTime = elapsedTime; storage.hexagonRecordTime = hexagonRecordTime; } else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) { endlessRecordTime = elapsedTime; storage.endlessRecordTime = endlessRecordTime; } gamestart = false; if (levelID === 0) { levelCompletedArrow = true; storage.levelCompletedArrow = true; // Save to cloud } else if (levelID === 1) { levelCompletedSaw = true; storage.levelCompletedSaw = true; // Save to cloud } else if (levelID === 2) { levelCompletedNinja = true; storage.levelCompletedNinja = true; // Save to cloud } else if (levelID === 3) { levelCompletedStar = true; storage.levelCompletedStar = true; // Save to cloud } else if (levelID === 4) { levelCompletedCircle = true; storage.levelCompletedCircle = true; // Save to cloud } else if (levelID === 5) { levelCompletedHexagon = true; storage.levelCompletedHexagon = true; // Save to cloud } LK.stopMusic(); LK.showYouWin(); // Show "you win" and reset the game state } var minutes = Math.floor(elapsedTime / 60); // Calculate minutes var seconds = elapsedTime % 60; // Calculate remaining seconds var timeString = minutes > 0 ? minutes + "m " + seconds + "s" : seconds + "s"; // Format time string timerTxt.setText(timeString); }, 1000); var player = game.addChild(new Player()); player.x = 2048 / 2; // Center the player on the x-axis player.y = 2732 / 2; // Center the player on the y-axis game.up = function (x, y, obj) { player.scaleX = 1; player.scaleY = 1; if (energyDecreaseInterval) { LK.clearInterval(energyDecreaseInterval); // Clear interval when player returns to normal size } }; game.down = function (x, y, obj) { if (energy.value > 0) { // Check if energy is greater than 0 player.scaleX = 0.5; player.scaleY = 0.5; energyDecreaseInterval = LK.setInterval(function () { energy.decrease(1); // Decrease energy by 2% energyText.setText(energy.value + '%'); // Update energy text if (energy.value <= 0) { player.scaleX = 1; // Reset player size if energy depletes player.scaleY = 1; LK.clearInterval(energyDecreaseInterval); // Clear interval } }, 500); // Decrease energy every second } }; // Create a list to store EnemyArrow instances function spawnEnemy(type, interval, levelCheck, enemyArray, enemyClass) { return LK.setInterval(function () { if (!gamestart || !levelCheck()) { return; } var newEnemy = game.addChild(new enemyClass()); enemyArray.push(newEnemy); newEnemy.spawnTime = Date.now(); LK.setTimeout(function () { if (enemyArray.includes(newEnemy) && Date.now() - newEnemy.spawnTime >= 10000) { newEnemy.destroy(); enemyArray.splice(enemyArray.indexOf(newEnemy), 1); } }, 20000); }, interval); } var enemyArrows = []; var enemySaw = []; var enemyNinjas = []; // New array to store EnemyNinja instances var enemyNinjaClones = []; // New array to store EnemyNinjaClone instances var enemyStars = []; // New array to store EnemyStar instances var enemyCircles = []; // New array to store EnemyCircle instances var enemyHexagons = []; // New array to store EnemyHexagon instances var enemyLasers = []; // Define enemyLasers array to fix the ReferenceError var enemyArrowInterval = spawnEnemy('arrow', 700, function () { return levelID === 0; }, enemyArrows, EnemyArrow); var enemySawInterval = spawnEnemy('saw', 1000, function () { return levelID === 1; }, enemySaw, EnemySaw); var enemyNinjaInterval = spawnEnemy('ninja', 1200, function () { return levelID === 2; }, enemyNinjas, EnemyNinja); var enemyStarInterval = spawnEnemy('star', 1500, function () { return levelID === 3; }, enemyStars, EnemyStar); var enemyCircleInterval = spawnEnemy('circle', 700, function () { return levelID === 4; }, enemyCircles, EnemyCircle); var enemyHexagonInterval = spawnEnemy('hexagon', 1000, function () { return levelID === 5; }, enemyHexagons, EnemyHexagon); // Endless mode logic for spawning two different enemies every 30 seconds var endlessEnemyTypes = [EnemyArrow, EnemySaw, EnemyNinja, EnemyStar, EnemyCircle, EnemyHexagon]; var currentEndlessEnemyIndex = 0; // Function to spawn 3 random enemies every 2 seconds in endless mode var endlessModeInterval = LK.setInterval(function () { if (levelID === 6 && gamestart) { // Assuming levelID 6 is for endless mode for (var i = 0; i < 2; i++) { var randomEnemyType = endlessEnemyTypes[Math.floor(Math.random() * endlessEnemyTypes.length)]; var newEnemy = game.addChild(new randomEnemyType()); enemyArrows.push(newEnemy); // Assuming all enemies are stored in enemyArrows for simplicity } } }, 2000); var lifeIcons = []; for (var i = 0; i < lifeQuantity; i++) { var lifeIcon = game.addChild(new Life()); lifeIcon.x = 2048 / 2 - 600 + i * 160; // Position each life icon to the right of the previous one lifeIcon.y = 100; // Align vertically with the timer lifeIcons.push(lifeIcon); } // Function to update life icons when life decreases function updateLifeIcons() { for (var i = 0; i < lifeIcons.length; i++) { if (i < lifeQuantity) { lifeIcons[i].visible = true; } else { lifeIcons[i].visible = false; } } } var energy = game.addChild(new Energy()); energy.x = 2048 / 2 + 600; // Position energy to the right of the timer energy.y = 100; // Align vertically with the timer var energyText = new Text2(energyQuantity + '%', { size: 80, fill: 0xFFFFFF }); energyText.anchor.set(1, 0.5); // Anchor to the right center energyText.x = energy.x - 100; // Position to the left of energy energyText.y = energy.y; game.addChild(energyText); var rangerlimited = game.addChild(new RangedLimiter()); rangerlimited.x = 2048 / 2; // Center the RangedLimiter on the x-axis rangerlimited.y = 2732 / 2; // Center the RangedLimiter on the y-axis // Create an initial menu var menuContainer = new Container(); /* * Menu inicial */ var menuBackground = LK.getAsset('BackgroundMenu', { anchorX: 0.5, anchorY: 0.5 }); menuBackground.x = 2048 / 2; menuBackground.y = 2732 / 2; menuContainer.addChild(menuBackground); // Add a title to the menu var title = new TextElement('Extreme, skill\n and figures', 135, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500); menuContainer.addChild(title); // Add a reset progress button to the menu var resetButtonAsset = LK.getAsset('ResetProgress', { anchorX: 0.5, anchorY: 0.5, color: 0xff0000 // Red color }); resetButtonAsset.x = 2048 - 150; resetButtonAsset.y = 2732 - 150; var resetTapCount = 0; var requiredTaps = 3; var resetMessage = new Text2('', { size: 60, fill: 0xFF0000, // Red color for the message font: "'Press Start 2P', cursive" }); resetMessage.anchor.set(0.5, 0.5); resetMessage.x = 2048 / 2; resetMessage.y = 2732 - 100; // Position at the bottom of the screen menuContainer.addChild(resetMessage); resetButtonAsset.down = function (x, y, obj) { LK.getSound('ButtomSound').play(); // Play button sound when reset button is pressed tween(resetButtonAsset, { rotation: -Math.PI * 2 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { resetButtonAsset.rotation = 0; // Reset rotation after tween } }); resetTapCount++; if (resetTapCount < requiredTaps) { resetMessage.setText("Press ".concat(requiredTaps - resetTapCount, " more times\nto reset progress")); LK.setTimeout(function () { resetMessage.setText(''); resetTapCount = 0; // Reset the tap count after message disappears }, 4000); } else { // Reset all progress and records storage.levelCompletedArrow = false; storage.levelCompletedSaw = false; storage.levelCompletedNinja = false; storage.levelCompletedStar = false; storage.levelCompletedCircle = false; storage.levelCompletedHexagon = false; storage.arrowRecordTime = 0; storage.sawRecordTime = 0; storage.ninjaRecordTime = 0; storage.starRecordTime = 0; storage.circleRecordTime = 0; storage.hexagonRecordTime = 0; storage.endlessRecordTime = 0; storage.CurrentSkin = 'faceObject'; // Reset CurrentSkin to default resetMessage.setText("Progress has been reset."); resetTapCount = 0; // Reset the tap count LK.setTimeout(function () { LK.showGameOver(); // End the game after 2 seconds }, 2000); } }; menuContainer.addChild(resetButtonAsset); // Create buttons var configButtonAsset = LK.getAsset('ConfigButon', { anchorX: 0.5, anchorY: 0.5 }); configButtonAsset.x = 150; configButtonAsset.y = 2732 - 150; configButtonAsset.down = function (x, y, obj) { LK.getSound('ButtomSound').play(); // Play button sound when config button is pressed menuContainer.visible = false; // Hide the main menu showConfigPage(); // Show the config page }; menuContainer.addChild(configButtonAsset); var startButton = new Button('Play', 2048 / 2, 1200, function (x, y, obj) { menuContainer.visible = false; // Hide the menu showSelectLevelPage(); // Redirect to 'select level' page }); menuContainer.addChild(startButton); var colorsButton = new Button('Colors', 2048 / 2, 1500, function (x, y, obj) { menuContainer.visible = false; // Hide the main menu showSkinsPage(); // Show the colors page }); menuContainer.addChild(colorsButton); var creditsButton = new Button('Credits', 2048 / 2, 2100, function (x, y, obj) { showCreditsPage(); }); menuContainer.addChild(creditsButton); var recordButton = new Button('Record', 2048 / 2, 1800, function (x, y, obj) { menuContainer.visible = false; // Hide the main menu showRecordsPage(); // Show the records page }); menuContainer.addChild(recordButton); function showCreditsPage() { // Create a new container for the credits page var creditsContainer = new Container(); // Add the credits background var creditsBackground = LK.getAsset('Credits', { anchorX: 0.5, anchorY: 0.5 }); creditsBackground.x = 2048 / 2; creditsBackground.y = 2732 / 2; creditsContainer.addChild(creditsBackground); // Add event listener to hide credits page on touch creditsBackground.down = function (x, y, obj) { creditsContainer.visible = false; // Hide the credits page menuContainer.visible = true; // Show the main menu }; // Add the credits page to the game game.addChild(creditsContainer); } game.addChild(menuContainer); ; // Function to display the records page function showRecordsPage() { // Create a new container for the records page var recordsContainer = new Container(); // Add a black background to the records page var recordsBackground = LK.getAsset('BackgroundMenu', { anchorX: 0.5, anchorY: 0.5 }); recordsBackground.x = 2048 / 2; recordsBackground.y = 2732 / 2; recordsContainer.addChild(recordsBackground); // Add a title to the records page var recordsTitle = new TextElement('Records', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500); recordsContainer.addChild(recordsTitle); // Display records for each level var recordYPosition = 700; var levels = [{ name: 'arrow', recordTime: arrowRecordTime, color: 0xFFBD4D }, { name: 'saw', recordTime: sawRecordTime, color: 0xF26A41 }, { name: 'ninja', recordTime: ninjaRecordTime, color: 0xF61C32 }, { name: 'star', recordTime: starRecordTime, color: 0xF61D64 }, { name: 'circle', recordTime: circleRecordTime, color: 0xF61CAD }, { name: 'hexagon', recordTime: hexagonRecordTime, color: 0xF61CF6 }, { name: 'endless', recordTime: endlessRecordTime, color: 0xFFFFFF // White for endless }]; levels.forEach(function (level) { var recordText = new Text2(level.name + ': ' + level.recordTime + 's', { size: 80, fill: level.color, font: "'Press Start 2P', cursive" }); recordText.anchor.set(0.5, 0.5); recordText.x = 2048 / 2; recordText.y = recordYPosition; recordsContainer.addChild(recordText); recordYPosition += 150; // Increase space between each record entry }); var backButton = new Button('Back', 2048 / 2, 2300, function (x, y, obj) { recordsContainer.visible = false; // Hide the records page menuContainer.visible = true; // Show the main menu }); recordsContainer.addChild(backButton); game.addChild(recordsContainer); }
/****
* Plugins
****/
var facekit = LK.import("@upit/facekit.v1");
var storage = LK.import("@upit/storage.v1", {
GameplayBG: false,
CurrentSkin: "faceObject"
});
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = self.attachAsset('Background', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = 2048 / 2; // Set the x position to the center of the screen
self.y = 2732 / 2; // Set the y position to the center of the screen
});
var Button = Container.expand(function (text, x, y, callback) {
var self = Container.call(this);
self.buttonAsset = self.attachAsset('Buttom', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.buttonAsset.x = x;
self.buttonAsset.y = y;
var buttonText = new Text2(text, {
size: 100,
fill: 0xFFFFFF,
font: "'Press Start 2P', cursive"
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = x;
buttonText.y = y;
self.addChild(buttonText);
self.buttonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play();
callback(x, y, obj);
};
});
var EnemyArrow = Container.expand(function () {
var self = Container.call(this);
var bEnemyArrowGraphics = self.attachAsset('EnemyArrow', {
anchorX: 0.5,
anchorY: 0.5
});
var arrowSound = LK.getSound('ArrowCreated');
arrowSound.pitch = 0.9 + Math.random() * 0.2; // Random pitch between 0.9 and 1.1
arrowSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var speed = 17.5; // Fixed speed for straight trajectory
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation = angle;
};
});
var EnemyCircle = Container.expand(function () {
var self = Container.call(this);
var bEnemyCircleGraphics = self.attachAsset('EnemyCircle', {
anchorX: 0.5,
anchorY: 0.5
});
var circleSound = LK.getSound('CircleCreated');
circleSound.play();
// Add pulsing transparency and size increase animation
function addPulsingAnimation(target) {
tween(target, {
alpha: 0.5,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
alpha: 1.0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
addPulsingAnimation(target); // Loop the effect
}
});
}
});
}
addPulsingAnimation(bEnemyCircleGraphics);
enemyLogic(self);
// Determine target position based on random chance
var randomChance = Math.random();
var targetX, targetY;
if (randomChance < 0.33) {
// 33% chance to go to the player's last position
targetX = player.x;
targetY = player.y;
} else if (randomChance < 0.66) {
// 33% chance to go to a very offset position from the player's last position
var offsetX = (Math.random() - 0.5) * 800; // Random offset between -400 and 400
var offsetY = (Math.random() - 0.5) * 800; // Random offset between -400 and 400
targetX = player.x + offsetX;
targetY = player.y + offsetY;
} else {
// 33% chance to go to a random position within the player's movement area
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.random() * (rightBound - leftBound) + leftBound;
targetY = Math.random() * (bottomBound - topBound) + topBound;
}
var angle = Math.atan2(targetY - self.y, targetX - self.x);
var speed;
if (randomChance < 0.33) {
speed = 15; // Speed for direct to player
} else if (randomChance < 0.66) {
speed = 10; // Speed for nearby position
} else {
var _addPulsingSizeAnimation = function addPulsingSizeAnimation(target) {
tween(target, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
_addPulsingSizeAnimation(target); // Loop the effect
}
});
}
});
};
speed = 5; // Speed for random position
// Add pulsing size animation for slower EnemyCircle instances
_addPulsingSizeAnimation(self);
}
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.03; // Add rotation to Circle
};
});
var EnemyHexagon = Container.expand(function () {
var self = Container.call(this);
var bEnemyHexagonGraphics = self.attachAsset('EnemyHexagon', {
anchorX: 0.5,
anchorY: 0.5
});
var hexagonSound = LK.getSound('HexagonCreated');
hexagonSound.play();
enemyLogic(self);
// Determine target position based on random chance
var randomChance = Math.random();
var targetX, targetY;
if (randomChance < 0.5) {
// 50% chance to go to a nearby position from the player's last position
var offsetX = (Math.random() - 0.5) * 400; // Random offset between -200 and 200
var offsetY = (Math.random() - 0.5) * 400; // Random offset between -200 and 200
targetX = player.x + offsetX;
targetY = player.y + offsetY;
} else {
// 50% chance to go to a random position within the player's movement area
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.random() * (rightBound - leftBound) + leftBound;
targetY = Math.random() * (bottomBound - topBound) + topBound;
}
var angle = Math.atan2(targetY - self.y, targetX - self.x);
var speed = 10; // Adjusted speed for new movement pattern
var zigzagFrequency = 0.1; // Frequency of zig-zag movement
var zigzagAmplitude = 12; // Amplitude of zig-zag movement
self.update = function () {
if (!gamestart) {
return;
}
var zigzagOffset = Math.sin(LK.ticks * zigzagFrequency) * zigzagAmplitude;
self.x += Math.cos(angle) * speed + Math.cos(angle + Math.PI / 2) * zigzagOffset;
self.y += Math.sin(angle) * speed + Math.sin(angle + Math.PI / 2) * zigzagOffset;
self.rotation = angle;
};
});
var EnemyNinja = Container.expand(function () {
var self = Container.call(this);
var bEnemyNinjaGraphics = self.attachAsset('EnemyNinja', {
anchorX: 0.5,
anchorY: 0.5
});
var ninjaSound = LK.getSound('Ninjacreated');
ninjaSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges = 0;
var speed = 18; // Set speed for Ninja
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.1; // Add rotation to Ninja
// Check if Ninja is near the player and not on cooldown
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distanceToPlayer <= 600 && !self.cooldown) {
self.cooldown = true; // Set cooldown to prevent immediate re-triggering
LK.setTimeout(function () {
self.cooldown = false; // Reset cooldown after 2 seconds
}, 2000);
self.cooldown = true; // Set cooldown to prevent immediate re-triggering
// Create 4 Ninja Clones at 90-degree angles
for (var i = 0; i < 4; i++) {
var clone = new EnemyNinjaClone();
clone.x = self.x;
clone.y = self.y;
var cloneAngle = angle + Math.PI / 2 * i; // 90-degree increments
clone.update = function (cloneAngle) {
return function () {
this.x += Math.cos(cloneAngle) * speed;
this.y += Math.sin(cloneAngle) * speed;
this.rotation += 0.1;
};
}(cloneAngle);
game.addChild(clone);
// Limit the number of EnemyNinjaClones to 16
if (enemyNinjaClones.length >= 16) {
var oldestClone = enemyNinjaClones.shift(); // Remove the oldest clone
oldestClone.destroy(); // Destroy the oldest clone
}
enemyNinjaClones.push(clone);
// Play 'Ninjasepare' sound with a slight delay for each clone
LK.setTimeout(function () {
LK.getSound('Ninjasepare').play();
}, i * 100);
}
self.destroy();
enemyNinjas.splice(enemyNinjas.indexOf(self), 1);
}
};
});
var EnemyNinjaClone = Container.expand(function () {
var self = Container.call(this);
var bEnemyNinjaCloneGraphics = self.attachAsset('EnemyNinja', {
anchorX: 0.5,
anchorY: 0.5
});
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges = 0;
var speed = 12; // Set speed for Ninja Clone
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.1; // Add rotation to Ninja Clone
};
});
var EnemySaw = Container.expand(function () {
var self = Container.call(this);
var bEnemySawGraphics = self.attachAsset('EnemySaw', {
anchorX: 0.5,
anchorY: 0.5
});
var sawSound = LK.getSound('sawcreated');
sawSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var newAngle = null;
var speed = 12.5;
self.update = function () {
if (!gamestart) {
return;
}
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distanceToPlayer <= 450 && !self.hasPaused) {
self.hasPaused = true; // Set the boolean to true to ensure it only happens once
var originalSpeed = speed; // Store original speed
speed = 0;
LK.setTimeout(function () {
speed = originalSpeed * 2;
newAngle = Math.atan2(player.y - self.y, player.x - self.x); // Assign new angle towards player's position
LK.getSound('Sawcharge').play(); // Play 'Sawcharge' sound
}, 1000);
}
var currentAngle = newAngle !== null ? newAngle : angle; // Use new angle if available
self.x += Math.cos(currentAngle) * speed;
self.y += Math.sin(currentAngle) * speed;
self.rotation += 0.05;
};
});
var EnemyStar = Container.expand(function () {
var self = Container.call(this);
var bEnemyStarGraphics = self.attachAsset('EnemyStar', {
anchorX: 0.5,
anchorY: 0.5
});
var starSound = LK.getSound('StarCreated');
starSound.play();
enemyLogic(self);
self.directionChanges = 0;
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var speed = 10; // Maintain original speed
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (self.directionChanges < 3 && distanceToPlayer < 600 && !self.cooldown) {
speed *= 1.2;
angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges++;
self.cooldown = true;
LK.setTimeout(function () {
self.cooldown = false;
}, 1000);
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.05;
};
});
var Energy = Container.expand(function () {
var self = Container.call(this);
var energyGraphics = self.attachAsset('Energy', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 100; // Initial energy value
self.decrease = function (amount) {
self.value = Math.max(0, self.value - amount);
};
self.increase = function (amount) {
self.value = Math.min(100, self.value + amount);
};
});
var Life = Container.expand(function () {
var self = Container.call(this);
var lifeGraphics = self.attachAsset('Life', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 100; // Initial life value
self.decrease = function (amount) {
self.value = Math.max(0, self.value - amount);
if (self.value === 0) {
lifeQuantity = Math.max(0, lifeQuantity - 1);
updateLifeIcons();
if (lifeQuantity === 0) {
self.destroy();
LK.showGameOver();
}
}
};
self.increase = function (amount) {
self.value = Math.min(100, self.value + amount);
};
});
var Player = Container.expand(function () {
var self = Container.call(this);
var faceGraphics = self.attachAsset(CurrentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
// Update faceGraphics when CurrentSkin changes
self.updateSkin = function () {
self.removeChild(faceGraphics);
faceGraphics = self.attachAsset(CurrentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
};
self.update = function () {
if (!gamestart) {
return;
}
faceGraphics.alpha = inmunidad ? 0.5 : 1.0;
var smoothing = 0.075;
var targetX = facekit.noseTip.x;
var targetY = facekit.noseTip.y;
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.max(leftBound, Math.min(rightBound, targetX));
targetY = Math.max(topBound, Math.min(bottomBound, targetY));
self.x += (targetX - self.x) * smoothing;
self.y += (targetY - self.y) * smoothing;
var allEnemies = enemyArrows.concat(enemySaw, enemyNinjas, enemyNinjaClones, enemyStars, enemyCircles, enemyHexagons);
for (var i = 0; i < allEnemies.length; i++) {
if (self.intersects(allEnemies[i]) && !allEnemies[i].destroyed && !inmunidad) {
lifeQuantity = Math.max(0, lifeQuantity - 1);
updateLifeIcons();
allEnemies[i].destroy();
inmunidad = true;
LK.setTimeout(function () {
inmunidad = false;
}, 1000);
var enemyArray = [enemyArrows, enemySaw, enemyNinjas, enemyStars, enemyCircles, enemyHexagons, enemyNinjaClones];
for (var j = 0; j < enemyArray.length; j++) {
if (enemyArray[j].includes(allEnemies[i])) {
enemyArray[j].splice(enemyArray[j].indexOf(allEnemies[i]), 1);
break;
}
}
if (lifeQuantity === 0) {
self.destroy();
gamestart = false;
// Save the time when the game ends
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless'];
var currentLevelName = levelNames[levelID];
if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) {
arrowRecordTime = elapsedTime;
storage.arrowRecordTime = arrowRecordTime;
} else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) {
sawRecordTime = elapsedTime;
storage.sawRecordTime = sawRecordTime;
} else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) {
ninjaRecordTime = elapsedTime;
storage.ninjaRecordTime = ninjaRecordTime;
} else if (currentLevelName === 'star' && elapsedTime > starRecordTime) {
starRecordTime = elapsedTime;
storage.starRecordTime = starRecordTime;
} else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) {
circleRecordTime = elapsedTime;
storage.circleRecordTime = circleRecordTime;
} else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) {
hexagonRecordTime = elapsedTime;
storage.hexagonRecordTime = hexagonRecordTime;
} else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) {
endlessRecordTime = elapsedTime;
storage.endlessRecordTime = endlessRecordTime;
}
LK.stopMusic();
LK.showGameOver();
}
break;
}
}
};
});
var RangedLimiter = Container.expand(function () {
var self = Container.call(this);
var limiterGraphics = self.attachAsset('RangedLimiter', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
});
var TextElement = Container.expand(function (text, size, color, font, x, y) {
var self = Container.call(this);
var textElement = new Text2(text, {
size: size,
fill: color,
font: font
});
textElement.anchor.set(0.5, 0.5);
textElement.x = x;
textElement.y = y;
self.addChild(textElement);
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Retro red
// Retro yellow
// Retro light green
// Retro dark red
// Retro purple
// Retro dark purple
//{2} // Retro purple
//{3} // Retro blue
//{4} // Retro teal
//{5} // Retro green
var CurrentSkin = storage.CurrentSkin || 'faceObject'; // Load CurrentSkin from storage or set default
var skins = ['faceObject', 'Skin1', 'Skin2', 'Skin3', 'Skin4', 'Skin5', 'Skin6', 'Skin7', 'Skin8', 'Skin9', 'Skin10', 'Skin11', 'Skin12', 'Skin13', 'Skin14', 'Skin15', 'Skin16', 'Skin17', 'Skin18', 'Skin19', 'Skin20', 'Skin21', 'Skin22', 'Skin23'];
function showSkinsPage() {
// Create a new container for the skins page
var skinsContainer = new Container();
// Add a background to the skins page
var skinsBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
skinsBackground.x = 2048 / 2;
skinsBackground.y = 2732 / 2;
skinsContainer.addChild(skinsBackground);
// Add a title to the skins page
var skinsTitle = new TextElement('Colors', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
skinsContainer.addChild(skinsTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
skinsContainer.visible = false; // Hide the skins page
menuContainer.visible = true; // Show the main menu
});
skinsContainer.addChild(backButton);
// Add a grid layout for skins
var gridColumns = 6;
var gridSpacing = 300;
var startX = 2048 / 2 - (gridColumns - 1) * gridSpacing / 2;
var startY = 1000;
skins.forEach(function (skin, index) {
var skinAsset = LK.getAsset(skin, {
anchorX: 0.5,
anchorY: 0.5
});
var column = index % gridColumns;
var row = Math.floor(index / gridColumns);
skinAsset.x = startX + column * gridSpacing;
skinAsset.y = startY + row * gridSpacing;
skinAsset.down = function (x, y, obj) {
CurrentSkin = skin; // Change the current skin to the selected one
storage.CurrentSkin = CurrentSkin; // Save the current skin to storage
player.updateSkin(); // Update the player's skin
console.log("CurrentSkin changed to:", CurrentSkin);
LK.getSound('ButtomSound').play(); // Play sound when a skin is selected
skinChangeMessage.setText("Skin changed to: ".concat(skin));
LK.setTimeout(function () {
if (skinChangeMessage.text === "Skin changed to: ".concat(skin)) {
skinChangeMessage.setText(''); // Reset to empty string
}
}, 2000);
};
skinsContainer.addChild(skinAsset);
});
// Add a message display for skin change notification
var skinChangeMessage = new Text2('', {
size: 60,
fill: 0x00FF00,
// Green color for the message
font: "'Press Start 2P', cursive"
});
skinChangeMessage.anchor.set(0.5, 0.5);
skinChangeMessage.x = 2048 / 2;
skinChangeMessage.y = 2732 - 100; // Position at the bottom of the screen
skinsContainer.addChild(skinChangeMessage);
// Add the skins page to the game
game.addChild(skinsContainer);
}
var GameplayBG = storage.GameplayBG || false;
function showConfigPage() {
// Create a new container for the config page
var configContainer = new Container();
// Add a background to the config page
var configBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
configBackground.x = 2048 / 2;
configBackground.y = 2732 / 2;
configContainer.addChild(configBackground);
// Add a title to the config page
var configTitle = new TextElement('Settings', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
configContainer.addChild(configTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
configContainer.visible = false; // Hide the config page
menuContainer.visible = true; // Show the main menu
});
configContainer.addChild(backButton);
// Add a button to toggle GameplayBG
var toggleGameplayBGButton = new Button(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off', 2048 / 2, 1000, function (x, y, obj) {
GameplayBG = !GameplayBG; // Toggle the boolean value
storage.GameplayBG = GameplayBG; // Save the state to storage
background.alpha = GameplayBG ? 1 : 0; // Update background transparency
toggleGameplayBGButton.children[1].setText(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off'); // Update button text
});
configContainer.addChild(toggleGameplayBGButton);
// Add the config page to the game
game.addChild(configContainer);
}
var inmunidad = false;
function showHowToPlayPage() {
// Create a new container for the how to play page
var howToPlayContainer = new Container();
// Add the how to play background
var howToPlayBackground = LK.getAsset('HowToPlayOne', {
anchorX: 0.5,
anchorY: 0.5
});
howToPlayBackground.x = 2048 / 2;
howToPlayBackground.y = 2732 / 2;
howToPlayContainer.addChild(howToPlayBackground);
// Add event listener to hide how to play page on touch
howToPlayContainer.down = function (x, y, obj) {
howToPlayContainer.visible = false; // Hide the how to play page
menuContainer.visible = true; // Show the main menu
};
// Add the how to play page to the game
game.addChild(howToPlayContainer);
// Toggle between HowToPlayOne and HowToPlayTwo every second
var toggle = true;
LK.setInterval(function () {
var newBackground = LK.getAsset(toggle ? 'HowToPlayTwo' : 'HowToPlayOne', {
anchorX: 0.5,
anchorY: 0.5
});
newBackground.x = 2048 / 2;
newBackground.y = 2732 / 2;
howToPlayContainer.addChild(newBackground);
howToPlayContainer.removeChild(howToPlayBackground);
howToPlayBackground = newBackground;
toggle = !toggle;
}, 1000);
}
var levelCompletedArrow = storage.levelCompletedArrow || false;
var levelCompletedSaw = storage.levelCompletedSaw || false;
var levelCompletedNinja = storage.levelCompletedNinja || false;
var levelCompletedStar = storage.levelCompletedStar || false;
var levelCompletedCircle = storage.levelCompletedCircle || false;
var levelCompletedHexagon = storage.levelCompletedHexagon || false; // New level 'hexagon' completion tracking
// Initialize records for each level
var arrowRecordTime = storage.arrowRecordTime || 0;
var sawRecordTime = storage.sawRecordTime || 0;
var ninjaRecordTime = storage.ninjaRecordTime || 0;
var starRecordTime = storage.starRecordTime || 0;
var circleRecordTime = storage.circleRecordTime || 0;
var hexagonRecordTime = storage.hexagonRecordTime || 0;
var endlessRecordTime = storage.endlessRecordTime || 0;
function showSelectLevelPage() {
// Add pulsing transparency effect to RangedLimiter using tween plugin
function addPulsingEffect(target) {
tween(target, {
alpha: 0.2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
alpha: 0.5
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
addPulsingEffect(target); // Loop the effect
}
});
}
});
}
addPulsingEffect(rangerlimited);
var selectLevelContainer = new Container();
// Add a background to the select level page
var selectLevelBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
selectLevelBackground.x = 2048 / 2;
selectLevelBackground.y = 2732 / 2;
selectLevelContainer.addChild(selectLevelBackground);
// Add a title to the select level page
var selectLevelTitle = new TextElement('Select Level', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
selectLevelContainer.addChild(selectLevelTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
selectLevelContainer.visible = false; // Hide the select level page
menuContainer.visible = true; // Show the main menu
});
selectLevelContainer.addChild(backButton);
// Add 'How to Play' button to the select level page
var howToPlayButton = new Button('How to Play', 2048 / 2, 2100, function (x, y, obj) {
showHowToPlayPage();
});
selectLevelContainer.addChild(howToPlayButton);
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon']; // Rename '???' to 'hexagon'
var endlessModeName = 'endless'; // Endless mode
var levelSelectors = []; // Array to store level selectors
for (var i = 0; i < levelNames.length + 1; i++) {
var levelName = i < levelNames.length ? levelNames[i] : endlessModeName; // Add endless mode after last level
var levelSelector;
var levelAssets = {
'arrow': levelCompletedArrow ? 'LevelArrowEndless' : 'LevelArrow',
'saw': levelCompletedSaw ? 'LevelSawEndless' : 'LevelSaw',
'star': levelCompletedStar ? 'LevelStarEndless' : 'LevelStar',
'ninja': levelCompletedNinja ? 'LevelNinjaEndless' : 'LevelNinja',
'circle': levelCompletedCircle ? 'LevelCircleEndless' : 'LevelCircle',
'hexagon': levelCompletedHexagon ? 'LevelLaserEndless' : 'LevelHexagon',
'endless': 'LevelEndless'
};
levelSelector = LK.getAsset(levelAssets[levelName], {
anchorX: 0.5,
anchorY: 0.5
});
levelSelector.x = 2048 / 2;
levelSelector.y = 1300; // Align vertically
levelSelector.levelType = levelName;
levelSelector.down = function (index) {
// Create a closure to capture the current index
return function (x, y, obj) {
if (true) {
leftArrow.buttonAsset.down = null; // Disable left arrow button
rightArrow.buttonAsset.down = null; // Disable right arrow button
backButton.buttonAsset.down = null; // Disable back button
howToPlayButton.buttonAsset.down = null; // Disable how to play button
if (!this.soundPlayed) {
LK.getSound('InitialLevel').play(); // Play initial level sound
this.soundPlayed = true; // Ensure the sound only plays once
LK.setTimeout(function () {
LK.setTimeout(function () {
LK.playMusic('GameplayMusic', {
loop: true
}); // Play music after sound
}, 2000); // Add 2-second delay before starting music
}, 898); // Duration of 'InitialLevel' sound
}
LK.setTimeout(function () {
// Add a 3-second cooldown before starting the level
gamestart = true; // Start the game
selectLevelContainer.visible = false;
levelID = index;
console.log("Starting level:", obj.levelType);
}, 3000);
} else {
console.log("Previous level's endless mode not completed. Cannot start this level.");
}
};
}(i); // Pass the current index to the closure
selectLevelContainer.addChild(levelSelector);
// Add level text below each level selector
var levelTextContent = levelName === 'endless' ? 'endless\nmode' : levelName === 'arrow' && levelCompletedArrow ? 'endless\narrow' : levelName === 'saw' && levelCompletedSaw ? 'endless\nsaw' : levelName === 'ninja' && levelCompletedNinja ? 'endless\nninja' : levelName === 'star' && levelCompletedStar ? 'endless\nstar' : levelName === 'circle' && levelCompletedCircle ? 'endless\ncircle' : levelName === 'hexagon' && levelCompletedHexagon ? 'endless\nhexagon' : levelName;
var levelText = new Text2(levelTextContent, {
size: 80,
fill: 0xFFFFFF,
font: "'Press Start 2P', cursive"
});
levelText.anchor.set(0.5, 0.5);
levelText.x = levelSelector.x;
levelText.y = levelSelector.y + 300; // Position text below the selector
selectLevelContainer.addChild(levelText);
levelSelector.levelText = levelText; // Store levelText in levelSelector
levelSelectors.push(levelSelector); // Add to array
}
// Add arrow buttons for level navigation
var currentLevelIndex = 0;
function updateLevelSelectors() {
for (var i = 0; i < levelSelectors.length; i++) {
levelSelectors[i].visible = i === currentLevelIndex;
levelSelectors[i].levelText.visible = i === currentLevelIndex;
}
leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level
rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level
leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level
rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level
}
var leftArrow = new Button('<', 2048 / 2 - 900, 1300, function (x, y, obj) {
if (currentLevelIndex > 0) {
currentLevelIndex--;
updateLevelSelectors();
}
});
selectLevelContainer.addChild(leftArrow);
var rightArrow = new Button('>', 2048 / 2 + 900, 1300, function (x, y, obj) {
if (currentLevelIndex < levelSelectors.length - 1) {
currentLevelIndex++;
updateLevelSelectors();
}
});
selectLevelContainer.addChild(rightArrow);
updateLevelSelectors();
game.addChild(selectLevelContainer);
}
var levelID = 0;
var lifeQuantity = 3;
var energyQuantity = 100;
var gamestart = false;
function enemyLogic(entity) {
var spawnPositions = [{
x: Math.random() * 2000,
y: 0
}, {
x: Math.random() * 2000,
y: 3000
}, {
x: 0,
y: Math.random() * 2000
}, {
x: 3000,
y: Math.random() * 2000
}];
var position = spawnPositions[Math.floor(Math.random() * spawnPositions.length)];
entity.x = position.x;
entity.y = position.y;
entity.spawnTime = entity.spawnTime || Math.random() * 2000 + 2000;
}
var background = game.addChild(new Background());
background.alpha = GameplayBG ? 1 : 0;
var timerTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0.5, 0);
timerTxt.visible = false; // Initially hide the timer text
LK.gui.top.addChild(timerTxt);
var elapsedTime = 0;
var timerInterval = LK.setInterval(function () {
if (!gamestart) {
return;
} // Ensure timer only updates when gamestart is true
if (gamestart && !timerTxt.visible) {
timerTxt.visible = true; // Show timer text when game starts
} else if (!gamestart && timerTxt.visible) {
timerTxt.visible = false; // Hide timer text when game is not started
}
elapsedTime++;
if (elapsedTime >= 30 && (levelID === 1 && !levelCompletedSaw || levelID === 2 && !levelCompletedNinja || levelID === 3 && !levelCompletedStar || levelID === 0 && !levelCompletedArrow || levelID === 4 && !levelCompletedCircle || levelID === 5 && !levelCompletedHexagon)) {
// Check if the current time is greater than the record time for the level
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless'];
var currentLevelName = levelNames[levelID];
if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) {
arrowRecordTime = elapsedTime;
storage.arrowRecordTime = arrowRecordTime;
} else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) {
sawRecordTime = elapsedTime;
storage.sawRecordTime = sawRecordTime;
} else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) {
ninjaRecordTime = elapsedTime;
storage.ninjaRecordTime = ninjaRecordTime;
} else if (currentLevelName === 'star' && elapsedTime > starRecordTime) {
starRecordTime = elapsedTime;
storage.starRecordTime = starRecordTime;
} else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) {
circleRecordTime = elapsedTime;
storage.circleRecordTime = circleRecordTime;
} else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) {
hexagonRecordTime = elapsedTime;
storage.hexagonRecordTime = hexagonRecordTime;
} else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) {
endlessRecordTime = elapsedTime;
storage.endlessRecordTime = endlessRecordTime;
}
gamestart = false;
if (levelID === 0) {
levelCompletedArrow = true;
storage.levelCompletedArrow = true; // Save to cloud
} else if (levelID === 1) {
levelCompletedSaw = true;
storage.levelCompletedSaw = true; // Save to cloud
} else if (levelID === 2) {
levelCompletedNinja = true;
storage.levelCompletedNinja = true; // Save to cloud
} else if (levelID === 3) {
levelCompletedStar = true;
storage.levelCompletedStar = true; // Save to cloud
} else if (levelID === 4) {
levelCompletedCircle = true;
storage.levelCompletedCircle = true; // Save to cloud
} else if (levelID === 5) {
levelCompletedHexagon = true;
storage.levelCompletedHexagon = true; // Save to cloud
}
LK.stopMusic();
LK.showYouWin(); // Show "you win" and reset the game state
}
var minutes = Math.floor(elapsedTime / 60); // Calculate minutes
var seconds = elapsedTime % 60; // Calculate remaining seconds
var timeString = minutes > 0 ? minutes + "m " + seconds + "s" : seconds + "s"; // Format time string
timerTxt.setText(timeString);
}, 1000);
var player = game.addChild(new Player());
player.x = 2048 / 2; // Center the player on the x-axis
player.y = 2732 / 2; // Center the player on the y-axis
game.up = function (x, y, obj) {
player.scaleX = 1;
player.scaleY = 1;
if (energyDecreaseInterval) {
LK.clearInterval(energyDecreaseInterval); // Clear interval when player returns to normal size
}
};
game.down = function (x, y, obj) {
if (energy.value > 0) {
// Check if energy is greater than 0
player.scaleX = 0.5;
player.scaleY = 0.5;
energyDecreaseInterval = LK.setInterval(function () {
energy.decrease(1); // Decrease energy by 2%
energyText.setText(energy.value + '%'); // Update energy text
if (energy.value <= 0) {
player.scaleX = 1; // Reset player size if energy depletes
player.scaleY = 1;
LK.clearInterval(energyDecreaseInterval); // Clear interval
}
}, 500); // Decrease energy every second
}
};
// Create a list to store EnemyArrow instances
function spawnEnemy(type, interval, levelCheck, enemyArray, enemyClass) {
return LK.setInterval(function () {
if (!gamestart || !levelCheck()) {
return;
}
var newEnemy = game.addChild(new enemyClass());
enemyArray.push(newEnemy);
newEnemy.spawnTime = Date.now();
LK.setTimeout(function () {
if (enemyArray.includes(newEnemy) && Date.now() - newEnemy.spawnTime >= 10000) {
newEnemy.destroy();
enemyArray.splice(enemyArray.indexOf(newEnemy), 1);
}
}, 20000);
}, interval);
}
var enemyArrows = [];
var enemySaw = [];
var enemyNinjas = []; // New array to store EnemyNinja instances
var enemyNinjaClones = []; // New array to store EnemyNinjaClone instances
var enemyStars = []; // New array to store EnemyStar instances
var enemyCircles = []; // New array to store EnemyCircle instances
var enemyHexagons = []; // New array to store EnemyHexagon instances
var enemyLasers = []; // Define enemyLasers array to fix the ReferenceError
var enemyArrowInterval = spawnEnemy('arrow', 700, function () {
return levelID === 0;
}, enemyArrows, EnemyArrow);
var enemySawInterval = spawnEnemy('saw', 1000, function () {
return levelID === 1;
}, enemySaw, EnemySaw);
var enemyNinjaInterval = spawnEnemy('ninja', 1200, function () {
return levelID === 2;
}, enemyNinjas, EnemyNinja);
var enemyStarInterval = spawnEnemy('star', 1500, function () {
return levelID === 3;
}, enemyStars, EnemyStar);
var enemyCircleInterval = spawnEnemy('circle', 700, function () {
return levelID === 4;
}, enemyCircles, EnemyCircle);
var enemyHexagonInterval = spawnEnemy('hexagon', 1000, function () {
return levelID === 5;
}, enemyHexagons, EnemyHexagon);
// Endless mode logic for spawning two different enemies every 30 seconds
var endlessEnemyTypes = [EnemyArrow, EnemySaw, EnemyNinja, EnemyStar, EnemyCircle, EnemyHexagon];
var currentEndlessEnemyIndex = 0;
// Function to spawn 3 random enemies every 2 seconds in endless mode
var endlessModeInterval = LK.setInterval(function () {
if (levelID === 6 && gamestart) {
// Assuming levelID 6 is for endless mode
for (var i = 0; i < 2; i++) {
var randomEnemyType = endlessEnemyTypes[Math.floor(Math.random() * endlessEnemyTypes.length)];
var newEnemy = game.addChild(new randomEnemyType());
enemyArrows.push(newEnemy); // Assuming all enemies are stored in enemyArrows for simplicity
}
}
}, 2000);
var lifeIcons = [];
for (var i = 0; i < lifeQuantity; i++) {
var lifeIcon = game.addChild(new Life());
lifeIcon.x = 2048 / 2 - 600 + i * 160; // Position each life icon to the right of the previous one
lifeIcon.y = 100; // Align vertically with the timer
lifeIcons.push(lifeIcon);
}
// Function to update life icons when life decreases
function updateLifeIcons() {
for (var i = 0; i < lifeIcons.length; i++) {
if (i < lifeQuantity) {
lifeIcons[i].visible = true;
} else {
lifeIcons[i].visible = false;
}
}
}
var energy = game.addChild(new Energy());
energy.x = 2048 / 2 + 600; // Position energy to the right of the timer
energy.y = 100; // Align vertically with the timer
var energyText = new Text2(energyQuantity + '%', {
size: 80,
fill: 0xFFFFFF
});
energyText.anchor.set(1, 0.5); // Anchor to the right center
energyText.x = energy.x - 100; // Position to the left of energy
energyText.y = energy.y;
game.addChild(energyText);
var rangerlimited = game.addChild(new RangedLimiter());
rangerlimited.x = 2048 / 2; // Center the RangedLimiter on the x-axis
rangerlimited.y = 2732 / 2; // Center the RangedLimiter on the y-axis
// Create an initial menu
var menuContainer = new Container();
/*
* Menu inicial
*/
var menuBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
menuBackground.x = 2048 / 2;
menuBackground.y = 2732 / 2;
menuContainer.addChild(menuBackground);
// Add a title to the menu
var title = new TextElement('Extreme, skill\n and figures', 135, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
menuContainer.addChild(title);
// Add a reset progress button to the menu
var resetButtonAsset = LK.getAsset('ResetProgress', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xff0000 // Red color
});
resetButtonAsset.x = 2048 - 150;
resetButtonAsset.y = 2732 - 150;
var resetTapCount = 0;
var requiredTaps = 3;
var resetMessage = new Text2('', {
size: 60,
fill: 0xFF0000,
// Red color for the message
font: "'Press Start 2P', cursive"
});
resetMessage.anchor.set(0.5, 0.5);
resetMessage.x = 2048 / 2;
resetMessage.y = 2732 - 100; // Position at the bottom of the screen
menuContainer.addChild(resetMessage);
resetButtonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play(); // Play button sound when reset button is pressed
tween(resetButtonAsset, {
rotation: -Math.PI * 2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
resetButtonAsset.rotation = 0; // Reset rotation after tween
}
});
resetTapCount++;
if (resetTapCount < requiredTaps) {
resetMessage.setText("Press ".concat(requiredTaps - resetTapCount, " more times\nto reset progress"));
LK.setTimeout(function () {
resetMessage.setText('');
resetTapCount = 0; // Reset the tap count after message disappears
}, 4000);
} else {
// Reset all progress and records
storage.levelCompletedArrow = false;
storage.levelCompletedSaw = false;
storage.levelCompletedNinja = false;
storage.levelCompletedStar = false;
storage.levelCompletedCircle = false;
storage.levelCompletedHexagon = false;
storage.arrowRecordTime = 0;
storage.sawRecordTime = 0;
storage.ninjaRecordTime = 0;
storage.starRecordTime = 0;
storage.circleRecordTime = 0;
storage.hexagonRecordTime = 0;
storage.endlessRecordTime = 0;
storage.CurrentSkin = 'faceObject'; // Reset CurrentSkin to default
resetMessage.setText("Progress has been reset.");
resetTapCount = 0; // Reset the tap count
LK.setTimeout(function () {
LK.showGameOver(); // End the game after 2 seconds
}, 2000);
}
};
menuContainer.addChild(resetButtonAsset);
// Create buttons
var configButtonAsset = LK.getAsset('ConfigButon', {
anchorX: 0.5,
anchorY: 0.5
});
configButtonAsset.x = 150;
configButtonAsset.y = 2732 - 150;
configButtonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play(); // Play button sound when config button is pressed
menuContainer.visible = false; // Hide the main menu
showConfigPage(); // Show the config page
};
menuContainer.addChild(configButtonAsset);
var startButton = new Button('Play', 2048 / 2, 1200, function (x, y, obj) {
menuContainer.visible = false; // Hide the menu
showSelectLevelPage(); // Redirect to 'select level' page
});
menuContainer.addChild(startButton);
var colorsButton = new Button('Colors', 2048 / 2, 1500, function (x, y, obj) {
menuContainer.visible = false; // Hide the main menu
showSkinsPage(); // Show the colors page
});
menuContainer.addChild(colorsButton);
var creditsButton = new Button('Credits', 2048 / 2, 2100, function (x, y, obj) {
showCreditsPage();
});
menuContainer.addChild(creditsButton);
var recordButton = new Button('Record', 2048 / 2, 1800, function (x, y, obj) {
menuContainer.visible = false; // Hide the main menu
showRecordsPage(); // Show the records page
});
menuContainer.addChild(recordButton);
function showCreditsPage() {
// Create a new container for the credits page
var creditsContainer = new Container();
// Add the credits background
var creditsBackground = LK.getAsset('Credits', {
anchorX: 0.5,
anchorY: 0.5
});
creditsBackground.x = 2048 / 2;
creditsBackground.y = 2732 / 2;
creditsContainer.addChild(creditsBackground);
// Add event listener to hide credits page on touch
creditsBackground.down = function (x, y, obj) {
creditsContainer.visible = false; // Hide the credits page
menuContainer.visible = true; // Show the main menu
};
// Add the credits page to the game
game.addChild(creditsContainer);
}
game.addChild(menuContainer);
;
// Function to display the records page
function showRecordsPage() {
// Create a new container for the records page
var recordsContainer = new Container();
// Add a black background to the records page
var recordsBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
recordsBackground.x = 2048 / 2;
recordsBackground.y = 2732 / 2;
recordsContainer.addChild(recordsBackground);
// Add a title to the records page
var recordsTitle = new TextElement('Records', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
recordsContainer.addChild(recordsTitle);
// Display records for each level
var recordYPosition = 700;
var levels = [{
name: 'arrow',
recordTime: arrowRecordTime,
color: 0xFFBD4D
}, {
name: 'saw',
recordTime: sawRecordTime,
color: 0xF26A41
}, {
name: 'ninja',
recordTime: ninjaRecordTime,
color: 0xF61C32
}, {
name: 'star',
recordTime: starRecordTime,
color: 0xF61D64
}, {
name: 'circle',
recordTime: circleRecordTime,
color: 0xF61CAD
}, {
name: 'hexagon',
recordTime: hexagonRecordTime,
color: 0xF61CF6
}, {
name: 'endless',
recordTime: endlessRecordTime,
color: 0xFFFFFF // White for endless
}];
levels.forEach(function (level) {
var recordText = new Text2(level.name + ': ' + level.recordTime + 's', {
size: 80,
fill: level.color,
font: "'Press Start 2P', cursive"
});
recordText.anchor.set(0.5, 0.5);
recordText.x = 2048 / 2;
recordText.y = recordYPosition;
recordsContainer.addChild(recordText);
recordYPosition += 150; // Increase space between each record entry
});
var backButton = new Button('Back', 2048 / 2, 2300, function (x, y, obj) {
recordsContainer.visible = false; // Hide the records page
menuContainer.visible = true; // Show the main menu
});
recordsContainer.addChild(backButton);
game.addChild(recordsContainer);
}
ButtomSound
Sound effect
InitialLevel
Sound effect
ArrowCreated
Sound effect
sawcreated
Sound effect
Sawcharge
Sound effect
Ninjacreated
Sound effect
Ninjasepare
Sound effect
StarCreated
Sound effect
CircleCreated
Sound effect
HexagonCreated
Sound effect
GameplayMusic
Music