User prompt
Al perder el modo gatito, volver a hacer visible el rango de los guardias
User prompt
As que la hitbox de arresto del guardia sea más pequeño que el rango de detección
User prompt
Al alertar a un guardia que el guardia no haga daño por 1 segundo y luego si sea ostil ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mostrar el rango de detección de los guardias con una textura como aura ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Al entrar en modo gatito las físicas de la roca lunar se bloquean por las coliciones , arreglarlo por favor
User prompt
El jugador al detenerse siempre mira a la derecha, arreglarlo por favor
User prompt
Desactiva la piedra dorada
User prompt
Al caer una piedra lunar, dejar un rastro azul brillante ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Al caer una piedra lunar , que deje un pequeño rastro de brillo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Si estás en modo gigante no podrás obtener piedras lunares
User prompt
Si el modo gigante está activo, no podrá obtenerse el modo gatito
User prompt
Si el modo gatito está activo, no podrá activarse ni acumularse ningún otro modo al igual que el modo gigante
User prompt
Que la piedra lunar dorada aparezca cada 30 segundos
User prompt
Poner las texturas del modo gatito al modo gigante
User prompt
Al entrar en modo gigante los guardias no harán daño
User prompt
Al entrar en modo gigante, desactiva el límite de tamaño
User prompt
Que el efecto de modo gigante aumente el límite de tamaño
User prompt
Crea una nueva roca luna dorada, que aparezca cada 20 segundos , que haga lo mismo que el modo gatito pero que en vez de hacer al jugador pequeño su tamaño se multiplique x10 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega texturas de caminata al modo gatito ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Al cambiar de fase las texturas se duplican, solucionalo por favor
User prompt
Volver a la textura de quieto cuando el jugador no se mueve ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega una segunda textura al jugador de cada fase, y cambia cuando camines ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega dos tipos de textura de árbol, una la clásica, y la otra la nueva
User prompt
Que las piedras estén por debajo de los guardias
User prompt
Reduce el aumento de tamaño del jugador al obtener una piedra lunar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Dog = Container.expand(function () { var self = Container.call(this); self.speed = 2.5; self.chaseSpeed = 5; self.detectionRadius = 300; self.isChasing = false; self.trailFollowDistance = 150; self.alertRadius = 400; self.hasAlertedGuards = false; self.isResting = false; self.restTimer = 0; self.restDuration = 300; // 5 seconds at 60fps self.chaseTimer = 0; self.chaseDuration = 180; // 3 seconds at 60fps self.stopTimer = 0; self.stopDuration = 120; // 2 seconds at 60fps self.isStopped = false; self.isInKittenMode = false; self.normalSpeed = self.speed; self.normalChaseSpeed = self.chaseSpeed; var dogGraphics = self.attachAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.update = function () { // Handle kitten mode changes if (isKittenMode && !self.isInKittenMode) { // Entering kitten mode - multiply speed and change to run texture self.isInKittenMode = true; self.speed = self.normalSpeed * 2; self.chaseSpeed = self.normalChaseSpeed * 2; // Change to run texture self.removeChild(dogGraphics); dogGraphics = self.attachAsset('dog_run', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.addChild(dogGraphics); } else if (!isKittenMode && self.isInKittenMode) { // Exiting kitten mode - restore normal speed and texture self.isInKittenMode = false; self.speed = self.normalSpeed; self.chaseSpeed = self.normalChaseSpeed; // Change back to normal texture self.removeChild(dogGraphics); dogGraphics = self.attachAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.addChild(dogGraphics); } // Handle rest mode if (self.isResting) { self.restTimer++; // Change to passive texture after 1 second (60 frames) if (self.restTimer === 60) { self.removeChild(dogGraphics); dogGraphics = self.attachAsset('dog_rest', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.addChild(dogGraphics); } if (self.restTimer >= self.restDuration) { // Exit rest mode self.isResting = false; self.restTimer = 0; self.hasAlertedGuards = false; // Reset so dog can alert again // Change back to normal texture self.removeChild(dogGraphics); dogGraphics = self.attachAsset('dog_normal', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.addChild(dogGraphics); } // Dog doesn't move or detect during rest mode return; } // Check if player is in detection range and not in kitten mode var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var canDetectPlayer = distance < self.detectionRadius && !player.isHiding && !isKittenMode; if (canDetectPlayer) { if (!self.isChasing && !self.isStopped) { // Start chasing self.isChasing = true; self.chaseTimer = 0; self.hasAlertedGuards = false; dogGraphics.tint = 0xFF4444; // Red when chasing // Play dog alert sound when detecting player LK.getSound('dog_alert').play(); } // Handle chase duration if (self.isChasing) { self.chaseTimer++; if (self.chaseTimer >= self.chaseDuration) { // Stop chasing after 3 seconds and enter stop mode self.isChasing = false; self.isStopped = true; self.stopTimer = 0; dogGraphics.tint = 0xFFFFFF; // Remove red tint when stopping } } // Handle stop duration if (self.isStopped) { self.stopTimer++; if (self.stopTimer >= self.stopDuration) { // End stop mode after 2 seconds self.isStopped = false; self.stopTimer = 0; } } // Alert all guards when close enough during chase if (self.isChasing && distance < self.alertRadius && !self.hasAlertedGuards) { self.hasAlertedGuards = true; // Alert all guards for (var i = 0; i < guards.length; i++) { var guard = guards[i]; if (!guard.isAlerted) { guard.isAlerted = true; guard.alertState = 'chase_player'; guard.chaseTimer = 0; guard.alertSpeed = 6; // Change guard to chase texture var currentGraphics = guard.children[0]; guard.removeChild(currentGraphics); var chaseGraphics = guard.attachAsset('guard_chase', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); guard.addChild(chaseGraphics); } } // Enter rest mode for 5 seconds after alerting guards self.isResting = true; self.restTimer = 0; // Change to rest texture self.removeChild(dogGraphics); dogGraphics = self.attachAsset('dog_rest', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); self.addChild(dogGraphics); } // Chase player directly only if chasing and not stopped if (self.isChasing && !self.isStopped) { var angle = Math.atan2(dy, dx); self.x += Math.cos(angle) * self.chaseSpeed; self.y += Math.sin(angle) * self.chaseSpeed; } } else if (self.isChasing && distance > self.detectionRadius * 1.5) { // Stop chasing if player gets too far self.isChasing = false; self.isStopped = false; self.chaseTimer = 0; self.stopTimer = 0; self.hasAlertedGuards = false; dogGraphics.tint = 0xFFFFFF; // Remove tint when not chasing } else if (!self.isChasing && !self.isStopped) { // Follow player trail when not actively chasing and not stopped var trailDistance = Math.sqrt(dx * dx + dy * dy); if (trailDistance > self.trailFollowDistance) { var angle = Math.atan2(dy, dx); self.x += Math.cos(angle) * self.speed; self.y += Math.sin(angle) * self.speed; } } // Keep dog within bounds if (self.x < 100) self.x = 100; if (self.x > 1948) self.x = 1948; if (self.y < 100) self.y = 100; if (self.y > 2632) self.y = 2632; // Update dog flip based on movement direction if (dx > 0) { dogGraphics.scaleX = Math.abs(dogGraphics.scaleX); } else { dogGraphics.scaleX = -Math.abs(dogGraphics.scaleX); } }; return self; }); var Guard = Container.expand(function () { var self = Container.call(this); self.patrolSpeed = 1.5; self.alertSpeed = 4; self.detectionRadius = 250; self.isAlerted = false; self.alertState = 'none'; // 'none', 'chase_player', 'move_to_moonstone' self.chaseTimer = 0; self.chaseDuration = 180; // 3 seconds at 60fps self.patrolDirection = Math.random() * Math.PI * 2; self.patrolTimer = 0; self.lastInDetectionRange = false; var guardGraphics = self.attachAsset('guard', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.update = function () { self.patrolTimer++; // Check if player is in detection range and not hiding (and not in kitten mode) var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var currentInDetectionRange = distance < self.detectionRadius + player.detectionRadius && !player.isHiding && !isKittenMode; if (currentInDetectionRange) { // Check if player just entered detection range (transition from false to true) if (!self.lastInDetectionRange && currentInDetectionRange) { var guardSounds = ['stop', 'hey', 'dont_run']; var randomSound = guardSounds[Math.floor(Math.random() * guardSounds.length)]; LK.getSound(randomSound).play(); // Double player speed when alerting a guard player.speed *= 2; // If "don't run" sound is played, alert 3 random guards if (randomSound === 'dont_run') { var availableGuards = []; for (var i = 0; i < guards.length; i++) { if (guards[i] !== self && !guards[i].isAlerted) { availableGuards.push(guards[i]); } } // Alert up to 3 random guards var guardsToAlert = Math.min(3, availableGuards.length); for (var j = 0; j < guardsToAlert; j++) { var randomIndex = Math.floor(Math.random() * availableGuards.length); var guardToAlert = availableGuards[randomIndex]; guardToAlert.isAlerted = true; guardToAlert.alertState = 'move_to_moonstone'; guardToAlert.chaseTimer = 0; guardToAlert.alertSpeed = 6; // Set increased speed for alerted guards // Remove from available list to avoid double selection availableGuards.splice(randomIndex, 1); } } } if (!self.isAlerted) { // Start chasing - reset timer self.chaseTimer = 0; // Increase speed for chase mode self.alertSpeed = 6; // Increased from 4 // Change to chase texture self.removeChild(guardGraphics); guardGraphics = self.attachAsset('guard_chase', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.addChild(guardGraphics); } self.isAlerted = true; self.alertState = 'chase_player'; guardGraphics.tint = 0xFF4444; } else if (self.isAlerted) { // Continue chasing for the duration even if player is out of range self.chaseTimer++; if (self.chaseTimer >= self.chaseDuration) { self.isAlerted = false; self.alertState = 'none'; guardGraphics.tint = 0xFFFFFF; self.chaseTimer = 0; // Reset speed to normal patrol speed self.alertSpeed = 4; // Reset to original speed // Revert to normal texture self.removeChild(guardGraphics); guardGraphics = self.attachAsset('guard', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.addChild(guardGraphics); } } else { guardGraphics.tint = 0xFFFFFF; } if (self.isAlerted) { var targetX, targetY; if (self.alertState === 'chase_player') { // Target only player (bot disabled) targetX = player.x; targetY = player.y; guardGraphics.tint = 0xFF4444; // Red tint for chasing player } else if (self.alertState === 'move_to_moonstone') { // Move towards moonstone drop position targetX = lastMoonstoneDropX; targetY = lastMoonstoneDropY; guardGraphics.tint = 0x44FF44; // Green tint for moving to moonstone } else { // Default behavior (shouldn't happen when alerted) targetX = player.x; targetY = player.y; } var angle = Math.atan2(targetY - self.y, targetX - self.x); self.x += Math.cos(angle) * self.alertSpeed; self.y += Math.sin(angle) * self.alertSpeed; } else { // Patrol behavior if (self.patrolTimer % 120 == 0) { self.patrolDirection = Math.random() * Math.PI * 2; } self.x += Math.cos(self.patrolDirection) * self.patrolSpeed; self.y += Math.sin(self.patrolDirection) * self.patrolSpeed; // Keep guards within bounds if (self.x < 100) { self.x = 100; self.patrolDirection = Math.random() * Math.PI; } if (self.x > 1948) { self.x = 1948; self.patrolDirection = Math.PI + Math.random() * Math.PI; } if (self.y < 100) { self.y = 100; self.patrolDirection = Math.PI * 0.5 + Math.random() * Math.PI; } if (self.y > 2632) { self.y = 2632; self.patrolDirection = Math.PI * 1.5 + Math.random() * Math.PI; } } // Update guard flip based on movement direction if (self.isAlerted) { // In chase mode, flip based on direction to player if (dx > 0) { guardGraphics.scaleX = Math.abs(guardGraphics.scaleX); // Face right } else { guardGraphics.scaleX = -Math.abs(guardGraphics.scaleX); // Face left } } else { // In patrol mode, flip based on patrol direction var movementX = Math.cos(self.patrolDirection); if (movementX > 0) { guardGraphics.scaleX = Math.abs(guardGraphics.scaleX); // Face right } else { guardGraphics.scaleX = -Math.abs(guardGraphics.scaleX); // Face left } } // Update last detection state self.lastInDetectionRange = distance < self.detectionRadius + player.detectionRadius && !player.isHiding; }; return self; }); var MoonBeam = Container.expand(function () { var self = Container.call(this); var moonbeamGraphics = self.attachAsset('golden_moonstone', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); moonbeamGraphics.tint = 0xFFD700; // Golden color self.moveTimer = 0; self.moveDirection = Math.random() * Math.PI * 2; self.speed = 2; self.lifeTimer = 0; self.maxLifetime = 900; // 15 seconds at 60fps self.update = function () { // Golden glow animation moonbeamGraphics.alpha = 0.6 + Math.sin(LK.ticks * 0.15) * 0.2; moonbeamGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.1) * 0.15; moonbeamGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.1) * 0.15; moonbeamGraphics.rotation += 0.02; // Random movement self.moveTimer++; if (self.moveTimer % 60 == 0) { // Change direction every second self.moveDirection = Math.random() * Math.PI * 2; } self.x += Math.cos(self.moveDirection) * self.speed; self.y += Math.sin(self.moveDirection) * self.speed; // Keep within bounds if (self.x < 60) { self.x = 60; self.moveDirection = Math.random() * Math.PI; } if (self.x > 1988) { self.x = 1988; self.moveDirection = Math.PI + Math.random() * Math.PI; } if (self.y < 60) { self.y = 60; self.moveDirection = Math.PI * 0.5 + Math.random() * Math.PI; } if (self.y > 2672) { self.y = 2672; self.moveDirection = Math.PI * 1.5 + Math.random() * Math.PI; } // Handle lifetime self.lifeTimer++; if (self.lifeTimer >= self.maxLifetime) { // Fade out effect before disappearing tween(moonbeamGraphics, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); // Remove from moonbeams array for (var i = moonbeams.length - 1; i >= 0; i--) { if (moonbeams[i] === self) { moonbeams.splice(i, 1); break; } } } }); } }; return self; }); var Moonstone = Container.expand(function () { var self = Container.call(this); var moonstoneGraphics = self.attachAsset('moonstone', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.gravity = 0.5; self.bounce = 0.7; self.friction = 0.98; self.isPhysicsActive = false; self.isZigzagBouncing = false; self.zigzagTimer = 0; self.zigzagSpeed = 8; self.zigzagDirection = 0; self.activatePhysics = function () { self.isPhysicsActive = true; // Give initial random velocity when physics activates self.velocityX = (Math.random() - 0.5) * 10; self.velocityY = (Math.random() - 0.5) * 10; }; self.update = function () { // Gentle glow animation moonstoneGraphics.alpha = 0.7 + Math.sin(LK.ticks * 0.1) * 0.3; moonstoneGraphics.rotation += 0.02; // Zigzag bouncing behavior if (self.isZigzagBouncing) { self.zigzagTimer++; // Change direction every 30 frames (0.5 seconds) for zigzag effect if (self.zigzagTimer % 30 === 0) { // Create zigzag pattern by alternating direction var zigzagAngle = self.zigzagDirection + Math.PI / 3 * (Math.random() - 0.5); self.velocityX = Math.cos(zigzagAngle) * self.zigzagSpeed; self.velocityY = Math.sin(zigzagAngle) * self.zigzagSpeed; self.zigzagDirection = zigzagAngle; } // Update position with zigzag movement self.x += self.velocityX; self.y += self.velocityY; // Check collision with obstacles during zigzag for (var o = 0; o < obstacles.length; o++) { var obstacle = obstacles[o]; var isColliding = false; if (obstacle.hasCircularHitbox) { // Use circular collision detection for rocks var dx = self.x - obstacle.x; var dy = self.y - obstacle.y; var distance = Math.sqrt(dx * dx + dy * dy); isColliding = distance < obstacle.hitboxRadius + 45; // 45 is moonstone radius } else { // Use default rectangular collision for trees isColliding = self.intersects(obstacle); } if (isColliding) { // Bounce off obstacle by reversing direction if (obstacle.hasCircularHitbox) { // For rocks, calculate proper bounce direction var dx = self.x - obstacle.x; var dy = self.y - obstacle.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { var normalX = dx / distance; var normalY = dy / distance; // Reflect velocity based on collision normal var dotProduct = self.velocityX * normalX + self.velocityY * normalY; self.velocityX = self.velocityX - 2 * dotProduct * normalX; self.velocityY = self.velocityY - 2 * dotProduct * normalY; // Push moonstone away from rock wall var pushDistance = obstacle.hitboxRadius + 50; self.x = obstacle.x + normalX * pushDistance; self.y = obstacle.y + normalY * pushDistance; } } else { // For trees, use simple velocity reversal self.velocityX = -self.velocityX; self.velocityY = -self.velocityY; self.zigzagDirection += Math.PI; // Reverse direction // Move away from obstacle to prevent sticking self.x -= self.velocityX; self.y -= self.velocityY; } break; } } // Bounce off boundaries with direction change for zigzag if (self.x <= 45) { self.x = 45; self.velocityX = Math.abs(self.velocityX); self.zigzagDirection = Math.random() * Math.PI / 2; // Random right direction } if (self.x >= 2003) { self.x = 2003; self.velocityX = -Math.abs(self.velocityX); self.zigzagDirection = Math.PI / 2 + Math.random() * Math.PI / 2; // Random left direction } if (self.y <= 45) { self.y = 45; self.velocityY = Math.abs(self.velocityY); self.zigzagDirection = Math.random() * Math.PI; // Random down direction } if (self.y >= 2687) { self.y = 2687; self.velocityY = -Math.abs(self.velocityY); self.zigzagDirection = Math.PI + Math.random() * Math.PI; // Random up direction } // Stop zigzag after 5 seconds if (self.zigzagTimer >= 300) { self.isZigzagBouncing = false; self.zigzagTimer = 0; } } // Ball physics when in kitten mode and not zigzag bouncing else if (self.isPhysicsActive && isKittenMode) { // Apply gravity self.velocityY += self.gravity; // Apply friction self.velocityX *= self.friction; self.velocityY *= self.friction; // Update position self.x += self.velocityX; self.y += self.velocityY; // Check collision with obstacles during physics mode for (var o = 0; o < obstacles.length; o++) { var obstacle = obstacles[o]; var isColliding = false; var dx = self.x - obstacle.x; var dy = self.y - obstacle.y; var distance = Math.sqrt(dx * dx + dy * dy); if (obstacle.hasCircularHitbox) { // Use circular collision detection for rocks isColliding = distance < obstacle.hitboxRadius + 45; // 45 is moonstone radius } else { // Use default rectangular collision for trees isColliding = self.intersects(obstacle); } if (isColliding) { // Bounce off obstacle if (distance > 0) { // Normalize collision direction var normalX = dx / distance; var normalY = dy / distance; // Reflect velocity based on collision normal var dotProduct = self.velocityX * normalX + self.velocityY * normalY; self.velocityX = (self.velocityX - 2 * dotProduct * normalX) * self.bounce; self.velocityY = (self.velocityY - 2 * dotProduct * normalY) * self.bounce; // Move moonstone away from obstacle to prevent sticking if (obstacle.hasCircularHitbox) { self.x = obstacle.x + normalX * (obstacle.hitboxRadius + 50); self.y = obstacle.y + normalY * (obstacle.hitboxRadius + 50); } else { self.x = obstacle.x + normalX * 100; self.y = obstacle.y + normalY * 100; } } break; } } // Bounce off boundaries if (self.x <= 45) { self.x = 45; self.velocityX = -self.velocityX * self.bounce; } if (self.x >= 2003) { self.x = 2003; self.velocityX = -self.velocityX * self.bounce; } if (self.y <= 45) { self.y = 45; self.velocityY = -self.velocityY * self.bounce; } if (self.y >= 2687) { self.y = 2687; self.velocityY = -self.velocityY * self.bounce; } } }; return self; }); var Obstacle = Container.expand(function (assetType) { var self = Container.call(this); var obstacleGraphics = self.attachAsset(assetType, { anchorX: 0.5, anchorY: 0.5 }); // Add circular hitbox for rocks if (assetType === 'rock') { self.hitboxRadius = 90; // Circular hitbox radius for rocks self.hasCircularHitbox = true; } else { self.hasCircularHitbox = false; } // Add transparency tracking for trees self.isPlayerTouching = false; self.lastPlayerTouching = false; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.transformationLevel = 0; self.speed = 3; self.isHiding = false; self.detectionRadius = 120; self.lastX = 0; self.lastY = 0; self.footstepTimer = 0; self.footstepInterval = 15; // Play footstep every 15 frames when moving self.isWalking = false; self.lastWalkingState = false; var playerGraphics = self.attachAsset('texture_phase0', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.05, scaleY: 0.05 }); self.transform = function () { self.transformationLevel++; // Remove current graphics self.removeChild(playerGraphics); // Update appearance based on transformation level if (self.transformationLevel >= 7) { // Full werewolf playerGraphics = self.attachAsset('werewolf', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.detectionRadius = 80; } else { // Use phase-specific texture with walking state var textureId = 'texture_phase' + self.transformationLevel; if (self.isWalking) { textureId += '_walk'; } playerGraphics = self.attachAsset(textureId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.05, scaleY: 0.05 }); // Adjust speed and detection based on transformation self.speed = 3 + self.transformationLevel * 0.7; self.detectionRadius = 120 - self.transformationLevel * 5; } // Re-add the updated graphics self.addChild(playerGraphics); LK.getSound('transformation').play(); LK.effects.flashObject(self, 0xE6E6FA, 1000); }; self.updateTexture = function () { // Check if walking state changed if (self.lastWalkingState !== self.isWalking) { self.lastWalkingState = self.isWalking; // Remove current graphics var currentGraphics = self.children[0]; self.removeChild(currentGraphics); var newGraphics; if (self.transformationLevel >= 7) { // Werewolf doesn't change texture when walking newGraphics = self.attachAsset('werewolf', { anchorX: 0.5, anchorY: 0.5 }); } else { // Choose texture based on walking state and transformation level var textureId = 'texture_phase' + self.transformationLevel; if (self.isWalking) { textureId += '_walk'; } newGraphics = self.attachAsset(textureId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.05, scaleY: 0.05 }); } self.addChild(newGraphics); } }; self.checkHiding = function () { self.isHiding = false; // Check if player is behind any obstacle for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; var dx = self.x - obstacle.x; var dy = self.y - obstacle.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 70) { self.isHiding = true; break; } } }; return self; }); var PlayerBot = Container.expand(function () { var self = Container.call(this); self.transformationLevel = 0; self.botTransformationLevel = 0; // Independent transformation level for bot self.speed = 2.5; // Slightly slower than player self.isHiding = false; self.detectionRadius = 120; self.followDistance = 150; // Distance to maintain from player self.targetX = 0; self.targetY = 0; self.moveTimer = 0; self.footstepTimer = 0; self.footstepInterval = 20; // Slightly different timing than player self.lastX = 0; self.lastY = 0; self.isInBotKittenMode = false; // Independent kitten mode for bot self.botKittenModeTimer = 0; self.botKittenModeDuration = 1200; // 20 seconds at 60fps - longer than player self.botEffectTimer = 0; self.botEffectInterval = 480; // 8 seconds - bot activates effects more frequently self.canAlertGuards = true; // Bot can alert guards self.hasAlertedGuards = false; // Track if bot has alerted guards self.alertCooldown = 0; // Cooldown before bot can alert again self.alertCooldownDuration = 600; // 10 seconds at 60fps self.maintainDistance = false; // Whether bot should maintain distance from player self.distanceFromPlayer = 300; // Distance to maintain when keeping away self.isCaught = false; // Whether bot has been caught by guards self.canMove = true; // Whether bot can move (disabled when caught) self.mode = 'normal'; // Bot mode: 'normal' or 'caught' var botGraphics = self.attachAsset('texture_phase0', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.04, // Slightly smaller than player scaleY: 0.04, alpha: 0.8 // Slightly transparent to distinguish from player }); // Apply a slight blue tint to distinguish from player botGraphics.tint = 0xADD8E6; self.transform = function () { self.transformationLevel++; // Remove current graphics self.removeChild(botGraphics); // Update appearance based on transformation level if (self.transformationLevel >= 7) { // Full werewolf botGraphics = self.attachAsset('werewolf', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.speed = 7; // Slightly slower than player werewolf self.detectionRadius = 80; } else { // Use phase-specific texture var textureId = 'texture_phase' + self.transformationLevel; botGraphics = self.attachAsset(textureId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.04, scaleY: 0.04, alpha: 0.8 }); // Adjust speed and detection based on transformation self.speed = 2.5 + self.transformationLevel * 0.6; self.detectionRadius = 120 - self.transformationLevel * 5; } // Apply blue tint to distinguish from player botGraphics.tint = 0xADD8E6; // Re-add the updated graphics self.addChild(botGraphics); LK.effects.flashObject(self, 0xADD8E6, 800); }; self.botTransform = function () { self.botTransformationLevel++; // Remove current graphics self.removeChild(botGraphics); // Update appearance based on bot's independent transformation level if (self.botTransformationLevel >= 7) { // Full werewolf botGraphics = self.attachAsset('werewolf', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.speed = 8; // Bot werewolf is faster than regular bot self.detectionRadius = 70; } else { // Use phase-specific texture var textureId = 'texture_phase' + self.botTransformationLevel; botGraphics = self.attachAsset(textureId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.04, scaleY: 0.04, alpha: 0.8 }); // Adjust speed and detection based on bot's transformation self.speed = 2.5 + self.botTransformationLevel * 0.8; self.detectionRadius = 120 - self.botTransformationLevel * 6; } // Apply purple tint to distinguish bot transformations botGraphics.tint = 0x9370DB; // Re-add the updated graphics self.addChild(botGraphics); LK.effects.flashObject(self, 0x9370DB, 1000); // Bot transformation effect tween(self, { scaleX: (self.scaleX || 1) + 0.15, scaleY: (self.scaleY || 1) + 0.15 }, { duration: 800, easing: tween.easeOut }); }; self.activateBotKittenMode = function () { if (!self.isInBotKittenMode) { self.isInBotKittenMode = true; self.botKittenModeTimer = 0; // Transform to kitten with unique bot styling var currentBotGraphics = self.children[0]; self.removeChild(currentBotGraphics); var botKittenGraphics = self.attachAsset('kitten', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); // Apply unique purple-blue tint for bot kitten mode botKittenGraphics.tint = 0x6A5ACD; self.addChild(botKittenGraphics); // Unique scaling for bot kitten mode tween(self, { scaleX: (self.scaleX || 1) * 0.4, scaleY: (self.scaleY || 1) * 0.4 }, { duration: 600, easing: tween.easeOut }); // Play unique bot meow with different pitch var botMeow = LK.getSound('meow'); botMeow.volume = 0.6; botMeow.play(); LK.effects.flashObject(self, 0x6A5ACD, 1200); } }; self.checkHiding = function () { self.isHiding = false; // Check if bot is behind any obstacle for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; var dx = self.x - obstacle.x; var dy = self.y - obstacle.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 70) { self.isHiding = true; break; } } }; self.update = function () { // Handle bot's independent kitten mode timer if (self.isInBotKittenMode) { self.botKittenModeTimer++; if (self.botKittenModeTimer >= self.botKittenModeDuration) { // Revert from bot kitten mode self.isInBotKittenMode = false; self.botKittenModeTimer = 0; // Change bot back to current bot transformation level var currentBotGraphics = self.children[0]; self.removeChild(currentBotGraphics); var revertGraphics; if (self.botTransformationLevel >= 7) { revertGraphics = self.attachAsset('werewolf', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); } else { var textureId = 'texture_phase' + self.botTransformationLevel; revertGraphics = self.attachAsset(textureId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.04, scaleY: 0.04, alpha: 0.8 }); } revertGraphics.tint = 0x9370DB; // Purple tint for bot transformations self.addChild(revertGraphics); // Restore bot size when reverting from kitten mode tween(self, { scaleX: 1, scaleY: 1 }, { duration: 600, easing: tween.easeOut }); LK.effects.flashObject(self, 0x9370DB, 900); } } // Bot independent effect timer self.botEffectTimer++; if (self.botEffectTimer >= self.botEffectInterval) { self.botEffectTimer = 0; // Bot has 30% chance to transform independently if (Math.random() < 0.3 && self.botTransformationLevel < 7) { self.botTransform(); } // Bot has 25% chance to activate kitten mode independently else if (Math.random() < 0.25 && !self.isInBotKittenMode) { self.activateBotKittenMode(); } } // Handle alert cooldown if (self.alertCooldown > 0) { self.alertCooldown--; if (self.alertCooldown <= 0) { self.canAlertGuards = true; self.hasAlertedGuards = false; self.maintainDistance = false; // Stop maintaining distance after cooldown } } // Check if bot should alert guards (only when bot enters a guard's detection range) var shouldAlert = false; if (self.canAlertGuards && !self.hasAlertedGuards && !isKittenMode) { // Check if bot is within any guard's detection range for (var g = 0; g < guards.length; g++) { var guard = guards[g]; var guardDx = self.x - guard.x; var guardDy = self.y - guard.y; var guardDistance = Math.sqrt(guardDx * guardDx + guardDy * guardDy); // Check if bot is within this guard's detection radius if (guardDistance < guard.detectionRadius + self.detectionRadius) { shouldAlert = true; break; } } } if (shouldAlert) { // Bot enters guard detection range - alert only the specific guard self.hasAlertedGuards = true; self.canAlertGuards = false; self.alertCooldown = self.alertCooldownDuration; self.maintainDistance = true; // Start maintaining distance // Alert only the guard whose zone the bot entered for (var g = 0; g < guards.length; g++) { var guard = guards[g]; var guardDx = self.x - guard.x; var guardDy = self.y - guard.y; var guardDistance = Math.sqrt(guardDx * guardDx + guardDy * guardDy); // Only alert this specific guard if bot is in its detection range if (guardDistance < guard.detectionRadius + self.detectionRadius && !guard.isAlerted) { guard.isAlerted = true; guard.alertState = 'chase_player'; guard.chaseTimer = 0; guard.alertSpeed = 6; // Change guard to chase texture var currentGraphics = guard.children[0]; guard.removeChild(currentGraphics); var chaseGraphics = guard.attachAsset('guard_chase', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); guard.addChild(chaseGraphics); break; // Only alert one guard - the one whose zone was entered } } // Play alert sound LK.getSound('dog_alert').play(); // Flash bot to indicate it alerted guards LK.effects.flashObject(self, 0xFF4444, 800); } // Store last position for movement detection self.lastX = self.x; self.lastY = self.y; // Skip movement and other behaviors if bot is caught if (self.isCaught || !self.canMove) { return; } // Free movement behavior - check for moonstones first var nearestMoonstone = null; var shortestDistance = Infinity; // Find nearest moonstone for (var m = 0; m < moonstones.length; m++) { var moonstone = moonstones[m]; var mstoneDx = moonstone.x - self.x; var mstoneDy = moonstone.y - self.y; var mstoneDistance = Math.sqrt(mstoneDx * mstoneDx + mstoneDy * mstoneDy); if (mstoneDistance < shortestDistance) { shortestDistance = mstoneDistance; nearestMoonstone = moonstone; } } // Calculate distance to player for bot logic var playerDistance = Math.sqrt((player.x - self.x) * (player.x - self.x) + (player.y - self.y) * (player.y - self.y)); // Determine target based on bot state if (self.maintainDistance) { // Maintain distance from player when bot has alerted guards if (playerDistance < self.distanceFromPlayer) { // Move away from player var awayAngle = Math.atan2(self.y - player.y, self.x - player.x); self.targetX = self.x + Math.cos(awayAngle) * self.speed * 2; // Move away faster self.targetY = self.y + Math.sin(awayAngle) * self.speed * 2; } else { // Maintain current position if far enough self.targetX = self.x; self.targetY = self.y; } } else if (nearestMoonstone && shortestDistance < 600) { // Move towards nearest moonstone var mstoneDx = nearestMoonstone.x - self.x; var mstoneDy = nearestMoonstone.y - self.y; var mstoneAngle = Math.atan2(mstoneDy, mstoneDx); self.targetX = self.x + Math.cos(mstoneAngle) * self.speed * 1.5; // Faster when seeking moonstone self.targetY = self.y + Math.sin(mstoneAngle) * self.speed * 1.5; } else { // Free roaming movement when no moonstone nearby self.moveTimer++; if (self.moveTimer % 120 === 0) { // Change direction every 2 seconds for more freedom var randomAngle = Math.random() * Math.PI * 2; var roamDistance = 80 + Math.random() * 120; // Vary roaming distance self.targetX = self.x + Math.cos(randomAngle) * roamDistance; self.targetY = self.y + Math.sin(randomAngle) * roamDistance; } } // Move towards target position var targetDx = self.targetX - self.x; var targetDy = self.targetY - self.y; var targetDistance = Math.sqrt(targetDx * targetDx + targetDy * targetDy); if (targetDistance > 1) { var moveX = targetDx / targetDistance * self.speed; var moveY = targetDy / targetDistance * self.speed; self.x += moveX; self.y += moveY; } // Keep bot within bounds if (self.x < 40) self.x = 40; if (self.x > 2008) self.x = 2008; if (self.y < 40) self.y = 40; if (self.y > 2692) self.y = 2692; // Check collision with rock obstacles (walls) for (var o = 0; o < obstacles.length; o++) { var obstacle = obstacles[o]; if (obstacle.hasCircularHitbox) { // Only check rocks as walls var obstacleDx = self.x - obstacle.x; var obstacleDy = self.y - obstacle.y; var obstacleDistance = Math.sqrt(obstacleDx * obstacleDx + obstacleDy * obstacleDy); var botRadius = 35; // Bot collision radius if (obstacleDistance < obstacle.hitboxRadius + botRadius) { // Bot is colliding with rock wall - push back if (obstacleDistance > 0) { var normalX = obstacleDx / obstacleDistance; var normalY = obstacleDy / obstacleDistance; var pushDistance = obstacle.hitboxRadius + botRadius; self.x = obstacle.x + normalX * pushDistance; self.y = obstacle.y + normalY * pushDistance; } } } } // Play footstep sounds when bot is moving var movementX = self.x - self.lastX; var movementY = self.y - self.lastY; var isMoving = Math.sqrt(movementX * movementX + movementY * movementY) > 0.5; if (isMoving) { self.footstepTimer++; if (self.footstepTimer >= self.footstepInterval) { // Play footstep at lower volume for bot var footstepSound = LK.getSound('footsteps'); footstepSound.volume = 0.3; footstepSound.play(); self.footstepTimer = 0; } } else { self.footstepTimer = 0; } // Flip bot based on movement direction if (self.children.length > 0 && self.children[0]) { if (movementX > 0) { // Moving right - face right self.children[0].scaleX = Math.abs(self.children[0].scaleX); } else if (movementX < 0) { // Moving left - face left self.children[0].scaleX = -Math.abs(self.children[0].scaleX); } } // Update hiding status self.checkHiding(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x191970 }); /**** * Game Code ****/ // Game variables var player; var playerBot; var moonstones = []; var guards = []; var obstacles = []; var moonbeams = []; var dragNode = null; var moonstonesCollected = 0; var playerLevel = 0; // Independent level counter for player transformations var botLevel = 0; // Independent level counter for bot transformations var totalMoonstones = 7; var lastMoonstoneDropX = 0; var lastMoonstoneDropY = 0; var moonbeamEventTimer = 0; var moonbeamEventInterval = 900; // 15 seconds at 60fps var hasTransformedToKitten = storage.hasTransformedToKitten || false; var isKittenMode = false; var kittenModeTimer = 0; var kittenModeDuration = 900; // 15 seconds at 60fps var dog = null; var dogSpawned = false; // Create UI var scoreText = new Text2('Moonstones: 0/7', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var transformationText = new Text2('Human Child', { size: 50, fill: 0xE6E6FA }); transformationText.anchor.set(0.5, 0); transformationText.y = 80; LK.gui.top.addChild(transformationText); // Create loading screen that covers the entire game var loadingScreen = LK.gui.center.addChild(LK.getAsset('loadingScreen', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, width: 2048, height: 2732 })); // Keep loading screen visible for exactly 3 seconds, then fade out LK.setTimeout(function () { tween(loadingScreen, { alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Remove loading screen from GUI and destroy to free memory LK.gui.center.removeChild(loadingScreen); loadingScreen.destroy(); loadingScreen = null; // Clear reference for garbage collection } }); }, 3000); // Create grass ground var grass = game.addChild(LK.getAsset('grass', { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 0.82, scaleY: 1.16 })); // Create player player = game.addChild(new Player()); player.x = 1024; player.y = 1366; // Bot spawning disabled playerBot = null; // Generate only one moonstone initially var moonstone = game.addChild(new Moonstone()); moonstone.x = 150 + Math.random() * 1748; moonstone.y = 150 + Math.random() * 2432; moonstones.push(moonstone); // Function to spawn moonbeam at random location function spawnMoonbeam() { var moonbeam = game.addChild(new MoonBeam()); moonbeam.x = 60 + Math.random() * 1928; moonbeam.y = 60 + Math.random() * 2612; moonbeams.push(moonbeam); // Add entrance effect moonbeam.children[0].alpha = 0; tween(moonbeam.children[0], { alpha: 0.8 }, { duration: 1000, easing: tween.easeOut }); } // Function to spawn new moonstone from the sky function spawnMoonstoneFromSky() { var newMoonstone = game.addChild(new Moonstone()); newMoonstone.x = 150 + Math.random() * 1748; newMoonstone.y = -100; // Start above the screen var finalY = 150 + Math.random() * 2432; // Store the drop position for guard alerting lastMoonstoneDropX = newMoonstone.x; lastMoonstoneDropY = finalY; moonstones.push(newMoonstone); // Activate physics if player is in kitten mode if (isKittenMode) { newMoonstone.activatePhysics(); } // Animate falling from sky tween(newMoonstone, { y: finalY }, { duration: 2000, easing: tween.easeOut, onComplete: function onComplete() { // Alert all guards to move towards the dropped moonstone for (var i = 0; i < guards.length; i++) { var guard = guards[i]; guard.isAlerted = true; guard.alertState = 'move_to_moonstone'; guard.chaseTimer = 0; guard.alertSpeed = 6; // Change to chase texture var currentGraphics = guard.children[0]; guard.removeChild(currentGraphics); var chaseGraphics = guard.attachAsset('guard_chase', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); guard.addChild(chaseGraphics); } } }); } // Generate obstacles for hiding - rocks first, then guards, then trees (so trees appear above guards and guards above rocks) // Generate rocks first (lowest z-index) for (var i = 0; i < 7; i++) { var rock = game.addChild(new Obstacle('rock')); rock.x = 200 + Math.random() * 1648; rock.y = 200 + Math.random() * 2332; obstacles.push(rock); } // Generate guards second so they appear above rocks but below trees for (var i = 0; i < 1; i++) { var guard = game.addChild(new Guard()); // Spawn guards far from player spawn (1024, 1366) var angle = Math.random() * Math.PI * 2; var distance = 1200 + Math.random() * 800; // 1200-2000 pixels away from center guard.x = 1024 + Math.cos(angle) * distance; guard.y = 1366 + Math.sin(angle) * distance; // Keep guards within game bounds if (guard.x < 100) guard.x = 100; if (guard.x > 1948) guard.x = 1948; if (guard.y < 100) guard.y = 100; if (guard.y > 2632) guard.y = 2632; guards.push(guard); } // Generate trees second (higher z-index, appear above rocks) for (var i = 0; i < 8; i++) { // Randomly choose between classic and new tree texture var treeType = Math.random() < 0.5 ? 'tree' : 'tree_new'; var tree = game.addChild(new Obstacle(treeType)); tree.x = 200 + Math.random() * 1648; tree.y = 200 + Math.random() * 2332; obstacles.push(tree); } // Start ambient music LK.playMusic('ambient'); function updateTransformationUI() { var transformationNames = ['Human Child', 'Growing Tail', 'Wolf Ears', 'Sharp Claws', 'Wolf Paws', 'Wolf Snout', 'Growing Fur', 'Full Werewolf']; transformationText.setText(transformationNames[player.transformationLevel] || 'Full Werewolf'); } function handleMove(x, y, obj) { if (dragNode) { // Track previous position for flip detection var previousX = dragNode.x; var previousY = dragNode.y; // Calculate desired movement var deltaX = x - dragNode.x; var deltaY = y - dragNode.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Check if player is actually moving var isMoving = distance > 0.5; // Only consider significant movement // Update player walking state and texture if (dragNode === player) { player.isWalking = isMoving; player.updateTexture(); } // Apply speed limit to prevent teleportation var maxSpeed = 15; // Maximum pixels per frame if (distance > maxSpeed) { // Normalize the movement vector and apply speed limit var normalizedX = deltaX / distance; var normalizedY = deltaY / distance; dragNode.x += normalizedX * maxSpeed; dragNode.y += normalizedY * maxSpeed; } else { dragNode.x = x; dragNode.y = y; } // Keep player within bounds if (dragNode.x < 40) dragNode.x = 40; if (dragNode.x > 2008) dragNode.x = 2008; if (dragNode.y < 40) dragNode.y = 40; if (dragNode.y > 2692) dragNode.y = 2692; // Check collision with rock obstacles (walls) if (dragNode === player) { for (var o = 0; o < obstacles.length; o++) { var obstacle = obstacles[o]; if (obstacle.hasCircularHitbox) { // Only check rocks as walls var dx = dragNode.x - obstacle.x; var dy = dragNode.y - obstacle.y; var distance = Math.sqrt(dx * dx + dy * dy); var playerRadius = 40; // Player collision radius if (distance < obstacle.hitboxRadius + playerRadius) { // Player is colliding with rock wall - push back if (distance > 0) { var normalX = dx / distance; var normalY = dy / distance; var pushDistance = obstacle.hitboxRadius + playerRadius; dragNode.x = obstacle.x + normalX * pushDistance; dragNode.y = obstacle.y + normalY * pushDistance; } } } } } // Play footstep sounds when player is moving if (dragNode === player && isMoving) { dragNode.footstepTimer++; if (dragNode.footstepTimer >= dragNode.footstepInterval) { LK.getSound('footsteps').play(); dragNode.footstepTimer = 0; } } else if (dragNode === player && !isMoving) { // Reset footstep timer when not moving dragNode.footstepTimer = 0; } // Flip player based on movement direction if (dragNode === player && player.children.length > 0 && player.children[0]) { var movementX = dragNode.x - previousX; if (movementX > 0) { // Moving right - face right player.children[0].scaleX = Math.abs(player.children[0].scaleX); } else if (movementX < 0) { // Moving left - face left player.children[0].scaleX = -Math.abs(player.children[0].scaleX); } } } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = player; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; game.update = function () { // Spawn moonbeam only once per game (only if not already spawned) if (!hasTransformedToKitten && moonbeams.length === 0) { moonbeamEventTimer++; if (moonbeamEventTimer >= moonbeamEventInterval) { spawnMoonbeam(); moonbeamEventTimer = 0; } } // Update kitten mode timer if (isKittenMode) { kittenModeTimer++; if (kittenModeTimer >= kittenModeDuration) { // Revert from kitten mode isKittenMode = false; kittenModeTimer = 0; // Change player back to current transformation var currentPlayerGraphics = player.children[0]; player.removeChild(currentPlayerGraphics); var revertGraphics; if (player.transformationLevel >= 7) { revertGraphics = player.attachAsset('werewolf', { anchorX: 0.5, anchorY: 0.5 }); } else { var textureId = 'texture_phase' + player.transformationLevel; if (player.isWalking) { textureId += '_walk'; } revertGraphics = player.attachAsset(textureId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.05, scaleY: 0.05 }); } player.addChild(revertGraphics); // Restore player size when reverting from kitten mode tween(player, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeOut }); LK.effects.flashObject(player, 0xE6E6FA, 1000); // Bot kitten mode revert disabled } } // Update player hiding status player.checkHiding(); // Check moonbeam collision for (var m = moonbeams.length - 1; m >= 0; m--) { var moonbeam = moonbeams[m]; if (player.intersects(moonbeam)) { // Transform player to kitten temporarily var currentPlayerGraphics = player.children[0]; player.removeChild(currentPlayerGraphics); var kittenGraphics = player.attachAsset('kitten', { anchorX: 0.5, anchorY: 0.5 }); player.addChild(kittenGraphics); // Reduce player size by half when entering kitten mode tween(player, { scaleX: (player.scaleX || 1) * 0.5, scaleY: (player.scaleY || 1) * 0.5 }, { duration: 500, easing: tween.easeOut }); // Bot kitten transformation disabled // Enable kitten mode for 15 seconds isKittenMode = true; kittenModeTimer = 0; // Play meow sound for kitten transformation LK.getSound('meow').play(); // Activate physics for all existing moonstones for (var p = 0; p < moonstones.length; p++) { moonstones[p].activatePhysics(); } // Make all guards passive for (var k = 0; k < guards.length; k++) { var guard = guards[k]; guard.isAlerted = false; guard.alertState = 'none'; guard.chaseTimer = 0; // Reset guard graphics to normal var currentGuardGraphics = guard.children[0]; guard.removeChild(currentGuardGraphics); var normalGraphics = guard.attachAsset('guard', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); guard.addChild(normalGraphics); normalGraphics.tint = 0xFFFFFF; } // Remove the moonbeam that was touched moonbeam.destroy(); moonbeams.splice(m, 1); LK.effects.flashObject(player, 0xffa500, 1000); break; } } // Check moonstone interactions if (!isKittenMode) { // Normal collection when not in kitten mode for (var i = moonstones.length - 1; i >= 0; i--) { var moonstone = moonstones[i]; var collected = false; // Check player collection if (player.intersects(moonstone)) { moonstone.destroy(); moonstones.splice(i, 1); moonstonesCollected++; playerLevel++; // Player collected - increment player level player.transformationLevel = Math.min(playerLevel - 1, 7); // Set player transformation level player.transform(); LK.getSound('collect').play(); LK.setScore(moonstonesCollected); scoreText.setText('Moonstones: ' + moonstonesCollected + '/' + totalMoonstones); updateTransformationUI(); } // Bot collection disabled // Spawn dog when collecting 4th moonstone if (moonstonesCollected === 4 && !dogSpawned) { dogSpawned = true; dog = game.addChild(new Dog()); // Spawn dog far from player var angle = Math.random() * Math.PI * 2; var distance = 800 + Math.random() * 400; dog.x = player.x + Math.cos(angle) * distance; dog.y = player.y + Math.sin(angle) * distance; // Keep dog within bounds if (dog.x < 100) dog.x = 100; if (dog.x > 1948) dog.x = 1948; if (dog.y < 100) dog.y = 100; if (dog.y > 2632) dog.y = 2632; } // Increase player size slightly with smooth animation when player collects (limited growth) if (playerLevel > 0 && playerLevel <= 7) { var newScale = Math.min((player.scaleX || 1) + 0.05, 1.35); // Cap maximum scale at 1.35 tween(player, { scaleX: newScale, scaleY: newScale }, { duration: 500, easing: tween.easeOut }); } // Spawn new moonstone from sky if there are none on screen and haven't won yet if (moonstones.length === 0 && moonstonesCollected < totalMoonstones) { spawnMoonstoneFromSky(); } // Check win condition if (moonstonesCollected >= totalMoonstones) { LK.showYouWin(); return; } // Add more guards as player transforms - insert at lower z-index to appear below trees if (moonstonesCollected % 2 == 0 && guards.length < 8) { var newGuard = new Guard(); // Find the index where obstacles start to insert guard before them var obstacleIndex = -1; for (var idx = 0; idx < game.children.length; idx++) { if (obstacles.indexOf(game.children[idx]) !== -1) { obstacleIndex = idx; break; } } // Insert guard before obstacles if found, otherwise add normally if (obstacleIndex !== -1) { game.addChildAt(newGuard, obstacleIndex); } else { game.addChild(newGuard); } // Spawn new guards far from current player position var angle = Math.random() * Math.PI * 2; var distance = 1000 + Math.random() * 600; // 1000-1600 pixels away from player newGuard.x = player.x + Math.cos(angle) * distance; newGuard.y = player.y + Math.sin(angle) * distance; // Keep guards within game bounds if (newGuard.x < 100) newGuard.x = 100; if (newGuard.x > 1948) newGuard.x = 1948; if (newGuard.y < 100) newGuard.y = 100; if (newGuard.y > 2632) newGuard.y = 2632; guards.push(newGuard); } } } else { // Collision detection in kitten mode - trigger zigzag bouncing for (var i = 0; i < moonstones.length; i++) { var moonstone = moonstones[i]; if (moonstone.lastWasColliding === undefined) moonstone.lastWasColliding = false; var currentColliding = player.intersects(moonstone); // Check if collision just started (transition from false to true) if (!moonstone.lastWasColliding && currentColliding) { // Start zigzag bouncing behavior moonstone.isZigzagBouncing = true; moonstone.zigzagTimer = 0; moonstone.zigzagSpeed = 8; moonstone.zigzagDirection = Math.random() * Math.PI * 2; // Override physics with zigzag movement moonstone.velocityX = Math.cos(moonstone.zigzagDirection) * moonstone.zigzagSpeed; moonstone.velocityY = Math.sin(moonstone.zigzagDirection) * moonstone.zigzagSpeed; } moonstone.lastWasColliding = currentColliding; } } // Check guard capture (only if not in kitten mode) if (!isKittenMode) { for (var g = 0; g < guards.length; g++) { var guard = guards[g]; // Check player capture if (player.intersects(guard)) { // Change player texture to caught state var currentPlayerGraphics = player.children[0]; player.removeChild(currentPlayerGraphics); var caughtGraphics = player.attachAsset('player_caught', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1, scaleY: 0.1 }); player.addChild(caughtGraphics); LK.getSound('caught').play(); LK.effects.flashScreen(0xFF0000, 1000); LK.showGameOver(); return; } // Bot capture and rescue mechanics disabled } // Check dog capture if (dog && player.intersects(dog)) { // Change player texture to caught state var currentPlayerGraphics = player.children[0]; player.removeChild(currentPlayerGraphics); var caughtGraphics = player.attachAsset('player_caught', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1, scaleY: 0.1 }); player.addChild(caughtGraphics); LK.getSound('caught').play(); LK.effects.flashScreen(0xFF0000, 1000); LK.showGameOver(); return; } } // Handle tree transparency when player touches them for (var t = 0; t < obstacles.length; t++) { var obstacle = obstacles[t]; // Only apply transparency to trees, not rocks if (!obstacle.hasCircularHitbox) { obstacle.lastPlayerTouching = obstacle.isPlayerTouching; obstacle.isPlayerTouching = player.intersects(obstacle); // Check if player just started touching the tree if (!obstacle.lastPlayerTouching && obstacle.isPlayerTouching) { // Make tree semi-transparent tween(obstacle.children[0], { alpha: 0.3 }, { duration: 300, easing: tween.easeOut }); } // Check if player stopped touching the tree else if (obstacle.lastPlayerTouching && !obstacle.isPlayerTouching) { // Make tree fully opaque again tween(obstacle.children[0], { alpha: 1.0 }, { duration: 500, easing: tween.easeOut }); } } } };
===================================================================
--- original.js
+++ change.js
@@ -630,8 +630,10 @@
self.lastX = 0;
self.lastY = 0;
self.footstepTimer = 0;
self.footstepInterval = 15; // Play footstep every 15 frames when moving
+ self.isWalking = false;
+ self.lastWalkingState = false;
var playerGraphics = self.attachAsset('texture_phase0', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.05,
@@ -650,10 +652,13 @@
});
self.speed = 8;
self.detectionRadius = 80;
} else {
- // Use phase-specific texture
+ // Use phase-specific texture with walking state
var textureId = 'texture_phase' + self.transformationLevel;
+ if (self.isWalking) {
+ textureId += '_walk';
+ }
playerGraphics = self.attachAsset(textureId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.05,
@@ -667,8 +672,38 @@
self.addChild(playerGraphics);
LK.getSound('transformation').play();
LK.effects.flashObject(self, 0xE6E6FA, 1000);
};
+ self.updateTexture = function () {
+ // Check if walking state changed
+ if (self.lastWalkingState !== self.isWalking) {
+ self.lastWalkingState = self.isWalking;
+ // Remove current graphics
+ var currentGraphics = self.children[0];
+ self.removeChild(currentGraphics);
+ var newGraphics;
+ if (self.transformationLevel >= 7) {
+ // Werewolf doesn't change texture when walking
+ newGraphics = self.attachAsset('werewolf', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else {
+ // Choose texture based on walking state and transformation level
+ var textureId = 'texture_phase' + self.transformationLevel;
+ if (self.isWalking) {
+ textureId += '_walk';
+ }
+ newGraphics = self.attachAsset(textureId, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.05,
+ scaleY: 0.05
+ });
+ }
+ self.addChild(newGraphics);
+ }
+ };
self.checkHiding = function () {
self.isHiding = false;
// Check if player is behind any obstacle
for (var i = 0; i < obstacles.length; i++) {
@@ -1273,8 +1308,13 @@
var deltaY = y - dragNode.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Check if player is actually moving
var isMoving = distance > 0.5; // Only consider significant movement
+ // Update player walking state and texture
+ if (dragNode === player) {
+ player.isWalking = isMoving;
+ player.updateTexture();
+ }
// Apply speed limit to prevent teleportation
var maxSpeed = 15; // Maximum pixels per frame
if (distance > maxSpeed) {
// Normalize the movement vector and apply speed limit
@@ -1372,8 +1412,11 @@
anchorY: 0.5
});
} else {
var textureId = 'texture_phase' + player.transformationLevel;
+ if (player.isWalking) {
+ textureId += '_walk';
+ }
revertGraphics = player.attachAsset(textureId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.05,
Pixel art de árbol pero de noche. In-Game asset. 2d. High contrast. No shadows
Piedra lunar brillante pixelart. In-Game asset. 2d. High contrast. No shadows
Guardia completamente negro con linterna iluminando con un circulo de aura pixelart. In-Game asset. 2d. High contrast. No shadows
Cesped oscuro de noche pixel art. In-Game asset. 2d. High contrast. No shadows
Niño pero de noche pixelart. In-Game asset. 2d. High contrast. No shadows
Cola de lobo, pixelart
Garras de lobo, pixelart
Nariz de lobo, pixel art
Silueta corriendo
Jaula de metal oscura , pixel art. In-Game asset. 2d. High contrast. No shadows
Transformalo en un gatito
Elimina los cristales y agrega árboles , estilo pixelart
Ahora que el perro esté ladrando
Silueta de perro corriendo
Corriendo
Corriendo pixelart
Gatito corriendo pixelart
Corriendo , pixelart
Corriendo, pixelart
Corriendo, pixelart
Corriendo, pixelart
Quítale la camisa, aslo más grande y peludo, que este en cuatro patas , pixelart