User prompt
Ensure that deeznuts and rickroll character have just the hyperspace background in bonus mode
User prompt
When you choose a character in bonus mode add hyperspace as background with no ropes
User prompt
Make hyperspace rotate slowly ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove runandgo music from bonus mode
User prompt
Once character has been selected in bonus mode start level with hyperspace background and a 30 second timer instead of launches ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Prevent character select screen from appearing behind bonus mode
User prompt
Remove everything in bonus mode except for background
User prompt
Remove all code elements associated with bonus mode
User prompt
Why is character frozen when I try to move in bonus mode
User prompt
Why is character freezing up at start of bonus mode
User prompt
Fix the freeze up
User prompt
Change bonus mode to add 1 popcorn at a time starting with 1 then 2 then 4 then 8 then 16 etc
User prompt
Once you collect all popcorn in bonus mode round 1 ends and round 2 starts with and 25 second timer. When you collect all popcorn before timer runs out round 3 starts and 20 second timer and so on untill you only have 5 seconds. Game over when you don't collect all popcorn within time limit
User prompt
Once you collect all popcorn in bonus mode round 1 ends and round 2 starts with double popcorn and 25 second timer. When you collect all popcorn before timer runs out round 3 starts and 20 second timer
User prompt
Remove launch limit in bonus mode and replace it with a 30 second countdown timer
User prompt
Remove launch limit in bonus mode and replace it with a 30 second countdown timer
User prompt
In bonus mode once all popcorn is collected from screen finish launch
User prompt
In bonus level make the popcorn spiral from middle of the screen ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove all animated features for bonus mode background
User prompt
Remove background animation in bonus mode
User prompt
Remove runandgo from bonus mode
User prompt
Please fix the issues
User prompt
In bonus level create d pad to control the character instead of drawing a path
User prompt
Change hyperspace animation to prevent rotation and slowly zoom in
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.hyperspaceAnimation = function animateHyperspace() {' Line Number: 3110
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScores: [], gamePlays: 0, steveUnlocked: false, piglinUnlocked: false, villagerUnlocked: false, spiderUnlocked: false, registeredScores: 0, skeletonUnlocked: false, grimaceUnlocked: false, mjUnlocked: false, johnCenaUnlocked: false, shootingStarsUnlocked: false, deezNutsUnlocked: false, rickrollUnlocked: false, selectedCharacter: "chicken", bonusAnimation: "undefined", titlePage: "undefined", highScorePage: "undefined", characterSelectPage: "undefined", arena: "undefined", backdrop: "undefined", chickenJockey: "undefined", launcher: "undefined", scoreText: "undefined", scoreTitleImg: "undefined", launchesText: "undefined", instructionText: "undefined", launchesTitleImg: "undefined", steve: "undefined", bonusApplied: false, pathTracker: "undefined", popcorns: [], superPopcorns: [], ropes: [], bounds: {}, grimaceTaps: 0, gameState: "title", score: 0, launches: 0, maxLaunches: 10, dragStartX: 0, dragStartY: 0, allCharactersUnlocked: false, hyperspaceAnimation: "undefined", hyperspaceDirection: 1 }); /**** * Classes ****/ var CharacterSelect = Container.expand(function () { var self = Container.call(this); // Add backdrop var backdrop = self.attachAsset('Backdrop', { anchorX: 0.5, anchorY: 0.5, x: 1009, y: 1366, alpha: 0.8 }); // Add title using Selectcharactertitle asset var titleImage = self.attachAsset('Selectcharactertitle', { anchorX: 0.5, anchorY: 0, x: 1024, y: 150 }); // Add back button self.backButton = new Container(); self.backButton.x = 150; // Position at top left, but not in the 0-100px reserved area self.backButton.y = 350; // Align vertically with reset button // Create back button using the Backbutton asset var backButtonImage = self.backButton.attachAsset('Backbutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }); self.addChild(self.backButton); // Add reset button self.resetButton = new Container(); self.resetButton.x = 1900; // Position at top right of screen self.resetButton.y = 350; // Position at top right of screen // Create reset button using the Resetcharacter asset var resetButtonImage = self.resetButton.attachAsset('Resetcharacter', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }); // Add reset button to character select page self.addChild(self.resetButton); // Character options self.characters = [{ name: "Chicken", asset: "chicken" }, { name: "Piglin", asset: "piglinjockey" }, { name: "Spider", asset: "spiderjockey" }, { name: "Steve", asset: "steveridingpig" }, { name: "Villager", asset: "vilagerjockey" }, { name: "Skeleton", asset: "skeletonhorse" }, { name: "Grimace", asset: "Grimacejockey" }, { name: "MJ", asset: "Michaeljackson" }, { name: "John Cena", asset: "Johncena" }, { name: "Shooting Stars", asset: "Shootingstars" }, { name: "DeezNuts", asset: "Deeznuts" }, { name: "Rickroll", asset: "Rickroll" }, { name: "Joe Nugget", asset: "Joenugget" }, { name: "Shrekwizowski", asset: "Shrekwizowski" }, { name: "Pomni", asset: "Pomni" }]; self.selectedCharacter = "chicken"; self.characterButtons = new Container(); self.characterButtons.x = 1024; self.characterButtons.y = 700; self.addChild(self.characterButtons); // Create character selection buttons var btnWidth = 300; var btnHeight = 300; var btnSpacing = 350; var buttonsPerRow = 3; for (var i = 0; i < self.characters.length; i++) { var character = self.characters[i]; var button = new Container(); // Calculate position var row = Math.floor(i / buttonsPerRow); var col = i % buttonsPerRow; var xPos = (col - (buttonsPerRow - 1) / 2) * btnSpacing + 10; // Move right 10 pixels var yPos = row * btnSpacing; button.x = xPos; button.y = yPos; // Create button background var buttonBg = button.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3, alpha: 0.6 }); // Add character image var charImg = button.attachAsset(character.asset, { anchorX: 0.5, anchorY: 0.5, scaleX: character.asset === "vilagerjockey" ? 0.45 : character.asset === "spiderjockey" ? 0.7 : character.asset === "chicken" ? 0.6 : 0.4, scaleY: character.asset === "vilagerjockey" ? 0.45 : character.asset === "spiderjockey" ? 0.7 : character.asset === "chicken" ? 0.6 : 0.4 }); // Add locked overlay for all characters except chicken, Steve (if unlocked), Piglin (if unlocked), Villager (if unlocked), Spider (if unlocked), Skeleton (if unlocked by S pattern), Grimace (if unlocked), MJ (if unlocked), and SpongeBob if (character.asset !== "chicken" && !(character.asset === "steveridingpig" && storage.steveUnlocked === true) && !(character.asset === "piglinjockey" && storage.piglinUnlocked === true) && !(character.asset === "vilagerjockey" && storage.villagerUnlocked === true) && !(character.asset === "spiderjockey" && storage.spiderUnlocked === true) && !(character.asset === "skeletonhorse" && storage.skeletonUnlocked === true) && !(character.asset === "Grimacejockey" && storage.grimaceUnlocked === true) && !(character.asset === "Michaeljackson" && storage.mjUnlocked === true) && !(character.asset === "Johncena" && storage.johnCenaUnlocked === true) && !(character.asset === "Shootingstars" && storage.shootingStarsUnlocked === true) && !(character.asset === "Deeznuts") && !(character.asset === "Rickroll") && !(character.asset === "Joenugget") && !(character.asset === "SpongeBob") && !(character.asset === "Shrekwizowski") && !(character.asset === "Pomni")) { var lockedImg = button.attachAsset('Locked', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); button.lockedImg = lockedImg; // Store reference to locked image } else { if (button.lockedImg && button.lockedImg.parent) { button.lockedImg.parent.removeChild(button.lockedImg); // Remove padlock if character is unlocked } } // Character name text removed // Store character data with button button.characterData = character; // Make button interactive button.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; button.up = function (x, y, obj) { var btnRef = this; // Check if character is unlocked before allowing selection var isUnlocked = btnRef.characterData.asset === "chicken" || btnRef.characterData.asset === "steveridingpig" && storage.steveUnlocked === true || btnRef.characterData.asset === "piglinjockey" && storage.piglinUnlocked === true || btnRef.characterData.asset === "vilagerjockey" && storage.villagerUnlocked === true || btnRef.characterData.asset === "spiderjockey" && storage.spiderUnlocked === true || btnRef.characterData.asset === "skeletonhorse" && storage.skeletonUnlocked === true || btnRef.characterData.asset === "Grimacejockey" && storage.grimaceUnlocked === true || btnRef.characterData.asset === "Michaeljackson" && storage.mjUnlocked === true || btnRef.characterData.asset === "Johncena" && storage.johnCenaUnlocked === true || btnRef.characterData.asset === "Shootingstars" && storage.shootingStarsUnlocked === true || btnRef.characterData.asset === "Deeznuts" && storage.deezNutsUnlocked === true || btnRef.characterData.asset === "Rickroll" || btnRef.characterData.asset === "Joenugget" || btnRef.characterData.asset === "SpongeBob" || btnRef.characterData.asset === "Shrekwizowski" || btnRef.characterData.asset === "Pomni"; if (!isUnlocked) { // Show unlock message based on character if (btnRef.characterData.asset === "Michaeljackson") { var playCount = storage.gamePlays || 0; var playsRemaining = Math.max(0, 20 - playCount); var unlockText = new Text2("Play " + playsRemaining + " more time" + (playsRemaining !== 1 ? "s" : "") + " to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } else if (btnRef.characterData.asset === "steveridingpig") { var playCount = storage.gamePlays || 0; var playsRemaining = Math.max(0, 3 - playCount); var unlockText = new Text2("Play " + playsRemaining + " more time" + (playsRemaining !== 1 ? "s" : "") + " to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } else if (btnRef.characterData.asset === "piglinjockey") { var scoresRegistered = storage.registeredScores || 0; var scoresRemaining = Math.max(0, 5 - scoresRegistered); var unlockText = new Text2("Register " + scoresRemaining + " more high score" + (scoresRemaining !== 1 ? "s" : "") + " to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } else if (btnRef.characterData.asset === "vilagerjockey") { var unlockText = new Text2("Score 1,000,000 points to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } else if (btnRef.characterData.asset === "spiderjockey") { var unlockText = new Text2("Score 10,000,000 points to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } else if (btnRef.characterData.asset === "skeletonhorse") { var unlockText = new Text2("Trace an 'S' on the arena to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } else if (btnRef.characterData.asset === "Johncena") { var playCount = storage.gamePlays || 0; var playsRemaining = Math.max(0, 30 - playCount); var unlockText = new Text2("Play " + playsRemaining + " more time" + (playsRemaining !== 1 ? "s" : "") + " to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } else if (btnRef.characterData.asset === "Shootingstars") { var unlockText = new Text2("Trace a star in arena to unlock", { size: 40, fill: 0xFFFFFF }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 0; unlockText.y = 150; btnRef.addChild(unlockText); // Fade out the text after 2 seconds tween(unlockText, { alpha: 0 }, { delay: 2000, duration: 500, onFinish: function onFinish() { if (unlockText.parent) { unlockText.parent.removeChild(unlockText); } } }); } // Animate button but don't select locked character tween(btnRef, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(btnRef, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); } }); return; } tween(btnRef, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(btnRef, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Set selected character self.selectedCharacter = btnRef.characterData.asset; // Update popcorn asset to 'Belt' if Johncena is selected if (btnRef.characterData.asset === "Johncena") { var popcornAsset = 'Belt'; for (var i = 0; i < popcorns.length; i++) { if (typeof popcorns[i].updateAsset === "function") { popcorns[i].updateAsset(popcornAsset); } } } // Notify game of selection if (typeof game.onCharacterSelected === 'function') { game.onCharacterSelected(btnRef.characterData.asset); } } }); } }); }; self.characterButtons.addChild(button); } // Make reset button interactive self.resetButton.down = function (x, y, obj) { // Animate button press tween(self.resetButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.resetButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); // Animate button release tween(self.resetButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(self.resetButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Reset unlock status for all characters storage.steveUnlocked = false; storage.piglinUnlocked = false; storage.villagerUnlocked = false; storage.spiderUnlocked = false; storage.gamePlays = 0; storage.registeredScores = 0; skeletonUnlocked = false; // Reset skeleton unlock state storage.skeletonUnlocked = false; // Persist reset state grimaceUnlocked = false; // Reset grimace unlock state storage.grimaceUnlocked = false; // Persist reset state storage.mjUnlocked = false; // Reset MJ unlock state storage.johnCenaUnlocked = false; // Reset John Cena unlock state storage.rickrollUnlocked = false; // Reset Rickroll unlock state storage.shootingStarsUnlocked = false; // Reset Shooting Stars unlock state storage.deezNutsUnlocked = false; // Reset DeezNuts unlock state storage.allCharactersUnlocked = false; // Reset all characters unlocked state // Flash confirmation message var confirmationMsg = new Text2("Characters reset!", { size: 70, fill: 0xFF0000 }); confirmationMsg.anchor.set(0.5, 0.5); confirmationMsg.x = 0; confirmationMsg.y = -400; // Position above characters self.characterButtons.addChild(confirmationMsg); // Fade out confirmation message tween(confirmationMsg, { alpha: 0 }, { delay: 1500, duration: 500, onFinish: function onFinish() { if (confirmationMsg.parent) { confirmationMsg.parent.removeChild(confirmationMsg); } // Force refresh the character selection screen if (typeof game.onCharacterSelectReset === 'function') { game.onCharacterSelectReset(); } } }); } }); } }); }; // Make back button interactive self.backButton.down = function (x, y, obj) { // Animate button press tween(self.backButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.backButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); // Animate button release tween(self.backButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(self.backButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Hide character select page and show title page if (self.parent) { self.parent.removeChild(self); } if (typeof game !== "undefined" && typeof titlePage !== "undefined") { game.addChild(titlePage); titlePage.alpha = 0; tween(titlePage, { alpha: 1 }, { duration: 500 }); // Set game state to title if (typeof gameState !== "undefined") { gameState = "title"; } } } }); } }); }; return self; }); var ChickenJockey = Container.expand(function () { var self = Container.call(this); // Create and attach character asset (default to chicken but will be updated) var chickenGraphics = self.attachAsset('chicken', { anchorX: 0.5, anchorY: 0.5 }); // Physics properties self.vx = 0; self.vy = 0; self.gravity = 0; // No gravity self.bounceDecay = 0.8; // Reduced energy loss per bounce self.friction = 0.99; // Reduced friction to maintain horizontal momentum self.launched = false; self.bounceCount = 0; self.maxBounces = 10; // Rotation properties self.rotationSpeed = 0; self.path = []; self.currentPathIndex = 0; self.pathSpeed = 15; // Speed at which chicken follows the path self.launch = function (power, angle, path) { // Store the path for later use self.path = path || []; self.currentPathIndex = 0; // Reset values self.vx = 0; self.vy = 0; self.rotationSpeed = power / 50; self.launched = true; self.bounceCount = 0; // Play launch sound LK.getSound('launch').play(); }; self.reset = function () { self.vx = 0; self.vy = 0; self.rotation = 0; self.rotationSpeed = 0; self.launched = false; self.bounceCount = 0; }; // Update the character asset self.updateCharacterAsset = function (assetName) { // Remove existing character graphic if (chickenGraphics && chickenGraphics.parent) { self.removeChild(chickenGraphics); } // Create and attach new character asset chickenGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); }; self.update = function () { if (!self.launched) { return; } // Special handling for bonus mode with D-pad if (gameMode === "bonus" && dPad && dPad.isMoving()) { // Get movement from d-pad var movement = dPad.getMovement(); // Apply movement directly self.vx = movement.dx; self.vy = movement.dy; // Update position self.x += self.vx; self.y += self.vy; // Apply rotation based on movement direction if (Math.abs(self.vx) > 0.1 || Math.abs(self.vy) > 0.1) { var targetRotation = Math.atan2(self.vy, self.vx); // Gradually rotate towards movement direction var rotDiff = targetRotation - self.rotation; // Normalize angle while (rotDiff > Math.PI) { rotDiff -= Math.PI * 2; } while (rotDiff < -Math.PI) { rotDiff += Math.PI * 2; } // Apply rotation self.rotation += rotDiff * 0.1; } // Enforce screen boundaries in bonus mode if (self.x < bounds.left) self.x = bounds.left; if (self.x > bounds.right) self.x = bounds.right; if (self.y < bounds.top) self.y = bounds.top; if (self.y > bounds.bottom) self.y = bounds.bottom; return; // Skip the rest of the update for D-pad control } // Path following for classic mode if (self.path.length > 0 && self.currentPathIndex < self.path.length) { // Get target point var targetPoint = self.path[self.currentPathIndex]; // Calculate direction to target var dx = targetPoint.x - self.x; var dy = targetPoint.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Move towards target point if (distance > self.pathSpeed) { self.vx = dx / distance * self.pathSpeed; self.vy = dy / distance * self.pathSpeed; } else { // Reached current target point, move to next self.currentPathIndex++; if (self.currentPathIndex >= self.path.length) { // End of path self.vx = 0; self.vy = 0; } } } else { // Apply friction when not following path self.vx *= self.friction; self.vy *= self.friction; } // Update position self.x += self.vx; self.y += self.vy; // Apply rotation based on movement direction if (Math.abs(self.vx) > 0.1 || Math.abs(self.vy) > 0.1) { var targetRotation = Math.atan2(self.vy, self.vx); // Gradually rotate towards movement direction var rotDiff = targetRotation - self.rotation; // Normalize angle while (rotDiff > Math.PI) { rotDiff -= Math.PI * 2; } while (rotDiff < -Math.PI) { rotDiff += Math.PI * 2; } // Apply rotation self.rotation += rotDiff * 0.1; } // Check if stopped (only in classic mode) if (gameMode !== "bonus" && Math.abs(self.vx) < 0.5 && Math.abs(self.vy) < 0.5 && (self.bounceCount > 0 || self.currentPathIndex >= self.path.length)) { self.launched = false; // Notify game that chicken jockey has stopped if (typeof game.onChickenJockeyStop === 'function') { game.onChickenJockeyStop(); } } // Check if max bounces reached if (self.bounceCount >= self.maxBounces) { self.launched = false; // Notify game that max bounces reached if (typeof game.onMaxBouncesReached === 'function') { game.onMaxBouncesReached(); } } }; return self; }); var DPad = Container.expand(function () { var self = Container.call(this); // Create d-pad buttons (up, down, left, right) self.buttonSize = 150; self.buttonSpacing = 10; // Create directional buttons self.upButton = new Container(); self.downButton = new Container(); self.leftButton = new Container(); self.rightButton = new Container(); // Create button visuals var upButtonBg = self.upButton.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.6 }); var downButtonBg = self.downButton.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.6 }); var leftButtonBg = self.leftButton.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.6 }); var rightButtonBg = self.rightButton.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.6 }); // Add arrow indicators var upArrow = self.upButton.attachAsset('aimLine', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 0.8, rotation: -Math.PI / 2, alpha: 0.9 }); var downArrow = self.downButton.attachAsset('aimLine', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 0.8, rotation: Math.PI / 2, alpha: 0.9 }); var leftArrow = self.leftButton.attachAsset('aimLine', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 0.8, rotation: Math.PI, alpha: 0.9 }); var rightArrow = self.rightButton.attachAsset('aimLine', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 0.8, rotation: 0, alpha: 0.9 }); // Position buttons in a cross layout self.upButton.x = 0; self.upButton.y = -(self.buttonSize + self.buttonSpacing); self.downButton.x = 0; self.downButton.y = self.buttonSize + self.buttonSpacing; self.leftButton.x = -(self.buttonSize + self.buttonSpacing); self.leftButton.y = 0; self.rightButton.x = self.buttonSize + self.buttonSpacing; self.rightButton.y = 0; // Add buttons to d-pad self.addChild(self.upButton); self.addChild(self.downButton); self.addChild(self.leftButton); self.addChild(self.rightButton); // Movement speed self.speed = 10; // Track which directions are pressed self.directions = { up: false, down: false, left: false, right: false }; // Button interaction handlers self.upButton.down = function (x, y, obj) { self.directions.up = true; tween(self.upButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.upButton.up = function (x, y, obj) { self.directions.up = false; tween(self.upButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; self.downButton.down = function (x, y, obj) { self.directions.down = true; tween(self.downButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.downButton.up = function (x, y, obj) { self.directions.down = false; tween(self.downButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; self.leftButton.down = function (x, y, obj) { self.directions.left = true; tween(self.leftButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.leftButton.up = function (x, y, obj) { self.directions.left = false; tween(self.leftButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; self.rightButton.down = function (x, y, obj) { self.directions.right = true; tween(self.rightButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.rightButton.up = function (x, y, obj) { self.directions.right = false; tween(self.rightButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; // Method to check if any direction is pressed self.isMoving = function () { return self.directions.up || self.directions.down || self.directions.left || self.directions.right; }; // Get the current movement direction for the character self.getMovement = function () { var dx = 0; var dy = 0; if (self.directions.up) dy -= self.speed; if (self.directions.down) dy += self.speed; if (self.directions.left) dx -= self.speed; if (self.directions.right) dx += self.speed; return { dx: dx, dy: dy }; }; return self; }); var GameModeSelect = Container.expand(function () { var self = Container.call(this); // Add backdrop var backdrop = self.attachAsset('Commandblock', { anchorX: 0.5, anchorY: 0.5, x: 1009, y: 1366, alpha: 0.8 }); // Add title var titleImage = self.attachAsset('Selectgame', { anchorX: 0.5, anchorY: 0, x: 1024, y: 150 }); // No title text needed as we use the Selectgame image instead // Create classic mode button self.classicModeButton = new Container(); self.classicModeButton.x = 614; self.classicModeButton.y = 1450; // No background needed for classic mode button // Use Classic asset instead of text var classicImg = self.classicModeButton.attachAsset('Classic', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // Create bonus mode button self.bonusModeButton = new Container(); self.bonusModeButton.x = 1059; self.bonusModeButton.y = 1450; // Use Bonusgame asset instead of text var bonusImg = self.bonusModeButton.attachAsset('Bonusgame', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, alpha: 1.0 }); // Create mini games button self.miniGamesButton = new Container(); self.miniGamesButton.x = 1509; self.miniGamesButton.y = 1450; // Minigame button has no background // Use Minigame asset instead of text var miniGamesImg = self.miniGamesButton.attachAsset('Minigame', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, alpha: 1.0 }); // Add back button self.backButton = new Container(); self.backButton.x = 150; self.backButton.y = 350; var backButtonImage = self.backButton.attachAsset('Backbutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }); self.addChild(self.classicModeButton); self.addChild(self.bonusModeButton); self.addChild(self.miniGamesButton); self.addChild(self.backButton); // Make classic mode button interactive self.classicModeButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.classicModeButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); tween(this, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(this, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Notify game of mode selection if (typeof game.onGameModeSelected === 'function') { game.onGameModeSelected("classic"); } } }); } }); }; // Make bonus mode button interactive self.bonusModeButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.bonusModeButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); tween(this, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(this, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Notify game of mode selection if (typeof game.onGameModeSelected === 'function') { game.onGameModeSelected("bonus"); } } }); } }); }; // Make mini games button interactive self.miniGamesButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.miniGamesButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); tween(this, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(this, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Notify game of mode selection if (typeof game.onGameModeSelected === 'function') { game.onGameModeSelected("minigames"); } } }); } }); }; // Make back button interactive self.backButton.down = function (x, y, obj) { tween(self.backButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.backButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); tween(self.backButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(self.backButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Hide game mode select page and show title page if (self.parent) { self.parent.removeChild(self); } if (typeof game !== "undefined" && typeof titlePage !== "undefined") { game.addChild(titlePage); titlePage.alpha = 0; tween(titlePage, { alpha: 1 }, { duration: 500 }); // Set game state to title if (typeof gameState !== "undefined") { gameState = "title"; } } } }); } }); }; return self; }); var HighScorePage = Container.expand(function () { var self = Container.call(this); // Add backdrop for high score page var backdrop = self.attachAsset('Hiscorebackdrop', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, alpha: 0.8, scaleX: 1, scaleY: 1 }); // Add title using Highscorestitle asset var titleImage = self.attachAsset('Highscorestitle', { anchorX: 0.5, anchorY: 0, x: 1024, y: 550 }); // Container for score entries self.scoreEntries = new Container(); self.scoreEntries.x = 1024; self.scoreEntries.y = 800; self.addChild(self.scoreEntries); // Back button self.backButton = new Container(); self.backButton.x = 1024; self.backButton.y = 2000; // Button using Backbutton asset var buttonBackground = self.backButton.attachAsset('Backbutton', { anchorX: 0.5, anchorY: 0.5 }); // No back text - using only the Backbutton asset // Add back button to high score page self.addChild(self.backButton); // Reset button - positioned to the right of back button self.resetButton = new Container(); self.resetButton.x = 1040; // Moved right 40 pixels self.resetButton.y = 2300; // Moved down 300 pixels // Create reset button using the Resetscores asset var resetButtonImage = self.resetButton.attachAsset('Resetscores', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }); // Add reset button to high score page self.addChild(self.resetButton); // Make back button interactive self.backButton.down = function (x, y, obj) { // Animate button press tween(self.backButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.backButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); // Animate button release tween(self.backButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(self.backButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Notify game that back button was pressed if (typeof game.onBackButtonPressed === 'function') { game.onBackButtonPressed(); } } }); } }); }; // Make reset button interactive self.resetButton.down = function (x, y, obj) { // Animate button press tween(self.resetButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.resetButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); // Animate button release tween(self.resetButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(self.resetButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Clear high scores and update display storage.highScores = []; self.updateScores(); // Flash confirmation message var confirmationMsg = new Text2("High scores reset!", { size: 70, fill: 0xFF0000 }); confirmationMsg.anchor.set(0.5, 0.5); confirmationMsg.x = 0; confirmationMsg.y = -200; // Position above scores self.scoreEntries.addChild(confirmationMsg); // Fade out confirmation message tween(confirmationMsg, { alpha: 0 }, { delay: 1500, duration: 500, onFinish: function onFinish() { if (confirmationMsg.parent) { confirmationMsg.parent.removeChild(confirmationMsg); } } }); } }); } }); }; // Update high scores display self.updateScores = function () { // Clear existing score entries while (self.scoreEntries.children.length > 0) { self.scoreEntries.removeChild(self.scoreEntries.children[0]); } // Get high scores from storage var highScores = storage.highScores || []; // Sort high scores in descending order highScores.sort(function (a, b) { return b - a; }); // Keep only top 5 scores highScores = highScores.slice(0, 5); // Track number of registered high scores storage.registeredScores = highScores.length; // Check if Piglin should be unlocked (after 5 high scores) if (storage.registeredScores >= 5 && storage.piglinUnlocked !== true) { // Removed unlock condition for Shooting Stars based on high score // DeezNuts character is automatically unlocked (removed condition check) storage.deezNutsUnlocked = true; storage.piglinUnlocked = true; // Create unlocked notification using piglinunlocked asset instead of text var unlockedMsg = LK.getAsset('Piglinunlocked', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -300 }); self.scoreEntries.addChild(unlockedMsg); // Immediately remove padlock for Piglin if (characterSelectPage) { for (var i = 0; i < characterSelectPage.characters.length; i++) { var character = characterSelectPage.characters[i]; if (character.asset === "piglinjockey" && characterSelectPage.characterButtons.children[i].lockedImg) { characterSelectPage.characterButtons.children[i].lockedImg.parent.removeChild(characterSelectPage.characterButtons.children[i].lockedImg); } } } // Animate and remove the notification tween(unlockedMsg, { scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, onFinish: function onFinish() { // Play Piglin sound to acknowledge unlock LK.getSound('Pignoise').play(); // Hold for a moment then fade out LK.setTimeout(function () { tween(unlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (unlockedMsg.parent) { unlockedMsg.parent.removeChild(unlockedMsg); } } }); }, 500); } }); } // Display each score var yPos = 0; for (var i = 0; i < highScores.length; i++) { var scoreText = new Text2(i + 1 + ". " + highScores[i], { size: 70, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.y = yPos; self.scoreEntries.addChild(scoreText); yPos += 100; } // If no scores yet, show a message if (highScores.length === 0) { var noScoresText = new Text2("No scores yet!", { size: 70, fill: 0xFFFFFF }); noScoresText.anchor.set(0.5, 0); self.scoreEntries.addChild(noScoresText); } // Show progress towards unlocking Piglin if (!storage.piglinUnlocked) { var scoresRemaining = Math.max(0, 5 - storage.registeredScores); var progressText = new Text2("Register " + scoresRemaining + " more high score" + (scoresRemaining !== 1 ? "s" : "") + " to unlock Piglin", { size: 40, fill: 0xFFFFFF }); progressText.anchor.set(0.5, 0.5); progressText.x = 0; progressText.y = 600; self.scoreEntries.addChild(progressText); } }; return self; }); var Launcher = Container.expand(function () { var self = Container.call(this); // Create and attach launcher asset with alpha 0 to make it invisible var launcherGraphics = self.attachAsset('launcher', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Create aim line (initially invisible) var aimLine = self.attachAsset('aimLine', { anchorX: 0, anchorY: 0.5, alpha: 0 }); // Launcher properties self.angle = -45; // Starting angle in degrees self.power = 20; // Increased starting power self.maxPower = 40; // Increased maximum power self.aiming = false; self.drawingPath = false; self.points = []; self.startX = 0; self.startY = 0; self.currentX = 0; self.currentY = 0; self.lastPointTime = 0; self.pathStep = 0; // Create trajectory path visualization self.trajectoryPath = new TrajectoryPath(); // Start aim by drawing a path self.startAim = function (x, y) { self.aiming = true; self.drawingPath = true; self.startX = x; self.startY = y; self.currentX = x; self.currentY = y; self.points = [{ x: x, y: y }]; self.lastPointTime = LK.ticks; // Show the trajectory path if (self.trajectoryPath.parent) { self.trajectoryPath.show(); } // Start path tracking for S detection if (pathTracker) { pathTracker.startTracking(); pathTracker.addPoint(x, y); } }; // Store for drawing path self.pathGraphics = new Container(); self.addChild(self.pathGraphics); self.updateAim = function (x, y) { if (!self.aiming) { return; } if (self.drawingPath) { // Update current position self.currentX = x; self.currentY = y; // Add a point every few frames to avoid too many points if (LK.ticks - self.lastPointTime > 2) { self.points.push({ x: x, y: y }); // Track point for S detection if (pathTracker) { pathTracker.addPoint(x, y); } // Visualize the path point var pathPoint = LK.getAsset('aimLine', { anchorX: 0.5, anchorY: 0.5, x: x, y: y, scaleX: 0.3, scaleY: 0.3, alpha: 0.7 }); self.pathGraphics.addChild(pathPoint); self.lastPointTime = LK.ticks; // Update trajectory path to show the actual path if (self.trajectoryPath.parent && self.points.length > 1) { self.trajectoryPath.updatePathFromPoints(self.points); } } // Calculate direction vector from start to current position var dx = x - self.startX; var dy = y - self.startY; // Calculate angle in degrees (0 is right, 90 is up) self.angle = Math.atan2(dy, dx) * 180 / Math.PI; // Calculate power based on path length var distance = Math.sqrt(dx * dx + dy * dy); self.power = Math.min(distance / 10, self.maxPower); // Update launcher rotation self.rotation = self.angle * Math.PI / 180; } }; self.endAim = function () { self.aiming = false; self.drawingPath = false; // Hide trajectory path if (self.trajectoryPath.parent) { self.trajectoryPath.hide(); } // Keep a copy of the path points var pathPoints = self.points.slice(); // Clear the path visualization after a delay LK.setTimeout(function () { // Remove all path point graphics while (self.pathGraphics.children.length > 0) { self.pathGraphics.removeChild(self.pathGraphics.children[0]); } }, 500); // Check if an S pattern or star pattern was detected if (pathTracker) { var patternDetected = pathTracker.stopTracking(); if (patternDetected) { // Check which pattern was detected if (pathTracker.sDetected && !skeletonUnlocked) { // Unlock skeleton character skeletonUnlocked = true; storage.skeletonUnlocked = true; // Play skeleton sound LK.getSound('Skeleton').play(); // Create and show unlock message using skeletonunlocked asset var unlockMsg = LK.getAsset('Skeletonunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(unlockMsg); // Animate and remove the notification tween(unlockMsg, { scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(unlockMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (unlockMsg.parent) { unlockMsg.parent.removeChild(unlockMsg); } } }); }, 500); } }); } else if (pathTracker.starDetected && !storage.shootingStarsUnlocked) { // Unlock Shooting Stars character storage.shootingStarsUnlocked = true; // Play Starz sound when Shooting Stars is unlocked LK.getSound('Starz').play(); // Play Shooting Stars sound LK.getSound('Shootingstars').play(); // Create and show unlock message using Shootingstarsunlocked asset var starsUnlockMsg = LK.getAsset('Shootingstarsunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(starsUnlockMsg); // Immediately remove padlock for Shooting Stars if on character select screen if (characterSelectPage) { for (var i = 0; i < characterSelectPage.characters.length; i++) { var character = characterSelectPage.characters[i]; if (character.asset === "Shootingstars" && characterSelectPage.characterButtons.children[i].lockedImg) { characterSelectPage.characterButtons.children[i].lockedImg.parent.removeChild(characterSelectPage.characterButtons.children[i].lockedImg); } } } // Animate and remove the notification tween(starsUnlockMsg, { scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(starsUnlockMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (starsUnlockMsg.parent) { starsUnlockMsg.parent.removeChild(starsUnlockMsg); } } }); }, 500); } }); } } } // Calculate final launch parameters var finalAngle = self.angle + 180; // Reverse direction // Return launch parameters return { angle: finalAngle, power: self.power }; }; return self; }); var NumberPattern = Container.expand(function () { var self = Container.call(this); // Patterns for numbers 1-9, each represented as a 5x5 grid // 1 = popcorn, 0 = empty space self.patterns = { 1: [[0, 0, 1, 0, 0], [0, 1, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 1, 1, 1, 0]], 2: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [0, 0, 1, 1, 0], [0, 1, 0, 0, 0], [1, 1, 1, 1, 1]], 3: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [0, 0, 1, 1, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], 4: [[0, 0, 1, 1, 0], [0, 1, 0, 1, 0], [1, 0, 0, 1, 0], [1, 1, 1, 1, 1], [0, 0, 0, 1, 0]], 5: [[1, 1, 1, 1, 1], [1, 0, 0, 0, 0], [1, 1, 1, 1, 0], [0, 0, 0, 0, 1], [1, 1, 1, 1, 0]], 6: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], 7: [[1, 1, 1, 1, 1], [0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 0, 0]], 8: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]], 9: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 1], [0, 0, 0, 0, 1], [0, 1, 1, 1, 0]] }; // Create popcorn in a number pattern self.createPattern = function (number, centerX, centerY, spacing) { if (number < 1 || number > 9 || !self.patterns[number]) { return []; } var pattern = self.patterns[number]; var patternHeight = pattern.length; var patternWidth = pattern[0].length; var createdPopcorns = []; // Calculate starting position to center the pattern var startX = centerX - patternWidth * spacing / 2; var startY = centerY - patternHeight * spacing / 2; // Create popcorn for each position in the pattern for (var row = 0; row < patternHeight; row++) { for (var col = 0; col < patternWidth; col++) { if (pattern[row][col] === 1) { // Create multiple popcorn in each position to make pattern denser var numPopcornPerSpot = 4; // Add 4 popcorn per pattern spot var offset = spacing / 5; // Small offset to spread them out for (var p = 0; p < numPopcornPerSpot; p++) { var popcorn = new Popcorn(); // Add small random offset for each popcorn to create a cluster var offsetX = p % 2 * offset - offset / 2; var offsetY = Math.floor(p / 2) * offset - offset / 2; popcorn.x = startX + col * spacing + offsetX; popcorn.y = startY + row * spacing + offsetY; createdPopcorns.push(popcorn); } } } } return createdPopcorns; }; return self; }); var PathTracker = Container.expand(function () { var self = Container.call(this); // Path tracking properties self.isTracking = false; self.pathPoints = []; self.sDetected = false; self.starDetected = false; // Track if star pattern is detected // Start tracking a new path self.startTracking = function () { self.isTracking = true; self.pathPoints = []; self.sDetected = false; self.starDetected = false; // Reset star pattern detection }; // Add a point to the tracking path self.addPoint = function (x, y) { if (!self.isTracking) { return; } // Add point to path self.pathPoints.push({ x: x, y: y }); // Check for patterns if we have enough points if (self.pathPoints.length > 20) { self.checkForSPattern(); self.checkForStarPattern(); // Also check for star pattern } }; // Stop tracking self.stopTracking = function () { self.isTracking = false; // Return true if either S or star pattern was detected return self.sDetected || self.starDetected; }; // Check if the path forms an S pattern self.checkForSPattern = function () { if (self.pathPoints.length < 20) { return false; } // Analyze path for S shape // An S shape should go from top to bottom with two major direction changes // Find bounding box of the path var minX = self.pathPoints[0].x; var maxX = self.pathPoints[0].x; var minY = self.pathPoints[0].y; var maxY = self.pathPoints[0].y; for (var i = 1; i < self.pathPoints.length; i++) { minX = Math.min(minX, self.pathPoints[i].x); maxX = Math.max(maxX, self.pathPoints[i].x); minY = Math.min(minY, self.pathPoints[i].y); maxY = Math.max(maxY, self.pathPoints[i].y); } // Check if path has enough height and width to be an S var width = maxX - minX; var height = maxY - minY; if (height < 300 || width < 200) { return false; } // Divide path into vertical thirds var topThird = minY + height / 3; var bottomThird = maxY - height / 3; // Count direction changes (left/right) in top, middle and bottom sections var topSection = self.analyzeSection(self.pathPoints, minY, topThird); var middleSection = self.analyzeSection(self.pathPoints, topThird, bottomThird); var bottomSection = self.analyzeSection(self.pathPoints, bottomThird, maxY); // For an S pattern, typically: // - Top section has rightward movement // - Middle section has leftward movement // - Bottom section has rightward movement if (topSection.direction === "right" && middleSection.direction === "left" && bottomSection.direction === "right") { self.sDetected = true; return true; } // Also check reverse S pattern if (topSection.direction === "left" && middleSection.direction === "right" && bottomSection.direction === "left") { self.sDetected = true; return true; } return false; }; // Check if the path forms a star pattern self.checkForStarPattern = function () { if (self.pathPoints.length < 20) { return false; } // Analyze path for star shape // Find the center point of all path points var centerX = 0; var centerY = 0; for (var i = 0; i < self.pathPoints.length; i++) { centerX += self.pathPoints[i].x; centerY += self.pathPoints[i].y; } centerX /= self.pathPoints.length; centerY /= self.pathPoints.length; // A star pattern should have at least 5 peaks (points extending outward) // and 5 valleys (points returning inward) var peaks = []; var valleys = []; var distanceThreshold = 100; // Minimum peak distance from center var minPeaks = 5; // Minimum number of peaks to be considered a star // Calculate distance from center for each point var distances = []; for (var i = 0; i < self.pathPoints.length; i++) { var dx = self.pathPoints[i].x - centerX; var dy = self.pathPoints[i].y - centerY; var distance = Math.sqrt(dx * dx + dy * dy); distances.push(distance); } // Find peaks (local maxima) in the distance function for (var i = 5; i < self.pathPoints.length - 5; i++) { var isPeak = true; var isValley = true; // Check if this is a peak for (var j = i - 5; j <= i + 5; j++) { if (j === i) { continue; } if (distances[j] > distances[i]) { isPeak = false; } if (distances[j] < distances[i]) { isValley = false; } } // Add to peaks if it's far enough from center if (isPeak && distances[i] > distanceThreshold) { peaks.push(i); } // Add to valleys if (isValley) { valleys.push(i); } } // For a star pattern, we need at least 5 peaks if (peaks.length >= minPeaks) { // Check that peaks are somewhat evenly distributed around the center var angles = []; for (var i = 0; i < peaks.length; i++) { var idx = peaks[i]; var dx = self.pathPoints[idx].x - centerX; var dy = self.pathPoints[idx].y - centerY; var angle = Math.atan2(dy, dx); if (angle < 0) { angle += 2 * Math.PI; } // Normalize to [0, 2π] angles.push(angle); } // Sort angles angles.sort(function (a, b) { return a - b; }); // Check for relatively even spacing between peaks var isEvenlySpaced = true; var idealSpacing = 2 * Math.PI / angles.length; var spacingTolerance = idealSpacing * 0.5; // 50% tolerance for (var i = 0; i < angles.length; i++) { var nextIdx = (i + 1) % angles.length; var spacing = angles[nextIdx] - angles[i]; if (spacing < 0) { spacing += 2 * Math.PI; } if (Math.abs(spacing - idealSpacing) > spacingTolerance) { isEvenlySpaced = false; break; } } // If we have enough peaks and they're evenly spaced, it's a star if (isEvenlySpaced) { self.starDetected = true; return true; } } return false; }; // Analyze a section of the path for predominant horizontal direction self.analyzeSection = function (points, minY, maxY) { var leftwardMovement = 0; var rightwardMovement = 0; // Find points in this vertical section var sectionPoints = []; for (var i = 0; i < points.length; i++) { if (points[i].y >= minY && points[i].y <= maxY) { sectionPoints.push(points[i]); } } // Sort points by y-coordinate sectionPoints.sort(function (a, b) { return a.y - b.y; }); // Calculate horizontal movement through the section for (var i = 1; i < sectionPoints.length; i++) { var dx = sectionPoints[i].x - sectionPoints[i - 1].x; if (dx > 0) { rightwardMovement += dx; } else if (dx < 0) { leftwardMovement += Math.abs(dx); } } return { direction: rightwardMovement > leftwardMovement ? "right" : "left", rightwardMovement: rightwardMovement, leftwardMovement: leftwardMovement }; }; return self; }); var Popcorn = Container.expand(function () { var self = Container.call(this); // Create and attach popcorn asset // Create and attach popcorn asset based on selected character var popcornGraphics = self.attachAsset(selectedCharacter === "Joenugget" ? 'Drumstick' : selectedCharacter === "Grimacejockey" ? 'Shakes' : selectedCharacter === "Johncena" ? 'Belt' : selectedCharacter === "Shootingstars" ? 'Stars' : selectedCharacter === "Deeznuts" ? 'Nuts' : selectedCharacter === "Rickroll" ? 'Hearts' : selectedCharacter === "Shrekwizowski" ? 'Shrekcorn' : selectedCharacter === "Pomni" ? 'Circuspop' : 'popcorn', { anchorX: 0.5, anchorY: 0.5 }); // Add slight animation self.animationOffset = Math.random() * Math.PI * 2; self.animationSpeed = 0.03 + Math.random() * 0.02; self.baseY = 0; self.updateAsset = function (assetName) { if (popcornGraphics && popcornGraphics.parent) { self.removeChild(popcornGraphics); } popcornGraphics = self.attachAsset(selectedCharacter === "Joenugget" ? 'Drumstick' : selectedCharacter === "Grimacejockey" ? 'Shakes' : selectedCharacter === "Johncena" ? 'Belt' : selectedCharacter === "Pomni" ? 'Circuspop' : assetName, { anchorX: 0.5, anchorY: 0.5 }); }; self.collect = function () { // Play collect sound LK.getSound('pop').play(); // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 200); // Animate collection with spinning and scaling tween(self, { y: self.y - 100, rotation: Math.PI * 4, // Spin multiple times scaleX: 1.5, // Grow while spinning scaleY: 1.5, // Grow while spinning alpha: 0 }, { duration: 800, // Longer duration for more visible animation easing: tween.easeOut, onFinish: function onFinish() { // Remove from parent if (self.parent) { self.parent.removeChild(self); } } }); }; self.update = function () { // Hover animation if (self.baseY === 0) { self.baseY = self.y; self.targetX = self.x; self.targetY = self.y; self.moveTimer = 0; self.moveDuration = 180 + Math.random() * 120; // 3-5 seconds at 60fps } // Smooth hovering self.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 5; // Random movement self.moveTimer++; if (self.moveTimer >= self.moveDuration) { // Set new random target within arena bounds (with padding) var padding = 200; var newX = bounds.left + padding + Math.random() * (arena.width - padding * 2); var newY = bounds.top + padding + Math.random() * (arena.height - padding * 2); // Check distance from ropes var validPosition = true; for (var j = 0; j < ropes.length; j++) { var dx = newX - ropes[j].x; var dy = newY - ropes[j].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { validPosition = false; break; } } if (validPosition) { self.targetX = newX; self.targetY = newY; self.baseY = newY; self.moveTimer = 0; } } // Move toward target with easing if (self.targetX !== self.x || self.targetY !== self.y) { self.x += (self.targetX - self.x) * 0.01; self.y += (self.targetY - self.y) * 0.01; } // Ensure popcorn stays within the rope boundaries var padding = 150; // Minimum distance from ropes if (self.x < bounds.left + padding) { self.x = bounds.left + padding; self.targetX = self.x; } else if (self.x > bounds.right - padding) { self.x = bounds.right - padding; self.targetX = self.x; } if (self.y < bounds.top + padding) { self.y = bounds.top + padding; self.targetY = self.y; self.baseY = self.y; } else if (self.y > bounds.bottom - padding) { self.y = bounds.bottom - padding; self.targetY = self.y; self.baseY = self.y; } }; return self; }); var Rope = Container.expand(function () { var self = Container.call(this); // Create and attach rope asset var ropeGraphics = self.attachAsset('rope', { anchorX: 0.5, anchorY: 0.5 }); // Rope properties self.tension = 0; // No tension for no bounce effect self.bounce = function (chickenJockey) { // No velocity change - completely removed bounce effect // Set velocity to zero in the direction of the rope if (self.rotation === 0 || self.rotation === Math.PI) { // Horizontal rope (top or bottom) chickenJockey.vy = 0; } else { // Vertical rope (left or right) chickenJockey.vx = 0; } // Still increment bounce count for tracking chickenJockey.bounceCount++; // Play bounce sound LK.getSound('bounce').play(); // Flash rope to indicate contact LK.effects.flashObject(self, 0xFFFFFF, 200); }; self.intersectsWithPoint = function (x, y) { var halfWidth = ropeGraphics.width / 2; var halfHeight = ropeGraphics.height / 2; // Check if point is within the rope's bounding box return x >= self.x - halfWidth && x <= self.x + halfWidth && y >= self.y - halfHeight && y <= self.y + halfHeight; }; return self; }); var Superpopcorn = Container.expand(function () { var self = Container.call(this); // Create and attach Superpopcorn asset // Create and attach Superpopcorn asset based on selected character var superPopcornGraphics = self.attachAsset(selectedCharacter === "Shootingstars" ? 'Whitestars' : selectedCharacter === "Deeznuts" ? 'Cashew' : selectedCharacter === "Rickroll" ? 'Purpleheart' : selectedCharacter === "Grimacejockey" ? 'Fries' : selectedCharacter === "Johncena" ? 'Wwe' : selectedCharacter === "Shrekwizowski" ? 'Shrekcorn' : selectedCharacter === "Pomni" ? 'Digpop' : 'Superpopcorn', { anchorX: 0.5, anchorY: 0.5 }); // Add slight animation self.animationOffset = Math.random() * Math.PI * 2; self.animationSpeed = 0.03 + Math.random() * 0.02; self.baseY = 0; self.updateAsset = function (assetName) { if (superPopcornGraphics && superPopcornGraphics.parent) { self.removeChild(superPopcornGraphics); } superPopcornGraphics = self.attachAsset(selectedCharacter === "Joenugget" ? 'Popchicken' : selectedCharacter === "Grimacejockey" ? 'Fries' : selectedCharacter === "Johncena" ? 'Wwe' : selectedCharacter === "Shrekwizowski" ? 'Shrekcorn' : selectedCharacter === "Pomni" ? 'Digpop' : assetName, { anchorX: 0.5, anchorY: 0.5 }); }; self.collect = function () { // Play collect sound LK.getSound('pop').play(); LK.getSound('collect').play(); // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 200); // Animate collection with spinning and scaling tween(self, { y: self.y - 150, // Fly higher for superpopcorn rotation: Math.PI * 6, // Spin more times for superpopcorn scaleX: 2.0, // Grow larger while spinning scaleY: 2.0, // Grow larger while spinning alpha: 0 }, { duration: 1000, // Longer duration for more visible animation easing: tween.easeOut, onFinish: function onFinish() { // Remove from parent if (self.parent) { self.parent.removeChild(self); } } }); }; self.update = function () { // Hover animation if (self.baseY === 0) { self.baseY = self.y; self.targetX = self.x; self.targetY = self.y; self.moveTimer = 0; self.moveDuration = 120 + Math.random() * 60; // 2-3 seconds at 60fps (faster than regular popcorn) } // Smooth hovering with larger amplitude for superpopcorn self.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 8; // Random movement self.moveTimer++; if (self.moveTimer >= self.moveDuration) { // Set new random target within arena bounds (with padding) var padding = 200; var newX = bounds.left + padding + Math.random() * (arena.width - padding * 2); var newY = bounds.top + padding + Math.random() * (arena.height - padding * 2); // Check distance from ropes var validPosition = true; for (var j = 0; j < ropes.length; j++) { var dx = newX - ropes[j].x; var dy = newY - ropes[j].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { validPosition = false; break; } } if (validPosition) { self.targetX = newX; self.targetY = newY; self.baseY = newY; self.moveTimer = 0; } } // Move toward target with easing (slightly faster than regular popcorn) if (self.targetX !== self.x || self.targetY !== self.y) { self.x += (self.targetX - self.x) * 0.015; self.y += (self.targetY - self.y) * 0.015; } // Ensure superpopcorn stays within the rope boundaries var padding = 150; // Minimum distance from ropes if (self.x < bounds.left + padding) { self.x = bounds.left + padding; self.targetX = self.x; } else if (self.x > bounds.right - padding) { self.x = bounds.right - padding; self.targetX = self.x; } if (self.y < bounds.top + padding) { self.y = bounds.top + padding; self.targetY = self.y; self.baseY = self.y; } else if (self.y > bounds.bottom - padding) { self.y = bounds.bottom - padding; self.targetY = self.y; self.baseY = self.y; } }; return self; }); var TitlePage = Container.expand(function () { var self = Container.call(this); // Add title screen background var titleBackground = self.attachAsset('Titlescreen', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); // Make title screen tappable to unlock Grimace titleBackground.down = function (x, y, obj) { grimaceTaps++; if (grimaceTaps === 5 && !grimaceUnlocked) { grimaceUnlocked = true; storage.grimaceUnlocked = true; // Play Maccas sound when Grimace is unlocked LK.getSound('Maccas').play(); // Update character buttons to remove padlock from Grimace and MJ if unlocked updateCharacterButtons(); // Create unlocked notification using grimaceunlocked asset var grimaceUnlockedMsg = LK.getAsset('Grimaceunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 0.8, scaleY: 0.8 }); // Replace grimacejockey with grimaceunlocked asset when unlocked if (characterSelectPage) { for (var i = 0; i < characterSelectPage.characters.length; i++) { var character = characterSelectPage.characters[i]; if (character.asset === "Grimacejockey" && characterSelectPage.characterButtons.children[i]) { var button = characterSelectPage.characterButtons.children[i]; // Remove existing character image for (var j = 0; j < button.children.length; j++) { if (button.children[j].assetId === "Grimacejockey") { button.removeChild(button.children[j]); break; } } // Add grimaceunlocked asset instead var grimaceImg = button.attachAsset('Grimaceunlocked', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7 }); } } } game.addChild(grimaceUnlockedMsg); // Animate and remove the notification tween(grimaceUnlockedMsg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(grimaceUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (grimaceUnlockedMsg.parent) { grimaceUnlockedMsg.parent.removeChild(grimaceUnlockedMsg); } } }); }, 500); } }); } }; // Add unlock progress text // Create start button self.startButton = new Container(); self.startButton.x = 1024; self.startButton.y = 1650; // Button using Startbutton asset var buttonBackground = self.startButton.attachAsset('Startbutton', { anchorX: 0.5, anchorY: 0.5 }); // Create high scores button (positioned below start button) self.highScoresButton = new Container(); self.highScoresButton.x = 1024; self.highScoresButton.y = 1900; // Button using Hiscorebutton asset var hsButtonBackground = self.highScoresButton.attachAsset('Hiscorebutton', { anchorX: 0.5, anchorY: 0.5 }); // Add both buttons to title page self.addChild(self.startButton); self.addChild(self.highScoresButton); // Make start button interactive self.startButton.down = function (x, y, obj) { // Animate button press tween(self.startButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.startButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); // Animate button release tween(self.startButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(self.startButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Notify game that start button was pressed if (typeof game.onStartButtonPressed === 'function') { game.onStartButtonPressed(); } } }); } }); }; // Make high scores button interactive self.highScoresButton.down = function (x, y, obj) { // Animate button press tween(self.highScoresButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.highScoresButton.up = function (x, y, obj) { // Play pop sound LK.getSound('pop').play(); // Animate button release tween(self.highScoresButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150, onFinish: function onFinish() { tween(self.highScoresButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { // Notify game that high scores button was pressed if (typeof game.onHighScoresButtonPressed === 'function') { game.onHighScoresButtonPressed(); } } }); } }); }; return self; }); var TrajectoryPath = Container.expand(function () { var self = Container.call(this); // Properties self.points = []; self.maxPoints = 40; // Increased number of trajectory points for better visualization self.visible = false; // Create path line graphics self.pathLine = new Container(); self.addChild(self.pathLine); // Create trajectory points self.createPoints = function () { // Clear existing points for (var i = 0; i < self.points.length; i++) { self.removeChild(self.points[i]); } self.points = []; // Create new points for (var i = 0; i < self.maxPoints; i++) { var point = new TrajectoryPoint(); point.alpha = 1 - i / self.maxPoints; self.addChild(point); self.points.push(point); } }; // Update trajectory path based on path points self.updatePathFromPoints = function (pathPoints) { if (!self.visible || !pathPoints || pathPoints.length < 2) { return; } // Clear existing path visualization while (self.pathLine.children.length > 0) { self.pathLine.removeChild(self.pathLine.children[0]); } // Draw path line segments for (var i = 0; i < pathPoints.length - 1; i++) { self.drawPathSegment(pathPoints[i], pathPoints[i + 1], i, pathPoints.length); } // Update trajectory points along the path for (var i = 0; i < self.points.length; i++) { var pointIndex = Math.floor(i * (pathPoints.length - 1) / self.points.length); if (pointIndex < pathPoints.length - 1) { var percent = i * (pathPoints.length - 1) / self.points.length - pointIndex; var p1 = pathPoints[pointIndex]; var p2 = pathPoints[pointIndex + 1]; self.points[i].x = p1.x + (p2.x - p1.x) * percent; self.points[i].y = p1.y + (p2.y - p1.y) * percent; self.points[i].alpha = 0.7 * (1 - i / self.points.length); } } }; // Draw a segment of the path between two points self.drawPathSegment = function (p1, p2, index, total) { var segment = LK.getAsset('aimLine', { anchorX: 0, anchorY: 0.5, alpha: 0.6 * (1 - index / total), scaleX: 0.5, scaleY: 0.3 }); // Position at start point segment.x = p1.x; segment.y = p1.y; // Calculate segment length and angle var dx = p2.x - p1.x; var dy = p2.y - p1.y; var distance = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); // Set length and rotation segment.width = distance; segment.rotation = angle; self.pathLine.addChild(segment); }; // Update trajectory path based on launch parameters self.updatePath = function (startX, startY, angle, power) { if (!self.visible) { return; } // Convert angle to radians var radians = angle * Math.PI / 180; // Calculate initial velocity var vx = Math.cos(radians) * power; var vy = Math.sin(radians) * power; // Simulate trajectory for each point var x = startX; var y = startY; var tempVX = vx; var tempVY = vy; for (var i = 0; i < self.points.length; i++) { // Update position based on velocity x += tempVX; y += tempVY; // Apply only friction (no gravity) tempVX *= 0.99; // friction // Position the trajectory point self.points[i].x = x; self.points[i].y = y; } }; // Show trajectory self.show = function () { self.visible = true; self.pathLine.alpha = 1; for (var i = 0; i < self.points.length; i++) { self.points[i].alpha = 1 - i / self.maxPoints; } }; // Hide trajectory self.hide = function () { self.visible = false; self.pathLine.alpha = 0; for (var i = 0; i < self.points.length; i++) { self.points[i].alpha = 0; } }; // Initialize points on creation self.createPoints(); return self; }); var TrajectoryPoint = Container.expand(function () { var self = Container.call(this); // Create and attach point asset var pointGraphics = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.2, scaleY: 0.2, alpha: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Black background }); /**** * Game Code ****/ // Game state var gameState = "title"; // title, gameModeSelect, characterSelect, ready, aiming, launched, gameOver, highScores var gameMode = "classic"; // classic or bonus var score = 0; var launches = 0; var maxLaunches = 10; var bonusTimer = 30; // 30 second countdown for bonus mode var bonusTimerInterval = null; // Store timer interval reference var bonusTimerText = null; // Text element for the timer var popcorns = []; var superPopcorns = []; var ropes = []; var bonusApplied = false; var bonusAnimation = null; var titlePage = null; var highScorePage = null; var gameModeSelectPage = null; var characterSelectPage = null; var selectedCharacter = "chicken"; // Default character var pathTracker = new PathTracker(); // Add path tracker for S detection var skeletonUnlocked = false; // Track if skeleton has been unlocked through S pattern var grimaceTaps = 0; // Counter for taps on title screen var grimaceUnlocked = false; // Track if Grimace character is unlocked var dPad = null; // D-pad controls for bonus mode // Create popcorn in a spiral pattern from the center function createSpiralPopcorn(count) { // Clear existing popcorn first for (var i = 0; i < popcorns.length; i++) { if (popcorns[i].parent) { popcorns[i].parent.removeChild(popcorns[i]); } } popcorns = []; // Parameters to control the spiral var centerX = 2048 / 2; var centerY = 2732 / 2; var radiusStart = 100; // Starting radius var radiusIncrement = 15; // How much the radius increases per popcorn var angleIncrement = 0.5; // How much the angle changes per popcorn (in radians) // Available popcorn asset types for variety var popcornAssets = ['popcorn', 'Drumstick', 'Shakes', 'Belt', 'Stars', 'Nuts', 'Hearts', 'Shrekcorn', 'Circuspop']; // Create popcorn in a spiral pattern var angle = 0; var radius = radiusStart; for (var i = 0; i < count; i++) { var popcorn = new Popcorn(); // Calculate position using polar coordinates var x = centerX + radius * Math.cos(angle); var y = centerY + radius * Math.sin(angle); // Set position popcorn.x = x; popcorn.y = y; // Assign a random popcorn asset type for variety var randomAsset = popcornAssets[Math.floor(Math.random() * popcornAssets.length)]; popcorn.updateAsset(randomAsset); // Add to game game.addChild(popcorn); popcorns.push(popcorn); // Increment angle and radius for next popcorn angle += angleIncrement; radius += radiusIncrement; } } // Function to update character buttons when a character is unlocked function updateCharacterButtons() { if (characterSelectPage) { for (var i = 0; i < characterSelectPage.characters.length; i++) { var character = characterSelectPage.characters[i]; if (character.asset === "Grimacejockey" && grimaceUnlocked && characterSelectPage.characterButtons.children[i].lockedImg) { characterSelectPage.characterButtons.children[i].lockedImg.parent.removeChild(characterSelectPage.characterButtons.children[i].lockedImg); } if (character.asset === "Michaeljackson" && storage.mjUnlocked && characterSelectPage.characterButtons.children[i].lockedImg) { characterSelectPage.characterButtons.children[i].lockedImg.parent.removeChild(characterSelectPage.characterButtons.children[i].lockedImg); // Show MJ unlocked asset when MJ is unlocked var mjUnlockedMsg = LK.getAsset('MJunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(mjUnlockedMsg); // Animate and remove the notification tween(mjUnlockedMsg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(mjUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (mjUnlockedMsg.parent) { mjUnlockedMsg.parent.removeChild(mjUnlockedMsg); } } }); }, 500); } }); } if (character.asset === "Johncena" && storage.johnCenaUnlocked && characterSelectPage.characterButtons.children[i].lockedImg) { characterSelectPage.characterButtons.children[i].lockedImg.parent.removeChild(characterSelectPage.characterButtons.children[i].lockedImg); // Show John Cena unlocked asset when John Cena is unlocked var johncenaUnlockedMsg = LK.getAsset('Johncenaunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(johncenaUnlockedMsg); // Animate and remove the notification tween(johncenaUnlockedMsg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(johncenaUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (johncenaUnlockedMsg.parent) { johncenaUnlockedMsg.parent.removeChild(johncenaUnlockedMsg); } } }); }, 500); } }); } } } // Check if Rickroll should be unlocked (when all other characters are unlocked) if (!storage.rickrollUnlocked) { // Check if all other characters are unlocked, excluding Joe Nugget var allCharactersUnlocked = storage.steveUnlocked && storage.piglinUnlocked && storage.villagerUnlocked && storage.spiderUnlocked && storage.skeletonUnlocked && storage.grimaceUnlocked && storage.mjUnlocked && storage.johnCenaUnlocked && storage.shootingStarsUnlocked && storage.deezNutsUnlocked; storage.allCharactersUnlocked = allCharactersUnlocked; if (allCharactersUnlocked) { storage.rickrollUnlocked = true; // Play rickroll sound when rickroll character is unlocked LK.getSound('Rickroll').play(); // Create unlocked notification using Rickroll unlocked asset var rickrollUnlockedMsg = LK.getAsset('Rickrollunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(rickrollUnlockedMsg); // If character select page exists, remove padlock from Rickroll character if (characterSelectPage) { for (var i = 0; i < characterSelectPage.characters.length; i++) { var character = characterSelectPage.characters[i]; if (character.asset === "Rickroll" && characterSelectPage.characterButtons.children[i].lockedImg) { characterSelectPage.characterButtons.children[i].lockedImg.parent.removeChild(characterSelectPage.characterButtons.children[i].lockedImg); } } } // Animate and remove the notification tween(rickrollUnlockedMsg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(rickrollUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (rickrollUnlockedMsg.parent) { rickrollUnlockedMsg.parent.removeChild(rickrollUnlockedMsg); } } }); }, 500); } }); } } } // Add backdrop behind arena var backdrop = game.addChild(LK.getAsset('Backdrop', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 })); // Create wrestling arena var arenaAsset = selectedCharacter === "Shootingstars" ? 'Space' : 'arena'; if (arena && arena.parent) { arena.parent.removeChild(arena); } var arenaAsset = selectedCharacter === "Joenugget" ? 'Jnugbackdrop' : selectedCharacter === "Shootingstars" ? 'Space' : 'arena'; var arena = game.addChild(LK.getAsset(arenaAsset, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: selectedCharacter === "Shootingstars" ? 1 : 1, scaleY: selectedCharacter === "Shootingstars" ? 1 : 1 })); // Create chicken jockey var chickenJockey = game.addChild(new ChickenJockey()); var launcher = game.addChild(new Launcher()); // Game boundaries var bounds = { left: arena.x - arena.width / 2, right: arena.x + arena.width / 2, top: arena.y - arena.height / 2, bottom: arena.y + arena.height / 2 }; // Create GUI elements var scoreTitleImg = LK.getAsset('Scoretitle', { anchorX: 0.5, anchorY: 0.5, x: -10, y: 40 }); LK.gui.top.addChild(scoreTitleImg); var scoreText = new Text2("0", { size: 70, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = -170; // Moved left by 50 pixels scoreText.y = 70; // Moved down by 70 pixels LK.gui.top.addChild(scoreText); // Create launches title using Launchestitle asset var launchesTitleImg = LK.getAsset('Launchestitle', { anchorX: 0.5, anchorY: 0.5, x: 150, y: 190 // Moved down by 170 pixels }); LK.gui.topLeft.addChild(launchesTitleImg); var launchesText = new Text2("0/" + maxLaunches, { size: 50, fill: 0xFFFFFF }); launchesText.anchor.set(0, 0); launchesText.x = 300; // Positioned after the title image launchesText.y = 160; // Moved down by 140 pixels LK.gui.topLeft.addChild(launchesText); var instructionText = new Text2("Draw a path to launch the chicken!", { size: 40, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0); instructionText.x = 100; // Move text right 50 more pixels instructionText.y = 180; LK.gui.top.addChild(instructionText); // Initialize game function initGame() { // Check if MJ should be unlocked when played 20 times if (!storage.mjUnlocked && storage.gamePlays >= 20) { storage.mjUnlocked = true; // Play MJ sound when MJ is unlocked LK.getSound('MJ').play(); // Show MJ unlocked asset when MJ is unlocked var mjUnlockedMsg = LK.getAsset('MJunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(mjUnlockedMsg); // Animate and remove the notification tween(mjUnlockedMsg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(mjUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (mjUnlockedMsg.parent) { mjUnlockedMsg.parent.removeChild(mjUnlockedMsg); } } }); }, 500); } }); } // Check if John Cena should be unlocked when played 30 times if (!storage.johnCenaUnlocked && storage.gamePlays >= 30) { storage.johnCenaUnlocked = true; // Play John Cena entrance sound when John Cena is unlocked LK.getSound('Johncena').play(); // Create unlocked notification using John Cena unlocked asset var cenaUnlockedMsg = LK.getAsset('Johncenaunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(cenaUnlockedMsg); // Animate and remove the notification tween(cenaUnlockedMsg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 1000, onFinish: function onFinish() { // Hold for a moment then fade out LK.setTimeout(function () { tween(cenaUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (cenaUnlockedMsg.parent) { cenaUnlockedMsg.parent.removeChild(cenaUnlockedMsg); } } }); }, 500); } }); } // Reset variables score = 0; launches = 0; gameState = "title"; bonusApplied = false; skeletonUnlocked = storage.skeletonUnlocked || false; storage.deezNutsUnlocked = true; grimaceUnlocked = storage.grimaceUnlocked || false; // Clear bonus timer if it exists if (bonusTimerInterval) { LK.clearInterval(bonusTimerInterval); bonusTimerInterval = null; } if (bonusTimerText && bonusTimerText.parent) { bonusTimerText.parent.removeChild(bonusTimerText); bonusTimerText = null; } // Remove bonus animation if it exists if (bonusAnimation && bonusAnimation.parent) { bonusAnimation.parent.removeChild(bonusAnimation); bonusAnimation = null; } // Update UI elements but hide them initially scoreText.setText(score); scoreText.alpha = 0; scoreTitleImg.alpha = 0; // Hide score title image initially launchesText.setText(launches + "/" + maxLaunches); launchesText.alpha = 0; instructionText.setText("Draw a path to launch your character!"); instructionText.alpha = 0; // Hide game elements initially arena.alpha = 0; backdrop.alpha = 0; chickenJockey.alpha = 0; launchesTitleImg.alpha = 0; // Make sure launchestitle is hidden initially // Show title page if (!titlePage) { titlePage = new TitlePage(); game.addChild(titlePage); } else { titlePage.alpha = 1; } // Initialize high score page if it doesn't exist if (!highScorePage) { highScorePage = new HighScorePage(); // Keep it detached until needed } // Initialize game mode select page if it doesn't exist if (!gameModeSelectPage) { gameModeSelectPage = new GameModeSelect(); // Keep it detached until needed } // Initialize character select page if it doesn't exist if (!characterSelectPage) { characterSelectPage = new CharacterSelect(); // Keep it detached until needed } // Add game start handler game.onStartButtonPressed = function () { // Track game plays in storage storage.gamePlays = (storage.gamePlays || 0) + 1; // Check if Steve should be unlocked (after 3 plays) if (storage.gamePlays >= 3 && storage.steveUnlocked !== true) { storage.steveUnlocked = true; // Play Steve sound when Steve is unlocked LK.getSound('Steve').play(); // Immediately remove padlock for Steve if (characterSelectPage) { for (var i = 0; i < characterSelectPage.characters.length; i++) { var character = characterSelectPage.characters[i]; if (character.asset === "steveridingpig" && characterSelectPage.characterButtons.children[i].lockedImg) { characterSelectPage.characterButtons.children[i].lockedImg.parent.removeChild(characterSelectPage.characterButtons.children[i].lockedImg); } } } // Create unlocked notification using steveunlocked asset instead of text var unlockedMsg = LK.getAsset('Steveunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(unlockedMsg); // Animate and remove the notification tween(unlockedMsg, { scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, onFinish: function onFinish() { tween(unlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (unlockedMsg.parent) { unlockedMsg.parent.removeChild(unlockedMsg); } } }); } }); } // Hide title page tween(titlePage, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (titlePage.parent) { titlePage.parent.removeChild(titlePage); } // Show game mode selection page instead of character select game.addChild(gameModeSelectPage); gameModeSelectPage.alpha = 0; tween(gameModeSelectPage, { alpha: 1 }, { duration: 500 }); // Set game state gameState = "gameModeSelect"; } }); }; // Add high scores button handler game.onHighScoresButtonPressed = function () { // Hide title page tween(titlePage, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (titlePage.parent) { titlePage.parent.removeChild(titlePage); } // Update high scores before showing highScorePage.updateScores(); // Show high scores page game.addChild(highScorePage); highScorePage.alpha = 0; tween(highScorePage, { alpha: 1 }, { duration: 500 }); // Set game state gameState = "highScores"; } }); }; // Add back button handler game.onBackButtonPressed = function () { // Hide high scores page tween(highScorePage, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (highScorePage.parent) { highScorePage.parent.removeChild(highScorePage); } // Stop any ongoing hyperspace animations if (storage.hyperspaceAnimation) { if (hyperspaceAnimationTween) { tween.stop(hyperspaceAnimationTween); } if (hyperspaceAnimationTween2) { tween.stop(hyperspaceAnimationTween2); } if (hyperspaceAnimationTween3) { tween.stop(hyperspaceAnimationTween3); } // Reset arena scale if (arena) { arena.scaleX = 1.0; arena.scaleY = 1.0; } storage.hyperspaceAnimation = false; } // Show title page game.addChild(titlePage); titlePage.alpha = 0; tween(titlePage, { alpha: 1 }, { duration: 500 }); // Set game state gameState = "title"; } }); }; // Add game mode selection handler game.onGameModeSelected = function (mode) { // Store selected game mode gameMode = mode; // Hide game mode select page tween(gameModeSelectPage, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (gameModeSelectPage.parent) { gameModeSelectPage.parent.removeChild(gameModeSelectPage); } // Store selected mode for later use gameMode = mode; // Remove D-pad if switching away from bonus mode if (gameMode !== "bonus" && dPad && dPad.parent) { dPad.parent.removeChild(dPad); dPad = null; // Make sure to clean up any references to the D-pad if (storage.hyperspaceAnimation) { if (hyperspaceAnimationTween) { tween.stop(hyperspaceAnimationTween); } if (hyperspaceAnimationTween2) { tween.stop(hyperspaceAnimationTween2); } if (hyperspaceAnimationTween3) { tween.stop(hyperspaceAnimationTween3); } storage.hyperspaceAnimation = false; } } // If bonus mode, initialize hyperspace background here if (mode === "bonus") { // Remove current arena if exists if (arena && arena.parent) { arena.parent.removeChild(arena); } // Create hyperspace background - randomly choose between two hyperspace backgrounds var hyperspaceAsset = Math.random() < 0.5 ? 'Hyperspace' : 'Hspace2'; arena = game.addChild(LK.getAsset(hyperspaceAsset, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1, scaleY: 1 })); // No animation in bonus mode storage.hyperspaceAnimation = false; } // Show character select page game.addChild(characterSelectPage); characterSelectPage.alpha = 0; tween(characterSelectPage, { alpha: 1 }, { duration: 500 }); // Set game state gameState = "characterSelect"; } }); }; // Add character selected handler game.onCharacterSelected = function (characterAsset) { // Store selected character selectedCharacter = characterAsset; // Replace arena with space asset when Shooting Stars character is selected if (arena && arena.parent) { arena.parent.removeChild(arena); } // Choose appropriate arena based on gameMode and selectedCharacter if (gameMode === "bonus") { // We already created the hyperspace background in onGameModeSelected // Just ensure it's properly positioned and visible if (arena && arena.parent) { arena.parent.removeChild(arena); } arena = game.addChild(LK.getAsset('Hyperspace', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1, scaleY: 1 })); // No background animation in bonus mode storage.hyperspaceAnimation = false; // No rotation animation // Keep the selected character for bonus mode // Update chicken jockey with selected character chickenJockey.updateCharacterAsset(selectedCharacter); // Ensure character is visible in front of hyperspace background if (chickenJockey && chickenJockey.parent) { chickenJockey.parent.removeChild(chickenJockey); } // Add chickenJockey AFTER the hyperspace background game.addChild(chickenJockey); // Ensure character is on top } else { var arenaAsset = selectedCharacter === "Joenugget" ? 'Jnugbackdrop' : selectedCharacter === "Shootingstars" || selectedCharacter === "Deeznuts" ? 'Space' : selectedCharacter === "Shrekwizowski" ? 'Swamp' : selectedCharacter === "Pomni" ? 'Digcircus' : selectedCharacter === "Michaeljackson" ? 'MJbackground' : 'arena'; arena = game.addChild(LK.getAsset(arenaAsset, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1, scaleY: 1 })); } // Update chicken jockey with selected character and make sure it's in front chickenJockey.updateCharacterAsset(selectedCharacter); // Ensure chicken jockey is on top by removing and re-adding it if (chickenJockey.parent) { chickenJockey.parent.removeChild(chickenJockey); } game.addChild(chickenJockey); if (selectedCharacter === "Deeznuts") { var spaceLevel = LK.getAsset('Spacelevel', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(spaceLevel); game.addChild(chickenJockey); // Ensure DeezNuts character is on top } // Add rickbackdrop when Rickroll character is selected if (selectedCharacter === "Rickroll") { var rickbackdrop = LK.getAsset('Rickbackdrop', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(rickbackdrop); // Make sure it's behind the chicken jockey if (chickenJockey.parent) { chickenJockey.parent.removeChild(chickenJockey); } game.addChild(chickenJockey); } // Update popcorn asset for existing popcorns var popcornAsset = selectedCharacter === "Grimacejockey" ? 'Shakes' : selectedCharacter === "Johncena" ? 'Belt' : selectedCharacter === "Shootingstars" ? 'Stars' : selectedCharacter === "Deeznuts" ? 'Nuts' : selectedCharacter === "Rickroll" ? 'Hearts' : selectedCharacter === "Shrekwizowski" ? 'Shrekcorn' : selectedCharacter === "Pomni" ? 'Circuspop' : 'popcorn'; for (var i = 0; i < popcorns.length; i++) { popcorns[i].updateAsset(popcornAsset); } var superPopcornAsset = selectedCharacter === "Shootingstars" ? 'Whitestars' : selectedCharacter === "Deeznuts" ? 'Cashew' : selectedCharacter === "Rickroll" ? 'Purpleheart' : selectedCharacter === "Grimacejockey" ? 'Fries' : selectedCharacter === "Johncena" ? 'Wwe' : selectedCharacter === "Shrekwizowski" ? 'Popshrek' : selectedCharacter === "Pomni" ? 'Digpop' : 'Superpopcorn'; for (var i = 0; i < superPopcorns.length; i++) { superPopcorns[i].updateAsset(superPopcornAsset); } // Play character-specific sounds if (selectedCharacter === "piglinjockey") { LK.getSound('Pignoise').play(); } else if (selectedCharacter === "steveridingpig") { LK.getSound('Steve').play(); } else if (selectedCharacter === "vilagerjockey") { LK.getSound('Villager').play(); } else if (selectedCharacter === "spiderjockey") { LK.getSound('Spider').play(); } else if (selectedCharacter === "skeletonhorse") { LK.getSound('Skeleton').play(); } else if (selectedCharacter === "Grimacejockey") { LK.getSound('Grimace').play(); } else if (selectedCharacter === "Michaeljackson") { LK.getSound('MJ').play(); // Thriller music will be played in startGamePlay() function //Removed duplicate music initialization here } else if (selectedCharacter === "Johncena") { LK.getSound('Johncena').play(); // Only play John Cena entrance music if not in bonus mode if (gameMode !== "bonus") { LK.playMusic('Cenaentrance'); } } else if (selectedCharacter === "Deeznuts") { LK.getSound('Deeznuts').play(); // Only play DeezNuts music if not in bonus mode if (gameMode !== "bonus") { LK.playMusic('Deeznutstrap'); } } else if (selectedCharacter === "Shootingstars") { // Only play Shooting Stars music if not in bonus mode if (gameMode !== "bonus") { LK.playMusic('Shootingstars'); } } else if (selectedCharacter === "Joenugget") { LK.getSound('Joenugget').play(); } else if (selectedCharacter === "Rickroll") { LK.getSound('Rickroll').play(); } else if (selectedCharacter === "Shrekwizowski") { LK.getSound('Shrek').play(); } else if (selectedCharacter === "Pomni") { LK.getSound('Pomni').play(); } else { // Play default game music for other characters but only if not in bonus mode if (gameMode !== "bonus") { LK.playMusic('gameMusic'); } } // Add handler for character select reset game.onCharacterSelectReset = function () { // Remove current character select page if (characterSelectPage && characterSelectPage.parent) { characterSelectPage.parent.removeChild(characterSelectPage); } // Create new character select page with reset unlocks characterSelectPage = new CharacterSelect(); game.addChild(characterSelectPage); }; // Hide character select page tween(characterSelectPage, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (characterSelectPage.parent) { characterSelectPage.parent.removeChild(characterSelectPage); } // Show game elements tween(arena, { alpha: 1 }, { duration: 300 }); tween(backdrop, { alpha: 1 }, { duration: 300 }); tween(chickenJockey, { alpha: 1 }, { duration: 300 }); scoreText.alpha = 1; scoreTitleImg.alpha = 1; // Show score title when game starts launchesText.alpha = 1; instructionText.alpha = 1; // Start the actual game startGamePlay(); } }); }; } // New function to start the actual gameplay after title screen function startGamePlay() { // Set game state to ready gameState = "ready"; // Reset chicken jockey resetChickenJockey(); // Update instruction text based on game mode if (gameMode === "bonus") { instructionText.setText("Bonus Mode: Collect spiraling popcorn with the D-pad!"); } else { // Update instruction text to show current pattern number var currentNumber = launches % 9 + 1; instructionText.setText("**Hidden character** Tap 5 popcorn in title screen to unlock."); } // Clear existing popcorn and ropes clearPopcornsAndRopes(); // Create ropes around the arena (not in bonus mode) if (gameMode !== "bonus") { createRopes(); } // Update launches text when game starts if (gameMode === "bonus") { // Change the arena background to hyperspace for bonus mode if (arena && arena.parent) { arena.parent.removeChild(arena); } arena = game.addChild(LK.getAsset('Hyperspace', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1, scaleY: 1 })); // No animation in bonus mode storage.hyperspaceAnimation = false; // No rotation animation // Update chicken jockey with the current selected character chickenJockey.updateCharacterAsset(selectedCharacter); // Make sure chickenJockey is in front of hyperspace background if (chickenJockey && chickenJockey.parent) { chickenJockey.parent.removeChild(chickenJockey); } game.addChild(chickenJockey); // Ensure character is on top // Add D-pad controls for bonus mode if (dPad && dPad.parent) { dPad.parent.removeChild(dPad); } dPad = new DPad(); dPad.x = 300; dPad.y = 2732 - 300; // Position at bottom left of screen game.addChild(dPad); // Create popcorn in a spiral pattern in bonus mode createSpiralPopcorn(150); // 10x the regular amount of popcorn in bonus mode // Animate the popcorn entrance animateSpiralPopcornEntrance(popcorns); // Reset and create bonus timer bonusTimer = 30; // Remove old timer text if it exists if (bonusTimerText && bonusTimerText.parent) { bonusTimerText.parent.removeChild(bonusTimerText); } // Create new timer text bonusTimerText = new Text2("Time: " + bonusTimer, { size: 60, fill: 0xFFFFFF }); bonusTimerText.anchor.set(0, 0); bonusTimerText.x = 300; bonusTimerText.y = 160; LK.gui.topLeft.addChild(bonusTimerText); // Hide launches text in bonus mode launchesText.alpha = 0; launchesTitleImg.alpha = 0; } else { createPopcorn(15); // Regular amount in classic mode // Show launches text in classic mode launchesText.alpha = 1; launchesText.setText(launches + "/" + maxLaunches); launchesTitleImg.alpha = 1; } // Update bounds for bonus mode to use full screen area if (gameMode === "bonus") { bounds = { left: 100, right: 2048 - 100, top: 100, bottom: 2732 - 100 }; } else { bounds = { left: arena.x - arena.width / 2, right: arena.x + arena.width / 2, top: arena.y - arena.height / 2, bottom: arena.y + arena.height / 2 }; } // Add trajectory path to game game.addChild(launcher.trajectoryPath); // Play background music based on selected character // In bonus mode, only play Runandgo music, which was already started if (gameMode !== "bonus") { if (selectedCharacter === "Michaeljackson") { LK.playMusic('Thriller'); } else if (selectedCharacter === "Johncena") { LK.playMusic('Cenaentrance'); } else if (selectedCharacter === "Shootingstars") { LK.playMusic('Shootingstars'); } else if (selectedCharacter === "Rickroll") { LK.playMusic('Nevergonna'); } else if (selectedCharacter === "Grimacejockey") { LK.playMusic('Grimaceshake'); } else if (selectedCharacter === "Joenugget") { LK.playMusic('gegagedi'); } else if (selectedCharacter === "Shrekwizowski") { LK.playMusic('Raveswamp'); } else if (selectedCharacter === "Pomni") { LK.playMusic('Digcircus'); } else if (selectedCharacter !== "Deeznuts") { LK.playMusic('gameMusic'); } } // Add Steve to the top left corner of the arena var steve = game.addChild(LK.getAsset('Steve', { anchorX: 0.5, anchorY: 0.5, x: bounds.left + 625, y: bounds.top + 325 })); // Initially hide the launchesTitleImg launchesTitleImg.alpha = 0; // Play gamestart sound when Steve appears LK.getSound('Gamestart').play(); // Remove Steve after 2 seconds and show launchestitle LK.setTimeout(function () { if (steve && steve.parent) { steve.parent.removeChild(steve); } // Show launchestitle after gamestart sound is played tween(launchesTitleImg, { alpha: 1 }, { duration: 300 }); }, 2000); } function resetChickenJockey() { chickenJockey.reset(); // Make sure the right character is displayed chickenJockey.updateCharacterAsset(selectedCharacter); // Position character in the center of the arena chickenJockey.x = arena.x - (selectedCharacter === "Michaeljackson" ? 150 : 0) + (selectedCharacter === "Michaeljackson" ? 300 : 0); chickenJockey.y = selectedCharacter === "Michaeljackson" ? arena.y - 670 : arena.y - 400; // Position launcher at the same position launcher.x = chickenJockey.x; launcher.y = chickenJockey.y; launcher.rotation = -Math.PI / 4; // 45 degrees upward // Reset instruction text when character is reset instructionText.setText("Draw a path to launch your character!"); } function clearPopcornsAndRopes() { // Remove all popcorn for (var i = 0; i < popcorns.length; i++) { if (popcorns[i].parent) { popcorns[i].parent.removeChild(popcorns[i]); } } popcorns = []; // Remove all superpopcorn for (var i = 0; i < superPopcorns.length; i++) { if (superPopcorns[i].parent) { superPopcorns[i].parent.removeChild(superPopcorns[i]); } } superPopcorns = []; // Remove all ropes for (var i = 0; i < ropes.length; i++) { if (ropes[i].parent) { ropes[i].parent.removeChild(ropes[i]); } } ropes = []; } function createRopes() { // Don't create ropes in bonus mode if (gameMode === "bonus") { return; } // Position ropes at edge of screen if using MJbackground var isMJBackground = selectedCharacter === "Michaeljackson"; var edgeOffset = isMJBackground ? 0 : 100; // Create top rope var topRope = new Rope(); topRope.x = arena.x; topRope.y = bounds.top + edgeOffset; game.addChild(topRope); ropes.push(topRope); // Create right rope var rightRope = new Rope(); rightRope.x = bounds.right - edgeOffset; rightRope.y = arena.y; rightRope.rotation = Math.PI / 2; // Rotate 90 degrees game.addChild(rightRope); ropes.push(rightRope); // Create bottom rope var bottomRope = new Rope(); bottomRope.x = arena.x; bottomRope.y = bounds.bottom - edgeOffset; game.addChild(bottomRope); ropes.push(bottomRope); // Create left rope var leftRope = new Rope(); leftRope.x = bounds.left + edgeOffset; leftRope.y = arena.y; leftRope.rotation = Math.PI / 2; // Rotate 90 degrees game.addChild(leftRope); ropes.push(leftRope); // If MJ background, animate ropes to make them more visible if (isMJBackground) { for (var i = 0; i < ropes.length; i++) { // Flash the ropes slightly to make them more visible against MJ background tween(ropes[i], { alpha: 0.7 }, { duration: 300, onFinish: function onFinish() { tween(this, { alpha: 1 }, { duration: 300 }); } }); } } } function createPopcorn(count) { // Create a number pattern generator var patternGenerator = new NumberPattern(); // Calculate spacing based on the arena size var spacing = 280; // Double the spacing to make the pattern larger // Determine which number to display (1-9) var currentNumber = launches % 9 + 1; // Create popcorn in the number pattern // Determine the correct popcorn asset based on the selected character var popcornAsset = selectedCharacter === "Joenugget" ? 'Drumstick' : 'popcorn'; // Default asset if (selectedCharacter === "Grimacejockey") { popcornAsset = 'Shakes'; } else if (selectedCharacter === "Johncena") { popcornAsset = 'Belt'; // Ensure Belt is used for John Cena } else if (selectedCharacter === "Shootingstars") { popcornAsset = 'Stars'; } else if (selectedCharacter === "Deeznuts") { popcornAsset = 'Nuts'; } else if (selectedCharacter === "Rickroll") { popcornAsset = 'Hearts'; } else if (selectedCharacter === "Shrekwizowski") { popcornAsset = 'Shrekcorn'; } else if (selectedCharacter === "Pomni") { popcornAsset = 'Circuspop'; } // For bonus mode, use all different types of popcorn assets var popcornAssets = ['popcorn', 'Drumstick', 'Shakes', 'Belt', 'Stars', 'Nuts', 'Hearts', 'Shrekcorn', 'Circuspop']; var newPopcorns = patternGenerator.createPattern(currentNumber, arena.x, // Center X position arena.y, // Center Y position spacing // Spacing between popcorn ); // Add all created popcorn to the game for (var i = 0; i < newPopcorns.length; i++) { var popcorn = newPopcorns[i]; // Verify position is valid (not too close to ropes) var validPosition = true; for (var j = 0; j < ropes.length; j++) { var dx = popcorn.x - ropes[j].x; var dy = popcorn.y - ropes[j].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 100) { validPosition = false; break; } } // Only add if position is valid if (validPosition) { // For bonus mode, assign a random popcorn asset type if (gameMode === "bonus") { var randomAsset = popcornAssets[Math.floor(Math.random() * popcornAssets.length)]; popcorn.updateAsset(randomAsset); } game.addChild(popcorn); popcorns.push(popcorn); } } // If we need more popcorn to reach the count, add some randomly if (popcorns.length < count) { for (var i = popcorns.length; i < count; i++) { var popcorn = new Popcorn(); // Update asset based on selected character popcorn.updateAsset(popcornAsset); // Random position within arena bounds var validPosition = false; var attempts = 0; var maxAttempts = 50; // Keep trying until we find a valid position while (!validPosition && attempts < maxAttempts) { // Generate random position within arena bounds popcorn.x = bounds.left + 200 + Math.random() * (arena.width - 400); popcorn.y = bounds.top + 200 + Math.random() * (arena.height - 400); // Check distance from each rope validPosition = true; for (var j = 0; j < ropes.length; j++) { var dx = popcorn.x - ropes[j].x; var dy = popcorn.y - ropes[j].y; var distance = Math.sqrt(dx * dx + dy * dy); // If too close to a rope, try again if (distance < 200) { validPosition = false; break; } } attempts++; } // Add to game game.addChild(popcorn); popcorns.push(popcorn); } } } function createSuperPopcorn(count) { for (var i = 0; i < count; i++) { var superPopcorn = new Superpopcorn(); // Update asset based on selected character var superPopcornAsset = selectedCharacter === "Joenugget" ? 'Popchicken' : selectedCharacter === "Shootingstars" ? 'Whitestars' : selectedCharacter === "Deeznuts" ? 'Cashew' : selectedCharacter === "Rickroll" ? 'Purpleheart' : selectedCharacter === "Grimacejockey" ? 'Fries' : selectedCharacter === "Johncena" ? 'Wwe' : selectedCharacter === "Shrekwizowski" ? 'Shrekcorn' : 'Superpopcorn'; superPopcorn.updateAsset(superPopcornAsset); // Random position within arena bounds var validPosition = false; var attempts = 0; var maxAttempts = 50; // Keep trying until we find a valid position while (!validPosition && attempts < maxAttempts) { // Generate random position within arena bounds superPopcorn.x = bounds.left + 200 + Math.random() * (arena.width - 400); superPopcorn.y = bounds.top + 200 + Math.random() * (arena.height - 400); // Check distance from each rope validPosition = true; for (var j = 0; j < ropes.length; j++) { var dx = superPopcorn.x - ropes[j].x; var dy = superPopcorn.y - ropes[j].y; var distance = Math.sqrt(dx * dx + dy * dy); // If too close to a rope, try again if (distance < 200) { validPosition = false; break; } } attempts++; } // Add to game game.addChild(superPopcorn); superPopcorns.push(superPopcorn); } } // Game events game.onChickenJockeyStop = function () { gameState = "ready"; // Check if all popcorn is collected to apply X5 bonus // Make sure we check for empty popcorns array at the exact moment the chicken stops if (popcorns.length === 0 && superPopcorns.length === 0 && !bonusApplied) { // Apply X5 bonus bonusApplied = true; score *= 5; scoreText.setText(score); LK.setScore(score); // Create and show X5 bonus animation in the center of the screen if (bonusAnimation && bonusAnimation.parent) { bonusAnimation.parent.removeChild(bonusAnimation); } // Play character-specific sounds for X5 bonus if (selectedCharacter === "Shootingstars") { // No sound for Shooting Stars } else if (selectedCharacter === "piglinjockey") { LK.getSound('Pignoise').play(); } else if (selectedCharacter === "steveridingpig") { LK.getSound('Steve').play(); } else if (selectedCharacter === "vilagerjockey") { LK.getSound('Villager').play(); } else if (selectedCharacter === "spiderjockey") { LK.getSound('Spider').play(); } else if (selectedCharacter === "skeletonhorse") { LK.getSound('Skeleton').play(); } else if (selectedCharacter === "Grimacejockey") { LK.getSound('Grimace').play(); } else if (selectedCharacter === "Michaeljackson") { LK.getSound('MJ').play(); } else if (selectedCharacter === "Deeznuts") { LK.getSound('Deeznuts').play(); } else if (selectedCharacter === "Rickroll") { LK.getSound('Rickroll').play(); } else if (selectedCharacter === "Joenugget") { LK.getSound('Joenugget').play(); } else if (selectedCharacter === "Johncena") { LK.getSound('Johncena').play(); } else if (selectedCharacter === "Shrekwizowski") { LK.getSound('Shrek').play(); } else if (selectedCharacter === "Pomni") { LK.getSound('Pomni').play(); } else { LK.getSound('Bogerk').play(); } // Create X5 animation bonusAnimation = LK.getAsset('X5', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1.5, scaleY: 1.5, alpha: 1 }); game.addChild(bonusAnimation); // Animate the X5 bonus tween(bonusAnimation, { scaleX: 2.5, scaleY: 2.5 }, { duration: 700, easing: tween.bounceOut, onFinish: function onFinish() { LK.setTimeout(function () { tween(bonusAnimation, { alpha: 0, scaleX: 3.0, scaleY: 3.0 }, { duration: 1000, easing: tween.easeOut }); }, 500); } }); // Play collect sound for bonus emphasis LK.getSound('collect').play(); } else if (popcorns.length === 0 && superPopcorns.length === 0) { // Reset bonus status for next round if all popcorn is collected but bonus was already applied bonusApplied = false; } // Check if score has reached 1000000 to unlock villager character if (score >= 1000000 && !storage.villagerUnlocked) { storage.villagerUnlocked = true; // Play Villager sound when Villager is unlocked LK.getSound('Villager').play(); // Create unlocked notification using villagerunlocked asset instead of text var villagerUnlockedMsg = LK.getAsset('Villagerunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(villagerUnlockedMsg); // Animate and remove the notification tween(villagerUnlockedMsg, { scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, onFinish: function onFinish() { // Play Chicken sound to acknowledge unlock LK.getSound('Chickencluck').play(); // Hold for a moment then fade out LK.setTimeout(function () { tween(villagerUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (villagerUnlockedMsg.parent) { villagerUnlockedMsg.parent.removeChild(villagerUnlockedMsg); } } }); }, 500); } }); } // Check if score has reached 10,000,000 to unlock spider character if (score >= 10000000 && !storage.spiderUnlocked) { storage.spiderUnlocked = true; // Play Spider sound to acknowledge unlock LK.getSound('Spider').play(); // Create unlocked notification using spiderjockeyunlocked asset instead of text var spiderUnlockedMsg = LK.getAsset('Spiderjockeyunlocked', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(spiderUnlockedMsg); // Animate and remove the notification tween(spiderUnlockedMsg, { scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, onFinish: function onFinish() { // Play Chicken sound to acknowledge unlock LK.getSound('Chickencluck').play(); // Hold for a moment then fade out LK.setTimeout(function () { tween(spiderUnlockedMsg, { alpha: 0 }, { delay: 1000, duration: 500, onFinish: function onFinish() { if (spiderUnlockedMsg.parent) { spiderUnlockedMsg.parent.removeChild(spiderUnlockedMsg); } } }); }, 500); } }); } // Check if we need to add more popcorn if (popcorns.length < 5) { createPopcorn(5); } // Check if out of launches if (launches >= maxLaunches) { // Game over instructionText.setText("Game Over! Final Score: " + score); gameState = "gameOver"; // Save score to high scores var highScores = storage.highScores || []; highScores.push(score); // Sort in descending order highScores.sort(function (a, b) { return b - a; }); // Keep only top 10 scores if (highScores.length > 10) { highScores = highScores.slice(0, 10); } storage.highScores = highScores; // Show game over after a short delay LK.setTimeout(function () { LK.showGameOver(); // Return to title screen after game over LK.setTimeout(function () { // Set game state back to title gameState = "title"; // Hide game elements arena.alpha = 0; backdrop.alpha = 0; chickenJockey.alpha = 0; scoreText.alpha = 0; launchesText.alpha = 0; instructionText.alpha = 0; // Show title page if (!titlePage) { titlePage = new TitlePage(); } game.addChild(titlePage); titlePage.alpha = 0; tween(titlePage, { alpha: 1 }, { duration: 500 }); }, 500); // Short delay after game over is shown }, 2000); } else { // Reset for next launch resetChickenJockey(); // Update the instruction text to show the current number pattern var currentNumber = launches % 9 + 1; instructionText.setText("Collect all popcorn for a X5 bonus!"); } }; game.onMaxBouncesReached = function () { // Same as onChickenJockeyStop for now game.onChickenJockeyStop(); }; // Input handling var dragStartX = 0; var dragStartY = 0; game.down = function (x, y, obj) { if (gameState === "title" || gameState === "highScores" || gameState === "characterSelect" || gameState === "gameModeSelect") { // Title page, high scores, game mode select and character select interactions are handled by their respective classes return; } // For bonus mode, we auto-launch the character when game is ready if (gameState === "ready") { if (gameMode === "bonus") { // Auto-launch the character in bonus mode chickenJockey.launched = true; gameState = "launched"; instructionText.setText("Use the D-pad to control your character!"); // Start bonus timer countdown if (bonusTimerInterval) { LK.clearInterval(bonusTimerInterval); } bonusTimerInterval = LK.setInterval(function () { bonusTimer--; if (bonusTimerText) { bonusTimerText.setText("Time: " + bonusTimer); } if (bonusTimer <= 0) { // Time's up, end the game LK.clearInterval(bonusTimerInterval); bonusTimerInterval = null; // Show game over after timer ends instructionText.setText("Time's up! Final Score: " + score); gameState = "gameOver"; // Show game over after a short delay LK.setTimeout(function () { LK.showGameOver(); }, 1500); } }, 1000); } else { // Classic mode uses path drawing gameState = "aiming"; dragStartX = x; dragStartY = y; launcher.startAim(x, y); } } // In bonus mode when already launched, don't do anything else on down // This prevents conflict between D-pad and other touch events if (gameMode === "bonus" && gameState === "launched") { return; } }; game.move = function (x, y, obj) { if (gameState === "title" || gameState === "highScores" || gameState === "characterSelect" || gameState === "gameModeSelect") { // Title page, high scores, game mode select and character select interactions are handled by their respective classes return; } if (gameState === "aiming") { launcher.updateAim(x, y); } }; game.up = function (x, y, obj) { if (gameState === "title" || gameState === "highScores" || gameState === "characterSelect" || gameState === "gameModeSelect") { // Title page, high scores, game mode select and character select interactions are handled by their respective classes return; } if (gameState === "aiming") { // Make sure we have enough points to create a valid path if (launcher.points.length < 2) { // Not enough points, cancel launch launcher.endAim(); gameState = "ready"; instructionText.setText("Draw a longer path to launch your character!"); return; } // Get launch parameters var launchParams = launcher.endAim(); // Create a smoothed path if needed var pathToDraw = launcher.points; if (pathToDraw.length > 20) { // Take fewer points if path is very long var smoothedPath = []; for (var i = 0; i < pathToDraw.length; i += Math.ceil(pathToDraw.length / 20)) { smoothedPath.push(pathToDraw[i]); } // Make sure we include the last point if (smoothedPath[smoothedPath.length - 1] !== pathToDraw[pathToDraw.length - 1]) { smoothedPath.push(pathToDraw[pathToDraw.length - 1]); } pathToDraw = smoothedPath; } // Launch the chicken jockey with the drawn path chickenJockey.launch(launchParams.power, launchParams.angle, pathToDraw); // Update game state gameState = "launched"; launches++; launchesText.setText(launches + "/" + maxLaunches); instructionText.setText("Watch the character follow your path!"); // Add 3 superpopcorn after each launch createSuperPopcorn(3); } }; // Main game loop game.update = function () { // Update all game objects if (gameState === "launched") { chickenJockey.update(); // Check for collisions with arena boundaries if (chickenJockey.x < bounds.left) { chickenJockey.x = bounds.left; chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } else if (chickenJockey.x > bounds.right) { chickenJockey.x = bounds.right; chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } if (chickenJockey.y < bounds.top) { chickenJockey.y = bounds.top; chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } else if (chickenJockey.y > bounds.bottom) { chickenJockey.y = bounds.bottom; chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } // Check for collisions with ropes for (var i = 0; i < ropes.length; i++) { if (chickenJockey.intersects(ropes[i])) { ropes[i].bounce(chickenJockey); } } // Check for collisions with popcorn for (var i = popcorns.length - 1; i >= 0; i--) { if (chickenJockey.intersects(popcorns[i])) { // Collect popcorn popcorns[i].collect(); // Remove from array popcorns.splice(i, 1); // Increase score score += 10; scoreText.setText(score); // Save score to LK LK.setScore(score); // Check if all popcorn is collected in bonus mode if (gameMode === "bonus" && popcorns.length === 0) { // Finish level when all popcorn is collected in bonus mode instructionText.setText("Bonus level complete! Great job!"); // Clear the bonus timer if (bonusTimerInterval) { LK.clearInterval(bonusTimerInterval); bonusTimerInterval = null; } if (bonusTimerText) { bonusTimerText.setText("Complete!"); } // Show you win after a short delay LK.setTimeout(function () { LK.showYouWin(); }, 1000); return; // Exit the loop } // Check if all popcorn has been collected if (popcorns.length === 0 && superPopcorns.length === 0 && !bonusApplied) { // Apply X5 bonus bonusApplied = true; score *= 5; scoreText.setText(score); LK.setScore(score); // Create and show X5 bonus animation in the center of the screen if (bonusAnimation && bonusAnimation.parent) { bonusAnimation.parent.removeChild(bonusAnimation); } // Play different sounds based on selected character if (selectedCharacter === "Shootingstars") { // No sound for Shooting Stars } else if (selectedCharacter === "piglinjockey") { LK.getSound('Pignoise').play(); } else if (selectedCharacter === "steveridingpig") { // Play Steve sound when Steve character is used and X5 bonus is achieved LK.getSound('Steve').play(); } else if (selectedCharacter === "vilagerjockey") { LK.getSound('Villager').play(); } else if (selectedCharacter === "spiderjockey") { LK.getSound('Spider').play(); } else if (selectedCharacter === "skeletonhorse") { // Play Skeleton sound when Skeleton character is used and X5 bonus is achieved LK.getSound('Skeleton').play(); } else if (selectedCharacter === "Grimacejockey") { // Play Grimace sound when Grimace character is used and X5 bonus is achieved LK.getSound('Grimace').play(); } else if (selectedCharacter === "Michaeljackson") { // Play MJ sound when MJ character is used and X5 bonus is achieved LK.getSound('MJ').play(); } else if (selectedCharacter === "Deeznuts") { // Play Deeznuts sound when DeezNuts character is used and X5 bonus is achieved LK.getSound('Deeznuts').play(); } else if (selectedCharacter === "Rickroll") { LK.getSound('Rickroll').play(); } else if (selectedCharacter === "Joenugget") { // Play Joenugget sound when Joe Nugget character is used and X5 bonus is achieved LK.getSound('Joenugget').play(); } else if (selectedCharacter === "Johncena") { // Play John Cena sound when John Cena character is used and X5 bonus is achieved LK.getSound('Johncena').play(); } else if (selectedCharacter === "Shrekwizowski") { LK.getSound('Shrek').play(); } else if (selectedCharacter === "Pomni") { LK.getSound('Pomni').play(); } else { // Play Bogerk sound for other characters LK.getSound('Bogerk').play(); } // Create X5 animation with explicit alpha=1 bonusAnimation = LK.getAsset('X5', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, // Center of screen X y: 2732 / 2, // Center of screen Y scaleX: 1.5, // Larger initial scale scaleY: 1.5, alpha: 1 // Explicitly set alpha to make it visible }); game.addChild(bonusAnimation); // Add to game for better visibility // Animate the X5 bonus with more dramatic effect tween(bonusAnimation, { scaleX: 2.5, scaleY: 2.5 }, { duration: 700, easing: tween.bounceOut, onFinish: function onFinish() { // Hold for a shorter moment then fade out LK.setTimeout(function () { tween(bonusAnimation, { alpha: 0, scaleX: 3.0, scaleY: 3.0 }, { duration: 1000, easing: tween.easeOut }); }, 500); } }); // Play collect sound for bonus emphasis LK.getSound('collect').play(); } } } // Check for collisions with superpopcorn for (var i = superPopcorns.length - 1; i >= 0; i--) { if (chickenJockey.intersects(superPopcorns[i])) { // Collect superpopcorn superPopcorns[i].collect(); // Remove from array superPopcorns.splice(i, 1); // Increase score score += 1000; scoreText.setText(score); // Save score to LK LK.setScore(score); } } } // Update popcorn animations for (var i = 0; i < popcorns.length; i++) { popcorns[i].update(); } // Update superpopcorn animations for (var i = 0; i < superPopcorns.length; i++) { superPopcorns[i].update(); } }; // Initialize the game initGame(); ; // Add tween animation to each popcorn as it's created function animateSpiralPopcornEntrance(popcornList) { for (var i = 0; i < popcornList.length; i++) { var popcorn = popcornList[i]; // Store original position var originalX = popcorn.x; var originalY = popcorn.y; // Start at center with zero scale popcorn.x = 2048 / 2; popcorn.y = 2732 / 2; popcorn.scaleX = 0; popcorn.scaleY = 0; popcorn.alpha = 0; // Animate to final position with staggered delay tween(popcorn, { x: originalX, y: originalY, scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 800, delay: i * 10, // Stagger the animations easing: tween.elasticOut }); } }
===================================================================
--- original.js
+++ change.js
@@ -2412,8 +2412,11 @@
var gameMode = "classic"; // classic or bonus
var score = 0;
var launches = 0;
var maxLaunches = 10;
+var bonusTimer = 30; // 30 second countdown for bonus mode
+var bonusTimerInterval = null; // Store timer interval reference
+var bonusTimerText = null; // Text element for the timer
var popcorns = [];
var superPopcorns = [];
var ropes = [];
var bonusApplied = false;
@@ -2427,11 +2430,8 @@
var skeletonUnlocked = false; // Track if skeleton has been unlocked through S pattern
var grimaceTaps = 0; // Counter for taps on title screen
var grimaceUnlocked = false; // Track if Grimace character is unlocked
var dPad = null; // D-pad controls for bonus mode
-var bonusTimer = 30; // Timer for bonus mode (in seconds)
-var bonusTimerInterval = null; // Interval for updating bonus timer
-var bonusTimerText = null; // Text display for bonus timer
// Create popcorn in a spiral pattern from the center
function createSpiralPopcorn(count) {
// Clear existing popcorn first
for (var i = 0; i < popcorns.length; i++) {
@@ -2754,8 +2754,17 @@
bonusApplied = false;
skeletonUnlocked = storage.skeletonUnlocked || false;
storage.deezNutsUnlocked = true;
grimaceUnlocked = storage.grimaceUnlocked || false;
+ // Clear bonus timer if it exists
+ if (bonusTimerInterval) {
+ LK.clearInterval(bonusTimerInterval);
+ bonusTimerInterval = null;
+ }
+ if (bonusTimerText && bonusTimerText.parent) {
+ bonusTimerText.parent.removeChild(bonusTimerText);
+ bonusTimerText = null;
+ }
// Remove bonus animation if it exists
if (bonusAnimation && bonusAnimation.parent) {
bonusAnimation.parent.removeChild(bonusAnimation);
bonusAnimation = null;
@@ -2950,17 +2959,8 @@
// Remove D-pad if switching away from bonus mode
if (gameMode !== "bonus" && dPad && dPad.parent) {
dPad.parent.removeChild(dPad);
dPad = null;
- // Clean up bonus timer resources
- if (bonusTimerText && bonusTimerText.parent) {
- bonusTimerText.parent.removeChild(bonusTimerText);
- bonusTimerText = null;
- }
- if (bonusTimerInterval) {
- LK.clearInterval(bonusTimerInterval);
- bonusTimerInterval = null;
- }
// Make sure to clean up any references to the D-pad
if (storage.hyperspaceAnimation) {
if (hyperspaceAnimationTween) {
tween.stop(hyperspaceAnimationTween);
@@ -3193,9 +3193,9 @@
// Reset chicken jockey
resetChickenJockey();
// Update instruction text based on game mode
if (gameMode === "bonus") {
- instructionText.setText("Bonus Mode: Collect spiraling popcorn with the D-pad! 30 seconds!");
+ instructionText.setText("Bonus Mode: Collect spiraling popcorn with the D-pad!");
} else {
// Update instruction text to show current pattern number
var currentNumber = launches % 9 + 1;
instructionText.setText("**Hidden character** Tap 5 popcorn in title screen to unlock.");
@@ -3205,9 +3205,9 @@
// Create ropes around the arena (not in bonus mode)
if (gameMode !== "bonus") {
createRopes();
}
- // Create popcorn scattered around the arena - more popcorn in bonus mode
+ // Update launches text when game starts
if (gameMode === "bonus") {
// Change the arena background to hyperspace for bonus mode
if (arena && arena.parent) {
arena.parent.removeChild(arena);
@@ -3241,54 +3241,32 @@
// Create popcorn in a spiral pattern in bonus mode
createSpiralPopcorn(150); // 10x the regular amount of popcorn in bonus mode
// Animate the popcorn entrance
animateSpiralPopcornEntrance(popcorns);
- // Initialize bonus timer
+ // Reset and create bonus timer
bonusTimer = 30;
- // Create or update timer text
+ // Remove old timer text if it exists
if (bonusTimerText && bonusTimerText.parent) {
bonusTimerText.parent.removeChild(bonusTimerText);
}
+ // Create new timer text
bonusTimerText = new Text2("Time: " + bonusTimer, {
- size: 70,
+ size: 60,
fill: 0xFFFFFF
});
- bonusTimerText.anchor.set(0.5, 0);
- bonusTimerText.x = 2048 / 2;
- bonusTimerText.y = 70;
- LK.gui.top.addChild(bonusTimerText);
- // Clear any existing timer interval
- if (bonusTimerInterval) {
- LK.clearInterval(bonusTimerInterval);
- }
- // Start the timer countdown
- bonusTimerInterval = LK.setInterval(function () {
- bonusTimer--;
- if (bonusTimerText) {
- bonusTimerText.setText("Time: " + bonusTimer);
- // Make timer red when low
- if (bonusTimer <= 10) {
- bonusTimerText.style.fill = 0xFF0000;
- }
- }
- // When timer runs out
- if (bonusTimer <= 0) {
- LK.clearInterval(bonusTimerInterval);
- // Show game over or you win based on how many popcorn collected
- if (popcorns.length === 0) {
- LK.showYouWin();
- } else {
- instructionText.setText("Time's up! Collected " + (150 - popcorns.length) + " popcorn!");
- LK.showGameOver();
- }
- }
- }, 1000);
- // No launch limit in bonus mode
- maxLaunches = Infinity;
- launchesText.setText("Time: " + bonusTimer);
- launchesText.alpha = 0; // Hide launches text as we're using the timer instead
+ bonusTimerText.anchor.set(0, 0);
+ bonusTimerText.x = 300;
+ bonusTimerText.y = 160;
+ LK.gui.topLeft.addChild(bonusTimerText);
+ // Hide launches text in bonus mode
+ launchesText.alpha = 0;
+ launchesTitleImg.alpha = 0;
} else {
createPopcorn(15); // Regular amount in classic mode
+ // Show launches text in classic mode
+ launchesText.alpha = 1;
+ launchesText.setText(launches + "/" + maxLaunches);
+ launchesTitleImg.alpha = 1;
}
// Update bounds for bonus mode to use full screen area
if (gameMode === "bonus") {
bounds = {
@@ -3736,10 +3714,10 @@
// Check if we need to add more popcorn
if (popcorns.length < 5) {
createPopcorn(5);
}
- // Check if out of launches (only in classic mode)
- if (gameMode !== "bonus" && launches >= maxLaunches) {
+ // Check if out of launches
+ if (launches >= maxLaunches) {
// Game over
instructionText.setText("Game Over! Final Score: " + score);
gameState = "gameOver";
// Save score to high scores
@@ -3767,18 +3745,8 @@
chickenJockey.alpha = 0;
scoreText.alpha = 0;
launchesText.alpha = 0;
instructionText.alpha = 0;
- // Hide bonus timer if it exists
- if (bonusTimerText && bonusTimerText.parent) {
- bonusTimerText.parent.removeChild(bonusTimerText);
- bonusTimerText = null;
- }
- // Clear any existing timer interval
- if (bonusTimerInterval) {
- LK.clearInterval(bonusTimerInterval);
- bonusTimerInterval = null;
- }
// Show title page
if (!titlePage) {
titlePage = new TitlePage();
}
@@ -3816,11 +3784,31 @@
if (gameMode === "bonus") {
// Auto-launch the character in bonus mode
chickenJockey.launched = true;
gameState = "launched";
- launches++;
- launchesText.setText(launches + "/" + maxLaunches);
instructionText.setText("Use the D-pad to control your character!");
+ // Start bonus timer countdown
+ if (bonusTimerInterval) {
+ LK.clearInterval(bonusTimerInterval);
+ }
+ bonusTimerInterval = LK.setInterval(function () {
+ bonusTimer--;
+ if (bonusTimerText) {
+ bonusTimerText.setText("Time: " + bonusTimer);
+ }
+ if (bonusTimer <= 0) {
+ // Time's up, end the game
+ LK.clearInterval(bonusTimerInterval);
+ bonusTimerInterval = null;
+ // Show game over after timer ends
+ instructionText.setText("Time's up! Final Score: " + score);
+ gameState = "gameOver";
+ // Show game over after a short delay
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1500);
+ }
+ }, 1000);
} else {
// Classic mode uses path drawing
gameState = "aiming";
dragStartX = x;
@@ -3933,20 +3921,24 @@
// Check if all popcorn is collected in bonus mode
if (gameMode === "bonus" && popcorns.length === 0) {
// Finish level when all popcorn is collected in bonus mode
instructionText.setText("Bonus level complete! Great job!");
- // Stop the timer
+ // Clear the bonus timer
if (bonusTimerInterval) {
LK.clearInterval(bonusTimerInterval);
+ bonusTimerInterval = null;
}
+ if (bonusTimerText) {
+ bonusTimerText.setText("Complete!");
+ }
// Show you win after a short delay
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
return; // Exit the loop
}
// Check if all popcorn has been collected
- if (gameMode !== "bonus" && popcorns.length === 0 && superPopcorns.length === 0 && !bonusApplied) {
+ if (popcorns.length === 0 && superPopcorns.length === 0 && !bonusApplied) {
// Apply X5 bonus
bonusApplied = true;
score *= 5;
scoreText.setText(score);
X5 symbol. In-Game asset. 2d. High contrast. No shadows
X2 symbol. In-Game asset. 2d. High contrast. No shadows
Super popcorn yellow. In-Game asset. 2d. High contrast. No shadows
Start button. In-Game asset. 2d. High contrast. No shadows
High score button. In-Game asset. 2d. High contrast. No shadows
Back button. In-Game asset. 2d. High contrast. No shadows
SELECT YOUR CHARACTER button. In-Game asset. 2d. High contrast. No shadows
Launches button. In-Game asset. 2d. High contrast. No shadows
How to play button. In-Game asset. 2d. High contrast. No shadows
Score button. In-Game asset. 2d. High contrast. No shadows
High Scores button. In-Game asset. 2d. High contrast. No shadows
Transparent padlock. In-Game asset. 2d. High contrast. No shadows
Chicken jockey character. In-Game asset. 2d. High contrast. No shadows
Reset scores button. In-Game asset. 2d. High contrast. No shadows
Spider jockey unlocked button. In-Game asset. 2d. High contrast. No shadows
Minecraft Steve unlocked button. In-Game asset. 2d. High contrast. No shadows
Piglin unlocked button. In-Game asset. 2d. High contrast. No shadows
Minecraft skeleton unlocked button. In-Game asset. 2d. High contrast. No shadows
Minecraft villager unlocked button. In-Game asset. 2d. High contrast. No shadows
Star. In-Game asset. 2d. High contrast. No shadows
White star. In-Game asset. 2d. High contrast. No shadows
Red heart. In-Game asset. 2d. High contrast. No shadows
Purple heart. In-Game asset. 2d. High contrast. No shadows
A peanut. In-Game asset. 2d. High contrast. No shadows
Cashew nut. In-Game asset. 2d. High contrast. No shadows
Grimace shake. In-Game asset. 2d. High contrast. No shadows
MacDonald's fries. In-Game asset. 2d. High contrast. No shadows
Grimace unlocked button. In-Game asset. 2d. High contrast. No shadows
Michael Jackson unlocked button. In-Game asset. 2d. High contrast. No shadows
John Cena unlocked button. In-Game asset. 2d. High contrast. No shadows
Deez nuts unlocked button. In-Game asset. 2d. High contrast. No shadows
Shooting stars unlocked button. In-Game asset. 2d. High contrast. No shadows
Rick roll unlocked button. In-Game asset. 2d. High contrast. No shadows
Popcorn chicken. In-Game asset. 2d. High contrast. No shadows
Fried chicken drumstick. In-Game asset. 2d. High contrast. No shadows
Amazing digital circus button. In-Game asset. 2d. High contrast. No shadows
Select game mode button. In-Game asset. 2d. High contrast. No shadows
Diamond shaped colourful classic mode button. In-Game asset. 2d. High contrast. No shadows
Diamond shaped colourful mini games button. In-Game asset. 2d. High contrast. No shadows
Same picture in high definition
Diamond shaped colourful button that says sling shot mode. In-Game asset. 2d. High contrast. No shadows
Make picture transparent
Bullet. In-Game asset. 2d. High contrast. No shadows
Start game button. In-Game asset. 2d. High contrast. No shadows
Shooting gallery button. In-Game asset. 2d. High contrast. No shadows
launch
Sound effect
Gamestart
Sound effect
collect
Sound effect
gameMusic
Music
Gamemusic
Sound effect
Bogerk
Sound effect
pop
Sound effect
Pignoise
Sound effect
Steve
Sound effect
Villager
Sound effect
Spider
Sound effect
Skeleton
Sound effect
Shootingstars
Music
Maccas
Sound effect
Grimace
Sound effect
Thriller
Music
MJ
Sound effect
Cenaentrance
Music
Johncena
Sound effect
Chickencluck
Sound effect
Deeznuts
Sound effect
Deeznutstrap
Music
Rickroll
Sound effect
Nevergonna
Music
Starz
Sound effect
Grimaceshake
Music
Joenugget
Sound effect
gegagedi
Music
Shrek
Sound effect
Raveswamp
Music
Pomni
Sound effect
Digcircus
Music
Runandgo
Music
Gunshot
Sound effect