User prompt
Fix
User prompt
Show path lines
User prompt
Trace a path for chicken jockey to follow βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make lines of popcorn coming from 1 corner at a time chicken jockey needs to collect all popcorn in one launch
User prompt
Add a SuperPopcorn class for special high-value popcorn β Add variables to track super popcorn in game state β Add create super popcorn function β Update game initialization to include super popcorn timer β Add super popcorn collision detection to ChickenJockey update method β Add super popcorn and multiple popcorns update in game update function π Update chicken jockey stop handler to create super popcorn sometimes
User prompt
Player returns to Centre of ring once popcorn has been collected
User prompt
Once popcorn is collected reset chicken to centre of the arena
User prompt
Increase amount of popcorn thrown by crowd
User prompt
Have popcorn throw in from the crowd outside the arena
User prompt
Prevent chicken getting stuck in the ropes
User prompt
Ensure player returns to centre of arena after every launch
User prompt
Remove all game over triggers
User prompt
Increase text size in instructions page
User prompt
Remove instruction text from title page
User prompt
Remove random movement code
User prompt
Fix this bug
User prompt
Please fix the bug: 'Uncaught ReferenceError: createRopes is not defined' in or related to this line: 'createRopes();' Line Number: 763
User prompt
Please fix the bug: 'PathTracer is not defined' in or related to this line: 'var pathTracer = game.addChild(new PathTracer());' Line Number: 651
User prompt
Remove all dead code that isn't used in game
User prompt
Move instruction text up 20
User prompt
Move instruction text down 100
User prompt
Reduce size of text to not conflict with score text
User prompt
Please fix the bug: 'Uncaught ReferenceError: instructionText is not defined' in or related to this line: 'instructionText.setText("Swipe or flick Chicken Jockey to launch!");' Line Number: 1203
User prompt
Check the title screen setup
User prompt
Remove all text that says drag to aim or draw a path
/**** 
* 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;
	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();
			}
		}
		// Track last intersecting state for popcorn collision
		if (typeof self.lastIntersectsPopcorn === 'undefined') {
			self.lastIntersectsPopcorn = false;
		}
		// Check for collision with popcorn
		if (popcorn !== null) {
			var currentIntersects = self.intersects(popcorn);
			if (currentIntersects) {
				// Collect popcorn
				popcorn.collect();
				// Set to null (will be recreated on stop)
				popcorn = null;
			}
			self.lastIntersectsPopcorn = currentIntersects;
		}
		// Track last intersecting state for x2 bonus collision
		if (typeof self.lastIntersectsX2Bonus === 'undefined') {
			self.lastIntersectsX2Bonus = false;
		}
		// Check for collision with x2 bonus
		if (x2Bonus !== null) {
			var currentIntersectsX2 = self.intersects(x2Bonus);
			if (currentIntersectsX2) {
				// Collect x2 bonus
				LK.getSound('collect').play();
				// Flash effect
				LK.effects.flashObject(x2Bonus, 0xFFFFFF, 300);
				// Animate collection
				tween(x2Bonus, {
					y: x2Bonus.y - 150,
					alpha: 0,
					scaleX: 2,
					scaleY: 2
				}, {
					duration: 600,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Remove from parent
						if (x2Bonus !== null && x2Bonus.parent) {
							x2Bonus.parent.removeChild(x2Bonus);
						}
					}
				});
				// Double the score
				game.addScore(score);
				// Show message
				showMessage("Score Doubled!", 0xFFD700);
				// Set to null
				x2Bonus = null;
			}
			self.lastIntersectsX2Bonus = currentIntersectsX2;
		}
		// Track last intersecting state for x5 bonus collision
		if (typeof self.lastIntersectsX5Bonus === 'undefined') {
			self.lastIntersectsX5Bonus = false;
		}
		// Check for collision with x5 bonus
		if (x5Bonus !== null) {
			var currentIntersectsX5 = self.intersects(x5Bonus);
			if (currentIntersectsX5) {
				// Collect x5 bonus
				LK.getSound('collect').play();
				// Flash effect
				LK.effects.flashObject(x5Bonus, 0xFFFFFF, 300);
				// Animate collection
				tween(x5Bonus, {
					y: x5Bonus.y - 150,
					alpha: 0,
					scaleX: 2,
					scaleY: 2
				}, {
					duration: 600,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Remove from parent
						if (x5Bonus !== null && x5Bonus.parent) {
							x5Bonus.parent.removeChild(x5Bonus);
						}
					}
				});
				// Multiply score by 5
				game.addScore(score * 4); // Add 4x more score (1x original + 4x new = 5x total)
				// Show message
				showMessage("Score Multiplied x5!", 0xFF4500);
				// Set to null and clear timer
				x5Bonus = null;
				if (x5BonusTimer !== null) {
					LK.clearTimeout(x5BonusTimer);
					x5BonusTimer = null;
				}
			}
			self.lastIntersectsX5Bonus = currentIntersectsX5;
		}
		// Track previous positions before bounce
		var prevX = self.x;
		var prevY = self.y;
		// Track previous positions for more accurate collision detection
		var prevX = self.x;
		var prevY = self.y;
		// Improved boundary bounce handling with minimum velocity thresholds
		// Horizontal boundaries with more dramatic bounce effect
		if (self.x <= bounds.left) {
			self.x = bounds.left;
			if (self.vx < 0 && Math.abs(self.vx) > 1) {
				// Enhance bounce effect with slightly more force
				self.vx = -self.vx * (self.bounceDecay + 0.1);
				self.bounceCount++;
				LK.getSound('bounce').play();
				// Add slight vertical boost for more interesting motion
				self.vy -= 2 * Math.random();
			}
		} else if (self.x >= bounds.right) {
			self.x = bounds.right;
			if (self.vx > 0 && Math.abs(self.vx) > 1) {
				// Enhance bounce effect with slightly more force
				self.vx = -self.vx * (self.bounceDecay + 0.1);
				self.bounceCount++;
				LK.getSound('bounce').play();
				game.addScore(2000);
				// Add slight vertical boost for more interesting motion
				self.vy -= 2 * Math.random();
			}
		}
		// Vertical boundary bounce handling with more dramatic effect
		if (self.y <= bounds.top) {
			self.y = bounds.top;
			if (self.vy < 0 && Math.abs(self.vy) > 1) {
				// Enhance bounce effect with slightly more force
				self.vy = -self.vy * (self.bounceDecay + 0.1);
				self.bounceCount++;
				LK.getSound('bounce').play();
				// Add slight horizontal boost for more interesting motion
				self.vx += (Math.random() - 0.5) * 4;
			}
		} else if (self.y >= bounds.bottom) {
			self.y = bounds.bottom;
			if (self.vy > 0 && Math.abs(self.vy) > 1) {
				// Enhance bounce effect with slightly more force
				self.vy = -self.vy * (self.bounceDecay + 0.1);
				self.bounceCount++;
				LK.getSound('bounce').play();
				// Add slight horizontal boost for more interesting motion
				self.vx += (Math.random() - 0.5) * 4;
			}
		}
		// 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('Hiscorebackdrop', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	background.width = 1400;
	background.height = 1200;
	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);
	// 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 + 250;
		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);
			// Score
			var scoreText = new Text2(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();
		}
	};
	// Reset high scores button
	var resetButton = new Container();
	var resetBg = resetButton.attachAsset('rope', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	resetBg.width = 600;
	resetBg.height = 150;
	resetBg.tint = 0xAA0000;
	var resetText = new Text2("RESET SCORES", {
		size: 70,
		fill: 0xFFFFFF
	});
	resetText.anchor.set(0.5, 0.5);
	resetButton.addChild(resetText);
	resetButton.y = background.height / 2 - 400;
	self.addChild(resetButton);
	resetButton.interactive = true;
	resetButton.down = function () {
		resetBg.tint = 0x770000;
	};
	resetButton.up = function () {
		resetBg.tint = 0xAA0000;
		if (typeof self.onResetScores === 'function') {
			self.onResetScores();
		}
	};
	// Make container position in center of screen
	self.x = 2048 / 2;
	self.y = 2732 / 2;
	return self;
});
var InstructionsScreen = Container.expand(function () {
	var self = Container.call(this);
	// Create black background
	var background = self.attachAsset('Hiscorebackdrop', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	background.width = 1400;
	background.height = 1500;
	background.alpha = 0.8;
	// Title
	var titleText = new Text2("HOW TO PLAY", {
		size: 80,
		fill: 0xFFD700
	});
	titleText.anchor.set(0.5, 0);
	titleText.y = -background.height / 2 + 100;
	self.addChild(titleText);
	// Instructions - split into smaller lines for better fitting
	var instructions = ["1: Swipe or flick any direction to launch Chicken Jockey.", "2: Aim Chicken Jockey at the popcorn pieces to eat popcorn.", "3: If you miss the popcorn, it will be GAME OVER.", "4: Scoring system starts at 1 point per popcorn, but", "   a multiplier increases the score per popcorn every 10 launches.", "5: Look out for X2 and X5 bonuses to maximise your total score,", "   but be careful...", "   if you miss the popcorn it will be game over so be patient", "   and wait till the popcorn is in the right place before", "   launching towards these bonuses.", "6: Good luck!"];
	var instructionContainer = new Container();
	var startY = -background.height / 2 + 250;
	var padding = 50; // Reduced padding to fit more lines
	for (var i = 0; i < instructions.length; i++) {
		var instructionText = new Text2(instructions[i], {
			size: 50,
			fill: 0xFFFFFF
		});
		instructionText.anchor.set(0, 0.5);
		instructionText.y = startY + i * padding;
		instructionContainer.addChild(instructionText);
	}
	instructionContainer.x = -700; // Move instructions text left 700 pixels
	self.addChild(instructionContainer);
	// Back button
	var backButton = new Container();
	var buttonBg = backButton.attachAsset('rope', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBg.width = 600;
	buttonBg.height = 150;
	buttonBg.tint = 0x0000AA;
	var buttonText = new Text2("BACK", {
		size: 70,
		fill: 0xFFFFFF
	});
	buttonText.anchor.set(0.5, 0.5);
	backButton.addChild(buttonText);
	backButton.y = background.height / 2 - 200;
	self.addChild(backButton);
	// Make button interactive
	backButton.interactive = true;
	backButton.down = function () {
		buttonBg.tint = 0x000077;
	};
	backButton.up = function () {
		buttonBg.tint = 0x0000AA;
		if (typeof self.onBack === 'function') {
			self.onBack();
		}
	};
	// 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 with smaller size
	var popcornGraphics = self.attachAsset('popcorn', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 1.5
	});
	// Popcorn properties
	self.collected = false;
	self.baseY = 0;
	self.animationOffset = Math.random() * Math.PI * 2;
	self.animationSpeed = 0.05 + Math.random() * 0.03;
	self.collect = function () {
		// Play collect sound
		LK.getSound('collect').play();
		// Flash effect
		LK.effects.flashObject(self, 0xFFFFFF, 300);
		// Animate collection
		tween(self, {
			y: self.y - 150,
			alpha: 0,
			scaleX: 4.5,
			scaleY: 4.5
		}, {
			duration: 600,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Remove from parent
				if (self.parent) {
					self.parent.removeChild(self);
				}
			}
		});
		// Add points
		if (typeof game.addScore === 'function') {
			game.addScore(1);
		}
		self.collected = true;
	};
	self.update = function () {
		// Hover animation
		if (self.baseY === 0) {
			self.baseY = self.y;
			// Start movement tween when popcorn is created
			self.startMovementTween();
		}
		// Vertical hover
		self.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 8;
	};
	// Method to start the popcorn moving around the arena
	self.startMovementTween = function () {
		// Calculate a random position within the arena bounds
		var randomX = bounds.left + 150 + Math.random() * (arena.width - 300);
		var randomY = bounds.top + 150 + Math.random() * (arena.height - 300);
		// Move to the new position over a few seconds
		tween(self, {
			x: randomX
			// Update baseY to keep hover effect consistent
		}, {
			duration: popcornMoveSpeed + Math.random() * 1000,
			// Use global popcorn speed variable plus some randomness
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				// When movement completes, start a new movement
				if (self.parent) {
					self.startMovementTween();
				}
			}
		});
	};
	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.8; // Increased tension for more springy, elastic bounces
	self.bounce = function (chickenJockey) {
		// Store original position for rope displacement effect
		var originalX = self.x;
		var originalY = self.y;
		// Calculate normal angle (perpendicular to rope)
		var normalAngle = Math.atan2(chickenJockey.y - self.y, chickenJockey.x - self.x);
		// Account for rope rotation when calculating normal
		normalAngle += self.rotation + Math.PI / 2;
		// Calculate velocity components
		var speed = Math.sqrt(chickenJockey.vx * chickenJockey.vx + chickenJockey.vy * chickenJockey.vy);
		var incomingAngle = Math.atan2(chickenJockey.vy, chickenJockey.vx);
		// Calculate angle of reflection
		var bounceAngle = 2 * normalAngle - incomingAngle;
		// Calculate new velocity with enhanced force based on incoming speed
		// Higher incoming speed = stronger bounce back effect
		var bounceForce = speed * self.tension * (1 + Math.min(0.5, speed / 40));
		// Reduce random angle variation for more predictable wrestling-style bounces
		var angleVariation = (Math.random() - 0.5) * 0.1; // Smaller random angle adjustment
		bounceAngle += angleVariation;
		// Better two-phase bounce: complete stop, then dramatic spring-off
		// First phase: completely stop the chicken to simulate "sticking" to rope
		chickenJockey.vx = 0;
		chickenJockey.vy = 0;
		// Add a slightly longer delay for more dramatic pause before the spring-off
		LK.setTimeout(function () {
			// Second phase: apply a much stronger bounce force with enhanced velocity
			var enhancedForce = bounceForce * 1.5; // Significantly increase spring force
			chickenJockey.vx = Math.cos(bounceAngle) * enhancedForce * chickenJockey.bounceDecay;
			chickenJockey.vy = Math.sin(bounceAngle) * enhancedForce * chickenJockey.bounceDecay;
			// Add a more dramatic burst of rotation to simulate impact force
			chickenJockey.rotationSpeed = (Math.random() - 0.5) * 0.25;
			// Play a sound to enhance the spring effect
			LK.getSound('bounce').play();
		}, 200); // Slightly longer delay for more dramatic effect
		// Create much more dramatic bounce visual effect with exaggerated rope "give"
		tween(self, {
			scaleY: 2.2,
			// More extreme stretch
			alpha: 0.7,
			// Add more significant displacement in direction of impact
			x: originalX + Math.cos(incomingAngle) * 20,
			y: originalY + Math.sin(incomingAngle) * 20
		}, {
			duration: 300,
			// Longer stretch duration for more dramatic effect
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Snap the rope back with way more dramatic effect
				tween(self, {
					scaleY: 1.0,
					alpha: 1.0,
					x: originalX,
					y: originalY
				}, {
					duration: 800,
					//{3l} // Much longer snap-back for even more visual impact
					easing: tween.elasticOut,
					amplitude: 2.0 // Higher amplitude for more dramatic snap back
				});
			}
		});
		// Increment bounce count
		chickenJockey.bounceCount++;
		// Create a more dramatic visual and audio experience
		// Play bounce sound with slightly randomized pitch for variety
		var bounceSound = LK.getSound('bounce');
		bounceSound.play();
		// More dramatic flash effect on the rope
		LK.effects.flashObject(self, 0xFFFFFF, 300);
		// Create a "pow" text effect at collision point
		var powText = new Text2("nomnomnom", {
			size: 120,
			fill: 0xFFFF00
		});
		powText.anchor.set(0.5, 0.5);
		powText.x = chickenJockey.x;
		powText.y = chickenJockey.y - 80;
		game.addChild(powText);
		// Animate the text
		tween(powText, {
			y: powText.y - 100,
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 600,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				if (powText.parent) {
					powText.parent.removeChild(powText);
				}
			}
		});
	};
	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 TitleScreen = Container.expand(function () {
	var self = Container.call(this);
	// Create and attach title screen background
	var titleGraphics = self.attachAsset('Titlescreen', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// 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("START GAME", {
		size: 70,
		fill: 0xFFFFFF
	});
	buttonText.anchor.set(0.5, 0.5);
	startButton.addChild(buttonText);
	startButton.y = 200;
	self.addChild(startButton);
	// Make button interactive
	startButton.interactive = true;
	startButton.down = function () {
		buttonBg.tint = 0x007700;
	};
	startButton.up = function () {
		buttonBg.tint = 0x00AA00;
		// Call start game function if defined
		if (typeof self.onStart === 'function') {
			self.onStart();
		}
	};
	// High scores button
	var scoresButton = new Container();
	var scoresBg = scoresButton.attachAsset('rope', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	scoresBg.width = 600;
	scoresBg.height = 150;
	scoresBg.tint = 0x0000AA;
	var scoresText = new Text2("HIGH SCORES", {
		size: 70,
		fill: 0xFFFFFF
	});
	scoresText.anchor.set(0.5, 0.5);
	scoresButton.addChild(scoresText);
	scoresButton.y = 400;
	self.addChild(scoresButton);
	// Make button interactive
	scoresButton.interactive = true;
	scoresButton.down = function () {
		scoresBg.tint = 0x000077;
	};
	scoresButton.up = function () {
		scoresBg.tint = 0x0000AA;
		// Call show high scores function if defined
		if (typeof self.onHighScores === 'function') {
			self.onHighScores();
		}
	};
	// Instructions button
	var instructionsButton = new Container();
	var instructionsBg = instructionsButton.attachAsset('rope', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	instructionsBg.width = 600;
	instructionsBg.height = 150;
	instructionsBg.tint = 0xAA7700;
	var instructionsText = new Text2("INSTRUCTIONS", {
		size: 70,
		fill: 0xFFFFFF
	});
	instructionsText.anchor.set(0.5, 0.5);
	instructionsButton.addChild(instructionsText);
	instructionsButton.y = 600;
	self.addChild(instructionsButton);
	// Make button interactive
	instructionsButton.interactive = true;
	instructionsButton.down = function () {
		instructionsBg.tint = 0x774400;
	};
	instructionsButton.up = function () {
		instructionsBg.tint = 0xAA7700;
		// Call show instructions function if defined
		if (typeof self.onInstructions === 'function') {
			self.onInstructions();
		}
	};
	// Position in center of screen
	self.x = 2048 / 2;
	self.y = 2732 / 2;
	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 ropes = [];
var powerUps = [];
var popcorn = null; // Track the active popcorn
var x2Bonus = null; // Track the active x2 bonus
var x5Bonus = null; // Track the active x5 bonus
var x5BonusTimer = null; // Timer for x5 bonus removal
var scoreMultiplier = 1;
var multiplierEndTime = 0;
var launchMultiplier = 1; // Track multiplier from launches
var popcornMoveSpeed = 5000; // Base popcorn movement duration in ms
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 = 140; // Moved down 120 pixels from original position of 20
LK.gui.topLeft.addChild(launchesText);
var instructionText = new Text2("", {
	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;
	popcornMoveSpeed = 5000; // Reset popcorn movement speed
	gameState = "ready";
	// Clear x2 bonus if exists
	if (x2Bonus !== null) {
		if (x2Bonus.parent) {
			x2Bonus.parent.removeChild(x2Bonus);
		}
		x2Bonus = null;
	}
	// Clear x5 bonus if exists
	if (x5Bonus !== null) {
		if (x5Bonus.parent) {
			x5Bonus.parent.removeChild(x5Bonus);
		}
		x5Bonus = null;
	}
	// Clear any existing x5 bonus timer
	if (x5BonusTimer !== null) {
		LK.clearTimeout(x5BonusTimer);
		x5BonusTimer = null;
	}
	// Update UI
	scoreText.setText("Score: " + score);
	launchesText.setText("Launches: " + launches);
	instructionText.setText("Swipe or flick Chicken Jockey to launch!");
	// Reset chicken jockey
	resetChickenJockey();
	// Clear existing popcorn and ropes
	clearPopcornsAndRopes();
	// Create ropes around the arena
	createRopes();
	// Create a few power-ups
	for (var i = 0; i < 3; i++) {
		createPowerUp();
	}
	// Create the initial popcorn
	createPopcorn();
	// Play game start sound
	LK.getSound('Gamestart').play();
	// Play background music after a short delay to ensure it starts after the game start sound
	LK.setTimeout(function () {
		LK.playMusic('gameMusic', {
			loop: true
		});
	}, 1000); // Delay of 1000ms (1 second)
}
function resetChickenJockey() {
	chickenJockey.reset();
	// Position chicken in the center of the arena
	chickenJockey.x = arena.x;
	chickenJockey.y = arena.y;
}
function clearPopcornsAndRopes() {
	// 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);
	// Center horizontal rope removed
}
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);
}
function createPopcorn() {
	// Only create if no popcorn exists
	if (popcorn === null) {
		var newPopcorn = new Popcorn();
		// Random position within arena bounds
		newPopcorn.x = bounds.left + 150 + Math.random() * (arena.width - 300);
		newPopcorn.y = bounds.top + 150 + Math.random() * (arena.height - 300);
		// Add to game
		game.addChild(newPopcorn);
		popcorn = newPopcorn;
	}
}
function createX2Bonus() {
	// Only create if no x2 bonus exists
	if (x2Bonus === null) {
		var newX2Bonus = LK.getAsset('X2', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Random position within arena bounds
		newX2Bonus.x = bounds.left + 150 + Math.random() * (arena.width - 300);
		newX2Bonus.y = bounds.top + 150 + Math.random() * (arena.height - 300);
		// Add to game
		game.addChild(newX2Bonus);
		x2Bonus = newX2Bonus;
		// Add hover animation
		var baseY = newX2Bonus.y;
		var animationOffset = Math.random() * Math.PI * 2;
		var animationSpeed = 0.05 + Math.random() * 0.03;
		newX2Bonus.update = function () {
			// Vertical hover animation
			newX2Bonus.y = baseY + Math.sin(LK.ticks * animationSpeed + animationOffset) * 8;
		};
	}
}
function createX5Bonus() {
	// Only create if no x5 bonus exists
	if (x5Bonus === null) {
		var newX5Bonus = LK.getAsset('X5', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Random position within arena bounds
		newX5Bonus.x = bounds.left + 150 + Math.random() * (arena.width - 300);
		newX5Bonus.y = bounds.top + 150 + Math.random() * (arena.height - 300);
		// Add to game
		game.addChild(newX5Bonus);
		x5Bonus = newX5Bonus;
		// Add hover animation
		var baseY = newX5Bonus.y;
		var animationOffset = Math.random() * Math.PI * 2;
		var animationSpeed = 0.05 + Math.random() * 0.03;
		newX5Bonus.update = function () {
			// Vertical hover animation
			newX5Bonus.y = baseY + Math.sin(LK.ticks * animationSpeed + animationOffset) * 8;
		};
		// Set timer to remove X5 bonus after 5 seconds
		if (x5BonusTimer !== null) {
			LK.clearTimeout(x5BonusTimer);
		}
		x5BonusTimer = LK.setTimeout(function () {
			if (x5Bonus !== null) {
				// Animate disappearing
				tween(x5Bonus, {
					alpha: 0,
					scaleX: 0.5,
					scaleY: 0.5
				}, {
					duration: 500,
					easing: tween.easeIn,
					onFinish: function onFinish() {
						if (x5Bonus && x5Bonus.parent) {
							x5Bonus.parent.removeChild(x5Bonus);
						}
						x5Bonus = null;
					}
				});
			}
		}, 5000); // 5 seconds
	}
}
// Game events
game.onChickenJockeyStop = function () {
	// If popcorn exists when the chicken stops, it's game over
	if (popcorn !== null) {
		gameState = "gameOver";
		instructionText.setText("Game Over! You missed the popcorn!");
		// Show game over screen
		LK.showGameOver();
		return;
	} else {
		gameState = "ready";
		// Occasionally add a power-up when chicken stops
		if (Math.random() < 0.3 && powerUps.length < 5) {
			createPowerUp();
		}
		// Check if chicken is close to the center of the arena
		var centerX = arena.x;
		var centerY = arena.y;
		var distanceToCenter = Math.sqrt(Math.pow(chickenJockey.x - centerX, 2) + Math.pow(chickenJockey.y - centerY, 2));
		var centerThreshold = 200; // Threshold distance to consider "at center"
		if (distanceToCenter <= centerThreshold) {
			// Create a new popcorn only when player is near the center
			createPopcorn();
			instructionText.setText("New popcorn appeared! Drag to aim and launch the chicken!");
		} else {
			instructionText.setText("What's the highest score you can get?");
		}
		// Instead of checking if out of launches, increase max launches
		maxLaunches++; // Increase max launches with each launch
		// Reset for next launch
		resetChickenJockey();
	}
};
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++;
			// Create x2 bonus every 13 launches
			if (launches % 13 === 0 && x2Bonus === null) {
				createX2Bonus();
			}
			// Create x5 bonus every 26 launches
			if (launches % 26 === 0 && x5Bonus === null) {
				createX5Bonus();
			}
			// Update launch multiplier (1x for first 10, 2x for 11-20, etc.)
			var newMultiplier = Math.floor(launches / 10) + 1;
			// If multiplier changed, speed up popcorn movement
			if (newMultiplier > launchMultiplier) {
				popcornMoveSpeed = Math.max(2000, popcornMoveSpeed - 500); // Speed up by 500ms each level, minimum 2000ms
				// Play Bogerk sound every 10 launches
				LK.getSound('Bogerk').play();
			}
			launchMultiplier = newMultiplier;
			launchesText.setText("Launches: " + launches);
			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);
	}
	// Apply launch multiplier
	finalPoints = Math.floor(finalPoints * launchMultiplier);
	score += finalPoints;
	scoreText.setText("Score: " + score);
	LK.setScore(score);
};
// 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);
		// 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 () {
	// Update all game objects
	if (gameState === "launched") {
		chickenJockey.update();
		// Check for collisions with arena boundaries - only detect boundaries
		// Horizontal boundaries are handled in ChickenJockey class
		if (chickenJockey.x < bounds.left) {
			chickenJockey.x = bounds.left;
		} else if (chickenJockey.x > bounds.right) {
			chickenJockey.x = bounds.right;
		}
		// Check vertical boundaries - only detect boundaries
		// Vertical boundaries are handled in ChickenJockey class
		if (chickenJockey.y < bounds.top) {
			chickenJockey.y = bounds.top;
		} else if (chickenJockey.y > bounds.bottom) {
			chickenJockey.y = bounds.bottom;
		}
		// Update x2 bonus if it exists
		if (x2Bonus !== null && typeof x2Bonus.update === 'function') {
			x2Bonus.update();
		}
		// Update x5 bonus if it exists
		if (x5Bonus !== null && typeof x5Bonus.update === 'function') {
			x5Bonus.update();
		}
		// Track last collision time for all ropes to prevent multiple bounces
		if (!chickenJockey.lastCollisionTime) {
			chickenJockey.lastCollisionTime = 0;
		}
		// Improved collision detection for ropes with proper cooldown
		var currentTime = Date.now();
		var collisionCooldown = 1000; // 1 second cooldown between any rope bounces
		var canBounce = currentTime - chickenJockey.lastCollisionTime > collisionCooldown;
		// Only check for rope collisions if cooldown period has passed
		if (canBounce && chickenJockey.launched && Math.abs(chickenJockey.vx) + Math.abs(chickenJockey.vy) > 1) {
			for (var i = 0; i < ropes.length; i++) {
				if (chickenJockey.intersects(ropes[i])) {
					// Perform the bounce
					ropes[i].bounce(chickenJockey);
					// Record collision time
					chickenJockey.lastCollisionTime = currentTime;
					// Flash screen slightly to emphasize impact
					LK.effects.flashScreen(0xFFFFFF, 100, 0.3);
					// Only bounce on one rope per cooldown period
					break;
				}
			}
		}
		// 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 baseY when its position changes from tween
		if (popcorn !== null && popcorn.baseY !== 0 && Math.abs(popcorn.baseY - popcorn.y) > 10) {
			popcorn.baseY = popcorn.y;
		}
		// Create a new popcorn after a delay if popcorn is null
		if (popcorn === null && gameState === "launched") {
			LK.setTimeout(function () {
				createPopcorn();
			}, 1000); // 1 second delay before creating new popcorn
		}
	}
	// Update power-up animations
	for (var i = 0; i < powerUps.length; i++) {
		powerUps[i].update();
	}
	// Update popcorn animation
	if (popcorn !== null) {
		popcorn.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 or if launch multiplier is greater than 1
	if (Date.now() < multiplierEndTime && scoreMultiplier > 1 || launchMultiplier > 1) {
		var multiplierString = "x" + launchMultiplier;
		if (Date.now() < multiplierEndTime && scoreMultiplier > 1) {
			var remainingSecs = Math.ceil((multiplierEndTime - Date.now()) / 1000);
			multiplierString += " (x" + scoreMultiplier + " for " + remainingSecs + "s)";
		}
		scoreText.setText("Score: " + score + " (" + multiplierString + ")");
	} else {
		scoreText.setText("Score: " + score);
	}
	// 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);
			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();
	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);
	}
	// Save to storage
	storage[highScoresKey] = highScores;
}
// Create high score tally
var highScoreTally = new HighScoreTally();
highScoreTally.visible = true;
highScoreTally.onStart = function () {
	game.removeChild(highScoreTally);
	initGame();
};
// Add reset scores functionality
highScoreTally.onResetScores = function () {
	// Clear high scores from storage
	storage[highScoresKey] = [];
	// Update display with empty scores
	highScoreTally.updateScores([]);
	// Show confirmation message
	var confirmText = new Text2("High scores reset!", {
		size: 60,
		fill: 0xFF0000
	});
	confirmText.anchor.set(0.5, 0.5);
	confirmText.x = 2048 / 2;
	confirmText.y = 2732 / 2 + 200;
	LK.gui.center.addChild(confirmText);
	// Animate and remove after delay
	tween(confirmText, {
		alpha: 1,
		scaleX: 1.2,
		scaleY: 1.2
	}, {
		duration: 300,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			LK.setTimeout(function () {
				tween(confirmText, {
					alpha: 0,
					y: confirmText.y - 100
				}, {
					duration: 500,
					easing: tween.easeIn,
					onFinish: function onFinish() {
						if (confirmText.parent) {
							confirmText.parent.removeChild(confirmText);
						}
					}
				});
			}, 1500);
		}
	});
};
// Create and show title screen at start
var titleScreen = new TitleScreen();
game.addChild(titleScreen);
// Set up title screen event handlers
titleScreen.onStart = function () {
	// Hide title screen and start game
	game.removeChild(titleScreen);
	initGame();
	// Play start sound
	LK.getSound('Gamestart').play();
};
titleScreen.onHighScores = function () {
	// Hide title screen and show high scores
	game.removeChild(titleScreen);
	game.addChild(highScoreTally);
	highScoreTally.updateScores(getHighScores());
};
// Create instructions screen
var instructionsScreen = new InstructionsScreen();
instructionsScreen.onBack = function () {
	game.removeChild(instructionsScreen);
	game.addChild(titleScreen);
};
// Add instructions button handler
titleScreen.onInstructions = function () {
	// Hide title screen and show instructions
	game.removeChild(titleScreen);
	game.addChild(instructionsScreen);
};
// Add a way to return to title screen from high scores
var originalOnStart = highScoreTally.onStart;
highScoreTally.onStart = function () {
	game.removeChild(highScoreTally);
	game.addChild(titleScreen);
};
// 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 over
LK.onGameOver = function () {
	// Save high score
	saveHighScore(score);
	// Show high score tally after game over
	game.addChild(highScoreTally);
	highScoreTally.updateScores(getHighScores());
	// Back button to return to title screen
	highScoreTally.onStart = function () {
		game.removeChild(highScoreTally);
		game.addChild(titleScreen);
	};
}; ===================================================================
--- original.js
+++ change.js
@@ -178,9 +178,10 @@
 				// Enhance bounce effect with slightly more force
 				self.vx = -self.vx * (self.bounceDecay + 0.1);
 				self.bounceCount++;
 				LK.getSound('bounce').play();
-				// Removed random vertical boost
+				// Add slight vertical boost for more interesting motion
+				self.vy -= 2 * Math.random();
 			}
 		} else if (self.x >= bounds.right) {
 			self.x = bounds.right;
 			if (self.vx > 0 && Math.abs(self.vx) > 1) {
@@ -188,9 +189,10 @@
 				self.vx = -self.vx * (self.bounceDecay + 0.1);
 				self.bounceCount++;
 				LK.getSound('bounce').play();
 				game.addScore(2000);
-				// Removed random vertical boost
+				// Add slight vertical boost for more interesting motion
+				self.vy -= 2 * Math.random();
 			}
 		}
 		// Vertical boundary bounce handling with more dramatic effect
 		if (self.y <= bounds.top) {
@@ -199,18 +201,20 @@
 				// Enhance bounce effect with slightly more force
 				self.vy = -self.vy * (self.bounceDecay + 0.1);
 				self.bounceCount++;
 				LK.getSound('bounce').play();
-				// Removed random horizontal boost
+				// Add slight horizontal boost for more interesting motion
+				self.vx += (Math.random() - 0.5) * 4;
 			}
 		} else if (self.y >= bounds.bottom) {
 			self.y = bounds.bottom;
 			if (self.vy > 0 && Math.abs(self.vy) > 1) {
 				// Enhance bounce effect with slightly more force
 				self.vy = -self.vy * (self.bounceDecay + 0.1);
 				self.bounceCount++;
 				LK.getSound('bounce').play();
-				// Removed random horizontal boost
+				// Add slight horizontal boost for more interesting motion
+				self.vx += (Math.random() - 0.5) * 4;
 			}
 		}
 		// Check if max bounces reached
 		if (self.bounceCount >= self.maxBounces) {
@@ -548,10 +552,9 @@
 		var randomX = bounds.left + 150 + Math.random() * (arena.width - 300);
 		var randomY = bounds.top + 150 + Math.random() * (arena.height - 300);
 		// Move to the new position over a few seconds
 		tween(self, {
-			x: randomX,
-			y: randomY // Add random Y movement
+			x: randomX
 			// Update baseY to keep hover effect consistent
 		}, {
 			duration: popcornMoveSpeed + Math.random() * 1000,
 			// Use global popcorn speed variable plus some randomness
@@ -860,16 +863,9 @@
 
 /**** 
 * Game Code
 ****/ 
