User prompt
Please fix the bug: 'ReferenceError: infiniteLuckyActive is not defined' in or related to this line: 'var questionMarkChance = infiniteLuckyActive ? 1.0 : megaLuckActive ? megaLuckQuestionMarkChance : baseQuestionMarkChance;' Line Number: 106
User prompt
Que el hack 6 de llame "infinite lucky" si esta función se activa todas las posibilidades del juego serán de 100%
User prompt
Haz el menú de hack más ancho
User prompt
Que las 5 nuevas opciones del hackmenú este al lado derecho
User prompt
Que al hayan más opciones en el hackmenú al lado de las primeras 5 opciones "hack6" "hack7" "hack8" "hack9" hack10"
User prompt
Quita el texto de vidas acumuladas
User prompt
Si el jugador tiene vidas acumula y recibe daño se usará la vida hasta que le queden 0 vidas acumuladas, El texto de vidas acumuladas se quedara en el medio hasta que se gasten todas la vidas acumuladas ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Si el jugador tiene toda la vida al máximo y recibe un corazón extra se se mostrará un texto en verde en el medio que dirá "vidas acumuladas x(número de vidas que tenga acumulado)" ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Que no aparezca un cuadrado marrón en la variaciónes de avión
User prompt
Que se incluya a "avin2" como variaciones en el avion
User prompt
Que el avión tenga variaciones de skin con las imágenes "avión2" "avin3" y "avin4"
User prompt
Que el avión tenga variaciones de imágenes "avión2" "avión3" "avión4" la imagen de avión4 tendrá un 20% de aparecer
User prompt
Que la quinta opción del hackmenú se llame "fortuna" y cuando se active el jugador tendra monedas 999 qué no puede subir y si baja después de 1 segundo le jugador trenda 999 monedas devuelta ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Si hay textos en el medio de la pantalla y se usa la tienda o el hackmenú los textos se ocultara
User prompt
Que enves de las opciones de hackmenú sea un recuadro que te indica si una función esta activa o no que sea una imagen que te indica si esta activa la función (esto para poder modicarlo)
User prompt
Que el fondo del menú del hackmenú sea negro
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Airplane = Container.expand(function () {
var self = Container.call(this);
// Select airplane image with avin4 having 20% chance, others equal chance
var airplaneAssets = ['airplane', 'avin2', 'avin3'];
var selectedAsset;
var randomChance = Math.random();
if (randomChance < 0.20) {
// 20% chance for avin4
selectedAsset = 'avin4';
} else {
// 80% chance split equally among the other 3 (26.67% each)
selectedAsset = airplaneAssets[Math.floor(Math.random() * airplaneAssets.length)];
}
var airplaneGraphics = self.attachAsset(selectedAsset, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 3.0
});
self.speed = 6;
self.isVisible = false;
self.targetX = 0;
self.hasDroppedBrick = false;
self.update = function () {
self.x += self.speed;
// Check if airplane reached drop position and hasn't dropped brick yet
if (!self.hasDroppedBrick && self.x >= self.targetX - 50) {
self.hasDroppedBrick = true;
// Question mark drop chance: 50% with mega luck, 5% normal
var baseQuestionMarkChance = 0.05;
var megaLuckQuestionMarkChance = 0.50;
// Apply night mode bonus - increase chances by 10%
if (nightModeActive) {
baseQuestionMarkChance = Math.min(0.15, baseQuestionMarkChance + 0.10);
megaLuckQuestionMarkChance = Math.min(0.60, megaLuckQuestionMarkChance + 0.10);
}
var questionMarkChance = infiniteLuckyActive ? 1.0 : megaLuckActive ? megaLuckQuestionMarkChance : baseQuestionMarkChance;
if (Math.random() < questionMarkChance) {
// Spawn question mark power-up that follows player
var newQuestionMark = new QuestionMarkPowerUp();
newQuestionMark.x = self.x;
newQuestionMark.y = self.y + 50; // Drop below airplane
newQuestionMark.isAirplaneDrop = true; // Mark as airplane drop
newQuestionMark.followsPlayer = true; // Enable player following
questionMarkPowerUps.push(newQuestionMark);
game.addChild(newQuestionMark);
} else {
// Spawn the brick at airplane's position
var newBrick = new Brick();
newBrick.x = self.x;
newBrick.y = self.y + 50; // Drop below airplane
bricks.push(newBrick);
game.addChild(newBrick);
}
}
// Handle hitbox overlay for airplane
if (hitboxActive) {
if (!self.hitboxOverlay) {
self.hitboxOverlay = self.attachAsset('hitbox2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 3.0
});
self.hitboxOverlay.alpha = 0.7;
}
self.hitboxOverlay.visible = true;
} else {
if (self.hitboxOverlay) {
self.hitboxOverlay.visible = false;
}
}
};
return self;
});
var BadOmenPowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('badomen', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.floatOffset = 0;
self.collected = false;
self.update = function () {
self.x -= self.speed;
// Floating animation
self.floatOffset += 0.2;
self.y += Math.sin(self.floatOffset) * 2;
// Dark pulsing animation
powerUpGraphics.alpha = 0.7 + Math.sin(self.floatOffset * 2) * 0.3;
};
return self;
});
var Brick = Container.expand(function () {
var self = Container.call(this);
// Randomly select one of the brick variations
var brickAssets = ['brick2', 'silla', 'roca', 'barril'];
var selectedAsset = brickAssets[Math.floor(Math.random() * brickAssets.length)];
var brickGraphics = self.attachAsset(selectedAsset, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 1.8
});
self.velocityY = 0;
self.gravity = 0.8;
self.hit = false;
self.update = function () {
if (self.isRainbowMissile) {
// Missile behavior - move toward chicken
var deltaX = chicken.x - self.x;
var deltaY = chicken.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 0) {
// Normalize direction and apply speed
self.x += deltaX / distance * self.missileSpeed;
self.y += deltaY / distance * self.missileSpeed;
}
} else if (self.isDeflected && self.targetAirplane) {
// Deflected brick behavior - move toward target airplane
var deltaX = self.targetAirplane.x - self.x;
var deltaY = self.targetAirplane.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 0) {
// Move toward airplane at high speed
var deflectSpeed = 12;
self.x += deltaX / distance * deflectSpeed;
self.y += deltaY / distance * deflectSpeed;
}
} else {
// Normal brick behavior
self.velocityY += self.gravity;
self.y += self.velocityY;
}
// Handle hitbox overlay for brick
if (hitboxActive) {
if (!self.hitboxOverlay) {
self.hitboxOverlay = self.attachAsset('hitbox2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 1.8
});
self.hitboxOverlay.alpha = 0.7;
}
self.hitboxOverlay.visible = true;
} else {
if (self.hitboxOverlay) {
self.hitboxOverlay.visible = false;
}
}
};
return self;
});
var Cactus = Container.expand(function (type) {
var self = Container.call(this);
var assetName = type === 'tall' ? 'tallCactus' : 'smallCactus';
var cactusGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 1.0
});
self.type = type;
self.speed = gameSpeed;
self.passed = false;
self.update = function () {
self.x -= self.speed;
// Handle hitbox overlay for cactus
if (hitboxActive) {
if (!self.hitboxOverlay) {
self.hitboxOverlay = self.attachAsset('hitbox2', {
anchorX: 0.5,
anchorY: 1.0,
width: assetName === 'tallCactus' ? 70 : 114,
height: assetName === 'tallCactus' ? 210 : 200
});
self.hitboxOverlay.alpha = 0.7;
}
self.hitboxOverlay.visible = true;
} else {
if (self.hitboxOverlay) {
self.hitboxOverlay.visible = false;
}
}
};
return self;
});
var CactusParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
// Green color for cactus particles
particleGraphics.tint = 0x00FF00;
self.velocityX = (Math.random() - 0.5) * 12;
self.velocityY = Math.random() * -8 - 3;
self.life = 45;
self.maxLife = 45;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += 0.3; // gravity
self.life--;
// Fade out over time
var alpha = self.life / self.maxLife;
particleGraphics.alpha = alpha;
if (self.life <= 0) {
self.markForDestroy = true;
}
};
return self;
});
var Chicken = Container.expand(function () {
var self = Container.call(this);
var chickenGraphics = self.attachAsset('chicken', {
anchorX: 0.5,
anchorY: 1.0
});
var chickenJumpGraphics = self.attachAsset('chickenjump', {
anchorX: 0.5,
anchorY: 1.0
});
chickenJumpGraphics.visible = false;
var chickenDownGraphics = self.attachAsset('chickendown', {
anchorX: 0.5,
anchorY: 1.0
});
chickenDownGraphics.visible = false;
self.groundY = 2732 - 200;
self.jumpStartY = self.groundY;
self.isJumping = false;
self.jumpVelocity = 0;
self.gravity = 1.2;
self.maxJumpVelocity = -45;
self.jumpChargeTime = 0;
self.isCharging = false;
self.canDoubleJump = false;
self.hasDoubleJumped = false;
self.isDashing = false;
self.dashSpeed = 25;
self.dashDuration = 300; // milliseconds
self.isCrouching = false;
self.update = function () {
// Freeze chicken movement when shop is open
if (isShopGamePaused) return;
// Starbot automatic jumping
if (starbotActive && !self.isJumping) {
// Check if there's a cactus within range that requires jumping
for (var i = 0; i < cacti.length; i++) {
var cactus = cacti[i];
var distanceToCactus = cactus.x - self.x;
// If cactus is close enough and chicken is on ground, auto jump
if (distanceToCactus > 0 && distanceToCactus <= 200 && self.y >= self.groundY - 10) {
self.isCharging = true;
self.jumpChargeTime = 15; // Medium jump power
self.executeJump();
// Schedule second jump for double jump after brief delay
LK.setTimeout(function () {
if (starbotActive && self.isJumping) {
self.executeJump(); // Perform second jump
}
}, 100); // 100ms delay between jumps
break;
}
}
}
if (self.isJumping && !self.isDashing) {
self.y += self.jumpVelocity;
self.jumpVelocity += self.gravity;
if (self.y >= self.groundY) {
self.y = self.groundY;
self.isJumping = false;
self.jumpVelocity = 0;
self.canDoubleJump = false;
self.hasDoubleJumped = false;
tripleJumpUsed = 0;
}
}
if (self.isCharging && self.jumpChargeTime < 30) {
self.jumpChargeTime++;
}
// Starbot brick deflection
if (starbotActive) {
// Check for bricks that are about to hit the chicken's head
for (var i = 0; i < bricks.length; i++) {
var brick = bricks[i];
if (!brick.hit && !brick.isDeflected) {
var distanceX = Math.abs(brick.x - self.x);
var distanceY = Math.abs(brick.y - self.y);
// If brick is close to chicken's head area
if (distanceX <= 50 && distanceY <= 100 && brick.y < self.y) {
// Deflect brick back to airplane
brick.isDeflected = true;
brick.gravity = 0; // Stop falling
brick.velocityY = 0;
// Find the airplane that dropped this brick
for (var j = 0; j < airplanes.length; j++) {
var airplane = airplanes[j];
if (airplane.hasDroppedBrick) {
// Set brick to move toward this airplane
brick.targetAirplane = airplane;
break;
}
}
}
}
}
}
// Switch between normal, jump, and crouch images based on state
if (self.isCrouching) {
// Hide all other graphics
chickenGraphics.visible = false;
chickenJumpGraphics.visible = false;
chickenDownGraphics.visible = true;
} else if (self.isJumping) {
// Hide all other graphics
chickenGraphics.visible = false;
chickenDownGraphics.visible = false;
chickenJumpGraphics.visible = true;
} else {
// Show normal chicken sprite when on ground
chickenJumpGraphics.visible = false;
chickenDownGraphics.visible = false;
chickenGraphics.visible = true;
}
// Handle hitbox overlay for chicken
if (hitboxActive) {
if (!self.hitboxOverlay) {
self.hitboxOverlay = self.attachAsset('hitbox2', {
anchorX: 0.5,
anchorY: 1.0,
width: 200,
height: 227.56
});
self.hitboxOverlay.alpha = 0.7;
}
self.hitboxOverlay.visible = true;
} else {
if (self.hitboxOverlay) {
self.hitboxOverlay.visible = false;
}
}
};
self.startJump = function () {
// Prevent jumping when shop is open
if (isShopGamePaused) return;
if (!self.isJumping) {
self.isCharging = true;
self.jumpChargeTime = 0;
}
};
self.executeJump = function () {
// Prevent jumping when shop is open
if (isShopGamePaused) return;
// Check if bad omen is active and jumps are exhausted
if (hasBadOmen && badOmenJumpsRemaining <= 0) return;
if (!self.isJumping && self.isCharging) {
var jumpPower = Math.min(self.jumpChargeTime / 30, 1);
self.jumpVelocity = self.maxJumpVelocity * (0.4 + jumpPower * 0.6);
self.isJumping = true;
self.isCharging = false;
self.jumpChargeTime = 0;
self.canDoubleJump = true;
LK.getSound('jump').play();
// Decrease bad omen jumps if active
if (hasBadOmen) {
badOmenJumpsRemaining--;
badOmenJumpsText.setText('Jumps: ' + badOmenJumpsRemaining);
if (badOmenJumpsRemaining <= 0) {
// Game over when jumps run out
LK.effects.flashScreen(0x8B0000, 800);
LK.setTimeout(function () {
LK.showGameOver();
}, 400);
}
}
} else if (self.isJumping && (self.canDoubleJump && !self.hasDoubleJumped || unlimitedJumpsActive)) {
// Check bad omen jumps for double jump
if (hasBadOmen && badOmenJumpsRemaining <= 0 && !unlimitedJumpsActive) return;
// Double jump or unlimited jumps
self.jumpVelocity = self.maxJumpVelocity * 0.8;
if (!unlimitedJumpsActive) {
self.hasDoubleJumped = true;
if (!tripleJumpActive) {
self.canDoubleJump = false;
}
tripleJumpUsed++;
}
LK.getSound('jump').play();
// Decrease bad omen jumps if active
if (hasBadOmen && !unlimitedJumpsActive) {
badOmenJumpsRemaining--;
badOmenJumpsText.setText('Jumps: ' + badOmenJumpsRemaining);
if (badOmenJumpsRemaining <= 0) {
// Game over when jumps run out
LK.effects.flashScreen(0x8B0000, 800);
LK.setTimeout(function () {
LK.showGameOver();
}, 400);
}
}
// Create particles below chicken's feet
for (var i = 0; i < 8; i++) {
var particle = new Particle();
particle.x = self.x + (Math.random() - 0.5) * 40;
particle.y = self.y + 30; // Below chicken's feet
particles.push(particle);
game.addChild(particle);
}
} else if (self.isJumping && tripleJumpActive && tripleJumpUsed < 2 && !unlimitedJumpsActive) {
// Check bad omen jumps for triple jump
if (hasBadOmen && badOmenJumpsRemaining <= 0) return;
// Triple jump (third jump)
self.jumpVelocity = self.maxJumpVelocity * 0.7;
tripleJumpUsed++;
if (!achievements.tripleJumps) achievements.tripleJumps = 0;
achievements.tripleJumps++;
if (tripleJumpUsed >= 2) {
self.canDoubleJump = false;
}
LK.getSound('jump').play();
// Decrease bad omen jumps if active
if (hasBadOmen) {
badOmenJumpsRemaining--;
badOmenJumpsText.setText('Jumps: ' + badOmenJumpsRemaining);
if (badOmenJumpsRemaining <= 0) {
// Game over when jumps run out
LK.effects.flashScreen(0x8B0000, 800);
LK.setTimeout(function () {
LK.showGameOver();
}, 400);
}
}
// Create special particles for triple jump
for (var i = 0; i < 12; i++) {
var particle = new Particle();
particle.x = self.x + (Math.random() - 0.5) * 60;
particle.y = self.y + 30;
particles.push(particle);
game.addChild(particle);
}
}
};
self.startDash = function () {
// Dash functionality disabled
};
self.startCrouch = function () {
// Prevent crouching when shop is open or jumping
if (isShopGamePaused || self.isJumping) return;
self.isCrouching = true;
};
self.stopCrouch = function () {
self.isCrouching = false;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
});
cloudGraphics.alpha = 0.7;
cloudGraphics.scaleX = 4.4;
cloudGraphics.scaleY = 4.4;
self.speed = 1;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var HackMenu = Container.expand(function () {
var self = Container.call(this);
// Pause the game when hack menu opens
isShopGamePaused = true;
// Semi-transparent background
var background = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 1800,
height: 900,
color: 0x000000
});
background.alpha = 0.9;
background.tint = 0x000000; // Ensure background is black
// Create hack buttons
var hack1Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack1Button.y = -300;
var hack2Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack2Button.y = -150;
var hack3Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack3Button.y = 0;
var hack4Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack4Button.y = 150;
var hack5Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack5Button.y = 300;
var hack6Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack6Button.x = 500;
hack6Button.y = -300;
var hack7Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack7Button.x = 500;
hack7Button.y = -150;
var hack8Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack8Button.x = 500;
hack8Button.y = 0;
var hack9Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack9Button.x = 500;
hack9Button.y = 150;
var hack10Button = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 450,
height: 90,
color: 0x444444
});
hack10Button.x = 500;
hack10Button.y = 300;
// Button texts and status indicators
var hack1Text = new Text2('God Mode', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack1Text.anchor.set(0.5, 0.5);
hack1Text.x = -100; // Position text to the left
hack1Button.addChild(hack1Text);
var hack1StatusRect = hack1Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack1StatusRect.x = 150; // Position rectangle to the right
var hack2Text = new Text2('Mega Suerte', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack2Text.anchor.set(0.5, 0.5);
hack2Text.x = -100; // Position text to the left
hack2Button.addChild(hack2Text);
var hack2StatusRect = hack2Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack2StatusRect.x = 150; // Position rectangle to the right
var hack3Text = new Text2('starbot', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack3Text.anchor.set(0.5, 0.5);
hack3Text.x = -100; // Position text to the left
hack3Button.addChild(hack3Text);
var hack3StatusRect = hack3Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack3StatusRect.x = 150; // Position rectangle to the right
var hack4Text = new Text2('hitbox', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack4Text.anchor.set(0.5, 0.5);
hack4Text.x = -100; // Position text to the left
hack4Button.addChild(hack4Text);
var hack4StatusRect = hack4Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack4StatusRect.x = 150; // Position rectangle to the right
var hack5Text = new Text2('fortuna', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack5Text.anchor.set(0.5, 0.5);
hack5Text.x = -100; // Position text to the left
hack5Button.addChild(hack5Text);
var hack5StatusRect = hack5Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack5StatusRect.x = 150; // Position rectangle to the right
var hack6Text = new Text2('infinite lucky', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack6Text.anchor.set(0.5, 0.5);
hack6Text.x = -100; // Position text to the left
hack6Button.addChild(hack6Text);
var hack6StatusRect = hack6Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack6StatusRect.x = 150; // Position rectangle to the right
var hack7Text = new Text2('hack7', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack7Text.anchor.set(0.5, 0.5);
hack7Text.x = -100; // Position text to the left
hack7Button.addChild(hack7Text);
var hack7StatusRect = hack7Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack7StatusRect.x = 150; // Position rectangle to the right
var hack8Text = new Text2('hack8', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack8Text.anchor.set(0.5, 0.5);
hack8Text.x = -100; // Position text to the left
hack8Button.addChild(hack8Text);
var hack8StatusRect = hack8Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack8StatusRect.x = 150; // Position rectangle to the right
var hack9Text = new Text2('hack9', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack9Text.anchor.set(0.5, 0.5);
hack9Text.x = -100; // Position text to the left
hack9Button.addChild(hack9Text);
var hack9StatusRect = hack9Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack9StatusRect.x = 150; // Position rectangle to the right
var hack10Text = new Text2('hack10', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hack10Text.anchor.set(0.5, 0.5);
hack10Text.x = -100; // Position text to the left
hack10Button.addChild(hack10Text);
var hack10StatusRect = hack10Button.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 40,
color: 0xff0000
});
hack10StatusRect.x = 150; // Position rectangle to the right
// Initialize button states from storage
var hack1Active = godModeActive;
var hack2Active = megaLuckActive;
var hack3Active = storage.hack3Active || false;
var hack4Active = storage.hack4Active || false;
var hack5Active = storage.hack5Active || false;
var hack6Active = storage.hack6Active || false;
var infiniteLuckyActive = storage.hack6Active || false;
var hack7Active = storage.hack7Active || false;
var hack8Active = storage.hack8Active || false;
var hack9Active = storage.hack9Active || false;
var hack10Active = storage.hack10Active || false;
// Update button appearance based on stored states
hack1StatusRect.tint = hack1Active ? 0x00FF00 : 0xff0000;
hack2StatusRect.tint = hack2Active ? 0x00FF00 : 0xff0000;
hack3StatusRect.tint = hack3Active ? 0x00FF00 : 0xff0000;
hack4StatusRect.tint = hack4Active ? 0x00FF00 : 0xff0000;
hack5StatusRect.tint = hack5Active ? 0x00FF00 : 0xff0000;
hack6StatusRect.tint = hack6Active ? 0x00FF00 : 0xff0000;
hack7StatusRect.tint = hack7Active ? 0x00FF00 : 0xff0000;
hack8StatusRect.tint = hack8Active ? 0x00FF00 : 0xff0000;
hack9StatusRect.tint = hack9Active ? 0x00FF00 : 0xff0000;
hack10StatusRect.tint = hack10Active ? 0x00FF00 : 0xff0000;
// Button functionality
hack1Button.down = function (x, y, obj) {
hack1Active = !hack1Active;
godModeActive = hack1Active; // Set global god mode state
storage.godModeActive = hack1Active; // Save to storage
// Deactivate god mode effects when turned off
if (!hack1Active) {
isInvincible = false;
invincibilityTimer = 0;
powerUpTimerText.visible = false;
// Reset chicken appearance if it was in god mode
if (chicken.tint !== 0xFFFFFF) {
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
}
hack1StatusRect.tint = hack1Active ? 0x00FF00 : 0xff0000;
};
hack2Button.down = function (x, y, obj) {
hack2Active = !hack2Active;
megaLuckActive = hack2Active; // Set global mega luck state
storage.megaLuckActive = hack2Active; // Save to storage
// No specific deactivation needed for mega luck as it only affects spawn chances
hack2StatusRect.tint = hack2Active ? 0x00FF00 : 0xff0000;
};
hack3Button.down = function (x, y, obj) {
hack3Active = !hack3Active;
starbotActive = hack3Active; // Set global starbot state
storage.hack3Active = hack3Active; // Save to storage
// Add deactivation logic when hack3 is turned off
if (!hack3Active) {
// Reset any hack3 related effects here when implemented
}
hack3StatusRect.tint = hack3Active ? 0x00FF00 : 0xff0000;
};
hack4Button.down = function (x, y, obj) {
hack4Active = !hack4Active;
hitboxActive = hack4Active; // Set global hitbox state
storage.hack4Active = hack4Active; // Save to storage
// Add deactivation logic when hack4 is turned off
if (!hack4Active) {
// Reset any hack4 related effects here when implemented
}
hack4StatusRect.tint = hack4Active ? 0x00FF00 : 0xff0000;
};
hack5Button.down = function (x, y, obj) {
hack5Active = !hack5Active;
fortunaActive = hack5Active; // Set global fortuna state
storage.hack5Active = hack5Active; // Save to storage
// Activate fortuna - set coins to 999
if (hack5Active) {
playerCoins = 999;
coinText.setText(playerCoins.toString());
fortunaTimer = 0;
} else {
// Deactivate fortuna - no special reset needed
fortunaTimer = 0;
}
hack5StatusRect.tint = hack5Active ? 0x00FF00 : 0xff0000;
};
hack6Button.down = function (x, y, obj) {
hack6Active = !hack6Active;
infiniteLuckyActive = hack6Active; // Set global infinite lucky state
storage.hack6Active = hack6Active; // Save to storage
// No specific deactivation needed for infinite lucky as it only affects chances
hack6StatusRect.tint = hack6Active ? 0x00FF00 : 0xff0000;
};
hack7Button.down = function (x, y, obj) {
hack7Active = !hack7Active;
storage.hack7Active = hack7Active; // Save to storage
// Add hack7 functionality here when implemented
hack7StatusRect.tint = hack7Active ? 0x00FF00 : 0xff0000;
};
hack8Button.down = function (x, y, obj) {
hack8Active = !hack8Active;
storage.hack8Active = hack8Active; // Save to storage
// Add hack8 functionality here when implemented
hack8StatusRect.tint = hack8Active ? 0x00FF00 : 0xff0000;
};
hack9Button.down = function (x, y, obj) {
hack9Active = !hack9Active;
storage.hack9Active = hack9Active; // Save to storage
// Add hack9 functionality here when implemented
hack9StatusRect.tint = hack9Active ? 0x00FF00 : 0xff0000;
};
hack10Button.down = function (x, y, obj) {
hack10Active = !hack10Active;
storage.hack10Active = hack10Active; // Save to storage
// Add hack10 functionality here when implemented
hack10StatusRect.tint = hack10Active ? 0x00FF00 : 0xff0000;
};
// Create X close button
var xButton = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 80,
color: 0xff0000
});
xButton.x = 550; // Position at top right of menu
xButton.y = -400; // Top of menu
// Add X text to button
var xText = new Text2('X', {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
xText.anchor.set(0.5, 0.5);
xButton.addChild(xText);
// X button functionality
xButton.down = function (x, y, obj) {
self.close();
};
// Close function
self.close = function () {
isShopGamePaused = false;
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
isHackMenuOpen = false;
}
});
};
// Close when clicking background
background.down = function (x, y, obj) {
self.close();
};
// Animate menu opening
self.alpha = 0;
self.scaleX = 0.5;
self.scaleY = 0.5;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = (Math.random() - 0.5) * 8;
self.velocityY = Math.random() * -4 - 2;
self.life = 30;
self.maxLife = 30;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += 0.2; // gravity
self.life--;
// Fade out over time
var alpha = self.life / self.maxLife;
particleGraphics.alpha = alpha;
if (self.life <= 0) {
self.markForDestroy = true;
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.floatOffset = 0;
self.collected = false;
self.update = function () {
self.x -= self.speed;
// Floating animation
self.floatOffset += 0.2;
self.y += Math.sin(self.floatOffset) * 2;
};
return self;
});
var QuestionMarkPowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('questionMark', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.floatOffset = 0;
self.collected = false;
self.update = function () {
if (self.followsPlayer) {
// Follow player behavior - move toward chicken
var deltaX = chicken.x - self.x;
var deltaY = chicken.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 100) {
// Only follow if not too close
// Normalize direction and apply following speed
var followSpeed = 3;
self.x += deltaX / distance * followSpeed;
self.y += deltaY / distance * followSpeed;
}
} else {
// Normal behavior for regular spawned question marks
self.x -= self.speed;
}
// Floating animation
self.floatOffset += 0.3;
self.y += Math.sin(self.floatOffset) * 3;
// Rotating animation
powerUpGraphics.rotation += 0.1;
};
return self;
});
var Shop = Container.expand(function () {
var self = Container.call(this);
// Pause the game when shop opens
isShopGamePaused = true;
// Semi-transparent background
var background = self.attachAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 600,
height: 800,
color: 0x000000
});
background.alpha = 0.8;
// Buy button (top)
var buyButton = self.attachAsset('compra', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 150
});
buyButton.y = -200;
self.addChild(buyButton);
// Heart store image next to buy button
var heartStoreImage = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
heartStoreImage.x = 250; // Position to the right of buy button
heartStoreImage.y = -200; // Same Y position as buy button
self.addChild(heartStoreImage);
// Exit button (bottom)
var exitButton = self.attachAsset('salir', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 150
});
exitButton.y = 200;
self.addChild(exitButton);
// Button functionality
buyButton.down = function (x, y, obj) {
// Check if player has enough coins
if (playerCoins >= 5) {
// Deduct 5 coins
playerCoins -= 5;
coinText.setText(playerCoins.toString());
// Give chicken an extra life
if (chickenLives < 10) {
chickenLives++;
// Add new heart to display
var newHeart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Position hearts in rows when more than 4
var heartIndex = chickenLives - 1;
var row = Math.floor(heartIndex / 4);
var col = heartIndex % 4;
newHeart.x = 250 + col * 75;
newHeart.y = 70 + row * 75;
newHeart.scaleX = 0;
newHeart.scaleY = 0;
newHeart.alpha = 0;
lifeDisplays.push(newHeart);
LK.gui.topLeft.addChild(newHeart);
// Animate heart appearing
tween(newHeart, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.bounceOut
});
}
// Show extra life message
showExtraLifeMessage();
// Buy functionality - close shop
LK.getSound('purchase').play();
self.close();
} else {
// Not enough coins - show error message and close shop
var errorMessages = ["no puedes comprar este objeto", "No Fiamos wacho"];
var selectedMessage = errorMessages[Math.floor(Math.random() * 2)];
LK.getSound('error').play();
// Create error message text
var errorText = new Text2(selectedMessage, {
size: 60,
fill: 0xFF0000,
// Red color
stroke: 0x000000,
strokeThickness: 3
});
errorText.anchor.set(0.5, 0.5);
errorText.x = 0;
errorText.y = -350; // Above the shop
errorText.alpha = 0;
self.addChild(errorText);
// Animate error message
tween(errorText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Wait then fade out
LK.setTimeout(function () {
tween(errorText, {
alpha: 0,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 300,
onFinish: function onFinish() {
// Close shop after error message
self.close();
}
});
}, 1500);
}
});
}
};
exitButton.down = function (x, y, obj) {
// Exit shop
self.close();
};
self.close = function () {
// Resume the game when shop closes
isShopGamePaused = false;
// Animate shop closing
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
isShopOpen = false;
}
});
};
// Animate shop opening
self.alpha = 0;
self.scaleX = 0.5;
self.scaleY = 0.5;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
return self;
});
var SuperTallCactus = Container.expand(function () {
var self = Container.call(this);
var cactusGraphics = self.attachAsset('superTallCactus', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 4.5,
scaleY: 4.5
});
self.type = 'superTall';
self.speed = gameSpeed;
self.passed = false;
self.tripleJumpActivated = false;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var TrailParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('trailParticle', {
anchorX: 0.5,
anchorY: 0.5
});
// Random color for trail particles
var colors = [0xff4500, 0xff6347, 0xffd700, 0xff1493, 0x00ff00, 0x00bfff];
particleGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
self.velocityX = (Math.random() - 0.5) * 6;
self.velocityY = Math.random() * -3 - 1;
self.life = 40;
self.maxLife = 40;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += 0.15; // gravity
self.life--;
// Fade out over time
var alpha = self.life / self.maxLife;
particleGraphics.alpha = alpha;
if (self.life <= 0) {
self.markForDestroy = true;
}
};
return self;
});
var Water = Container.expand(function () {
var self = Container.call(this);
var waterGraphics = self.attachAsset('water', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.floatOffset = 0;
self.collected = false;
self.update = function () {
self.x -= self.speed;
// Floating animation
self.floatOffset += 0.3;
self.y += Math.sin(self.floatOffset) * 3;
};
return self;
});
var Wings = Container.expand(function () {
var self = Container.call(this);
var wingsGraphics = self.attachAsset('alas', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.floatOffset = 0;
self.collected = false;
self.update = function () {
self.x -= self.speed;
// Floating animation
self.floatOffset += 0.2;
self.y += Math.sin(self.floatOffset) * 2;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var gameSpeed = 8;
var godModeActive = storage.godModeActive || false;
var megaLuckActive = storage.megaLuckActive || false;
var infiniteLuckyActive = storage.hack6Active || false;
var hack3Active = storage.hack3Active || false;
var hack4Active = storage.hack4Active || false;
var hack5Active = storage.hack5Active || false;
var fortunaActive = storage.hack5Active || false;
var fortunaTimer = 0;
var starbotActive = storage.hack3Active || false;
var hitboxActive = storage.hack4Active || false;
// Achievement system variables
var achievements = storage.achievements || {};
var achievementNotifications = [];
var maxGameSpeed = 20;
var speedIncrement = 0.02;
// Night mode initialization with 30% chance
var nightModeStartChance = Math.random();
var isNightTime = nightModeStartChance < 0.30;
var nightModeActive = isNightTime; // Track if we started in night mode
var nightTimer = 0;
var nightDuration = 3000; // 50 seconds at 60fps
var dayBackground;
var nightBackground;
var cactusSpawnTimer = 0;
var cactusSpawnInterval = 90;
var minSpawnInterval = 45;
var cloudSpawnTimer = 0;
var distanceTraveled = 0;
var lastScoreSound = 0;
var jumpScore = 0;
var scoreTimer = 0; // Timer for automatic scoring every second
var chicken;
var chickenLives = 3;
var lifeDisplays = [];
var playerCoins = 0;
var lastCoinScore = 0;
var cacti = [];
var clouds = [];
var powerUps = [];
var particles = [];
var trailParticles = [];
var bricks = [];
var airplanes = [];
var cactusParticles = [];
var waters = [];
var wings = [];
var questionMarkPowerUps = [];
var badOmenPowerUps = [];
var hasBadOmen = false;
var badOmenJumpsRemaining = 0;
var badOmenSpawnedAtStart = false;
var badOmenSpawnedAt100 = false;
var hasWings = false;
var unlimitedJumpsActive = false;
var unlimitedJumpsTimer = 0;
var unlimitedJumpsDuration = 1740; // 29 seconds at 60fps
var brickSpawnTimer = 0;
var brickSpawnInterval = 600; // 10 seconds at 60fps (10 * 60 = 600 frames)
var ground;
var isGameRunning = true;
var isShopOpen = false;
var isShopGamePaused = false;
var isHackMenuOpen = false;
var shopSpawnTimer = 0;
var shopSpawnInterval = 1800 + Math.random() * 1800; // Random 30-60 seconds at 60fps
var isJumpPressed = false;
var tapCount = 0;
var lastTapTime = 0;
var doubleTapThreshold = 300; // milliseconds for double tap detection
var touchStartY = 0;
var isTouchDown = false;
var swipeThreshold = 100; // Minimum distance for swipe detection
var dashCooldown = 0; // Timer for dash cooldown
var dashCooldownDuration = 600; // 10 seconds at 60fps (10 * 60 = 600 frames)
var hasSuperTallCactusSpawned = false;
var tripleJumpActive = false;
var tripleJumpUsed = 0;
var tripleJumpTimer = 0;
var tripleJumpDuration = 4140; // 69 seconds at 60fps (69 * 60 = 4140 frames)
// Power-up system
var powerUpSpawnTimer = 0;
var powerUpSpawnInterval = 1200 + Math.random() * 1200; // Random 20-40 seconds at 60fps
var isInvincible = false;
var invincibilityTimer = 0;
var invincibilityDuration = 120; // 2 seconds at 60fps
var baseGameSpeed = 8;
// Pause system
var isPaused = false;
var pauseButton;
// Create day and night backgrounds
dayBackground = game.addChild(LK.getAsset('dayBackground', {
anchorX: 0,
anchorY: 0
}));
dayBackground.x = 0;
dayBackground.y = 0;
nightBackground = game.addChild(LK.getAsset('nightBackground', {
anchorX: 0,
anchorY: 0
}));
nightBackground.x = 0;
nightBackground.y = 0;
nightBackground.visible = isNightTime;
// Set day background visibility opposite to night
dayBackground.visible = !isNightTime;
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1.0
}));
ground.x = 0;
ground.y = 2732 - 20;
// Create chicken
chicken = game.addChild(new Chicken());
chicken.x = 300;
chicken.y = chicken.groundY;
// Camera system variables (disabled)
var cameraX = 0;
var cameraY = 0;
var cameraFollowSpeed = 0.1;
var cameraZoom = 1; // Normal zoom - no zoom applied
var targetCameraX = 0;
var targetCameraY = 0;
// Apply normal camera zoom (no zoom)
game.scale.set(cameraZoom);
// Create life display hearts beside pause button
for (var i = 0; i < chickenLives; i++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Position hearts in rows when more than 4
var row = Math.floor(i / 4);
var col = i % 4;
heart.x = 250 + col * 75; // Larger spacing for bigger hearts
heart.y = 70 + row * 75; // Stack in rows
lifeDisplays.push(heart);
LK.gui.topLeft.addChild(heart);
}
// Create coin display below hearts
var coinIcon = LK.getAsset('coins', {
anchorX: 0.5,
anchorY: 0.5
});
coinIcon.x = 250; // Align with hearts
coinIcon.y = 120; // Below hearts
LK.gui.topLeft.addChild(coinIcon);
var coinText = new Text2('0', {
size: 80,
fill: 0xFFD700,
// Gold color
stroke: 0x000000,
strokeThickness: 3
});
coinText.anchor.set(0, 0.5);
coinText.x = 280; // Next to coin icon
coinText.y = 120; // Align with coin icon
LK.gui.topLeft.addChild(coinText);
// Score display for cactus jumps
var jumpScoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
jumpScoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(jumpScoreText);
jumpScoreText.y = 20;
// High score display next to current score
var highScoreText = new Text2('Best: ' + (storage.highScore || 0), {
size: 60,
fill: 0xFFD700,
stroke: 0x000000,
strokeThickness: 3
});
highScoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(highScoreText);
highScoreText.y = 90;
// Tap counter display
var tapCountText = new Text2('CP: 0', {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
tapCountText.anchor.set(0.5, 0);
LK.gui.top.addChild(tapCountText);
tapCountText.y = 160;
// Distance display
var scoreText = new Text2('Distance: 0m', {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -20;
scoreText.y = 20;
// Instructions
var instructionText = new Text2('TAP & HOLD TO JUMP HIGHER', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
instructionText.anchor.set(0.5, 0);
LK.gui.top.addChild(instructionText);
instructionText.y = 230;
// Power-up timer display
var powerUpTimerText = new Text2('', {
size: 80,
fill: 0xFFFF00,
// Yellow color
stroke: 0x000000,
strokeThickness: 4
});
powerUpTimerText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(powerUpTimerText);
powerUpTimerText.visible = false;
// Triple jump display
var tripleJumpText = new Text2('TRIPLE JUMP ACTIVE!', {
size: 70,
fill: 0x00FF00,
// Green color
stroke: 0x000000,
strokeThickness: 4
});
tripleJumpText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tripleJumpText);
tripleJumpText.visible = false;
tripleJumpText.y = -100; // Position above center
// Triple jump timer display (below pause button)
var tripleJumpTimerText = new Text2('', {
size: 50,
fill: 0x00FF00,
// Green color
stroke: 0x000000,
strokeThickness: 3
});
tripleJumpTimerText.anchor.set(0, 0);
LK.gui.topLeft.addChild(tripleJumpTimerText);
tripleJumpTimerText.x = 120; // Align with pause button
tripleJumpTimerText.y = 140; // Below pause button
tripleJumpTimerText.visible = false;
// Extra life message display
var extraLifeText = new Text2('Vida Extra +1', {
size: 80,
fill: 0x00FF00,
// Green color
stroke: 0x000000,
strokeThickness: 4
});
extraLifeText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(extraLifeText);
extraLifeText.visible = false;
// Unlimited jumps display
var unlimitedJumpsText = new Text2('UNLIMITED JUMPS!', {
size: 70,
fill: 0x00FFFF,
// Cyan color
stroke: 0x000000,
strokeThickness: 4
});
unlimitedJumpsText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(unlimitedJumpsText);
unlimitedJumpsText.visible = false;
unlimitedJumpsText.y = -200; // Position above center
// Unlimited jumps timer display
var unlimitedJumpsTimerText = new Text2('', {
size: 50,
fill: 0x00FFFF,
// Cyan color
stroke: 0x000000,
strokeThickness: 3
});
unlimitedJumpsTimerText.anchor.set(0, 0);
LK.gui.topLeft.addChild(unlimitedJumpsTimerText);
unlimitedJumpsTimerText.x = 120;
unlimitedJumpsTimerText.y = 200; // Below other timers
unlimitedJumpsTimerText.visible = false;
// Bad omen jumps remaining display (center of screen)
var badOmenJumpsText = new Text2('', {
size: 80,
fill: 0x8B0000,
// Dark red color
stroke: 0x000000,
strokeThickness: 4
});
badOmenJumpsText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(badOmenJumpsText);
badOmenJumpsText.visible = false;
// Achievement notification display
var achievementNotificationPanel = LK.getAsset('pauseButton', {
anchorX: 0,
anchorY: 0,
width: 600,
height: 80,
color: 0x000000
});
achievementNotificationPanel.alpha = 0.8;
achievementNotificationPanel.x = 2048; // Start off-screen right
achievementNotificationPanel.y = 20;
LK.gui.topRight.addChild(achievementNotificationPanel);
achievementNotificationPanel.visible = false;
var achievementText = new Text2('', {
size: 40,
fill: 0xFF69B4,
stroke: 0x000000,
strokeThickness: 3
});
achievementText.anchor.set(0.5, 0.5);
achievementText.x = 300; // Center of panel
achievementText.y = 40; // Center of panel
achievementNotificationPanel.addChild(achievementText);
// Create pause button in top left (avoiding the 100x100 platform menu area)
pauseButton = LK.getAsset('pauseButton', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(pauseButton);
pauseButton.x = 120; // Offset from very top left to avoid platform menu
pauseButton.y = 20;
// Add pause symbol (two vertical lines)
var pauseLine1 = LK.getAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 8,
height: 40,
color: 0xffffff
});
var pauseLine2 = LK.getAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 8,
height: 40,
color: 0xffffff
});
pauseButton.addChild(pauseLine1);
pauseButton.addChild(pauseLine2);
pauseLine1.x = 25;
pauseLine1.y = 40;
pauseLine2.x = 55;
pauseLine2.y = 40;
// Create shop button
var shopButton = LK.getAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
LK.gui.topLeft.addChild(shopButton);
shopButton.x = 300; // Position below coins
shopButton.y = 220; // Position below coin display
// Add "SHOP" text to button
var shopButtonText = new Text2('SHOP', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
shopButtonText.anchor.set(0.5, 0.5);
shopButton.addChild(shopButtonText);
// Shop button functionality
shopButton.down = function (x, y, obj) {
if (!isShopOpen && isGameRunning && !isShopGamePaused) {
// Open shop
var newShop = new Shop();
newShop.x = 2048 / 2; // Center of screen
newShop.y = 2732 / 2; // Center of screen
game.addChild(newShop);
isShopOpen = true;
}
};
// Create hack button
var hackButton = LK.getAsset('hackButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
LK.gui.topRight.addChild(hackButton);
hackButton.x = -120; // Position from right edge
hackButton.y = 100; // Position below score display
// Add "HACK" text to button
var hackButtonText = new Text2('HACK', {
size: 40,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
hackButtonText.anchor.set(0.5, 0.5);
hackButton.addChild(hackButtonText);
// Hack button functionality
hackButton.down = function (x, y, obj) {
if (!isHackMenuOpen && isGameRunning && !isShopGamePaused) {
// Open hack menu
var newHackMenu = new HackMenu();
newHackMenu.x = 2048 / 2; // Center of screen
newHackMenu.y = 2732 / 2; // Center of screen
game.addChild(newHackMenu);
isHackMenuOpen = true;
}
};
// Variable to store play triangle reference
var playTriangle = null;
// Pause button functionality
pauseButton.down = function (x, y, obj) {
isPaused = !isPaused;
if (isPaused) {
// Show paused state - make lines into play triangle
pauseLine1.visible = false;
pauseLine2.visible = false;
// Create play triangle
playTriangle = LK.getAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5,
width: 0,
height: 0,
color: 0xffffff
});
pauseButton.addChild(playTriangle);
playTriangle.x = 45;
playTriangle.y = 40;
// Create triangle using three lines (simple approach)
var tri1 = LK.getAsset('pauseButton', {
width: 30,
height: 4,
color: 0xffffff,
anchorX: 0,
anchorY: 0.5
});
var tri2 = LK.getAsset('pauseButton', {
width: 30,
height: 4,
color: 0xffffff,
anchorX: 0,
anchorY: 0.5
});
var tri3 = LK.getAsset('pauseButton', {
width: 30,
height: 4,
color: 0xffffff,
anchorX: 0,
anchorY: 0.5
});
playTriangle.addChild(tri1);
playTriangle.addChild(tri2);
playTriangle.addChild(tri3);
tri1.x = -15;
tri1.y = -15;
tri1.rotation = 0.5;
tri2.x = -15;
tri2.y = 15;
tri2.rotation = -0.5;
tri3.x = -15;
tri3.y = 0;
tri3.rotation = 0;
} else {
// Show pause state - remove play triangle and show pause lines
if (playTriangle) {
pauseButton.removeChild(playTriangle);
playTriangle = null;
}
pauseLine1.visible = true;
pauseLine2.visible = true;
}
};
// Game controls
game.down = function (x, y, obj) {
if (isGameRunning && !isShopGamePaused) {
// Track touch start position for swipe detection
touchStartY = y;
isTouchDown = true;
// Single tap - start jump
isJumpPressed = true;
chicken.startJump();
tapCount++;
tapCountText.setText('CP: ' + tapCount);
// Place recuadro image at touch position
var recuadroImage = LK.getAsset('recuadro', {
anchorX: 0.5,
anchorY: 0.5
});
recuadroImage.x = x;
recuadroImage.y = y;
recuadroImage.alpha = 0.7;
game.addChild(recuadroImage);
// Animate and fade out the recuadro
tween(recuadroImage, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
recuadroImage.destroy();
}
});
}
};
game.move = function (x, y, obj) {
if (isGameRunning && !isShopGamePaused && isTouchDown) {
// Check for downward swipe
var swipeDistance = y - touchStartY;
if (swipeDistance > swipeThreshold && !chicken.isJumping) {
// Downward swipe detected - start crouching
chicken.startCrouch();
}
}
};
game.up = function (x, y, obj) {
if (isGameRunning && !isShopGamePaused) {
isTouchDown = false;
// Check for swipe on release
var swipeDistance = y - touchStartY;
if (swipeDistance > swipeThreshold && !chicken.isJumping) {
// Stop crouching after swipe
chicken.stopCrouch();
} else if (isJumpPressed) {
// Regular jump
isJumpPressed = false;
chicken.executeJump();
}
}
};
function spawnCactus() {
// Only spawn if no cacti are currently visible on screen
if (cacti.length > 0) {
return; // Don't spawn if there's already a cactus
}
var spawnX = 2048 + 100;
// Check if super tall cactus should spawn (random chance and hasn't spawned yet)
if (!hasSuperTallCactusSpawned && Math.random() < 0.02 && jumpScore > 20) {
// Spawn super tall cactus
var newSuperCactus = new SuperTallCactus();
newSuperCactus.x = spawnX;
newSuperCactus.y = 2732 - 200;
newSuperCactus.speed = gameSpeed;
cacti.push(newSuperCactus);
game.addChild(newSuperCactus);
hasSuperTallCactusSpawned = true;
// Activate triple jump for 69 seconds when super cactus appears
tripleJumpActive = true;
tripleJumpTimer = 0;
achievements.tripleJumpUsed = true;
tripleJumpText.visible = true;
tripleJumpTimerText.visible = true;
// Flash screen to indicate special event
LK.effects.flashScreen(0x00FF00, 500);
// Play background music
LK.playMusic('Japan1');
// Add glow effect to chicken
tween(chicken, {
tint: 0x00FF00
}, {
duration: 500,
onFinish: function onFinish() {
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
});
} else {
// Normal cactus spawning
var cactusType = Math.random() < 0.6 ? 'small' : 'tall';
var newCactus = new Cactus(cactusType);
newCactus.x = spawnX;
newCactus.y = 2732 - 200;
newCactus.speed = gameSpeed;
cacti.push(newCactus);
game.addChild(newCactus);
}
}
function spawnCloud() {
var newCloud = new Cloud();
newCloud.x = 2048 + 200;
newCloud.y = 200 + Math.random() * 400;
clouds.push(newCloud);
game.addChild(newCloud);
}
function spawnPowerUp() {
var newPowerUp = new PowerUp();
newPowerUp.x = 2048 + 100;
newPowerUp.y = 2732 - 400 - Math.random() * 200; // Spawn in air
newPowerUp.speed = gameSpeed;
powerUps.push(newPowerUp);
game.addChild(newPowerUp);
}
function spawnBrick() {
var newAirplane = new Airplane();
newAirplane.x = -150; // Start off-screen left
newAirplane.y = 300 + Math.random() * 200; // Random height in sky
newAirplane.targetX = 200 + Math.random() * 1648; // Random drop position
airplanes.push(newAirplane);
game.addChild(newAirplane);
// Add slight bobbing animation to airplane
tween(newAirplane, {
y: newAirplane.y + 20
}, {
duration: 2000,
easing: tween.easeInOut
});
}
function spawnWings() {
var newWings = new Wings();
newWings.x = 2048 + 100;
newWings.y = 2732 - 400 - Math.random() * 200; // Spawn in air
newWings.speed = gameSpeed;
wings.push(newWings);
game.addChild(newWings);
}
function spawnQuestionMarkPowerUp() {
var newQuestionMark = new QuestionMarkPowerUp();
newQuestionMark.x = 2048 + 100;
newQuestionMark.y = 2732 - 400 - Math.random() * 200; // Spawn in air
newQuestionMark.speed = gameSpeed;
questionMarkPowerUps.push(newQuestionMark);
game.addChild(newQuestionMark);
}
function spawnBadOmenPowerUp() {
var newBadOmen = new BadOmenPowerUp();
newBadOmen.x = 2048 + 100;
newBadOmen.y = 2732 - 400 - Math.random() * 200; // Spawn in air
newBadOmen.speed = gameSpeed;
badOmenPowerUps.push(newBadOmen);
game.addChild(newBadOmen);
}
function spawnBadOmenAtStart() {
var newBadOmen = new BadOmenPowerUp();
// Position in front of first cactus (around x: 400-500)
newBadOmen.x = 450;
newBadOmen.y = 2732 - 400; // Spawn in air at fixed height
newBadOmen.speed = gameSpeed;
badOmenPowerUps.push(newBadOmen);
game.addChild(newBadOmen);
}
function checkCollisions() {
for (var i = cacti.length - 1; i >= 0; i--) {
var cactus = cacti[i];
// Break cacti automatically during dash even without collision
if (chicken.isDashing && Math.abs(chicken.x - cactus.x) < 200) {
// Add 1 point for destroying cactus
jumpScore++;
LK.setScore(jumpScore);
jumpScoreText.setText('Score: ' + jumpScore);
LK.getSound('score').play();
// Create enhanced explosion particles during dash
for (var p = 0; p < 20; p++) {
var cactusParticle = new CactusParticle();
cactusParticle.x = cactus.x + (Math.random() - 0.5) * 120;
cactusParticle.y = cactus.y + (Math.random() - 0.5) * 120;
cactusParticles.push(cactusParticle);
game.addChild(cactusParticle);
}
// Destroy cactus with enhanced visual effect
tween(cactus, {
alpha: 0,
scaleX: 3,
scaleY: 3,
rotation: Math.PI
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
cactus.destroy();
}
});
cacti.splice(i, 1);
continue; // Skip regular collision check
}
if (chicken.intersects(cactus)) {
if (isInvincible) {
// Add 1 point for destroying cactus
jumpScore++;
LK.setScore(jumpScore);
jumpScoreText.setText('Score: ' + jumpScore);
LK.getSound('score').play();
// Create green explosion particles
for (var p = 0; p < 15; p++) {
var cactusParticle = new CactusParticle();
cactusParticle.x = cactus.x + (Math.random() - 0.5) * 80;
cactusParticle.y = cactus.y + (Math.random() - 0.5) * 100;
cactusParticles.push(cactusParticle);
game.addChild(cactusParticle);
}
// Destroy cactus with visual effect
tween(cactus, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 200,
onFinish: function onFinish() {
cactus.destroy();
}
});
cacti.splice(i, 1);
} else {
// Lose a life - use accumulated lives if available
if (chickenLives > 10) {
// Use accumulated life
chickenLives--;
} else {
// Use regular life
chickenLives--;
LK.getSound('hit').play();
// Hide one heart
if (lifeDisplays.length > 0) {
var heartToRemove = lifeDisplays.pop();
tween(heartToRemove, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
onFinish: function onFinish() {
heartToRemove.destroy();
}
});
}
}
// Start damage rush mechanic without position change
chicken.isDashing = true;
LK.getSound('dash').play();
// Flash red and break cacti without moving
tween(chicken, {
tint: 0xff0000
}, {
duration: chicken.dashDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
chicken.isDashing = false;
tween(chicken, {
tint: 0xffffff // Reset to normal color
}, {
duration: 200
});
}
});
// Create green explosion particles
for (var p = 0; p < 12; p++) {
var cactusParticle = new CactusParticle();
cactusParticle.x = cactus.x + (Math.random() - 0.5) * 70;
cactusParticle.y = cactus.y + (Math.random() - 0.5) * 90;
cactusParticles.push(cactusParticle);
game.addChild(cactusParticle);
}
// Destroy the cactus that hit the chicken with animation
tween(cactus, {
alpha: 0,
scaleX: 2,
scaleY: 2,
rotation: Math.PI
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
cactus.destroy();
}
});
cacti.splice(i, 1);
// Check if all lives are lost
if (chickenLives <= 0) {
// Check for miracle (25% chance)
if (Math.random() < (infiniteLuckyActive ? 1.0 : 0.25)) {
// Miracle occurs - prevent death and give 10 hearts
chickenLives = Math.min(50, chickenLives + 10); // Give 10 hearts, max 50
// Remove all existing hearts
for (var h = lifeDisplays.length - 1; h >= 0; h--) {
var heartToRemove = lifeDisplays[h];
LK.gui.topLeft.removeChild(heartToRemove);
heartToRemove.destroy();
}
lifeDisplays = [];
// Add new hearts based on chickenLives
for (var h = 0; h < chickenLives; h++) {
var newHeart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
var row = Math.floor(h / 4);
var col = h % 4;
newHeart.x = 250 + col * 75;
newHeart.y = 70 + row * 75;
newHeart.scaleX = 0;
newHeart.scaleY = 0;
newHeart.alpha = 0;
lifeDisplays.push(newHeart);
LK.gui.topLeft.addChild(newHeart);
// Animate heart appearing
tween(newHeart, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.bounceOut
});
}
// Show miracle message in purple
var miracleText = new Text2('un milagro no lo desaprobé ches', {
size: 70,
fill: 0x800080,
stroke: 0x000000,
strokeThickness: 4
});
miracleText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(miracleText);
miracleText.alpha = 0;
tween(miracleText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(miracleText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
miracleText.destroy();
}
});
}, 2000);
}
});
LK.effects.flashScreen(0x800080, 1000);
LK.getSound('miracle').play();
return;
}
// Check if player has wings power-up
if (hasWings) {
// Use wings to prevent death
hasWings = false;
chickenLives = 4; // Give 4 hearts
// Remove all existing hearts
for (var h = lifeDisplays.length - 1; h >= 0; h--) {
var heartToRemove = lifeDisplays[h];
LK.gui.topLeft.removeChild(heartToRemove);
heartToRemove.destroy();
}
lifeDisplays = [];
// Add 4 new hearts
for (var h = 0; h < 4; h++) {
var newHeart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
var row = Math.floor(h / 4);
var col = h % 4;
newHeart.x = 250 + col * 75;
newHeart.y = 70 + row * 75;
newHeart.scaleX = 0;
newHeart.scaleY = 0;
newHeart.alpha = 0;
lifeDisplays.push(newHeart);
LK.gui.topLeft.addChild(newHeart);
// Animate heart appearing
tween(newHeart, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.bounceOut
});
}
// Show special revival message
var revivalText = new Text2('¡ALAS USADAS! +4 CORAZONES', {
size: 70,
fill: 0xFFD700,
stroke: 0x000000,
strokeThickness: 4
});
revivalText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(revivalText);
revivalText.alpha = 0;
tween(revivalText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(revivalText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
revivalText.destroy();
}
});
}, 2000);
}
});
LK.effects.flashScreen(0xFFD700, 1000);
LK.getSound('wings').play();
return;
} else {
isGameRunning = false;
LK.effects.flashScreen(0xFF0000, 800);
LK.getSound('death').play();
LK.setTimeout(function () {
LK.showGameOver();
}, 400);
return;
}
}
}
}
}
}
function updateScore() {
distanceTraveled = Math.floor(LK.ticks / 6);
scoreText.setText('Distance: ' + distanceTraveled + 'm');
// Play score sound every 100 meters
if (distanceTraveled > 0 && distanceTraveled % 100 === 0 && distanceTraveled !== lastScoreSound) {
LK.getSound('score').play();
lastScoreSound = distanceTraveled;
}
}
function checkCactusJumps() {
for (var i = 0; i < cacti.length; i++) {
var cactus = cacti[i];
// Check if chicken has passed the cactus (chicken is to the right of cactus)
if (!cactus.passed && chicken.x > cactus.x + 30) {
cactus.passed = true;
if (cactus.type === 'superTall') {
// Super tall cactus gives 5 points
jumpScore += 5;
// Keep triple jump active permanently after passing
cactus.tripleJumpActivated = true;
} else {
jumpScore++;
}
LK.setScore(jumpScore);
jumpScoreText.setText('Score: ' + jumpScore);
// Update high score if current score is higher
var currentHighScore = storage.highScore || 0;
if (jumpScore > currentHighScore) {
storage.highScore = jumpScore;
highScoreText.setText('Best: ' + jumpScore);
}
LK.getSound('score').play();
increaseDifficulty();
}
}
}
function checkPowerUpCollisions() {
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (chicken.intersects(powerUp) && !powerUp.collected) {
powerUp.collected = true;
// Activate invincibility
isInvincible = true;
invincibilityTimer = 0;
achievements.invincibilityUsed = true;
// Increase chicken speed by 70%
chicken.speed = baseGameSpeed * 1.7;
LK.getSound('powerup').play();
// Create colorful trail particles behind chicken
for (var j = 0; j < 12; j++) {
var trailParticle = new TrailParticle();
trailParticle.x = chicken.x - 50 - Math.random() * 30; // Behind chicken
trailParticle.y = chicken.y - Math.random() * 40;
trailParticles.push(trailParticle);
game.addChild(trailParticle);
}
// Visual feedback - make chicken glow
tween(chicken, {
tint: 0xffff00
}, {
duration: 300
});
// Remove power-up with effect
tween(powerUp, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
powerUp.destroy();
}
});
powerUps.splice(i, 1);
}
}
}
function checkBrickCactusCollisions() {
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (brick.hit) continue; // Skip already hit bricks
for (var j = cacti.length - 1; j >= 0; j--) {
var cactus = cacti[j];
if (brick.intersects(cactus)) {
brick.hit = true;
LK.getSound('break').play();
// Create green explosion particles for cactus breaking
for (var p = 0; p < 15; p++) {
var cactusParticle = new CactusParticle();
cactusParticle.x = cactus.x + (Math.random() - 0.5) * 80;
cactusParticle.y = cactus.y + (Math.random() - 0.5) * 100;
cactusParticles.push(cactusParticle);
game.addChild(cactusParticle);
}
// Destroy cactus with visual effect
tween(cactus, {
alpha: 0,
scaleX: 2,
scaleY: 2,
rotation: Math.PI
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
cactus.destroy();
}
});
cacti.splice(j, 1);
// Water drop chance: 80% with mega luck, 25% normal
var baseWaterDropChance = 0.25;
var megaLuckWaterDropChance = 0.80;
// Apply night mode bonus - increase chances by 10%
if (nightModeActive) {
baseWaterDropChance = Math.min(0.35, baseWaterDropChance + 0.10);
megaLuckWaterDropChance = Math.min(0.90, megaLuckWaterDropChance + 0.10);
}
var waterDropChance = infiniteLuckyActive ? 1.0 : megaLuckActive ? megaLuckWaterDropChance : baseWaterDropChance;
if (Math.random() < waterDropChance) {
var newWater = new Water();
newWater.x = cactus.x;
newWater.y = cactus.y - 100; // Spawn above ground
newWater.speed = gameSpeed;
waters.push(newWater);
game.addChild(newWater);
}
// Destroy the brick with animation
tween(brick, {
alpha: 0,
scaleX: 2,
scaleY: 2,
rotation: Math.PI
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
brick.destroy();
}
});
bricks.splice(i, 1);
break; // Exit cactus loop since brick is destroyed
}
}
}
}
function checkBrickAirplaneCollisions() {
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (brick.isDeflected && brick.targetAirplane) {
// Check collision with target airplane
if (brick.intersects(brick.targetAirplane)) {
// Create white explosion particles
for (var p = 0; p < 20; p++) {
var particle = new Particle();
particle.x = brick.targetAirplane.x + (Math.random() - 0.5) * 100;
particle.y = brick.targetAirplane.y + (Math.random() - 0.5) * 60;
particles.push(particle);
game.addChild(particle);
}
// Destroy airplane with effect
tween(brick.targetAirplane, {
alpha: 0,
scaleX: 2,
scaleY: 2,
rotation: Math.PI
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
brick.targetAirplane.destroy();
}
});
// Remove airplane from array
for (var j = airplanes.length - 1; j >= 0; j--) {
if (airplanes[j] === brick.targetAirplane) {
airplanes.splice(j, 1);
break;
}
}
// Destroy brick
brick.destroy();
bricks.splice(i, 1);
}
}
}
}
function checkBrickGroundCollisions() {
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (brick.hit) continue; // Skip already hit bricks
// Check if brick hit the ground (ground.y is at 2732 - 140)
if (brick.y + 20 >= ground.y) {
// +20 accounts for half brick height
brick.hit = true;
LK.getSound('brick_fall').play();
// Camera shake effect when brick hits ground
var shakeIntensity = 15;
var originalX = game.x;
var originalY = game.y;
// Create multiple quick shake movements
tween(game, {
x: originalX + (Math.random() - 0.5) * shakeIntensity,
y: originalY + (Math.random() - 0.5) * shakeIntensity
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: originalX + (Math.random() - 0.5) * shakeIntensity * 0.7,
y: originalY + (Math.random() - 0.5) * shakeIntensity * 0.7
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: originalX + (Math.random() - 0.5) * shakeIntensity * 0.4,
y: originalY + (Math.random() - 0.5) * shakeIntensity * 0.4
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: originalX,
y: originalY
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
});
}
});
// Create particles for brick breaking on ground
for (var p = 0; p < 10; p++) {
var particle = new Particle();
particle.x = brick.x + (Math.random() - 0.5) * 60;
particle.y = brick.y + (Math.random() - 0.5) * 30;
particles.push(particle);
game.addChild(particle);
}
// Destroy the brick with animation
tween(brick, {
alpha: 0,
scaleX: 2,
scaleY: 2,
rotation: Math.PI
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
brick.destroy();
}
});
bricks.splice(i, 1);
}
}
}
function checkWaterCollisions() {
for (var i = waters.length - 1; i >= 0; i--) {
var water = waters[i];
if (chicken.intersects(water) && !water.collected) {
water.collected = true;
// Activate unlimited jumps for 29 seconds
unlimitedJumpsActive = true;
unlimitedJumpsTimer = 0;
achievements.unlimitedJumpsUsed = true;
LK.getSound('collect').play();
// Visual feedback
unlimitedJumpsText.visible = true;
unlimitedJumpsTimerText.visible = true;
// Flash screen cyan to indicate special event
LK.effects.flashScreen(0x00FFFF, 500);
// Add glow effect to chicken
tween(chicken, {
tint: 0x00FFFF
}, {
duration: 500,
onFinish: function onFinish() {
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
});
// Remove water with effect
tween(water, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
water.destroy();
}
});
waters.splice(i, 1);
}
}
}
function checkBrickCollisions() {
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (chicken.intersects(brick) && !brick.hit) {
brick.hit = true;
// Check if this brick had previously hit a power-up and deactivate all options
if (brick.hitPowerUp) {
// Deactivate all active power-ups and options
isInvincible = false;
invincibilityTimer = 0;
unlimitedJumpsActive = false;
unlimitedJumpsTimer = 0;
tripleJumpActive = false;
tripleJumpTimer = 0;
hasWings = false;
hasBadOmen = false;
badOmenJumpsRemaining = 0;
// Hide all power-up UI elements
powerUpTimerText.visible = false;
tripleJumpText.visible = false;
tripleJumpTimerText.visible = false;
unlimitedJumpsText.visible = false;
unlimitedJumpsTimerText.visible = false;
badOmenJumpsText.visible = false;
// Reset chicken appearance and speed
chicken.speed = baseGameSpeed;
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
// Visual feedback for power-up removal
LK.effects.flashScreen(0x800080, 500);
}
// Check if this is a rainbow missile - instant death
if (brick.isRainbowMissile) {
// Instant death regardless of invincibility
chickenLives = 0;
isGameRunning = false;
// Create spectacular explosion effect
for (var p = 0; p < 30; p++) {
var particle = new Particle();
particle.x = chicken.x + (Math.random() - 0.5) * 100;
particle.y = chicken.y + (Math.random() - 0.5) * 100;
particles.push(particle);
game.addChild(particle);
}
// Flash screen with rainbow colors
LK.effects.flashScreen(0xff0000, 200);
LK.setTimeout(function () {
LK.effects.flashScreen(0x00ff00, 200);
LK.setTimeout(function () {
LK.effects.flashScreen(0x0000ff, 200);
LK.setTimeout(function () {
LK.getSound('explosion').play();
LK.showGameOver();
}, 200);
}, 200);
}, 200);
// Destroy the missile brick with dramatic effect
tween(brick, {
alpha: 0,
scaleX: 5,
scaleY: 5,
rotation: Math.PI * 2
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
brick.destroy();
}
});
bricks.splice(i, 1);
return;
}
if (!isInvincible) {
// Lose 2 lives - use accumulated lives if available
if (chickenLives > 10) {
// Use accumulated lives
chickenLives -= 2;
} else {
// Use regular lives
chickenLives -= 2;
// Hide two hearts
for (var h = 0; h < 2 && lifeDisplays.length > 0; h++) {
var heartToRemove = lifeDisplays.pop();
tween(heartToRemove, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
onFinish: function onFinish() {
heartToRemove.destroy();
}
});
}
}
// Start damage rush mechanic without position change
chicken.isDashing = true;
// Flash red and break cacti without moving
tween(chicken, {
tint: 0xff0000
}, {
duration: chicken.dashDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
chicken.isDashing = false;
tween(chicken, {
tint: 0xffffff // Reset to normal color
}, {
duration: 200
});
}
});
// Check if all lives are lost
if (chickenLives <= 0) {
// Check for miracle (25% chance)
if (Math.random() < (infiniteLuckyActive ? 1.0 : 0.25)) {
// Miracle occurs - prevent death and give 10 hearts
chickenLives = Math.min(50, chickenLives + 10); // Give 10 hearts, max 50
// Remove all existing hearts
for (var h = lifeDisplays.length - 1; h >= 0; h--) {
var heartToRemove = lifeDisplays[h];
LK.gui.topLeft.removeChild(heartToRemove);
heartToRemove.destroy();
}
lifeDisplays = [];
// Add new hearts based on chickenLives
for (var h = 0; h < chickenLives; h++) {
var newHeart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
var row = Math.floor(h / 4);
var col = h % 4;
newHeart.x = 250 + col * 75;
newHeart.y = 70 + row * 75;
newHeart.scaleX = 0;
newHeart.scaleY = 0;
newHeart.alpha = 0;
lifeDisplays.push(newHeart);
LK.gui.topLeft.addChild(newHeart);
// Animate heart appearing
tween(newHeart, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.bounceOut
});
}
// Show miracle message in purple
var miracleText = new Text2('un milagro no lo desaprobé ches', {
size: 70,
fill: 0x800080,
stroke: 0x000000,
strokeThickness: 4
});
miracleText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(miracleText);
miracleText.alpha = 0;
tween(miracleText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(miracleText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
miracleText.destroy();
}
});
}, 2000);
}
});
LK.effects.flashScreen(0x800080, 1000);
LK.getSound('miracle').play();
return;
}
// Check if player has wings power-up
if (hasWings) {
// Use wings to prevent death
hasWings = false;
chickenLives = 4; // Give 4 hearts
// Remove all existing hearts
for (var h = lifeDisplays.length - 1; h >= 0; h--) {
var heartToRemove = lifeDisplays[h];
LK.gui.topLeft.removeChild(heartToRemove);
heartToRemove.destroy();
}
lifeDisplays = [];
// Add 4 new hearts
for (var h = 0; h < 4; h++) {
var newHeart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
var row = Math.floor(h / 4);
var col = h % 4;
newHeart.x = 250 + col * 75;
newHeart.y = 70 + row * 75;
newHeart.scaleX = 0;
newHeart.scaleY = 0;
newHeart.alpha = 0;
lifeDisplays.push(newHeart);
LK.gui.topLeft.addChild(newHeart);
// Animate heart appearing
tween(newHeart, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.bounceOut
});
}
// Show special revival message
var revivalText = new Text2('¡ALAS USADAS! +4 CORAZONES', {
size: 70,
fill: 0xFFD700,
stroke: 0x000000,
strokeThickness: 4
});
revivalText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(revivalText);
revivalText.alpha = 0;
tween(revivalText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(revivalText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
revivalText.destroy();
}
});
}, 2000);
}
});
LK.effects.flashScreen(0xFFD700, 1000);
LK.getSound('wings').play();
return;
} else {
isGameRunning = false;
LK.effects.flashScreen(0xFF0000, 800);
LK.getSound('death').play();
LK.setTimeout(function () {
LK.showGameOver();
}, 400);
return;
}
}
} else {
// Chicken is invincible - give extra life instead of losing lives
if (chickenLives < 10) {
chickenLives++;
// Add new heart to display
var newHeart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Position hearts in rows when more than 4
var heartIndex = chickenLives - 1;
var row = Math.floor(heartIndex / 4);
var col = heartIndex % 4;
newHeart.x = 250 + col * 75;
newHeart.y = 70 + row * 75;
newHeart.scaleX = 0;
newHeart.scaleY = 0;
newHeart.alpha = 0;
lifeDisplays.push(newHeart);
LK.gui.topLeft.addChild(newHeart);
// Animate heart appearing
tween(newHeart, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.bounceOut
});
} else if (chickenLives >= 10) {
// Player at max health - add accumulated life
chickenLives++;
}
// Show extra life message
showExtraLifeMessage();
// Flash chicken green to show positive effect
tween(chicken, {
tint: 0x00FF00
}, {
duration: 200,
onFinish: function onFinish() {
tween(chicken, {
tint: 0xFFFF00
}, {
duration: 200
});
}
});
}
// Destroy the brick with animation
tween(brick, {
alpha: 0,
scaleX: 2,
scaleY: 2,
rotation: Math.PI
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
brick.destroy();
}
});
bricks.splice(i, 1);
}
}
}
function increaseDifficulty() {
// Increase speed every 50 points
var targetSpeed = 8 + Math.floor(jumpScore / 50) * 2;
if (targetSpeed > maxGameSpeed) {
targetSpeed = maxGameSpeed;
}
gameSpeed = targetSpeed;
// Decrease spawn interval based on score
var targetInterval = 90 - Math.floor(jumpScore / 50) * 10;
if (targetInterval < minSpawnInterval) {
targetInterval = minSpawnInterval;
}
cactusSpawnInterval = targetInterval;
}
function updateCamera() {
// Camera disabled - return to normal static view
game.x = 0;
game.y = 0;
}
function updateDayNightCycle() {
// Calculate which 100-point interval we're in
var currentInterval = Math.floor(jumpScore / 100);
var shouldBeNight = currentInterval % 2 === 1; // Odd intervals = night, even = day
var lastInterval = Math.floor((jumpScore - 1) / 100);
var intervalChanged = currentInterval !== lastInterval && jumpScore > 0;
// Check if we need to change from day to night
if (shouldBeNight && !isNightTime && intervalChanged) {
isNightTime = true;
nightTimer = 0;
LK.getSound('night').play();
// Transition to night
tween(dayBackground, {
alpha: 0
}, {
duration: 2000
});
tween(nightBackground, {
alpha: 1
}, {
duration: 2000,
onFinish: function onFinish() {
nightBackground.visible = true;
dayBackground.visible = false;
}
});
}
// Check if we need to change from night to day
if (!shouldBeNight && isNightTime && intervalChanged) {
isNightTime = false;
nightTimer = 0;
LK.getSound('day').play();
// Transition back to day
dayBackground.visible = true;
nightBackground.visible = true;
tween(dayBackground, {
alpha: 1
}, {
duration: 2000
});
tween(nightBackground, {
alpha: 0
}, {
duration: 2000,
onFinish: function onFinish() {
nightBackground.visible = false;
}
});
}
}
function showExtraLifeMessage() {
// Show the extra life message
extraLifeText.visible = true;
extraLifeText.alpha = 0;
extraLifeText.scaleX = 0.5;
extraLifeText.scaleY = 0.5;
// Animate message appearing
tween(extraLifeText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Scale back to normal
tween(extraLifeText, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
onFinish: function onFinish() {
// Wait a moment then fade out
LK.setTimeout(function () {
tween(extraLifeText, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
onFinish: function onFinish() {
extraLifeText.visible = false;
}
});
}, 1000);
}
});
}
});
}
function updateAccumulatedLivesDisplay() {
// Functionality removed - no accumulated lives display
}
function updateTripleJumpTimer() {
if (tripleJumpActive) {
tripleJumpTimer++;
// Calculate remaining seconds
var remainingSeconds = Math.ceil((tripleJumpDuration - tripleJumpTimer) / 60);
tripleJumpTimerText.setText(remainingSeconds + 's');
// End triple jump after 69 seconds
if (tripleJumpTimer >= tripleJumpDuration) {
tripleJumpActive = false;
tripleJumpTimer = 0;
tripleJumpText.visible = false;
tripleJumpTimerText.visible = false;
// Reset chicken appearance
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
}
}
function updateUnlimitedJumpsTimer() {
if (unlimitedJumpsActive) {
unlimitedJumpsTimer++;
// Calculate remaining seconds
var remainingSeconds = Math.ceil((unlimitedJumpsDuration - unlimitedJumpsTimer) / 60);
unlimitedJumpsTimerText.setText('UJ: ' + remainingSeconds + 's');
// End unlimited jumps after 29 seconds
if (unlimitedJumpsTimer >= unlimitedJumpsDuration) {
unlimitedJumpsActive = false;
unlimitedJumpsTimer = 0;
unlimitedJumpsText.visible = false;
unlimitedJumpsTimerText.visible = false;
// Reset chicken appearance
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
}
}
function updateInvincibility() {
// God mode gives unlimited invincibility
if (godModeActive) {
isInvincible = true;
powerUpTimerText.setText('GOD MODE');
powerUpTimerText.visible = true;
// Make chicken flash with rainbow colors during god mode
var rainbowColors = [0xff0000, 0xff4500, 0xffa500, 0xffff00, 0x00ff00, 0x0000ff, 0x4b0082, 0x9400d3];
var colorIndex = Math.floor(LK.ticks / 5) % rainbowColors.length;
chicken.tint = rainbowColors[colorIndex];
return; // Don't process normal invincibility logic when god mode is active
}
if (isInvincible) {
invincibilityTimer++;
// Update power-up timer display - changed to 27 seconds
var remainingSeconds = Math.ceil((1620 - invincibilityTimer) / 60); // 27 seconds = 1620 frames
powerUpTimerText.setText(remainingSeconds + 's');
powerUpTimerText.visible = true;
// Make chicken flash with rainbow colors during invincibility
var rainbowColors = [0xff0000, 0xff4500, 0xffa500, 0xffff00, 0x00ff00, 0x0000ff, 0x4b0082, 0x9400d3];
var colorIndex = Math.floor(invincibilityTimer / 5) % rainbowColors.length;
chicken.tint = rainbowColors[colorIndex];
// End invincibility after 27 seconds (1620 frames)
if (invincibilityTimer >= 1620) {
isInvincible = false;
invincibilityTimer = 0;
powerUpTimerText.visible = false;
// Reset chicken speed
chicken.speed = baseGameSpeed;
// Reset chicken appearance
tween(chicken, {
tint: 0xffffff
}, {
duration: 500
});
}
} else {
powerUpTimerText.visible = false;
}
}
game.update = function () {
if (!isGameRunning || isPaused || isShopGamePaused) return;
updateScore();
// Add 1 point every second (60 frames at 60fps)
scoreTimer++;
if (scoreTimer >= 60) {
jumpScore++;
LK.setScore(jumpScore);
jumpScoreText.setText('Score: ' + jumpScore);
// Update high score if current score is higher
var currentHighScore = storage.highScore || 0;
if (jumpScore > currentHighScore) {
storage.highScore = jumpScore;
highScoreText.setText('Best: ' + jumpScore);
}
scoreTimer = 0; // Reset timer
}
// Spawn cacti when no cactus is visible on screen
if (cacti.length === 0) {
spawnCactus();
}
// Spawn clouds
cloudSpawnTimer++;
if (cloudSpawnTimer >= 180) {
spawnCloud();
cloudSpawnTimer = 0;
}
// Spawn bad omen at start (20% chance) - only once and only if no cacti spawned yet
if (!badOmenSpawnedAtStart && cacti.length === 0 && LK.ticks > 60) {
var badOmenStartChance = infiniteLuckyActive ? 1.0 : 0.20;
// Apply night mode bonus - increase chance by 10%
if (nightModeActive && !infiniteLuckyActive) {
badOmenStartChance = Math.min(0.30, badOmenStartChance + 0.10);
}
if (Math.random() < badOmenStartChance) {
spawnBadOmenAtStart();
}
badOmenSpawnedAtStart = true;
}
// Spawn bad omen at 100 points (50% chance) - only once
if (!badOmenSpawnedAt100 && jumpScore >= 100) {
var badOmen100Chance = infiniteLuckyActive ? 1.0 : 0.50;
// Apply night mode bonus - increase chance by 10%
if (nightModeActive && !infiniteLuckyActive) {
badOmen100Chance = Math.min(0.60, badOmen100Chance + 0.10);
}
if (Math.random() < badOmen100Chance) {
spawnBadOmenPowerUp();
}
badOmenSpawnedAt100 = true;
}
// Spawn power-ups
powerUpSpawnTimer++;
if (powerUpSpawnTimer >= powerUpSpawnInterval) {
var spawnChance = Math.random();
var basePowerUpChance = 0.85;
var megaLuckChance = 0.90;
// Apply night mode bonus - increase chances by 10%
if (nightModeActive) {
basePowerUpChance = Math.min(0.95, basePowerUpChance + 0.10);
megaLuckChance = Math.min(1.0, megaLuckChance + 0.10);
}
var powerUpChance = infiniteLuckyActive ? 1.0 : megaLuckActive ? megaLuckChance : basePowerUpChance;
if (spawnChance < powerUpChance) {
if (spawnChance < 0.15) {
// 15% chance to spawn wings
spawnWings();
} else if (spawnChance < 0.25) {
// 10% chance to spawn bad omen (only if not already spawned special ones)
if (badOmenSpawnedAtStart && badOmenSpawnedAt100) {
spawnBadOmenPowerUp();
} else {
// Spawn regular power-up instead
spawnPowerUp();
}
} else {
// Remaining chance to spawn regular power-up
spawnPowerUp();
}
}
powerUpSpawnTimer = 0;
// Set new random interval for next power-up (20-40 seconds)
powerUpSpawnInterval = 1200 + Math.random() * 1200;
}
// Make last heart pulsate when only 1 heart left
if (chickenLives === 1 && lifeDisplays.length > 0) {
var lastHeart = lifeDisplays[0];
if (!lastHeart.isPulsating) {
LK.getSound('heartbeat').play();
// Create continuous pulsating effect
var _pulseHeart = function pulseHeart() {
tween(lastHeart, {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(lastHeart, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (chickenLives === 1 && lastHeart.isPulsating) {
_pulseHeart();
}
}
});
}
});
};
lastHeart.isPulsating = true;
_pulseHeart();
}
} else if (lifeDisplays.length > 0) {
// Reset pulsation if more than 1 heart
lifeDisplays[0].isPulsating = false;
}
// Spawn bricks - don't spawn when chicken has only 1 heart
if (chickenLives > 1) {
brickSpawnTimer++;
if (brickSpawnTimer >= brickSpawnInterval) {
spawnBrick();
brickSpawnTimer = 0;
}
}
// Shop spawning is now handled by shop button - no random spawning
// Update and clean up cacti
for (var i = cacti.length - 1; i >= 0; i--) {
var cactus = cacti[i];
cactus.speed = gameSpeed;
if (cactus.x < -100) {
cactus.destroy();
cacti.splice(i, 1);
}
}
// Update and clean up clouds
for (var i = clouds.length - 1; i >= 0; i--) {
var cloud = clouds[i];
if (cloud.x < -200) {
cloud.destroy();
clouds.splice(i, 1);
}
}
// Update and clean up power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
powerUp.speed = gameSpeed;
if (powerUp.x < -100) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Update and clean up particles
for (var i = particles.length - 1; i >= 0; i--) {
var particle = particles[i];
if (particle.markForDestroy) {
particle.destroy();
particles.splice(i, 1);
}
}
// Update and clean up trail particles
for (var i = trailParticles.length - 1; i >= 0; i--) {
var trailParticle = trailParticles[i];
if (trailParticle.markForDestroy) {
trailParticle.destroy();
trailParticles.splice(i, 1);
}
}
// Update and clean up cactus particles
for (var i = cactusParticles.length - 1; i >= 0; i--) {
var cactusParticle = cactusParticles[i];
if (cactusParticle.markForDestroy) {
cactusParticle.destroy();
cactusParticles.splice(i, 1);
}
}
// Update and clean up airplanes
for (var i = airplanes.length - 1; i >= 0; i--) {
var airplane = airplanes[i];
if (airplane.x > 2048 + 200) {
// Off-screen cleanup
airplane.destroy();
airplanes.splice(i, 1);
}
}
// Update and clean up bricks
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (brick.y > 2732 + 100) {
// Off-screen cleanup
brick.destroy();
bricks.splice(i, 1);
}
}
// Update and clean up waters
for (var i = waters.length - 1; i >= 0; i--) {
var water = waters[i];
water.speed = gameSpeed;
if (water.x < -100) {
water.destroy();
waters.splice(i, 1);
}
}
// Update and clean up wings
for (var i = wings.length - 1; i >= 0; i--) {
var wing = wings[i];
wing.speed = gameSpeed;
if (wing.x < -100) {
wing.destroy();
wings.splice(i, 1);
}
}
// Update and clean up question mark power-ups
for (var i = questionMarkPowerUps.length - 1; i >= 0; i--) {
var questionMark = questionMarkPowerUps[i];
questionMark.speed = gameSpeed;
if (questionMark.x < -100) {
questionMark.destroy();
questionMarkPowerUps.splice(i, 1);
}
}
// Update and clean up bad omen power-ups
for (var i = badOmenPowerUps.length - 1; i >= 0; i--) {
var badOmen = badOmenPowerUps[i];
badOmen.speed = gameSpeed;
if (badOmen.x < -100) {
badOmen.destroy();
badOmenPowerUps.splice(i, 1);
}
}
updateTripleJumpTimer();
updateUnlimitedJumpsTimer();
updateInvincibility();
// Check for coin rewards every 10 points
var currentTenPoints = Math.floor(jumpScore / 10) * 10;
if (currentTenPoints > lastCoinScore && currentTenPoints > 0) {
playerCoins++;
lastCoinScore = currentTenPoints;
coinText.setText(playerCoins.toString());
LK.getSound('coin').play();
// Visual feedback for coin earned
tween(coinIcon, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
tween(coinIcon, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
// Flash coin text
tween(coinText, {
tint: 0xFFFF00
}, {
duration: 300,
onFinish: function onFinish() {
tween(coinText, {
tint: 0xFFD700
}, {
duration: 300
});
}
});
}
updateDayNightCycle();
updateCamera();
// Update dash cooldown
if (dashCooldown > 0) {
dashCooldown--;
}
checkCollisions();
checkCactusJumps();
checkPowerUpCollisions();
checkBrickCollisions();
checkWaterCollisions();
checkWingsCollisions();
checkBrickCactusCollisions();
checkBrickGroundCollisions();
checkBrickAirplaneCollisions();
checkBrickPowerUpCollisions();
checkCactusWingsCollisions();
checkQuestionMarkPowerUpCollisions();
checkBadOmenPowerUpCollisions();
// Hide center texts when shop or hack menu is open
if (isShopGamePaused) {
powerUpTimerText.visible = false;
tripleJumpText.visible = false;
unlimitedJumpsText.visible = false;
badOmenJumpsText.visible = false;
extraLifeText.visible = false;
} else {
// Restore visibility based on actual states when shop/hack menu closes
if (isInvincible || godModeActive) {
powerUpTimerText.visible = true;
}
if (tripleJumpActive) {
tripleJumpText.visible = true;
}
if (unlimitedJumpsActive) {
unlimitedJumpsText.visible = true;
}
if (hasBadOmen) {
badOmenJumpsText.visible = true;
}
// extraLifeText visibility is controlled by showExtraLifeMessage function
}
updateCenterTextLayout();
checkAchievements();
// Fortuna feature - maintain 999 coins
if (fortunaActive) {
if (playerCoins < 999) {
fortunaTimer++;
// After 1 second (60 frames), restore to 999 coins
if (fortunaTimer >= 60) {
playerCoins = 999;
coinText.setText(playerCoins.toString());
fortunaTimer = 0;
}
} else if (playerCoins > 999) {
// Cap at 999 coins if somehow exceeded
playerCoins = 999;
coinText.setText(playerCoins.toString());
fortunaTimer = 0;
} else {
// Reset timer when at exactly 999 coins
fortunaTimer = 0;
}
}
// Hide instructions after first jump
if (chicken.isJumping && instructionText.alpha > 0) {
tween(instructionText, {
alpha: 0
}, {
duration: 1000
});
}
};
function checkWingsCollisions() {
for (var i = wings.length - 1; i >= 0; i--) {
var wing = wings[i];
if (chicken.intersects(wing) && !wing.collected) {
wing.collected = true;
hasWings = true;
achievements.wingsUsed = true;
LK.getSound('wings').play();
// Visual feedback
LK.effects.flashScreen(0xFFD700, 500);
// Add glow effect to chicken
tween(chicken, {
tint: 0xFFD700
}, {
duration: 500,
onFinish: function onFinish() {
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
});
// Remove wings with effect
tween(wing, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
wing.destroy();
}
});
wings.splice(i, 1);
}
}
}
function checkBrickPowerUpCollisions() {
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (brick.hit) continue; // Skip already hit bricks
for (var j = powerUps.length - 1; j >= 0; j--) {
var powerUp = powerUps[j];
if (brick.intersects(powerUp) && !powerUp.collected) {
brick.hit = true;
powerUp.collected = true;
// Mark that this brick hit a power-up
brick.hitPowerUp = true;
LK.getSound('whoosh').play();
// Give brick rainbow effect
brick.isRainbowMissile = true;
brick.missileSpeed = 9.8;
brick.gravity = 0; // Remove gravity
brick.velocityY = 0; // Stop falling
// Create rainbow tween effect
var rainbowColors = [0xff0000, 0xff4500, 0xffa500, 0xffff00, 0x00ff00, 0x0000ff, 0x4b0082, 0x9400d3];
var colorIndex = 0;
var rainbowInterval = LK.setInterval(function () {
if (brick && brick.isRainbowMissile) {
brick.tint = rainbowColors[colorIndex % rainbowColors.length];
colorIndex++;
} else {
LK.clearInterval(rainbowInterval);
}
}, 100);
// Remove power-up with effect
tween(powerUp, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
powerUp.destroy();
}
});
powerUps.splice(j, 1);
break;
}
}
}
}
function checkQuestionMarkPowerUpCollisions() {
for (var i = questionMarkPowerUps.length - 1; i >= 0; i--) {
var questionMark = questionMarkPowerUps[i];
// Check ground collision for airplane-dropped question marks
if (questionMark.isAirplaneDrop && !questionMark.followsPlayer && questionMark.y + 40 >= ground.y) {
// Start following the player when it hits the ground
questionMark.followsPlayer = true;
}
if (chicken.intersects(questionMark) && !questionMark.collected) {
questionMark.collected = true;
// Random power-up effect when collecting question mark
var randomEffect = Math.floor(Math.random() * 6);
if (randomEffect === 0) {
// Give 1-3 extra lives
var extraLives = Math.floor(Math.random() * 3) + 1;
for (var l = 0; l < extraLives && chickenLives < 10; l++) {
chickenLives++;
var newHeart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
var heartIndex = chickenLives - 1;
var row = Math.floor(heartIndex / 4);
var col = heartIndex % 4;
newHeart.x = 250 + col * 75;
newHeart.y = 70 + row * 75;
newHeart.scaleX = 0;
newHeart.scaleY = 0;
newHeart.alpha = 0;
lifeDisplays.push(newHeart);
LK.gui.topLeft.addChild(newHeart);
tween(newHeart, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.bounceOut
});
}
showExtraLifeMessage();
} else if (randomEffect === 1) {
// Give 5-10 coins
var extraCoins = Math.floor(Math.random() * 6) + 5;
playerCoins += extraCoins;
coinText.setText(playerCoins.toString());
LK.effects.flashScreen(0xFFD700, 500);
} else if (randomEffect === 2) {
// Activate unlimited jumps for 15 seconds
unlimitedJumpsActive = true;
unlimitedJumpsTimer = 0;
achievements.waterUsed = true;
unlimitedJumpsText.visible = true;
unlimitedJumpsTimerText.visible = true;
LK.effects.flashScreen(0x00FFFF, 500);
} else if (randomEffect === 3) {
// Activate invincibility for 10 seconds
isInvincible = true;
invincibilityTimer = 0;
LK.effects.flashScreen(0xFFFF00, 500);
} else if (randomEffect === 4) {
// Give wings power-up
hasWings = true;
LK.effects.flashScreen(0xFFD700, 500);
tween(chicken, {
tint: 0xFFD700
}, {
duration: 500,
onFinish: function onFinish() {
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
});
} else {
// Activate triple jump for 30 seconds
tripleJumpActive = true;
tripleJumpTimer = 0;
tripleJumpText.visible = true;
tripleJumpTimerText.visible = true;
LK.effects.flashScreen(0x00FF00, 500);
tween(chicken, {
tint: 0x00FF00
}, {
duration: 500,
onFinish: function onFinish() {
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
});
}
LK.getSound('powerup').play();
// Remove question mark with effect
tween(questionMark, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
questionMark.destroy();
}
});
questionMarkPowerUps.splice(i, 1);
}
}
}
function checkBadOmenPowerUpCollisions() {
for (var i = badOmenPowerUps.length - 1; i >= 0; i--) {
var badOmen = badOmenPowerUps[i];
if (chicken.intersects(badOmen) && !badOmen.collected) {
badOmen.collected = true;
if (hasBadOmen) {
// Player already has bad omen - reduce jumps based on score
var jumpsToReduce = Math.max(1, Math.floor(jumpScore / 10)); // Reduce at least 1 jump, more based on score
badOmenJumpsRemaining = Math.max(0, badOmenJumpsRemaining - jumpsToReduce);
badOmenJumpsText.setText('Jumps: ' + badOmenJumpsRemaining);
// Check if jumps are exhausted after reduction
if (badOmenJumpsRemaining <= 0) {
// Game over when jumps run out
LK.effects.flashScreen(0x8B0000, 800);
LK.setTimeout(function () {
LK.showGameOver();
}, 400);
}
} else {
// First time collecting bad omen - activate bad omen with limited jumps
hasBadOmen = true;
badOmenJumpsRemaining = 1500;
badOmenJumpsText.setText('Jumps: ' + badOmenJumpsRemaining);
badOmenJumpsText.visible = true;
}
LK.getSound('powerup').play();
// Visual feedback - dark red flash
LK.effects.flashScreen(0x8B0000, 500);
// Add dark effect to chicken
tween(chicken, {
tint: 0x8B0000
}, {
duration: 500,
onFinish: function onFinish() {
tween(chicken, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
});
// Remove bad omen with effect
tween(badOmen, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
badOmen.destroy();
}
});
badOmenPowerUps.splice(i, 1);
}
}
}
function showAchievementNotification(name, description) {
if (achievementNotificationPanel.visible) return; // Don't stack notifications
achievementText.setText(name);
achievementNotificationPanel.visible = true;
achievementNotificationPanel.x = 2048; // Start off-screen right
// Animate panel sliding in from right
tween(achievementNotificationPanel, {
x: 2048 - 620 // Slide to visible position (20px from right edge)
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Wait 3 seconds then slide out
LK.setTimeout(function () {
tween(achievementNotificationPanel, {
x: 2048 // Slide back off-screen right
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
achievementNotificationPanel.visible = false;
}
});
}, 3000);
}
});
// Flash screen gold
LK.effects.flashScreen(0xFFD700, 300);
LK.getSound('achievement').play();
}
function updateCenterTextLayout() {
var visibleTexts = [];
// Collect all visible center texts
if (powerUpTimerText.visible) visibleTexts.push(powerUpTimerText);
if (tripleJumpText.visible) visibleTexts.push(tripleJumpText);
if (unlimitedJumpsText.visible) visibleTexts.push(unlimitedJumpsText);
if (badOmenJumpsText.visible) visibleTexts.push(badOmenJumpsText);
if (extraLifeText.visible) visibleTexts.push(extraLifeText);
// If more than one text is visible, arrange them in a vertical column
if (visibleTexts.length > 1) {
var totalHeight = 0;
var spacing = 80; // Space between texts
// Calculate total height needed
for (var i = 0; i < visibleTexts.length; i++) {
totalHeight += visibleTexts[i].height;
if (i < visibleTexts.length - 1) totalHeight += spacing;
}
// Start position (center the entire column)
var startY = -totalHeight / 2;
var currentY = startY;
// Position each text in the column
for (var i = 0; i < visibleTexts.length; i++) {
visibleTexts[i].x = 0; // Keep them centered horizontally
visibleTexts[i].y = currentY + visibleTexts[i].height / 2;
currentY += visibleTexts[i].height + spacing;
}
} else if (visibleTexts.length === 1) {
// Single text - center it
visibleTexts[0].x = 0;
visibleTexts[0].y = 0;
}
}
function checkAchievements() {
// First Cactus Jump - "el comienzo"
if (!achievements.firstCactusJump && jumpScore >= 1) {
achievements.firstCactusJump = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('el comienzo', 'Jump over your first cactus');
}
// First Jump
if (!achievements.firstJump && jumpScore >= 1) {
achievements.firstJump = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('FIRST JUMP', 'Jump over your first cactus');
}
// Speed Demon - 10 cacti in a row
if (!achievements.speedDemon && jumpScore >= 10) {
achievements.speedDemon = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('SPEED DEMON', 'Jump over 10 cacti');
}
// Marathon Runner - 50 cacti
if (!achievements.marathonRunner && jumpScore >= 50) {
achievements.marathonRunner = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('MARATHON RUNNER', 'Jump over 50 cacti');
}
// Cactus Master - 100 cacti
if (!achievements.cactusMaster && jumpScore >= 100) {
achievements.cactusMaster = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('CACTUS MASTER', 'Jump over 100 cacti');
}
// Distance Walker - 500m
if (!achievements.distanceWalker && distanceTraveled >= 500) {
achievements.distanceWalker = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('DISTANCE WALKER', 'Travel 500 meters');
}
// Long Distance Runner - 1000m
if (!achievements.longDistanceRunner && distanceTraveled >= 1000) {
achievements.longDistanceRunner = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('LONG DISTANCE RUNNER', 'Travel 1000 meters');
}
// Ultra Marathon - 2000m
if (!achievements.ultraMarathon && distanceTraveled >= 2000) {
achievements.ultraMarathon = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('ULTRA MARATHON', 'Travel 2000 meters');
}
// Tap Master - 100 taps
if (!achievements.tapMaster && tapCount >= 100) {
achievements.tapMaster = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('TAP MASTER', 'Tap 100 times');
}
// Coin Collector - 25 coins
if (!achievements.coinCollector && playerCoins >= 25) {
achievements.coinCollector = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('COIN COLLECTOR', 'Collect 25 coins');
}
// Rich Chicken - 50 coins
if (!achievements.richChicken && playerCoins >= 50) {
achievements.richChicken = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('RICH CHICKEN', 'Collect 50 coins');
}
// Night Walker - survive night time
if (!achievements.nightWalker && isNightTime && jumpScore >= 105) {
achievements.nightWalker = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('NIGHT WALKER', 'Survive the night');
}
// Cat Lives - collect 9 hearts
if (!achievements.catLives && chickenLives >= 9) {
achievements.catLives = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('CAT LIVES', 'Have 9 or more lives');
}
// Last Stand - survive with 1 heart for 10 jumps
if (chickenLives === 1) {
if (!achievements.lastStandStart) {
achievements.lastStandStart = jumpScore;
}
if (!achievements.lastStand && jumpScore >= achievements.lastStandStart + 10) {
achievements.lastStand = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('LAST STAND', 'Survive 10 jumps with 1 life');
}
} else {
achievements.lastStandStart = null;
}
// Power Up Collector - collect 10 power-ups
if (!achievements.powerUpCollector) {
var powerUpsCollected = 0;
if (achievements.invincibilityUsed) powerUpsCollected++;
if (achievements.wingsUsed) powerUpsCollected++;
if (achievements.tripleJumpUsed) powerUpsCollected++;
if (achievements.unlimitedJumpsUsed) powerUpsCollected++;
if (achievements.waterUsed) powerUpsCollected++;
if (powerUpsCollected >= 5) {
achievements.powerUpCollector = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('POWER UP COLLECTOR', 'Use 5 different power-ups');
}
}
// Bad Omen Survivor - survive 100 jumps with bad omen
if (!achievements.badOmenSurvivor && hasBadOmen) {
if (!achievements.badOmenStartJumps) {
achievements.badOmenStartJumps = jumpScore;
}
if (jumpScore >= achievements.badOmenStartJumps + 100) {
achievements.badOmenSurvivor = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('BAD OMEN SURVIVOR', 'Jump 100 times with bad omen');
}
}
// Triple Jump Master - use triple jump 20 times
if (!achievements.tripleJumpMaster && achievements.tripleJumps >= 20) {
achievements.tripleJumpMaster = true;
// Award 5 coins for achievement
playerCoins += 5;
coinText.setText(playerCoins.toString());
showAchievementNotification('TRIPLE JUMP MASTER', 'Use triple jump 20 times');
}
// Store achievements
storage.achievements = achievements;
}
function checkCactusWingsCollisions() {
for (var i = cacti.length - 1; i >= 0; i--) {
var cactus = cacti[i];
for (var j = wings.length - 1; j >= 0; j--) {
var wing = wings[j];
if (cactus.intersects(wing) && !wing.collected) {
// Wings power-up breaks the cactus
wing.collected = true;
// Create green explosion particles for cactus breaking
for (var p = 0; p < 15; p++) {
var cactusParticle = new CactusParticle();
cactusParticle.x = cactus.x + (Math.random() - 0.5) * 80;
cactusParticle.y = cactus.y + (Math.random() - 0.5) * 100;
cactusParticles.push(cactusParticle);
game.addChild(cactusParticle);
}
// Destroy cactus with visual effect
tween(cactus, {
alpha: 0,
scaleX: 2,
scaleY: 2,
rotation: Math.PI
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
cactus.destroy();
}
});
cacti.splice(i, 1);
// Remove wings with effect
tween(wing, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
wing.destroy();
}
});
wings.splice(j, 1);
break; // Exit wings loop since cactus is destroyed
}
}
}
} ===================================================================
--- original.js
+++ change.js
@@ -1252,8 +1252,9 @@
****/
var gameSpeed = 8;
var godModeActive = storage.godModeActive || false;
var megaLuckActive = storage.megaLuckActive || false;
+var infiniteLuckyActive = storage.hack6Active || false;
var hack3Active = storage.hack3Active || false;
var hack4Active = storage.hack4Active || false;
var hack5Active = storage.hack5Active || false;
var fortunaActive = storage.hack5Active || false;
Cactus 2d style pixel 1980. 2d. High contrast. No shadows. 2d
White chicken military hat style 2d pixel 1980. In-Game asset. 2d. High contrast. No shadows
Chicken jump
Brick style pixel 1980. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Day sky and clouds style pixel 1980. In-Game asset. 2d. High contrast. No shadows. Pixel
Airplane 2d style pixel 1980. 2d. High contrast. No shadows
Night sky
Tubería gris radioactiva estilo pixel de 1983. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Boton verde ovalado qué dice "compra" estilo 2d pixel 1989. In-Game asset. 2d. High contrast. No shadows
Que el botón sea rojo y que diga salir
Pocion azul clara estilo pixel art . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Golden con style pixel art. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Red heart style pixel art. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Fondo verde
One Cloud style pixel art. 2d. High contrast. No shadows
Alas de ángel blancas estilo pixel art. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Un barrir marrón con 2 líneas negras en el medio estilo pixel art. 2d. High contrast. No shadows
Gray rock (stone) style pixel art. 2d. High contrast. No shadows
Yellow star with Black eyes style pixel art. 2d. High contrast. No shadows
Silla amarilla de un avion estilo pixel art. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Has el cuadro un poco más recto y sin líneas blancas
Caja de Interrogación alcoiris de líneas blancas estilo pixel art. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Una bola de acero negro con unas cadenas grises estilo pixel art. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Hitbox green. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Tiburón azul robótico volando con una elize abajo y una cara graciosa . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat