User prompt
Agrega texturas únicas al perro , la de modo normal y estado de reposo
User prompt
El perro no atacará al jugador ni lo detendrá, al avisar a los guardias, el perro entrara en modo de reposo por 5 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega otro tipo de guardias, pero que este sea un perro, que aparezca al recolectar 4 piedras y que siga los rastros del jugador, si el perro entra en modo persecución alertara a todos los guardias ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega sonidos de pasos al jugador cada vez que se mueva
User prompt
Una vez desaparezca la imagen de cargaz eliminarla para optimizar el juego ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Arregla la pantalla de carga para que se vea por encima de todo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Que la pantalla de carga se vea por 3 segundos al iniciar el juego ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Que la pantalla de carga cubra todo
User prompt
Agrega una imagen que cubra todo al iniciar el juego y que desaparezca en 3 segundos como si fuera una pantalla de carga ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Reestablece el tamaño del jugador al salir del modo gatito ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'scaleX')' in or related to this line: 'player.children[0].scaleX = -Math.abs(player.children[0].scaleX);' Line Number: 738
User prompt
Agrega efecto de sonido miau al entrar en modo gatito
User prompt
Si el jugador está dentro de una pared que sea expulsado
User prompt
As que los árboles aparezcan un poco más alejados de la zona de Spawn
User prompt
Ahora agrega también una pared al árbol para que tampoco sea atravesable
User prompt
Agrega paredes a la roca , y que no pueda atravesarle
User prompt
Agrega hitbox circular a las rocas
User prompt
Agrega coliciones a la piedra y al árbol
User prompt
Al entrar en colición con la piedra lunar en modo gatito , la piedra empieza a rebotar en zigzag ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cambia la luz lunar por una nueva piedra lunar pero de color dorado
User prompt
Al entrar en modo gatito, que el tamaño del jugador se redusca de doble ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Agrega música de ambiente
User prompt
Cambia el spanw de la luz lunar, y que solo aparezca una vez
User prompt
Agrega hitbox y físicas de balón a la piedra lunar al entrar en modo gatito ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Al entrar en modo gatito, el jugador no podrá agarrar las piedras lunares
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
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') {
// Chase player
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;
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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x191970
});
/****
* Game Code
****/
// Game variables
var player;
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
// 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 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;
// Generate obstacles for hiding
for (var i = 0; i < 15; i++) {
var obstacleType = Math.random() > 0.5 ? 'tree' : 'rock';
var obstacle = game.addChild(new Obstacle(obstacleType));
// Generate position, ensuring trees are away from spawn area
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
obstacle.x = 200 + Math.random() * 1648;
obstacle.y = 200 + Math.random() * 2332;
// Check distance from player spawn (1024, 1366) for trees
if (obstacleType === 'tree') {
var dx = obstacle.x - 1024;
var dy = obstacle.y - 1366;
var distanceFromSpawn = Math.sqrt(dx * dx + dy * dy);
// Trees must be at least 400 pixels away from spawn
if (distanceFromSpawn >= 400) {
validPosition = true;
}
} else {
// Rocks can spawn anywhere
validPosition = true;
}
attempts++;
}
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);
// 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 obstacles (walls)
if (dragNode === player) {
for (var o = 0; o < obstacles.length; o++) {
var obstacle = obstacles[o];
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
var isColliding = false;
if (obstacle.hasCircularHitbox) {
// Check rocks with circular collision
isColliding = distance < obstacle.hitboxRadius + playerRadius;
} else {
// Check trees with rectangular collision
isColliding = player.intersects(obstacle);
}
if (isColliding) {
// Player is colliding with obstacle wall - push back
if (obstacle.hasCircularHitbox) {
// Handle rock collision with circular hitbox
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;
}
} else {
// Handle tree collision with rectangular bounds
if (distance > 0) {
var normalX = dx / distance;
var normalY = dy / distance;
var pushDistance = 120; // Tree collision distance
dragNode.x = obstacle.x + normalX * pushDistance;
dragNode.y = obstacle.y + normalY * pushDistance;
}
}
}
}
}
// Flip player based on movement direction
if (dragNode === player) {
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: (player.scaleX || 1) * 2,
scaleY: (player.scaleY || 1) * 2
}, {
duration: 500,
easing: tween.easeOut
});
LK.effects.flashObject(player, 0xE6E6FA, 1000);
}
}
// 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
});
// Enable kitten mode for 15 seconds
isKittenMode = true;
kittenModeTimer = 0;
// 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];
if (player.intersects(moonstone)) {
moonstone.destroy();
moonstones.splice(i, 1);
moonstonesCollected++;
LK.getSound('collect').play();
LK.setScore(moonstonesCollected);
scoreText.setText('Moonstones: ' + moonstonesCollected + '/' + totalMoonstones);
// Transform player
player.transform();
updateTransformationUI();
// 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];
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;
}
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -543,11 +543,31 @@
player.x = 1024;
player.y = 1366;
// 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;
+ var obstacleType = Math.random() > 0.5 ? 'tree' : 'rock';
+ var obstacle = game.addChild(new Obstacle(obstacleType));
+ // Generate position, ensuring trees are away from spawn area
+ var validPosition = false;
+ var attempts = 0;
+ while (!validPosition && attempts < 50) {
+ obstacle.x = 200 + Math.random() * 1648;
+ obstacle.y = 200 + Math.random() * 2332;
+ // Check distance from player spawn (1024, 1366) for trees
+ if (obstacleType === 'tree') {
+ var dx = obstacle.x - 1024;
+ var dy = obstacle.y - 1366;
+ var distanceFromSpawn = Math.sqrt(dx * dx + dy * dy);
+ // Trees must be at least 400 pixels away from spawn
+ if (distanceFromSpawn >= 400) {
+ validPosition = true;
+ }
+ } else {
+ // Rocks can spawn anywhere
+ validPosition = true;
+ }
+ attempts++;
+ }
obstacles.push(obstacle);
}
// Generate only one moonstone initially
var moonstone = game.addChild(new Moonstone());
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