-// Game state 
-var instructionText = new Text2("", {
-	size: 50,
-	fill: 0xFFFFFF
-});
-instructionText.anchor.set(0.5, 0);
-instructionText.y = 80;
-LK.gui.top.addChild(instructionText);
+// Game state
 var gameState = "ready"; // ready, aiming, launched, gameOver
 var score = 0;
 var launches = 0;
 var maxLaunches = 5;
@@ -881,9 +877,9 @@
 var x5BonusTimer = null; // Timer for x5 bonus removal
 var scoreMultiplier = 1;
 var multiplierEndTime = 0;
 var launchMultiplier = 1; // Track multiplier from launches
-var popcornMoveSpeed = 2500; // Base popcorn movement duration in ms (decreased for faster movement)
+var popcornMoveSpeed = 5000; // Base popcorn movement duration in ms
 var highScoresKey = 'chickenJockeyHighScores';
 var pathTracer = game.addChild(new PathTracer());
 // Add backdrop first
 var backdrop = game.addChild(LK.getAsset('Backdrop', {
@@ -922,17 +918,24 @@
 launchesText.anchor.set(0, 0);
 launchesText.x = 120; // Avoid top-left corner
 launchesText.y = 140; // Moved down 120 pixels from original position of 20
 LK.gui.topLeft.addChild(launchesText);
+var instructionText = new Text2("", {
+	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;
-	popcornMoveSpeed = 3000; // Increase base popcorn movement speed for faster movement 
+	popcornMoveSpeed = 5000; // Reset popcorn movement speed
 	gameState = "ready";
 	// Clear x2 bonus if exists
 	if (x2Bonus !== null) {
 		if (x2Bonus.parent) {
@@ -1155,9 +1158,9 @@
 		var centerThreshold = 200; // Threshold distance to consider "at center"
 		if (distanceToCenter <= centerThreshold) {
 			// Create a new popcorn only when player is near the center
 			createPopcorn();
-			instructionText.setText("What's the highest score you can get?");
+			instructionText.setText("New popcorn appeared! Drag to aim and launch the chicken!");
 		} else {
 			instructionText.setText("What's the highest score you can get?");
 		}
 		// Instead of checking if out of launches, increase max launches
@@ -1180,9 +1183,9 @@
 		gameState = "aiming";
 		dragStartX = x;
 		dragStartY = y;
 		pathTracer.startTracing(x, y);
-		instructionText.setText("Swipe or flick Chicken Jockey to launch!");
+		instructionText.setText("Draw a path for the chicken!");
 	}
 };
 game.move = function (x, y, obj) {
 	if (gameState === "aiming") {
@@ -1382,10 +1385,14 @@
 		// Update popcorn baseY when its position changes from tween
 		if (popcorn !== null && popcorn.baseY !== 0 && Math.abs(popcorn.baseY - popcorn.y) > 10) {
 			popcorn.baseY = popcorn.y;
 		}
-		// We don't need this as createPopcorn is already called in onChickenJockeyStop
-		// This was causing duplicate popcorn creation due to race conditions
+		// Create a new popcorn after a delay if popcorn is null
+		if (popcorn === null && gameState === "launched") {
+			LK.setTimeout(function () {
+				createPopcorn();
+			}, 1000); // 1 second delay before creating new popcorn
+		}
 	}
 	// Update power-up animations
 	for (var i = 0; i < powerUps.length; i++) {
 		powerUps[i].update();
:quality(85)/https://cdn.frvr.ai/680e2cb731e90df6e3a79663.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/680f25b74b91ed99c0c93065.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/68107d72af890f4678fa3c0c.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6811f7e547f9689b747b894b.png%3F3) 
 X5 symbol. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6811f84547f9689b747b8951.png%3F3) 
 X2 symbol. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6812d11c31e90df6e3a797a7.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6812d23e21b2d4faceef26d6.png%3F3) 
 Super popcorn yellow. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814a4059dcd06d468edb7f4.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6814a730211045a0f483816f.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6814a81e211045a0f4838182.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6814a94a211045a0f483818b.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6814aa19211045a0f4838190.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6814aae1211045a0f4838194.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6814dcf6bef1291d4e518ee7.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6814e89f0e23fbc7292fa249.png%3F3) 
 Start button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814e9750e23fbc7292fa26a.png%3F3) 
 High score button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814ea630e23fbc7292fa285.png%3F3) 
 Back button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814eb8e0e23fbc7292fa299.png%3F3) 
 SELECT YOUR CHARACTER button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814ed0e0e23fbc7292fa2b0.png%3F3) 
 Launches button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814f180fb90c04ce18c733a.png%3F3) 
 How to play button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814f1d4fb90c04ce18c733e.png%3F3) 
 Score button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814fcd30e23fbc7292fa369.png%3F3) 
 High Scores button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814fe1d0e23fbc7292fa377.png%3F3) 
 Transparent padlock. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6814ff160e23fbc7292fa382.png%3F3) 
 Chicken jockey character. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6815cc2e1a2f31aebc36772c.png%3F3) 
 Reset scores button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6815e8706137896f737201af.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6816d35ae16864a155151a6f.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6816db39d574efc6b10a8c23.png%3F3) 
 Spider jockey unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816dba1d574efc6b10a8c2b.png%3F3) 
 Minecraft Steve unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816dc6cd574efc6b10a8c3b.png%3F3) 
 Piglin unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816dcafd574efc6b10a8c41.png%3F3) 
 Minecraft skeleton unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6816dd05d574efc6b10a8c49.png%3F3) 
 Minecraft villager unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6817072827945e34d88365bf.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6817077827945e34d88365c7.png%3F3) 
 Star. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681707d227945e34d88365cd.png%3F3) 
 White star. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681709c927945e34d88365da.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/68170ba127945e34d88365fe.png%3F3) 
 Red heart. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68170bea27945e34d8836604.png%3F3) 
 Purple heart. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68170c3730f9a3ca3143c36b.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/68170df027945e34d8836617.png%3F3) 
 A peanut. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68170e3627945e34d883661c.png%3F3) 
 Cashew nut. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6817137327945e34d883666e.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681717d45557ee2046ecc2f7.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/68171a3c27945e34d883669c.png%3F3) 
 Grimace shake. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68171a8627945e34d88366a8.png%3F3) 
 MacDonald's fries. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68172b1b527b05c35818e92d.png%3F3) 
 Grimace unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68176ba74a0979b918f7a043.png%3F3) 
 Michael Jackson unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68176bfb4a0979b918f7a047.png%3F3) 
 John Cena unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681848065557ee2046ecc355.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681852a92383a43353c7548b.png%3F3) 
 Deez nuts unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681852f02383a43353c75498.png%3F3) 
 Shooting stars unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68185b748a0e5c4bce224097.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681875d52be3391f326409d8.png%3F3) 
 Rick roll unlocked button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681952795557ee2046ecc397.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6819530ee4bfd0bbff165058.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681c8c14c433709b9f3496bb.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681c9e526135700112f879bd.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681d93b51b9e5a67ebab2a52.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681d95da1b9e5a67ebab2a5f.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681e1884c7ebd23c4bdd5928.png%3F3) 
 Popcorn chicken. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681e18f9c7ebd23c4bdd5939.png%3F3) 
 Fried chicken drumstick. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681eb5fbce5c2130acf291bd.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681eb6868578d3fadb9cac49.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681eb95249de8df9599c5b97.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681ebb3049de8df9599c5ba9.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681ee624b1146135aaefe63c.png%3F3) 
 Amazing digital circus button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681ef7e841b5fb6826081a28.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681ef98cce5c2130acf291c1.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681ef9efce5c2130acf291c3.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/681f82fa4de4664a77b8eb6f.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6826b332054039919f0a089c.png%3F3) 
 Select game mode button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6826bbff97a2158c01b6e945.png%3F3) 
 Diamond shaped colourful classic mode button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6826c2d197a2158c01b6e963.png%3F3) 
 Diamond shaped colourful mini games button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6827168900c54e0648f3278d.png%3F3) 
 Same picture in high definition
:quality(85)/https://cdn.frvr.ai/6827414625df75ae7a4de4a6.png%3F3) 
 Diamond shaped colourful button that says sling shot mode. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/682548fd80be55c1986a9d45.png%3F3) 
 Make picture transparent
:quality(85)/https://cdn.frvr.ai/6827dcc4f0da5bc629928468.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6827fd58f0da5bc629928492.png%3F3) 
 Bullet. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6827fdd2f0da5bc6299284a3.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6828170b80d2c88911cb1d24.png%3F3) 
 Start game button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/682b446c031377340829c968.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/682b45b0031377340829ca5d.png%3F3) 
 Shooting gallery button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/682ec3c623c50e12668ce9bd.png%3F3) 
 Chain reaction button. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/682ecaa723c50e12668cea01.png%3F3) 
 Realistic space backdrop. 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
Reelbadman
Sound effect
Tinggoes
Music