User prompt
If the power goes out the player will be jumpscared by the blue and green cat
User prompt
When the blue and green cat shows up at the corridor the player has five seconds to close the door or the cat will jumpscare the player ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'ReferenceError: currentRoomIndex is not defined' in or related to this line: 'if (currentRoomIndex !== 0) {' Line Number: 762
User prompt
The alarm warning sound can't play if the blue and green cat is on the main entrance camera
User prompt
Remove the warning alarm sound
User prompt
The warning sound will only play when the blue and green cat makes his first camera movement
User prompt
When a door is closed and the blue and green cat is at that door's corresponding hallway the blue and green cat must be sent back to the main entrance area and can't attack the player again until an in-game hour has past the blue and green cat can't jumpscare if he isn't at the corridor
User prompt
The blue and green cat must wait an in -game hour before attacking again
User prompt
The blue and green cat must be at the corridor to jumpscare the player
User prompt
The blue and green cat can only jumpscare the player if the power goes out or if the blue and green cat is standing at the corridor
User prompt
When the blue and green cat is about to jumpscare the player he should appear at the corridor
User prompt
Make sure the blue and green cat is visible to the player in the office when a jumpscare is triggered
User prompt
Make sure the blue and green cat is visible to the player in the office when a jumpscare is triggered
User prompt
Please fix the bug: 'Uncaught ReferenceError: inCorridor is not defined' in or related to this line: 'corridorAnimatronics["right"].setVisible(animatronicController.corridorSide === "right" && inCorridor);' Line Number: 1117
User prompt
The blue and green cat's first camera movement must happen at the moment the in-game clock reads 12:50 AM
User prompt
Make the blue and green cat move from one camera to the next camera more often
User prompt
Make the blue and green cat slowly approach the play by occasionally moving from one camera to the next when the cat reaches camera five Make the cat appear at the corridor if the player closes the door within 5 seconds the cat will return to the main entrance camera ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught ReferenceError: corridorSide is not defined' in or related to this line: 'corridorAnimatronics["left"].setVisible(corridorSide === "left" && inCorridor);' Line Number: 985
User prompt
Stop the wihte flashing on the cameras
User prompt
Please fix the bug: 'Uncaught ReferenceError: corridorSide is not defined' in or related to this line: 'corridorAnimatronics["left"].setVisible(corridorSide === "left" && inCorridor);' Line Number: 986
User prompt
Remove the random black squares and rectangles on the cameras
User prompt
Okay these cameras are just nearly unusable
User prompt
Remove the blinking red screen on the main entrance camera
User prompt
Remove the video effect on camera one (main entrance)
User prompt
The blue and green cat should not disappear
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { currentNight: 1, highestNight: 1 }); /**** * Classes ****/ var AnimatronicCorridor = Container.expand(function (side) { var self = Container.call(this); self.side = side; // "left" or "right" // Create the animatronic for the corridor var animatronic = self.attachAsset('animatronic', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.setVisible = function (visible) { self.visible = visible; if (visible) { // Animation for appearing in corridor animatronic.alpha = 0; tween(animatronic, { alpha: 1 }, { duration: 500 }); // Add a creepy movement animation tween(animatronic, { y: animatronic.y + 30 }, { duration: 2000, yoyo: true, repeat: -1 }); } }; // Make initially visible self.visible = true; return self; }); var CameraButton = Container.expand(function (id, x, y) { var self = Container.call(this); self.roomId = id; var button = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); var text = new Text2('CAM ' + id, { size: 60, fill: 0xFFFFFF }); text.anchor.set(0.5, 0.5); self.addChild(text); self.x = x; self.y = y; self.interactive = true; self.down = function () { tween(button, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); LK.getSound('camera').play(); }; self.up = function () { tween(button, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (currentCamera !== self.roomId) { currentCamera = self.roomId; showCamera(self.roomId); } }; return self; }); var DoorButton = Container.expand(function (side) { var self = Container.call(this); self.side = side; // "left" or "right" self.isOpen = true; var button = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 150, height: 150 }); var text = new Text2('DOOR', { size: 40, fill: 0xFFFFFF }); text.anchor.set(0.5, 0.5); self.addChild(text); self.interactive = true; self.down = function () { tween(button, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.up = function () { tween(button, { scaleX: 1, scaleY: 1 }, { duration: 100 }); self.toggleDoor(); LK.getSound('door').play(); }; self.toggleDoor = function () { self.isOpen = !self.isOpen; if (self.isOpen) { text.setText("DOOR"); button.tint = 0x333333; powerDrain -= 5; // Reduce power drain when door is opened if (doors[self.side]) { tween(doors[self.side], { y: 2732 - doors[self.side].height / 2, tint: 0x000000 }, { duration: 300 }); } } else { text.setText("OPEN"); button.tint = 0x555555; powerDrain += 5; // Increase power drain when door is closed if (doors[self.side]) { tween(doors[self.side], { y: 2732 - doors[self.side].height, tint: 0xFFFFFF }, { duration: 300 }); } } }; return self; }); var LightButton = Container.expand(function (side) { var self = Container.call(this); self.side = side; // "left" or "right" self.isOn = false; var button = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 150, height: 150 }); var text = new Text2('LIGHT', { size: 40, fill: 0xFFFFFF }); text.anchor.set(0.5, 0.5); self.addChild(text); self.interactive = true; self.down = function () { tween(button, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); if (!self.isOn) { self.isOn = true; text.setText("OFF"); powerDrain += 1; if (warnings[self.side]) { warnings[self.side].visible = animatronicAtDoor === self.side; if (animatronicAtDoor === self.side) { LK.getSound('warning').play(); } } // Make corridor visible when light is on if (corridorLights[self.side]) { corridorLights[self.side].visible = true; } } }; self.up = function () { tween(button, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (self.isOn) { self.isOn = false; text.setText("LIGHT"); powerDrain -= 1; if (warnings[self.side]) { warnings[self.side].visible = false; } // Hide corridor when light is off if (corridorLights[self.side]) { corridorLights[self.side].visible = false; } } }; return self; }); var Room = Container.expand(function (roomId, hasAnimatronic) { var self = Container.call(this); self.roomId = roomId; self.hasAnimatronic = hasAnimatronic || false; var background = self.attachAsset('cameraBg', { anchorX: 0.5, anchorY: 0.5 }); // Make each camera visually unique if (roomId === 1) { // Camera 1: Entrance/Main Area - brighter, security desk background.tint = 0xd0d0d0; // Brighter area var desk = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: -200, y: 100, width: 300, height: 150, tint: 0x553300 // Brown desk }); } else if (roomId === 2) { // Camera 2: Hallway - darker, narrow space background.tint = 0x707070; // Darker hallway var hallLight = self.attachAsset('warningLight', { anchorX: 0.5, anchorY: 0.5, x: 300, y: -200, width: 50, height: 50, tint: 0xffffaa // Dimmed hallway light }); } else if (roomId === 3) { // Camera 3: Storage Room - messy with boxes background.tint = 0x606060; // Add some storage boxes for (var i = 0; i < 3; i++) { var box = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: -300 + i * 200, y: 200, width: 150, height: 150, tint: 0x855500 // Brown boxes }); } } else if (roomId === 4) { // Camera 4: Kitchen area - with counter background.tint = 0x505050; var counter = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 200, width: 500, height: 100, tint: 0x888888 // Metal counter }); } else if (roomId === 5) { // Camera 5: Back Room - very dark, closest to player background.tint = 0x404040; // Very dark // Add some creepy elements var backLight = self.attachAsset('warningLight', { anchorX: 0.5, anchorY: 0.5, x: -200, y: -250, width: 30, height: 30, tint: 0xff3300 // Red warning light }); // Flicker the light in the back room if (LK.ticks % 120 < 10) { backLight.visible = false; } else { backLight.visible = true; } } // Custom room names instead of generic "Room X" var roomNames = ["Main Entrance", "West Hallway", "Storage Room", "Kitchen Area", "Back Room"]; var roomText = new Text2(roomNames[roomId - 1], { size: 80, fill: 0xFFFFFF }); roomText.anchor.set(0.5, 0); roomText.y = -background.height / 2 + 50; self.addChild(roomText); // Add camera ID indicator in corner var camIdText = new Text2('CAM ' + roomId, { size: 60, fill: 0xFF0000 }); camIdText.anchor.set(0, 0); camIdText.x = -background.width / 2 + 50; camIdText.y = -background.height / 2 + 50; self.addChild(camIdText); // Always create animatronic, but set visibility based on hasAnimatronic var animatronic = self.attachAsset('animatronic', { anchorX: 0.5, anchorY: 1, y: background.height / 2 - 100 }); self.animatronic = animatronic; animatronic.visible = true; // Make animatronic always visible // Position animatronic differently in each room if (roomId === 1) { animatronic.x = -100; // Near the entrance animatronic.scaleX = 1.0; animatronic.scaleY = 1.0; } else if (roomId === 2) { animatronic.x = 200; // Coming down the hallway animatronic.scaleX = 0.9; animatronic.scaleY = 0.9; } else if (roomId === 3) { animatronic.x = -150; // Behind boxes animatronic.scaleX = 0.8; animatronic.scaleY = 0.8; } else if (roomId === 4) { animatronic.x = 50; // By the counter animatronic.scaleX = 1.1; animatronic.scaleY = 1.1; } else if (roomId === 5) { animatronic.x = 0; // In center, closer to camera animatronic.scaleX = 1.3; animatronic.scaleY = 1.3; } // Add method to update animatronic - properly handle visibility self.setAnimatronic = function (visible) { self.hasAnimatronic = visible; if (self.animatronic) { self.animatronic.visible = visible; // Force the update to take effect immediately to prevent glitching self.animatronic.alpha = visible ? 1 : 0; } }; // Add static effect to camera feed self.update = function () { // Increased static effect when animatronic is in the room var staticProbability = self.hasAnimatronic ? 0.08 : 0.01; // Random static effect on the camera if (Math.random() < staticProbability) { // Occasionally add static effect - more severe when animatronic present var staticTint = self.hasAnimatronic ? 0xffdddd : 0xdddddd; // Reddish static when animatronic present background.tint = staticTint; // If animatronic is present, sometimes make them temporarily invisible during static if (self.hasAnimatronic && self.animatronic && Math.random() < 0.3) { var wasVisible = self.animatronic.visible; self.animatronic.visible = false; // Make them reappear in a slightly different position var originalX = self.animatronic.x; var originalY = self.animatronic.y; LK.setTimeout(function () { if (self.animatronic) { self.animatronic.visible = wasVisible; self.animatronic.x = originalX + (Math.random() * 60 - 30); self.animatronic.y = originalY + (Math.random() * 60 - 30); // Reset position after a brief moment LK.setTimeout(function () { if (self.animatronic) { self.animatronic.x = originalX; self.animatronic.y = originalY; } }, 200); } }, 100); } LK.setTimeout(function () { // Reset the tint back to the room's normal tint if (roomId === 1) { background.tint = 0xd0d0d0; } else if (roomId === 2) { background.tint = 0x707070; } else if (roomId === 3) { background.tint = 0x606060; } else if (roomId === 4) { background.tint = 0x505050; } else if (roomId === 5) { background.tint = 0x404040; } }, 100); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game constants var AnimatronicController = function AnimatronicController() { // Make these properties accessible outside the function this.moveTime = 0; this.initialDelay = 20000; // Initial delay before animatronic starts moving (20 seconds) this.gameStartTime = 0; this.hasStartedMoving = false; this.moveDuration = 20000; // Move every 20 seconds this.currentRoomIndex = 0; // Start at room 1 var movementPath = [0, 1, 2, 3, 4]; // Room indices (0-based) var atDoorProbability = 0.3; // Probability to go to door when at rooms 3 or 4 var inCorridor = false; var corridorSide = null; function moveAnimatronic() { // Hide animatronic from ALL rooms first to ensure no duplicates for (var i = 0; i < rooms.length; i++) { if (rooms[i]) { rooms[i].setAnimatronic(i === currentRoomIndex); // Only show in current room } } // Make sure to hide the standalone cat animatronic as well if (catAnimatronic) { catAnimatronic.visible = false; } // Hide animatronic from corridor as well if (corridorAnimatronics["left"]) { corridorAnimatronics["left"].setVisible(corridorSide === "left" && inCorridor); } if (corridorAnimatronics["right"]) { corridorAnimatronics["right"].setVisible(corridorSide === "right" && inCorridor); } // Create a camera disruption effect when animatronic moves if (isCameraActive) { LK.effects.flashScreen(0xffffff, 300); // Add screen shake effect - temporarily move the camera view if (cameraView) { var origX = cameraView.x; var origY = cameraView.y; cameraView.x += Math.random() * 50 - 25; cameraView.y += Math.random() * 50 - 25; LK.setTimeout(function () { cameraView.x = origX; cameraView.y = origY; }, 200); } } // Play footstep sound for every move LK.getSound('footstep').play({ volume: 0.7 }); // If the animatronic was in camera 5 (index 4), it should appear in corridor if (currentRoomIndex === 4) { // Coming from camera 5 - show in corridor before going to door inCorridor = true; corridorSide = Math.random() < 0.5 ? "left" : "right"; // Show the animatronic in corridor if (corridorAnimatronics[corridorSide]) { corridorAnimatronics[corridorSide].setVisible(true); } // Turn on corridor light automatically to show the threat if (corridorLights[corridorSide]) { corridorLights[corridorSide].visible = true; } // Play a warning sound to alert player LK.getSound('warning').play({ volume: 0.7 }); // Start a 5-second door timer var doorTimer = LK.setTimeout(function () { // Check if the door is closed var doorObj = corridorSide === "left" ? doorLeft : doorRight; if (doorObj.isOpen) { // Door still open after 5 seconds - trigger jumpscare game.triggerJumpscare(); } else { // Door was closed in time // Hide from corridor if (corridorAnimatronics[corridorSide]) { corridorAnimatronics[corridorSide].setVisible(false); } // Turn off corridor light if (corridorLights[corridorSide]) { corridorLights[corridorSide].visible = false; } // Reset animatronic back to camera 1 after 3 seconds LK.setTimeout(function () { inCorridor = false; currentRoomIndex = 0; // Camera 1 animatronicRoom = 1; animatronicAtDoor = null; // Show in camera 1 if (rooms[0]) { rooms[0].hasAnimatronic = true; if (rooms[0].animatronic) { rooms[0].animatronic.visible = true; } } // Play movement sound LK.getSound('footstep').play({ volume: 0.7 }); // Reset timer for next move moveTime = 0; }, 3000); // Reset back to camera 1 after 3 seconds } }, 5000); // Player has 5 seconds to close the door return; // Early return to handle special corridor case } // Decide next location based on current room var nextIndex = getNextRoom(); currentRoomIndex = nextIndex; // Check if animatronic should go to a door if (currentRoomIndex === -1) { // Animatronic is at door animatronicRoom = -1; animatronicAtDoor = Math.random() < 0.5 ? "left" : "right"; // Play door approach sound (louder to indicate danger) LK.getSound('footstep').play({ volume: 0.9 }); // Also play warning sound when approaching door LK.getSound('warning').play({ volume: 0.7 }); } else { // Normal room movement animatronicRoom = currentRoomIndex + 1; // Show animatronic in new room with a dramatic effect if (rooms[currentRoomIndex]) { rooms[currentRoomIndex].hasAnimatronic = true; if (rooms[currentRoomIndex].animatronic) { rooms[currentRoomIndex].animatronic.visible = true; // Add a sudden scaling effect to make the cat appear more threatening var originalScaleX = rooms[currentRoomIndex].animatronic.scaleX; var originalScaleY = rooms[currentRoomIndex].animatronic.scaleY; rooms[currentRoomIndex].animatronic.scaleX *= 1.2; rooms[currentRoomIndex].animatronic.scaleY *= 1.2; LK.setTimeout(function () { if (rooms[currentRoomIndex] && rooms[currentRoomIndex].animatronic) { rooms[currentRoomIndex].animatronic.scaleX = originalScaleX; rooms[currentRoomIndex].animatronic.scaleY = originalScaleY; } }, 500); } } // Play movement sound LK.getSound('footstep').play(); } // Reset timer moveTime = 0; } function getNextRoom() { // Special logic when at door if (currentRoomIndex === -1) { // If at door, check if door is closed var doorObj = animatronicAtDoor === "left" ? doorLeft : doorRight; if (!doorObj.isOpen) { // Door closed, retreat to room 3 or 4 return Math.random() < 0.5 ? 2 : 3; // Room 3 or 4 (0-based) } else { // Door open, stay at door (will trigger jumpscare in main game code) return -1; } } // As time progresses, make cat more aggressive by increasing probability of going to door var baseAggressiveness = 0.2; // Base aggressiveness var timeAggressiveness = Math.min(0.3, gameTime / GAME_DURATION * 0.5); // Increases with time var totalAggressiveness = baseAggressiveness + timeAggressiveness; // Special case for rooms 3 and 4 - might go to door if (currentRoomIndex === 2 || currentRoomIndex === 3) { if (Math.random() < atDoorProbability + totalAggressiveness) { return -1; // Go to door with increasing probability } } // Sometimes allow cat to skip rooms (becoming more unpredictable) if (Math.random() < totalAggressiveness) { // Skip to a further room or back to beginning for surprise factor var possibleRooms = [0, 1, 2, 3, 4]; // Filter out current room possibleRooms = possibleRooms.filter(function (idx) { return idx !== currentRoomIndex; }); return possibleRooms[Math.floor(Math.random() * possibleRooms.length)]; } // Normal sequential movement return (currentRoomIndex + 1) % ROOM_COUNT; } this.update = function (dt) { if (!gameStarted || gameOver) { return; } // Set game start time when not initialized if (this.gameStartTime === 0) { this.gameStartTime = LK.ticks; } // Check if we should start animatronic movement if (!this.hasStartedMoving) { // Only start moving after the initial delay has passed if (LK.ticks - this.gameStartTime >= this.initialDelay) { this.hasStartedMoving = true; // Play a warning sound to signal the animatronic is starting to move LK.getSound('warning').play({ volume: 0.7 }); // Play footstep sound when animatronic starts moving LK.getSound('footstep').play({ volume: 0.7 }); console.log("Animatronic has started moving!"); // Visual cue for camera disruption during movement if (isCameraActive) { // Create screen distortion effect LK.effects.flashScreen(0xFFFFFF, 300); } // First move is specifically from camera 1 to camera 2 this.currentRoomIndex = 0; // Ensure we're at camera 1 rooms[0].hasAnimatronic = false; if (rooms[0].animatronic) { rooms[0].animatronic.visible = false; } // Set to camera 2 this.currentRoomIndex = 1; animatronicRoom = 2; if (rooms[1]) { rooms[1].hasAnimatronic = true; if (rooms[1].animatronic) { rooms[1].animatronic.visible = true; } } // Reset timer for next move after this this.moveTime = 0; } else { return; // Don't update movement time until initial delay has passed } } this.moveTime += dt; // Create a more dynamic movement pattern with increasing speed based on time var movementInterval = this.moveDuration - gameTime / GAME_DURATION * 5000; // Gets slightly faster as time progresses // Move to next camera periodically if (this.moveTime >= movementInterval) { moveAnimatronic(); } }; return this; }; var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var MAX_POWER = 100; var POWER_DRAIN_RATE = 0.003; // Reduced base drain rate var GAME_DURATION = 360000; // 6 minutes (6 game hours) var ROOM_COUNT = 5; // Game state variables var currentNight = storage.currentNight || 1; var power = MAX_POWER; var powerDrain = 1; // Base power drain var gameTime = 0; var currentCamera = 1; var isCameraActive = false; var gameStarted = false; var gameOver = false; var animatronicRoom = 1; var animatronicMoveProbability = 0.05 * currentNight; var animatronicAtDoor = null; // "left", "right", or null var lastAnimatronicMove = 0; var doorLeftOpen = true; var doorRightOpen = true; var animatronicController = new AnimatronicController(); var rooms = []; var cameraButtons = []; var doors = { left: null, right: null }; var warnings = { left: null, right: null }; var corridorLights = { left: null, right: null }; var corridorAnimatronics = { left: null, right: null }; // Initialize the office view var office = game.addChild(LK.getAsset('office', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2, scaleX: 10, scaleY: 10 })); // We don't need a standalone cat animatronic since we already have animatronics in rooms and corridors // Creating a completely hidden reference for animatronic that will never be shown var catAnimatronic = new Container(); catAnimatronic.x = -9999; catAnimatronic.y = -9999; catAnimatronic.visible = false; catAnimatronic.alpha = 0; catAnimatronic.scaleX = 0; catAnimatronic.scaleY = 0; // Setup camera view var cameraView = new Container(); cameraView.x = GAME_WIDTH / 2; cameraView.y = GAME_HEIGHT / 2; cameraView.visible = false; game.addChild(cameraView); var cameraScreen = cameraView.addChild(LK.getAsset('cameraScreen', { anchorX: 0.5, anchorY: 0.5 })); // Create rooms for the camera system for (var i = 1; i <= ROOM_COUNT; i++) { var room = new Room(i, i === animatronicRoom); room.x = 0; room.y = 0; room.visible = false; cameraView.addChild(room); rooms.push(room); } // Make the first room visible initially and ensure animatronic is visible rooms[0].visible = true; rooms[0].hasAnimatronic = true; if (rooms[0].animatronic) { rooms[0].animatronic.visible = true; } // Create camera buttons panel var cameraPanel = new Container(); cameraPanel.x = GAME_WIDTH / 2; cameraPanel.y = GAME_HEIGHT - 300; cameraPanel.visible = false; game.addChild(cameraPanel); for (var i = 1; i <= ROOM_COUNT; i++) { var col = (i - 1) % 3; var row = Math.floor((i - 1) / 3); var button = new CameraButton(i, (col - 1) * 350, row * 220); cameraPanel.addChild(button); cameraButtons.push(button); } // Create camera toggle button var toggleCameraBtn = game.addChild(LK.getAsset('button', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT - 150 })); var cameraText = new Text2('CAMERAS', { size: 60, fill: 0xFFFFFF }); cameraText.anchor.set(0.5, 0.5); cameraText.x = toggleCameraBtn.x; cameraText.y = toggleCameraBtn.y; game.addChild(cameraText); // Create power indicator var powerBarBg = game.addChild(LK.getAsset('powerBar', { anchorX: 0, anchorY: 0.5, x: 150, y: 150, tint: 0x555555 })); var powerBarFg = game.addChild(LK.getAsset('powerBar', { anchorX: 0, anchorY: 0.5, x: 150, y: 150 })); var powerText = new Text2('Power: 100%', { size: 40, fill: 0xFFFFFF }); powerText.anchor.set(0, 0.5); powerText.x = 150; powerText.y = 200; game.addChild(powerText); // Create clock var clockBg = game.addChild(LK.getAsset('clockBg', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH - 200, y: 100 })); var clockText = new Text2('12:00 AM', { size: 50, fill: 0xFFFFFF }); clockText.anchor.set(0.5, 0.5); clockText.x = clockBg.x; clockText.y = clockBg.y; game.addChild(clockText); // Create night indicator var nightText = new Text2('Night ' + currentNight, { size: 70, fill: 0xFFFFFF }); nightText.anchor.set(0.5, 0.5); nightText.x = GAME_WIDTH / 2; nightText.y = 100; game.addChild(nightText); // Create door controls var doorLeft = new DoorButton("left"); doorLeft.x = 150; doorLeft.y = GAME_HEIGHT / 2; game.addChild(doorLeft); var doorRight = new DoorButton("right"); doorRight.x = GAME_WIDTH - 150; doorRight.y = GAME_HEIGHT / 2; game.addChild(doorRight); // Create light controls var lightLeft = new LightButton("left"); lightLeft.x = 150; lightLeft.y = GAME_HEIGHT / 2 + 200; game.addChild(lightLeft); var lightRight = new LightButton("right"); lightRight.x = GAME_WIDTH - 150; lightRight.y = GAME_HEIGHT / 2 + 200; game.addChild(lightRight); // Create door visuals var leftDoor = game.addChild(LK.getAsset('door', { anchorX: 0.5, anchorY: 0, x: 550, y: GAME_HEIGHT - 800 / 2 })); doors.left = leftDoor; var rightDoor = game.addChild(LK.getAsset('door', { anchorX: 0.5, anchorY: 0, x: GAME_WIDTH - 550, y: GAME_HEIGHT - 800 / 2 })); doors.right = rightDoor; // Create warning lights var warningLeft = game.addChild(LK.getAsset('warningLight', { anchorX: 0.5, anchorY: 0.5, x: 550, y: GAME_HEIGHT / 2 })); warningLeft.visible = false; warnings.left = warningLeft; var warningRight = game.addChild(LK.getAsset('warningLight', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH - 550, y: GAME_HEIGHT / 2 })); warningRight.visible = false; warnings.right = warningRight; // Create corridor light visuals as simple yellow rectangles var corridorLightLeft = game.addChild(LK.getAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 550, y: GAME_HEIGHT / 2, width: 400, height: 800, tint: 0xffff00 })); corridorLightLeft.visible = false; corridorLights.left = corridorLightLeft; var corridorLightRight = game.addChild(LK.getAsset('button', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH - 550, y: GAME_HEIGHT / 2, width: 400, height: 800, tint: 0xffff00 })); corridorLightRight.visible = false; corridorLights.right = corridorLightRight; // Create corridor animatronics - remove both left and right corridor animatronics corridorAnimatronics.left = null; // No animatronic in left corridor corridorAnimatronics.right = null; // No animatronic in right corridor // Create start game instructions var instructionText = new Text2("Click to start Night " + currentNight, { size: 80, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0.5); instructionText.x = GAME_WIDTH / 2; instructionText.y = GAME_HEIGHT / 2; game.addChild(instructionText); // Helper function to show camera function showCamera(roomId) { // Hide all rooms first for (var i = 0; i < rooms.length; i++) { rooms[i].visible = false; } // Hide corridor animatronics when switching cameras if (corridorAnimatronics["left"]) { corridorAnimatronics["left"].setVisible(false); } if (corridorAnimatronics["right"]) { corridorAnimatronics["right"].setVisible(false); } // Show the selected room if (roomId >= 1 && roomId <= rooms.length) { rooms[roomId - 1].visible = true; // Show the animatronic only if it's in this room for (var i = 0; i < rooms.length; i++) { if (rooms[i].animatronic) { // Only update visibility for the current viewed room if (i === roomId - 1) { rooms[i].setAnimatronic(i === animatronicRoom - 1); } } } } } // Helper function to toggle camera view function toggleCamera() { isCameraActive = !isCameraActive; cameraView.visible = isCameraActive; cameraPanel.visible = isCameraActive; if (isCameraActive) { LK.getSound('camera').play(); cameraText.setText("CLOSE"); // Manage corridor animatronics when switching to camera if (corridorAnimatronics["left"]) { corridorAnimatronics["left"].setVisible(corridorSide === "left" && inCorridor && !isCameraActive); } if (corridorAnimatronics["right"]) { corridorAnimatronics["right"].setVisible(corridorSide === "right" && inCorridor && !isCameraActive); } // Make sure to call showCamera after handling the corridor animatronics LK.setTimeout(function () { showCamera(currentCamera); }, 10); powerDrain += 2; // Increased power drain for cameras // Hide doors when camera view is active if (doors.left) { doors.left.visible = false; } if (doors.right) { doors.right.visible = false; } } else { cameraText.setText("CAMERAS"); powerDrain -= 2; // Decreased by same amount when turning off // Show doors when returning to office view if (doors.left) { doors.left.visible = true; } if (doors.right) { doors.right.visible = true; } } } // Update animatronic location function has been replaced by the AnimatronicController // Trigger jumpscare - defined as a game method to be accessible from AnimatronicController game.triggerJumpscare = function triggerJumpscare() { if (gameOver) { return; } gameOver = true; LK.getSound('jumpscare').play(); // Deactivate cameras if they're active if (isCameraActive) { isCameraActive = false; cameraView.visible = false; cameraPanel.visible = false; cameraText.setText("CAMERAS"); // Show doors when returning to office view if (doors.left) { doors.left.visible = true; } if (doors.right) { doors.right.visible = true; } } // Open both doors when jumpscared if (doors.left && !doorLeft.isOpen) { doorLeft.isOpen = true; tween(doors.left, { y: 2732 - doors.left.height / 2, tint: 0x000000 }, { duration: 300 }); } if (doors.right && !doorRight.isOpen) { doorRight.isOpen = true; tween(doors.right, { y: 2732 - doors.right.height / 2, tint: 0x000000 }, { duration: 300 }); } // Create invisible jumpscare animation (no animatronic visible) var jumpscare = game.addChild(new Container()); jumpscare.x = GAME_WIDTH / 2; jumpscare.y = GAME_HEIGHT / 2; jumpscare.visible = false; // Add jumpscare animation tween(jumpscare, { scaleX: 4.5, scaleY: 4.5, x: GAME_WIDTH / 2 + Math.random() * 100 - 50, // Random movement y: GAME_HEIGHT / 2 + Math.random() * 100 - 50 // Random movement }, { duration: 300, easing: tween.outQuad }); LK.effects.flashScreen(0xff0000, 500); LK.setTimeout(function () { // Reset night to 1 when player dies storage.currentNight = 1; LK.showGameOver(); }, 1500); }; // Handle winning the night function winNight() { if (gameOver) { return; } gameOver = true; // Save progress if (currentNight >= storage.highestNight) { storage.highestNight = currentNight + 1; } storage.currentNight = currentNight + 1; // Display winning message var winText = new Text2("You survived until 6:00 AM! Night " + currentNight + " complete!", { size: 80, fill: 0xFFFFFF }); winText.anchor.set(0.5, 0.5); winText.x = GAME_WIDTH / 2; winText.y = GAME_HEIGHT / 2; game.addChild(winText); LK.setTimeout(function () { LK.showYouWin(); }, 3000); } // Event handlers game.down = function (x, y, obj) { if (!gameStarted) { // Start game when clicked gameStarted = true; instructionText.visible = false; LK.getSound('ambience').play(); LK.playMusic('backgroundMusic'); // Open doors when first night starts if (doors.left) { tween(doors.left, { y: 2732 - doors.left.height / 2, tint: 0x000000 }, { duration: 300 }); doorLeft.isOpen = true; } if (doors.right) { tween(doors.right, { y: 2732 - doors.right.height / 2, tint: 0x000000 }, { duration: 300 }); doorRight.isOpen = true; } return; } // Handle camera toggle button if (x >= toggleCameraBtn.x - toggleCameraBtn.width / 2 && x <= toggleCameraBtn.x + toggleCameraBtn.width / 2 && y >= toggleCameraBtn.y - toggleCameraBtn.height / 2 && y <= toggleCameraBtn.y + toggleCameraBtn.height / 2) { toggleCamera(); } }; // Game update loop game.update = function () { if (!gameStarted || gameOver) { return; } // Update game time gameTime += 16.67; // Approximate milliseconds per frame at 60fps // Update clock (6 hours from 12AM to 6AM in game duration) var gameProgress = Math.min(gameTime / GAME_DURATION, 1); // Check if animatronic is about to start moving based on the controller's timing var nearInitialMove = animatronicController && !animatronicController.hasStartedMoving && LK.ticks - animatronicController.gameStartTime >= animatronicController.initialDelay - 300 && LK.ticks - animatronicController.gameStartTime < animatronicController.initialDelay; if (nearInitialMove) { // Force the clock to show 12:50 AM right before the first movement hour = 12; minute = 50; } else { var hour = Math.floor(gameProgress * 6); if (hour === 0) { hour = 12; // 12 AM } else { hour = hour % 12; if (hour === 0) { hour = 6; } // Cap at 6 AM } var minute = Math.floor(gameProgress * 6 % 1 * 60); } var ampm = "AM"; // Always AM between 12 AM and 6 AM clockText.setText(hour + ":" + (minute < 10 ? "0" + minute : minute) + " " + ampm); // Win condition - survive until 6AM if (hour === 6 && minute === 0) { winNight(); return; } // Update power var closedDoorMultiplier = 1; // Check if doors are closed and increase power drain if (!doorLeft.isOpen && !doorRight.isOpen) { closedDoorMultiplier = 2; // Both doors closed - double drain } else if (!doorLeft.isOpen || !doorRight.isOpen) { closedDoorMultiplier = 1.5; // One door closed - 50% more drain } // Check if lights are on and adjust power drain accordingly var lightMultiplier = 1; if (lightLeft.isOn && lightRight.isOn) { lightMultiplier = 1.5; // Both lights on - 50% more drain } else if (lightLeft.isOn || lightRight.isOn) { lightMultiplier = 1.2; // One light on - 20% more drain } // Add camera multiplier var cameraMultiplier = isCameraActive ? 1.3 : 1; // Camera uses 30% more power when active power -= POWER_DRAIN_RATE * powerDrain * closedDoorMultiplier * lightMultiplier * cameraMultiplier; power = Math.max(0, power); var powerPercent = Math.floor(power); powerText.setText("Power: " + powerPercent + "%"); powerBarFg.width = power / MAX_POWER * powerBarBg.width; // Game over if power runs out if (power <= 0) { game.triggerJumpscare(); return; } // Update animatronic controller animatronicController.update(16.67); // Update warning lights visibility based on light button state if (animatronicAtDoor === "left" && lightLeft.isOn) { warningLeft.visible = true; // Play warning sound occasionally when animatronic is spotted if (LK.ticks % 120 === 0) { // Approximately every 2 seconds LK.getSound('warning').play({ volume: 0.5 }); } } else { warningLeft.visible = false; } if (animatronicAtDoor === "right" && lightRight.isOn) { warningRight.visible = true; // Play warning sound occasionally when animatronic is spotted if (LK.ticks % 120 === 0) { // Approximately every 2 seconds LK.getSound('warning').play({ volume: 0.5 }); } } else { warningRight.visible = false; } // Visual cue when animatronic is moving between cameras if (LK.ticks % 900 === 0 && isCameraActive) { // Every 15 seconds during camera view // Brief static effect LK.effects.flashScreen(0xFFFFFF, 100); } // Add special visual effects when player is viewing the camera that contains the animatronic if (isCameraActive && currentCamera === animatronicRoom && rooms[animatronicRoom - 1] && rooms[animatronicRoom - 1].hasAnimatronic) { // Create occasional glitching/interference effect when looking directly at the animatronic if (LK.ticks % 120 === 0 && currentCamera !== 1) { // Every 2 seconds (but not for Camera 1) // Make screen briefly flash red to indicate danger LK.effects.flashScreen(0xff0000, 100); // Sometimes play a warning sound when looking at the animatronic if (Math.random() < 0.3 && currentCamera !== 1) { LK.getSound('warning').play({ volume: 0.4 }); } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
currentNight: 1,
highestNight: 1
});
/****
* Classes
****/
var AnimatronicCorridor = Container.expand(function (side) {
var self = Container.call(this);
self.side = side; // "left" or "right"
// Create the animatronic for the corridor
var animatronic = self.attachAsset('animatronic', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.setVisible = function (visible) {
self.visible = visible;
if (visible) {
// Animation for appearing in corridor
animatronic.alpha = 0;
tween(animatronic, {
alpha: 1
}, {
duration: 500
});
// Add a creepy movement animation
tween(animatronic, {
y: animatronic.y + 30
}, {
duration: 2000,
yoyo: true,
repeat: -1
});
}
};
// Make initially visible
self.visible = true;
return self;
});
var CameraButton = Container.expand(function (id, x, y) {
var self = Container.call(this);
self.roomId = id;
var button = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
var text = new Text2('CAM ' + id, {
size: 60,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
self.addChild(text);
self.x = x;
self.y = y;
self.interactive = true;
self.down = function () {
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
LK.getSound('camera').play();
};
self.up = function () {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (currentCamera !== self.roomId) {
currentCamera = self.roomId;
showCamera(self.roomId);
}
};
return self;
});
var DoorButton = Container.expand(function (side) {
var self = Container.call(this);
self.side = side; // "left" or "right"
self.isOpen = true;
var button = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: 150,
height: 150
});
var text = new Text2('DOOR', {
size: 40,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
self.addChild(text);
self.interactive = true;
self.down = function () {
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function () {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
self.toggleDoor();
LK.getSound('door').play();
};
self.toggleDoor = function () {
self.isOpen = !self.isOpen;
if (self.isOpen) {
text.setText("DOOR");
button.tint = 0x333333;
powerDrain -= 5; // Reduce power drain when door is opened
if (doors[self.side]) {
tween(doors[self.side], {
y: 2732 - doors[self.side].height / 2,
tint: 0x000000
}, {
duration: 300
});
}
} else {
text.setText("OPEN");
button.tint = 0x555555;
powerDrain += 5; // Increase power drain when door is closed
if (doors[self.side]) {
tween(doors[self.side], {
y: 2732 - doors[self.side].height,
tint: 0xFFFFFF
}, {
duration: 300
});
}
}
};
return self;
});
var LightButton = Container.expand(function (side) {
var self = Container.call(this);
self.side = side; // "left" or "right"
self.isOn = false;
var button = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: 150,
height: 150
});
var text = new Text2('LIGHT', {
size: 40,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
self.addChild(text);
self.interactive = true;
self.down = function () {
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
if (!self.isOn) {
self.isOn = true;
text.setText("OFF");
powerDrain += 1;
if (warnings[self.side]) {
warnings[self.side].visible = animatronicAtDoor === self.side;
if (animatronicAtDoor === self.side) {
LK.getSound('warning').play();
}
}
// Make corridor visible when light is on
if (corridorLights[self.side]) {
corridorLights[self.side].visible = true;
}
}
};
self.up = function () {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (self.isOn) {
self.isOn = false;
text.setText("LIGHT");
powerDrain -= 1;
if (warnings[self.side]) {
warnings[self.side].visible = false;
}
// Hide corridor when light is off
if (corridorLights[self.side]) {
corridorLights[self.side].visible = false;
}
}
};
return self;
});
var Room = Container.expand(function (roomId, hasAnimatronic) {
var self = Container.call(this);
self.roomId = roomId;
self.hasAnimatronic = hasAnimatronic || false;
var background = self.attachAsset('cameraBg', {
anchorX: 0.5,
anchorY: 0.5
});
// Make each camera visually unique
if (roomId === 1) {
// Camera 1: Entrance/Main Area - brighter, security desk
background.tint = 0xd0d0d0; // Brighter area
var desk = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: 100,
width: 300,
height: 150,
tint: 0x553300 // Brown desk
});
} else if (roomId === 2) {
// Camera 2: Hallway - darker, narrow space
background.tint = 0x707070; // Darker hallway
var hallLight = self.attachAsset('warningLight', {
anchorX: 0.5,
anchorY: 0.5,
x: 300,
y: -200,
width: 50,
height: 50,
tint: 0xffffaa // Dimmed hallway light
});
} else if (roomId === 3) {
// Camera 3: Storage Room - messy with boxes
background.tint = 0x606060;
// Add some storage boxes
for (var i = 0; i < 3; i++) {
var box = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: -300 + i * 200,
y: 200,
width: 150,
height: 150,
tint: 0x855500 // Brown boxes
});
}
} else if (roomId === 4) {
// Camera 4: Kitchen area - with counter
background.tint = 0x505050;
var counter = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 200,
width: 500,
height: 100,
tint: 0x888888 // Metal counter
});
} else if (roomId === 5) {
// Camera 5: Back Room - very dark, closest to player
background.tint = 0x404040; // Very dark
// Add some creepy elements
var backLight = self.attachAsset('warningLight', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: -250,
width: 30,
height: 30,
tint: 0xff3300 // Red warning light
});
// Flicker the light in the back room
if (LK.ticks % 120 < 10) {
backLight.visible = false;
} else {
backLight.visible = true;
}
}
// Custom room names instead of generic "Room X"
var roomNames = ["Main Entrance", "West Hallway", "Storage Room", "Kitchen Area", "Back Room"];
var roomText = new Text2(roomNames[roomId - 1], {
size: 80,
fill: 0xFFFFFF
});
roomText.anchor.set(0.5, 0);
roomText.y = -background.height / 2 + 50;
self.addChild(roomText);
// Add camera ID indicator in corner
var camIdText = new Text2('CAM ' + roomId, {
size: 60,
fill: 0xFF0000
});
camIdText.anchor.set(0, 0);
camIdText.x = -background.width / 2 + 50;
camIdText.y = -background.height / 2 + 50;
self.addChild(camIdText);
// Always create animatronic, but set visibility based on hasAnimatronic
var animatronic = self.attachAsset('animatronic', {
anchorX: 0.5,
anchorY: 1,
y: background.height / 2 - 100
});
self.animatronic = animatronic;
animatronic.visible = true; // Make animatronic always visible
// Position animatronic differently in each room
if (roomId === 1) {
animatronic.x = -100; // Near the entrance
animatronic.scaleX = 1.0;
animatronic.scaleY = 1.0;
} else if (roomId === 2) {
animatronic.x = 200; // Coming down the hallway
animatronic.scaleX = 0.9;
animatronic.scaleY = 0.9;
} else if (roomId === 3) {
animatronic.x = -150; // Behind boxes
animatronic.scaleX = 0.8;
animatronic.scaleY = 0.8;
} else if (roomId === 4) {
animatronic.x = 50; // By the counter
animatronic.scaleX = 1.1;
animatronic.scaleY = 1.1;
} else if (roomId === 5) {
animatronic.x = 0; // In center, closer to camera
animatronic.scaleX = 1.3;
animatronic.scaleY = 1.3;
}
// Add method to update animatronic - properly handle visibility
self.setAnimatronic = function (visible) {
self.hasAnimatronic = visible;
if (self.animatronic) {
self.animatronic.visible = visible;
// Force the update to take effect immediately to prevent glitching
self.animatronic.alpha = visible ? 1 : 0;
}
};
// Add static effect to camera feed
self.update = function () {
// Increased static effect when animatronic is in the room
var staticProbability = self.hasAnimatronic ? 0.08 : 0.01;
// Random static effect on the camera
if (Math.random() < staticProbability) {
// Occasionally add static effect - more severe when animatronic present
var staticTint = self.hasAnimatronic ? 0xffdddd : 0xdddddd; // Reddish static when animatronic present
background.tint = staticTint;
// If animatronic is present, sometimes make them temporarily invisible during static
if (self.hasAnimatronic && self.animatronic && Math.random() < 0.3) {
var wasVisible = self.animatronic.visible;
self.animatronic.visible = false;
// Make them reappear in a slightly different position
var originalX = self.animatronic.x;
var originalY = self.animatronic.y;
LK.setTimeout(function () {
if (self.animatronic) {
self.animatronic.visible = wasVisible;
self.animatronic.x = originalX + (Math.random() * 60 - 30);
self.animatronic.y = originalY + (Math.random() * 60 - 30);
// Reset position after a brief moment
LK.setTimeout(function () {
if (self.animatronic) {
self.animatronic.x = originalX;
self.animatronic.y = originalY;
}
}, 200);
}
}, 100);
}
LK.setTimeout(function () {
// Reset the tint back to the room's normal tint
if (roomId === 1) {
background.tint = 0xd0d0d0;
} else if (roomId === 2) {
background.tint = 0x707070;
} else if (roomId === 3) {
background.tint = 0x606060;
} else if (roomId === 4) {
background.tint = 0x505050;
} else if (roomId === 5) {
background.tint = 0x404040;
}
}, 100);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game constants
var AnimatronicController = function AnimatronicController() {
// Make these properties accessible outside the function
this.moveTime = 0;
this.initialDelay = 20000; // Initial delay before animatronic starts moving (20 seconds)
this.gameStartTime = 0;
this.hasStartedMoving = false;
this.moveDuration = 20000; // Move every 20 seconds
this.currentRoomIndex = 0; // Start at room 1
var movementPath = [0, 1, 2, 3, 4]; // Room indices (0-based)
var atDoorProbability = 0.3; // Probability to go to door when at rooms 3 or 4
var inCorridor = false;
var corridorSide = null;
function moveAnimatronic() {
// Hide animatronic from ALL rooms first to ensure no duplicates
for (var i = 0; i < rooms.length; i++) {
if (rooms[i]) {
rooms[i].setAnimatronic(i === currentRoomIndex); // Only show in current room
}
}
// Make sure to hide the standalone cat animatronic as well
if (catAnimatronic) {
catAnimatronic.visible = false;
}
// Hide animatronic from corridor as well
if (corridorAnimatronics["left"]) {
corridorAnimatronics["left"].setVisible(corridorSide === "left" && inCorridor);
}
if (corridorAnimatronics["right"]) {
corridorAnimatronics["right"].setVisible(corridorSide === "right" && inCorridor);
}
// Create a camera disruption effect when animatronic moves
if (isCameraActive) {
LK.effects.flashScreen(0xffffff, 300);
// Add screen shake effect - temporarily move the camera view
if (cameraView) {
var origX = cameraView.x;
var origY = cameraView.y;
cameraView.x += Math.random() * 50 - 25;
cameraView.y += Math.random() * 50 - 25;
LK.setTimeout(function () {
cameraView.x = origX;
cameraView.y = origY;
}, 200);
}
}
// Play footstep sound for every move
LK.getSound('footstep').play({
volume: 0.7
});
// If the animatronic was in camera 5 (index 4), it should appear in corridor
if (currentRoomIndex === 4) {
// Coming from camera 5 - show in corridor before going to door
inCorridor = true;
corridorSide = Math.random() < 0.5 ? "left" : "right";
// Show the animatronic in corridor
if (corridorAnimatronics[corridorSide]) {
corridorAnimatronics[corridorSide].setVisible(true);
}
// Turn on corridor light automatically to show the threat
if (corridorLights[corridorSide]) {
corridorLights[corridorSide].visible = true;
}
// Play a warning sound to alert player
LK.getSound('warning').play({
volume: 0.7
});
// Start a 5-second door timer
var doorTimer = LK.setTimeout(function () {
// Check if the door is closed
var doorObj = corridorSide === "left" ? doorLeft : doorRight;
if (doorObj.isOpen) {
// Door still open after 5 seconds - trigger jumpscare
game.triggerJumpscare();
} else {
// Door was closed in time
// Hide from corridor
if (corridorAnimatronics[corridorSide]) {
corridorAnimatronics[corridorSide].setVisible(false);
}
// Turn off corridor light
if (corridorLights[corridorSide]) {
corridorLights[corridorSide].visible = false;
}
// Reset animatronic back to camera 1 after 3 seconds
LK.setTimeout(function () {
inCorridor = false;
currentRoomIndex = 0; // Camera 1
animatronicRoom = 1;
animatronicAtDoor = null;
// Show in camera 1
if (rooms[0]) {
rooms[0].hasAnimatronic = true;
if (rooms[0].animatronic) {
rooms[0].animatronic.visible = true;
}
}
// Play movement sound
LK.getSound('footstep').play({
volume: 0.7
});
// Reset timer for next move
moveTime = 0;
}, 3000); // Reset back to camera 1 after 3 seconds
}
}, 5000); // Player has 5 seconds to close the door
return; // Early return to handle special corridor case
}
// Decide next location based on current room
var nextIndex = getNextRoom();
currentRoomIndex = nextIndex;
// Check if animatronic should go to a door
if (currentRoomIndex === -1) {
// Animatronic is at door
animatronicRoom = -1;
animatronicAtDoor = Math.random() < 0.5 ? "left" : "right";
// Play door approach sound (louder to indicate danger)
LK.getSound('footstep').play({
volume: 0.9
});
// Also play warning sound when approaching door
LK.getSound('warning').play({
volume: 0.7
});
} else {
// Normal room movement
animatronicRoom = currentRoomIndex + 1;
// Show animatronic in new room with a dramatic effect
if (rooms[currentRoomIndex]) {
rooms[currentRoomIndex].hasAnimatronic = true;
if (rooms[currentRoomIndex].animatronic) {
rooms[currentRoomIndex].animatronic.visible = true;
// Add a sudden scaling effect to make the cat appear more threatening
var originalScaleX = rooms[currentRoomIndex].animatronic.scaleX;
var originalScaleY = rooms[currentRoomIndex].animatronic.scaleY;
rooms[currentRoomIndex].animatronic.scaleX *= 1.2;
rooms[currentRoomIndex].animatronic.scaleY *= 1.2;
LK.setTimeout(function () {
if (rooms[currentRoomIndex] && rooms[currentRoomIndex].animatronic) {
rooms[currentRoomIndex].animatronic.scaleX = originalScaleX;
rooms[currentRoomIndex].animatronic.scaleY = originalScaleY;
}
}, 500);
}
}
// Play movement sound
LK.getSound('footstep').play();
}
// Reset timer
moveTime = 0;
}
function getNextRoom() {
// Special logic when at door
if (currentRoomIndex === -1) {
// If at door, check if door is closed
var doorObj = animatronicAtDoor === "left" ? doorLeft : doorRight;
if (!doorObj.isOpen) {
// Door closed, retreat to room 3 or 4
return Math.random() < 0.5 ? 2 : 3; // Room 3 or 4 (0-based)
} else {
// Door open, stay at door (will trigger jumpscare in main game code)
return -1;
}
}
// As time progresses, make cat more aggressive by increasing probability of going to door
var baseAggressiveness = 0.2; // Base aggressiveness
var timeAggressiveness = Math.min(0.3, gameTime / GAME_DURATION * 0.5); // Increases with time
var totalAggressiveness = baseAggressiveness + timeAggressiveness;
// Special case for rooms 3 and 4 - might go to door
if (currentRoomIndex === 2 || currentRoomIndex === 3) {
if (Math.random() < atDoorProbability + totalAggressiveness) {
return -1; // Go to door with increasing probability
}
}
// Sometimes allow cat to skip rooms (becoming more unpredictable)
if (Math.random() < totalAggressiveness) {
// Skip to a further room or back to beginning for surprise factor
var possibleRooms = [0, 1, 2, 3, 4];
// Filter out current room
possibleRooms = possibleRooms.filter(function (idx) {
return idx !== currentRoomIndex;
});
return possibleRooms[Math.floor(Math.random() * possibleRooms.length)];
}
// Normal sequential movement
return (currentRoomIndex + 1) % ROOM_COUNT;
}
this.update = function (dt) {
if (!gameStarted || gameOver) {
return;
}
// Set game start time when not initialized
if (this.gameStartTime === 0) {
this.gameStartTime = LK.ticks;
}
// Check if we should start animatronic movement
if (!this.hasStartedMoving) {
// Only start moving after the initial delay has passed
if (LK.ticks - this.gameStartTime >= this.initialDelay) {
this.hasStartedMoving = true;
// Play a warning sound to signal the animatronic is starting to move
LK.getSound('warning').play({
volume: 0.7
});
// Play footstep sound when animatronic starts moving
LK.getSound('footstep').play({
volume: 0.7
});
console.log("Animatronic has started moving!");
// Visual cue for camera disruption during movement
if (isCameraActive) {
// Create screen distortion effect
LK.effects.flashScreen(0xFFFFFF, 300);
}
// First move is specifically from camera 1 to camera 2
this.currentRoomIndex = 0; // Ensure we're at camera 1
rooms[0].hasAnimatronic = false;
if (rooms[0].animatronic) {
rooms[0].animatronic.visible = false;
}
// Set to camera 2
this.currentRoomIndex = 1;
animatronicRoom = 2;
if (rooms[1]) {
rooms[1].hasAnimatronic = true;
if (rooms[1].animatronic) {
rooms[1].animatronic.visible = true;
}
}
// Reset timer for next move after this
this.moveTime = 0;
} else {
return; // Don't update movement time until initial delay has passed
}
}
this.moveTime += dt;
// Create a more dynamic movement pattern with increasing speed based on time
var movementInterval = this.moveDuration - gameTime / GAME_DURATION * 5000; // Gets slightly faster as time progresses
// Move to next camera periodically
if (this.moveTime >= movementInterval) {
moveAnimatronic();
}
};
return this;
};
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var MAX_POWER = 100;
var POWER_DRAIN_RATE = 0.003; // Reduced base drain rate
var GAME_DURATION = 360000; // 6 minutes (6 game hours)
var ROOM_COUNT = 5;
// Game state variables
var currentNight = storage.currentNight || 1;
var power = MAX_POWER;
var powerDrain = 1; // Base power drain
var gameTime = 0;
var currentCamera = 1;
var isCameraActive = false;
var gameStarted = false;
var gameOver = false;
var animatronicRoom = 1;
var animatronicMoveProbability = 0.05 * currentNight;
var animatronicAtDoor = null; // "left", "right", or null
var lastAnimatronicMove = 0;
var doorLeftOpen = true;
var doorRightOpen = true;
var animatronicController = new AnimatronicController();
var rooms = [];
var cameraButtons = [];
var doors = {
left: null,
right: null
};
var warnings = {
left: null,
right: null
};
var corridorLights = {
left: null,
right: null
};
var corridorAnimatronics = {
left: null,
right: null
};
// Initialize the office view
var office = game.addChild(LK.getAsset('office', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2,
y: GAME_HEIGHT / 2,
scaleX: 10,
scaleY: 10
}));
// We don't need a standalone cat animatronic since we already have animatronics in rooms and corridors
// Creating a completely hidden reference for animatronic that will never be shown
var catAnimatronic = new Container();
catAnimatronic.x = -9999;
catAnimatronic.y = -9999;
catAnimatronic.visible = false;
catAnimatronic.alpha = 0;
catAnimatronic.scaleX = 0;
catAnimatronic.scaleY = 0;
// Setup camera view
var cameraView = new Container();
cameraView.x = GAME_WIDTH / 2;
cameraView.y = GAME_HEIGHT / 2;
cameraView.visible = false;
game.addChild(cameraView);
var cameraScreen = cameraView.addChild(LK.getAsset('cameraScreen', {
anchorX: 0.5,
anchorY: 0.5
}));
// Create rooms for the camera system
for (var i = 1; i <= ROOM_COUNT; i++) {
var room = new Room(i, i === animatronicRoom);
room.x = 0;
room.y = 0;
room.visible = false;
cameraView.addChild(room);
rooms.push(room);
}
// Make the first room visible initially and ensure animatronic is visible
rooms[0].visible = true;
rooms[0].hasAnimatronic = true;
if (rooms[0].animatronic) {
rooms[0].animatronic.visible = true;
}
// Create camera buttons panel
var cameraPanel = new Container();
cameraPanel.x = GAME_WIDTH / 2;
cameraPanel.y = GAME_HEIGHT - 300;
cameraPanel.visible = false;
game.addChild(cameraPanel);
for (var i = 1; i <= ROOM_COUNT; i++) {
var col = (i - 1) % 3;
var row = Math.floor((i - 1) / 3);
var button = new CameraButton(i, (col - 1) * 350, row * 220);
cameraPanel.addChild(button);
cameraButtons.push(button);
}
// Create camera toggle button
var toggleCameraBtn = game.addChild(LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2,
y: GAME_HEIGHT - 150
}));
var cameraText = new Text2('CAMERAS', {
size: 60,
fill: 0xFFFFFF
});
cameraText.anchor.set(0.5, 0.5);
cameraText.x = toggleCameraBtn.x;
cameraText.y = toggleCameraBtn.y;
game.addChild(cameraText);
// Create power indicator
var powerBarBg = game.addChild(LK.getAsset('powerBar', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 150,
tint: 0x555555
}));
var powerBarFg = game.addChild(LK.getAsset('powerBar', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 150
}));
var powerText = new Text2('Power: 100%', {
size: 40,
fill: 0xFFFFFF
});
powerText.anchor.set(0, 0.5);
powerText.x = 150;
powerText.y = 200;
game.addChild(powerText);
// Create clock
var clockBg = game.addChild(LK.getAsset('clockBg', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH - 200,
y: 100
}));
var clockText = new Text2('12:00 AM', {
size: 50,
fill: 0xFFFFFF
});
clockText.anchor.set(0.5, 0.5);
clockText.x = clockBg.x;
clockText.y = clockBg.y;
game.addChild(clockText);
// Create night indicator
var nightText = new Text2('Night ' + currentNight, {
size: 70,
fill: 0xFFFFFF
});
nightText.anchor.set(0.5, 0.5);
nightText.x = GAME_WIDTH / 2;
nightText.y = 100;
game.addChild(nightText);
// Create door controls
var doorLeft = new DoorButton("left");
doorLeft.x = 150;
doorLeft.y = GAME_HEIGHT / 2;
game.addChild(doorLeft);
var doorRight = new DoorButton("right");
doorRight.x = GAME_WIDTH - 150;
doorRight.y = GAME_HEIGHT / 2;
game.addChild(doorRight);
// Create light controls
var lightLeft = new LightButton("left");
lightLeft.x = 150;
lightLeft.y = GAME_HEIGHT / 2 + 200;
game.addChild(lightLeft);
var lightRight = new LightButton("right");
lightRight.x = GAME_WIDTH - 150;
lightRight.y = GAME_HEIGHT / 2 + 200;
game.addChild(lightRight);
// Create door visuals
var leftDoor = game.addChild(LK.getAsset('door', {
anchorX: 0.5,
anchorY: 0,
x: 550,
y: GAME_HEIGHT - 800 / 2
}));
doors.left = leftDoor;
var rightDoor = game.addChild(LK.getAsset('door', {
anchorX: 0.5,
anchorY: 0,
x: GAME_WIDTH - 550,
y: GAME_HEIGHT - 800 / 2
}));
doors.right = rightDoor;
// Create warning lights
var warningLeft = game.addChild(LK.getAsset('warningLight', {
anchorX: 0.5,
anchorY: 0.5,
x: 550,
y: GAME_HEIGHT / 2
}));
warningLeft.visible = false;
warnings.left = warningLeft;
var warningRight = game.addChild(LK.getAsset('warningLight', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH - 550,
y: GAME_HEIGHT / 2
}));
warningRight.visible = false;
warnings.right = warningRight;
// Create corridor light visuals as simple yellow rectangles
var corridorLightLeft = game.addChild(LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 550,
y: GAME_HEIGHT / 2,
width: 400,
height: 800,
tint: 0xffff00
}));
corridorLightLeft.visible = false;
corridorLights.left = corridorLightLeft;
var corridorLightRight = game.addChild(LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH - 550,
y: GAME_HEIGHT / 2,
width: 400,
height: 800,
tint: 0xffff00
}));
corridorLightRight.visible = false;
corridorLights.right = corridorLightRight;
// Create corridor animatronics - remove both left and right corridor animatronics
corridorAnimatronics.left = null; // No animatronic in left corridor
corridorAnimatronics.right = null; // No animatronic in right corridor
// Create start game instructions
var instructionText = new Text2("Click to start Night " + currentNight, {
size: 80,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = GAME_WIDTH / 2;
instructionText.y = GAME_HEIGHT / 2;
game.addChild(instructionText);
// Helper function to show camera
function showCamera(roomId) {
// Hide all rooms first
for (var i = 0; i < rooms.length; i++) {
rooms[i].visible = false;
}
// Hide corridor animatronics when switching cameras
if (corridorAnimatronics["left"]) {
corridorAnimatronics["left"].setVisible(false);
}
if (corridorAnimatronics["right"]) {
corridorAnimatronics["right"].setVisible(false);
}
// Show the selected room
if (roomId >= 1 && roomId <= rooms.length) {
rooms[roomId - 1].visible = true;
// Show the animatronic only if it's in this room
for (var i = 0; i < rooms.length; i++) {
if (rooms[i].animatronic) {
// Only update visibility for the current viewed room
if (i === roomId - 1) {
rooms[i].setAnimatronic(i === animatronicRoom - 1);
}
}
}
}
}
// Helper function to toggle camera view
function toggleCamera() {
isCameraActive = !isCameraActive;
cameraView.visible = isCameraActive;
cameraPanel.visible = isCameraActive;
if (isCameraActive) {
LK.getSound('camera').play();
cameraText.setText("CLOSE");
// Manage corridor animatronics when switching to camera
if (corridorAnimatronics["left"]) {
corridorAnimatronics["left"].setVisible(corridorSide === "left" && inCorridor && !isCameraActive);
}
if (corridorAnimatronics["right"]) {
corridorAnimatronics["right"].setVisible(corridorSide === "right" && inCorridor && !isCameraActive);
}
// Make sure to call showCamera after handling the corridor animatronics
LK.setTimeout(function () {
showCamera(currentCamera);
}, 10);
powerDrain += 2; // Increased power drain for cameras
// Hide doors when camera view is active
if (doors.left) {
doors.left.visible = false;
}
if (doors.right) {
doors.right.visible = false;
}
} else {
cameraText.setText("CAMERAS");
powerDrain -= 2; // Decreased by same amount when turning off
// Show doors when returning to office view
if (doors.left) {
doors.left.visible = true;
}
if (doors.right) {
doors.right.visible = true;
}
}
}
// Update animatronic location function has been replaced by the AnimatronicController
// Trigger jumpscare - defined as a game method to be accessible from AnimatronicController
game.triggerJumpscare = function triggerJumpscare() {
if (gameOver) {
return;
}
gameOver = true;
LK.getSound('jumpscare').play();
// Deactivate cameras if they're active
if (isCameraActive) {
isCameraActive = false;
cameraView.visible = false;
cameraPanel.visible = false;
cameraText.setText("CAMERAS");
// Show doors when returning to office view
if (doors.left) {
doors.left.visible = true;
}
if (doors.right) {
doors.right.visible = true;
}
}
// Open both doors when jumpscared
if (doors.left && !doorLeft.isOpen) {
doorLeft.isOpen = true;
tween(doors.left, {
y: 2732 - doors.left.height / 2,
tint: 0x000000
}, {
duration: 300
});
}
if (doors.right && !doorRight.isOpen) {
doorRight.isOpen = true;
tween(doors.right, {
y: 2732 - doors.right.height / 2,
tint: 0x000000
}, {
duration: 300
});
}
// Create invisible jumpscare animation (no animatronic visible)
var jumpscare = game.addChild(new Container());
jumpscare.x = GAME_WIDTH / 2;
jumpscare.y = GAME_HEIGHT / 2;
jumpscare.visible = false;
// Add jumpscare animation
tween(jumpscare, {
scaleX: 4.5,
scaleY: 4.5,
x: GAME_WIDTH / 2 + Math.random() * 100 - 50,
// Random movement
y: GAME_HEIGHT / 2 + Math.random() * 100 - 50 // Random movement
}, {
duration: 300,
easing: tween.outQuad
});
LK.effects.flashScreen(0xff0000, 500);
LK.setTimeout(function () {
// Reset night to 1 when player dies
storage.currentNight = 1;
LK.showGameOver();
}, 1500);
};
// Handle winning the night
function winNight() {
if (gameOver) {
return;
}
gameOver = true;
// Save progress
if (currentNight >= storage.highestNight) {
storage.highestNight = currentNight + 1;
}
storage.currentNight = currentNight + 1;
// Display winning message
var winText = new Text2("You survived until 6:00 AM! Night " + currentNight + " complete!", {
size: 80,
fill: 0xFFFFFF
});
winText.anchor.set(0.5, 0.5);
winText.x = GAME_WIDTH / 2;
winText.y = GAME_HEIGHT / 2;
game.addChild(winText);
LK.setTimeout(function () {
LK.showYouWin();
}, 3000);
}
// Event handlers
game.down = function (x, y, obj) {
if (!gameStarted) {
// Start game when clicked
gameStarted = true;
instructionText.visible = false;
LK.getSound('ambience').play();
LK.playMusic('backgroundMusic');
// Open doors when first night starts
if (doors.left) {
tween(doors.left, {
y: 2732 - doors.left.height / 2,
tint: 0x000000
}, {
duration: 300
});
doorLeft.isOpen = true;
}
if (doors.right) {
tween(doors.right, {
y: 2732 - doors.right.height / 2,
tint: 0x000000
}, {
duration: 300
});
doorRight.isOpen = true;
}
return;
}
// Handle camera toggle button
if (x >= toggleCameraBtn.x - toggleCameraBtn.width / 2 && x <= toggleCameraBtn.x + toggleCameraBtn.width / 2 && y >= toggleCameraBtn.y - toggleCameraBtn.height / 2 && y <= toggleCameraBtn.y + toggleCameraBtn.height / 2) {
toggleCamera();
}
};
// Game update loop
game.update = function () {
if (!gameStarted || gameOver) {
return;
}
// Update game time
gameTime += 16.67; // Approximate milliseconds per frame at 60fps
// Update clock (6 hours from 12AM to 6AM in game duration)
var gameProgress = Math.min(gameTime / GAME_DURATION, 1);
// Check if animatronic is about to start moving based on the controller's timing
var nearInitialMove = animatronicController && !animatronicController.hasStartedMoving && LK.ticks - animatronicController.gameStartTime >= animatronicController.initialDelay - 300 && LK.ticks - animatronicController.gameStartTime < animatronicController.initialDelay;
if (nearInitialMove) {
// Force the clock to show 12:50 AM right before the first movement
hour = 12;
minute = 50;
} else {
var hour = Math.floor(gameProgress * 6);
if (hour === 0) {
hour = 12; // 12 AM
} else {
hour = hour % 12;
if (hour === 0) {
hour = 6;
} // Cap at 6 AM
}
var minute = Math.floor(gameProgress * 6 % 1 * 60);
}
var ampm = "AM"; // Always AM between 12 AM and 6 AM
clockText.setText(hour + ":" + (minute < 10 ? "0" + minute : minute) + " " + ampm);
// Win condition - survive until 6AM
if (hour === 6 && minute === 0) {
winNight();
return;
}
// Update power
var closedDoorMultiplier = 1;
// Check if doors are closed and increase power drain
if (!doorLeft.isOpen && !doorRight.isOpen) {
closedDoorMultiplier = 2; // Both doors closed - double drain
} else if (!doorLeft.isOpen || !doorRight.isOpen) {
closedDoorMultiplier = 1.5; // One door closed - 50% more drain
}
// Check if lights are on and adjust power drain accordingly
var lightMultiplier = 1;
if (lightLeft.isOn && lightRight.isOn) {
lightMultiplier = 1.5; // Both lights on - 50% more drain
} else if (lightLeft.isOn || lightRight.isOn) {
lightMultiplier = 1.2; // One light on - 20% more drain
}
// Add camera multiplier
var cameraMultiplier = isCameraActive ? 1.3 : 1; // Camera uses 30% more power when active
power -= POWER_DRAIN_RATE * powerDrain * closedDoorMultiplier * lightMultiplier * cameraMultiplier;
power = Math.max(0, power);
var powerPercent = Math.floor(power);
powerText.setText("Power: " + powerPercent + "%");
powerBarFg.width = power / MAX_POWER * powerBarBg.width;
// Game over if power runs out
if (power <= 0) {
game.triggerJumpscare();
return;
}
// Update animatronic controller
animatronicController.update(16.67);
// Update warning lights visibility based on light button state
if (animatronicAtDoor === "left" && lightLeft.isOn) {
warningLeft.visible = true;
// Play warning sound occasionally when animatronic is spotted
if (LK.ticks % 120 === 0) {
// Approximately every 2 seconds
LK.getSound('warning').play({
volume: 0.5
});
}
} else {
warningLeft.visible = false;
}
if (animatronicAtDoor === "right" && lightRight.isOn) {
warningRight.visible = true;
// Play warning sound occasionally when animatronic is spotted
if (LK.ticks % 120 === 0) {
// Approximately every 2 seconds
LK.getSound('warning').play({
volume: 0.5
});
}
} else {
warningRight.visible = false;
}
// Visual cue when animatronic is moving between cameras
if (LK.ticks % 900 === 0 && isCameraActive) {
// Every 15 seconds during camera view
// Brief static effect
LK.effects.flashScreen(0xFFFFFF, 100);
}
// Add special visual effects when player is viewing the camera that contains the animatronic
if (isCameraActive && currentCamera === animatronicRoom && rooms[animatronicRoom - 1] && rooms[animatronicRoom - 1].hasAnimatronic) {
// Create occasional glitching/interference effect when looking directly at the animatronic
if (LK.ticks % 120 === 0 && currentCamera !== 1) {
// Every 2 seconds (but not for Camera 1)
// Make screen briefly flash red to indicate danger
LK.effects.flashScreen(0xff0000, 100);
// Sometimes play a warning sound when looking at the animatronic
if (Math.random() < 0.3 && currentCamera !== 1) {
LK.getSound('warning').play({
volume: 0.4
});
}
}
}
};
An anthropomorphic blue and green cat animatronic wearing rockstar attire. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Metal door. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Two doorways. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Pet store. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows