User prompt
bon appears in your office instead of the usual route and if you're on the camera system you cant see him in your office! If he's in your office click on him to send him away, if you dont click him in time he jumpscares you but doesn't kill you. Instead he steals 10 power and leaves.
User prompt
Generate the first version of the source code of my game: Five Scary Nights with Dobby. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Five Scary Nights with Dobby
Initial prompt
Make a game similar to fnaf 1 with doors and 4 unique characters that can be seen at the doors when the light is on. There is only 3 animatronics, the three have their own picture and are called: Dobby, Bon, and Spinny. They also all have jumpscares when they catch you. Add a title screen and the main animatronic is Dobby. There is only 5 cameras that these animatronics traverse through. And dont forget about the power meter! Dobby is an animatronic lollypop, Bon is just a red balloon with a drawn smile and eyes, and lastly Spinny is an radar spider animatronic. DOBBY IS THE MAIN CHARACTER!
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { currentNight: 1, highestNight: 1 }); /**** * Classes ****/ var Animatronic = Container.expand(function (id, name, difficulty, startLocation) { var self = Container.call(this); self.id = id; self.name = name; self.difficulty = difficulty; self.currentLocation = startLocation; self.lastLocation = startLocation; self.atDoor = false; self.doorSide = null; self.moveTimer = null; self.viewX = Math.random() * 400 - 200; // Random position in camera view self.viewY = Math.random() * 300 - 150; // Set movement pattern (different for each animatronic) self.setMovementPattern = function () { // Movement paths from cameras to door if (self.id === 'dobby') { self.movementPath = { 1: [2, 3], 2: [1, 3], 3: [2, 4, 'leftDoor'], 4: [3, 'rightDoor'], 'leftDoor': ['jumpscare', 3], 'rightDoor': ['jumpscare', 4] }; } else if (self.id === 'bon') { self.movementPath = { 1: [3, 'leftDoor', 'rightDoor'], 3: [1, 'rightDoor', 'leftDoor'], 5: [1, 'leftDoor', 'rightDoor'], 'leftDoor': ['jumpscare', 5], 'rightDoor': ['jumpscare', 3] }; } else if (self.id === 'spinny') { // Make Spinny's movement pattern identical to Dobby self.movementPath = { 1: [2, 3], 2: [1, 3], 3: [2, 4, 'leftDoor'], 4: [3, 'rightDoor'], 'leftDoor': ['jumpscare', 3], 'rightDoor': ['jumpscare', 4] }; } }; // Make movement decisions self.move = function () { self.lastLocation = self.currentLocation; // Check activity level (based on difficulty and night) var activityLevel = self.difficulty + (game.currentNight - 1) * 2; // Make Bon move much faster if (self.id === 'bon') { activityLevel = activityLevel * 2.5; // Significantly increase Bon's activity } var willMove = Math.random() * 20 < activityLevel; if (!willMove) return; // If at a door and door is open, enter and trigger jumpscare if (self.currentLocation === 'leftDoor' || self.currentLocation === 'rightDoor') { // Check if door is open (accessible from animatronic's door side) var door = self.currentLocation === 'leftDoor' ? game.office.leftDoor : game.office.rightDoor; if (door.isOpen) { self.triggerJumpscare(); return; } else { // Door is closed, retreat var possibleMoves = self.movementPath[self.currentLocation]; for (var i = 1; i < possibleMoves.length; i++) { self.currentLocation = possibleMoves[i]; break; } self.atDoor = false; door.setAnimatronic(null); } } else { // Choose a random valid location to move to var possibleMoves = self.movementPath[self.currentLocation]; if (!possibleMoves || !possibleMoves.length) { // No valid moves, stay in place return; } var nextLocation = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]; self.currentLocation = nextLocation; // If moved to a door, update door status if (nextLocation === 'leftDoor') { self.atDoor = true; self.doorSide = 'left'; game.office.leftDoor.setAnimatronic(self); } else if (nextLocation === 'rightDoor') { self.atDoor = true; self.doorSide = 'right'; game.office.rightDoor.setAnimatronic(self); } else { self.atDoor = false; // Clear from doors if moved away if (self.lastLocation === 'leftDoor') { game.office.leftDoor.setAnimatronic(null); } else if (self.lastLocation === 'rightDoor') { game.office.rightDoor.setAnimatronic(null); } } } }; // Trigger jumpscare sequence self.triggerJumpscare = function () { // Special handling for Bon - he takes power instead of game over if (self.id === 'bon' && game.powerRemaining > 0) { // Play jumpscare sound LK.getSound('jumpscare').play(); // Create jumpscare animation var jumpscare = new Container(); var jumpscareGraphic = jumpscare.attachAsset('jumpscare', { anchorX: 0.5, anchorY: 0.5 }); var animatronicImage = jumpscare.attachAsset(self.id, { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); // Position at center of screen jumpscare.x = 2048 / 2; jumpscare.y = 2732 / 2; // Add to game game.addChild(jumpscare); // Animate jumpscare tween(animatronicImage, { scaleX: 5, scaleY: 5 }, { duration: 500, onFinish: function onFinish() { // Remove Bon from game for this night self.currentLocation = 0; // Set to invalid location // Remove from doors if present if (self.doorSide === 'left') { game.office.leftDoor.setAnimatronic(null); } else if (self.doorSide === 'right') { game.office.rightDoor.setAnimatronic(null); } self.atDoor = false; // Take power instead of game over game.powerRemaining -= 10; if (game.powerRemaining < 0) game.powerRemaining = 0; game.powerSystem.updateDisplay(game.powerRemaining, game.powerConsumption); // Remove jumpscare after a moment LK.setTimeout(function () { jumpscare.destroy(); }, 500); } }); } else { // Regular jumpscare behavior for other animatronics // Set game state game.isGameOver = true; // Play jumpscare sound LK.getSound('jumpscare').play(); // Create jumpscare animation var jumpscare = new Container(); var jumpscareGraphic = jumpscare.attachAsset('jumpscare', { anchorX: 0.5, anchorY: 0.5 }); var animatronicImage = jumpscare.attachAsset(self.id, { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); // Position at center of screen jumpscare.x = 2048 / 2; jumpscare.y = 2732 / 2; // Add to game game.addChild(jumpscare); // Animate jumpscare tween(animatronicImage, { scaleX: 5, scaleY: 5 }, { duration: 500, onFinish: function onFinish() { // Game over LK.setTimeout(function () { LK.showGameOver(); }, 500); } }); } }; // Initialize movement pattern self.setMovementPattern(); return self; }); var Button = Container.expand(function (label, callback) { var self = Container.call(this); self.buttonGraphic = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); var labelText = new Text2(label, { size: 40, fill: 0xFFFFFF }); labelText.anchor.set(0.5, 0.5); self.addChild(labelText); self.down = function (x, y, obj) { self.buttonGraphic.alpha = 0.7; if (callback) callback(); }; self.up = function (x, y, obj) { self.buttonGraphic.alpha = 1; }; return self; }); var CameraSystem = Container.expand(function () { var self = Container.call(this); self.isOpen = false; self.currentCam = 1; // Camera view background var cameraBackground = self.attachAsset('camera', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); // Camera label self.camLabel = new Text2("CAM 1", { size: 60, fill: 0xFFFFFF }); self.camLabel.anchor.set(0.5, 0); self.camLabel.y = -600; self.addChild(self.camLabel); // Static overlay self["static"] = self.attachAsset('background', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self["static"].alpha = 0.3; // Camera buttons self.camButtons = []; for (var i = 1; i <= 5; i++) { var btn = self.addChild(new Button("CAM " + i, function (camNum) { return function () { self.switchCam(camNum); }; }(i))); btn.x = -800 + (i - 1) * 400; btn.y = 600; self.camButtons.push(btn); } // Animatronics in view self.animatronicsInView = self.addChild(new Container()); // Switch to a different camera self.switchCam = function (camNum) { if (camNum === self.currentCam) return; LK.getSound('cameraSound').play(); self.currentCam = camNum; self.camLabel.setText("CAM " + camNum); // Show static effect when switching self["static"].alpha = 0.8; tween(self["static"], { alpha: 0.3 }, { duration: 300 }); // Update which animatronics are visible self.updateAnimatronicsView(); }; // Toggle camera system self.toggle = function () { // Only allow toggling if power is on if (game.powerRemaining <= 0) return; self.isOpen = !self.isOpen; if (self.isOpen) { LK.getSound('cameraSound').play(); LK.getSound('static').play(); self.alpha = 1; game.powerConsumption += 1; self.updateAnimatronicsView(); } else { LK.getSound('static').stop(); self.alpha = 0; game.powerConsumption -= 1; } }; // Update which animatronics are shown based on current camera self.updateAnimatronicsView = function () { self.animatronicsInView.removeChildren(); for (var i = 0; i < game.animatronics.length; i++) { var animatronic = game.animatronics[i]; // Don't show Bon on cameras - he's too fast to be seen if (animatronic.currentLocation === self.currentCam && animatronic.id !== 'bon') { var graphic = self.animatronicsInView.attachAsset(animatronic.id, { anchorX: 0.5, anchorY: 0.5, x: animatronic.viewX, y: animatronic.viewY, scaleX: 1.5, scaleY: 1.5 }); } } }; // Initially hide camera system self.alpha = 0; return self; }); var ClockDisplay = Container.expand(function () { var self = Container.call(this); // Current in-game time (12 AM to 6 AM) self.hour = 12; self.am = true; // Time text self.timeText = new Text2("12 AM", { size: 60, fill: 0xFFFFFF }); self.timeText.anchor.set(0.5, 0.5); self.addChild(self.timeText); // Night text self.nightText = new Text2("Night 1", { size: 40, fill: 0xFFFFFF }); self.nightText.anchor.set(0.5, 0.5); self.nightText.y = 50; self.addChild(self.nightText); // Update the clock display self.updateTime = function (night, gameTime) { // Calculate hour based on game time (7 hours for 420 seconds - 12AM to 6AM) var hourValue = Math.floor(gameTime / 60) + 12; if (hourValue > 12) hourValue -= 12; self.hour = hourValue; self.am = true; // Update display self.timeText.setText(self.hour + " AM"); self.nightText.setText("Night " + night); }; return self; }); var Door = Container.expand(function (side) { var self = Container.call(this); self.side = side; self.isOpen = true; self.lightOn = false; self.animatronicPresent = false; // Door visuals self.doorGraphic = self.attachAsset('door', { anchorX: 0.5, anchorY: 0.5 }); self.doorGraphic.alpha = 0; // Hidden when open // Light area self.lightGraphic = self.attachAsset('doorLight', { anchorX: 0.5, anchorY: 0.5 }); self.lightGraphic.alpha = 0; // Light is off by default // Door button self.doorBtn = self.addChild(new Button('DOOR', function () { self.toggleDoor(); })); self.doorBtn.y = -400; self.doorBtn.x = self.side === 'left' ? 150 : -150; // Light button self.lightBtn = self.addChild(new Button('LIGHT', function () { self.toggleLight(); })); self.lightBtn.y = -300; self.lightBtn.x = self.side === 'left' ? 150 : -150; // Animatronic that might be at the door self.animatronic = self.addChild(new Container()); if (self.side === 'left') { self.animatronic.x = -200; } else { self.animatronic.x = 200; } self.animatronic.y = 0; self.animatronic.alpha = 0; // Toggle door open/closed self.toggleDoor = function () { // Only allow toggling if power is on if (game.powerRemaining <= 0) return; LK.getSound('doorSound').play(); self.isOpen = !self.isOpen; // Update visuals and power consumption if (self.isOpen) { self.doorGraphic.alpha = 0; game.powerConsumption -= 1; } else { self.doorGraphic.alpha = 1; game.powerConsumption += 1; } }; // Toggle light on/off self.toggleLight = function () { // Only allow toggling if power is on if (game.powerRemaining <= 0) return; // Play light sound when button is clicked LK.getSound('fnaf_light_soundmp3').play(); // Toggle the light self.lightOn = !self.lightOn; if (self.lightOn) { self.lightGraphic.alpha = 0.5; // Show animatronic if present if (self.animatronicPresent) { self.showAnimatronic(); } // Light uses power while on game.powerConsumption += 1; // Auto turn off light after 2 seconds LK.setTimeout(function () { if (self.lightOn) { self.toggleLight(); } }, 2000); } else { self.lightGraphic.alpha = 0; self.animatronic.alpha = 0; game.powerConsumption -= 1; } }; // Show the animatronic at the door self.showAnimatronic = function () { if (!self.animatronicData) return; // Clear existing animatronic self.animatronic.removeChildren(); // Create new animatronic based on which one is at the door var animatronicGraphic = self.animatronic.attachAsset(self.animatronicData.id, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.animatronic.alpha = 1; }; // Set which animatronic is at the door self.setAnimatronic = function (animatronicData) { self.animatronicData = animatronicData; self.animatronicPresent = !!animatronicData; // Show animatronic if light is on if (self.lightOn && self.animatronicPresent) { self.showAnimatronic(); } else { self.animatronic.alpha = 0; } }; return self; }); var Office = Container.expand(function () { var self = Container.call(this); var officeBackground = self.attachAsset('office', { anchorX: 0.5, anchorY: 0.5 }); // Add left door and light self.leftDoor = self.addChild(new Door('left')); self.leftDoor.x = 400; self.leftDoor.y = 1366 / 2; // Add right door and light self.rightDoor = self.addChild(new Door('right')); self.rightDoor.x = 2048 - 400; self.rightDoor.y = 1366 / 2; return self; }); var PowerSystem = Container.expand(function () { var self = Container.call(this); // Power background var powerBg = self.attachAsset('powerBg', { anchorX: 0, anchorY: 0.5 }); // Power meter self.powerMeter = self.attachAsset('powerMeter', { anchorX: 0, anchorY: 0.5, x: 10, y: 0 }); // Power text self.powerText = new Text2("Power: 100%", { size: 40, fill: 0xFFFFFF }); self.powerText.anchor.set(0, 0.5); self.powerText.x = 430; self.addChild(self.powerText); // Power usage indicator self.usageText = new Text2("Usage: •", { size: 40, fill: 0xFFFFFF }); self.usageText.anchor.set(0, 0.5); self.usageText.x = 430; self.usageText.y = 50; self.addChild(self.usageText); // Update power display self.updateDisplay = function (power, usage) { // Update power percentage text var percent = Math.floor(power / game.maxPower * 100); self.powerText.setText("Power: " + percent + "%"); // Update power meter width var meterWidth = 400 * (power / game.maxPower); self.powerMeter.width = Math.max(meterWidth, 0); // Update power usage indicators var usageIndicator = ""; for (var i = 0; i < usage; i++) { usageIndicator += "•"; } self.usageText.setText("Usage: " + usageIndicator); // Change power meter color based on remaining power if (percent <= 10) { self.powerMeter.tint = 0xff0000; // Red when low } else if (percent <= 30) { self.powerMeter.tint = 0xffff00; // Yellow when medium } else { self.powerMeter.tint = 0x00ff00; // Green when high } }; return self; }); var TitleScreen = Container.expand(function () { var self = Container.call(this); // Title background var titleBg = self.attachAsset('background', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); // Main character display var dobbyDisplay = self.attachAsset('dobby', { anchorX: 0.5, anchorY: 0.5, y: -300, scaleX: 2, scaleY: 2 }); // Title text var titleText = new Text2("FIVE SCARY NIGHTS", { size: 100, fill: 0xFF0000 }); titleText.anchor.set(0.5, 0.5); titleText.y = -600; self.addChild(titleText); var subtitleText = new Text2("with Dobby", { size: 80, fill: 0xFFFFFF }); subtitleText.anchor.set(0.5, 0.5); subtitleText.y = -500; self.addChild(subtitleText); // Night display var nightText = new Text2("Night " + (storage.currentNight > 5 ? 5 : storage.currentNight), { size: 60, fill: 0xFFFFFF }); nightText.anchor.set(0.5, 0.5); nightText.y = 100; self.addChild(nightText); // UCN mode state self.ucnMode = false; self.ucnAnimatronics = { dobby: true, bon: true, spinny: true }; // UCN mode button var ucnBtn = self.addChild(new Button("UCN MODE", function () { self.ucnMode = !self.ucnMode; if (self.ucnMode) { ucnBtnText.setText("UCN MODE: ON"); startBtn.alpha = 0.5; ucnStartBtn.alpha = 1; ucnPanel.alpha = 1; } else { ucnBtnText.setText("UCN MODE: OFF"); startBtn.alpha = 1; ucnStartBtn.alpha = 0.5; ucnPanel.alpha = 0; } })); ucnBtn.y = 450; var ucnBtnText = new Text2("UCN MODE: OFF", { size: 40, fill: 0xFFFF00 }); ucnBtnText.anchor.set(0.5, 0.5); ucnBtn.addChild(ucnBtnText); // UCN animatronic selection panel var ucnPanel = self.addChild(new Container()); ucnPanel.y = 650; ucnPanel.alpha = 0; var ucnTitle = new Text2("Pick who you want to survive:", { size: 40, fill: 0xFFFFFF }); ucnTitle.anchor.set(0.5, 0.5); ucnPanel.addChild(ucnTitle); ucnTitle.y = 0; var ucnAnimBtns = []; var animList = [{ id: "dobby", name: "Dobby", x: -400 }, { id: "bon", name: "Bon", x: 0 }, { id: "spinny", name: "Spinny", x: 400 }]; for (var i = 0; i < animList.length; i++) { (function (i) { var anim = animList[i]; var btn = ucnPanel.addChild(new Button(anim.name, function () { self.ucnAnimatronics[anim.id] = !self.ucnAnimatronics[anim.id]; btnText.setText(anim.name + ": " + (self.ucnAnimatronics[anim.id] ? "ON" : "OFF")); btn.buttonGraphic.alpha = self.ucnAnimatronics[anim.id] ? 1 : 0.4; })); btn.x = anim.x; btn.y = 80; var btnText = new Text2(anim.name + ": ON", { size: 32, fill: 0xFFFFFF }); btnText.anchor.set(0.5, 0.5); btn.addChild(btnText); btn.buttonGraphic.alpha = 1; ucnAnimBtns.push(btn); })(i); } // Update night text when shown self.updateNightText = function () { nightText.setText("Night " + (storage.currentNight > 5 ? 5 : storage.currentNight)); }; self.updateNightText(); // Start button (normal mode) var startBtn = self.addChild(new Button("START NIGHT", function () { if (!self.ucnMode) { game.startNight(); } })); startBtn.y = 300; // UCN start button var ucnStartBtn = self.addChild(new Button("START UCN", function () { if (self.ucnMode) { game.startNightUCN(self.ucnAnimatronics); } })); ucnStartBtn.y = 300; ucnStartBtn.x = 400; ucnStartBtn.alpha = 0.5; // Animate Dobby function animateDobby() { tween(dobbyDisplay, { rotation: 0.1 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(dobbyDisplay, { rotation: -0.1 }, { duration: 2000, easing: tween.easeInOut, onFinish: animateDobby }); } }); } // Start animation animateDobby(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state variables game.isPlaying = false; game.isGameOver = false; game.titleScreen = null; game.office = null; game.cameraSystem = null; game.powerSystem = null; game.clockDisplay = null; game.animatronics = []; game.currentNight = storage.currentNight || 1; game.gameTime = 0; game.maxGameTime = 60; // 1 minute per night, makes AM go REALLY fast game.maxPower = 100; game.powerRemaining = 100; game.powerConsumption = 1; // Basic power consumption game.powerDrainTimer = null; // Initialize the game game.initialize = function () { // Create title screen game.titleScreen = game.addChild(new TitleScreen()); game.titleScreen.x = 2048 / 2; game.titleScreen.y = 2732 / 2; // Set current night game.currentNight = storage.currentNight || 1; if (game.currentNight > 5) game.currentNight = 5; // Play ambient sound LK.getSound('ambience').play(); }; // Start a night game.startNight = function () { // Hide title screen game.titleScreen.alpha = 0; // Reset game state game.isPlaying = true; game.isGameOver = false; game.gameTime = 0; game.powerRemaining = game.maxPower; game.powerConsumption = 1; // Create office game.office = game.addChild(new Office()); game.office.x = 2048 / 2; game.office.y = 2732 / 2; // Create camera system game.cameraSystem = game.addChild(new CameraSystem()); game.cameraSystem.x = 2048 / 2; game.cameraSystem.y = 2732 / 2; // Create power system game.powerSystem = game.addChild(new PowerSystem()); game.powerSystem.x = 150; game.powerSystem.y = 100; // Create clock display game.clockDisplay = game.addChild(new ClockDisplay()); game.clockDisplay.x = 2048 - 150; game.clockDisplay.y = 100; // Camera button game.cameraBtn = game.addChild(new Button("CAMERA", function () { game.cameraSystem.toggle(); })); game.cameraBtn.x = 2048 / 2; game.cameraBtn.y = 2732 - 150; // Create animatronics - starting positions and difficulties vary by night game.animatronics = []; // Dobby - main animatronic, active from night 1 game.animatronics.push(new Animatronic('dobby', 'Dobby', 2 + game.currentNight, 1)); // Bon - active from night 1 (modified to always be active) game.animatronics.push(new Animatronic('bon', 'Bon', 3 + game.currentNight, 1)); // Spinny - active from night 1 (just like Dobby) game.animatronics.push(new Animatronic('spinny', 'Spinny', game.currentNight, 2)); // Start power drain game.startPowerDrain(); // Play night music LK.playMusic('nightMusic'); }; // UCN mode: start a night with selected animatronics game.startNightUCN = function (ucnAnimatronics) { // Hide title screen game.titleScreen.alpha = 0; // Reset game state game.isPlaying = true; game.isGameOver = false; game.gameTime = 0; game.powerRemaining = game.maxPower; game.powerConsumption = 1; // Create office game.office = game.addChild(new Office()); game.office.x = 2048 / 2; game.office.y = 2732 / 2; // Create camera system game.cameraSystem = game.addChild(new CameraSystem()); game.cameraSystem.x = 2048 / 2; game.cameraSystem.y = 2732 / 2; // Create power system game.powerSystem = game.addChild(new PowerSystem()); game.powerSystem.x = 150; game.powerSystem.y = 100; // Create clock display game.clockDisplay = game.addChild(new ClockDisplay()); game.clockDisplay.x = 2048 - 150; game.clockDisplay.y = 100; // Camera button game.cameraBtn = game.addChild(new Button("CAMERA", function () { game.cameraSystem.toggle(); })); game.cameraBtn.x = 2048 / 2; game.cameraBtn.y = 2732 - 150; // Create animatronics based on UCN selection game.animatronics = []; if (ucnAnimatronics.dobby) { game.animatronics.push(new Animatronic('dobby', 'Dobby', 2 + game.currentNight, 1)); } if (ucnAnimatronics.bon) { game.animatronics.push(new Animatronic('bon', 'Bon', 3 + game.currentNight, 1)); } if (ucnAnimatronics.spinny) { game.animatronics.push(new Animatronic('spinny', 'Spinny', game.currentNight, 2)); } // Start power drain game.startPowerDrain(); // Play night music LK.playMusic('nightMusic'); }; // Start power drainage game.startPowerDrain = function () { // Clear existing timer if any if (game.powerDrainTimer) { LK.clearInterval(game.powerDrainTimer); } // Start draining power based on consumption game.powerDrainTimer = LK.setInterval(function () { if (!game.isPlaying || game.isGameOver) return; // Drain power based on current consumption var drainAmount = 0.1 * game.powerConsumption; game.powerRemaining -= drainAmount; // Handle power out if (game.powerRemaining <= 0) { game.powerRemaining = 0; game.powerOut(); } // Update power display game.powerSystem.updateDisplay(game.powerRemaining, game.powerConsumption); }, 1000); }; // Handle power outage game.powerOut = function () { // Stop power drain LK.clearInterval(game.powerDrainTimer); // Play power down sound LK.getSound('powerDown').play(); // Close camera if open if (game.cameraSystem.isOpen) { game.cameraSystem.toggle(); } // Turn off all lights if (game.office.leftDoor.lightOn) { game.office.leftDoor.toggleLight(); } if (game.office.rightDoor.lightOn) { game.office.rightDoor.toggleLight(); } // Open all doors if (!game.office.leftDoor.isOpen) { game.office.leftDoor.doorGraphic.alpha = 0; game.office.leftDoor.isOpen = true; } if (!game.office.rightDoor.isOpen) { game.office.rightDoor.doorGraphic.alpha = 0; game.office.rightDoor.isOpen = true; } // Wait 10 seconds, then let Bon jumpscare (rather than Dobby) LK.setTimeout(function () { for (var i = 0; i < game.animatronics.length; i++) { if (game.animatronics[i].id === 'bon') { // Override Bon's normal behavior for power outage - he will cause game over var bonAnimatronic = game.animatronics[i]; // Create jumpscare animation with game over game.isGameOver = true; LK.getSound('jumpscare').play(); var jumpscare = new Container(); var jumpscareGraphic = jumpscare.attachAsset('jumpscare', { anchorX: 0.5, anchorY: 0.5 }); var animatronicImage = jumpscare.attachAsset('bon', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); jumpscare.x = 2048 / 2; jumpscare.y = 2732 / 2; game.addChild(jumpscare); tween(animatronicImage, { scaleX: 5, scaleY: 5 }, { duration: 500, onFinish: function onFinish() { LK.setTimeout(function () { LK.showGameOver(); }, 500); } }); break; } } }, 10000); // 10 seconds instead of 5 }; // Win the night game.winNight = function () { // Stop gameplay game.isPlaying = false; // If already on night 5, do not increment further if (game.currentNight < 5) { storage.currentNight = game.currentNight + 1; } else { storage.currentNight = 5; } // Update highest night if needed if (storage.currentNight > storage.highestNight) { storage.highestNight = storage.currentNight; } // Show win screen LK.showYouWin(); }; // Spinny stare jumpscare variables game.spinnyStareTime = 0; // How long player has stared at Spinny on cam game.spinnyStareThreshold = 4; // Seconds to trigger jumpscare game.spinnyLastSeen = false; // Update game state game.update = function () { if (!game.isPlaying || game.isGameOver) return; // Update game time game.gameTime += 1 / 60; // Add 1/60th of a second (assuming 60 FPS) // Update clock if (game.clockDisplay) { game.clockDisplay.updateTime(game.currentNight, game.gameTime); } // Check for win condition if (game.clockDisplay && game.clockDisplay.hour === 6 && game.clockDisplay.am) { // 6 AM reached, player wins the night game.winNight(); return; } // --- Spinny stare jumpscare logic --- var spinny = null; for (var i = 0; i < game.animatronics.length; i++) { if (game.animatronics[i].id === 'spinny') { spinny = game.animatronics[i]; break; } } var spinnyOnCam = false; if (game.cameraSystem && game.cameraSystem.isOpen && spinny && spinny.currentLocation === game.cameraSystem.currentCam) { spinnyOnCam = true; } if (spinnyOnCam) { game.spinnyStareTime += 1 / 60; // Only trigger jumpscare if not already game over if (game.spinnyStareTime >= game.spinnyStareThreshold && !game.isGameOver) { // Trigger Spinny jumpscare game.isGameOver = true; LK.getSound('jumpscare').play(); var jumpscare = new Container(); var jumpscareGraphic = jumpscare.attachAsset('jumpscare', { anchorX: 0.5, anchorY: 0.5 }); var animatronicImage = jumpscare.attachAsset('spinny', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); jumpscare.x = 2048 / 2; jumpscare.y = 2732 / 2; game.addChild(jumpscare); tween(animatronicImage, { scaleX: 5, scaleY: 5 }, { duration: 500, onFinish: function onFinish() { LK.setTimeout(function () { LK.showGameOver(); }, 500); } }); } } else { game.spinnyStareTime = 0; } // Move animatronics (time-based probability) if (LK.ticks % 150 === 0) { // Every 2.5 seconds approximately for (var i = 0; i < game.animatronics.length; i++) { game.animatronics[i].move(); } // Update camera view if open if (game.cameraSystem && game.cameraSystem.isOpen) { game.cameraSystem.updateAnimatronicsView(); } } }; // Initialize the game game.initialize(); // Import tween for animations // Import storage for saving game progress // Initialize assets // Sound effects // Background music
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
currentNight: 1,
highestNight: 1
});
/****
* Classes
****/
var Animatronic = Container.expand(function (id, name, difficulty, startLocation) {
var self = Container.call(this);
self.id = id;
self.name = name;
self.difficulty = difficulty;
self.currentLocation = startLocation;
self.lastLocation = startLocation;
self.atDoor = false;
self.doorSide = null;
self.moveTimer = null;
self.viewX = Math.random() * 400 - 200; // Random position in camera view
self.viewY = Math.random() * 300 - 150;
// Set movement pattern (different for each animatronic)
self.setMovementPattern = function () {
// Movement paths from cameras to door
if (self.id === 'dobby') {
self.movementPath = {
1: [2, 3],
2: [1, 3],
3: [2, 4, 'leftDoor'],
4: [3, 'rightDoor'],
'leftDoor': ['jumpscare', 3],
'rightDoor': ['jumpscare', 4]
};
} else if (self.id === 'bon') {
self.movementPath = {
1: [3, 'leftDoor', 'rightDoor'],
3: [1, 'rightDoor', 'leftDoor'],
5: [1, 'leftDoor', 'rightDoor'],
'leftDoor': ['jumpscare', 5],
'rightDoor': ['jumpscare', 3]
};
} else if (self.id === 'spinny') {
// Make Spinny's movement pattern identical to Dobby
self.movementPath = {
1: [2, 3],
2: [1, 3],
3: [2, 4, 'leftDoor'],
4: [3, 'rightDoor'],
'leftDoor': ['jumpscare', 3],
'rightDoor': ['jumpscare', 4]
};
}
};
// Make movement decisions
self.move = function () {
self.lastLocation = self.currentLocation;
// Check activity level (based on difficulty and night)
var activityLevel = self.difficulty + (game.currentNight - 1) * 2;
// Make Bon move much faster
if (self.id === 'bon') {
activityLevel = activityLevel * 2.5; // Significantly increase Bon's activity
}
var willMove = Math.random() * 20 < activityLevel;
if (!willMove) return;
// If at a door and door is open, enter and trigger jumpscare
if (self.currentLocation === 'leftDoor' || self.currentLocation === 'rightDoor') {
// Check if door is open (accessible from animatronic's door side)
var door = self.currentLocation === 'leftDoor' ? game.office.leftDoor : game.office.rightDoor;
if (door.isOpen) {
self.triggerJumpscare();
return;
} else {
// Door is closed, retreat
var possibleMoves = self.movementPath[self.currentLocation];
for (var i = 1; i < possibleMoves.length; i++) {
self.currentLocation = possibleMoves[i];
break;
}
self.atDoor = false;
door.setAnimatronic(null);
}
} else {
// Choose a random valid location to move to
var possibleMoves = self.movementPath[self.currentLocation];
if (!possibleMoves || !possibleMoves.length) {
// No valid moves, stay in place
return;
}
var nextLocation = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];
self.currentLocation = nextLocation;
// If moved to a door, update door status
if (nextLocation === 'leftDoor') {
self.atDoor = true;
self.doorSide = 'left';
game.office.leftDoor.setAnimatronic(self);
} else if (nextLocation === 'rightDoor') {
self.atDoor = true;
self.doorSide = 'right';
game.office.rightDoor.setAnimatronic(self);
} else {
self.atDoor = false;
// Clear from doors if moved away
if (self.lastLocation === 'leftDoor') {
game.office.leftDoor.setAnimatronic(null);
} else if (self.lastLocation === 'rightDoor') {
game.office.rightDoor.setAnimatronic(null);
}
}
}
};
// Trigger jumpscare sequence
self.triggerJumpscare = function () {
// Special handling for Bon - he takes power instead of game over
if (self.id === 'bon' && game.powerRemaining > 0) {
// Play jumpscare sound
LK.getSound('jumpscare').play();
// Create jumpscare animation
var jumpscare = new Container();
var jumpscareGraphic = jumpscare.attachAsset('jumpscare', {
anchorX: 0.5,
anchorY: 0.5
});
var animatronicImage = jumpscare.attachAsset(self.id, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
// Position at center of screen
jumpscare.x = 2048 / 2;
jumpscare.y = 2732 / 2;
// Add to game
game.addChild(jumpscare);
// Animate jumpscare
tween(animatronicImage, {
scaleX: 5,
scaleY: 5
}, {
duration: 500,
onFinish: function onFinish() {
// Remove Bon from game for this night
self.currentLocation = 0; // Set to invalid location
// Remove from doors if present
if (self.doorSide === 'left') {
game.office.leftDoor.setAnimatronic(null);
} else if (self.doorSide === 'right') {
game.office.rightDoor.setAnimatronic(null);
}
self.atDoor = false;
// Take power instead of game over
game.powerRemaining -= 10;
if (game.powerRemaining < 0) game.powerRemaining = 0;
game.powerSystem.updateDisplay(game.powerRemaining, game.powerConsumption);
// Remove jumpscare after a moment
LK.setTimeout(function () {
jumpscare.destroy();
}, 500);
}
});
} else {
// Regular jumpscare behavior for other animatronics
// Set game state
game.isGameOver = true;
// Play jumpscare sound
LK.getSound('jumpscare').play();
// Create jumpscare animation
var jumpscare = new Container();
var jumpscareGraphic = jumpscare.attachAsset('jumpscare', {
anchorX: 0.5,
anchorY: 0.5
});
var animatronicImage = jumpscare.attachAsset(self.id, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
// Position at center of screen
jumpscare.x = 2048 / 2;
jumpscare.y = 2732 / 2;
// Add to game
game.addChild(jumpscare);
// Animate jumpscare
tween(animatronicImage, {
scaleX: 5,
scaleY: 5
}, {
duration: 500,
onFinish: function onFinish() {
// Game over
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
}
});
}
};
// Initialize movement pattern
self.setMovementPattern();
return self;
});
var Button = Container.expand(function (label, callback) {
var self = Container.call(this);
self.buttonGraphic = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
var labelText = new Text2(label, {
size: 40,
fill: 0xFFFFFF
});
labelText.anchor.set(0.5, 0.5);
self.addChild(labelText);
self.down = function (x, y, obj) {
self.buttonGraphic.alpha = 0.7;
if (callback) callback();
};
self.up = function (x, y, obj) {
self.buttonGraphic.alpha = 1;
};
return self;
});
var CameraSystem = Container.expand(function () {
var self = Container.call(this);
self.isOpen = false;
self.currentCam = 1;
// Camera view background
var cameraBackground = self.attachAsset('camera', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
// Camera label
self.camLabel = new Text2("CAM 1", {
size: 60,
fill: 0xFFFFFF
});
self.camLabel.anchor.set(0.5, 0);
self.camLabel.y = -600;
self.addChild(self.camLabel);
// Static overlay
self["static"] = self.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
self["static"].alpha = 0.3;
// Camera buttons
self.camButtons = [];
for (var i = 1; i <= 5; i++) {
var btn = self.addChild(new Button("CAM " + i, function (camNum) {
return function () {
self.switchCam(camNum);
};
}(i)));
btn.x = -800 + (i - 1) * 400;
btn.y = 600;
self.camButtons.push(btn);
}
// Animatronics in view
self.animatronicsInView = self.addChild(new Container());
// Switch to a different camera
self.switchCam = function (camNum) {
if (camNum === self.currentCam) return;
LK.getSound('cameraSound').play();
self.currentCam = camNum;
self.camLabel.setText("CAM " + camNum);
// Show static effect when switching
self["static"].alpha = 0.8;
tween(self["static"], {
alpha: 0.3
}, {
duration: 300
});
// Update which animatronics are visible
self.updateAnimatronicsView();
};
// Toggle camera system
self.toggle = function () {
// Only allow toggling if power is on
if (game.powerRemaining <= 0) return;
self.isOpen = !self.isOpen;
if (self.isOpen) {
LK.getSound('cameraSound').play();
LK.getSound('static').play();
self.alpha = 1;
game.powerConsumption += 1;
self.updateAnimatronicsView();
} else {
LK.getSound('static').stop();
self.alpha = 0;
game.powerConsumption -= 1;
}
};
// Update which animatronics are shown based on current camera
self.updateAnimatronicsView = function () {
self.animatronicsInView.removeChildren();
for (var i = 0; i < game.animatronics.length; i++) {
var animatronic = game.animatronics[i];
// Don't show Bon on cameras - he's too fast to be seen
if (animatronic.currentLocation === self.currentCam && animatronic.id !== 'bon') {
var graphic = self.animatronicsInView.attachAsset(animatronic.id, {
anchorX: 0.5,
anchorY: 0.5,
x: animatronic.viewX,
y: animatronic.viewY,
scaleX: 1.5,
scaleY: 1.5
});
}
}
};
// Initially hide camera system
self.alpha = 0;
return self;
});
var ClockDisplay = Container.expand(function () {
var self = Container.call(this);
// Current in-game time (12 AM to 6 AM)
self.hour = 12;
self.am = true;
// Time text
self.timeText = new Text2("12 AM", {
size: 60,
fill: 0xFFFFFF
});
self.timeText.anchor.set(0.5, 0.5);
self.addChild(self.timeText);
// Night text
self.nightText = new Text2("Night 1", {
size: 40,
fill: 0xFFFFFF
});
self.nightText.anchor.set(0.5, 0.5);
self.nightText.y = 50;
self.addChild(self.nightText);
// Update the clock display
self.updateTime = function (night, gameTime) {
// Calculate hour based on game time (7 hours for 420 seconds - 12AM to 6AM)
var hourValue = Math.floor(gameTime / 60) + 12;
if (hourValue > 12) hourValue -= 12;
self.hour = hourValue;
self.am = true;
// Update display
self.timeText.setText(self.hour + " AM");
self.nightText.setText("Night " + night);
};
return self;
});
var Door = Container.expand(function (side) {
var self = Container.call(this);
self.side = side;
self.isOpen = true;
self.lightOn = false;
self.animatronicPresent = false;
// Door visuals
self.doorGraphic = self.attachAsset('door', {
anchorX: 0.5,
anchorY: 0.5
});
self.doorGraphic.alpha = 0; // Hidden when open
// Light area
self.lightGraphic = self.attachAsset('doorLight', {
anchorX: 0.5,
anchorY: 0.5
});
self.lightGraphic.alpha = 0; // Light is off by default
// Door button
self.doorBtn = self.addChild(new Button('DOOR', function () {
self.toggleDoor();
}));
self.doorBtn.y = -400;
self.doorBtn.x = self.side === 'left' ? 150 : -150;
// Light button
self.lightBtn = self.addChild(new Button('LIGHT', function () {
self.toggleLight();
}));
self.lightBtn.y = -300;
self.lightBtn.x = self.side === 'left' ? 150 : -150;
// Animatronic that might be at the door
self.animatronic = self.addChild(new Container());
if (self.side === 'left') {
self.animatronic.x = -200;
} else {
self.animatronic.x = 200;
}
self.animatronic.y = 0;
self.animatronic.alpha = 0;
// Toggle door open/closed
self.toggleDoor = function () {
// Only allow toggling if power is on
if (game.powerRemaining <= 0) return;
LK.getSound('doorSound').play();
self.isOpen = !self.isOpen;
// Update visuals and power consumption
if (self.isOpen) {
self.doorGraphic.alpha = 0;
game.powerConsumption -= 1;
} else {
self.doorGraphic.alpha = 1;
game.powerConsumption += 1;
}
};
// Toggle light on/off
self.toggleLight = function () {
// Only allow toggling if power is on
if (game.powerRemaining <= 0) return;
// Play light sound when button is clicked
LK.getSound('fnaf_light_soundmp3').play();
// Toggle the light
self.lightOn = !self.lightOn;
if (self.lightOn) {
self.lightGraphic.alpha = 0.5;
// Show animatronic if present
if (self.animatronicPresent) {
self.showAnimatronic();
}
// Light uses power while on
game.powerConsumption += 1;
// Auto turn off light after 2 seconds
LK.setTimeout(function () {
if (self.lightOn) {
self.toggleLight();
}
}, 2000);
} else {
self.lightGraphic.alpha = 0;
self.animatronic.alpha = 0;
game.powerConsumption -= 1;
}
};
// Show the animatronic at the door
self.showAnimatronic = function () {
if (!self.animatronicData) return;
// Clear existing animatronic
self.animatronic.removeChildren();
// Create new animatronic based on which one is at the door
var animatronicGraphic = self.animatronic.attachAsset(self.animatronicData.id, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.animatronic.alpha = 1;
};
// Set which animatronic is at the door
self.setAnimatronic = function (animatronicData) {
self.animatronicData = animatronicData;
self.animatronicPresent = !!animatronicData;
// Show animatronic if light is on
if (self.lightOn && self.animatronicPresent) {
self.showAnimatronic();
} else {
self.animatronic.alpha = 0;
}
};
return self;
});
var Office = Container.expand(function () {
var self = Container.call(this);
var officeBackground = self.attachAsset('office', {
anchorX: 0.5,
anchorY: 0.5
});
// Add left door and light
self.leftDoor = self.addChild(new Door('left'));
self.leftDoor.x = 400;
self.leftDoor.y = 1366 / 2;
// Add right door and light
self.rightDoor = self.addChild(new Door('right'));
self.rightDoor.x = 2048 - 400;
self.rightDoor.y = 1366 / 2;
return self;
});
var PowerSystem = Container.expand(function () {
var self = Container.call(this);
// Power background
var powerBg = self.attachAsset('powerBg', {
anchorX: 0,
anchorY: 0.5
});
// Power meter
self.powerMeter = self.attachAsset('powerMeter', {
anchorX: 0,
anchorY: 0.5,
x: 10,
y: 0
});
// Power text
self.powerText = new Text2("Power: 100%", {
size: 40,
fill: 0xFFFFFF
});
self.powerText.anchor.set(0, 0.5);
self.powerText.x = 430;
self.addChild(self.powerText);
// Power usage indicator
self.usageText = new Text2("Usage: •", {
size: 40,
fill: 0xFFFFFF
});
self.usageText.anchor.set(0, 0.5);
self.usageText.x = 430;
self.usageText.y = 50;
self.addChild(self.usageText);
// Update power display
self.updateDisplay = function (power, usage) {
// Update power percentage text
var percent = Math.floor(power / game.maxPower * 100);
self.powerText.setText("Power: " + percent + "%");
// Update power meter width
var meterWidth = 400 * (power / game.maxPower);
self.powerMeter.width = Math.max(meterWidth, 0);
// Update power usage indicators
var usageIndicator = "";
for (var i = 0; i < usage; i++) {
usageIndicator += "•";
}
self.usageText.setText("Usage: " + usageIndicator);
// Change power meter color based on remaining power
if (percent <= 10) {
self.powerMeter.tint = 0xff0000; // Red when low
} else if (percent <= 30) {
self.powerMeter.tint = 0xffff00; // Yellow when medium
} else {
self.powerMeter.tint = 0x00ff00; // Green when high
}
};
return self;
});
var TitleScreen = Container.expand(function () {
var self = Container.call(this);
// Title background
var titleBg = self.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
// Main character display
var dobbyDisplay = self.attachAsset('dobby', {
anchorX: 0.5,
anchorY: 0.5,
y: -300,
scaleX: 2,
scaleY: 2
});
// Title text
var titleText = new Text2("FIVE SCARY NIGHTS", {
size: 100,
fill: 0xFF0000
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -600;
self.addChild(titleText);
var subtitleText = new Text2("with Dobby", {
size: 80,
fill: 0xFFFFFF
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.y = -500;
self.addChild(subtitleText);
// Night display
var nightText = new Text2("Night " + (storage.currentNight > 5 ? 5 : storage.currentNight), {
size: 60,
fill: 0xFFFFFF
});
nightText.anchor.set(0.5, 0.5);
nightText.y = 100;
self.addChild(nightText);
// UCN mode state
self.ucnMode = false;
self.ucnAnimatronics = {
dobby: true,
bon: true,
spinny: true
};
// UCN mode button
var ucnBtn = self.addChild(new Button("UCN MODE", function () {
self.ucnMode = !self.ucnMode;
if (self.ucnMode) {
ucnBtnText.setText("UCN MODE: ON");
startBtn.alpha = 0.5;
ucnStartBtn.alpha = 1;
ucnPanel.alpha = 1;
} else {
ucnBtnText.setText("UCN MODE: OFF");
startBtn.alpha = 1;
ucnStartBtn.alpha = 0.5;
ucnPanel.alpha = 0;
}
}));
ucnBtn.y = 450;
var ucnBtnText = new Text2("UCN MODE: OFF", {
size: 40,
fill: 0xFFFF00
});
ucnBtnText.anchor.set(0.5, 0.5);
ucnBtn.addChild(ucnBtnText);
// UCN animatronic selection panel
var ucnPanel = self.addChild(new Container());
ucnPanel.y = 650;
ucnPanel.alpha = 0;
var ucnTitle = new Text2("Pick who you want to survive:", {
size: 40,
fill: 0xFFFFFF
});
ucnTitle.anchor.set(0.5, 0.5);
ucnPanel.addChild(ucnTitle);
ucnTitle.y = 0;
var ucnAnimBtns = [];
var animList = [{
id: "dobby",
name: "Dobby",
x: -400
}, {
id: "bon",
name: "Bon",
x: 0
}, {
id: "spinny",
name: "Spinny",
x: 400
}];
for (var i = 0; i < animList.length; i++) {
(function (i) {
var anim = animList[i];
var btn = ucnPanel.addChild(new Button(anim.name, function () {
self.ucnAnimatronics[anim.id] = !self.ucnAnimatronics[anim.id];
btnText.setText(anim.name + ": " + (self.ucnAnimatronics[anim.id] ? "ON" : "OFF"));
btn.buttonGraphic.alpha = self.ucnAnimatronics[anim.id] ? 1 : 0.4;
}));
btn.x = anim.x;
btn.y = 80;
var btnText = new Text2(anim.name + ": ON", {
size: 32,
fill: 0xFFFFFF
});
btnText.anchor.set(0.5, 0.5);
btn.addChild(btnText);
btn.buttonGraphic.alpha = 1;
ucnAnimBtns.push(btn);
})(i);
}
// Update night text when shown
self.updateNightText = function () {
nightText.setText("Night " + (storage.currentNight > 5 ? 5 : storage.currentNight));
};
self.updateNightText();
// Start button (normal mode)
var startBtn = self.addChild(new Button("START NIGHT", function () {
if (!self.ucnMode) {
game.startNight();
}
}));
startBtn.y = 300;
// UCN start button
var ucnStartBtn = self.addChild(new Button("START UCN", function () {
if (self.ucnMode) {
game.startNightUCN(self.ucnAnimatronics);
}
}));
ucnStartBtn.y = 300;
ucnStartBtn.x = 400;
ucnStartBtn.alpha = 0.5;
// Animate Dobby
function animateDobby() {
tween(dobbyDisplay, {
rotation: 0.1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(dobbyDisplay, {
rotation: -0.1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: animateDobby
});
}
});
}
// Start animation
animateDobby();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game state variables
game.isPlaying = false;
game.isGameOver = false;
game.titleScreen = null;
game.office = null;
game.cameraSystem = null;
game.powerSystem = null;
game.clockDisplay = null;
game.animatronics = [];
game.currentNight = storage.currentNight || 1;
game.gameTime = 0;
game.maxGameTime = 60; // 1 minute per night, makes AM go REALLY fast
game.maxPower = 100;
game.powerRemaining = 100;
game.powerConsumption = 1; // Basic power consumption
game.powerDrainTimer = null;
// Initialize the game
game.initialize = function () {
// Create title screen
game.titleScreen = game.addChild(new TitleScreen());
game.titleScreen.x = 2048 / 2;
game.titleScreen.y = 2732 / 2;
// Set current night
game.currentNight = storage.currentNight || 1;
if (game.currentNight > 5) game.currentNight = 5;
// Play ambient sound
LK.getSound('ambience').play();
};
// Start a night
game.startNight = function () {
// Hide title screen
game.titleScreen.alpha = 0;
// Reset game state
game.isPlaying = true;
game.isGameOver = false;
game.gameTime = 0;
game.powerRemaining = game.maxPower;
game.powerConsumption = 1;
// Create office
game.office = game.addChild(new Office());
game.office.x = 2048 / 2;
game.office.y = 2732 / 2;
// Create camera system
game.cameraSystem = game.addChild(new CameraSystem());
game.cameraSystem.x = 2048 / 2;
game.cameraSystem.y = 2732 / 2;
// Create power system
game.powerSystem = game.addChild(new PowerSystem());
game.powerSystem.x = 150;
game.powerSystem.y = 100;
// Create clock display
game.clockDisplay = game.addChild(new ClockDisplay());
game.clockDisplay.x = 2048 - 150;
game.clockDisplay.y = 100;
// Camera button
game.cameraBtn = game.addChild(new Button("CAMERA", function () {
game.cameraSystem.toggle();
}));
game.cameraBtn.x = 2048 / 2;
game.cameraBtn.y = 2732 - 150;
// Create animatronics - starting positions and difficulties vary by night
game.animatronics = [];
// Dobby - main animatronic, active from night 1
game.animatronics.push(new Animatronic('dobby', 'Dobby', 2 + game.currentNight, 1));
// Bon - active from night 1 (modified to always be active)
game.animatronics.push(new Animatronic('bon', 'Bon', 3 + game.currentNight, 1));
// Spinny - active from night 1 (just like Dobby)
game.animatronics.push(new Animatronic('spinny', 'Spinny', game.currentNight, 2));
// Start power drain
game.startPowerDrain();
// Play night music
LK.playMusic('nightMusic');
};
// UCN mode: start a night with selected animatronics
game.startNightUCN = function (ucnAnimatronics) {
// Hide title screen
game.titleScreen.alpha = 0;
// Reset game state
game.isPlaying = true;
game.isGameOver = false;
game.gameTime = 0;
game.powerRemaining = game.maxPower;
game.powerConsumption = 1;
// Create office
game.office = game.addChild(new Office());
game.office.x = 2048 / 2;
game.office.y = 2732 / 2;
// Create camera system
game.cameraSystem = game.addChild(new CameraSystem());
game.cameraSystem.x = 2048 / 2;
game.cameraSystem.y = 2732 / 2;
// Create power system
game.powerSystem = game.addChild(new PowerSystem());
game.powerSystem.x = 150;
game.powerSystem.y = 100;
// Create clock display
game.clockDisplay = game.addChild(new ClockDisplay());
game.clockDisplay.x = 2048 - 150;
game.clockDisplay.y = 100;
// Camera button
game.cameraBtn = game.addChild(new Button("CAMERA", function () {
game.cameraSystem.toggle();
}));
game.cameraBtn.x = 2048 / 2;
game.cameraBtn.y = 2732 - 150;
// Create animatronics based on UCN selection
game.animatronics = [];
if (ucnAnimatronics.dobby) {
game.animatronics.push(new Animatronic('dobby', 'Dobby', 2 + game.currentNight, 1));
}
if (ucnAnimatronics.bon) {
game.animatronics.push(new Animatronic('bon', 'Bon', 3 + game.currentNight, 1));
}
if (ucnAnimatronics.spinny) {
game.animatronics.push(new Animatronic('spinny', 'Spinny', game.currentNight, 2));
}
// Start power drain
game.startPowerDrain();
// Play night music
LK.playMusic('nightMusic');
};
// Start power drainage
game.startPowerDrain = function () {
// Clear existing timer if any
if (game.powerDrainTimer) {
LK.clearInterval(game.powerDrainTimer);
}
// Start draining power based on consumption
game.powerDrainTimer = LK.setInterval(function () {
if (!game.isPlaying || game.isGameOver) return;
// Drain power based on current consumption
var drainAmount = 0.1 * game.powerConsumption;
game.powerRemaining -= drainAmount;
// Handle power out
if (game.powerRemaining <= 0) {
game.powerRemaining = 0;
game.powerOut();
}
// Update power display
game.powerSystem.updateDisplay(game.powerRemaining, game.powerConsumption);
}, 1000);
};
// Handle power outage
game.powerOut = function () {
// Stop power drain
LK.clearInterval(game.powerDrainTimer);
// Play power down sound
LK.getSound('powerDown').play();
// Close camera if open
if (game.cameraSystem.isOpen) {
game.cameraSystem.toggle();
}
// Turn off all lights
if (game.office.leftDoor.lightOn) {
game.office.leftDoor.toggleLight();
}
if (game.office.rightDoor.lightOn) {
game.office.rightDoor.toggleLight();
}
// Open all doors
if (!game.office.leftDoor.isOpen) {
game.office.leftDoor.doorGraphic.alpha = 0;
game.office.leftDoor.isOpen = true;
}
if (!game.office.rightDoor.isOpen) {
game.office.rightDoor.doorGraphic.alpha = 0;
game.office.rightDoor.isOpen = true;
}
// Wait 10 seconds, then let Bon jumpscare (rather than Dobby)
LK.setTimeout(function () {
for (var i = 0; i < game.animatronics.length; i++) {
if (game.animatronics[i].id === 'bon') {
// Override Bon's normal behavior for power outage - he will cause game over
var bonAnimatronic = game.animatronics[i];
// Create jumpscare animation with game over
game.isGameOver = true;
LK.getSound('jumpscare').play();
var jumpscare = new Container();
var jumpscareGraphic = jumpscare.attachAsset('jumpscare', {
anchorX: 0.5,
anchorY: 0.5
});
var animatronicImage = jumpscare.attachAsset('bon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
jumpscare.x = 2048 / 2;
jumpscare.y = 2732 / 2;
game.addChild(jumpscare);
tween(animatronicImage, {
scaleX: 5,
scaleY: 5
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
}
});
break;
}
}
}, 10000); // 10 seconds instead of 5
};
// Win the night
game.winNight = function () {
// Stop gameplay
game.isPlaying = false;
// If already on night 5, do not increment further
if (game.currentNight < 5) {
storage.currentNight = game.currentNight + 1;
} else {
storage.currentNight = 5;
}
// Update highest night if needed
if (storage.currentNight > storage.highestNight) {
storage.highestNight = storage.currentNight;
}
// Show win screen
LK.showYouWin();
};
// Spinny stare jumpscare variables
game.spinnyStareTime = 0; // How long player has stared at Spinny on cam
game.spinnyStareThreshold = 4; // Seconds to trigger jumpscare
game.spinnyLastSeen = false;
// Update game state
game.update = function () {
if (!game.isPlaying || game.isGameOver) return;
// Update game time
game.gameTime += 1 / 60; // Add 1/60th of a second (assuming 60 FPS)
// Update clock
if (game.clockDisplay) {
game.clockDisplay.updateTime(game.currentNight, game.gameTime);
}
// Check for win condition
if (game.clockDisplay && game.clockDisplay.hour === 6 && game.clockDisplay.am) {
// 6 AM reached, player wins the night
game.winNight();
return;
}
// --- Spinny stare jumpscare logic ---
var spinny = null;
for (var i = 0; i < game.animatronics.length; i++) {
if (game.animatronics[i].id === 'spinny') {
spinny = game.animatronics[i];
break;
}
}
var spinnyOnCam = false;
if (game.cameraSystem && game.cameraSystem.isOpen && spinny && spinny.currentLocation === game.cameraSystem.currentCam) {
spinnyOnCam = true;
}
if (spinnyOnCam) {
game.spinnyStareTime += 1 / 60;
// Only trigger jumpscare if not already game over
if (game.spinnyStareTime >= game.spinnyStareThreshold && !game.isGameOver) {
// Trigger Spinny jumpscare
game.isGameOver = true;
LK.getSound('jumpscare').play();
var jumpscare = new Container();
var jumpscareGraphic = jumpscare.attachAsset('jumpscare', {
anchorX: 0.5,
anchorY: 0.5
});
var animatronicImage = jumpscare.attachAsset('spinny', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
jumpscare.x = 2048 / 2;
jumpscare.y = 2732 / 2;
game.addChild(jumpscare);
tween(animatronicImage, {
scaleX: 5,
scaleY: 5
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
}
});
}
} else {
game.spinnyStareTime = 0;
}
// Move animatronics (time-based probability)
if (LK.ticks % 150 === 0) {
// Every 2.5 seconds approximately
for (var i = 0; i < game.animatronics.length; i++) {
game.animatronics[i].move();
}
// Update camera view if open
if (game.cameraSystem && game.cameraSystem.isOpen) {
game.cameraSystem.updateAnimatronicsView();
}
}
};
// Initialize the game
game.initialize();
// Import tween for animations
// Import storage for saving game progress
// Initialize assets
// Sound effects
// Background music
animatronic lollypop scary. In-Game asset. 2d. High contrast. No shadows
a creepy balloon with a drawn smile and eyes. In-Game asset. 2d. High contrast. No shadows
creepy animatronic spider. In-Game asset. 2d. High contrast. No shadows
a creepy office. In-Game asset. 2d. High contrast. No shadows
door shut. In-Game asset. 2d. High contrast. No shadows