User prompt
Que los árboles estén por encima de las rocas
User prompt
Que los árboles estén por encima de los guardias
User prompt
Cuándo el jugador toque los árboles se vuelvan semi transparentes asta que el jugador deje de tocarlos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Desactiva la aparición del bot
User prompt
Desactiva temporalmente al bot
User prompt
Reduce el número de guardias iniciales a 1
User prompt
Al iniciar el juego solo Allan 3 guardias
User prompt
El jugador ahora crese infinitamente, arregla eso por favor
User prompt
Que los niveles de recolección sean únicos para el jugador , y que el bot también tenga su propio nivel de recolección
User prompt
Independiza los niveles del bot a
User prompt
Si el playera bot está en modo atrapado, solo podrá volver a la normalidad si el jugador lo toca
User prompt
Si el bot entra en la zona de un guardia, solo alerte a este, no a todos
User prompt
Si el bot es atrapado cambie su textura a jugador atrapado , y cambie su modo a atrapado
User prompt
Please fix the bug: 'ReferenceError: playerDistance is not defined' in or related to this line: 'if (playerDistance < self.distanceFromPlayer) {' Line Number: 1031
User prompt
Si los guardias son alertados, que sigan al jugador o player bot más cercano
User prompt
Que el playera bot solo alerte a los guardias si entra en su zona de alcance
User prompt
Que el player bot pueda ser atrapado por los guardias, si es atrapado no activará el gane over
User prompt
Que el player bot pueda alertar a los guardias, y si lo hace que mantenga distancia
User prompt
Que el player bot tenga movimiento libre , y si aparece una piedra lunar que el player bot se dirijan a obtenerla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Que el player bot tenga niveles de transformación y activación de efecto aparte del jugador ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega un player bot
User prompt
Al entrar en modo gatito, el perro multiplique su velocidad y cambie la textura a carrera ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Modifican el modo de seguimiento del perro, que persiga por 3 segundos y luego se detenga por 2 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Al entrar en modo de reposo al pasar 1 segundo cambiar la textura del perro a pasivo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega un sonido de alerta al perro al detectar al jugador
/****
* 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') {
// Find nearest target (player or playerBot)
var distanceToPlayer = Math.sqrt((player.x - self.x) * (player.x - self.x) + (player.y - self.y) * (player.y - self.y));
var distanceToBot = Infinity;
if (playerBot && !playerBot.isCaught) {
distanceToBot = Math.sqrt((playerBot.x - self.x) * (playerBot.x - self.x) + (playerBot.y - self.y) * (playerBot.y - self.y));
}
// Chase the nearest target
if (distanceToBot < distanceToPlayer) {
targetX = playerBot.x;
targetY = playerBot.y;
} else {
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;
}
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
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
var textureId = 'texture_phase' + self.transformationLevel;
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.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)
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 guards
self.hasAlertedGuards = true;
self.canAlertGuards = false;
self.alertCooldown = self.alertCooldownDuration;
self.maintainDistance = true; // Start maintaining distance
// Alert all guards to chase player
for (var g = 0; g < guards.length; g++) {
var guard = guards[g];
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);
}
}
// 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 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;
// Create player bot
playerBot = game.addChild(new PlayerBot());
playerBot.x = 1024 + 100; // Start slightly offset from player
playerBot.y = 1366 + 50;
// Generate obstacles for hiding
for (var i = 0; i < 15; i++) {
var obstacle = game.addChild(new Obstacle(Math.random() > 0.5 ? 'tree' : 'rock'));
obstacle.x = 200 + Math.random() * 1648;
obstacle.y = 200 + Math.random() * 2332;
obstacles.push(obstacle);
}
// 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 guards
for (var i = 0; i < 4; 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);
}
// 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
// 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;
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);
// Also revert bot from kitten mode
if (playerBot) {
var currentBotGraphics = playerBot.children[0];
playerBot.removeChild(currentBotGraphics);
var botRevertGraphics;
if (playerBot.transformationLevel >= 7) {
botRevertGraphics = playerBot.attachAsset('werewolf', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
} else {
var botTextureId = 'texture_phase' + playerBot.transformationLevel;
botRevertGraphics = playerBot.attachAsset(botTextureId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.04,
scaleY: 0.04,
alpha: 0.8
});
}
botRevertGraphics.tint = 0xADD8E6; // Maintain blue tint
playerBot.addChild(botRevertGraphics);
// Restore bot size when reverting from kitten mode
tween(playerBot, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeOut
});
LK.effects.flashObject(playerBot, 0xADD8E6, 800);
}
}
}
// 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
});
// Also transform bot to kitten
if (playerBot) {
var currentBotGraphics = playerBot.children[0];
playerBot.removeChild(currentBotGraphics);
var botKittenGraphics = playerBot.attachAsset('kitten', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
botKittenGraphics.tint = 0xADD8E6; // Maintain blue tint
playerBot.addChild(botKittenGraphics);
// Reduce bot size by half when entering kitten mode
tween(playerBot, {
scaleX: (playerBot.scaleX || 1) * 0.5,
scaleY: (playerBot.scaleY || 1) * 0.5
}, {
duration: 500,
easing: tween.easeOut
});
}
// 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)) {
collected = true;
}
// Check bot collection
else if (playerBot && playerBot.intersects(moonstone)) {
collected = true;
}
if (collected) {
moonstone.destroy();
moonstones.splice(i, 1);
moonstonesCollected++;
LK.getSound('collect').play();
LK.setScore(moonstonesCollected);
scoreText.setText('Moonstones: ' + moonstonesCollected + '/' + totalMoonstones);
// Transform both player and bot
player.transform();
if (playerBot) {
playerBot.transform();
}
updateTransformationUI();
// 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
var newScale = (player.scaleX || 1) + 0.1;
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
if (moonstonesCollected % 2 == 0 && guards.length < 8) {
var newGuard = game.addChild(new Guard());
// 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;
}
// Check bot capture - bot gets caught but game continues
if (playerBot && playerBot.intersects(guard) && !playerBot.isCaught) {
// Mark bot as caught
playerBot.isCaught = true;
// Change bot texture to caught state
var currentBotGraphics = playerBot.children[0];
playerBot.removeChild(currentBotGraphics);
var botCaughtGraphics = playerBot.attachAsset('player_caught', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.08,
scaleY: 0.08,
alpha: 0.7
});
playerBot.addChild(botCaughtGraphics);
// Flash bot red but don't trigger game over
LK.effects.flashObject(playerBot, 0xFF0000, 1500);
// Play caught sound at lower volume for bot
var botCaughtSound = LK.getSound('caught');
botCaughtSound.volume = 0.3;
botCaughtSound.play();
// Stop bot movement and alerting abilities
playerBot.canMove = false;
playerBot.canAlertGuards = false;
}
}
// 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;
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -979,8 +979,10 @@
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) {
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