User prompt
Add more velocity to bounce of ropes
User prompt
Make launcher invisible
User prompt
Replace slingshot launch method with draw a path method and show the path âŞđĄ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove ropes in middle of arena
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
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var ChickenJockey = Container.expand(function () { var self = Container.call(this); // Create and attach chicken asset var chickenGraphics = self.attachAsset('chicken', { anchorX: 0.5, anchorY: 0.5 }); // Physics properties self.vx = 0; self.vy = 0; self.gravity = 0.5; self.bounceDecay = 0.7; // Energy loss per bounce self.friction = 0.99; // Horizontal friction self.launched = false; self.bounceCount = 0; self.maxBounces = 10; // 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.update = function () { if (!self.launched) { return; } // Apply physics self.vy += self.gravity; self.x += self.vx; self.y += self.vy; self.vx *= self.friction; // Apply rotation self.rotation += self.rotationSpeed; // Check if stopped if (Math.abs(self.vx) < 0.5 && Math.abs(self.vy) < 0.5 && self.bounceCount > 0) { self.launched = false; // Notify game that chicken jockey has stopped if (typeof game.onChickenJockeyStop === 'function') { game.onChickenJockeyStop(); } } // Check if max bounces reached if (self.bounceCount >= self.maxBounces) { self.launched = false; // Notify game that max bounces reached if (typeof game.onMaxBouncesReached === 'function') { game.onMaxBouncesReached(); } } }; return self; }); var Launcher = Container.expand(function () { var self = Container.call(this); // Create and attach launcher asset var launcherGraphics = self.attachAsset('launcher', { anchorX: 0.5, anchorY: 0.5 }); // Create aim line (initially invisible) var aimLine = self.attachAsset('aimLine', { anchorX: 0, anchorY: 0.5, alpha: 0 }); // Launcher properties self.angle = -45; // Starting angle in degrees self.power = 20; // Starting power self.maxPower = 40; self.aiming = false; self.startX = 0; self.startY = 0; self.startAim = function (x, y) { self.aiming = true; self.startX = x; self.startY = y; aimLine.alpha = 0.7; }; self.updateAim = function (x, y) { if (!self.aiming) { return; } // Calculate angle based on drag direction var dx = self.startX - x; var dy = self.startY - y; // Calculate angle in degrees (0 is right, 90 is up) self.angle = Math.atan2(dy, dx) * 180 / Math.PI; // Limit angle to upper half (0 to 180 degrees) if (self.angle < 0) { self.angle += 360; } if (self.angle > 180) { self.angle = 180; } // Calculate power based on drag distance var distance = Math.sqrt(dx * dx + dy * dy); self.power = Math.min(distance / 10, self.maxPower); // Update launcher rotation self.rotation = self.angle * Math.PI / 180; // Update aim line aimLine.width = self.power * 10; aimLine.rotation = 0; // The rotation is applied to the parent container }; self.endAim = function () { self.aiming = false; aimLine.alpha = 0; // Return launch parameters return { angle: self.angle, power: self.power }; }; return self; }); var Popcorn = Container.expand(function () { var self = Container.call(this); // Create and attach popcorn asset var popcornGraphics = self.attachAsset('popcorn', { anchorX: 0.5, anchorY: 0.5 }); // Add slight animation self.animationOffset = Math.random() * Math.PI * 2; self.animationSpeed = 0.03 + Math.random() * 0.02; self.baseY = 0; self.collect = function () { // Play collect sound LK.getSound('collect').play(); // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 200); // Animate collection (flying up) tween(self, { y: self.y - 100, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Remove from parent if (self.parent) { self.parent.removeChild(self); } } }); }; self.update = function () { // Hover animation if (self.baseY === 0) { self.baseY = self.y; } self.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 5; }; return self; }); var 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 = 1.2; // Higher tension = more bounce self.bounce = function (chickenJockey) { // Calculate new velocity based on collision angle and rope tension var normalAngle = Math.atan2(chickenJockey.y - self.y, chickenJockey.x - self.x) + Math.PI / 2; // Calculate velocity components along normal direction var vn = chickenJockey.vx * Math.cos(normalAngle) + chickenJockey.vy * Math.sin(normalAngle); var vt = -chickenJockey.vx * Math.sin(normalAngle) + chickenJockey.vy * Math.cos(normalAngle); // Reverse normal component with tension and bounce decay vn = -vn * chickenJockey.bounceDecay * self.tension; // Convert back to x,y velocities chickenJockey.vx = vn * Math.cos(normalAngle) - vt * Math.sin(normalAngle); chickenJockey.vy = vn * Math.sin(normalAngle) + vt * Math.cos(normalAngle); // Increment bounce count chickenJockey.bounceCount++; // Play bounce sound LK.getSound('bounce').play(); // Flash rope to indicate bounce LK.effects.flashObject(self, 0xFFFFFF, 200); }; self.intersectsWithPoint = function (x, y) { var halfWidth = ropeGraphics.width / 2; var halfHeight = ropeGraphics.height / 2; // Check if point is within the rope's bounding box return x >= self.x - halfWidth && x <= self.x + halfWidth && y >= self.y - halfHeight && y <= self.y + halfHeight; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue background }); /**** * Game Code ****/ // Game state var gameState = "ready"; // ready, aiming, launched, gameOver var score = 0; var launches = 0; var maxLaunches = 5; var popcorns = []; var ropes = []; // 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()); var launcher = game.addChild(new Launcher()); // Game boundaries var bounds = { left: arena.x - arena.width / 2, right: arena.x + arena.width / 2, top: arena.y - arena.height / 2, bottom: arena.y + arena.height / 2 }; // Create GUI elements var 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; gameState = "ready"; // Update UI scoreText.setText("Score: " + score); launchesText.setText("Launches: " + launches + "/" + maxLaunches); // Reset chicken jockey resetChickenJockey(); // Clear existing popcorn and ropes clearPopcornsAndRopes(); // Create ropes around the arena createRopes(); // Create popcorn scattered around the arena createPopcorn(15); // Play background music LK.playMusic('gameMusic'); } function resetChickenJockey() { chickenJockey.reset(); // Position chicken in the center of the arena chickenJockey.x = arena.x; chickenJockey.y = arena.y; // Position launcher at the same position launcher.x = chickenJockey.x; launcher.y = chickenJockey.y; launcher.rotation = -Math.PI / 4; // 45 degrees upward } function clearPopcornsAndRopes() { // Remove all popcorn for (var i = 0; i < popcorns.length; i++) { if (popcorns[i].parent) { popcorns[i].parent.removeChild(popcorns[i]); } } popcorns = []; // Remove all ropes for (var i = 0; i < ropes.length; i++) { if (ropes[i].parent) { ropes[i].parent.removeChild(ropes[i]); } } ropes = []; } function createRopes() { // Create top rope var topRope = new Rope(); topRope.x = arena.x; topRope.y = bounds.top + 100; game.addChild(topRope); ropes.push(topRope); // Create right rope var rightRope = new Rope(); rightRope.x = bounds.right - 100; rightRope.y = arena.y; rightRope.rotation = Math.PI / 2; // Rotate 90 degrees game.addChild(rightRope); ropes.push(rightRope); // Create bottom rope var bottomRope = new Rope(); bottomRope.x = arena.x; bottomRope.y = bounds.bottom - 100; game.addChild(bottomRope); ropes.push(bottomRope); // Create left rope var leftRope = new Rope(); leftRope.x = bounds.left + 100; leftRope.y = arena.y; leftRope.rotation = Math.PI / 2; // Rotate 90 degrees game.addChild(leftRope); ropes.push(leftRope); } function createPopcorn(count) { for (var i = 0; i < count; i++) { var popcorn = new Popcorn(); // Random position within arena bounds popcorn.x = bounds.left + 100 + Math.random() * (arena.width - 200); popcorn.y = bounds.top + 100 + Math.random() * (arena.height - 200); // Add to game game.addChild(popcorn); popcorns.push(popcorn); } } // Game events game.onChickenJockeyStop = function () { gameState = "ready"; // Check if we need to add more popcorn if (popcorns.length < 5) { createPopcorn(5); } // Check if out of launches if (launches >= maxLaunches) { // Game over instructionText.setText("Game Over! Final Score: " + score); gameState = "gameOver"; // Show game over after a short delay LK.setTimeout(function () { LK.showGameOver(); }, 2000); } else { // Reset for next launch resetChickenJockey(); instructionText.setText("Drag to aim and launch the chicken!"); } }; game.onMaxBouncesReached = function () { // Same as onChickenJockeyStop for now game.onChickenJockeyStop(); }; // Input handling var dragStartX = 0; var dragStartY = 0; game.down = function (x, y, obj) { if (gameState === "ready") { gameState = "aiming"; dragStartX = x; dragStartY = y; launcher.startAim(x, y); } }; game.move = function (x, y, obj) { if (gameState === "aiming") { launcher.updateAim(x, y); } }; game.up = function (x, y, obj) { if (gameState === "aiming") { // Get launch parameters var launchParams = launcher.endAim(); // Launch the chicken jockey chickenJockey.launch(launchParams.power, launchParams.angle); // Update game state gameState = "launched"; launches++; launchesText.setText("Launches: " + launches + "/" + maxLaunches); instructionText.setText("Watch the chicken bounce!"); } }; // Main game loop game.update = function () { // Update all game objects if (gameState === "launched") { chickenJockey.update(); // Check for collisions with arena boundaries if (chickenJockey.x < bounds.left) { chickenJockey.x = bounds.left; chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } else if (chickenJockey.x > bounds.right) { chickenJockey.x = bounds.right; chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } if (chickenJockey.y < bounds.top) { chickenJockey.y = bounds.top; chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } else if (chickenJockey.y > bounds.bottom) { chickenJockey.y = bounds.bottom; chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay; chickenJockey.bounceCount++; LK.getSound('bounce').play(); } // Check for collisions with ropes for (var i = 0; i < ropes.length; i++) { if (chickenJockey.intersects(ropes[i])) { ropes[i].bounce(chickenJockey); } } // Check for collisions with popcorn for (var i = popcorns.length - 1; i >= 0; i--) { if (chickenJockey.intersects(popcorns[i])) { // Collect popcorn popcorns[i].collect(); // Remove from array popcorns.splice(i, 1); // Increase score score += 10; scoreText.setText("Score: " + score); // Save score to LK LK.setScore(score); } } } // Update popcorn animations for (var i = 0; i < popcorns.length; i++) { popcorns[i].update(); } }; // Initialize the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -16,19 +16,16 @@
});
// 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.gravity = 0.5;
+ self.bounceDecay = 0.7; // Energy loss per bounce
+ self.friction = 0.99; // Horizontal friction
self.launched = false;
self.bounceCount = 0;
- self.maxBounces = 5; // Allow 5 bounces per swipe
+ self.maxBounces = 10;
// Rotation properties
self.rotationSpeed = 0;
- // Path following properties
- self.path = null;
- self.currentPathIndex = 0;
self.launch = function (power, angle) {
// Convert angle to radians
var radians = angle * Math.PI / 180;
// Set initial velocity based on power and angle
@@ -47,255 +44,28 @@
self.rotation = 0;
self.rotationSpeed = 0;
self.launched = false;
self.bounceCount = 0;
- self.maxBounces = 300; // Set the max bounces here too
- self.path = null;
- self.currentPathIndex = 0;
};
- // Method to set a path for the chicken to follow
- self.setPath = function (pathPoints) {
- if (pathPoints && pathPoints.length >= 2) {
- self.path = pathPoints;
- self.currentPathIndex = 0;
- self.launched = true;
- // Play launch sound
- LK.getSound('launch').play();
- }
- };
self.update = function () {
if (!self.launched) {
return;
}
- // Follow path if available
- if (self.path && self.path.length > 0 && self.currentPathIndex < self.path.length) {
- // Get target point
- var targetPoint = self.path[self.currentPathIndex];
- // Calculate direction to target
- var dx = targetPoint.x - self.x;
- var dy = targetPoint.y - self.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- // If reached target point, move to next one
- if (distance < 20) {
- self.currentPathIndex++;
- // If we've reached the end of the path
- if (self.currentPathIndex >= self.path.length) {
- // Instead of just clearing the path and leaving with zero velocity,
- // maintain momentum in the direction we were traveling
- if (self.vx == 0 && self.vy == 0) {
- // Get last two points to determine direction
- var lastPoint = self.path[self.path.length - 1];
- var prevPoint = self.path.length > 1 ? self.path[self.path.length - 2] : self.path[0];
- // Calculate direction vector
- var dx = lastPoint.x - prevPoint.x;
- var dy = lastPoint.y - prevPoint.y;
- // Normalize and apply initial velocity
- var length = Math.sqrt(dx * dx + dy * dy);
- if (length > 0) {
- self.vx = dx / length * 15;
- self.vy = dy / length * 15;
- }
- }
- // Clear path and continue with normal physics
- self.path = null;
- }
- } else {
- // Move toward target point
- var moveSpeed = 15; // Adjust for desired speed
- self.vx = dx / distance * moveSpeed;
- self.vy = dy / distance * moveSpeed;
- // Calculate rotation based on movement direction
- var targetRotation = Math.atan2(dy, dx);
- // Gradually rotate toward target rotation
- var rotDiff = targetRotation - self.rotation;
- // Normalize rotation difference
- while (rotDiff > Math.PI) {
- rotDiff -= Math.PI * 2;
- }
- while (rotDiff < -Math.PI) {
- rotDiff += Math.PI * 2;
- }
- self.rotation += rotDiff * 0.1; // Adjust for rotation speed
- }
- } else {
- // Normal physics when not following path
- 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;
- }
+ // Apply physics
+ self.vy += self.gravity;
+ self.x += self.vx;
+ self.y += self.vy;
+ self.vx *= self.friction;
+ // Apply rotation
+ 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 (legacy support)
- 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;
- }
- // Check for collisions with popcorn line
- if (popcornLine && popcornLine.active && popcornLine.popcorns.length > 0) {
- for (var i = popcornLine.popcorns.length - 1; i >= 0; i--) {
- var p = popcornLine.popcorns[i];
- if (!p.collected && self.intersects(p)) {
- // Collect popcorn
- p.collect();
- // Track if all popcorns are collected
- allPopcornsCollected = popcornLine.isComplete();
- }
- }
- }
- // 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
@@ -305,612 +75,107 @@
}
};
return self;
});
-var HighScoreTally = Container.expand(function () {
+var Launcher = Container.expand(function () {
var self = Container.call(this);
- // Background container
- var background = self.attachAsset('Hiscorebackdrop', {
+ // Create and attach launcher asset
+ var launcherGraphics = self.attachAsset('launcher', {
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
+ // Create aim line (initially invisible)
+ var aimLine = self.attachAsset('aimLine', {
+ anchorX: 0,
+ anchorY: 0.5,
+ alpha: 0
});
- 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);
- }
+ // Launcher properties
+ self.angle = -45; // Starting angle in degrees
+ self.power = 20; // Starting power
+ self.maxPower = 40;
+ self.aiming = false;
+ self.startX = 0;
+ self.startY = 0;
+ self.startAim = function (x, y) {
+ self.aiming = true;
+ self.startX = x;
+ self.startY = y;
+ aimLine.alpha = 0.7;
};
- // 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();
+ self.updateAim = function (x, y) {
+ if (!self.aiming) {
+ return;
}
- };
- // 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();
+ // Calculate angle based on drag direction
+ var dx = self.startX - x;
+ var dy = self.startY - y;
+ // Calculate angle in degrees (0 is right, 90 is up)
+ self.angle = Math.atan2(dy, dx) * 180 / Math.PI;
+ // Limit angle to upper half (0 to 180 degrees)
+ if (self.angle < 0) {
+ self.angle += 360;
}
- };
- // 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();
+ if (self.angle > 180) {
+ self.angle = 180;
}
- };
- // 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;
- self.pathLines = [];
- // 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;
- // Method to create a visible path line between two points
- self.createPathLine = function (x1, y1, x2, y2) {
- var line = new Container();
- var lineGraphics = line.attachAsset('rope', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- // Calculate position (midpoint between the two points)
- var midX = (x1 + x2) / 2;
- var midY = (y1 + y2) / 2;
- line.x = midX;
- line.y = midY;
- // Calculate length and angle
- var dx = x2 - x1;
- var dy = y2 - y1;
- var length = Math.sqrt(dx * dx + dy * dy);
- var angle = Math.atan2(dy, dx);
- // Set line properties
- lineGraphics.width = length;
- lineGraphics.height = self.lineWidth;
- lineGraphics.rotation = angle;
- lineGraphics.tint = 0x00FFFF;
- lineGraphics.alpha = 0.7;
- // Add to game and track in array
- game.addChild(line);
- self.pathLines.push(line);
- return line;
- };
- self.startTracing = function (x, y) {
- self.points = [{
- x: x,
- y: y
- }];
- self.active = true;
- // Add visual feedback when starting to trace
- var startMarker = new Container();
- var marker = startMarker.attachAsset('centerCircle', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 0.5,
- scaleY: 0.5
- });
- marker.tint = 0x00FFFF;
- startMarker.x = x;
- startMarker.y = y;
- game.addChild(startMarker);
- // Animate the marker
- tween(marker, {
- scaleX: 1,
- scaleY: 1,
- alpha: 0
- }, {
- duration: 500,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- if (startMarker.parent) {
- startMarker.parent.removeChild(startMarker);
- }
- }
- });
- };
- 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;
+ // Calculate power based on drag distance
var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance > 20) {
- self.points.push({
- x: x,
- y: y
- });
- // Create line between previous point and new point
- self.createPathLine(lastPoint.x, lastPoint.y, x, y);
- // Limit number of points
- if (self.points.length > self.maxPoints) {
- self.points.shift();
- // Remove oldest line if we've exceeded max points
- if (self.pathLines.length > self.maxPoints - 1) {
- var oldestLine = self.pathLines.shift();
- if (oldestLine.parent) {
- oldestLine.parent.removeChild(oldestLine);
- }
- }
- }
- }
+ self.power = Math.min(distance / 10, self.maxPower);
+ // Update launcher rotation
+ self.rotation = self.angle * Math.PI / 180;
+ // Update aim line
+ aimLine.width = self.power * 10;
+ aimLine.rotation = 0; // The rotation is applied to the parent container
};
- self.stopTracing = function () {
- self.active = false;
- return self.points.length >= 2 ? self.points : null;
+ self.endAim = function () {
+ self.aiming = false;
+ aimLine.alpha = 0;
+ // Return launch parameters
+ return {
+ angle: self.angle,
+ power: self.power
+ };
};
- self.clear = function () {
- // Remove all path lines
- for (var i = 0; i < self.pathLines.length; i++) {
- if (self.pathLines[i].parent) {
- self.pathLines[i].parent.removeChild(self.pathLines[i]);
- }
- }
- self.pathLines = [];
- 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.7;
- // Enhanced path visualization - highlight the path more clearly
- pathGraphics.tint = 0x00FFFF; // Cyan color for more visibility
- // 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 * 2; // Make the line thicker
- pathGraphics.rotation = angle;
- // Make path pulse for better visibility
- var pulseSpeed = 0.02;
- if (!self.pulseDirection) {
- self.pulseDirection = 1;
- }
- if (!self.pulseAmount) {
- self.pulseAmount = 1;
- }
- self.pulseAmount += pulseSpeed * self.pulseDirection;
- if (self.pulseAmount > 1.2) {
- self.pulseAmount = 1.2;
- self.pulseDirection = -1;
- } else if (self.pulseAmount < 0.8) {
- self.pulseAmount = 0.8;
- self.pulseDirection = 1;
- }
- pathGraphics.alpha = 0.7 * self.pulseAmount;
- // Pulse all path lines
- for (var i = 0; i < self.pathLines.length; i++) {
- var line = self.pathLines[i];
- if (line.children && line.children[0]) {
- line.children[0].alpha = 0.7 * self.pulseAmount;
- }
- }
- };
return self;
});
var Popcorn = Container.expand(function () {
var self = Container.call(this);
- // Create and attach popcorn asset with smaller size
+ // Create and attach popcorn asset
var popcornGraphics = self.attachAsset('popcorn', {
anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 1.5,
- scaleY: 1.5
+ anchorY: 0.5
});
- // Popcorn properties
- self.collected = false;
- self.baseY = 0;
+ // Add slight animation
self.animationOffset = Math.random() * Math.PI * 2;
- self.animationSpeed = 0.05 + Math.random() * 0.03;
+ self.animationSpeed = 0.03 + Math.random() * 0.02;
+ self.baseY = 0;
self.collect = function () {
// Play collect sound
LK.getSound('collect').play();
// Flash effect
- LK.effects.flashObject(self, 0xFFFFFF, 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 PopcornLine = Container.expand(function () {
- var self = Container.call(this);
- // Properties
- self.popcorns = [];
- self.corner = 0; // 0: top-left, 1: top-right, 2: bottom-right, 3: bottom-left
- self.active = false;
- // Create a line of popcorn from a specific corner
- self.createLine = function (corner, count) {
- // Clear existing popcorns
- self.clearLine();
- // Set corner
- self.corner = corner;
- self.active = true;
- // Determine start and end positions based on corner
- var startX, startY, endX, endY;
- switch (corner) {
- case 0:
- // Top-left
- startX = bounds.left + 100;
- startY = bounds.top + 100;
- endX = bounds.right - 100;
- endY = bounds.bottom - 100;
- break;
- case 1:
- // Top-right
- startX = bounds.right - 100;
- startY = bounds.top + 100;
- endX = bounds.left + 100;
- endY = bounds.bottom - 100;
- break;
- case 2:
- // Bottom-right
- startX = bounds.right - 100;
- startY = bounds.bottom - 100;
- endX = bounds.left + 100;
- endY = bounds.top + 100;
- break;
- case 3:
- // Bottom-left
- startX = bounds.left + 100;
- startY = bounds.bottom - 100;
- endX = bounds.right - 100;
- endY = bounds.top + 100;
- break;
- }
- // Create popcorns along the line
- for (var i = 0; i < count; i++) {
- var progress = i / (count - 1);
- var x = startX + (endX - startX) * progress;
- var y = startY + (endY - startY) * progress;
- var newPopcorn = new Popcorn();
- newPopcorn.x = x;
- newPopcorn.y = y;
- // Add to game and track in array
- game.addChild(newPopcorn);
- self.popcorns.push(newPopcorn);
- }
- // Return the number of popcorns created
- return self.popcorns.length;
- };
- // Clear all popcorns in the line
- self.clearLine = function () {
- for (var i = 0; i < self.popcorns.length; i++) {
- if (self.popcorns[i].parent) {
- self.popcorns[i].parent.removeChild(self.popcorns[i]);
- }
- }
- self.popcorns = [];
- self.active = false;
- };
- // Check if all popcorns in line have been collected
- self.isComplete = function () {
- return self.popcorns.length === 0 || self.popcorns.every(function (p) {
- return p.collected;
- });
- };
- // Update method
- self.update = function () {
- if (!self.active) {
- return;
- }
- // Remove collected popcorns from array
- for (var i = self.popcorns.length - 1; i >= 0; i--) {
- if (self.popcorns[i].collected) {
- self.popcorns.splice(i, 1);
- }
- }
- // Check if all collected
- if (self.popcorns.length === 0) {
- self.active = false;
- }
- };
- 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);
+ LK.effects.flashObject(self, 0xFFFFFF, 200);
// Animate collection (flying up)
tween(self, {
- y: self.y - 150,
- alpha: 0,
- scaleX: 2,
- scaleY: 2
+ y: self.y - 100,
+ alpha: 0
}, {
- duration: 600,
+ duration: 500,
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;
+ self.y = self.baseY + Math.sin(LK.ticks * self.animationSpeed + self.animationOffset) * 5;
};
return self;
});
var Rope = Container.expand(function () {
@@ -920,102 +185,26 @@
anchorX: 0.5,
anchorY: 0.5
});
// Rope properties
- self.tension = 0.8; // Increased tension for more springy, elastic bounces
+ self.tension = 1.2; // Higher tension = more bounce
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
- });
- }
- });
+ // Calculate new velocity based on collision angle and rope tension
+ var normalAngle = Math.atan2(chickenJockey.y - self.y, chickenJockey.x - self.x) + Math.PI / 2;
+ // Calculate velocity components along normal direction
+ var vn = chickenJockey.vx * Math.cos(normalAngle) + chickenJockey.vy * Math.sin(normalAngle);
+ var vt = -chickenJockey.vx * Math.sin(normalAngle) + chickenJockey.vy * Math.cos(normalAngle);
+ // Reverse normal component with tension and bounce decay
+ vn = -vn * chickenJockey.bounceDecay * self.tension;
+ // Convert back to x,y velocities
+ chickenJockey.vx = vn * Math.cos(normalAngle) - vt * Math.sin(normalAngle);
+ chickenJockey.vy = vn * Math.sin(normalAngle) + vt * Math.cos(normalAngle);
// 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);
- }
- }
- });
+ // Play bounce sound
+ LK.getSound('bounce').play();
+ // Flash rope to indicate bounce
+ LK.effects.flashObject(self, 0xFFFFFF, 200);
};
self.intersectsWithPoint = function (x, y) {
var halfWidth = ropeGraphics.width / 2;
var halfHeight = ropeGraphics.height / 2;
@@ -1023,113 +212,14 @@
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
+ backgroundColor: 0x87CEEB // Sky blue background
});
/****
* Game Code
@@ -1138,32 +228,10 @@
var gameState = "ready"; // ready, aiming, launched, gameOver
var score = 0;
var launches = 0;
var maxLaunches = 5;
+var popcorns = [];
var ropes = [];
-var powerUps = [];
-var popcorn = null; // Track the active popcorn (legacy - keeping for compatibility)
-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());
-var popcornLine = new PopcornLine(); // Popcorn line manager
-var currentCorner = 0; // Current corner from which popcorn line is created
-var popcornCount = 10; // Number of popcorns in a line
-var allPopcornsCollected = true; // Track if all popcorns are collected
-game.addChild(popcornLine);
-// 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,
@@ -1171,8 +239,9 @@
y: 2732 / 2
}));
// Create chicken jockey
var chickenJockey = game.addChild(new ChickenJockey());
+var launcher = game.addChild(new Launcher());
// Game boundaries
var bounds = {
left: arena.x - arena.width / 2,
right: arena.x + arena.width / 2,
@@ -1191,11 +260,11 @@
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
+launchesText.y = 20;
LK.gui.topLeft.addChild(launchesText);
-var instructionText = new Text2("", {
+var instructionText = new Text2("Drag to aim and launch the chicken!", {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
@@ -1205,78 +274,48 @@
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("Draw a path for Chicken Jockey to follow!");
+ launchesText.setText("Launches: " + launches + "/" + maxLaunches);
// 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 line
- createPopcornLine();
- // 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)
+ // Create popcorn scattered around the arena
+ createPopcorn(15);
+ // Play background music
+ LK.playMusic('gameMusic');
}
function resetChickenJockey() {
chickenJockey.reset();
// Position chicken in the center of the arena
chickenJockey.x = arena.x;
chickenJockey.y = arena.y;
+ // Position launcher at the same position
+ launcher.x = chickenJockey.x;
+ launcher.y = chickenJockey.y;
+ launcher.rotation = -Math.PI / 4; // 45 degrees upward
}
function clearPopcornsAndRopes() {
+ // Remove all popcorn
+ for (var i = 0; i < popcorns.length; i++) {
+ if (popcorns[i].parent) {
+ popcorns[i].parent.removeChild(popcorns[i]);
+ }
+ }
+ popcorns = [];
// Remove all ropes
for (var i = 0; i < ropes.length; i++) {
if (ropes[i].parent) {
ropes[i].parent.removeChild(ropes[i]);
}
}
ropes = [];
- // Remove all power-ups
- for (var i = 0; i < powerUps.length; i++) {
- if (powerUps[i].parent) {
- powerUps[i].parent.removeChild(powerUps[i]);
- }
- }
- powerUps = [];
}
function createRopes() {
// Create top rope
var topRope = new Rope();
@@ -1303,142 +342,40 @@
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();
+function createPopcorn(count) {
+ for (var i = 0; i < count; i++) {
+ var popcorn = 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);
+ popcorn.x = bounds.left + 100 + Math.random() * (arena.width - 200);
+ popcorn.y = bounds.top + 100 + Math.random() * (arena.height - 200);
// Add to game
- game.addChild(newPopcorn);
- popcorn = newPopcorn;
+ game.addChild(popcorn);
+ popcorns.push(popcorn);
}
}
-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 () {
- // Check if all popcorns in the line were collected
- if (popcornLine.active && !allPopcornsCollected) {
+ gameState = "ready";
+ // Check if we need to add more popcorn
+ if (popcorns.length < 5) {
+ createPopcorn(5);
+ }
+ // Check if out of launches
+ if (launches >= maxLaunches) {
+ // Game over
+ instructionText.setText("Game Over! Final Score: " + score);
gameState = "gameOver";
- instructionText.setText("Game Over! You missed some popcorn!");
- // Show game over screen
- LK.showGameOver();
- return;
+ // Show game over after a short delay
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 2000);
} else {
- gameState = "ready";
- // Occasionally add a power-up when chicken stops
- if (Math.random() < 0.3 && powerUps.length < 5) {
- createPowerUp();
- }
- // Create a new popcorn line
- createPopcornLine();
- // Increase score for completing line
- if (allPopcornsCollected) {
- // Bonus for completing the line
- game.addScore(popcornCount * 5);
- showMessage("Line Bonus: " + popcornCount * 5 + " points!", 0xFFD700);
- }
- // Instead of checking if out of launches, increase max launches
- maxLaunches++; // Increase max launches with each launch
// Reset for next launch
resetChickenJockey();
+ instructionText.setText("Drag to aim and launch the chicken!");
}
};
game.onMaxBouncesReached = function () {
// Same as onChickenJockeyStop for now
@@ -1446,436 +383,86 @@
};
// 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!");
+ launcher.startAim(x, y);
}
};
game.move = function (x, y, obj) {
if (gameState === "aiming") {
- pathTracer.addPoint(x, y);
+ launcher.updateAim(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;
- // Use the traced path to guide the chicken jockey
- chickenJockey.setPath(path);
- // 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 follow your path!");
- } else {
- // Cancel the launch if the path was too short
- gameState = "ready";
- }
- // Clear the path tracer visual display
- pathTracer.clear();
+ // Get launch parameters
+ var launchParams = launcher.endAim();
+ // Launch the chicken jockey
+ chickenJockey.launch(launchParams.power, launchParams.angle);
+ // Update game state
+ gameState = "launched";
+ launches++;
+ launchesText.setText("Launches: " + launches + "/" + maxLaunches);
+ instructionText.setText("Watch the chicken bounce!");
}
};
-// 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
+ // Check for collisions with arena boundaries
if (chickenJockey.x < bounds.left) {
chickenJockey.x = bounds.left;
+ chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay;
+ chickenJockey.bounceCount++;
+ LK.getSound('bounce').play();
} else if (chickenJockey.x > bounds.right) {
chickenJockey.x = bounds.right;
+ chickenJockey.vx = -chickenJockey.vx * chickenJockey.bounceDecay;
+ chickenJockey.bounceCount++;
+ LK.getSound('bounce').play();
}
- // Check vertical boundaries - only detect boundaries
- // Vertical boundaries are handled in ChickenJockey class
if (chickenJockey.y < bounds.top) {
chickenJockey.y = bounds.top;
+ chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay;
+ chickenJockey.bounceCount++;
+ LK.getSound('bounce').play();
} else if (chickenJockey.y > bounds.bottom) {
chickenJockey.y = bounds.bottom;
+ chickenJockey.vy = -chickenJockey.vy * chickenJockey.bounceDecay;
+ chickenJockey.bounceCount++;
+ LK.getSound('bounce').play();
}
- // 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 ropes
+ for (var i = 0; i < ropes.length; i++) {
+ if (chickenJockey.intersects(ropes[i])) {
+ ropes[i].bounce(chickenJockey);
}
}
- // 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();
+ // Check for collisions with popcorn
+ for (var i = popcorns.length - 1; i >= 0; i--) {
+ if (chickenJockey.intersects(popcorns[i])) {
+ // Collect popcorn
+ popcorns[i].collect();
// Remove from array
- powerUps.splice(i, 1);
+ popcorns.splice(i, 1);
+ // Increase score
+ score += 10;
+ scoreText.setText("Score: " + score);
+ // Save score to LK
+ LK.setScore(score);
}
}
- // 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 animations
+ for (var i = 0; i < popcorns.length; i++) {
+ popcorns[i].update();
}
- // Update popcorn animation (legacy)
- if (popcorn !== null) {
- popcorn.update();
- }
- // Update popcorn line
- if (popcornLine && popcornLine.active) {
- popcornLine.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);
- };
-};
-function createPopcornLine() {
- // Clear any existing line
- popcornLine.clearLine();
- // Create new line from current corner
- popcornCount = 8 + Math.floor(launches / 5); // Increase count based on launches
- popcornLine.createLine(currentCorner, popcornCount);
- // Update to next corner for next time
- currentCorner = (currentCorner + 1) % 4;
- // Reset collected state
- allPopcornsCollected = false;
- // Update instruction
- instructionText.setText("Collect all popcorn in a single launch!");
-}
\ No newline at end of file
+// Initialize the game
+initGame();
\ No newline at end of file
X5 symbol. In-Game asset. 2d. High contrast. No shadows
X2 symbol. In-Game asset. 2d. High contrast. No shadows
Super popcorn yellow. In-Game asset. 2d. High contrast. No shadows
Start button. In-Game asset. 2d. High contrast. No shadows
High score button. In-Game asset. 2d. High contrast. No shadows
Back button. In-Game asset. 2d. High contrast. No shadows
SELECT YOUR CHARACTER button. In-Game asset. 2d. High contrast. No shadows
Launches button. In-Game asset. 2d. High contrast. No shadows
How to play button. In-Game asset. 2d. High contrast. No shadows
Score button. In-Game asset. 2d. High contrast. No shadows
High Scores button. In-Game asset. 2d. High contrast. No shadows
Transparent padlock. In-Game asset. 2d. High contrast. No shadows
Chicken jockey character. In-Game asset. 2d. High contrast. No shadows
Reset scores button. In-Game asset. 2d. High contrast. No shadows
Spider jockey unlocked button. In-Game asset. 2d. High contrast. No shadows
Minecraft Steve unlocked button. In-Game asset. 2d. High contrast. No shadows
Piglin unlocked button. In-Game asset. 2d. High contrast. No shadows
Minecraft skeleton unlocked button. In-Game asset. 2d. High contrast. No shadows
Minecraft villager unlocked button. In-Game asset. 2d. High contrast. No shadows
Star. In-Game asset. 2d. High contrast. No shadows
White star. In-Game asset. 2d. High contrast. No shadows
Red heart. In-Game asset. 2d. High contrast. No shadows
Purple heart. In-Game asset. 2d. High contrast. No shadows
A peanut. In-Game asset. 2d. High contrast. No shadows
Cashew nut. In-Game asset. 2d. High contrast. No shadows
Grimace shake. In-Game asset. 2d. High contrast. No shadows
MacDonald's fries. In-Game asset. 2d. High contrast. No shadows
Grimace unlocked button. In-Game asset. 2d. High contrast. No shadows
Michael Jackson unlocked button. In-Game asset. 2d. High contrast. No shadows
John Cena unlocked button. In-Game asset. 2d. High contrast. No shadows
Deez nuts unlocked button. In-Game asset. 2d. High contrast. No shadows
Shooting stars unlocked button. In-Game asset. 2d. High contrast. No shadows
Rick roll unlocked button. In-Game asset. 2d. High contrast. No shadows
Popcorn chicken. In-Game asset. 2d. High contrast. No shadows
Fried chicken drumstick. In-Game asset. 2d. High contrast. No shadows
Amazing digital circus button. In-Game asset. 2d. High contrast. No shadows
Select game mode button. In-Game asset. 2d. High contrast. No shadows
Diamond shaped colourful classic mode button. In-Game asset. 2d. High contrast. No shadows
Diamond shaped colourful mini games button. In-Game asset. 2d. High contrast. No shadows
Same picture in high definition
Diamond shaped colourful button that says sling shot mode. In-Game asset. 2d. High contrast. No shadows
Make picture transparent
Bullet. In-Game asset. 2d. High contrast. No shadows
Start game button. In-Game asset. 2d. High contrast. No shadows
Shooting gallery button. In-Game asset. 2d. High contrast. No shadows
launch
Sound effect
Gamestart
Sound effect
collect
Sound effect
gameMusic
Music
Gamemusic
Sound effect
Bogerk
Sound effect
pop
Sound effect
Pignoise
Sound effect
Steve
Sound effect
Villager
Sound effect
Spider
Sound effect
Skeleton
Sound effect
Shootingstars
Music
Maccas
Sound effect
Grimace
Sound effect
Thriller
Music
MJ
Sound effect
Cenaentrance
Music
Johncena
Sound effect
Chickencluck
Sound effect
Deeznuts
Sound effect
Deeznutstrap
Music
Rickroll
Sound effect
Nevergonna
Music
Starz
Sound effect
Grimaceshake
Music
Joenugget
Sound effect
gegagedi
Music
Shrek
Sound effect
Raveswamp
Music
Pomni
Sound effect
Digcircus
Music
Runandgo
Music
Gunshot
Sound effect