User prompt
Make x2 randomly appear in the arena and if player hits it and the popcorn it doubles their total score ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Every 10 launches make bogerk sound
User prompt
Make nomnomnom text bigger
User prompt
Chang bounce text to say nomnomnom
User prompt
Reduce popcorn size
User prompt
Chicken always returns to centre of screen after launch
User prompt
Player needs to collect one popcorn each launch or else game over
User prompt
Remove all game over conditions
User prompt
Fix this please
User prompt
Player doesn't die if they collect 1 popcorn per launch
User prompt
Make sure that 2 popcorn don't appear at the same time
User prompt
Change bounce text to say YUMMY
User prompt
Player only need to eat 1 popcorn per launch
User prompt
Ensure that next popcorn doesn't appear until player has returned to centre of screen
User prompt
Make popcorn shrink every 10 launches
User prompt
Speed up popcorn movement slightly every 10 launches
User prompt
Make popcorn move slowly around arena ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add x1 multiplier after 10 launches x2 multiplier after 20 launches and so on
User prompt
Change scoring system to 1 point per popcorn and no points anywhere else
User prompt
Remove chicken from title screen
User prompt
Move chicken on title screen down 400
User prompt
Move chicken on title screen down 500
User prompt
Remove title text from title screen
User prompt
Remove WrestleMania word from title screen
User prompt
Remove title text from title screen
/****
* 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;
}
// Track last intersecting state for x2 collision
if (typeof self.lastIntersectsX2 === 'undefined') {
self.lastIntersectsX2 = false;
}
// Check for collision with popcorn
if (popcorn !== null) {
var currentIntersects = self.intersects(popcorn);
if (currentIntersects) {
// Collect popcorn
if (game.x2Collected) {
// Double the total score if x2 was collected
game.addScore(game.totalScore);
// Reset x2 collection status
game.x2Collected = false;
// Show message
showMessage("TOTAL SCORE DOUBLED!", 0xFFD700);
} else {
popcorn.collect();
}
// Set to null (will be recreated on stop)
popcorn = null;
}
self.lastIntersectsPopcorn = currentIntersects;
}
// Check for collision with x2 multiplier
if (x2Multiplier !== null) {
var currentIntersectsX2 = self.intersects(x2Multiplier);
if (currentIntersectsX2) {
// Collect x2 multiplier
x2Multiplier.collect();
// Set to null
x2Multiplier = null;
}
self.lastIntersectsX2 = currentIntersectsX2;
}
// 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 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();
}
};
// Position in center of screen
self.x = 2048 / 2;
self.y = 2732 / 2;
return self;
});
var X2Multiplier = Container.expand(function () {
var self = Container.call(this);
// Create and attach X2 asset
var x2Graphics = self.attachAsset('X2', {
anchorX: 0.5,
anchorY: 0.5
});
// X2 properties
self.collected = false;
self.baseY = 0;
self.animationOffset = Math.random() * Math.PI * 2;
self.animationSpeed = 0.05 + Math.random() * 0.03;
// Pulse animation
self.pulseDirection = 1;
self.pulseSpeed = 0.02;
self.minScale = 0.9;
self.maxScale = 1.1;
self.scale = 1.0;
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: 2,
scaleY: 2
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove from parent
if (self.parent) {
self.parent.removeChild(self);
}
}
});
self.collected = true;
game.x2Collected = true;
showMessage("X2 Collected! Catch popcorn for double score!", 0xFFFF00);
};
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;
});
/****
* 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 x2Multiplier = null; // Track the active x2 multiplier
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());
game.x2Collected = false; // Track if x2 has been collected
// 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;
popcornMoveSpeed = 5000; // Reset popcorn movement speed
game.x2Collected = false; // Reset x2 collected status
gameState = "ready";
// Update UI
scoreText.setText("Score: " + score);
launchesText.setText("Launches: " + launches);
instructionText.setText("Swipe and flick the chicken to collect as much popcorn as possible!");
// 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();
// Create X2 multiplier with a random chance
if (Math.random() < 0.7) {
createX2Multiplier();
}
// 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 = [];
// Remove x2 multiplier if exists
if (x2Multiplier && x2Multiplier.parent) {
x2Multiplier.parent.removeChild(x2Multiplier);
}
x2Multiplier = null;
}
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 createX2Multiplier() {
// Only create if no x2Multiplier exists
if (x2Multiplier === null && !game.x2Collected) {
var newX2 = new X2Multiplier();
// Random position within arena bounds
newX2.x = bounds.left + 150 + Math.random() * (arena.width - 300);
newX2.y = bounds.top + 150 + Math.random() * (arena.height - 300);
// Add to game
game.addChild(newX2);
x2Multiplier = newX2;
}
}
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;
}
}
// 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("Return to the center of the ring to make popcorn appear!");
}
// 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++;
// 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;
// Track total score for x2 feature
game.totalScore = score;
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;
}
// 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();
}
// Update x2 multiplier animation
if (x2Multiplier !== null) {
x2Multiplier.update();
}
// Randomly spawn new power-ups (rare)
if (gameState === "launched" && Math.random() < 0.001 && powerUps.length < 5) {
createPowerUp();
}
// Randomly spawn new x2 multiplier (even more rare)
if (gameState === "launched" && Math.random() < 0.0005 && x2Multiplier === null && !game.x2Collected) {
createX2Multiplier();
}
// 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());
};
// 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
@@ -74,19 +74,43 @@
// Track last intersecting state for popcorn collision
if (typeof self.lastIntersectsPopcorn === 'undefined') {
self.lastIntersectsPopcorn = false;
}
+ // Track last intersecting state for x2 collision
+ if (typeof self.lastIntersectsX2 === 'undefined') {
+ self.lastIntersectsX2 = false;
+ }
// Check for collision with popcorn
if (popcorn !== null) {
var currentIntersects = self.intersects(popcorn);
if (currentIntersects) {
// Collect popcorn
- popcorn.collect();
+ if (game.x2Collected) {
+ // Double the total score if x2 was collected
+ game.addScore(game.totalScore);
+ // Reset x2 collection status
+ game.x2Collected = false;
+ // Show message
+ showMessage("TOTAL SCORE DOUBLED!", 0xFFD700);
+ } else {
+ popcorn.collect();
+ }
// Set to null (will be recreated on stop)
popcorn = null;
}
self.lastIntersectsPopcorn = currentIntersects;
}
+ // Check for collision with x2 multiplier
+ if (x2Multiplier !== null) {
+ var currentIntersectsX2 = self.intersects(x2Multiplier);
+ if (currentIntersectsX2) {
+ // Collect x2 multiplier
+ x2Multiplier.collect();
+ // Set to null
+ x2Multiplier = null;
+ }
+ self.lastIntersectsX2 = currentIntersectsX2;
+ }
// Track previous positions before bounce
var prevX = self.x;
var prevY = self.y;
// Track previous positions for more accurate collision detection
@@ -678,8 +702,74 @@
self.x = 2048 / 2;
self.y = 2732 / 2;
return self;
});
+var X2Multiplier = Container.expand(function () {
+ var self = Container.call(this);
+ // Create and attach X2 asset
+ var x2Graphics = self.attachAsset('X2', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // X2 properties
+ self.collected = false;
+ self.baseY = 0;
+ self.animationOffset = Math.random() * Math.PI * 2;
+ self.animationSpeed = 0.05 + Math.random() * 0.03;
+ // Pulse animation
+ self.pulseDirection = 1;
+ self.pulseSpeed = 0.02;
+ self.minScale = 0.9;
+ self.maxScale = 1.1;
+ self.scale = 1.0;
+ 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: 2,
+ scaleY: 2
+ }, {
+ duration: 600,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ // Remove from parent
+ if (self.parent) {
+ self.parent.removeChild(self);
+ }
+ }
+ });
+ self.collected = true;
+ game.x2Collected = true;
+ showMessage("X2 Collected! Catch popcorn for double score!", 0xFFFF00);
+ };
+ 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;
+});
/****
* Initialize Game
****/
@@ -697,14 +787,16 @@
var maxLaunches = 5;
var ropes = [];
var powerUps = [];
var popcorn = null; // Track the active popcorn
+var x2Multiplier = null; // Track the active x2 multiplier
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());
+game.x2Collected = false; // Track if x2 has been collected
// Add backdrop first
var backdrop = game.addChild(LK.getAsset('Backdrop', {
anchorX: 0.5,
anchorY: 0.5,
@@ -757,8 +849,9 @@
maxLaunches = 5;
scoreMultiplier = 1;
multiplierEndTime = 0;
popcornMoveSpeed = 5000; // Reset popcorn movement speed
+ game.x2Collected = false; // Reset x2 collected status
gameState = "ready";
// Update UI
scoreText.setText("Score: " + score);
launchesText.setText("Launches: " + launches);
@@ -774,8 +867,12 @@
createPowerUp();
}
// Create the initial popcorn
createPopcorn();
+ // Create X2 multiplier with a random chance
+ if (Math.random() < 0.7) {
+ createX2Multiplier();
+ }
// 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 () {
@@ -804,8 +901,13 @@
powerUps[i].parent.removeChild(powerUps[i]);
}
}
powerUps = [];
+ // Remove x2 multiplier if exists
+ if (x2Multiplier && x2Multiplier.parent) {
+ x2Multiplier.parent.removeChild(x2Multiplier);
+ }
+ x2Multiplier = null;
}
function createRopes() {
// Create top rope
var topRope = new Rope();
@@ -858,8 +960,20 @@
// Add to game
game.addChild(powerUp);
powerUps.push(powerUp);
}
+function createX2Multiplier() {
+ // Only create if no x2Multiplier exists
+ if (x2Multiplier === null && !game.x2Collected) {
+ var newX2 = new X2Multiplier();
+ // Random position within arena bounds
+ newX2.x = bounds.left + 150 + Math.random() * (arena.width - 300);
+ newX2.y = bounds.top + 150 + Math.random() * (arena.height - 300);
+ // Add to game
+ game.addChild(newX2);
+ x2Multiplier = newX2;
+ }
+}
function createPopcorn() {
// Only create if no popcorn exists
if (popcorn === null) {
var newPopcorn = new Popcorn();
@@ -978,8 +1092,10 @@
}
// Apply launch multiplier
finalPoints = Math.floor(finalPoints * launchMultiplier);
score += finalPoints;
+ // Track total score for x2 feature
+ game.totalScore = score;
scoreText.setText("Score: " + score);
LK.setScore(score);
};
// Power-up activation function
@@ -1119,12 +1235,20 @@
// Update popcorn animation
if (popcorn !== null) {
popcorn.update();
}
+ // Update x2 multiplier animation
+ if (x2Multiplier !== null) {
+ x2Multiplier.update();
+ }
// Randomly spawn new power-ups (rare)
if (gameState === "launched" && Math.random() < 0.001 && powerUps.length < 5) {
createPowerUp();
}
+ // Randomly spawn new x2 multiplier (even more rare)
+ if (gameState === "launched" && Math.random() < 0.0005 && x2Multiplier === null && !game.x2Collected) {
+ createX2Multiplier();
+ }
// 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) {
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
Chain reaction button. In-Game asset. 2d. High contrast. No shadows
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