Code edit (8 edits merged)
Please save this source code
User prompt
necesito que vidas stage objects y time tengan color oscuro y que esten todos en una linea, arriba de todo, y que se note mas el texto
User prompt
left barrier tambien debe bloquear al gato, creo que el problema es que como lo choca desde la derecha no detecta la colision, porque en right barrer lo hace ok ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (3 edits merged)
Please save this source code
User prompt
necesito bajar dangerousHitbox unos 459 px
Code edit (1 edits merged)
Please save this source code
User prompt
hay que reemplazar las barreras del comienzo y del final por el asset cube
Code edit (1 edits merged)
Please save this source code
User prompt
tanto la araña como el pez deben cambiar al asset de su caida, cuando el gato se topa con el fin del camino tambien debe actuar como cuando se topa con la barrera ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cuando choca una barrera y el usuario da la vuelta, inmediatamente debe volver al aset del gato caminando y caminar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cuando el gato se choca con una barrera debe alejarse unos 30 pixeles como cuando choca una lampara para que pueda escapar mas facil, solo debe quedar detenido un segundo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (19 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: laserPointers is not defined' in or related to this line: 'for (var i = laserPointers.length - 1; i >= 0; i--) {' Line Number: 3499
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (13 edits merged)
Please save this source code
User prompt
el perro es enemigo del gato, nunca puede aparecer en el mismo lugar, quiero agregar 4 tipos mas de objetos para que no sea tan repetitivo, "pecera, movil, portatil" deben estar repartidos entre los que ya hay, sin incrementar el numero de objetos por partida
User prompt
añade mas stages, a partir de la 10 el tiempo se baja en 4 segundos y el gato aumenta su velocidad un 10% para compensar, recuerda que el perro a partir de la segunda etapa debe aparecer y de ahi en todas las pantallas, genera un margen de area segura donde nace el gato para que cuando comienza un stage no este arriba de ni un obstaculo ni del perro ni de los objetos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
se debe repetir el proceso de los stages, debe haber al menos 10 stages ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
debes bajar otra vez al gato cuando festeja unos 50px, por otro lado el juego tiene varias etapas, cuando termina una debe seguir la etapa 2, reordenando los objetos y reduciendo 10 segundos del time, tambien debe aparecer el perro en la segunda etapa ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
en el festejo el punto de pivot debe estar en la parte inferior del asset, y debe hacer un flip en el eje y para girar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
el gato cuando termina el juego y festeja, esta unos 50 pixeles por encima del suelo
Code edit (1 edits merged)
Please save this source code
User prompt
El objetivo del juego sigue sin funcionar y al limpiar la pantalla el gato sigue caminando y el juego continúa, cuando no debería ser así, además las barreras que bloquean el camino aparecen a mitad de juego y deberían estar predeterminadas al comenzar el juego, el perro debe tumbar al gato t el gato debe comerse al ratón, eso no sirve
/**** * 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 }); var catStepGraphics = self.attachAsset('Cat-step', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); catStepGraphics.visible = false; self.walkAnimTimer = 0; self.isWalkAnimStep = false; 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; // Laser mode removed self.normalSpeed = 8; // Laser speed removed 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.gatoKissGraphics = self.attachAsset('gato-kiss', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); self.gatoKissGraphics.visible = false; self.isKissMode = false; self.catHitGraphics = self.attachAsset('cat-hit', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); self.catHitGraphics.visible = false; self.isHitMode = false; self.hitTimer = 0; self.catBlockGraphics = self.attachAsset('cat-block', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); self.catBlockGraphics.visible = false; self.isBlockMode = false; self.blockTimer = 0; self.isFloating = false; self.floatingTimer = 0; self.gatoBailaGraphics = self.attachAsset('gatoBaila', { anchorX: 0.5, anchorY: 1, // Use bottom anchor for proper grounding during dance scaleX: 2, scaleY: 2 }); self.gatoBailaGraphics.visible = false; self.isDancing = false; // Dance flip variables self.danceFlipTimer = 0; self.danceFlipDirection = 1; self.activateZarpazo = function () { LK.getSound('zarpazo').play(); if (self.isZarpazoMode || self.isKissMode) { return; } // Already in zarpazo or kiss mode self.isZarpazoMode = true; // Stop movement during zarpazo var originalSpeed = self.speed; self.speed = 0; // Create zarpazo graphics if not exists if (!self.zarpazoGraphics) { self.zarpazoGraphics = self.attachAsset('zarpazo', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); } // Hide all other cat graphics - only show zarpazo catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; // Show only zarpazo graphics self.zarpazoGraphics.visible = true; self.zarpazoGraphics.scaleX = 2 * self.direction; self.zarpazoGraphics.scaleY = 2; LK.getSound('zarpazo').play(); // Return to normal after zarpazo tween.stop(self, { isZarpazoMode: true }); // Stop any existing zarpazo tween LK.setTimeout(function () { self.isZarpazoMode = false; self.isKissMode = true; // Hide zarpazo and show kiss if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoKissGraphics.visible = true; self.gatoKissGraphics.scaleX = 2 * self.direction; self.gatoKissGraphics.scaleY = 2; // Play kiss sound when entering kiss mode LK.getSound('gato-kiss').play(); // After kiss, return to normal walking LK.setTimeout(function () { self.isKissMode = false; self.gatoKissGraphics.visible = false; catGraphics.visible = true; // Restore movement speed self.speed = originalSpeed; }, 330); // Kiss lasts 0.33 seconds (33% less than original) }, 500); // 0.5 seconds for zarpazo duration (half the original time) }; 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; // Immediately hide all other cat assets and show only gatoEnjabonado catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoKissGraphics.visible = false; if (self.catHitGraphics) { self.catHitGraphics.visible = false; } if (self.catBlockGraphics) { self.catBlockGraphics.visible = false; } if (self.gatoBailaGraphics) { self.gatoBailaGraphics.visible = false; } self.gatoEnjabonado.visible = true; // 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; } // Laser mode removed // Handle walking animation - alternate between cat and cat-step every 15 frames (0.25 seconds) self.walkAnimTimer++; if (self.walkAnimTimer >= 15) { self.walkAnimTimer = 0; self.isWalkAnimStep = !self.isWalkAnimStep; // Only show walking animation when cat is moving and not in special states (including bubble and floating) var showWalkAnim = !self.isElectrocuted && !self.isSlipping && !self.isJumping && !self.isZarpazoMode && !self.isInBubble && !self.isFloating; if (showWalkAnim) { if (self.isWalkAnimStep) { catGraphics.visible = false; catStepGraphics.visible = true; } else { catGraphics.visible = true; catStepGraphics.visible = false; } } else if (!self.isJumping && !self.isInBubble && !self.isFloating) { // Show normal cat when not walking or in special states (but not when jumping, in bubble, or floating) catGraphics.visible = true; catStepGraphics.visible = false; } // When jumping, ensure only cat-jump is visible if (self.isJumping) { catGraphics.visible = false; catStepGraphics.visible = false; // cat-jump visibility is handled in the jumping animation logic above } // When in bubble, hide ALL other animations - only show gatoEnjabonado if (self.isInBubble) { catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoKissGraphics.visible = false; if (self.catHitGraphics) { self.catHitGraphics.visible = false; } if (self.catBlockGraphics) { self.catBlockGraphics.visible = false; } if (self.gatoBailaGraphics) { self.gatoBailaGraphics.visible = false; } // Only show the soapy/bubble cat self.gatoEnjabonado.visible = true; } // When floating with soap, hide all other animations if (self.isFloating) { catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoEnjabonado.visible = true; } // When in zarpazo mode, hide all other animations if (self.isZarpazoMode) { catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = true; } } // When in kiss mode, hide all other animations if (self.isKissMode) { catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } self.gatoEnjabonado.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } if (self.catHitGraphics) { self.catHitGraphics.visible = false; } self.gatoKissGraphics.visible = true; } // When in hit mode, hide all other animations if (self.isHitMode) { catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } self.gatoEnjabonado.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoKissGraphics.visible = false; if (self.catBlockGraphics) { self.catBlockGraphics.visible = false; } self.catHitGraphics.visible = true; } // When in block mode, hide all other animations if (self.isBlockMode) { catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } self.gatoEnjabonado.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoKissGraphics.visible = false; self.catHitGraphics.visible = false; self.gatoBailaGraphics.visible = false; self.catBlockGraphics.visible = true; } // When dancing, hide all other animations and show dance if (self.isDancing) { catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; if (self.catElectrocutedGraphics) { self.catElectrocutedGraphics.visible = false; } self.gatoEnjabonado.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoKissGraphics.visible = false; self.catHitGraphics.visible = false; self.catBlockGraphics.visible = false; self.gatoBailaGraphics.visible = true; // Advanced dancing animation with multiple dance moves var beatTime = LK.ticks * 0.15; // Main beat var fastBeat = LK.ticks * 0.4; // Fast beat for quick movements var slowBeat = LK.ticks * 0.08; // Slow beat for direction changes // Multi-layered scale animation for dancing effect var baseScale = 2; var bounceScale = Math.sin(beatTime) * 0.4; // Main bounce var quickPulse = Math.sin(fastBeat) * 0.15; // Quick pulse var breathe = Math.sin(slowBeat) * 0.1; // Breathing effect // X and Y scale with different patterns for asymmetric dance var scaleX = baseScale + bounceScale + quickPulse; var scaleY = baseScale + bounceScale * 0.7 + breathe; // Different Y movement // Dance flip animation - similar to running animation self.danceFlipTimer++; if (self.danceFlipTimer >= 45) { // Flip every 45 ticks (0.75 seconds) self.danceFlipDirection = -self.danceFlipDirection; self.danceFlipTimer = 0; } // Add some random flips for more dynamic dancing if (LK.ticks % 120 === 0 && Math.random() < 0.3) { // 30% chance every 2 seconds to do extra flip self.danceFlipDirection = -self.danceFlipDirection; } // Add random Y-axis flips during dance if (LK.ticks % 180 === 0 && Math.random() < 0.4) { // 40% chance every 3 seconds to do Y-axis flip tween(self.gatoBailaGraphics, { scaleY: -self.gatoBailaGraphics.scaleY }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { // Flip back after a moment tween(self.gatoBailaGraphics, { scaleY: Math.abs(self.gatoBailaGraphics.scaleY) }, { duration: 400, easing: tween.bounceOut }); } }); } // Apply scale with flip direction self.gatoBailaGraphics.scaleX = scaleX * self.danceFlipDirection; self.gatoBailaGraphics.scaleY = scaleY; // No rotation - keep cat upright, only horizontal flips for dancing self.gatoBailaGraphics.rotation = 0; // Add slight vertical bobbing for dance effect - positioned 50px lower var danceBob = Math.sin(beatTime * 1.8) * 8; self.gatoBailaGraphics.y = danceBob + 50; // Occasional dramatic scale changes and Y-axis flips for dance highlights if (LK.ticks % 240 === 0) { // Every 4 seconds - perform Y-axis flip tween(self.gatoBailaGraphics, { scaleX: scaleX * self.danceFlipDirection * 1.5, scaleY: -scaleY * 1.3 }, { duration: 200, easing: tween.elasticOut, onFinish: function onFinish() { // Flip back to normal orientation tween(self.gatoBailaGraphics, { scaleX: scaleX * self.danceFlipDirection, scaleY: scaleY }, { duration: 200, easing: tween.elasticOut }); } }); } } } // Update graphics direction based on movement direction if (self.direction > 0) { catGraphics.scaleX = 2; catStepGraphics.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; } if (self.gatoKissGraphics) { self.gatoKissGraphics.scaleX = 2; } if (self.catHitGraphics) { self.catHitGraphics.scaleX = 2; } if (self.catBlockGraphics) { self.catBlockGraphics.scaleX = 2; } if (self.gatoBailaGraphics) { self.gatoBailaGraphics.scaleX = 2; } } else { catGraphics.scaleX = -2; catStepGraphics.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; } if (self.gatoKissGraphics) { self.gatoKissGraphics.scaleX = -2; } if (self.catHitGraphics) { self.catHitGraphics.scaleX = -2; } if (self.catBlockGraphics) { self.catBlockGraphics.scaleX = -2; } if (self.gatoBailaGraphics) { self.gatoBailaGraphics.scaleX = -2; } } // Handle floating timer countdown with wavy random movement if (self.isFloating) { self.floatingTimer--; // Initialize wave variables if not set if (self.soapWaveTime === undefined) { self.soapWaveTime = 0; self.soapBaseX = self.x; self.soapWaveSpeedX = 0.05 + Math.random() * 0.03; self.soapWaveSpeedY = 0.04 + Math.random() * 0.02; self.soapAmplitudeX = 20 + Math.random() * 15; self.soapAmplitudeY = 10 + Math.random() * 8; } // Increment wave time for smooth animation self.soapWaveTime += 1; // Complex wavy movement with multiple wave components var primaryWaveX = Math.sin(self.soapWaveTime * self.soapWaveSpeedX) * self.soapAmplitudeX; var secondaryWaveX = Math.cos(self.soapWaveTime * self.soapWaveSpeedX * 1.7) * (self.soapAmplitudeX * 0.4); var primaryWaveY = Math.sin(self.soapWaveTime * self.soapWaveSpeedY) * self.soapAmplitudeY; // Add some randomness for more organic movement var randomDriftX = (Math.random() - 0.5) * 4; var randomDriftY = (Math.random() - 0.5) * 2; var verticalDrift = -2.5 - Math.random() * 1.5; // Upward drift // Apply the wavy movement with more pronounced vertical oscillation var targetX = self.soapBaseX + primaryWaveX + secondaryWaveX; self.x += (targetX - self.x) * 0.02 + randomDriftX * 0.3; // Increased vertical wave amplitude to about 20px up and down var verticalWave = Math.sin(self.soapWaveTime * self.soapWaveSpeedY * 0.8) * 20; self.y += verticalDrift + verticalWave * 0.15 + primaryWaveY * 0.05 + randomDriftY; // Add rotation for more dramatic soap floating effect self.gatoEnjabonado.rotation = Math.sin(LK.ticks * 0.05) * 0.3 + Math.cos(LK.ticks * 0.03) * 0.2; // Scaling animation for floating effect if (LK.ticks % 45 === 0) { // Every 0.75 seconds var scaleVariation = 0.9 + Math.random() * 0.2; // Random scale between 0.9-1.1 tween(self.gatoEnjabonado, { scaleX: Math.abs(self.gatoEnjabonado.scaleX) * scaleVariation, scaleY: self.gatoEnjabonado.scaleY * (1.1 + Math.random() * 0.1) }, { duration: 400 + Math.random() * 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.gatoEnjabonado, { scaleX: self.direction > 0 ? 2 : -2, scaleY: 2 }, { duration: 300 + Math.random() * 200, easing: tween.easeInOut }); } }); } if (self.floatingTimer <= 0) { // Stop floating after timer expires self.isFloating = false; self.floatingTimer = 0; // Stop any floating tween tween.stop(self, { y: true }); tween.stop(self.gatoEnjabonado, { scaleX: true, scaleY: true, rotation: true }); // Reset rotation and scale self.gatoEnjabonado.rotation = 0; self.gatoEnjabonado.scaleX = self.direction > 0 ? 2 : -2; self.gatoEnjabonado.scaleY = 2; self.gatoEnjabonado.visible = false; catGraphics.visible = true; // Reset wave variables for next soap interaction self.soapWaveTime = undefined; self.soapBaseX = undefined; self.soapWaveSpeedX = undefined; self.soapWaveSpeedY = undefined; self.soapAmplitudeX = undefined; self.soapAmplitudeY = undefined; // Return to current shelf level self.y = shelfLevels[self.currentShelfLevel] - 208; } } // Handle hit timer countdown if (self.isHitMode) { self.hitTimer--; if (self.hitTimer <= 0) { // Recover from hit mode self.isHitMode = false; self.catHitGraphics.visible = false; catGraphics.visible = true; // Restore movement speed self.speed = self.normalSpeed; } } // Handle block timer countdown if (self.isBlockMode) { self.blockTimer--; if (self.blockTimer <= 0) { // Recover from block mode self.isBlockMode = false; self.catBlockGraphics.visible = false; catGraphics.visible = true; // Restore movement speed self.speed = self.normalSpeed; } } // Handle horizontal movement when not electrocuted, slipping, floating, in zarpazo, kiss, hit, or block mode if (!self.isElectrocuted && (!self.isSlipping || self.slipTimer % 30 !== 0) && !self.isFloating && !self.isZarpazoMode && !self.isKissMode && !self.isHitMode && !self.isBlockMode) { var newX = self.x + self.speed * self.direction; // Check if cat reaches right edge of screen (not world boundary) var rightScreenEdge = cameraX + 2048; if (newX >= rightScreenEdge) { // Cat stops responding when reaching right edge of screen self.speed = 0; self.x = rightScreenEdge; return; } // Check for barrier blocking before moving var wouldBeBlocked = false; 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; } } // Check if separator would block movement on same shelf level if (separator.isBlocking && sepShelfLevel === self.currentShelfLevel) { var distanceToSeparator = Math.abs(newX - separator.x); // Check collision from both directions with proper blocking distance if (distanceToSeparator < 120 && (self.direction > 0 && newX > separator.x - 60 && self.x <= separator.x - 60 || self.direction < 0 && newX < separator.x + 60 && self.x >= separator.x + 60)) { wouldBeBlocked = true; break; } } } if (wouldBeBlocked && !self.isBlockMode) { // Enter block mode when stuck against barrier self.isBlockMode = true; self.blockTimer = 180; // 3 seconds at 60fps // Stop movement during block self.speed = 0; // Show only cat-block graphics catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; self.catHitGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.catBlockGraphics.visible = true; self.catBlockGraphics.scaleX = 2 * self.direction; self.catBlockGraphics.scaleY = 2; } else if (!wouldBeBlocked) { // Constrain cat movement within reduced world boundaries (24 sections * 400px = 9600px) // Allow some buffer on both sides for smooth movement self.x = Math.max(-50, Math.min(newX, 9650)); // Keep cat within reduced world bounds } } for (var i = shelfObjects.length - 1; i >= 0; i--) { var obj = shelfObjects[i]; if (self.intersects(obj) && !obj.isFalling && !self.isJumping) { obj.startFalling(); // Update objects knocked down counter based on objects that are NOT falling var actualObjectsRemaining = 0; for (var j = 0; j < shelfObjects.length; j++) { if (!shelfObjects[j].isFalling) { actualObjectsRemaining++; } } objectsKnockedDown = totalObjectsToKnock - actualObjectsRemaining; storage.objectsKnockedDown = objectsKnockedDown; // Check if all objects have been knocked down if (actualObjectsRemaining <= 0) { // Calculate stage score based on remaining time and penalties var remainingSeconds = Math.max(0, Math.ceil((TIME_LIMIT - gameTimer) / 60)); var stageScore = remainingSeconds * 10 - obstaclePenalties; // 10 points per remaining second minus penalties stageScore = Math.max(stageScore, 0); // Ensure score doesn't go negative // Add stage score to total finalScore += stageScore; LK.setScore(finalScore); // Stop the game timer to prevent time-based game over gameTimer = TIME_LIMIT; // Activate dancing mode for cat self.isDancing = true; // Reset dance flip variables for consistent start self.danceFlipTimer = 0; self.danceFlipDirection = 1; // Stop main theme music when dancing starts try { if (LK.stopMusic) { LK.stopMusic('mainTheme'); } else if (LK.pauseMusic) { LK.pauseMusic('mainTheme'); } } catch (e) { console.log('Music stop/pause not available'); } // Stop cat movement during victory dance self.speed = 0; // Stop all cat behaviors self.isElectrocuted = false; self.isSlipping = false; self.isFloating = false; self.isZarpazoMode = false; self.isKissMode = false; self.isHitMode = false; self.isBlockMode = false; // Play success song LK.getSound('successSong').play(); // Check if this is the final stage if (currentStage >= maxStages) { // Final victory - show you win after dance LK.setTimeout(function () { // Player wins when all stages completed - reset storage for new game storage.totalObjectsToKnock = 0; storage.objectsKnockedDown = 0; // Show level complete message LK.showYouWin(); }, 4000); // Wait 4 seconds to let cat dance longer before victory } else { // Move to next stage after dance LK.setTimeout(function () { // Advance to next stage currentStage++; // Reset for next stage setupStage(currentStage); }, 4000); // Wait 4 seconds to let cat dance } 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; } } // Usar hitbox de dangerousObj para evitar desfase por sprite elevado var targetForCollision = dangerousObj.hitbox ? dangerousObj.hitbox : dangerousObj; // Colisionar solo si están en la misma repisa (usa base del objeto) y con el hitbox if (self.intersects(targetForCollision) && dangerousObj.isDangerous && !dangerousObj.isFalling && objShelfLevel === self.currentShelfLevel && !self.isHitMode && !self.isJumping) { // Cat gets hit and stops for a few seconds dangerousObj.startFalling(); obstaclePenalties += 10; // Add penalty for hitting dangerous object LK.getSound('catFall').play(); LK.effects.flashScreen(0xff0000, 500); // Enter hit mode self.isHitMode = true; self.hitTimer = 180; // 3 seconds at 60fps // Stop movement during hit self.speed = 0; // Show only cat-hit graphics catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.catHitGraphics.visible = true; self.catHitGraphics.scaleX = 2 * self.direction; self.catHitGraphics.scaleY = 2; } } // Check for collisions with dogs - only on same shelf level for (var i = dogs.length - 1; i >= 0; i--) { var dog = dogs[i]; // Calculate which shelf level the dog is on var dogShelfLevel = -1; for (var level = 0; level < 5; level++) { if (Math.abs(dog.y - (shelfLevels[level] - 75)) < 50) { dogShelfLevel = level; break; } } // Only collide if on same shelf level or jumping attack from above if (self.intersects(dog)) { if (self.isJumping && self.y < dog.y - 20) { // Cat falls on dog and kills it (can happen from any level when jumping) LK.getSound('dogBark').play(); LK.effects.flashObject(self, 0x00ff00, 500); // 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; } } else if (!self.isHitMode && !self.isInvulnerable && !self.isJumping && dogShelfLevel === self.currentShelfLevel) { // Dog knocks down the cat (only on same shelf level and not jumping) LK.getSound('dogBark').play(); LK.getSound('catFall').play(); LK.effects.flashScreen(0xff0000, 500); obstaclePenalties += 15; // Add penalty for being knocked down by dog // Enter hit mode self.isHitMode = true; self.hitTimer = 180; // 3 seconds at 60fps // Stop movement during hit self.speed = 0; // Show only cat-hit graphics catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.catHitGraphics.visible = true; self.catHitGraphics.scaleX = 2 * self.direction; self.catHitGraphics.scaleY = 2; } } } // Check if cat reaches right world boundary and trigger block mode with pushback if (self.x >= 9500 && !self.isBlockMode) { // Push cat away from boundary by 30 pixels var pushDirection = -1; // Always push left from right boundary var pushDistance = 30; var targetX = self.x + pushDistance * pushDirection; // Ensure target position is within game bounds targetX = Math.max(200, Math.min(targetX, 9600)); // Stop any existing movement tweens on cat tween.stop(self, { x: true }); // Push cat away from boundary tween(self, { x: targetX }, { duration: 200, easing: tween.easeOut }); // Enter block mode when reaching right boundary barriers self.isBlockMode = true; self.blockTimer = 60; // 1 second at 60fps (reduced from 180) // Stop movement during block self.speed = 0; // Show only cat-block graphics catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; self.catHitGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.catBlockGraphics.visible = true; self.catBlockGraphics.scaleX = 2 * self.direction; self.catBlockGraphics.scaleY = 2; } // Check if cat reaches left world boundary and lose life if (!self.isInvulnerable && self.x <= -150) { // Cat reaches left world limit and loses a life self.lives--; self.isInvulnerable = true; self.invulnerabilityTimer = 120; // 2 seconds of invulnerability obstaclePenalties += 25; // Add penalty for losing a life 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(); } } // Check for collisions with separators and barriers - 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 && sepShelfLevel === self.currentShelfLevel && !self.isBlockMode && !self.isJumping) { // Push cat away from separator by 30 pixels var pushDirection = self.x > separator.x ? 1 : -1; var pushDistance = 30; var targetX = self.x + pushDistance * pushDirection; // Ensure target position is within game bounds targetX = Math.max(200, Math.min(targetX, 9600)); // Stop any existing movement tweens on cat tween.stop(self, { x: true }); // Push cat away from separator tween(self, { x: targetX }, { duration: 200, easing: tween.easeOut }); // Enter block mode when hitting separator self.isBlockMode = true; self.blockTimer = 60; // 1 second at 60fps (reduced from 180) // Stop movement during block self.speed = 0; // Show only cat-block graphics catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; self.catHitGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.catBlockGraphics.visible = true; self.catBlockGraphics.scaleX = 2 * self.direction; self.catBlockGraphics.scaleY = 2; } } // Check for collisions with left barriers - only on same shelf level for (var i = leftBarriers.length - 1; i >= 0; i--) { var leftBarrier = leftBarriers[i]; // Calculate which shelf level the left barrier is on var barrierShelfLevel = -1; for (var level = 0; level < 5; level++) { if (Math.abs(leftBarrier.y - (shelfLevels[level] - 150)) < 50) { barrierShelfLevel = level; break; } } // Only collide if on same shelf level if (self.intersects(leftBarrier) && leftBarrier.isBlocking && barrierShelfLevel === self.currentShelfLevel && !self.isBlockMode && !self.isJumping) { // Push cat away from left barrier by 30 pixels var pushDirection = 1; // Always push right from left barrier var pushDistance = 30; var targetX = self.x + pushDistance * pushDirection; // Ensure target position is within game bounds targetX = Math.max(200, Math.min(targetX, 9600)); // Stop any existing movement tweens on cat tween.stop(self, { x: true }); // Push cat away from barrier tween(self, { x: targetX }, { duration: 200, easing: tween.easeOut }); // Enter block mode when hitting left barrier self.isBlockMode = true; self.blockTimer = 60; // 1 second at 60fps // Stop movement during block self.speed = 0; // Show only cat-block graphics catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; self.gatoEnjabonado.visible = false; self.gatoKissGraphics.visible = false; self.catHitGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.catBlockGraphics.visible = true; self.catBlockGraphics.scaleX = 2 * self.direction; self.catBlockGraphics.scaleY = 2; } } // 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; catStepGraphics.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; catStepGraphics.visible = false; 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; catStepGraphics.visible = false; } } // 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, applied to the correct asset if (LK.ticks % 90 === 0) { // Every 1.5 seconds - slower, more gentle tween(self.gatoEnjabonado, { scaleX: Math.abs(self.gatoEnjabonado.scaleX) * 1.05, scaleY: self.gatoEnjabonado.scaleY * 1.15 }, { duration: 750, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.gatoEnjabonado, { scaleX: Math.abs(self.gatoEnjabonado.scaleX) / 1.05, scaleY: self.gatoEnjabonado.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 bubble asset visibility and scale self.gatoEnjabonado.visible = false; self.gatoEnjabonado.scaleX = self.direction > 0 ? 2 : -2; self.gatoEnjabonado.scaleY = 2; // Show normal cat catGraphics.visible = true; 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 cat is not immune to lamp electrocution if (self.intersects(lamp) && lampShelfLevel === self.currentShelfLevel && !self.isElectrocuted && !self.isJumping) { // Electrocute cat for 2 seconds self.isElectrocuted = true; self.electrocutionTimer = 120; // 2 seconds at 60fps obstaclePenalties += 15; // Add penalty for lamp electrocution // 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 = self.x > lamp.x ? 1 : -1; var pushDistance = 250; var targetX = self.x + pushDistance * pushDirection; // Ensure target position is within game bounds targetX = Math.max(200, Math.min(targetX, 9600)); // Stop any existing movement tweens on cat tween.stop(self, { x: true }); // Make cat get pushed away with stronger force tween(self, { x: targetX }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Additional push to ensure separation var secondPushX = targetX + pushDirection * 100; secondPushX = Math.max(200, Math.min(secondPushX, 9600)); tween(self, { x: secondPushX }, { duration: 150, easing: tween.easeOut }); } }); } } // Check for soap collision - only on same shelf level and causes floating upward 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 && !self.isJumping) { soap.hasBeenUsed = true; // Set floating state self.isFloating = true; self.floatingTimer = 300; // 5 seconds at 60fps // Show only the soapy cat asset and hide all others catGraphics.visible = false; catStepGraphics.visible = false; self.catJumpGraphics.visible = false; self.catElectrocutedGraphics.visible = false; if (self.zarpazoGraphics) { self.zarpazoGraphics.visible = false; } self.gatoEnjabonado.visible = true; // Stop any existing movement animations self.isJumping = false; self.isElectrocuted = false; self.isZarpazoMode = false; // Play slip sound and bubble sound for soapy floating effect LK.getSound('soapSlip').play(); LK.getSound('bubble').play(); // Stop any existing tweens on cat position tween.stop(self, { y: true, x: true }); // Initialize soap floating variables for wavy movement self.soapWaveTime = 0; self.soapBaseX = self.x; self.soapWaveSpeedX = 0.05 + Math.random() * 0.03; self.soapWaveSpeedY = 0.04 + Math.random() * 0.02; self.soapAmplitudeX = 20 + Math.random() * 15; self.soapAmplitudeY = 10 + Math.random() * 8; // Note: The actual wavy movement is now handled in the floating timer section above // 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 collisions with mice - cat can eat mouse for (var i = mice.length - 1; i >= 0; i--) { var mouse = mice[i]; // Calculate which shelf level the mouse is on var mouseShelfLevel = -1; for (var level = 0; level < 5; level++) { if (Math.abs(mouse.y - (shelfLevels[level] - 75)) < 50) { mouseShelfLevel = level; break; } } // Only collide if on same shelf level if (self.intersects(mouse) && mouseShelfLevel === self.currentShelfLevel && !self.isJumping) { // Cat eats mouse LK.getSound('mouseSqueak').play(); LK.effects.flashObject(self, 0x00ff00, 500); // Activate zarpazo mode when eating mouse self.activateZarpazo(); // Remove mouse from game mouse.destroy(); mice.splice(i, 1); // Stop chasing behavior if this was the chase target if (mouse === self.chaseTarget) { self.isChasing = false; self.chaseTarget = null; } } } // Laser system removed }; return self; }); var DangerousObject = Container.expand(function () { var self = Container.call(this); var dangerousGraphics = self.attachAsset('dangerousObject', { anchorX: 0.5, anchorY: 0, scaleX: 4, scaleY: 4, y: -500 }); // Hitbox en la base para mantener colisión al nivel de repisa var dangerousHitbox = self.attachAsset('dangerousHitbox', { anchorX: 0.5, anchorY: 1, scaleX: 4, scaleY: 4, y: 0 }); dangerousHitbox.alpha = 0; // invisible // Exponer hitbox para colisiones precisas self.hitbox = dangerousHitbox; 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 // Change to falling asset dangerousGraphics.visible = false; // Create falling graphics if not exists if (!self.fallingGraphics) { self.fallingGraphics = self.attachAsset('dangerousObjectFall', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 4 }); } self.fallingGraphics.visible = true; // 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.1; dangerousGraphics.scaleY = scale; dangerousGraphics.scaleX = 1; } else { self.y += self.fallSpeed; self.fallSpeed += 0.2; // Gravity self.rotation += 0.1; if (self.y > 2732 + 50) { // Emit sound when dangerous object falls off screen LK.getSound('dangerousFall').play(); 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; // Dog follows cat behavior var distanceToCat = Math.abs(self.x - cat.x); var catDirection = cat.x > self.x ? 1 : -1; // Follow cat if within following range (500px) but maintain some distance (100px) if (distanceToCat > 100 && distanceToCat < 500) { self.direction = catDirection; // Move towards cat with smooth tweening if (!self.isTweening) { var followSpeed = Math.min(self.speed, distanceToCat / 50); // Slower when closer var targetX = self.x + followSpeed * self.direction * 20; tween(self, { x: targetX }, { duration: 400, easing: tween.easeInOut, onFinish: function onFinish() { self.isTweening = false; } }); self.isTweening = true; } } else { // Regular movement when not following 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 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: 10, 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.flickerTimer = 0; self.isFlickering = false; self.flickerInterval = 60 + Math.random() * 120; // Random flicker every 1-3 seconds 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) { // Handle bulb flickering like electrical fault self.flickerTimer++; if (self.flickerTimer >= self.flickerInterval) { self.flickerTimer = 0; self.flickerInterval = 60 + Math.random() * 120; // New random interval self.isFlickering = true; // Quick flicker sequence - on/off/on rapidly tween(lightBulbGraphics, { alpha: 0.1 // Almost off }, { duration: 80, easing: tween.linear, onFinish: function onFinish() { tween(lightBulbGraphics, { alpha: 1 // Bright on }, { duration: 60, easing: tween.linear, onFinish: function onFinish() { tween(lightBulbGraphics, { alpha: 0.2 // Dim again }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(lightBulbGraphics, { alpha: 1 // Back to normal }, { duration: 120, easing: tween.easeOut, onFinish: function onFinish() { self.isFlickering = false; } }); } }); } }); } }); } // Create pulsing glow effect with tint when not flickering if (!self.isFlickering && self.flickerTimer % 120 === 0) { // Every 2 seconds, create a glow pulse tween(lightBulbGraphics, { tint: 0xFFFF88 // Bright yellow glow }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinished() { 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; LK.getSound('electricShock').play(); cat.electrocutionTimer = 120; // 2 seconds at 60fps // 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) { // Emit sound when lamp falls off screen LK.getSound('electricShock').play(); self.destroy(); var index = lamps.indexOf(self); if (index > -1) { lamps.splice(index, 1); } } } }; 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.7, scaleX: 4, scaleY: 4 }); self.isBlocking = true; return self; }); var ShelfObject = Container.expand(function (objectType) { var self = Container.call(this); var assetName; // Map object types to their asset names switch (objectType) { case 1: case 2: case 3: assetName = 'object' + objectType; break; case 4: assetName = 'pecera'; break; case 5: assetName = 'movil'; break; case 6: assetName = 'portatil'; break; default: assetName = 'object1'; } 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; // Change to falling asset if this is a pecera (fish tank) if (objectType === 4) { objectGraphics.visible = false; // Create falling fish graphics if not exists if (!self.fallingGraphics) { self.fallingGraphics = self.attachAsset('pezCayendo', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 4 }); } self.fallingGraphics.visible = true; // Apply falling animation to falling graphics instead tween(self.fallingGraphics, { scaleX: 6, scaleY: 6 }, { duration: 800, easing: tween.bounceOut }); } else { // Add dynamic falling animation with scaling and rotation for other objects tween(objectGraphics, { scaleX: 6, scaleY: 6 }, { duration: 800, easing: tween.bounceOut }); } // Play sound based on object type var soundId = 'objectFall' + (objectType || 1); LK.getSound(soundId).play(); // 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 - dog runs away scared LK.getSound('dogBark').play(); LK.effects.flashObject(dog, 0xFFFF00, 300); // Make dog run away fast dog.speed = 25; // Much faster running speed dog.direction = dog.x > cat.x ? 1 : -1; // Run away from cat dog.isRunningAway = true; // Add running away animation tween(dog, { x: dog.x + dog.direction * 800, y: dog.y + 100 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Remove dog after running away dog.destroy(); var dogIndex = dogs.indexOf(dog); if (dogIndex > -1) { dogs.splice(dogIndex, 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) { // Emit sound when object falls off screen LK.getSound('objectHit').play(); 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: 1.8, scaleY: 1.8 }); self.hasBeenUsed = false; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var cat; var shelfObjects = []; var dangerousObjects = []; // Laser removed 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; // Laser removed var cameraX = 0; var gameTimer = 0; var TIME_LIMIT = 9600; // 160 seconds at 60fps (9600 ticks) // Stage system variables var currentStage = 1; var maxStages = 20; // Increased to 20 stages var baseTimeLimit = 9600; // Base time limit for stage 1 // Always start fresh - ignore storage values to ensure correct initialization var totalObjectsToKnock = 15; var objectsKnockedDown = 0; var obstaclePenalties = 0; // Track penalties from hitting obstacles var finalScore = 0; // Score display removed - game now uses timer-based gameplay // 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 with initial values var progressText = new Text2('Objects: 0/15', { size: 60, fill: 0x00FF00 }); progressText.anchor.set(0.5, 0); LK.gui.top.addChild(progressText); progressText.y = 120; // Create score display var scoreText = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); scoreText.y = 180; // Claw button removed - zarpazo is now automatic when picking up objects // Create shelves first - reduced to 96 shelves wide (24 sections per level) for (var level = 0; level < 5; level++) { for (var section = 0; section < 24; 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 // Reset counters at game start to ensure proper initialization totalObjectsToKnock = 15; // Always start with 15 objects objectsKnockedDown = 0; // Always start with 0 knocked down storage.totalObjectsToKnock = totalObjectsToKnock; storage.objectsKnockedDown = objectsKnockedDown; // Clear any existing objects from previous games shelfObjects = []; // Pre-define object positions ensuring proper spacing (minimum 500px apart) within shelf boundaries (400-9200px) var objectPositions = [{ x: 600, level: 0, type: 1 }, // Object 1 { x: 1600, level: 1, type: 4 }, // Object 2 - pecera { x: 1800, level: 2, type: 3 }, // Object 3 { x: 2400, level: 3, type: 5 }, // Object 4 - movil { x: 3000, level: 4, type: 2 }, // Object 5 { x: 3600, level: 0, type: 6 }, // Object 6 - portatil { x: 4200, level: 1, type: 1 }, // Object 7 { x: 4800, level: 2, type: 4 }, // Object 8 - pecera { x: 5400, level: 3, type: 3 }, // Object 9 { x: 6000, level: 4, type: 5 }, // Object 10 - movil { x: 6800, level: 0, type: 2 }, // Object 11 { x: 7300, level: 1, type: 6 }, // Object 12 - portatil { x: 7800, level: 2, type: 1 }, // Object 13 { x: 8500, level: 3, type: 4 }, // Object 14 - pecera { x: 9100, level: 4, type: 3 } // Object 15 ]; // Create all 15 objects at game start with proper spacing for (var i = 0; i < totalObjectsToKnock; i++) { var pos = objectPositions[i]; var obj = new ShelfObject(pos.type); obj.x = pos.x; obj.y = shelfLevels[pos.level] - 155; // Position much higher on top of shelf (60px higher) obj.objectNumber = i + 1; // Add numbering for identification 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(LK.getAsset('cubos', { anchorX: 0.5, anchorY: 0, scaleX: 4, scaleY: 4 })); leftBarrier.x = -100; // 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 96 shelves wide for (var level = 0; level < 5; level++) { var rightBarrier = game.addChild(LK.getAsset('cubos', { anchorX: 0.5, anchorY: 0, scaleX: 4, scaleY: 4 })); rightBarrier.x = 9700; // Position at end of 24 sections (24 * 400 = 9600) rightBarrier.y = shelfLevels[level] - 150; // Position on each shelf level rightBarrier.isBlocking = true; rightBarriers.push(rightBarrier); } // Pre-define separator positions ensuring proper spacing (minimum 60px from other elements) var separatorPositions = [{ x: 1900, level: 0 }, { x: 2600, level: 2 }, { x: 3600, level: 1 }, { x: 4600, level: 4 }, { x: 5600, level: 3 }, { x: 6700, level: 0 }, { x: 7600, level: 2 }, { x: 8600, level: 1 }]; // Create all separators at game start with proper spacing for (var i = 0; i < separatorPositions.length; i++) { var sepPos = separatorPositions[i]; var separator = new Separator(); separator.x = sepPos.x; separator.y = shelfLevels[sepPos.level] - 150; // Position higher above shelf separator.isBlocking = true; game.addChild(separator); separators.push(separator); } // Pre-define dangerous object positions ensuring proper spacing from other elements (minimum 60px spacing) var dangerousObjectPositions = [{ x: 2000, level: 1 }, { x: 2300, level: 0 }, { x: 3900, level: 3 }, { x: 5300, level: 2 }, { x: 6900, level: 4 }, { x: 8300, level: 1 }]; // Create all dangerous objects at game start for (var i = 0; i < dangerousObjectPositions.length; i++) { var dangerPos = dangerousObjectPositions[i]; var dangerousObj = new DangerousObject(); dangerousObj.x = dangerPos.x; dangerousObj.y = shelfLevels[dangerPos.level] - 75; // Position on top of shelf (match shelf-level detection) game.addChild(dangerousObj); dangerousObjects.push(dangerousObj); } // Pre-define dog positions ensuring proper spacing (minimum 60px from other elements) var dogPositions = [{ x: 2700, level: 4 }, { x: 4100, level: 0 }, { x: 7100, level: 3 }]; // Create all dogs at game start for (var i = 0; i < dogPositions.length; i++) { var dogPos = dogPositions[i]; var dog = new Dog(); dog.x = dogPos.x; dog.y = shelfLevels[dogPos.level] - 75; // Position on top of shelf game.addChild(dog); dogs.push(dog); } // Pre-define mouse positions ensuring proper spacing (far from cat start position) var mousePositions = [{ x: 3300, level: 4 }, { x: 3400, level: 1 }, { x: 5900, level: 0 }, { x: 8700, level: 2 }]; // Create all mice at game start for (var i = 0; i < mousePositions.length; i++) { var mousePos = mousePositions[i]; var mouse = new Mouse(); mouse.x = mousePos.x; mouse.y = shelfLevels[mousePos.level] - 75; // Position on top of shelf game.addChild(mouse); mice.push(mouse); } // Pre-define lamp positions ensuring proper spacing (minimum 60px from other elements) var lampPositions = [{ x: 1750, level: 1 }, { x: 4700, level: 3 }, { x: 6300, level: 0 }, { x: 8900, level: 4 }]; // Create all lamps at game start for (var i = 0; i < lampPositions.length; i++) { var lampPos = lampPositions[i]; var lamp = new Lamp(); lamp.x = lampPos.x; lamp.y = shelfLevels[lampPos.level]; // Position on shelf game.addChild(lamp); lamps.push(lamp); } // Pre-define soap positions ensuring proper spacing (minimum 60px from other elements) var soapPositions = [{ x: 2100, level: 4 }, { x: 4500, level: 1 }, { x: 6500, level: 2 }]; // Create all soaps at game start for (var i = 0; i < soapPositions.length; i++) { var soapPos = soapPositions[i]; var soap = new Soap(); soap.x = soapPos.x; soap.y = shelfLevels[soapPos.level] - 40; // Position on shelf game.addChild(soap); soaps.push(soap); } // 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; // Laser removed }; game.move = function (x, y, obj) { // Laser removed }; game.up = function (x, y, obj) { if (!isDragging) { return; } isDragging = false; // Don't respond to swipe controls when floating if (cat.isFloating) { return; } 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 } // If cat is in block mode, immediately exit it when direction changes if (cat.isBlockMode) { cat.isBlockMode = false; cat.blockTimer = 0; // Restore movement speed cat.speed = cat.normalSpeed; // Hide block graphics and show normal cat cat.catBlockGraphics.visible = false; var catGraphics = cat.children.find(function (child) { return child.texture && child.texture.baseTexture && child.texture.baseTexture.resource && child.texture.baseTexture.resource.url && child.texture.baseTexture.resource.url.includes('cat') && !child.texture.baseTexture.resource.url.includes('step') && !child.texture.baseTexture.resource.url.includes('jump') && !child.texture.baseTexture.resource.url.includes('hit') && !child.texture.baseTexture.resource.url.includes('block'); }); if (catGraphics) { catGraphics.visible = true; } } } } }; // Spawn objects and laser pointers function spawnObject() { // Objects are distributed at the beginning and remain persistent // No automatic spawning during gameplay return; } function spawnDangerousObject() { // Dangerous objects are now pre-defined at game start - no dynamic spawning return; } // Laser spawn removed function spawnMouse() { // Mice are now pre-defined at game start - no dynamic spawning return; } function spawnDog() { // Dogs are now pre-defined at game start - no dynamic spawning return; } function spawnSeparator() { // Separators are now pre-defined at game start - no dynamic spawning return; } function spawnLamp() { // Lamps are now pre-defined at game start - no dynamic spawning return; } function spawnSoap() { // Soaps are now pre-defined at game start - no dynamic spawning return; } // 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 96 shelves - no dynamic expansion var rightmostShelf = Math.max.apply(Math, shelves.map(function (s) { return s.x; })); // No shelf expansion - world stays at fixed 96 shelves wide (9600px) } // Stage setup function function setupStage(stage) { // Reset game state gameTimer = 0; obstaclePenalties = 0; // Adjust time limit - reduce by 10 seconds (600 ticks) each stage up to stage 10, then 4 seconds (240 ticks) each stage after 10 if (stage <= 10) { TIME_LIMIT = baseTimeLimit - (stage - 1) * 600; // 10 seconds reduction per stage up to stage 10 } else { // After stage 10: base time reduced by 9*600 for first 9 stages, then 4 seconds per additional stage TIME_LIMIT = baseTimeLimit - 9 * 600 - (stage - 10) * 240; // 4 seconds reduction per stage after 10 } // Clear existing objects for (var i = shelfObjects.length - 1; i >= 0; i--) { shelfObjects[i].destroy(); } shelfObjects = []; // Clear existing dangerous objects for (var i = dangerousObjects.length - 1; i >= 0; i--) { dangerousObjects[i].destroy(); } dangerousObjects = []; // Clear existing dogs (will be respawned for stage 2+) for (var i = dogs.length - 1; i >= 0; i--) { dogs[i].destroy(); } dogs = []; // Reset cat state cat.isDancing = false; // Apply stage-based speed increase for stages 10+ if (stage >= 10) { var speedIncrease = (stage - 9) * 0.1; // 10% increase per stage after 10 cat.normalSpeed = cat.normalSpeed * (1 + speedIncrease); cat.speed = cat.normalSpeed; } else { cat.speed = cat.normalSpeed; } // Find safe spawn position for cat (away from obstacles and dogs) var safeCatX = 1024; // Default center position var minSafeDistance = 200; // Minimum distance from obstacles // Check if center position is safe var isCenterSafe = true; // Check distance from objects for (var i = 0; i < shelfObjects.length; i++) { if (Math.abs(shelfObjects[i].x - 1024) < minSafeDistance && Math.abs(shelfObjects[i].y - (shelfLevels[2] - 155)) < 100) { isCenterSafe = false; break; } } // Check distance from dogs for (var i = 0; i < dogs.length; i++) { if (Math.abs(dogs[i].x - 1024) < minSafeDistance && Math.abs(dogs[i].y - (shelfLevels[2] - 75)) < 100) { isCenterSafe = false; break; } } // Check distance from dangerous objects for (var i = 0; i < dangerousObjects.length; i++) { if (Math.abs(dangerousObjects[i].x - 1024) < minSafeDistance && Math.abs(dangerousObjects[i].y - (shelfLevels[2] - 75)) < 100) { isCenterSafe = false; break; } } // If center isn't safe, find alternative safe position if (!isCenterSafe) { var potentialPositions = [800, 600, 1200, 1400]; // Alternative spawn positions for (var p = 0; p < potentialPositions.length; p++) { var testX = potentialPositions[p]; var positionSafe = true; // Check all obstacles for this position for (var i = 0; i < shelfObjects.length; i++) { if (Math.abs(shelfObjects[i].x - testX) < minSafeDistance && Math.abs(shelfObjects[i].y - (shelfLevels[2] - 155)) < 100) { positionSafe = false; break; } } if (!positionSafe) { continue; } for (var i = 0; i < dogs.length; i++) { if (Math.abs(dogs[i].x - testX) < minSafeDistance && Math.abs(dogs[i].y - (shelfLevels[2] - 75)) < 100) { positionSafe = false; break; } } if (!positionSafe) { continue; } for (var i = 0; i < dangerousObjects.length; i++) { if (Math.abs(dangerousObjects[i].x - testX) < minSafeDistance && Math.abs(dangerousObjects[i].y - (shelfLevels[2] - 75)) < 100) { positionSafe = false; break; } } if (positionSafe) { safeCatX = testX; break; } } } cat.x = safeCatX; // Use safe position cat.targetShelfLevel = 2; cat.currentShelfLevel = 2; cat.y = shelfLevels[2] - 208; cat.direction = 1; // Hide dance graphics and show normal cat cat.gatoBailaGraphics.visible = false; var catGraphics = cat.children.find(function (child) { return child.texture && child.texture.baseTexture && child.texture.baseTexture.resource && child.texture.baseTexture.resource.url && child.texture.baseTexture.resource.url.includes('cat') && !child.texture.baseTexture.resource.url.includes('step'); }); if (catGraphics) { catGraphics.visible = true; } // Create new object positions for the stage (randomized but properly spaced) var newObjectPositions = []; if (stage === 1) { // Stage 1 positions (updated with new object types) newObjectPositions = [{ x: 600, level: 0, type: 1 }, { x: 1600, level: 1, type: 4 }, { x: 1800, level: 2, type: 3 }, { x: 2400, level: 3, type: 5 }, { x: 3000, level: 4, type: 2 }, { x: 3600, level: 0, type: 6 }, { x: 4200, level: 1, type: 1 }, { x: 4800, level: 2, type: 4 }, { x: 5400, level: 3, type: 3 }, { x: 6000, level: 4, type: 5 }, { x: 6800, level: 0, type: 2 }, { x: 7300, level: 1, type: 6 }, { x: 7800, level: 2, type: 1 }, { x: 8500, level: 3, type: 4 }, { x: 9100, level: 4, type: 3 }]; } else if (stage === 2) { // Stage 2 positions (reorganized) newObjectPositions = [{ x: 800, level: 4, type: 2 }, { x: 1400, level: 0, type: 1 }, { x: 2000, level: 2, type: 3 }, { x: 2800, level: 1, type: 2 }, { x: 3400, level: 3, type: 1 }, { x: 4000, level: 4, type: 3 }, { x: 4600, level: 0, type: 2 }, { x: 5200, level: 2, type: 1 }, { x: 5800, level: 1, type: 3 }, { x: 6400, level: 3, type: 2 }, { x: 7000, level: 4, type: 1 }, { x: 7600, level: 0, type: 3 }, { x: 8200, level: 2, type: 2 }, { x: 8800, level: 1, type: 1 }, { x: 9200, level: 3, type: 3 }]; } else if (stage === 3) { // Stage 3 positions newObjectPositions = [{ x: 700, level: 2, type: 3 }, { x: 1300, level: 4, type: 1 }, { x: 1900, level: 1, type: 2 }, { x: 2500, level: 0, type: 3 }, { x: 3100, level: 3, type: 1 }, { x: 3700, level: 2, type: 2 }, { x: 4300, level: 4, type: 3 }, { x: 4900, level: 1, type: 1 }, { x: 5500, level: 0, type: 2 }, { x: 6100, level: 3, type: 3 }, { x: 6700, level: 2, type: 1 }, { x: 7300, level: 4, type: 2 }, { x: 7900, level: 1, type: 3 }, { x: 8500, level: 0, type: 1 }, { x: 9000, level: 3, type: 2 }]; } else if (stage === 4) { // Stage 4 positions newObjectPositions = [{ x: 900, level: 1, type: 1 }, { x: 1500, level: 3, type: 2 }, { x: 2100, level: 0, type: 3 }, { x: 2700, level: 4, type: 1 }, { x: 3300, level: 2, type: 2 }, { x: 3900, level: 1, type: 3 }, { x: 4500, level: 3, type: 1 }, { x: 5100, level: 0, type: 2 }, { x: 5700, level: 4, type: 3 }, { x: 6300, level: 2, type: 1 }, { x: 6900, level: 1, type: 2 }, { x: 7500, level: 3, type: 3 }, { x: 8100, level: 0, type: 1 }, { x: 8700, level: 4, type: 2 }, { x: 9300, level: 2, type: 3 }]; } else if (stage === 5) { // Stage 5 positions newObjectPositions = [{ x: 600, level: 3, type: 2 }, { x: 1200, level: 1, type: 3 }, { x: 1800, level: 4, type: 1 }, { x: 2400, level: 2, type: 2 }, { x: 3000, level: 0, type: 3 }, { x: 3600, level: 3, type: 1 }, { x: 4200, level: 1, type: 2 }, { x: 4800, level: 4, type: 3 }, { x: 5400, level: 2, type: 1 }, { x: 6000, level: 0, type: 2 }, { x: 6600, level: 3, type: 3 }, { x: 7200, level: 1, type: 1 }, { x: 7800, level: 4, type: 2 }, { x: 8400, level: 2, type: 3 }, { x: 9000, level: 0, type: 1 }]; } else if (stage === 6) { // Stage 6 positions newObjectPositions = [{ x: 800, level: 0, type: 3 }, { x: 1400, level: 2, type: 1 }, { x: 2000, level: 4, type: 2 }, { x: 2600, level: 1, type: 3 }, { x: 3200, level: 3, type: 1 }, { x: 3800, level: 0, type: 2 }, { x: 4400, level: 2, type: 3 }, { x: 5000, level: 4, type: 1 }, { x: 5600, level: 1, type: 2 }, { x: 6200, level: 3, type: 3 }, { x: 6800, level: 0, type: 1 }, { x: 7400, level: 2, type: 2 }, { x: 8000, level: 4, type: 3 }, { x: 8600, level: 1, type: 1 }, { x: 9200, level: 3, type: 2 }]; } else if (stage === 7) { // Stage 7 positions newObjectPositions = [{ x: 1000, level: 4, type: 1 }, { x: 1600, level: 2, type: 3 }, { x: 2200, level: 0, type: 2 }, { x: 2800, level: 3, type: 1 }, { x: 3400, level: 1, type: 3 }, { x: 4000, level: 4, type: 2 }, { x: 4600, level: 2, type: 1 }, { x: 5200, level: 0, type: 3 }, { x: 5800, level: 3, type: 2 }, { x: 6400, level: 1, type: 1 }, { x: 7000, level: 4, type: 3 }, { x: 7600, level: 2, type: 2 }, { x: 8200, level: 0, type: 1 }, { x: 8800, level: 3, type: 3 }, { x: 9400, level: 1, type: 2 }]; } else if (stage === 8) { // Stage 8 positions newObjectPositions = [{ x: 650, level: 1, type: 2 }, { x: 1250, level: 4, type: 1 }, { x: 1850, level: 2, type: 3 }, { x: 2450, level: 0, type: 2 }, { x: 3050, level: 3, type: 1 }, { x: 3650, level: 1, type: 3 }, { x: 4250, level: 4, type: 2 }, { x: 4850, level: 2, type: 1 }, { x: 5450, level: 0, type: 3 }, { x: 6050, level: 3, type: 2 }, { x: 6650, level: 1, type: 1 }, { x: 7250, level: 4, type: 3 }, { x: 7850, level: 2, type: 2 }, { x: 8450, level: 0, type: 1 }, { x: 9050, level: 3, type: 3 }]; } else if (stage === 9) { // Stage 9 positions newObjectPositions = [{ x: 750, level: 3, type: 3 }, { x: 1350, level: 1, type: 2 }, { x: 1950, level: 4, type: 1 }, { x: 2550, level: 2, type: 3 }, { x: 3150, level: 0, type: 2 }, { x: 3750, level: 3, type: 1 }, { x: 4350, level: 1, type: 3 }, { x: 4950, level: 4, type: 2 }, { x: 5550, level: 2, type: 1 }, { x: 6150, level: 0, type: 3 }, { x: 6750, level: 3, type: 2 }, { x: 7350, level: 1, type: 1 }, { x: 7950, level: 4, type: 3 }, { x: 8550, level: 2, type: 2 }, { x: 9150, level: 0, type: 1 }]; } else if (stage === 10) { // Stage 10 positions (final stage) newObjectPositions = [{ x: 850, level: 2, type: 1 }, { x: 1450, level: 0, type: 3 }, { x: 2050, level: 3, type: 2 }, { x: 2650, level: 1, type: 1 }, { x: 3250, level: 4, type: 3 }, { x: 3850, level: 2, type: 2 }, { x: 4450, level: 0, type: 1 }, { x: 5050, level: 3, type: 3 }, { x: 5650, level: 1, type: 2 }, { x: 6250, level: 4, type: 1 }, { x: 6850, level: 2, type: 3 }, { x: 7450, level: 0, type: 2 }, { x: 8050, level: 3, type: 1 }, { x: 8650, level: 1, type: 3 }, { x: 9250, level: 4, type: 2 }]; } else { // For stages 11-20, generate randomized but properly spaced positions newObjectPositions = []; var usedPositions = []; var minDistance = 500; for (var objCount = 0; objCount < totalObjectsToKnock; objCount++) { var attempts = 0; var validPosition = false; var newPos; while (!validPosition && attempts < 50) { newPos = { x: 600 + Math.floor(Math.random() * 8500), // Random X between 600-9100 level: Math.floor(Math.random() * 5), // Random level 0-4 type: objCount % 6 + 1 // Cycle through types 1,2,3,4,5,6 }; validPosition = true; // Check distance from existing positions for (var u = 0; u < usedPositions.length; u++) { if (Math.abs(newPos.x - usedPositions[u].x) < minDistance && Math.abs(newPos.level - usedPositions[u].level) <= 1) { validPosition = false; break; } } attempts++; } if (validPosition) { newObjectPositions.push(newPos); usedPositions.push(newPos); } else { // Fallback to spread positions newObjectPositions.push({ x: 700 + objCount * 550, level: objCount % 5, type: objCount % 6 + 1 }); } } } // Create objects for the stage for (var i = 0; i < totalObjectsToKnock; i++) { var pos = newObjectPositions[i]; var obj = new ShelfObject(pos.type); obj.x = pos.x; obj.y = shelfLevels[pos.level] - 155; obj.objectNumber = i + 1; game.addChild(obj); shelfObjects.push(obj); } // Recreate dangerous objects for the stage var newDangerousPositions = []; if (stage === 1) { newDangerousPositions = [{ x: 2000, level: 1 }, { x: 2300, level: 0 }, { x: 3900, level: 3 }, { x: 5300, level: 2 }, { x: 6900, level: 4 }, { x: 8300, level: 1 }]; } else if (stage === 2) { newDangerousPositions = [{ x: 1200, level: 2 }, { x: 2600, level: 4 }, { x: 3800, level: 0 }, { x: 5000, level: 1 }, { x: 6600, level: 3 }, { x: 8000, level: 2 }]; } else if (stage === 3) { newDangerousPositions = [{ x: 1100, level: 1 }, { x: 2400, level: 3 }, { x: 3700, level: 0 }, { x: 5200, level: 4 }, { x: 6800, level: 2 }, { x: 8100, level: 3 }]; } else if (stage === 4) { newDangerousPositions = [{ x: 1400, level: 0 }, { x: 2800, level: 2 }, { x: 4100, level: 4 }, { x: 5600, level: 1 }, { x: 7000, level: 3 }, { x: 8400, level: 0 }]; } else if (stage === 5) { newDangerousPositions = [{ x: 1300, level: 3 }, { x: 2700, level: 1 }, { x: 4200, level: 2 }, { x: 5800, level: 4 }, { x: 7300, level: 0 }, { x: 8600, level: 3 }]; } else if (stage === 6) { newDangerousPositions = [{ x: 1100, level: 2 }, { x: 2500, level: 4 }, { x: 3900, level: 1 }, { x: 5300, level: 0 }, { x: 6700, level: 3 }, { x: 8200, level: 2 }]; } else if (stage === 7) { newDangerousPositions = [{ x: 1500, level: 1 }, { x: 2900, level: 3 }, { x: 4300, level: 0 }, { x: 5700, level: 4 }, { x: 7100, level: 2 }, { x: 8500, level: 1 }]; } else if (stage === 8) { newDangerousPositions = [{ x: 1200, level: 4 }, { x: 2600, level: 2 }, { x: 4000, level: 0 }, { x: 5400, level: 3 }, { x: 6800, level: 1 }, { x: 8300, level: 4 }]; } else if (stage === 9) { newDangerousPositions = [{ x: 1000, level: 0 }, { x: 2400, level: 2 }, { x: 3800, level: 4 }, { x: 5200, level: 1 }, { x: 6600, level: 3 }, { x: 8000, level: 0 }]; } else if (stage === 10) { newDangerousPositions = [{ x: 1300, level: 3 }, { x: 2700, level: 1 }, { x: 4100, level: 4 }, { x: 5500, level: 2 }, { x: 6900, level: 0 }, { x: 8400, level: 3 }]; } else { // For stages 11-20, generate randomized dangerous object positions newDangerousPositions = []; var dangerCount = Math.min(8, 4 + Math.floor(stage / 3)); // Increase danger objects as stages progress for (var d = 0; d < dangerCount; d++) { newDangerousPositions.push({ x: 1000 + Math.floor(Math.random() * 8000), // Random X between 1000-9000 level: Math.floor(Math.random() * 5) // Random level 0-4 }); } } for (var i = 0; i < newDangerousPositions.length; i++) { var dangerPos = newDangerousPositions[i]; var dangerousObj = new DangerousObject(); dangerousObj.x = dangerPos.x; dangerousObj.y = shelfLevels[dangerPos.level] - 75; game.addChild(dangerousObj); dangerousObjects.push(dangerousObj); } // Add dogs starting from stage 2 with safe distance from cat spawn if (stage >= 2) { var newDogPositions = []; // Generate dog positions ensuring they are away from cat safe spawn area var baseDogPositions = [{ x: 1500, level: 2 }, { x: 3200, level: 4 }, { x: 4800, level: 1 }, { x: 6400, level: 0 }, { x: 7800, level: 3 }]; for (var d = 0; d < baseDogPositions.length; d++) { var dogPos = baseDogPositions[d]; // Ensure dogs are at least 400px away from cat spawn area (safeCatX) if (Math.abs(dogPos.x - safeCatX) >= 400) { newDogPositions.push(dogPos); } else { // Adjust position to be further away var adjustedX = dogPos.x < safeCatX ? dogPos.x - 400 : dogPos.x + 400; adjustedX = Math.max(600, Math.min(adjustedX, 9000)); // Keep within bounds newDogPositions.push({ x: adjustedX, level: dogPos.level }); } } for (var i = 0; i < newDogPositions.length; i++) { var dogPos = newDogPositions[i]; var dog = new Dog(); dog.x = dogPos.x; dog.y = shelfLevels[dogPos.level] - 75; game.addChild(dog); dogs.push(dog); } } // Reset counters totalObjectsToKnock = 15; objectsKnockedDown = 0; storage.totalObjectsToKnock = totalObjectsToKnock; storage.objectsKnockedDown = objectsKnockedDown; // Resume music LK.playMusic('mainTheme'); } // 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 objects that are NOT falling var actualObjectsRemaining = 0; for (var j = 0; j < shelfObjects.length; j++) { if (!shelfObjects[j].isFalling) { actualObjectsRemaining++; } } var actualObjectsKnockedDown = totalObjectsToKnock - actualObjectsRemaining; progressText.setText('Stage ' + currentStage + ' - Objects: ' + actualObjectsKnockedDown + '/' + totalObjectsToKnock); // Update score display with current calculated score var currentRemainingSeconds = Math.max(0, Math.ceil((TIME_LIMIT - gameTimer) / 60)); var currentScore = Math.max(0, currentRemainingSeconds * 10 - obstaclePenalties); scoreText.setText('Score: ' + currentScore); // Check if time limit reached (only if cat is not dancing - i.e., game hasn't been won) if (gameTimer >= TIME_LIMIT && !cat.isDancing) { // Time's up - player loses regardless of objects remaining LK.showGameOver(); return; } spawnObject(); spawnDangerousObject(); // Laser removed spawnMouse(); spawnDog(); 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); } } // Laser cleanup removed // Separators are now persistent and don't need cleanup // 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); } } // Laser dot removed };
===================================================================
--- original.js
+++ change.js
@@ -698,9 +698,10 @@
}
// Check if separator would block movement on same shelf level
if (separator.isBlocking && sepShelfLevel === self.currentShelfLevel) {
var distanceToSeparator = Math.abs(newX - separator.x);
- if (distanceToSeparator < 100 && (self.direction > 0 && newX > separator.x && self.x <= separator.x || self.direction < 0 && newX < separator.x && self.x >= separator.x)) {
+ // Check collision from both directions with proper blocking distance
+ if (distanceToSeparator < 120 && (self.direction > 0 && newX > separator.x - 60 && self.x <= separator.x - 60 || self.direction < 0 && newX < separator.x + 60 && self.x >= separator.x + 60)) {
wouldBeBlocked = true;
break;
}
}
@@ -970,9 +971,9 @@
if (self.lives <= 0) {
LK.showGameOver();
}
}
- // Check for collisions with separators - only on same shelf level
+ // Check for collisions with separators and barriers - 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;
@@ -1021,8 +1022,59 @@
self.catBlockGraphics.scaleX = 2 * self.direction;
self.catBlockGraphics.scaleY = 2;
}
}
+ // Check for collisions with left barriers - only on same shelf level
+ for (var i = leftBarriers.length - 1; i >= 0; i--) {
+ var leftBarrier = leftBarriers[i];
+ // Calculate which shelf level the left barrier is on
+ var barrierShelfLevel = -1;
+ for (var level = 0; level < 5; level++) {
+ if (Math.abs(leftBarrier.y - (shelfLevels[level] - 150)) < 50) {
+ barrierShelfLevel = level;
+ break;
+ }
+ }
+ // Only collide if on same shelf level
+ if (self.intersects(leftBarrier) && leftBarrier.isBlocking && barrierShelfLevel === self.currentShelfLevel && !self.isBlockMode && !self.isJumping) {
+ // Push cat away from left barrier by 30 pixels
+ var pushDirection = 1; // Always push right from left barrier
+ var pushDistance = 30;
+ var targetX = self.x + pushDistance * pushDirection;
+ // Ensure target position is within game bounds
+ targetX = Math.max(200, Math.min(targetX, 9600));
+ // Stop any existing movement tweens on cat
+ tween.stop(self, {
+ x: true
+ });
+ // Push cat away from barrier
+ tween(self, {
+ x: targetX
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ // Enter block mode when hitting left barrier
+ self.isBlockMode = true;
+ self.blockTimer = 60; // 1 second at 60fps
+ // Stop movement during block
+ self.speed = 0;
+ // Show only cat-block graphics
+ catGraphics.visible = false;
+ catStepGraphics.visible = false;
+ self.catJumpGraphics.visible = false;
+ self.catElectrocutedGraphics.visible = false;
+ self.gatoEnjabonado.visible = false;
+ self.gatoKissGraphics.visible = false;
+ self.catHitGraphics.visible = false;
+ if (self.zarpazoGraphics) {
+ self.zarpazoGraphics.visible = false;
+ }
+ self.catBlockGraphics.visible = true;
+ self.catBlockGraphics.scaleX = 2 * self.direction;
+ self.catBlockGraphics.scaleY = 2;
+ }
+ }
// Handle electrocution
if (self.isElectrocuted === undefined) {
self.isElectrocuted = false;
self.electrocutionTimer = 0;
@@ -1367,11 +1419,11 @@
anchorX: 0.5,
anchorY: 1,
scaleX: 4,
scaleY: 4,
- y: 459
+ y: 0
});
- dangerousHitbox.alpha = 0.5; // invisible
+ dangerousHitbox.alpha = 0; // invisible
// Exponer hitbox para colisiones precisas
self.hitbox = dangerousHitbox;
self.isFalling = false;
self.fallSpeed = 0;
@@ -2135,26 +2187,26 @@
// Create left barrier column (at the beginning)
for (var level = 0; level < 5; level++) {
var leftBarrier = game.addChild(LK.getAsset('cubos', {
anchorX: 0.5,
- anchorY: 1,
+ anchorY: 0,
scaleX: 4,
scaleY: 4
}));
- leftBarrier.x = -200; // Position at the very start
+ leftBarrier.x = -100; // 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 96 shelves wide
for (var level = 0; level < 5; level++) {
var rightBarrier = game.addChild(LK.getAsset('cubos', {
anchorX: 0.5,
- anchorY: 1,
+ anchorY: 0,
scaleX: 4,
scaleY: 4
}));
- rightBarrier.x = 9600; // Position at end of 24 sections (24 * 400 = 9600)
+ rightBarrier.x = 9700; // Position at end of 24 sections (24 * 400 = 9600)
rightBarrier.y = shelfLevels[level] - 150; // Position on each shelf level
rightBarrier.isBlocking = true;
rightBarriers.push(rightBarrier);
}
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