User prompt
El gato camina alternando entre 2 assets ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El gato deja de responder al alejarse de su posición inicial
User prompt
El gato deja de responder al avanzar mucho a la derecha
User prompt
Pareciera ser que los objetos se crean fuera del área de juego, fuera de la estantería
User prompt
Has la estantería el doble de grande
User prompt
El juego debe empezar 10/10 y al llegar a 0/10 gana
User prompt
El juego debe tener 10 objetos, cuando tumba los 10 y ganaba
User prompt
Los objetos deben están siendo creados por fuera de la estantería
User prompt
La estantería es muy corta, debe ser 4 veces mas larga
User prompt
El gato pierde unas vida al llegar al límite
User prompt
Los esenarios no deben ser tan grandes, con que ocupen 16 tablas de ancho ya esta bien
User prompt
Tener en cuenta la dirección en que va el gato. Cuando va para un lado, la inclinación tiene que ser una. Y cuando va para el lado contrario, la inclinación tiene que ser otra. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cuando cat pasa hacia una tabla superior, debe cambiar el asset a cat-jump inclinado hacia arriba y cuando pasa s una tabla inferior debe inclinado hacia abajo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
implementa una solución al código
User prompt
Deja solo el objeto soap como jabon el otro eliminalo
User prompt
Debe haber una columna tanto al inicio como al fin que no deje seguir avanzando al gato
User prompt
El gato, cuando está en la burbuja después de haber tocado el jabón, tiene que flotar como lo hace una burbuja en la realidad, irse para arriba como si fuera un globo de gas. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cuando el gato está dentro de la burbuja, debe flotar e ir escalando los shelves y quedar en el que más cerca esté cuando la burbuja revienta. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Hay que prevenir que el gato quede pegado en la lámpara porque se electrocuta y está demasiado cerca y no puede salir de ese estado de electrocución
User prompt
Hay que prevenir que el gato quede pegado en la lámpara porque se electrocuta y está demasiado cerca y no puede salir de ese estado de electrocución
User prompt
antes de quedar electrocutado, que se aleje de la lámpara porque si no queda electrocutado siempre. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Los objetos como la luz, el jabón y el objeto peligroso, el objetivo del gato no es derribarlo, debe derribar los demás objetos. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Tanto el jabón como la luz son objetos que tiene que esquivar el gato, así que no cuentan como objetos a derribar. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Hay un problema con la mecánica del fuego. La cantidad de objetos no se condice con la que está en el marcador. Además, los objetos desaparecen de su posición cuando no están en la pantalla, cuando salen fuera de la pantalla.
User prompt
Hay un problema con la mecánica del juego, los objetos deben permanecer fijos en su posición hasta que se termine el juego, no debe borrarse nunca el juego, la memoria tiene que durar hasta que todos los objetos sean tumbados, y también tiene que tener un límite al principio de la partida ↪💡 Consider importing and using the following plugins: @upit/storage.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Cat = Container.expand(function () {
var self = Container.call(this);
var catGraphics = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
self.catElectrocutedGraphics = self.attachAsset('catElectrocuted', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
self.catElectrocutedGraphics.visible = false;
self.gatoEnjabonado = self.attachAsset('Gato-enjabonado', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
self.gatoEnjabonado.visible = false;
self.catJumpGraphics = self.attachAsset('cat-jump', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
self.catJumpGraphics.visible = false;
self.speed = 10; // Much faster cat movement
self.direction = 1; // 1 for right, -1 for left
self.targetShelfLevel = 2; // Start on middle shelf (0-4)
self.currentShelfLevel = 2;
self.isLaserMode = false;
self.laserModeTimer = 0;
self.normalSpeed = 8;
self.laserSpeed = 15;
self.isChasing = false;
self.chaseTarget = null;
self.isHiding = false;
self.hideTarget = null;
self.isJumping = false;
self.lives = 3;
self.isInvulnerable = false;
self.invulnerabilityTimer = 0;
self.isZarpazoMode = false;
self.zarpazoGraphics = null;
self.activateZarpazo = function () {
if (self.isZarpazoMode) {
return;
} // Already in zarpazo mode
self.isZarpazoMode = true;
// Create zarpazo graphics if not exists
if (!self.zarpazoGraphics) {
self.zarpazoGraphics = self.attachAsset('zarpazo', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
}
// Show zarpazo, hide normal cat
catGraphics.visible = false;
self.zarpazoGraphics.visible = true;
self.zarpazoGraphics.scaleX = 2 * self.direction;
self.zarpazoGraphics.scaleY = 2;
// Return to normal after much faster zarpazo
tween.stop(self, {
isZarpazoMode: true
}); // Stop any existing zarpazo tween
LK.setTimeout(function () {
self.isZarpazoMode = false;
catGraphics.visible = true;
if (self.zarpazoGraphics) {
self.zarpazoGraphics.visible = false;
}
}, 200); // 0.2 seconds for much faster zarpazo
};
self.activateBubble = function (duration) {
if (self.isInBubble) {
return; // Already in bubble
}
self.isInBubble = true;
self.bubbleTimer = duration || 600; // Default 10 seconds at 60fps
self.originalTargetShelf = self.targetShelfLevel;
// Stop any existing movement tweens
tween.stop(self, {
y: true
});
self.isJumping = false;
// Visual effect when bubble starts
LK.effects.flashObject(self, 0x87CEEB, 300);
};
self.update = function () {
// Move towards target shelf level with dynamic jumping animation
var targetY = shelfLevels[self.targetShelfLevel] - 208; // Position to stand on shelf - raised by 30px
if (Math.abs(self.y - targetY) > 5) {
// Check if we need to start a new jump animation
if (!self.isJumping) {
self.isJumping = true;
var jumpDistance = targetY - self.y;
var jumpDuration = Math.abs(jumpDistance) * 0.8; // Duration based on distance
// Stop any existing tween
tween.stop(self, {
y: true
});
// Create dynamic jump with bounce effect
if (self.y < targetY) {
// Jumping down - show cat-jump tilted downward
catGraphics.visible = false;
self.catJumpGraphics.visible = true;
self.catJumpGraphics.rotation = self.direction > 0 ? 0.5 : -0.5; // Tilt downward for jumping down, consider direction
self.catJumpGraphics.scaleX = self.direction > 0 ? 2 : -2;
// Jumping down - faster with bounce landing
tween(self, {
y: targetY
}, {
duration: jumpDuration,
easing: tween.linear,
onFinish: function onFinish() {
self.y = targetY;
self.currentShelfLevel = self.targetShelfLevel;
// Switch back to normal cat after landing
self.catJumpGraphics.visible = false;
self.catJumpGraphics.rotation = 0;
catGraphics.visible = true;
// Add bounce effect when landing - move down and up a few pixels
tween(self, {
y: self.y + 15
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.y - 15
}, {
duration: 100,
easing: tween.bounceOut
});
}
});
self.isJumping = false;
}
});
} else {
// Jumping up - show cat-jump tilted upward and squeeze first for momentum
catGraphics.visible = false;
self.catJumpGraphics.visible = true;
self.catJumpGraphics.rotation = self.direction > 0 ? -0.5 : 0.5; // Tilt upward for jumping up, consider direction
self.catJumpGraphics.scaleX = self.direction > 0 ? 2 : -2;
// First squeeze to take impulse
tween(self.catJumpGraphics, {
scaleX: (self.direction > 0 ? 2 : -2) * 1.3,
scaleY: 2 * 0.7
}, {
duration: jumpDuration * 0.3,
easing: tween.easeIn,
onFinish: function onFinish() {
// Then jump with normal scale
tween(self.catJumpGraphics, {
scaleX: self.direction > 0 ? 2 : -2,
scaleY: 2
}, {
duration: 100,
easing: tween.easeOut
});
// Actual jump movement
tween(self, {
y: targetY
}, {
duration: jumpDuration * 1.2,
easing: tween.easeOut,
onFinish: function onFinish() {
self.y = targetY;
self.currentShelfLevel = self.targetShelfLevel;
self.isJumping = false;
// Switch back to normal cat after landing
self.catJumpGraphics.visible = false;
self.catJumpGraphics.rotation = 0;
catGraphics.visible = true;
}
});
}
});
}
}
} else {
self.y = targetY;
self.currentShelfLevel = self.targetShelfLevel;
self.isJumping = false;
}
// Handle laser mode
if (self.isLaserMode) {
self.laserModeTimer--;
if (self.laserModeTimer <= 0) {
self.isLaserMode = false;
self.speed = self.normalSpeed;
}
}
// Update graphics direction based on movement direction
if (self.direction > 0) {
catGraphics.scaleX = 2;
if (self.catElectrocutedGraphics) {
self.catElectrocutedGraphics.scaleX = 2;
}
if (self.zarpazoGraphics) {
self.zarpazoGraphics.scaleX = 2;
}
if (self.gatoEnjabonado) {
self.gatoEnjabonado.scaleX = 2;
}
if (self.catJumpGraphics) {
self.catJumpGraphics.scaleX = 2;
}
} else {
catGraphics.scaleX = -2;
if (self.catElectrocutedGraphics) {
self.catElectrocutedGraphics.scaleX = -2;
}
if (self.zarpazoGraphics) {
self.zarpazoGraphics.scaleX = -2;
}
if (self.gatoEnjabonado) {
self.gatoEnjabonado.scaleX = -2;
}
if (self.catJumpGraphics) {
self.catJumpGraphics.scaleX = -2;
}
}
// Handle horizontal movement when not electrocuted or slipping uncontrollably
if (!self.isElectrocuted && (!self.isSlipping || self.slipTimer % 30 !== 0)) {
self.x += self.speed * self.direction;
}
for (var i = shelfObjects.length - 1; i >= 0; i--) {
var obj = shelfObjects[i];
if (self.intersects(obj) && !obj.isFalling) {
obj.startFalling();
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Update objects knocked down counter based on actual remaining objects
var actualObjectsRemaining = shelfObjects.length;
objectsKnockedDown = totalObjectsToKnock - actualObjectsRemaining;
storage.objectsKnockedDown = objectsKnockedDown;
// Check if all objects have been knocked down
if (actualObjectsRemaining <= 0) {
// Player wins when all objects are knocked down - reset storage for new game
storage.totalObjectsToKnock = 0;
storage.objectsKnockedDown = 0;
LK.showYouWin();
return;
}
// Play random knock sound
var soundId = 'knock' + (Math.floor(Math.random() * 3) + 1);
LK.getSound(soundId).play();
// Activate zarpazo mode when knocking objects
self.activateZarpazo();
}
}
// Check for collisions with dangerous objects - only on same shelf level
for (var i = dangerousObjects.length - 1; i >= 0; i--) {
var dangerousObj = dangerousObjects[i];
// Calculate which shelf level the dangerous object is on
var objShelfLevel = -1;
for (var level = 0; level < 5; level++) {
if (Math.abs(dangerousObj.y - (shelfLevels[level] - 75)) < 50) {
objShelfLevel = level;
break;
}
}
// Only collide if on same shelf level
if (self.intersects(dangerousObj) && dangerousObj.isDangerous && !dangerousObj.isFalling && objShelfLevel === self.currentShelfLevel) {
// Cat falls off the shelf
dangerousObj.startFalling();
LK.getSound('catFall').play();
LK.effects.flashScreen(0xff0000, 500);
// Reset cat position and reduce score - keep at horizontal center
self.x = 1024;
self.y = shelfLevels[2] - 208;
self.targetShelfLevel = 2;
self.currentShelfLevel = 2;
LK.setScore(Math.max(0, LK.getScore() - 50));
scoreTxt.setText(LK.getScore());
}
}
// Check for collisions with dogs - cat can kill dog by falling on it
for (var i = dogs.length - 1; i >= 0; i--) {
var dog = dogs[i];
if (self.intersects(dog) && self.isJumping && self.y < dog.y - 20) {
// Cat falls on dog and kills it
LK.getSound('dogBark').play();
LK.effects.flashObject(self, 0x00ff00, 500);
LK.setScore(LK.getScore() + 200);
scoreTxt.setText(LK.getScore());
// Remove dog from game
dog.destroy();
dogs.splice(i, 1);
// Stop hiding behavior if this was the hide target
if (dog === self.hideTarget) {
self.isHiding = false;
self.hideTarget = null;
}
}
}
// Check if cat reaches world boundaries and lose life
if (!self.isInvulnerable && (self.x <= -150 || self.x >= 6550)) {
// Cat reaches world limit and loses a life
self.lives--;
self.isInvulnerable = true;
self.invulnerabilityTimer = 120; // 2 seconds of invulnerability
LK.getSound('catFall').play();
LK.effects.flashScreen(0xff0000, 1000);
// Dramatic fall animation
tween(self, {
y: 2732 + 200 // Fall off screen bottom
}, {
duration: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
// Reset cat position after fall - keep at horizontal center
self.x = 1024;
self.y = shelfLevels[2] - 208;
self.targetShelfLevel = 2;
self.currentShelfLevel = 2;
}
});
// Update lives display
livesText.setText('Lives: ' + self.lives);
// Check for game over
if (self.lives <= 0) {
LK.showGameOver();
}
LK.setScore(Math.max(0, LK.getScore() - 100));
scoreTxt.setText(LK.getScore());
}
// Check for collisions with separators - only on same shelf level
for (var i = separators.length - 1; i >= 0; i--) {
var separator = separators[i];
// Calculate which shelf level the separator is on
var sepShelfLevel = -1;
for (var level = 0; level < 5; level++) {
if (Math.abs(separator.y - (shelfLevels[level] - 150)) < 50) {
sepShelfLevel = level;
break;
}
}
// Only collide if on same shelf level
if (self.intersects(separator) && separator.isBlocking && !self.isInvulnerable && sepShelfLevel === self.currentShelfLevel) {
// Cat hits separator and loses a life
self.lives--;
self.isInvulnerable = true;
self.invulnerabilityTimer = 120; // 2 seconds of invulnerability
LK.getSound('catFall').play();
LK.effects.flashScreen(0xff0000, 1000);
// Dramatic fall animation
tween(self, {
y: 2732 + 200 // Fall off screen bottom
}, {
duration: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
// Reset cat position after fall - keep at horizontal center
self.x = 1024;
self.y = shelfLevels[2] - 208;
self.targetShelfLevel = 2;
self.currentShelfLevel = 2;
}
});
// Update lives display
livesText.setText('Lives: ' + self.lives);
// Check for game over
if (self.lives <= 0) {
LK.showGameOver();
}
LK.setScore(Math.max(0, LK.getScore() - 100));
scoreTxt.setText(LK.getScore());
}
}
// Handle electrocution
if (self.isElectrocuted === undefined) {
self.isElectrocuted = false;
self.electrocutionTimer = 0;
}
if (self.isElectrocuted) {
self.electrocutionTimer--;
// Cat cannot move when electrocuted
self.speed = 0;
// Switch to electrocuted asset
catGraphics.visible = false;
self.catElectrocutedGraphics.visible = true;
// Electric flash effect on electrocuted graphics
var electricFlash = Math.sin(LK.ticks * 2) > 0;
self.catElectrocutedGraphics.tint = electricFlash ? 0x00FFFF : 0xFFFFFF;
self.catElectrocutedGraphics.alpha = 0.7 + Math.sin(LK.ticks * 1.5) * 0.3;
// Update scale to match direction
self.catElectrocutedGraphics.scaleX = self.direction > 0 ? 2 : -2;
self.catElectrocutedGraphics.scaleY = 2;
if (self.electrocutionTimer <= 0) {
self.isElectrocuted = false;
self.speed = self.isLaserMode ? self.laserSpeed : self.normalSpeed;
// Switch back to normal cat
catGraphics.visible = true;
self.catElectrocutedGraphics.visible = false;
catGraphics.tint = 0xFFFFFF;
catGraphics.alpha = 1;
}
}
// Handle soap slipping
if (self.isSlipping === undefined) {
self.isSlipping = false;
self.slipTimer = 0;
self.originalDirection = self.direction;
}
if (self.isSlipping) {
self.slipTimer--;
// Cat slides uncontrollably in random directions
if (self.slipTimer % 30 === 0) {
// Change direction every 0.5 seconds
self.direction = Math.random() < 0.5 ? 1 : -1;
}
// Slipping animation - cat tilts side to side
var tilt = Math.sin(LK.ticks * 0.4) * 0.3;
catGraphics.rotation = tilt;
catGraphics.alpha = 0.8; // Slightly transparent while slipping
if (self.slipTimer <= 0) {
self.isSlipping = false;
self.direction = self.originalDirection;
catGraphics.rotation = 0;
catGraphics.alpha = 1;
// Switch back to normal cat
self.gatoEnjabonado.visible = false;
catGraphics.visible = true;
}
}
// Handle lamp immunity timer
if (self.lampImmunity === undefined) {
self.lampImmunity = false;
self.lampImmunityTimer = 0;
}
if (self.lampImmunity) {
self.lampImmunityTimer--;
if (self.lampImmunityTimer <= 0) {
self.lampImmunity = false;
}
}
// Handle bubble floating mechanics
if (self.isInBubble === undefined) {
self.isInBubble = false;
self.bubbleTimer = 0;
self.bubbleFloatSpeed = -4; // Negative for upward movement - like a helium balloon
self.originalTargetShelf = self.targetShelfLevel;
}
if (self.isInBubble) {
self.bubbleTimer--;
// Float upward continuously like a real bubble/balloon
self.y += self.bubbleFloatSpeed;
// Add gentle side-to-side floating motion like real bubbles
var sideFloat = Math.sin(LK.ticks * 0.05) * 1.5;
self.x += sideFloat;
// Gradually increase floating speed as it goes up (buoyancy effect)
if (self.bubbleFloatSpeed > -8) {
self.bubbleFloatSpeed -= 0.02; // Accelerate upward gradually
}
// Check which shelf level we're passing through and update target
for (var level = 4; level >= 0; level--) {
var shelfY = shelfLevels[level] - 208;
if (self.y <= shelfY + 50 && self.y >= shelfY - 50) {
self.targetShelfLevel = level;
break;
}
}
// Gentle floating animation with tween - more bubble-like
if (LK.ticks % 90 === 0) {
// Every 1.5 seconds - slower, more gentle
tween(catGraphics, {
scaleX: Math.abs(catGraphics.scaleX) * 1.05,
scaleY: catGraphics.scaleY * 1.15
}, {
duration: 750,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(catGraphics, {
scaleX: Math.abs(catGraphics.scaleX) / 1.05,
scaleY: catGraphics.scaleY / 1.15
}, {
duration: 750,
easing: tween.easeInOut
});
}
});
}
// Bubble bursts after timer expires
if (self.bubbleTimer <= 0) {
self.isInBubble = false;
// Reset bubble float speed
self.bubbleFloatSpeed = -4;
// Find nearest shelf level to current position
var nearestShelf = 0;
var minDistance = Math.abs(self.y - (shelfLevels[0] - 208));
for (var level = 1; level < 5; level++) {
var distance = Math.abs(self.y - (shelfLevels[level] - 208));
if (distance < minDistance) {
minDistance = distance;
nearestShelf = level;
}
}
// Land on nearest shelf with bounce effect
self.targetShelfLevel = nearestShelf;
self.currentShelfLevel = nearestShelf;
tween(self, {
y: shelfLevels[nearestShelf] - 208
}, {
duration: 800,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Reset cat graphics to normal
catGraphics.scaleY = Math.abs(catGraphics.scaleY);
catGraphics.scaleX = self.direction > 0 ? 2 : -2;
// Flash effect when landing
LK.effects.flashObject(self, 0x87CEEB, 500);
}
});
}
}
// Handle invulnerability timer
if (self.isInvulnerable) {
self.invulnerabilityTimer--;
// Flash effect during invulnerability (only if not electrocuted)
if (!self.isElectrocuted) {
catGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5;
if (self.catElectrocutedGraphics) {
self.catElectrocutedGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5;
}
}
if (self.invulnerabilityTimer <= 0) {
self.isInvulnerable = false;
if (!self.isElectrocuted) {
catGraphics.alpha = 1;
if (self.catElectrocutedGraphics) {
self.catElectrocutedGraphics.alpha = 1;
}
}
}
}
// Check for collisions with lamps - only on same shelf level
for (var i = lamps.length - 1; i >= 0; i--) {
var lamp = lamps[i];
// Calculate which shelf level the lamp is on
var lampShelfLevel = -1;
for (var level = 0; level < 5; level++) {
if (Math.abs(lamp.y - shelfLevels[level]) < 50) {
lampShelfLevel = level;
break;
}
}
// Only collide if on same shelf level and not immune to lamps
if (self.intersects(lamp) && !lamp.isFalling && !self.isElectrocuted && !self.lampImmunity && lampShelfLevel === self.currentShelfLevel) {
lamp.startFalling();
LK.setScore(LK.getScore() + 15);
scoreTxt.setText(LK.getScore());
// Update objects knocked down counter based on actual remaining objects
var actualObjectsRemaining = shelfObjects.length;
objectsKnockedDown = totalObjectsToKnock - actualObjectsRemaining;
storage.objectsKnockedDown = objectsKnockedDown;
// Check if all objects have been knocked down
if (actualObjectsRemaining <= 0) {
// Player wins when all objects are knocked down - reset storage for new game
storage.totalObjectsToKnock = 0;
storage.objectsKnockedDown = 0;
LK.showYouWin();
return;
}
// Activate zarpazo mode when knocking lamp
self.activateZarpazo();
}
}
// Check for soap collision - only on same shelf level and causes floating upward and downward
var _loop = function _loop() {
soap = soaps[i]; // Calculate which shelf level the soap is on
soapShelfLevel = -1;
for (level = 0; level < 5; level++) {
if (Math.abs(soap.y - (shelfLevels[level] - 40)) < 50) {
soapShelfLevel = level;
break;
}
}
// Only collide if on same shelf level
if (self.intersects(soap) && !soap.hasBeenUsed && !self.isSlipping && soapShelfLevel === self.currentShelfLevel) {
// Cat floats upward and downward once then returns
var _floatUpAndDown = function floatUpAndDown() {
// Stop any existing tweens on cat position
tween.stop(self, {
y: true
});
// Float upward to top of screen
tween(self, {
y: -100
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Float back down to bottom of screen
tween(self, {
y: 2732 + 100
}, {
duration: 2500,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Always return to shelf level when floating ends
self.isSlipping = false;
self.slipTimer = 0;
self.direction = self.originalDirection;
catGraphics.rotation = 0;
catGraphics.alpha = 1;
// Switch back to normal cat
self.gatoEnjabonado.visible = false;
catGraphics.visible = true;
// Return to current shelf level
tween(self, {
y: shelfLevels[self.currentShelfLevel] - 208
}, {
duration: 1000,
easing: tween.bounceOut
});
}
});
}
});
};
soap.hasBeenUsed = true;
// Cat starts slipping for 3 seconds - no life reduction
self.isSlipping = true;
self.slipTimer = 180; // 3 seconds at 60fps
self.originalDirection = self.direction;
// Switch to soapy cat asset
catGraphics.visible = false;
self.gatoEnjabonado.visible = true;
// Play slip sound
LK.getSound('soapSlip').play();
_floatUpAndDown();
// Visual effect - soap disappears with tween
tween(soap, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
soap.destroy();
var index = soaps.indexOf(soap);
if (index > -1) {
soaps.splice(index, 1);
}
}
});
// Flash screen light blue for soap effect
LK.effects.flashScreen(0x87CEEB, 800);
return 1; // break
}
},
soap,
soapShelfLevel,
level;
for (var i = soaps.length - 1; i >= 0; i--) {
if (_loop()) break;
}
// Check for laser pointer pickup - only on same shelf level
for (var i = laserPointers.length - 1; i >= 0; i--) {
var pointer = laserPointers[i];
// Calculate which shelf level the laser pointer is on
var pointerShelfLevel = -1;
for (var level = 0; level < 5; level++) {
if (Math.abs(pointer.y - (shelfLevels[level] - 75)) < 50) {
pointerShelfLevel = level;
break;
}
}
// Only collide if on same shelf level
if (self.intersects(pointer) && pointerShelfLevel === self.currentShelfLevel) {
self.isLaserMode = true;
self.laserModeTimer = 300; // 5 seconds at 60fps
self.speed = self.laserSpeed;
LK.getSound('laserPickup').play();
pointer.destroy();
laserPointers.splice(i, 1);
// Create laser dot
if (!laserDot) {
laserDot = game.addChild(LK.getAsset('laserDot', {
anchorX: 0.5,
anchorY: 0.5
}));
}
laserDot.x = self.x + 100;
laserDot.y = self.y;
laserDot.visible = false; // Hide the laser dot
// Activate zarpazo mode when picking up laser pointer
self.activateZarpazo();
break;
}
}
};
return self;
});
var DangerousObject = Container.expand(function () {
var self = Container.call(this);
var dangerousGraphics = self.attachAsset('dangerousObject', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.isFalling = false;
self.fallSpeed = 0;
self.isDangerous = true;
self.pulseTimer = 0;
self.startFalling = function () {
self.isFalling = true;
self.fallSpeed = 2;
self.isDangerous = false; // Not dangerous when falling
// Play dangerous object falling sound
LK.getSound('dangerousFall').play();
};
self.update = function () {
if (!self.isFalling) {
// Pulse effect to show it's dangerous
self.pulseTimer++;
var scale = 1 + Math.sin(self.pulseTimer * 0.15) * 0.3;
dangerousGraphics.scaleX = scale;
dangerousGraphics.scaleY = scale;
} else {
self.y += self.fallSpeed;
self.fallSpeed += 0.2; // Gravity
self.rotation += 0.1;
if (self.y > 2732 + 50) {
self.destroy();
var index = dangerousObjects.indexOf(self);
if (index > -1) {
dangerousObjects.splice(index, 1);
}
}
}
};
return self;
});
var Dog = Container.expand(function () {
var self = Container.call(this);
var dogGraphics = self.attachAsset('dog', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.speed = 8; // Much faster dog movement
self.direction = 1;
self.alertRadius = 200;
self.pulseTimer = 0;
self.barkTimer = 0;
self.isBarkingOpen = false;
self.dogCloseGraphics = null;
self.isTweening = false; // Flag for smooth movement
self.update = function () {
// Pulse effect to show dog is dangerous
self.pulseTimer++;
var scale = 1 + Math.sin(self.pulseTimer * 0.15) * 0.2;
dogGraphics.scaleX = scale * self.direction;
dogGraphics.scaleY = scale;
// Move mouse with smooth tweening and dynamic scaling
if (!self.isTweening) {
var targetX = self.x + self.speed * self.direction * 30; // Move distance over 0.5 seconds
tween(self, {
x: targetX
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isTweening = false;
}
});
self.isTweening = true;
}
// Change direction randomly
// Change direction randomly or when hitting boundaries with bounce animation
if (Math.random() < 0.008) {
self.direction *= -1;
tween(dogGraphics, {
scaleX: scale * self.direction * 1.3
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(dogGraphics, {
scaleX: scale * self.direction
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
// Handle barking animation - 2 times per second (every 15 ticks = 4 times per second, so every 30 ticks = 2 times per second)
self.barkTimer++;
if (self.barkTimer >= 30) {
// Change every 0.5 seconds (30 ticks) for 2 times per second
self.barkTimer = 0;
if (self.isBarkingOpen) {
// Switch to normal dog with smooth tween
tween(dogGraphics, {
alpha: 1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
dogGraphics.visible = true;
if (self.dogCloseGraphics) {
self.dogCloseGraphics.visible = false;
}
self.isBarkingOpen = false;
}
});
} else {
// Switch to barking dog (close mouth) with smooth tween
if (!self.dogCloseGraphics) {
self.dogCloseGraphics = self.attachAsset('Dog-close', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
}
tween(self.dogCloseGraphics, {
alpha: 1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
dogGraphics.visible = false;
self.dogCloseGraphics.visible = true;
self.dogCloseGraphics.scaleX = scale * self.direction;
self.dogCloseGraphics.scaleY = scale;
self.isBarkingOpen = true;
}
});
}
}
// Sync dog-close graphics scale with regular graphics
if (self.dogCloseGraphics && self.dogCloseGraphics.visible) {
self.dogCloseGraphics.scaleX = scale * self.direction;
self.dogCloseGraphics.scaleY = scale;
}
// Check if cat is within alert radius for barking only
var distance = Math.abs(self.x - cat.x) + Math.abs(self.y - cat.y);
if (distance < self.alertRadius) {
if (Math.random() < 0.08) {
// Increased from 0.02 to 0.08 for more frequent barking
LK.getSound('dogBark').play();
}
}
// Additional barking when mouth opens (barking animation)
if (self.barkTimer === 0 && !self.isBarkingOpen && Math.random() < 0.7) {
// 70% chance to bark when switching to open mouth
LK.getSound('dogBark').play();
}
};
return self;
});
var Lamp = Container.expand(function () {
var self = Container.call(this);
// Create visible light bulb first (behind)
var lightBulbGraphics = self.attachAsset('lightbulb', {
anchorX: 0.5,
anchorY: 1,
scaleX: 2.5,
scaleY: 2.5
});
lightBulbGraphics.y = -130; // Position higher above lamp base
// Create lamp base second (in front)
var lampGraphics = self.attachAsset('lamp', {
anchorX: 0.5,
anchorY: 1,
scaleX: 3,
scaleY: 3
});
self.isFalling = false;
self.fallSpeed = 0;
self.pulseTimer = 0;
self.hasElectrocuted = false;
self.startFalling = function () {
if (self.isFalling) {
return;
}
self.isFalling = true;
self.fallSpeed = 2;
// Play lamp falling sound
LK.getSound('objectHit').play();
// Add falling animation with rotation
tween(self, {
rotation: self.rotation + Math.PI * 2
}, {
duration: 1500,
easing: tween.easeOut
});
};
self.update = function () {
if (!self.isFalling) {
// Gentle glow pulse effect for the light bulb using tween
self.pulseTimer++;
// Create pulsing glow effect with tint instead of scaling
if (self.pulseTimer % 120 === 0) {
// Every 2 seconds, create a glow pulse
tween(lightBulbGraphics, {
tint: 0xFFFF88 // Bright yellow glow
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(lightBulbGraphics, {
tint: 0xFFFFFF // Back to white
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}
} else {
self.y += self.fallSpeed;
self.fallSpeed += 0.3; // Gravity
// Check for collision with cat when falling
if (!self.hasElectrocuted && self.intersects(cat)) {
self.hasElectrocuted = true;
// Electrocute cat for 2 seconds (reduced from 3)
cat.isElectrocuted = true;
cat.electrocutionTimer = 120; // 2 seconds at 60fps
// Add temporary immunity to prevent immediate re-electrocution
cat.lampImmunity = true;
cat.lampImmunityTimer = 240; // 4 seconds immunity
// Play electric shock sound
LK.getSound('electricShock').play();
// Flash screen blue/white for electric effect
LK.effects.flashScreen(0x00FFFF, 1000);
// Push cat away from lamp with stronger force to prevent getting stuck
var pushDirection = cat.x > self.x ? 1 : -1;
var pushDistance = 250; // Increased from 150 to 250
var targetX = cat.x + pushDistance * pushDirection;
// Ensure target position is within game bounds
targetX = Math.max(200, Math.min(targetX, 3800));
// Stop any existing movement tweens on cat
tween.stop(cat, {
x: true
});
// Make cat get pushed away with stronger force
tween(cat, {
x: targetX
}, {
duration: 200,
// Faster push
easing: tween.easeOut,
onFinish: function onFinish() {
// Additional push to ensure separation
var secondPushX = targetX + pushDirection * 100;
secondPushX = Math.max(200, Math.min(secondPushX, 3800));
tween(cat, {
x: secondPushX
}, {
duration: 150,
easing: tween.easeOut
});
}
});
}
// Remove when off screen
if (self.y > 2732 + 100) {
self.destroy();
var index = lamps.indexOf(self);
if (index > -1) {
lamps.splice(index, 1);
}
}
}
};
return self;
});
var LaserPointer = Container.expand(function () {
var self = Container.call(this);
var pointerGraphics = self.attachAsset('laserPointer', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.pulseTimer = 0;
self.update = function () {
self.pulseTimer++;
// Hide laser pointer
pointerGraphics.visible = false;
// Dynamic pulsing with tween animation
if (self.pulseTimer % 120 === 0) {
// Every 2 seconds
tween(pointerGraphics, {
scaleX: 6,
scaleY: 6
}, {
duration: 600,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(pointerGraphics, {
scaleX: 4,
scaleY: 4
}, {
duration: 400,
easing: tween.bounceOut
});
}
});
}
// Add rotation animation for more visual appeal
tween(pointerGraphics, {
rotation: pointerGraphics.rotation + Math.PI * 2
}, {
duration: 3000,
easing: tween.linear
});
};
return self;
});
var Mouse = Container.expand(function () {
var self = Container.call(this);
var mouseGraphics = self.attachAsset('mouse', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.speed = 12; // Much faster mouse movement
self.direction = 1;
self.isBeingChased = false;
self.pulseTimer = 0;
self.isTweening = false; // Flag for smooth movement
self.update = function () {
// Pulse effect to make mouse visible
self.pulseTimer++;
var scale = 1 + Math.sin(self.pulseTimer * 0.2) * 0.3;
mouseGraphics.scaleX = scale * self.direction;
mouseGraphics.scaleY = scale;
// Move mouse
self.x += self.speed * self.direction;
// Change direction randomly or when hitting boundaries
if (Math.random() < 0.01 || self.x < cat.x - 600 || self.x > cat.x + 600) {
self.direction *= -1;
// Add dynamic bounce effect when changing direction
tween(mouseGraphics, {
scaleX: scale * self.direction * 1.5,
scaleY: scale * 1.2
}, {
duration: 300,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(mouseGraphics, {
scaleX: scale * self.direction,
scaleY: scale
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
// Mouse squeaks when cat gets close
var distance = Math.abs(self.x - cat.x) + Math.abs(self.y - cat.y);
if (distance < 100 && !self.isBeingChased) {
self.isBeingChased = true;
LK.getSound('mouseSqueak').play();
}
};
return self;
});
var Separator = Container.expand(function () {
var self = Container.call(this);
var separatorGraphics = self.attachAsset('separator', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.isBlocking = true;
return self;
});
var ShelfObject = Container.expand(function (objectType) {
var self = Container.call(this);
var assetName = 'object' + (objectType || 1);
var objectGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.isFalling = false;
self.fallSpeed = 0;
self.startFalling = function () {
self.isFalling = true;
self.fallSpeed = 2;
// Play sound based on object type
var soundId = 'objectFall' + (objectType || 1);
LK.getSound(soundId).play();
// Add dynamic falling animation with scaling and rotation
tween(objectGraphics, {
scaleX: 6,
scaleY: 6
}, {
duration: 800,
easing: tween.bounceOut
});
// Add spinning effect while falling
var spinDirection = Math.random() < 0.5 ? 1 : -1;
tween(self, {
rotation: self.rotation + Math.PI * 4 * spinDirection
}, {
duration: 2000,
easing: tween.easeOut
});
};
self.update = function () {
if (self.isFalling) {
self.y += self.fallSpeed;
self.fallSpeed += 0.2; // Gravity
self.rotation += 0.1;
// Check for collisions with dogs when falling
for (var i = dogs.length - 1; i >= 0; i--) {
var dog = dogs[i];
if (self.intersects(dog)) {
// Object hits dog and defeats it
LK.getSound('objectHit').play();
LK.effects.flashObject(dog, 0xff0000, 500);
LK.setScore(LK.getScore() + 200);
scoreTxt.setText(LK.getScore());
// Remove dog from game
dog.destroy();
dogs.splice(i, 1);
// Stop hiding behavior if this was the hide target
if (dog === cat.hideTarget) {
cat.isHiding = false;
cat.hideTarget = null;
}
// Remove the object that hit the dog
self.destroy();
var index = shelfObjects.indexOf(self);
if (index > -1) {
shelfObjects.splice(index, 1);
}
return; // Exit early since object is destroyed
}
}
if (self.y > 2732 + 50) {
self.destroy();
var index = shelfObjects.indexOf(self);
if (index > -1) {
shelfObjects.splice(index, 1);
}
}
}
};
return self;
});
var Soap = Container.expand(function () {
var self = Container.call(this);
var soapGraphics = self.attachAsset('soap', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
self.pulseTimer = 0;
self.hasBeenUsed = false;
self.update = function () {
// Gentle shine effect to make soap visible
self.pulseTimer++;
var shine = 1 + Math.sin(self.pulseTimer * 0.15) * 0.2;
soapGraphics.alpha = shine;
soapGraphics.tint = 0xF0F8FF; // Light blue tint for soap
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var cat;
var shelfObjects = [];
var dangerousObjects = [];
var laserPointers = [];
var laserDot = null;
var mice = [];
var dogs = [];
var separators = [];
var lamps = [];
var soaps = [];
var nextMouseSpawn = 0;
var nextDogSpawn = 0;
var nextSeparatorSpawn = 0;
var nextLampSpawn = 0;
var nextSoapSpawn = 0;
var shelfLevels = [500, 1000, 1500, 2000, 2500]; // Y positions for 5 shelf levels aligned with object feet
var shelves = [];
var nextObjectSpawn = 0;
var nextDangerousSpawn = 0;
var nextLaserSpawn = 0;
var cameraX = 0;
var gameTimer = 0;
var TIME_LIMIT = 3600; // 60 seconds at 60fps (3600 ticks)
var totalObjectsToKnock = storage.totalObjectsToKnock || 0;
var objectsKnockedDown = storage.objectsKnockedDown || 0;
// Create score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
// Create lives display
var livesText = new Text2('Lives: 3', {
size: 60,
fill: 0xFF6B6B
});
livesText.anchor.set(0, 0);
LK.gui.topLeft.addChild(livesText);
livesText.x = 120; // Avoid the menu icon area
livesText.y = 50;
// Create timer display
var timerText = new Text2('Time: 60', {
size: 60,
fill: 0xFFD700
});
timerText.anchor.set(1, 0);
LK.gui.topRight.addChild(timerText);
timerText.x = -20;
timerText.y = 50;
// Create progress display
var progressText = new Text2('Objects: ' + (totalObjectsToKnock - objectsKnockedDown) + '/' + totalObjectsToKnock, {
size: 60,
fill: 0x00FF00
});
progressText.anchor.set(0.5, 0);
LK.gui.top.addChild(progressText);
progressText.y = 120;
// Claw button removed - zarpazo is now automatic when picking up objects
// Create shelves first - expanded to 64 shelves wide (16 sections per level)
for (var level = 0; level < 5; level++) {
for (var section = 0; section < 16; section++) {
var shelf = game.addChild(LK.getAsset('shelf', {
anchorX: 0,
anchorY: 1
}));
shelf.x = section * 400;
shelf.y = shelfLevels[level];
shelves.push(shelf);
}
}
// Initialize objects at the beginning of the game with persistence
if (totalObjectsToKnock === 0) {
// First time playing - set fixed limit and distribute objects
totalObjectsToKnock = 25; // Fixed limit of objects to knock down
objectsKnockedDown = 0;
storage.totalObjectsToKnock = totalObjectsToKnock;
storage.objectsKnockedDown = objectsKnockedDown;
}
// Always distribute objects at game start (they persist until all are knocked down)
if (objectsKnockedDown < totalObjectsToKnock) {
// Distribute remaining objects across 64 shelves at game start
var objectsToPlace = totalObjectsToKnock - objectsKnockedDown;
for (var i = 0; i < objectsToPlace; i++) {
var objectType = Math.floor(Math.random() * 3) + 1;
var obj = new ShelfObject(objectType);
var level = Math.floor(Math.random() * 5);
var xPos = 100 + i % 60 * 100 + Math.random() * 50; // Distribute within 6000px world width
obj.x = xPos;
obj.y = shelfLevels[level] - 75; // Position on top of shelf
game.addChild(obj);
shelfObjects.push(obj);
}
}
// Create barrier columns at start and end of game world
var leftBarriers = [];
var rightBarriers = [];
// Create left barrier column (at the beginning)
for (var level = 0; level < 5; level++) {
var leftBarrier = game.addChild(new Separator());
leftBarrier.x = -200; // Position at the very start
leftBarrier.y = shelfLevels[level] - 150; // Position on each shelf level
leftBarrier.isBlocking = true;
leftBarriers.push(leftBarrier);
}
// Create right barrier column (at the end) - positioned for 64 shelves wide
for (var level = 0; level < 5; level++) {
var rightBarrier = game.addChild(new Separator());
rightBarrier.x = 6400; // Position at end of 16 sections (16 * 400 = 6400)
rightBarrier.y = shelfLevels[level] - 150; // Position on each shelf level
rightBarrier.isBlocking = true;
rightBarriers.push(rightBarrier);
}
// Create cat after shelves so it appears in front
cat = game.addChild(new Cat());
// Position cat at horizontal center of screen
cat.x = 1024; // Center of screen horizontally (2048/2 = 1024)
cat.targetShelfLevel = 2; // Start on middle shelf
cat.currentShelfLevel = cat.targetShelfLevel;
cat.y = shelfLevels[cat.targetShelfLevel] - 208; // Position cat to stand on shelf (accounting for cat height and anchor) - raised by 30px
// Handle swipe controls
var swipeStartX = 0;
var swipeStartY = 0;
var isDragging = false;
game.down = function (x, y, obj) {
swipeStartX = x;
swipeStartY = y;
isDragging = true;
// If in laser mode, move laser dot
if (cat.isLaserMode && laserDot) {
laserDot.x = x;
laserDot.y = y;
laserDot.visible = false; // Keep laser dot hidden
}
};
game.move = function (x, y, obj) {
// If in laser mode, move laser dot
if (cat.isLaserMode && laserDot) {
laserDot.x = x;
laserDot.y = y;
laserDot.visible = false; // Keep laser dot hidden
}
};
game.up = function (x, y, obj) {
if (!isDragging) {
return;
}
isDragging = false;
var deltaX = x - swipeStartX;
var deltaY = y - swipeStartY;
var swipeDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (swipeDistance < 50) {
return;
} // Minimum swipe distance
if (Math.abs(deltaY) > Math.abs(deltaX)) {
// Vertical swipe - change shelf level
if (deltaY < 0 && cat.targetShelfLevel > 0) {
cat.targetShelfLevel--; // Swipe up
} else if (deltaY > 0 && cat.targetShelfLevel < 4) {
cat.targetShelfLevel++; // Swipe down
}
} else {
// Horizontal swipe - change direction
if (!cat.isLaserMode) {
if (deltaX > 0) {
cat.direction = 1; // Right
} else {
cat.direction = -1; // Left
}
}
}
};
// Spawn objects and laser pointers
function spawnObject() {
// Objects are distributed at the beginning and remain persistent
// No automatic spawning during gameplay
return;
}
function spawnDangerousObject() {
if (LK.ticks < nextDangerousSpawn) {
return;
}
var dangerousObj = new DangerousObject();
var level = Math.floor(Math.random() * 5);
var xPos = cat.x + Math.random() * 1000 + 1500; // Spawn further ahead, outside visible area
dangerousObj.x = xPos;
dangerousObj.y = shelfLevels[level] - 75; // Position on top of shelf
game.addChild(dangerousObj);
dangerousObjects.push(dangerousObj);
nextDangerousSpawn = LK.ticks + 300 + Math.random() * 450; // 10% spawn rate - 5-12.5 seconds
}
function spawnLaserPointer() {
if (LK.ticks < nextLaserSpawn) {
return;
}
var pointer = new LaserPointer();
var level = Math.floor(Math.random() * 5);
var xPos = cat.x + Math.random() * 600 + 1400; // Spawn further ahead, outside visible area
pointer.x = xPos;
pointer.y = shelfLevels[level] - 75; // Position on top of shelf
game.addChild(pointer);
laserPointers.push(pointer);
nextLaserSpawn = LK.ticks + 600 + Math.random() * 600; // 10-20 seconds
}
function spawnMouse() {
if (LK.ticks < nextMouseSpawn) {
return;
}
var mouse = new Mouse();
var level = Math.floor(Math.random() * 5);
var xPos = cat.x + (Math.random() < 0.5 ? -1500 : 1500); // Spawn outside visible area on either side
mouse.x = xPos;
mouse.y = shelfLevels[level] - 75; // Position on top of shelf
game.addChild(mouse);
mice.push(mouse);
nextMouseSpawn = LK.ticks + 4500 + Math.random() * 3000; // 10% spawn rate - 75-125 seconds
}
function spawnDog() {
if (LK.ticks < nextDogSpawn) {
return;
}
var dog = new Dog();
var level = Math.floor(Math.random() * 5);
var xPos = cat.x + (Math.random() < 0.5 ? -1500 : 1500); // Spawn outside visible area on either side
dog.x = xPos;
dog.y = shelfLevels[level] - 75; // Position on top of shelf
game.addChild(dog);
dogs.push(dog);
nextDogSpawn = LK.ticks + 12000 + Math.random() * 9000; // 10% spawn rate - 200-350 seconds
}
function spawnSeparator() {
if (LK.ticks < nextSeparatorSpawn) {
return;
}
var separator = new Separator();
var level = Math.floor(Math.random() * 5);
var xPos = cat.x + Math.random() * 1200 + 1400; // Spawn further ahead, outside visible area
separator.x = xPos;
separator.y = shelfLevels[level] - 150; // Position higher above shelf
game.addChild(separator);
separators.push(separator);
nextSeparatorSpawn = LK.ticks + 600 + Math.random() * 900; // 10% spawn rate - 10-25 seconds
}
function spawnLamp() {
if (LK.ticks < nextLampSpawn) {
return;
}
var lamp = new Lamp();
var level = Math.floor(Math.random() * 5);
var xPos = cat.x + Math.random() * 800 + 1500; // Spawn further ahead, outside visible area
lamp.x = xPos;
lamp.y = shelfLevels[level]; // Position on shelf
game.addChild(lamp);
lamps.push(lamp);
nextLampSpawn = LK.ticks + 900 + Math.random() * 1200; // 15-35 seconds
}
function spawnSoap() {
if (LK.ticks < nextSoapSpawn) {
return;
}
var soap = new Soap();
var level = Math.floor(Math.random() * 5);
var xPos = cat.x + Math.random() * 600 + 1400; // Spawn further ahead, outside visible area
soap.x = xPos;
soap.y = shelfLevels[level] - 40; // Position on shelf
game.addChild(soap);
soaps.push(soap);
nextSoapSpawn = LK.ticks + 1200 + Math.random() * 1800; // 20-50 seconds
}
// Camera follow with smooth tweening
function updateCamera() {
var targetCameraX = cat.x - 1024; // Center cat on screen (2048/2 = 1024)
// Smooth camera movement with easing
if (Math.abs(cameraX - targetCameraX) > 5) {
tween.stop(game, {
x: true
}); // Stop any existing camera tween
tween(game, {
x: -targetCameraX
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
cameraX = targetCameraX;
}
});
} else {
cameraX = targetCameraX;
game.x = -cameraX;
}
// Keep world size limited to 64 shelves - no dynamic expansion
var rightmostShelf = Math.max.apply(Math, shelves.map(function (s) {
return s.x;
}));
// No shelf expansion - world stays at fixed 64 shelves wide (6400px)
}
// Play main theme music
LK.playMusic('mainTheme');
game.update = function () {
gameTimer++;
var remainingTime = Math.max(0, Math.ceil((TIME_LIMIT - gameTimer) / 60));
timerText.setText('Time: ' + remainingTime);
// Update progress display based on actual objects in game
var actualObjectsRemaining = shelfObjects.length;
var actualObjectsKnockedDown = totalObjectsToKnock - actualObjectsRemaining;
progressText.setText('Objects: ' + actualObjectsRemaining + '/' + totalObjectsToKnock);
// Check if time limit reached
if (gameTimer >= TIME_LIMIT) {
LK.showYouWin();
return;
}
spawnObject();
spawnDangerousObject();
spawnLaserPointer();
spawnMouse();
spawnDog();
spawnSeparator();
spawnLamp();
spawnSoap();
updateCamera();
// Keep all objects persistent - no cleanup during gameplay
// Objects remain in their positions until knocked down by the cat
// Only clean up non-persistent objects that spawn dynamically
for (var i = dangerousObjects.length - 1; i >= 0; i--) {
var dangerousObj = dangerousObjects[i];
if (dangerousObj.x < cameraX - 500) {
dangerousObj.destroy();
dangerousObjects.splice(i, 1);
}
}
for (var i = laserPointers.length - 1; i >= 0; i--) {
var pointer = laserPointers[i];
if (pointer.x < cameraX - 500) {
pointer.destroy();
laserPointers.splice(i, 1);
}
}
// Clean up separators
for (var i = separators.length - 1; i >= 0; i--) {
var separator = separators[i];
if (separator.x < cameraX - 500) {
separator.destroy();
separators.splice(i, 1);
}
}
// Clean up lamps only if they have fallen off screen, not just off camera
for (var i = lamps.length - 1; i >= 0; i--) {
var lamp = lamps[i];
if (lamp.y > 2732 + 100 && lamp.isFalling) {
lamp.destroy();
lamps.splice(i, 1);
}
}
// Clean up soaps only if they have been used and destroyed
for (var i = soaps.length - 1; i >= 0; i--) {
var soap = soaps[i];
if (soap.alpha <= 0 || soap.destroyed) {
soaps.splice(i, 1);
}
}
// Clean up mice
for (var i = mice.length - 1; i >= 0; i--) {
var mouse = mice[i];
if (mouse.x < cameraX - 600 || mouse.x > cameraX + 2500) {
if (mouse === cat.chaseTarget) {
cat.isChasing = false;
cat.chaseTarget = null;
}
mouse.destroy();
mice.splice(i, 1);
}
}
// Clean up dogs
for (var i = dogs.length - 1; i >= 0; i--) {
var dog = dogs[i];
if (dog.x < cameraX - 600 || dog.x > cameraX + 2500) {
if (dog === cat.hideTarget) {
cat.isHiding = false;
cat.hideTarget = null;
}
dog.destroy();
dogs.splice(i, 1);
}
}
// Remove laser dot when laser mode ends
if (!cat.isLaserMode && laserDot) {
laserDot.destroy();
laserDot = null;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -310,9 +310,9 @@
}
}
}
// Check if cat reaches world boundaries and lose life
- if (!self.isInvulnerable && (self.x <= -150 || self.x >= 1550)) {
+ if (!self.isInvulnerable && (self.x <= -150 || self.x >= 6550)) {
// Cat reaches world limit and loses a life
self.lives--;
self.isInvulnerable = true;
self.invulnerabilityTimer = 120; // 2 seconds of invulnerability
@@ -1259,11 +1259,11 @@
progressText.anchor.set(0.5, 0);
LK.gui.top.addChild(progressText);
progressText.y = 120;
// Claw button removed - zarpazo is now automatic when picking up objects
-// Create shelves first - reduced to 16 shelves wide (4 sections per level)
+// Create shelves first - expanded to 64 shelves wide (16 sections per level)
for (var level = 0; level < 5; level++) {
- for (var section = 0; section < 4; section++) {
+ for (var section = 0; section < 16; section++) {
var shelf = game.addChild(LK.getAsset('shelf', {
anchorX: 0,
anchorY: 1
}));
@@ -1281,15 +1281,15 @@
storage.objectsKnockedDown = objectsKnockedDown;
}
// Always distribute objects at game start (they persist until all are knocked down)
if (objectsKnockedDown < totalObjectsToKnock) {
- // Distribute remaining objects across 16 shelves at game start
+ // Distribute remaining objects across 64 shelves at game start
var objectsToPlace = totalObjectsToKnock - objectsKnockedDown;
for (var i = 0; i < objectsToPlace; i++) {
var objectType = Math.floor(Math.random() * 3) + 1;
var obj = new ShelfObject(objectType);
var level = Math.floor(Math.random() * 5);
- var xPos = 100 + i % 15 * 100 + Math.random() * 50; // Distribute within 1500px world width
+ var xPos = 100 + i % 60 * 100 + Math.random() * 50; // Distribute within 6000px world width
obj.x = xPos;
obj.y = shelfLevels[level] - 75; // Position on top of shelf
game.addChild(obj);
shelfObjects.push(obj);
@@ -1305,12 +1305,12 @@
leftBarrier.y = shelfLevels[level] - 150; // Position on each shelf level
leftBarrier.isBlocking = true;
leftBarriers.push(leftBarrier);
}
-// Create right barrier column (at the end) - positioned for 16 shelves wide
+// Create right barrier column (at the end) - positioned for 64 shelves wide
for (var level = 0; level < 5; level++) {
var rightBarrier = game.addChild(new Separator());
- rightBarrier.x = 1600; // Position at end of 4 sections (4 * 400 = 1600)
+ rightBarrier.x = 6400; // Position at end of 16 sections (16 * 400 = 6400)
rightBarrier.y = shelfLevels[level] - 150; // Position on each shelf level
rightBarrier.isBlocking = true;
rightBarriers.push(rightBarrier);
}
@@ -1490,13 +1490,13 @@
} else {
cameraX = targetCameraX;
game.x = -cameraX;
}
- // Keep world size limited to 16 shelves - no dynamic expansion
+ // Keep world size limited to 64 shelves - no dynamic expansion
var rightmostShelf = Math.max.apply(Math, shelves.map(function (s) {
return s.x;
}));
- // No shelf expansion - world stays at fixed 16 shelves wide (1600px)
+ // No shelf expansion - world stays at fixed 64 shelves wide (6400px)
}
// Play main theme music
LK.playMusic('mainTheme');
game.update = function () {
Tabla de madera vista de costado, muy fina. Pixel art. In-Game asset. 2d. High contrast. No shadows
Raton tipo pixel art earthworm jim, la personalidad del ratón debe ser frenética asustadizo como la de ten de ten y stimpy, debe estar en cuatro patas. In-Game asset. 2d. High contrast. No shadows
Un perro bobo ladrando con los ojos cerrados pixel art dientes grandes, estilo earthworm jim. In-Game asset. 2d. High contrast. No shadows
Una madera separadora de estantería pixel art estilo metal slug vista de perfil In-Game asset. 2d. High contrast. No shadows
plato con decoraciones de oro pixel art metal slug style. In-Game asset. 2d. High contrast. No shadows
un vaso con agua estilo pixel art metal slug. In-Game asset. 2d. High contrast. No shadows
Un jabon con espuma, pixel art, metal slug. In-Game asset. 2d. High contrast. No shadows
hazlo con fondo verde, con el mismo estilo dando un sarpazo con mirada burlona a la camara
hazlo con fondo verde, con el mismo estilo cerrando los dientes con fuerza y bronca
Con el mismo estilo, modo cauteloso con la boca cerrada
Un foco pixel art tipo metal slug. In-Game asset. 2d. High contrast. No shadows
Un velador con base muy simple, sin lampara, tipo pixel art meta slug. In-Game asset. 2d. High contrast. No shadows
El mudo gato con el mismo estilo pero electrocutado con fondo verde
puedes cambiar la posicion de las patas, es decir las que estan atras pasan adelante y viceversa, con el mismo estilo pixel art de la foto original y fondo azul
cambia la posicion de las piernas como si hubiese dado un paso con el mismo estilo pixel art
Maceta con una flor, pixel art metal slug. In-Game asset. 2d. High contrast. No shadows
Puedes encerrarlo en una burbuja
En medio de un salto con el mismo estilo pixel art y fondo verde
con cara arrogante tiene que tirar un beso a camara y mostrar un corazon, la imagen sarcastica y graciosa, con fondo verde
El gato de estar sentado sobre sus dos patas traseras señalando hacia adelante y mirando a la cámara como irónicamente porque no puedes seguir avanzando
una pecera con un pez durmiendo, con estilo pixel art de metal slug con fondo verde. In-Game asset. 2d. High contrast. No shadows
el gato asustado arqueado con los pelos parados con el mismo estilo pixel art
un iphone en pixel art que tenga en la pantalla un ninja con una estrella y un rollo de papel higienico estilo comico. In-Game asset. 2d. High contrast. No shadows
el pez asustadisimo con estilo comico sin sombra con fondo verde
imagina un portatil que tenga en la pantalla la imagen actual, debe ser pixel art y con estilo comico
quiero construir una columa cilindrica muy larga de madera, para eso tengo que recurrir a repetir assets uno arriba del otro , puedes crear un segmento que pueda repetirse en pixel art?. In-Game asset. 2d. High contrast. No shadows
necesito construir un background para un hud, color madera clarito con 2 tornillos en los extremos bien en los bordes, con un borde viselado pixel art, muchisimo mas ancho que alto (relacion 5 - 20 aprox). In-Game asset. 2d. High contrast. No shadows
imagina un fondo con el mismo estilo del juego, debe decir arriba, Catatack y tener un estilo gatuno, siempre en pixel art, en el medio de la imagen, pondre texto variable, debes dejar ese espacio libre.. In-Game asset. 2d. High contrast. No shadows
reimaginalo bailando como tony manero en fiebre de sabado por la noche con fondo verde
una bola de espejos tipo fiebre de sabado por la noche con estilo pixel art con el cable de donde cuelga largo, con fondo verde . In-Game asset. 2d. High contrast. No shadows
perro cayendo de mucha altura asustadisimo con el mismo estilo con fondo verde, muy gracioso
dibuja 3 zetas en vez de 2, manten el mismo estilo pixel art