User prompt
Change instructions to swipe and flick the chicken and collect as much popcorn as possible
User prompt
Adjust bounce so chicken moves from side to side
User prompt
Play background music after gamestart sound
User prompt
Add game music in background
User prompt
Please fix the bug: 'Cannot read properties of null (reading 'toLocaleString')' in or related to this line: 'var scoreText = new Text2(highScores[i].toLocaleString(), {' Line Number: 142
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'highScores.push(scoreObj);' Line Number: 1228
User prompt
Fix errors please
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'highScores.push(scoreObj);' Line Number: 1222
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'highScores.push(scoreObj);' Line Number: 1215
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'highScores.push({' Line Number: 1209 âȘđĄ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'highScores.push({' Line Number: 1209
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'highScores.push({' Line Number: 1205
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'highScores.push({' Line Number: 1205
User prompt
Enlarge keyboard
User prompt
Move keyboard down 500
User prompt
Move keyboard down 500 so you can see name entry
User prompt
Allow more time to enter initials before game over appears
User prompt
Increase size of keyboard to enter initials
User prompt
Please fix the bug: 'Cannot read properties of null (reading 'score')' in or related to this line: 'scoreValue = highScore.score;' Line Number: 137
User prompt
Add initials on high score list
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading '_ref')' in or related to this line: 'var scoreA = storage[highScoresKey + '_' + a._ref + '_score'] || 0;' Line Number: 1101
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: 'highScores[i] = {' Line Number: 1086
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: 'highScores[i] = {' Line Number: 1086
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: 'highScores[i] = {' Line Number: 1086
User prompt
Please fix the bug: 'Cannot read properties of null (reading 'score')' in or related to this line: 'var scoreText = new Text2(highScores[i].score ? highScores[i].score.toLocaleString() : highScores[i].toLocaleString(), {' Line Number: 232 âȘđĄ Consider importing and using the following plugins: @upit/storage.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var ChickenJockey = Container.expand(function () { var self = Container.call(this); // Create and attach chicken asset var chickenGraphics = self.attachAsset('chicken', { anchorX: 0.5, anchorY: 0.5 }); // Physics properties self.vx = 0; self.vy = 0; self.gravity = 0.5; self.bounceDecay = 0.7; // Reduced bounce decay for more sustained bounces self.friction = 0.998; // Increased horizontal friction for less horizontal drift self.launched = false; self.bounceCount = 0; self.maxBounces = 5; // Allow 5 bounces per swipe // Rotation properties self.rotationSpeed = 0; self.launch = function (power, angle) { // Convert angle to radians var radians = angle * Math.PI / 180; // Set initial velocity based on power and angle self.vx = Math.cos(radians) * power; self.vy = Math.sin(radians) * power; // Set rotation speed based on velocity 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; self.maxBounces = 300; // Set the max bounces here too }; self.update = function () { if (!self.launched) { return; } // Apply physics with speed limiting self.vy += self.gravity; // Cap maximum velocity to prevent freezing var maxSpeed = 30; self.vx = Math.max(-maxSpeed, Math.min(maxSpeed, self.vx)); self.vy = Math.max(-maxSpeed, Math.min(maxSpeed, self.vy)); self.x += self.vx; self.y += self.vy; self.vx *= self.friction; // Apply rotation with speed limiting self.rotationSpeed = Math.max(-0.2, Math.min(0.2, self.rotationSpeed)); self.rotation += self.rotationSpeed; // Check if stopped if (Math.abs(self.vx) < 0.5 && Math.abs(self.vy) < 0.5 && self.bounceCount > 0) { 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 HighScoreTally = Container.expand(function () { var self = Container.call(this); // Background container var background = self.attachAsset('rope', { anchorX: 0.5, anchorY: 0.5 }); background.width = 1400; background.height = 1200; background.tint = 0x000000; background.alpha = 0.8; // Title text var titleText = new Text2("HIGH SCORES", { size: 100, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0); titleText.y = -background.height / 2 + 100; self.addChild(titleText); // Username input container var usernameContainer = new Container(); var usernameLabel = new Text2("Enter Your Name:", { size: 50, fill: 0xFFFFFF }); usernameLabel.anchor.set(0.5, 0.5); usernameLabel.y = -30; usernameContainer.addChild(usernameLabel); // Username input field var inputFieldBg = usernameContainer.attachAsset('rope', { anchorX: 0.5, anchorY: 0.5 }); inputFieldBg.width = 800; inputFieldBg.height = 80; inputFieldBg.tint = 0x333333; var usernameText = new Text2("PLAYER", { size: 50, fill: 0xFFFFFF }); usernameText.anchor.set(0.5, 0.5); usernameContainer.addChild(usernameText); // Position username container usernameContainer.y = -background.height / 2 + 170; self.addChild(usernameContainer); // Username edit state var editingUsername = false; usernameContainer.interactive = true; usernameContainer.down = function () { editingUsername = true; inputFieldBg.tint = 0x555555; usernameText.tint = 0xFFFF00; // Display keyboard instruction self.showKeyboardInstruction(); }; // Show keyboard instruction self.showKeyboardInstruction = function () { if (self.keyboardInstruction) { return; } self.keyboardInstruction = new Text2("Tap on screen to type your name", { size: 40, fill: 0xFFFFFF }); self.keyboardInstruction.anchor.set(0.5, 0); self.keyboardInstruction.y = usernameContainer.y + 50; self.addChild(self.keyboardInstruction); }; // Hide keyboard instruction self.hideKeyboardInstruction = function () { if (self.keyboardInstruction && self.keyboardInstruction.parent) { self.keyboardInstruction.parent.removeChild(self.keyboardInstruction); self.keyboardInstruction = null; } }; // Handle background tap to exit editing mode background.interactive = true; background.down = function (x, y, obj) { if (editingUsername && !usernameContainer.contains(obj.position)) { editingUsername = false; inputFieldBg.tint = 0x333333; usernameText.tint = 0xFFFFFF; self.hideKeyboardInstruction(); } }; // Method to set username self.setUsername = function (name) { usernameText.setText(name); storage['playerName'] = name; }; // Initialize with stored username if available if (storage['playerName']) { usernameText.setText(storage['playerName']); } // Score entries container var scoreEntries = []; self.updateScores = function (highScores) { // Clear existing entries for (var i = 0; i < scoreEntries.length; i++) { if (scoreEntries[i].parent) { scoreEntries[i].parent.removeChild(scoreEntries[i]); } } scoreEntries = []; // Create new entries var startY = -background.height / 2 + 350; // Adjusted to make room for username input var padding = 80; for (var i = 0; i < highScores.length && i < 5; i++) { var entry = new Container(); // Rank var rankText = new Text2(i + 1 + ".", { size: 70, fill: 0xFFFFFF }); rankText.anchor.set(0, 0.5); rankText.x = -background.width / 2 + 200; entry.addChild(rankText); // Username var username = "PLAYER"; if (highScores[i] && highScores[i].name) { username = highScores[i].name; } else if (highScores[i] && highScores[i]._ref !== undefined) { var ref = highScores[i]._ref; username = storage[highScoresKey + '_' + ref + '_name'] || "PLAYER"; } var nameText = new Text2(username, { size: 50, fill: 0xFFFFFF }); nameText.anchor.set(0, 0.5); nameText.x = -background.width / 2 + 300; entry.addChild(nameText); // Score var scoreText = new Text2(highScores[i] && highScores[i].score ? highScores[i].score.toLocaleString() : highScores[i] ? highScores[i].toLocaleString() : "0", { size: 70, fill: 0xFFD700 }); scoreText.anchor.set(1, 0.5); scoreText.x = background.width / 2 - 200; entry.addChild(scoreText); // Position entry entry.y = startY + i * padding; self.addChild(entry); scoreEntries.push(entry); } // If no scores available if (highScores.length === 0) { var noScoreText = new Text2("No scores yet!", { size: 70, fill: 0xFFFFFF }); noScoreText.anchor.set(0.5, 0.5); noScoreText.y = 0; self.addChild(noScoreText); scoreEntries.push(noScoreText); } }; // Start button var startButton = new Container(); var buttonBg = startButton.attachAsset('rope', { anchorX: 0.5, anchorY: 0.5 }); buttonBg.width = 600; buttonBg.height = 150; buttonBg.tint = 0x00AA00; var buttonText = new Text2("PLAY GAME", { size: 70, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); startButton.addChild(buttonText); startButton.y = background.height / 2 - 200; self.addChild(startButton); startButton.interactive = true; startButton.down = function () { buttonBg.tint = 0x007700; }; startButton.up = function () { buttonBg.tint = 0x00AA00; if (typeof self.onStart === 'function') { self.onStart(); } }; // Make container position in center of screen self.x = 2048 / 2; self.y = 2732 / 2; return self; }); var PathTracer = Container.expand(function () { var self = Container.call(this); self.points = []; self.maxPoints = 50; self.lineWidth = 5; self.lineColor = 0xFFFFFF; self.active = false; // Create visual representation of the path var pathGraphics = self.attachAsset('rope', { anchorX: 0.5, anchorY: 0.5 }); // Initialize path graphics pathGraphics.alpha = 0.5; pathGraphics.width = 0; pathGraphics.height = 0; self.startTracing = function (x, y) { self.points = [{ x: x, y: y }]; self.active = true; }; self.addPoint = function (x, y) { if (!self.active) { return; } // Only add point if it's significantly different from last point var lastPoint = self.points[self.points.length - 1]; var dx = x - lastPoint.x; var dy = y - lastPoint.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 20) { self.points.push({ x: x, y: y }); // Limit number of points if (self.points.length > self.maxPoints) { self.points.shift(); } } }; self.stopTracing = function () { self.active = false; return self.points.length >= 2 ? self.points : null; }; self.clear = function () { self.points = []; self.active = false; }; self.update = function () { // Update path visualization based on current points if (self.points.length < 2) { pathGraphics.alpha = 0; return; } pathGraphics.alpha = 0.5; // Calculate path visual representation var firstPoint = self.points[0]; var lastPoint = self.points[self.points.length - 1]; // Position at midpoint of path self.x = (firstPoint.x + lastPoint.x) / 2; self.y = (firstPoint.y + lastPoint.y) / 2; // Calculate path length and angle var dx = lastPoint.x - firstPoint.x; var dy = lastPoint.y - firstPoint.y; var length = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); // Update path graphics pathGraphics.width = length; pathGraphics.height = self.lineWidth; pathGraphics.rotation = angle; }; return self; }); var Popcorn = Container.expand(function () { var self = Container.call(this); // Create and attach popcorn asset var popcornGraphics = self.attachAsset('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.collect = function () { // Play collect sound LK.getSound('collect').play(); // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 200); // Animate collection (flying up) tween(self, { y: self.y - 100, alpha: 0 }, { duration: 500, 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.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 5; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); // Create and attach power-up asset (using popcorn as base) var powerUpGraphics = self.attachAsset('popcorn', { anchorX: 0.5, anchorY: 0.5 }); // Make it visually distinct powerUpGraphics.tint = 0x00FFFF; // PowerUp properties self.type = "multiplier"; // Default type self.value = 2; // Default multiplier value self.duration = 10000; // 10 seconds self.active = false; // Animation properties self.animationOffset = Math.random() * Math.PI * 2; self.animationSpeed = 0.05 + Math.random() * 0.03; self.baseY = 0; self.scale = 1.5; // Make power-ups slightly larger // Pulse animation self.pulseDirection = 1; self.pulseSpeed = 0.02; self.minScale = 1.3; self.maxScale = 1.7; self.collect = function () { // Play collect sound with higher pitch var sound = LK.getSound('collect'); sound.play(); // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 300); // Animate collection (flying up) tween(self, { y: self.y - 150, alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { // Remove from parent if (self.parent) { self.parent.removeChild(self); } } }); // Activate the powerup effect if (typeof game.activatePowerUp === 'function') { game.activatePowerUp(self.type, self.value, self.duration); } }; self.update = function () { // Hover animation if (self.baseY === 0) { self.baseY = self.y; } // Vertical hover self.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 8; // Pulsing animation var currentScale = self.scale; currentScale += self.pulseDirection * self.pulseSpeed; if (currentScale > self.maxScale) { currentScale = self.maxScale; self.pulseDirection = -1; } else if (currentScale < self.minScale) { currentScale = self.minScale; self.pulseDirection = 1; } self.scale = currentScale; self.scaleX = self.scale; self.scaleY = self.scale; }; 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.5; // Reduced tension for less chaotic bounces self.bounce = function (chickenJockey) { // Calculate new velocity based on collision angle and rope tension var normalAngle = Math.atan2(chickenJockey.y - self.y, chickenJockey.x - self.x); // Angle from rope to chicken // Calculate new velocity based on angle and tension var speed = Math.sqrt(chickenJockey.vx * chickenJockey.vx + chickenJockey.vy * chickenJockey.vy); var bounceAngle = 2 * normalAngle - Math.atan2(chickenJockey.vy, chickenJockey.vx); // Angle of reflection var bounceForce = speed * self.tension; chickenJockey.vx = Math.cos(bounceAngle) * bounceForce * chickenJockey.bounceDecay; chickenJockey.vy = Math.sin(bounceAngle) * bounceForce * chickenJockey.bounceDecay; // Increment bounce count chickenJockey.bounceCount++; // Play bounce sound LK.getSound('bounce').play(); // Flash rope to indicate bounce LK.effects.flashObject(self, 0xFFFFFF, 200); // Add points for bouncing if (typeof game.addScore === 'function') { game.addScore(5000); } // Occasionally spawn popcorn on rope bounce if (Math.random() < 0.3 && typeof game.createPopcornAt === 'function') { game.createPopcornAt(chickenJockey.x, chickenJockey.y, 3); } }; 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Black background }); /**** * Game Code ****/ // Game state var gameState = "ready"; // ready, aiming, launched, gameOver var score = 0; var launches = 0; var maxLaunches = 5; var popcorns = []; var ropes = []; var powerUps = []; var scoreMultiplier = 1; var multiplierEndTime = 0; var highScoresKey = 'chickenJockeyHighScores'; var pathTracer = game.addChild(new PathTracer()); // Add backdrop first var backdrop = game.addChild(LK.getAsset('Backdrop', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 })); // Create wrestling arena var arena = game.addChild(LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 })); // Create chicken jockey var chickenJockey = game.addChild(new ChickenJockey()); // 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 scoreText = new Text2("Score: 0", { size: 70, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var launchesText = new Text2("Launches: 0/" + maxLaunches, { size: 50, fill: 0xFFFFFF }); launchesText.anchor.set(0, 0); launchesText.x = 120; // Avoid top-left corner launchesText.y = 20; LK.gui.topLeft.addChild(launchesText); var instructionText = new Text2("Drag to aim and launch the chicken!", { size: 40, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0); instructionText.y = 100; LK.gui.top.addChild(instructionText); // Initialize game function initGame() { // Reset variables score = 0; launches = 0; maxLaunches = 5; scoreMultiplier = 1; multiplierEndTime = 0; gameState = "ready"; // Update UI scoreText.setText("Score: " + score); launchesText.setText("Launches: " + launches + "/" + maxLaunches); instructionText.setText("Swipe to launch the chicken!"); // Reset chicken jockey resetChickenJockey(); // Clear existing popcorn and ropes clearPopcornsAndRopes(); // Create ropes around the arena createRopes(); // Create popcorn scattered around the arena createPopcorn(40); // Create a few power-ups for (var i = 0; i < 3; i++) { createPowerUp(); } // Play game start sound LK.getSound('Gamestart').play(); // Play background music LK.playMusic('gameMusic'); } function resetChickenJockey() { chickenJockey.reset(); // Position chicken in the center of the arena chickenJockey.x = arena.x; chickenJockey.y = arena.y; } 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 ropes for (var i = 0; i < ropes.length; i++) { if (ropes[i].parent) { ropes[i].parent.removeChild(ropes[i]); } } ropes = []; // Remove all power-ups for (var i = 0; i < powerUps.length; i++) { if (powerUps[i].parent) { powerUps[i].parent.removeChild(powerUps[i]); } } powerUps = []; } function createRopes() { // Create top rope var topRope = new Rope(); topRope.x = arena.x; topRope.y = bounds.top + 100; game.addChild(topRope); ropes.push(topRope); // Create right rope var rightRope = new Rope(); rightRope.x = bounds.right - 100; 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 - 100; game.addChild(bottomRope); ropes.push(bottomRope); // Create left rope var leftRope = new Rope(); leftRope.x = bounds.left + 100; leftRope.y = arena.y; leftRope.rotation = Math.PI / 2; // Rotate 90 degrees game.addChild(leftRope); ropes.push(leftRope); } function createPopcorn(count) { for (var i = 0; i < count; i++) { var popcorn = new Popcorn(); // Random position within arena bounds popcorn.x = bounds.left + 100 + Math.random() * (arena.width - 200); popcorn.y = bounds.top + 100 + Math.random() * (arena.height - 200); // Add to game game.addChild(popcorn); popcorns.push(popcorn); } } function createPowerUp() { var powerUp = new PowerUp(); // Random position within arena bounds powerUp.x = bounds.left + 150 + Math.random() * (arena.width - 300); powerUp.y = bounds.top + 150 + Math.random() * (arena.height - 300); // Random power-up type var types = ["multiplier", "extraLaunch", "superBounce"]; var randomType = types[Math.floor(Math.random() * types.length)]; powerUp.type = randomType; // Configure based on type if (randomType === "multiplier") { powerUp.tint = 0x00FFFF; // Cyan powerUp.value = 2 + Math.floor(Math.random() * 3); // 2x to 4x multiplier } else if (randomType === "extraLaunch") { powerUp.tint = 0xFF00FF; // Purple powerUp.value = 1; // Extra launch } else if (randomType === "superBounce") { powerUp.tint = 0xFFFF00; // Yellow powerUp.value = 2; // Double bounce points } // Add to game game.addChild(powerUp); powerUps.push(powerUp); } // Game events game.onChickenJockeyStop = function () { gameState = "ready"; // Add more popcorn when chicken jockey stops if (popcorns.length < 20) { createPopcorn(15); } // Occasionally add a power-up when chicken stops if (Math.random() < 0.3 && powerUps.length < 5) { createPowerUp(); } // Check if out of launches if (launches >= maxLaunches) { // Game over instructionText.setText("Game Over! Final Score: " + score); gameState = "gameOver"; // Show game over after a short delay LK.setTimeout(function () { // Play game start sound again as game over sound LK.getSound('Gamestart').play(); LK.showGameOver(); }, 2000); } else { // Reset for next launch resetChickenJockey(); instructionText.setText("Drag to aim and launch the chicken!"); } }; game.onMaxBouncesReached = function () { // Same as onChickenJockeyStop for now game.onChickenJockeyStop(); }; // Input handling var dragStartX = 0; var dragStartY = 0; var dragEndX = 0; var dragEndY = 0; game.down = function (x, y, obj) { if (gameState === "ready") { gameState = "aiming"; dragStartX = x; dragStartY = y; pathTracer.startTracing(x, y); instructionText.setText("Draw a path for the chicken!"); } }; game.move = function (x, y, obj) { if (gameState === "aiming") { pathTracer.addPoint(x, y); } }; game.up = function (x, y, obj) { if (gameState === "aiming") { // Get the path from the path tracer var path = pathTracer.stopTracing(); // Only launch if we have a valid path if (path && path.length >= 2) { // Record drag end position dragEndX = x; dragEndY = y; // Calculate direction from the path var firstPoint = path[0]; var lastPoint = path[path.length - 1]; var dx = lastPoint.x - firstPoint.x; var dy = lastPoint.y - firstPoint.y; var distance = Math.sqrt(dx * dx + dy * dy); // Calculate power based on path length (with a more controlled range) var power = Math.min(distance, 200) * 0.2; // Calculate angle based on path direction var angle = Math.atan2(dy, dx) * 180 / Math.PI; chickenJockey.launch(power, angle); // Update game state gameState = "launched"; launches++; launchesText.setText("Launches: " + launches + "/" + maxLaunches); instructionText.setText("Watch the chicken bounce!"); } else { // Cancel the launch if the path was too short gameState = "ready"; } // Clear the path tracer regardless pathTracer.clear(); } }; // Add helper to update score game.addScore = function (points) { // Apply multiplier if active var finalPoints = points; if (Date.now() < multiplierEndTime) { finalPoints = Math.floor(points * scoreMultiplier); } score += finalPoints; scoreText.setText("Score: " + score); LK.setScore(score); // Visual feedback for big point gains if (finalPoints >= 5000) { var pointText = new Text2("+" + finalPoints, { size: 50, fill: 0xFFFF00 }); pointText.anchor.set(0.5, 0.5); pointText.x = chickenJockey.x; pointText.y = chickenJockey.y - 100; game.addChild(pointText); tween(pointText, { y: pointText.y - 150, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { if (pointText.parent) { pointText.parent.removeChild(pointText); } } }); } }; // Helper method to create popcorn at specific location game.createPopcornAt = function (x, y, count) { count = count || 1; for (var i = 0; i < count; i++) { var popcorn = new Popcorn(); // Position near the specified location with some random offset var offsetX = (Math.random() - 0.5) * 200; var offsetY = (Math.random() - 0.5) * 200; popcorn.x = Math.max(bounds.left + 50, Math.min(bounds.right - 50, x + offsetX)); popcorn.y = Math.max(bounds.top + 50, Math.min(bounds.bottom - 50, y + offsetY)); // Add to game game.addChild(popcorn); popcorns.push(popcorn); } }; // Power-up activation function game.activatePowerUp = function (type, value, duration) { // Visual feedback for power-up activation LK.effects.flashScreen(0x00FFFF, 500); if (type === "multiplier") { // Set score multiplier scoreMultiplier = value; // Display message showMessage("Score x" + value + " for " + duration / 1000 + "s!", 0x00FFFF); // Set timer to end effect multiplierEndTime = Date.now() + duration; } else if (type === "extraLaunch") { // Add extra launches maxLaunches += value; launches = Math.max(0, launches - value); // Refund a launch launchesText.setText("Launches: " + launches + "/" + maxLaunches); // Display message showMessage("+" + value + " Extra Launch!", 0xFF00FF); } else if (type === "superBounce") { // Temporarily increase bounce values var oldBounceDecay = chickenJockey.bounceDecay; chickenJockey.bounceDecay = Math.min(1.0, chickenJockey.bounceDecay * 1.3); // Display message showMessage("Super Bounce for " + duration / 1000 + "s!", 0xFFFF00); // Set timer to end effect LK.setTimeout(function () { chickenJockey.bounceDecay = oldBounceDecay; }, duration); } }; // Helper function to show temporary messages function showMessage(text, color) { var message = new Text2(text, { size: 60, fill: color || 0xFFFFFF }); message.anchor.set(0.5, 0.5); message.x = 2048 / 2; message.y = 400; LK.gui.center.addChild(message); // Animate in message.alpha = 0; message.scaleX = 0.5; message.scaleY = 0.5; tween(message, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); // Animate out after delay LK.setTimeout(function () { tween(message, { alpha: 0, y: message.y - 100 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { if (message.parent) { message.parent.removeChild(message); } } }); }, 2000); } // Main game loop game.update = function () { // Check for keyboard input for username if (highScoreTally.parent && highScoreTally.editingUsername) { // Simulate keyboard input for demonstration if (LK.ticks % 30 === 0 && Math.random() < 0.1) { var currentName = storage['playerName'] || "PLAYER"; // Generate random character var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var randomChar = chars.charAt(Math.floor(Math.random() * chars.length)); if (currentName === "PLAYER") { currentName = randomChar; } else if (currentName.length < 10) { currentName += randomChar; } highScoreTally.setUsername(currentName); } } // 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; // Apply decay on horizontal bounce chickenJockey.bounceCount++; LK.getSound('bounce').play(); game.addScore(2000); } else if (chickenJockey.x > bounds.right) { chickenJockey.x = bounds.right; chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay; // Apply decay on horizontal bounce chickenJockey.bounceCount++; LK.getSound('bounce').play(); game.addScore(2000); } if (chickenJockey.y < bounds.top) { chickenJockey.y = bounds.top; chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; // Apply decay on vertical bounce chickenJockey.bounceCount++; LK.getSound('bounce').play(); game.addScore(2000); } else if (chickenJockey.y > bounds.bottom) { chickenJockey.y = bounds.bottom; chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; // Apply decay on vertical bounce chickenJockey.bounceCount++; LK.getSound('bounce').play(); game.addScore(2000); } // 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 game.addScore(10000); scoreText.setText("Score: " + score); // Save score to LK LK.setScore(score); // No longer reset launches when score reaches 1000 } } // Check for collisions with power-ups for (var i = powerUps.length - 1; i >= 0; i--) { if (chickenJockey.intersects(powerUps[i])) { // Collect power-up powerUps[i].collect(); // Remove from array powerUps.splice(i, 1); } } } // Update popcorn animations for (var i = 0; i < popcorns.length; i++) { popcorns[i].update(); } // Update power-up animations for (var i = 0; i < powerUps.length; i++) { powerUps[i].update(); } // Randomly spawn new power-ups (rare) if (gameState === "launched" && Math.random() < 0.001 && powerUps.length < 5) { createPowerUp(); } // Update path tracer pathTracer.update(); // Update score multiplier UI if active if (Date.now() < multiplierEndTime && scoreMultiplier > 1) { // Update multiplier display in score text var remainingSecs = Math.ceil((multiplierEndTime - Date.now()) / 1000); scoreText.setText("Score: " + score + " (x" + scoreMultiplier + " for " + remainingSecs + "s)"); } // Award extra launch for every million points if (score >= 1000000 && score % 1000000 < 10000) { // Only award once when crossing each million point threshold if (!game.lastMillionMark || Math.floor(score / 1000000) > Math.floor(game.lastMillionMark / 1000000)) { maxLaunches++; showMessage("Extra Launch for 1,000,000 points!", 0xFFFF00); launchesText.setText("Launches: " + launches + "/" + maxLaunches); game.lastMillionMark = score; // Create animated free launch text var freeText = new Text2("FREE LAUNCH!", { size: 100, fill: 0xFFFF00 }); freeText.anchor.set(0.5, 0.5); freeText.x = 2048 / 2; freeText.y = 2732 / 2; freeText.alpha = 0; freeText.scaleX = 0.5; freeText.scaleY = 0.5; LK.gui.center.addChild(freeText); // Animate in with bounce effect tween(freeText, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.elasticOut, onFinish: function onFinish() { // Pulse animation tween(freeText, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { // Animate out with upward movement tween(freeText, { alpha: 0, y: freeText.y - 200 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { if (freeText.parent) { freeText.parent.removeChild(freeText); } } }); } }); } }); } } }; // High score management functions function getHighScores() { return storage[highScoresKey] || []; } function saveHighScore(score) { var highScores = getHighScores(); // Create score object with name and score var playerName = storage['playerName'] || "PLAYER"; // Convert old format scores if needed for (var i = 0; i < highScores.length; i++) { if (typeof highScores[i] === 'number') { // Create individual properties for storage compatibility var tempScore = highScores[i]; // Clear the entry first highScores[i] = null; // Set each property individually storage[highScoresKey + '_' + i + '_name'] = "PLAYER"; storage[highScoresKey + '_' + i + '_score'] = tempScore; storage[highScoresKey + '_' + i + '_date'] = 0; // Store the mapping in the array highScores[i] = { _ref: i }; } } // Create new score entry using separate storage var newScoreIndex = highScores.length; storage[highScoresKey + '_' + newScoreIndex + '_name'] = playerName; storage[highScoresKey + '_' + newScoreIndex + '_score'] = score; storage[highScoresKey + '_' + newScoreIndex + '_date'] = Date.now(); // Add reference to the array - avoid nested objects highScores.push(null); highScores[highScores.length - 1] = {}; highScores[highScores.length - 1]._ref = newScoreIndex; // Sort in descending order by score highScores.sort(function (a, b) { var scoreA = storage[highScoresKey + '_' + a._ref + '_score'] || 0; var scoreB = storage[highScoresKey + '_' + b._ref + '_score'] || 0; return scoreB - scoreA; }); // Keep only top 10 scores if (highScores.length > 10) { highScores = highScores.slice(0, 10); } // Save to storage storage[highScoresKey] = highScores; } // Create high score tally var highScoreTally = new HighScoreTally(); highScoreTally.visible = true; highScoreTally.onStart = function () { game.removeChild(highScoreTally); initGame(); }; // Show high scores at start game.addChild(highScoreTally); highScoreTally.updateScores(getHighScores()); // Modified game over handling var originalOnChickenJockeyStop = game.onChickenJockeyStop; game.onChickenJockeyStop = function () { // Call original function first originalOnChickenJockeyStop(); // If game over, save score if (gameState === "gameOver") { saveHighScore(score); // We'll show high scores after game over in LK.showGameOver callback } }; // Handle game start LK.onGameOver = function () { // Show high score tally after game over game.addChild(highScoreTally); highScoreTally.updateScores(getHighScores()); }; // Initialize the game (commented out because we're showing high scores first) // initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var ChickenJockey = Container.expand(function () {
var self = Container.call(this);
// Create and attach chicken asset
var chickenGraphics = self.attachAsset('chicken', {
anchorX: 0.5,
anchorY: 0.5
});
// Physics properties
self.vx = 0;
self.vy = 0;
self.gravity = 0.5;
self.bounceDecay = 0.7; // Reduced bounce decay for more sustained bounces
self.friction = 0.998; // Increased horizontal friction for less horizontal drift
self.launched = false;
self.bounceCount = 0;
self.maxBounces = 5; // Allow 5 bounces per swipe
// Rotation properties
self.rotationSpeed = 0;
self.launch = function (power, angle) {
// Convert angle to radians
var radians = angle * Math.PI / 180;
// Set initial velocity based on power and angle
self.vx = Math.cos(radians) * power;
self.vy = Math.sin(radians) * power;
// Set rotation speed based on velocity
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;
self.maxBounces = 300; // Set the max bounces here too
};
self.update = function () {
if (!self.launched) {
return;
}
// Apply physics with speed limiting
self.vy += self.gravity;
// Cap maximum velocity to prevent freezing
var maxSpeed = 30;
self.vx = Math.max(-maxSpeed, Math.min(maxSpeed, self.vx));
self.vy = Math.max(-maxSpeed, Math.min(maxSpeed, self.vy));
self.x += self.vx;
self.y += self.vy;
self.vx *= self.friction;
// Apply rotation with speed limiting
self.rotationSpeed = Math.max(-0.2, Math.min(0.2, self.rotationSpeed));
self.rotation += self.rotationSpeed;
// Check if stopped
if (Math.abs(self.vx) < 0.5 && Math.abs(self.vy) < 0.5 && self.bounceCount > 0) {
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 HighScoreTally = Container.expand(function () {
var self = Container.call(this);
// Background container
var background = self.attachAsset('rope', {
anchorX: 0.5,
anchorY: 0.5
});
background.width = 1400;
background.height = 1200;
background.tint = 0x000000;
background.alpha = 0.8;
// Title text
var titleText = new Text2("HIGH SCORES", {
size: 100,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0);
titleText.y = -background.height / 2 + 100;
self.addChild(titleText);
// Username input container
var usernameContainer = new Container();
var usernameLabel = new Text2("Enter Your Name:", {
size: 50,
fill: 0xFFFFFF
});
usernameLabel.anchor.set(0.5, 0.5);
usernameLabel.y = -30;
usernameContainer.addChild(usernameLabel);
// Username input field
var inputFieldBg = usernameContainer.attachAsset('rope', {
anchorX: 0.5,
anchorY: 0.5
});
inputFieldBg.width = 800;
inputFieldBg.height = 80;
inputFieldBg.tint = 0x333333;
var usernameText = new Text2("PLAYER", {
size: 50,
fill: 0xFFFFFF
});
usernameText.anchor.set(0.5, 0.5);
usernameContainer.addChild(usernameText);
// Position username container
usernameContainer.y = -background.height / 2 + 170;
self.addChild(usernameContainer);
// Username edit state
var editingUsername = false;
usernameContainer.interactive = true;
usernameContainer.down = function () {
editingUsername = true;
inputFieldBg.tint = 0x555555;
usernameText.tint = 0xFFFF00;
// Display keyboard instruction
self.showKeyboardInstruction();
};
// Show keyboard instruction
self.showKeyboardInstruction = function () {
if (self.keyboardInstruction) {
return;
}
self.keyboardInstruction = new Text2("Tap on screen to type your name", {
size: 40,
fill: 0xFFFFFF
});
self.keyboardInstruction.anchor.set(0.5, 0);
self.keyboardInstruction.y = usernameContainer.y + 50;
self.addChild(self.keyboardInstruction);
};
// Hide keyboard instruction
self.hideKeyboardInstruction = function () {
if (self.keyboardInstruction && self.keyboardInstruction.parent) {
self.keyboardInstruction.parent.removeChild(self.keyboardInstruction);
self.keyboardInstruction = null;
}
};
// Handle background tap to exit editing mode
background.interactive = true;
background.down = function (x, y, obj) {
if (editingUsername && !usernameContainer.contains(obj.position)) {
editingUsername = false;
inputFieldBg.tint = 0x333333;
usernameText.tint = 0xFFFFFF;
self.hideKeyboardInstruction();
}
};
// Method to set username
self.setUsername = function (name) {
usernameText.setText(name);
storage['playerName'] = name;
};
// Initialize with stored username if available
if (storage['playerName']) {
usernameText.setText(storage['playerName']);
}
// Score entries container
var scoreEntries = [];
self.updateScores = function (highScores) {
// Clear existing entries
for (var i = 0; i < scoreEntries.length; i++) {
if (scoreEntries[i].parent) {
scoreEntries[i].parent.removeChild(scoreEntries[i]);
}
}
scoreEntries = [];
// Create new entries
var startY = -background.height / 2 + 350; // Adjusted to make room for username input
var padding = 80;
for (var i = 0; i < highScores.length && i < 5; i++) {
var entry = new Container();
// Rank
var rankText = new Text2(i + 1 + ".", {
size: 70,
fill: 0xFFFFFF
});
rankText.anchor.set(0, 0.5);
rankText.x = -background.width / 2 + 200;
entry.addChild(rankText);
// Username
var username = "PLAYER";
if (highScores[i] && highScores[i].name) {
username = highScores[i].name;
} else if (highScores[i] && highScores[i]._ref !== undefined) {
var ref = highScores[i]._ref;
username = storage[highScoresKey + '_' + ref + '_name'] || "PLAYER";
}
var nameText = new Text2(username, {
size: 50,
fill: 0xFFFFFF
});
nameText.anchor.set(0, 0.5);
nameText.x = -background.width / 2 + 300;
entry.addChild(nameText);
// Score
var scoreText = new Text2(highScores[i] && highScores[i].score ? highScores[i].score.toLocaleString() : highScores[i] ? highScores[i].toLocaleString() : "0", {
size: 70,
fill: 0xFFD700
});
scoreText.anchor.set(1, 0.5);
scoreText.x = background.width / 2 - 200;
entry.addChild(scoreText);
// Position entry
entry.y = startY + i * padding;
self.addChild(entry);
scoreEntries.push(entry);
}
// If no scores available
if (highScores.length === 0) {
var noScoreText = new Text2("No scores yet!", {
size: 70,
fill: 0xFFFFFF
});
noScoreText.anchor.set(0.5, 0.5);
noScoreText.y = 0;
self.addChild(noScoreText);
scoreEntries.push(noScoreText);
}
};
// Start button
var startButton = new Container();
var buttonBg = startButton.attachAsset('rope', {
anchorX: 0.5,
anchorY: 0.5
});
buttonBg.width = 600;
buttonBg.height = 150;
buttonBg.tint = 0x00AA00;
var buttonText = new Text2("PLAY GAME", {
size: 70,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
startButton.addChild(buttonText);
startButton.y = background.height / 2 - 200;
self.addChild(startButton);
startButton.interactive = true;
startButton.down = function () {
buttonBg.tint = 0x007700;
};
startButton.up = function () {
buttonBg.tint = 0x00AA00;
if (typeof self.onStart === 'function') {
self.onStart();
}
};
// Make container position in center of screen
self.x = 2048 / 2;
self.y = 2732 / 2;
return self;
});
var PathTracer = Container.expand(function () {
var self = Container.call(this);
self.points = [];
self.maxPoints = 50;
self.lineWidth = 5;
self.lineColor = 0xFFFFFF;
self.active = false;
// Create visual representation of the path
var pathGraphics = self.attachAsset('rope', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize path graphics
pathGraphics.alpha = 0.5;
pathGraphics.width = 0;
pathGraphics.height = 0;
self.startTracing = function (x, y) {
self.points = [{
x: x,
y: y
}];
self.active = true;
};
self.addPoint = function (x, y) {
if (!self.active) {
return;
}
// Only add point if it's significantly different from last point
var lastPoint = self.points[self.points.length - 1];
var dx = x - lastPoint.x;
var dy = y - lastPoint.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 20) {
self.points.push({
x: x,
y: y
});
// Limit number of points
if (self.points.length > self.maxPoints) {
self.points.shift();
}
}
};
self.stopTracing = function () {
self.active = false;
return self.points.length >= 2 ? self.points : null;
};
self.clear = function () {
self.points = [];
self.active = false;
};
self.update = function () {
// Update path visualization based on current points
if (self.points.length < 2) {
pathGraphics.alpha = 0;
return;
}
pathGraphics.alpha = 0.5;
// Calculate path visual representation
var firstPoint = self.points[0];
var lastPoint = self.points[self.points.length - 1];
// Position at midpoint of path
self.x = (firstPoint.x + lastPoint.x) / 2;
self.y = (firstPoint.y + lastPoint.y) / 2;
// Calculate path length and angle
var dx = lastPoint.x - firstPoint.x;
var dy = lastPoint.y - firstPoint.y;
var length = Math.sqrt(dx * dx + dy * dy);
var angle = Math.atan2(dy, dx);
// Update path graphics
pathGraphics.width = length;
pathGraphics.height = self.lineWidth;
pathGraphics.rotation = angle;
};
return self;
});
var Popcorn = Container.expand(function () {
var self = Container.call(this);
// Create and attach popcorn asset
var popcornGraphics = self.attachAsset('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.collect = function () {
// Play collect sound
LK.getSound('collect').play();
// Flash effect
LK.effects.flashObject(self, 0xFFFFFF, 200);
// Animate collection (flying up)
tween(self, {
y: self.y - 100,
alpha: 0
}, {
duration: 500,
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.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 5;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
// Create and attach power-up asset (using popcorn as base)
var powerUpGraphics = self.attachAsset('popcorn', {
anchorX: 0.5,
anchorY: 0.5
});
// Make it visually distinct
powerUpGraphics.tint = 0x00FFFF;
// PowerUp properties
self.type = "multiplier"; // Default type
self.value = 2; // Default multiplier value
self.duration = 10000; // 10 seconds
self.active = false;
// Animation properties
self.animationOffset = Math.random() * Math.PI * 2;
self.animationSpeed = 0.05 + Math.random() * 0.03;
self.baseY = 0;
self.scale = 1.5; // Make power-ups slightly larger
// Pulse animation
self.pulseDirection = 1;
self.pulseSpeed = 0.02;
self.minScale = 1.3;
self.maxScale = 1.7;
self.collect = function () {
// Play collect sound with higher pitch
var sound = LK.getSound('collect');
sound.play();
// Flash effect
LK.effects.flashObject(self, 0xFFFFFF, 300);
// Animate collection (flying up)
tween(self, {
y: self.y - 150,
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove from parent
if (self.parent) {
self.parent.removeChild(self);
}
}
});
// Activate the powerup effect
if (typeof game.activatePowerUp === 'function') {
game.activatePowerUp(self.type, self.value, self.duration);
}
};
self.update = function () {
// Hover animation
if (self.baseY === 0) {
self.baseY = self.y;
}
// Vertical hover
self.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 8;
// Pulsing animation
var currentScale = self.scale;
currentScale += self.pulseDirection * self.pulseSpeed;
if (currentScale > self.maxScale) {
currentScale = self.maxScale;
self.pulseDirection = -1;
} else if (currentScale < self.minScale) {
currentScale = self.minScale;
self.pulseDirection = 1;
}
self.scale = currentScale;
self.scaleX = self.scale;
self.scaleY = self.scale;
};
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.5; // Reduced tension for less chaotic bounces
self.bounce = function (chickenJockey) {
// Calculate new velocity based on collision angle and rope tension
var normalAngle = Math.atan2(chickenJockey.y - self.y, chickenJockey.x - self.x); // Angle from rope to chicken
// Calculate new velocity based on angle and tension
var speed = Math.sqrt(chickenJockey.vx * chickenJockey.vx + chickenJockey.vy * chickenJockey.vy);
var bounceAngle = 2 * normalAngle - Math.atan2(chickenJockey.vy, chickenJockey.vx); // Angle of reflection
var bounceForce = speed * self.tension;
chickenJockey.vx = Math.cos(bounceAngle) * bounceForce * chickenJockey.bounceDecay;
chickenJockey.vy = Math.sin(bounceAngle) * bounceForce * chickenJockey.bounceDecay;
// Increment bounce count
chickenJockey.bounceCount++;
// Play bounce sound
LK.getSound('bounce').play();
// Flash rope to indicate bounce
LK.effects.flashObject(self, 0xFFFFFF, 200);
// Add points for bouncing
if (typeof game.addScore === 'function') {
game.addScore(5000);
}
// Occasionally spawn popcorn on rope bounce
if (Math.random() < 0.3 && typeof game.createPopcornAt === 'function') {
game.createPopcornAt(chickenJockey.x, chickenJockey.y, 3);
}
};
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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Black background
});
/****
* Game Code
****/
// Game state
var gameState = "ready"; // ready, aiming, launched, gameOver
var score = 0;
var launches = 0;
var maxLaunches = 5;
var popcorns = [];
var ropes = [];
var powerUps = [];
var scoreMultiplier = 1;
var multiplierEndTime = 0;
var highScoresKey = 'chickenJockeyHighScores';
var pathTracer = game.addChild(new PathTracer());
// Add backdrop first
var backdrop = game.addChild(LK.getAsset('Backdrop', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}));
// Create wrestling arena
var arena = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}));
// Create chicken jockey
var chickenJockey = game.addChild(new ChickenJockey());
// 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 scoreText = new Text2("Score: 0", {
size: 70,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var launchesText = new Text2("Launches: 0/" + maxLaunches, {
size: 50,
fill: 0xFFFFFF
});
launchesText.anchor.set(0, 0);
launchesText.x = 120; // Avoid top-left corner
launchesText.y = 20;
LK.gui.topLeft.addChild(launchesText);
var instructionText = new Text2("Drag to aim and launch the chicken!", {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 100;
LK.gui.top.addChild(instructionText);
// Initialize game
function initGame() {
// Reset variables
score = 0;
launches = 0;
maxLaunches = 5;
scoreMultiplier = 1;
multiplierEndTime = 0;
gameState = "ready";
// Update UI
scoreText.setText("Score: " + score);
launchesText.setText("Launches: " + launches + "/" + maxLaunches);
instructionText.setText("Swipe to launch the chicken!");
// Reset chicken jockey
resetChickenJockey();
// Clear existing popcorn and ropes
clearPopcornsAndRopes();
// Create ropes around the arena
createRopes();
// Create popcorn scattered around the arena
createPopcorn(40);
// Create a few power-ups
for (var i = 0; i < 3; i++) {
createPowerUp();
}
// Play game start sound
LK.getSound('Gamestart').play();
// Play background music
LK.playMusic('gameMusic');
}
function resetChickenJockey() {
chickenJockey.reset();
// Position chicken in the center of the arena
chickenJockey.x = arena.x;
chickenJockey.y = arena.y;
}
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 ropes
for (var i = 0; i < ropes.length; i++) {
if (ropes[i].parent) {
ropes[i].parent.removeChild(ropes[i]);
}
}
ropes = [];
// Remove all power-ups
for (var i = 0; i < powerUps.length; i++) {
if (powerUps[i].parent) {
powerUps[i].parent.removeChild(powerUps[i]);
}
}
powerUps = [];
}
function createRopes() {
// Create top rope
var topRope = new Rope();
topRope.x = arena.x;
topRope.y = bounds.top + 100;
game.addChild(topRope);
ropes.push(topRope);
// Create right rope
var rightRope = new Rope();
rightRope.x = bounds.right - 100;
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 - 100;
game.addChild(bottomRope);
ropes.push(bottomRope);
// Create left rope
var leftRope = new Rope();
leftRope.x = bounds.left + 100;
leftRope.y = arena.y;
leftRope.rotation = Math.PI / 2; // Rotate 90 degrees
game.addChild(leftRope);
ropes.push(leftRope);
}
function createPopcorn(count) {
for (var i = 0; i < count; i++) {
var popcorn = new Popcorn();
// Random position within arena bounds
popcorn.x = bounds.left + 100 + Math.random() * (arena.width - 200);
popcorn.y = bounds.top + 100 + Math.random() * (arena.height - 200);
// Add to game
game.addChild(popcorn);
popcorns.push(popcorn);
}
}
function createPowerUp() {
var powerUp = new PowerUp();
// Random position within arena bounds
powerUp.x = bounds.left + 150 + Math.random() * (arena.width - 300);
powerUp.y = bounds.top + 150 + Math.random() * (arena.height - 300);
// Random power-up type
var types = ["multiplier", "extraLaunch", "superBounce"];
var randomType = types[Math.floor(Math.random() * types.length)];
powerUp.type = randomType;
// Configure based on type
if (randomType === "multiplier") {
powerUp.tint = 0x00FFFF; // Cyan
powerUp.value = 2 + Math.floor(Math.random() * 3); // 2x to 4x multiplier
} else if (randomType === "extraLaunch") {
powerUp.tint = 0xFF00FF; // Purple
powerUp.value = 1; // Extra launch
} else if (randomType === "superBounce") {
powerUp.tint = 0xFFFF00; // Yellow
powerUp.value = 2; // Double bounce points
}
// Add to game
game.addChild(powerUp);
powerUps.push(powerUp);
}
// Game events
game.onChickenJockeyStop = function () {
gameState = "ready";
// Add more popcorn when chicken jockey stops
if (popcorns.length < 20) {
createPopcorn(15);
}
// Occasionally add a power-up when chicken stops
if (Math.random() < 0.3 && powerUps.length < 5) {
createPowerUp();
}
// Check if out of launches
if (launches >= maxLaunches) {
// Game over
instructionText.setText("Game Over! Final Score: " + score);
gameState = "gameOver";
// Show game over after a short delay
LK.setTimeout(function () {
// Play game start sound again as game over sound
LK.getSound('Gamestart').play();
LK.showGameOver();
}, 2000);
} else {
// Reset for next launch
resetChickenJockey();
instructionText.setText("Drag to aim and launch the chicken!");
}
};
game.onMaxBouncesReached = function () {
// Same as onChickenJockeyStop for now
game.onChickenJockeyStop();
};
// Input handling
var dragStartX = 0;
var dragStartY = 0;
var dragEndX = 0;
var dragEndY = 0;
game.down = function (x, y, obj) {
if (gameState === "ready") {
gameState = "aiming";
dragStartX = x;
dragStartY = y;
pathTracer.startTracing(x, y);
instructionText.setText("Draw a path for the chicken!");
}
};
game.move = function (x, y, obj) {
if (gameState === "aiming") {
pathTracer.addPoint(x, y);
}
};
game.up = function (x, y, obj) {
if (gameState === "aiming") {
// Get the path from the path tracer
var path = pathTracer.stopTracing();
// Only launch if we have a valid path
if (path && path.length >= 2) {
// Record drag end position
dragEndX = x;
dragEndY = y;
// Calculate direction from the path
var firstPoint = path[0];
var lastPoint = path[path.length - 1];
var dx = lastPoint.x - firstPoint.x;
var dy = lastPoint.y - firstPoint.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate power based on path length (with a more controlled range)
var power = Math.min(distance, 200) * 0.2;
// Calculate angle based on path direction
var angle = Math.atan2(dy, dx) * 180 / Math.PI;
chickenJockey.launch(power, angle);
// Update game state
gameState = "launched";
launches++;
launchesText.setText("Launches: " + launches + "/" + maxLaunches);
instructionText.setText("Watch the chicken bounce!");
} else {
// Cancel the launch if the path was too short
gameState = "ready";
}
// Clear the path tracer regardless
pathTracer.clear();
}
};
// Add helper to update score
game.addScore = function (points) {
// Apply multiplier if active
var finalPoints = points;
if (Date.now() < multiplierEndTime) {
finalPoints = Math.floor(points * scoreMultiplier);
}
score += finalPoints;
scoreText.setText("Score: " + score);
LK.setScore(score);
// Visual feedback for big point gains
if (finalPoints >= 5000) {
var pointText = new Text2("+" + finalPoints, {
size: 50,
fill: 0xFFFF00
});
pointText.anchor.set(0.5, 0.5);
pointText.x = chickenJockey.x;
pointText.y = chickenJockey.y - 100;
game.addChild(pointText);
tween(pointText, {
y: pointText.y - 150,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
if (pointText.parent) {
pointText.parent.removeChild(pointText);
}
}
});
}
};
// Helper method to create popcorn at specific location
game.createPopcornAt = function (x, y, count) {
count = count || 1;
for (var i = 0; i < count; i++) {
var popcorn = new Popcorn();
// Position near the specified location with some random offset
var offsetX = (Math.random() - 0.5) * 200;
var offsetY = (Math.random() - 0.5) * 200;
popcorn.x = Math.max(bounds.left + 50, Math.min(bounds.right - 50, x + offsetX));
popcorn.y = Math.max(bounds.top + 50, Math.min(bounds.bottom - 50, y + offsetY));
// Add to game
game.addChild(popcorn);
popcorns.push(popcorn);
}
};
// Power-up activation function
game.activatePowerUp = function (type, value, duration) {
// Visual feedback for power-up activation
LK.effects.flashScreen(0x00FFFF, 500);
if (type === "multiplier") {
// Set score multiplier
scoreMultiplier = value;
// Display message
showMessage("Score x" + value + " for " + duration / 1000 + "s!", 0x00FFFF);
// Set timer to end effect
multiplierEndTime = Date.now() + duration;
} else if (type === "extraLaunch") {
// Add extra launches
maxLaunches += value;
launches = Math.max(0, launches - value); // Refund a launch
launchesText.setText("Launches: " + launches + "/" + maxLaunches);
// Display message
showMessage("+" + value + " Extra Launch!", 0xFF00FF);
} else if (type === "superBounce") {
// Temporarily increase bounce values
var oldBounceDecay = chickenJockey.bounceDecay;
chickenJockey.bounceDecay = Math.min(1.0, chickenJockey.bounceDecay * 1.3);
// Display message
showMessage("Super Bounce for " + duration / 1000 + "s!", 0xFFFF00);
// Set timer to end effect
LK.setTimeout(function () {
chickenJockey.bounceDecay = oldBounceDecay;
}, duration);
}
};
// Helper function to show temporary messages
function showMessage(text, color) {
var message = new Text2(text, {
size: 60,
fill: color || 0xFFFFFF
});
message.anchor.set(0.5, 0.5);
message.x = 2048 / 2;
message.y = 400;
LK.gui.center.addChild(message);
// Animate in
message.alpha = 0;
message.scaleX = 0.5;
message.scaleY = 0.5;
tween(message, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
// Animate out after delay
LK.setTimeout(function () {
tween(message, {
alpha: 0,
y: message.y - 100
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
if (message.parent) {
message.parent.removeChild(message);
}
}
});
}, 2000);
}
// Main game loop
game.update = function () {
// Check for keyboard input for username
if (highScoreTally.parent && highScoreTally.editingUsername) {
// Simulate keyboard input for demonstration
if (LK.ticks % 30 === 0 && Math.random() < 0.1) {
var currentName = storage['playerName'] || "PLAYER";
// Generate random character
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var randomChar = chars.charAt(Math.floor(Math.random() * chars.length));
if (currentName === "PLAYER") {
currentName = randomChar;
} else if (currentName.length < 10) {
currentName += randomChar;
}
highScoreTally.setUsername(currentName);
}
}
// 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; // Apply decay on horizontal bounce
chickenJockey.bounceCount++;
LK.getSound('bounce').play();
game.addScore(2000);
} else if (chickenJockey.x > bounds.right) {
chickenJockey.x = bounds.right;
chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay; // Apply decay on horizontal bounce
chickenJockey.bounceCount++;
LK.getSound('bounce').play();
game.addScore(2000);
}
if (chickenJockey.y < bounds.top) {
chickenJockey.y = bounds.top;
chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; // Apply decay on vertical bounce
chickenJockey.bounceCount++;
LK.getSound('bounce').play();
game.addScore(2000);
} else if (chickenJockey.y > bounds.bottom) {
chickenJockey.y = bounds.bottom;
chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; // Apply decay on vertical bounce
chickenJockey.bounceCount++;
LK.getSound('bounce').play();
game.addScore(2000);
}
// 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
game.addScore(10000);
scoreText.setText("Score: " + score);
// Save score to LK
LK.setScore(score);
// No longer reset launches when score reaches 1000
}
}
// Check for collisions with power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
if (chickenJockey.intersects(powerUps[i])) {
// Collect power-up
powerUps[i].collect();
// Remove from array
powerUps.splice(i, 1);
}
}
}
// Update popcorn animations
for (var i = 0; i < popcorns.length; i++) {
popcorns[i].update();
}
// Update power-up animations
for (var i = 0; i < powerUps.length; i++) {
powerUps[i].update();
}
// Randomly spawn new power-ups (rare)
if (gameState === "launched" && Math.random() < 0.001 && powerUps.length < 5) {
createPowerUp();
}
// Update path tracer
pathTracer.update();
// Update score multiplier UI if active
if (Date.now() < multiplierEndTime && scoreMultiplier > 1) {
// Update multiplier display in score text
var remainingSecs = Math.ceil((multiplierEndTime - Date.now()) / 1000);
scoreText.setText("Score: " + score + " (x" + scoreMultiplier + " for " + remainingSecs + "s)");
}
// Award extra launch for every million points
if (score >= 1000000 && score % 1000000 < 10000) {
// Only award once when crossing each million point threshold
if (!game.lastMillionMark || Math.floor(score / 1000000) > Math.floor(game.lastMillionMark / 1000000)) {
maxLaunches++;
showMessage("Extra Launch for 1,000,000 points!", 0xFFFF00);
launchesText.setText("Launches: " + launches + "/" + maxLaunches);
game.lastMillionMark = score;
// Create animated free launch text
var freeText = new Text2("FREE LAUNCH!", {
size: 100,
fill: 0xFFFF00
});
freeText.anchor.set(0.5, 0.5);
freeText.x = 2048 / 2;
freeText.y = 2732 / 2;
freeText.alpha = 0;
freeText.scaleX = 0.5;
freeText.scaleY = 0.5;
LK.gui.center.addChild(freeText);
// Animate in with bounce effect
tween(freeText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Pulse animation
tween(freeText, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Animate out with upward movement
tween(freeText, {
alpha: 0,
y: freeText.y - 200
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
if (freeText.parent) {
freeText.parent.removeChild(freeText);
}
}
});
}
});
}
});
}
}
};
// High score management functions
function getHighScores() {
return storage[highScoresKey] || [];
}
function saveHighScore(score) {
var highScores = getHighScores();
// Create score object with name and score
var playerName = storage['playerName'] || "PLAYER";
// Convert old format scores if needed
for (var i = 0; i < highScores.length; i++) {
if (typeof highScores[i] === 'number') {
// Create individual properties for storage compatibility
var tempScore = highScores[i];
// Clear the entry first
highScores[i] = null;
// Set each property individually
storage[highScoresKey + '_' + i + '_name'] = "PLAYER";
storage[highScoresKey + '_' + i + '_score'] = tempScore;
storage[highScoresKey + '_' + i + '_date'] = 0;
// Store the mapping in the array
highScores[i] = {
_ref: i
};
}
}
// Create new score entry using separate storage
var newScoreIndex = highScores.length;
storage[highScoresKey + '_' + newScoreIndex + '_name'] = playerName;
storage[highScoresKey + '_' + newScoreIndex + '_score'] = score;
storage[highScoresKey + '_' + newScoreIndex + '_date'] = Date.now();
// Add reference to the array - avoid nested objects
highScores.push(null);
highScores[highScores.length - 1] = {};
highScores[highScores.length - 1]._ref = newScoreIndex;
// Sort in descending order by score
highScores.sort(function (a, b) {
var scoreA = storage[highScoresKey + '_' + a._ref + '_score'] || 0;
var scoreB = storage[highScoresKey + '_' + b._ref + '_score'] || 0;
return scoreB - scoreA;
});
// Keep only top 10 scores
if (highScores.length > 10) {
highScores = highScores.slice(0, 10);
}
// Save to storage
storage[highScoresKey] = highScores;
}
// Create high score tally
var highScoreTally = new HighScoreTally();
highScoreTally.visible = true;
highScoreTally.onStart = function () {
game.removeChild(highScoreTally);
initGame();
};
// Show high scores at start
game.addChild(highScoreTally);
highScoreTally.updateScores(getHighScores());
// Modified game over handling
var originalOnChickenJockeyStop = game.onChickenJockeyStop;
game.onChickenJockeyStop = function () {
// Call original function first
originalOnChickenJockeyStop();
// If game over, save score
if (gameState === "gameOver") {
saveHighScore(score);
// We'll show high scores after game over in LK.showGameOver callback
}
};
// Handle game start
LK.onGameOver = function () {
// Show high score tally after game over
game.addChild(highScoreTally);
highScoreTally.updateScores(getHighScores());
};
// Initialize the game (commented out because we're showing high scores first)
// initGame();
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