User prompt
herhangi bir kapıyı kapattığımız zaman animatronik gitsin
User prompt
make the nightoverlay invisible
User prompt
oyun ilk başladığında NightOverlay i gösterme bu kadar
User prompt
hala duruyor NIGHT OVERLAY ASSET INI ANA MENUDE SAKLA STARTBUTTON A BASTIĞIMDA BANA GERİ GÖSTER. O TUŞA BASMADAN NIGHTOVERLAY I GÖRMEK İSTEMİYORUM
User prompt
hide nightOverlay if its main menu
User prompt
hala ana menüde gözüküyor. onu start tuşuna bastığımda bana göster
User prompt
nightOverlay asset'i ben zorluğu seçip oyunu başlattığımda gözüksün, ana menüde değil.
User prompt
make the nightOverlay asset appear when the game starts, not in the main menu
User prompt
Hayır animatronik gelince 5 saniye kamerada en ön odada beklerken aynı anda BearCame sesini çıkartsın böylece geleceğini anlayayım da kapıyı kapatayım.
User prompt
Hayır animatronik gelince 5 saniye kamerada en ön odada beklerken BearCame sesini çıkartsın böylece geleceğini anlayayım
User prompt
animatronik geldiğinde ses çıkartsın ki onu duyabiliyim. Kameradan göremezsem sesini duyayım diye söyledim.
User prompt
Animatronik geldiğinde BearCame sesini çıkartsın
User prompt
make the nightOverlay asset appear when the game starts, not in the main menu
User prompt
no arrow keys on the main menu, only when the game starts.
User prompt
look brother, let the door open/close button be used only as a door open/close button. let the camera, arrow keys and the keys in the main menu have their own assets.
User prompt
doorbutton u her yere gereksiz şekilde koyma. ana menüye şu seçenekleri koy; easy mode, hard mode
User prompt
oyuna bir kolay mod bir de zor mod ekle
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'visible')' in or related to this line: 'leftArrow.visible = false;' Line Number: 1072
User prompt
şimdi oyunun en başına bir ana menü ekle
User prompt
ortaya çıktığında bana 5 saniye süre ver, gördüğüm gibi kapılardan birini kapayayım ve gitsin.
User prompt
animatronik herhangi bir yerde ortaya çıksın.
User prompt
not exactly full screen. switch to full screen inside the game.
User prompt
I can't switch to a different camera in each camera and then switch back to the first camera I looked at. After clicking on a camera, it stays black and does not open back.
User prompt
animatronic will take turns starting from the farthest room to the office and moving to the fastest room.
User prompt
cameras should have separate images of each room
/****
* 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, startingRoom, aggressiveness) {
var self = Container.call(this);
self.id = id;
self.currentRoom = startingRoom;
self.previousRoom = startingRoom;
self.aggressiveness = aggressiveness;
self.moveTimer = 0;
self.moveCooldown = Math.floor(600 / self.aggressiveness);
self.active = true;
var sprite = self.attachAsset('animatronic', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.update = function () {
if (!self.active) return;
// Increment move timer
self.moveTimer++;
// Check if it's time to move
if (self.moveTimer >= self.moveCooldown) {
self.moveTimer = 0;
// Determine if animatronic will move based on aggressiveness
if (Math.random() * 100 < self.aggressiveness) {
self.moveToNextRoom();
}
}
};
self.moveToNextRoom = function () {
self.previousRoom = self.currentRoom;
// Instead of only adjacent rooms, allow animatronic to appear at any random room
var allRooms = Object.keys(roomMap);
// Exclude office itself as a spawn, but allow officeLeft/officeRight
var validRooms = allRooms.filter(function (room) {
return room !== 'office';
});
var targetRoom = validRooms[Math.floor(Math.random() * validRooms.length)];
self.currentRoom = targetRoom;
// If moved to office or right outside office door, check door status
if (self.currentRoom === 'officeLeft' || self.currentRoom === 'officeRight') {
// Play BearCame sound when animatronic comes to the door
LK.getSound('BearCame').play();
var doorSide = self.currentRoom === 'officeLeft' ? 'left' : 'right';
if (!doors[doorSide].closed) {
// Jumpscare if door is open!
triggerJumpscare(self.id);
}
}
// Notify that an animatronic moved for camera updates
animatronicMoved = true;
};
self.render = function (cameraElement) {
// Position the animatronic in the correct spot based on the camera view
if (self.currentRoom === currentCamera) {
sprite.alpha = 1;
// Position differently based on the room
var roomPosition = cameraPositions[self.currentRoom];
if (roomPosition) {
sprite.x = roomPosition.x;
sprite.y = roomPosition.y;
// Add to the camera feed
cameraElement.addChild(sprite);
}
}
};
return self;
});
var Door = Container.expand(function (side) {
var self = Container.call(this);
self.side = side; // 'left' or 'right'
self.closed = false;
var doorGraphic = self.attachAsset('door', {
anchorX: 0.5,
anchorY: 0.5
});
var doorButton = self.attachAsset('doorButton', {
anchorX: 0.5,
anchorY: 0.5,
y: -250
});
var buttonLabel = new Text2("DOOR", {
size: 20,
fill: 0xFFFFFF
});
buttonLabel.anchor.set(0.5, 0.5);
doorButton.addChild(buttonLabel);
// Door starts open (hidden)
doorGraphic.alpha = 0;
self.toggleDoor = function () {
self.closed = !self.closed;
if (self.closed) {
// Close door
doorGraphic.alpha = 1;
LK.getSound('doorClose').play();
buttonLabel.setText("OPEN");
doorButton.tint = 0xff0000;
// Use power
increasePowerUsage();
// If animatronic is attacking at this door, cancel attack and make animatronic leave
if (typeof animatronicAttacking !== "undefined" && animatronicAttacking[self.side]) {
animatronicAttacking[self.side] = false;
if (typeof animatronicAttackTimeouts !== "undefined" && animatronicAttackTimeouts[self.side]) {
LK.clearTimeout(animatronicAttackTimeouts[self.side]);
animatronicAttackTimeouts[self.side] = null;
}
// Make animatronic leave: move to a random non-office room
for (var i = 0; i < animatronics.length; i++) {
var dangerRoom = self.side === 'left' ? 'officeLeft' : 'officeRight';
if (animatronics[i].currentRoom === dangerRoom) {
// Pick a random non-office room
var allRooms = Object.keys(roomMap).filter(function (room) {
return room !== 'office' && room !== 'officeLeft' && room !== 'officeRight';
});
var newRoom = allRooms[Math.floor(Math.random() * allRooms.length)];
animatronics[i].currentRoom = newRoom;
animatronicMoved = true;
}
}
}
} else {
// Open door
doorGraphic.alpha = 0;
LK.getSound('doorOpen').play();
buttonLabel.setText("DOOR");
doorButton.tint = 0x008000;
// Save power
decreasePowerUsage();
// Check if any animatronics are waiting outside
for (var i = 0; i < animatronics.length; i++) {
var dangerRoom = self.side === 'left' ? 'officeLeft' : 'officeRight';
if (animatronics[i].currentRoom === dangerRoom) {
// Jumpscare!
triggerJumpscare(animatronics[i].id);
return;
}
}
}
};
doorButton.down = function () {
self.toggleDoor();
};
return self;
});
var PowerSystem = Container.expand(function () {
var self = Container.call(this);
self.powerLevel = 100;
self.powerUsage = 1; // Base level (always uses some power)
self.drainTimer = 0;
var powerBarBg = self.attachAsset('powerBarBg', {
anchorX: 0,
anchorY: 0.5
});
var powerBar = self.attachAsset('powerBar', {
anchorX: 0,
anchorY: 0.5,
width: 400 // Start at full width
});
var powerLabel = new Text2("POWER: 100%", {
size: 30,
fill: 0xFFFFFF
});
powerLabel.anchor.set(0, 0.5);
powerLabel.x = 420;
self.addChild(powerLabel);
var usageLabel = new Text2("USAGE: ▮", {
size: 30,
fill: 0xFFFFFF
});
usageLabel.anchor.set(0, 0.5);
usageLabel.y = 40;
self.addChild(usageLabel);
self.update = function () {
// Drain power based on usage level and game difficulty
self.drainTimer++;
// Drain every X frames based on current night (higher nights drain faster)
// Hard mode: power drains faster
var drainRate;
if (typeof selectedDifficulty === "undefined" || selectedDifficulty === "easy") {
drainRate = Math.max(15 - currentNight * 2, 5);
} else {
drainRate = Math.max(10 - currentNight * 3, 3);
}
if (self.drainTimer >= drainRate) {
self.drainTimer = 0;
self.powerLevel -= self.powerUsage * 0.1;
// Update power bar width
powerBar.width = 400 * (self.powerLevel / 100);
// Update label
powerLabel.setText("POWER: " + Math.floor(self.powerLevel) + "%");
// Change color as power decreases
if (self.powerLevel <= 20) {
powerBar.tint = 0xff0000; // Red when low
// Warning sounds when power is very low
if (self.powerLevel <= 10 && self.drainTimer % 5 === 0) {
LK.getSound('warning').play();
}
} else if (self.powerLevel <= 50) {
powerBar.tint = 0xffff00; // Yellow when medium
}
// Check for power out
if (self.powerLevel <= 0) {
powerOut();
}
}
};
self.updateUsageDisplay = function () {
var usageText = "USAGE: ";
for (var i = 0; i < self.powerUsage; i++) {
usageText += "▮";
}
usageLabel.setText(usageText);
};
return self;
});
var SecurityCamera = Container.expand(function (roomId, x, y) {
var self = Container.call(this);
self.roomId = roomId;
self.x = x;
self.y = y;
self.isActive = false;
// Use a unique camera feed image for each room
var camFeedAssetId = 'camFeed_' + roomId;
var cameraFeed = self.attachAsset(camFeedAssetId, {
anchorX: 0.5,
anchorY: 0.5,
width: 120,
height: 112.5
});
var roomLabel = new Text2(roomId.toUpperCase(), {
size: 24,
fill: 0xFF0000
});
roomLabel.anchor.set(0.5, 0);
roomLabel.y = -cameraFeed.height / 2 - 30;
self.addChild(roomLabel);
var staticOverlay = self.attachAsset('staticOverlay', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
width: 120,
height: 80
});
self.activate = function () {
self.isActive = true;
LK.getSound('camSwitch').play();
// Increase static effect briefly
tween(staticOverlay, {
alpha: 0.7
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(staticOverlay, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// Always clear and re-add animatronics to prevent black feed
self.updateAnimatronics();
};
self.deactivate = function () {
self.isActive = false;
// Clear any animatronics from view
while (cameraFeed.children.length > 0) {
cameraFeed.removeChild(cameraFeed.children[0]);
}
// Also reset static overlay to default alpha
staticOverlay.alpha = 0.3;
};
self.updateAnimatronics = function () {
// Clear previous animatronics
while (cameraFeed.children.length > 0) {
cameraFeed.removeChild(cameraFeed.children[0]);
}
// Add animatronics that are in this room
for (var i = 0; i < animatronics.length; i++) {
if (animatronics[i].currentRoom === self.roomId && self.isActive) {
animatronics[i].render(cameraFeed);
// --- BearCame sound logic for animatronic waiting in officeLeft/officeRight ---
// Only for officeLeft or officeRight, and only if animatronic has been there for 5 seconds
if (self.roomId === 'officeLeft' || self.roomId === 'officeRight') {
if (!animatronics[i].waitTimer) animatronics[i].waitTimer = 0;
// Play BearCame sound immediately when animatronic starts waiting in front of office
if (animatronics[i].waitTimer === 0) {
LK.getSound('BearCame').play();
}
animatronics[i].waitTimer++;
// 5 seconds = 5*60 = 300 frames
if (animatronics[i].waitTimer === 300) {
// (No need to play BearCame here anymore, already played at waitTimer === 0)
}
} else {
// Reset waitTimer if not in front of office
animatronics[i].waitTimer = 0;
}
} else if (animatronics[i].currentRoom === self.roomId) {
// Not active camera, but still reset waitTimer if not in officeLeft/officeRight
if (self.roomId !== 'officeLeft' && self.roomId !== 'officeRight') {
animatronics[i].waitTimer = 0;
}
}
}
};
self.down = function () {
// When this camera is clicked, make it the active camera
if (cameraSystemActive && self.roomId !== currentCamera) {
switchCamera(self.roomId);
}
};
return self;
});
var SecurityMonitor = Container.expand(function () {
var self = Container.call(this);
var monitorBg = self.attachAsset('securityMonitor', {
anchorX: 0.5,
anchorY: 0.5
});
var mapContainer = new Container();
// Center the map in the monitor background
mapContainer.x = -monitorBg.width / 2 + 200;
mapContainer.y = -monitorBg.height / 2 + 100;
self.addChild(mapContainer);
var cameraViewContainer = new Container();
cameraViewContainer.x = 200;
cameraViewContainer.y = 0;
self.addChild(cameraViewContainer);
var activeCamera = null;
var cameraLabel = new Text2("CAMERA: NONE", {
size: 40,
fill: 0xFF0000
});
cameraLabel.anchor.set(0.5, 0);
cameraLabel.x = 200;
cameraLabel.y = -monitorBg.height / 2 + 50;
self.addChild(cameraLabel);
var closeButton = self.attachAsset('closeCameraButton', {
anchorX: 0.5,
anchorY: 0.5,
x: monitorBg.width / 2 - 50,
y: -monitorBg.height / 2 + 50
});
var closeLabel = new Text2("X", {
size: 40,
fill: 0xFFFFFF
});
closeLabel.anchor.set(0.5, 0.5);
closeButton.addChild(closeLabel);
closeButton.down = function () {
toggleCameraSystem();
};
self.setup = function () {
// Optionally: Draw lines or dots to visually separate rooms (spacer lines)
// We'll use simple rectangles as spacers between clusters of rooms
// (This is a visual aid, not interactive)
var roomGroups = [['stage', 'kitchen', 'diningArea', 'laundry', 'storage'], ['arcade', 'partyRoom', 'backstage', 'restroom'], ['westHall', 'westCorner', 'officeLeft'], ['eastHall', 'eastCorner', 'officeRight']];
// Draw spacers between groups
for (var g = 1; g < roomGroups.length; g++) {
var prevGroup = roomGroups[g - 1];
var currGroup = roomGroups[g];
// Find center of last room in prev group and first room in curr group
var prevRoom = prevGroup[prevGroup.length - 1];
var currRoom = currGroup[0];
var prevPos = mapPositions[prevRoom];
var currPos = mapPositions[currRoom];
if (prevPos && currPos) {
var spacer = new Container();
var line = spacer.attachAsset('powerBarBg', {
anchorX: 0,
anchorY: 0.5,
width: Math.abs(currPos.x - prevPos.x),
height: 10,
tint: 0x222222,
alpha: 0.5
});
spacer.x = Math.min(prevPos.x, currPos.x);
spacer.y = (prevPos.y + currPos.y) / 2;
mapContainer.addChild(spacer);
}
}
// Create cameras for each room
for (var room in cameraPositions) {
var pos = mapPositions[room] || {
x: 0,
y: 0
};
var camera = new SecurityCamera(room, pos.x, pos.y);
mapContainer.addChild(camera);
cameras[room] = camera;
}
// Set initial camera to show
self.switchCamera('stage');
};
self.switchCamera = function (roomId) {
// Deactivate current camera
if (activeCamera) {
activeCamera.deactivate();
}
// Activate new camera
activeCamera = cameras[roomId];
if (activeCamera) {
activeCamera.activate();
currentCamera = roomId;
cameraLabel.setText("CAMERA: " + roomId.toUpperCase());
}
};
self.updateCameras = function () {
if (activeCamera) {
activeCamera.updateAnimatronics();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game constants and settings
// Unique assets for UI (not doorButton)
var currentNight = storage.currentNight || 1;
var gameTime = 0; // in seconds
var nightDuration = 360; // 6 minutes per night
var cameraSystemActive = false;
var currentCamera = 'stage';
var animatronicMoved = false;
var gameOver = false;
var powerOutTriggered = false;
// Room layout definitions
var roomMap = {
'stage': ['diningArea'],
'diningArea': ['stage', 'westHall', 'eastHall', 'kitchen', 'arcade', 'partyRoom', 'laundry', 'backstage'],
'westHall': ['diningArea', 'westCorner', 'officeLeft', 'storage', 'laundry'],
'eastHall': ['diningArea', 'eastCorner', 'officeRight', 'arcade'],
'westCorner': ['westHall', 'officeLeft'],
'eastCorner': ['eastHall', 'officeRight'],
'kitchen': ['diningArea', 'storage', 'laundry'],
'arcade': ['diningArea', 'eastHall', 'partyRoom'],
'partyRoom': ['diningArea', 'arcade', 'storage', 'backstage'],
'storage': ['westHall', 'kitchen', 'partyRoom', 'laundry'],
'laundry': ['storage', 'kitchen', 'westHall', 'diningArea'],
'backstage': ['partyRoom', 'diningArea'],
// 'restroom' removed
'officeLeft': ['westCorner', 'office'],
'officeRight': ['eastCorner', 'office'],
'office': ['officeLeft', 'officeRight']
};
// Distance from each room to the office (for AI pathfinding)
var roomDistanceToOffice = {
'office': 0,
'officeLeft': 1,
'officeRight': 1,
'westCorner': 2,
'eastCorner': 2,
'westHall': 3,
'eastHall': 3,
'diningArea': 4,
'kitchen': 5,
'arcade': 5,
'partyRoom': 5,
'storage': 6,
'laundry': 6,
'backstage': 6,
'stage': 6
};
// Camera positions on the map (expanded area, problematic rooms adjusted/removed)
var mapPositions = {
'stage': {
x: 200,
y: 200
},
'diningArea': {
x: 500,
y: 200
},
'kitchen': {
x: 800,
y: 200
},
'laundry': {
x: 1100,
y: 200
},
'storage': {
x: 200,
y: 500
},
'partyRoom': {
x: 500,
y: 500
},
'arcade': {
x: 800,
y: 500
},
'backstage': {
x: 1100,
y: 500
},
// 'restroom' removed for clarity and space (no camera will be created for restroom)
'westHall': {
x: 200,
y: 800
},
// 'eastHall', 'eastCorner', and 'officeRight' removed from mapPositions to prevent their camera creation
'westCorner': {
x: 200,
y: 1100
},
'officeLeft': {
x: 200,
y: 1400
}
};
// Camera positions for rendering animatronics
var cameraPositions = {
'stage': {
x: 0,
y: 0
},
'diningArea': {
x: 50,
y: 0
},
'westHall': {
x: -50,
y: 0
},
// 'eastHall', 'eastCorner', and 'officeRight' removed from cameraPositions to prevent animatronic rendering in those rooms
'westCorner': {
x: -80,
y: 20
},
'kitchen': {
x: 0,
y: -30
},
'arcade': {
x: 60,
y: -20
},
'partyRoom': {
x: 0,
y: 40
},
'storage': {
x: -60,
y: -40
},
'laundry': {
x: -30,
y: -60
},
'backstage': {
x: 100,
y: -50
},
// (restroom removed to prevent out-of-bounds camera)
'officeLeft': {
x: -100,
y: 0
}
};
// Initialize game objects
var securityMonitor = new SecurityMonitor();
var powerSystem = new PowerSystem();
var doors = {
'left': new Door('left'),
'right': new Door('right')
};
var cameras = {};
var animatronics = [];
var clockDisplay, nightDisplay, cameraToggleBtn;
// Initialize office background as a single image covering the whole office
var officeFull = LK.getAsset('officeFull', {
anchorX: 0.5,
anchorY: 0,
x: 2048 / 2,
y: 1200
});
game.addChild(officeFull);
// Position and add doors on top of the officeFull image
doors.left.x = 800; // moved further to the right from 700 to 800
doors.left.y = 1200 + 400;
doors.right.x = 1748; // 2048 - 300
doors.right.y = 1200 + 400;
game.addChild(doors.left);
game.addChild(doors.right);
// Add security monitor (initially hidden)
securityMonitor.visible = false;
securityMonitor.y = 1300;
game.addChild(securityMonitor);
// Camera navigation buttons
var cameraRoomOrder = ['stage', 'diningArea', 'kitchen', 'laundry', 'storage', 'partyRoom', 'arcade', 'backstage', 'westHall', 'westCorner', 'officeLeft'];
// easthall, eastcorner, and officeRight removed from cameraRoomOrder to delete their cameras
function getCurrentCameraIndex() {
for (var i = 0; i < cameraRoomOrder.length; i++) {
if (cameraRoomOrder[i] === currentCamera) return i;
}
return 0;
}
// Set up camera button
cameraToggleBtn = LK.getAsset('cameraButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2200
});
game.addChild(cameraToggleBtn);
var cameraLabel = new Text2("CAMERAS", {
size: 30,
fill: 0xFFFFFF
});
cameraLabel.anchor.set(0.5, 0.5);
cameraToggleBtn.addChild(cameraLabel);
// Set up power display
powerSystem.x = 150;
powerSystem.y = 150;
LK.gui.topLeft.addChild(powerSystem);
// Set up clock
clockDisplay = new Text2("12:00 AM", {
size: 60,
fill: 0xFFFFFF
});
clockDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(clockDisplay);
// --- Fullscreen Button ---
// Place at top right, but not overlapping nightDisplay (which is x = -150 from right edge)
var fullscreenBtn = LK.getAsset('fullscreenButton', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
// further left from nightDisplay
y: 80,
width: 120,
height: 120,
alpha: 0.8
});
LK.gui.topRight.addChild(fullscreenBtn);
var fullscreenLabel = new Text2("⛶", {
size: 60,
fill: 0xffffff
});
fullscreenLabel.anchor.set(0.5, 0.5);
fullscreenBtn.addChild(fullscreenLabel);
// Only show if not already fullscreen
fullscreenBtn.visible = !LK.isFullscreen || !LK.isFullscreen();
// Handler to enter fullscreen
fullscreenBtn.down = function () {
if (LK.requestFullscreen) {
LK.requestFullscreen();
}
// Optionally hide the button after entering fullscreen
fullscreenBtn.visible = false;
};
// Set up night display
nightDisplay = new Text2("NIGHT " + currentNight, {
size: 60,
fill: 0xFFFFFF
});
nightDisplay.anchor.set(1, 0);
nightDisplay.x = -150;
LK.gui.topRight.addChild(nightDisplay);
// Night overlay for transitions
var nightOverlay = LK.getAsset('nightOverlay', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 1
});
game.addChild(nightOverlay);
// Initialize animatronics based on current night
function setupAnimatronics() {
animatronics = [];
// Clear any existing animatronics
for (var i = 0; i < animatronics.length; i++) {
if (animatronics[i].parent) {
animatronics[i].parent.removeChild(animatronics[i]);
}
}
// All animatronics start on the stage (except Foxy)
// Difficulty affects aggressiveness
var baseAggressiveness;
if (typeof selectedDifficulty === "undefined" || selectedDifficulty === "easy") {
baseAggressiveness = 5 + currentNight * 5;
} else {
baseAggressiveness = 15 + currentNight * 8;
}
// Define animatronic turn order (farthest to closest)
var animatronicOrder = [];
animatronicOrder.push({
id: 'freddy',
start: 'stage',
aggr: baseAggressiveness
});
if (currentNight >= 2) {
animatronicOrder.push({
id: 'bonnie',
start: 'stage',
aggr: baseAggressiveness + 5
});
}
if (currentNight >= 3) {
animatronicOrder.push({
id: 'chica',
start: 'stage',
aggr: baseAggressiveness + 2
});
}
if (currentNight >= 4) {
animatronicOrder.push({
id: 'foxy',
start: 'westHall',
aggr: baseAggressiveness + 10
});
}
// Create animatronics in order
for (var i = 0; i < animatronicOrder.length; i++) {
var a = animatronicOrder[i];
animatronics.push(new Animatronic(a.id, a.start, a.aggr));
}
// Track whose turn it is to move
animatronicTurnIndex = 0;
}
// Function to start a new night
function startNight() {
// Reset game state
gameTime = 0;
cameraSystemActive = false;
currentCamera = 'stage';
animatronicMoved = false;
gameOver = false;
powerOutTriggered = false;
// Difficulty is already set by menu, nothing to do here
// Reset doors
doors.left.closed = false;
doors.right.closed = false;
doors.left.toggleDoor();
doors.left.toggleDoor();
doors.right.toggleDoor();
doors.right.toggleDoor();
// Reset power
powerSystem.powerLevel = 100;
powerSystem.powerUsage = 1;
powerSystem.updateUsageDisplay();
// Setup security cameras
securityMonitor.setup();
// Setup animatronics
setupAnimatronics();
// Update display
nightDisplay.setText("NIGHT " + currentNight);
// Fade in
tween(nightOverlay, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeIn
});
// Play ambient sounds
LK.playMusic('ambientMusic', {
loop: true
});
LK.getSound('ambient').play();
}
// Function to toggle camera system
function toggleCameraSystem() {
cameraSystemActive = !cameraSystemActive;
if (cameraSystemActive) {
// Show camera system
securityMonitor.visible = true;
cameraToggleBtn.tint = 0xff0000;
// Use more power
increasePowerUsage();
// Play sound
LK.getSound('camSwitch').play();
} else {
// Hide camera system
securityMonitor.visible = false;
cameraToggleBtn.tint = 0x990000;
// Use less power
decreasePowerUsage();
// Play sound
LK.getSound('camSwitch').play();
}
}
// Function to switch camera views
function switchCamera(roomId) {
// Always allow switching to any valid camera, including the first one
if (cameras[roomId]) {
// Deactivate all cameras first to prevent multiple active states
for (var camKey in cameras) {
if (cameras.hasOwnProperty(camKey)) {
cameras[camKey].deactivate();
}
}
securityMonitor.switchCamera(roomId);
currentCamera = roomId;
// Play sound
LK.getSound('camSwitch').play();
}
}
// Function to increase power usage
function increasePowerUsage() {
powerSystem.powerUsage++;
powerSystem.updateUsageDisplay();
}
// Function to decrease power usage
function decreasePowerUsage() {
if (powerSystem.powerUsage > 1) {
powerSystem.powerUsage--;
powerSystem.updateUsageDisplay();
}
}
// Function to handle power outage
function powerOut() {
if (powerOutTriggered) return;
powerOutTriggered = true;
// Turn off all systems
securityMonitor.visible = false;
cameraSystemActive = false;
// Open all doors
if (doors.left.closed) doors.left.toggleDoor();
if (doors.right.closed) doors.right.toggleDoor();
// Play power down sound
LK.getSound('powerDown').play();
// Game over with slight delay (for tension)
LK.setTimeout(function () {
triggerJumpscare('freddy');
}, 5000);
}
// Function to trigger jumpscare
function triggerJumpscare(animatronicId) {
if (gameOver) return;
gameOver = true;
// Play jumpscare sound
LK.getSound('jumpscare').play();
// Flash screen red
LK.effects.flashScreen(0xff0000, 500);
// --- Jumpscare image and animation ---
var jumpscareImg = LK.getAsset('animatronic', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 1200,
height: 1200,
alpha: 0
});
game.addChild(jumpscareImg);
// Terrifying GAME OVER text
var gameOverText = new Text2("GAME OVER", {
size: 200,
fill: 0xff0000,
font: "Impact, 'Arial Black', Tahoma"
});
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2 + 500;
gameOverText.alpha = 0;
game.addChild(gameOverText);
// Animate: fade in and scale up for a terrifying effect
jumpscareImg.scaleX = 1;
jumpscareImg.scaleY = 1;
tween(jumpscareImg, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 350,
easing: tween.easeIn,
onFinish: function onFinish() {
// Hold for a moment, then fade in GAME OVER text and fade out jumpscare
tween(gameOverText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
// Fade out jumpscare image, keep GAME OVER text for a bit
tween(jumpscareImg, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (jumpscareImg.parent) jumpscareImg.parent.removeChild(jumpscareImg);
// Hold GAME OVER text, then fade out and show LK game over
tween(gameOverText, {
alpha: 0
}, {
duration: 800,
delay: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
if (gameOverText.parent) gameOverText.parent.removeChild(gameOverText);
LK.showGameOver();
}
});
}
});
}
});
}
});
}
// Function to complete the night successfully
function completeNight() {
// Update stored progress
if (currentNight >= storage.highestNight) {
storage.highestNight = currentNight + 1;
}
currentNight++;
storage.currentNight = currentNight;
// Show win screen
LK.showYouWin();
}
// Events for camera toggle button
cameraToggleBtn.down = function () {
toggleCameraSystem();
};
// Update game time and clock display
function updateClock() {
var hour = Math.floor(gameTime / 60) + 12;
if (hour > 12) hour -= 12;
var timeString = hour + ":00 AM";
clockDisplay.setText(timeString);
// Check if night is complete
if (gameTime >= nightDuration) {
completeNight();
}
}
// Main game update function
game.update = function () {
if (nightOverlay.alpha > 0) return; // Don't update while fading in
// Update game time (every half second, so time passes 2x faster)
if (LK.ticks % 30 === 0) {
gameTime++;
updateClock();
}
// Update power system
powerSystem.update();
// Animatronics take turns moving, from farthest to closest (one per update cycle)
if (typeof animatronicTurnIndex === "undefined") {
animatronicTurnIndex = 0;
}
if (animatronics.length > 0) {
// Only one animatronic moves per update
animatronics[animatronicTurnIndex].update();
animatronicTurnIndex++;
if (animatronicTurnIndex >= animatronics.length) {
animatronicTurnIndex = 0;
}
}
// Update camera feed if an animatronic moved
if (animatronicMoved) {
animatronicMoved = false;
securityMonitor.updateCameras();
}
};
// --- Main Menu Overlay ---
var mainMenuOverlay = new Container();
mainMenuOverlay.x = 0;
mainMenuOverlay.y = 0;
mainMenuOverlay.width = 2048;
mainMenuOverlay.height = 2732;
mainMenuOverlay.visible = true;
// Dimmed background
var menuBg = mainMenuOverlay.attachAsset('nightOverlay', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732,
alpha: 0.85
});
mainMenuOverlay.addChild(menuBg);
// Game Title
var titleText = new Text2("FNAF FRVR", {
size: 180,
fill: 0xffcc00,
font: "Impact, 'Arial Black', Tahoma"
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 700;
mainMenuOverlay.addChild(titleText);
// --- Difficulty Buttons (only on main menu) ---
var selectedDifficulty = "easy";
var easyBtn = LK.getAsset('easyButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 250,
y: 1050,
width: 300,
height: 120,
alpha: 0.95
});
mainMenuOverlay.addChild(easyBtn);
var easyLabel = new Text2("EASY", {
size: 60,
fill: 0xffffff,
font: "Impact, 'Arial Black', Tahoma"
});
easyLabel.anchor.set(0.5, 0.5);
easyBtn.addChild(easyLabel);
var hardBtn = LK.getAsset('hardButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 250,
y: 1050,
width: 300,
height: 120,
alpha: 0.95
});
mainMenuOverlay.addChild(hardBtn);
var hardLabel = new Text2("HARD", {
size: 60,
fill: 0xffffff,
font: "Impact, 'Arial Black', Tahoma"
});
hardLabel.anchor.set(0.5, 0.5);
hardBtn.addChild(hardLabel);
function updateDifficultyButtons() {
if (selectedDifficulty === "easy") {
easyBtn.tint = 0x00ff00;
hardBtn.tint = 0xcc0000;
} else {
easyBtn.tint = 0x00cc00;
hardBtn.tint = 0xff2222;
}
}
easyBtn.down = function () {
selectedDifficulty = "easy";
updateDifficultyButtons();
};
hardBtn.down = function () {
selectedDifficulty = "hard";
updateDifficultyButtons();
};
updateDifficultyButtons();
// Start Button
var startBtn = LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1200,
width: 400,
height: 200,
alpha: 0.95
});
mainMenuOverlay.addChild(startBtn);
var startLabel = new Text2("START", {
size: 90,
fill: 0xffffff,
font: "Impact, 'Arial Black', Tahoma"
});
startLabel.anchor.set(0.5, 0.5);
startBtn.addChild(startLabel);
// Optionally: Instructions
var instrText = new Text2("Kapılardan hayatta kal!\nKameraları kullan, kapıları kapat, gücünü idare et.", {
size: 48,
fill: 0xffffff,
font: "Tahoma"
});
instrText.anchor.set(0.5, 0);
instrText.x = 2048 / 2;
instrText.y = 1450;
mainMenuOverlay.addChild(instrText);
// Add overlay to game
game.addChild(mainMenuOverlay);
// Disable all game UI until menu is dismissed
function showMainMenu() {
mainMenuOverlay.visible = true;
// Hide night overlay in main menu
if (typeof nightOverlay !== "undefined" && nightOverlay) nightOverlay.visible = false;
// Reset difficulty to easy by default
selectedDifficulty = "easy";
if (typeof updateDifficultyButtons === "function") updateDifficultyButtons();
// Optionally hide other UI
securityMonitor.visible = false;
cameraToggleBtn.visible = false;
powerSystem.visible = false;
clockDisplay.visible = false;
nightDisplay.visible = false;
fullscreenBtn.visible = false;
if (typeof leftArrow !== "undefined" && leftArrow) leftArrow.visible = false;
if (typeof rightArrow !== "undefined" && rightArrow) rightArrow.visible = false;
if (typeof upArrow !== "undefined" && upArrow) upArrow.visible = false;
if (typeof downArrow !== "undefined" && downArrow) downArrow.visible = false;
if (typeof playerDot !== "undefined" && playerDot) playerDot.visible = false;
if (typeof officeFull !== "undefined" && officeFull) officeFull.visible = false;
if (typeof doors !== "undefined" && doors.left) doors.left.visible = false;
if (typeof doors !== "undefined" && doors.right) doors.right.visible = false;
}
function hideMainMenu() {
mainMenuOverlay.visible = false;
// Show night overlay when game starts
if (typeof nightOverlay !== "undefined" && nightOverlay) nightOverlay.visible = true;
// Show UI
securityMonitor.visible = false;
cameraToggleBtn.visible = true;
powerSystem.visible = true;
clockDisplay.visible = true;
nightDisplay.visible = true;
fullscreenBtn.visible = !LK.isFullscreen || !LK.isFullscreen();
if (typeof leftArrow !== "undefined" && leftArrow) leftArrow.visible = true;
if (typeof rightArrow !== "undefined" && rightArrow) rightArrow.visible = true;
if (typeof upArrow !== "undefined" && upArrow) upArrow.visible = true;
if (typeof downArrow !== "undefined" && downArrow) downArrow.visible = true;
if (typeof playerDot !== "undefined" && playerDot) playerDot.visible = true;
if (typeof officeFull !== "undefined" && officeFull) officeFull.visible = true;
if (typeof doors !== "undefined" && doors.left) doors.left.visible = true;
if (typeof doors !== "undefined" && doors.right) doors.right.visible = true;
}
// Start game when start button is pressed
startBtn.down = function () {
hideMainMenu();
startNight();
};
// Show menu at launch
showMainMenu();
;
// --- On-screen Arrow Keys for Player Movement ---
// Arrow key asset sizes and positions
var arrowSize = 180;
var arrowAlpha = 0.7;
var arrowY = 2732 - 250;
var arrowXCenter = 2048 / 2;
var arrowSpacing = 220;
// Create arrow containers
var leftArrow = new Container();
var rightArrow = new Container();
var upArrow = new Container();
var downArrow = new Container();
// Add arrow graphics
var leftArrowGraphic = leftArrow.attachAsset('arrowLeft', {
anchorX: 0.5,
anchorY: 0.5,
width: arrowSize,
height: arrowSize,
alpha: arrowAlpha
});
var rightArrowGraphic = rightArrow.attachAsset('arrowRight', {
anchorX: 0.5,
anchorY: 0.5,
width: arrowSize,
height: arrowSize,
alpha: arrowAlpha
});
var upArrowGraphic = upArrow.attachAsset('arrowUp', {
anchorX: 0.5,
anchorY: 0.5,
width: arrowSize,
height: arrowSize,
alpha: arrowAlpha
});
var downArrowGraphic = downArrow.attachAsset('arrowDown', {
anchorX: 0.5,
anchorY: 0.5,
width: arrowSize,
height: arrowSize,
alpha: arrowAlpha
});
// Add arrow labels
var leftLabel = new Text2("◀", {
size: 100,
fill: 0xFFFFFF
});
leftLabel.anchor.set(0.5, 0.5);
leftArrow.addChild(leftLabel);
var rightLabel = new Text2("▶", {
size: 100,
fill: 0xFFFFFF
});
rightLabel.anchor.set(0.5, 0.5);
rightArrow.addChild(rightLabel);
var upLabel = new Text2("▲", {
size: 100,
fill: 0xFFFFFF
});
upLabel.anchor.set(0.5, 0.5);
upArrow.addChild(upLabel);
var downLabel = new Text2("▼", {
size: 100,
fill: 0xFFFFFF
});
downLabel.anchor.set(0.5, 0.5);
downArrow.addChild(downLabel);
// Position arrows (bottom center, spaced out)
leftArrow.x = arrowXCenter - arrowSpacing;
leftArrow.y = arrowY;
rightArrow.x = arrowXCenter + arrowSpacing;
rightArrow.y = arrowY;
upArrow.x = arrowXCenter;
upArrow.y = arrowY - arrowSpacing;
downArrow.x = arrowXCenter;
downArrow.y = arrowY + arrowSpacing / 1.5;
// Add to game
game.addChild(leftArrow);
game.addChild(rightArrow);
game.addChild(upArrow);
game.addChild(downArrow);
// Hide arrows initially (main menu is visible at start)
leftArrow.visible = false;
rightArrow.visible = false;
upArrow.visible = false;
downArrow.visible = false;
// --- Player movement logic ---
// Define player position in the office (for demo, just a dot in the office)
if (typeof playerPos === "undefined") {
var playerPos = {
x: 2048 / 2,
y: 1800
};
}
if (typeof playerDot === "undefined") {
var playerDot = new Container();
var characterGraphic = playerDot.attachAsset('playerCharacter', {
anchorX: 0.5,
anchorY: 0.5,
width: 120,
height: 120,
alpha: 1
});
playerDot.x = playerPos.x;
playerDot.y = playerPos.y;
game.addChild(playerDot);
}
// Movement boundaries (keep player in office area)
var minX = 300 + 80,
maxX = 1748 - 80;
var minY = 1200 + 80,
maxY = 1200 + 600 - 80;
// Move player and update dot position
function movePlayer(dx, dy) {
playerPos.x += dx;
playerPos.y += dy;
// Clamp to bounds
if (playerPos.x < minX) playerPos.x = minX;
if (playerPos.x > maxX) playerPos.x = maxX;
if (playerPos.y < minY) playerPos.y = minY;
if (playerPos.y > maxY) playerPos.y = maxY;
playerDot.x = playerPos.x;
playerDot.y = playerPos.y;
// --- Animatronic comes to the door when player arrives ---
// Define door trigger areas (left and right)
var doorTriggerYMin = 1200 + 200;
var doorTriggerYMax = 1200 + 600 - 200;
var leftDoorX = 300;
var rightDoorX = 1748;
var doorTriggerDist = 100;
// Check if player is at left door
if (playerPos.x >= leftDoorX - doorTriggerDist && playerPos.x <= leftDoorX + doorTriggerDist && playerPos.y >= doorTriggerYMin && playerPos.y <= doorTriggerYMax) {
// Play scary sound before animatronic comes to the door
LK.getSound('warning').play();
// Move a random animatronic to officeLeft if not already there
for (var i = 0; i < animatronics.length; i++) {
if (animatronics[i].currentRoom !== 'officeLeft') {
animatronics[i].currentRoom = 'officeLeft';
animatronicMoved = true;
// Play BearCame sound when animatronic comes to the door (left)
LK.getSound('BearCame').play();
// Start 5-second timer for player to close the left door
if (typeof animatronicAttackTimeouts === "undefined") animatronicAttackTimeouts = {};
if (animatronicAttackTimeouts['left']) {
LK.clearTimeout(animatronicAttackTimeouts['left']);
}
// Mark animatronic as attacking at left
if (typeof animatronicAttacking === "undefined") animatronicAttacking = {};
animatronicAttacking['left'] = true;
animatronicAttackTimeouts['left'] = LK.setTimeout(function () {
// If door is not closed after 5 seconds, trigger jumpscare
if (!doors.left.closed && animatronicAttacking['left']) {
triggerJumpscare(animatronics[i].id);
}
animatronicAttacking['left'] = false;
animatronicAttackTimeouts['left'] = null;
}, 5000);
break;
}
}
}
// Check if player is at right door
if (playerPos.x >= rightDoorX - doorTriggerDist && playerPos.x <= rightDoorX + doorTriggerDist && playerPos.y >= doorTriggerYMin && playerPos.y <= doorTriggerYMax) {
// Play scary sound before animatronic comes to the door
LK.getSound('warning').play();
// Move a random animatronic to officeRight if not already there
for (var i = 0; i < animatronics.length; i++) {
if (animatronics[i].currentRoom !== 'officeRight') {
animatronics[i].currentRoom = 'officeRight';
animatronicMoved = true;
// Play BearCame sound when animatronic comes to the door (right)
LK.getSound('BearCame').play();
// Start 5-second timer for player to close the right door
if (typeof animatronicAttackTimeouts === "undefined") animatronicAttackTimeouts = {};
if (animatronicAttackTimeouts['right']) {
LK.clearTimeout(animatronicAttackTimeouts['right']);
}
// Mark animatronic as attacking at right
if (typeof animatronicAttacking === "undefined") animatronicAttacking = {};
animatronicAttacking['right'] = true;
animatronicAttackTimeouts['right'] = LK.setTimeout(function () {
// If door is not closed after 5 seconds, trigger jumpscare
if (!doors.right.closed && animatronicAttacking['right']) {
triggerJumpscare(animatronics[i].id);
}
animatronicAttacking['right'] = false;
animatronicAttackTimeouts['right'] = null;
}, 5000);
break;
}
}
}
}
// Arrow key event handlers
leftArrow.down = function () {
movePlayer(-100, 0);
};
rightArrow.down = function () {
movePlayer(100, 0);
};
upArrow.down = function () {
movePlayer(0, -100);
};
downArrow.down = function () {
movePlayer(0, 100);
}; ===================================================================
--- original.js
+++ change.js
@@ -293,12 +293,16 @@
// --- BearCame sound logic for animatronic waiting in officeLeft/officeRight ---
// Only for officeLeft or officeRight, and only if animatronic has been there for 5 seconds
if (self.roomId === 'officeLeft' || self.roomId === 'officeRight') {
if (!animatronics[i].waitTimer) animatronics[i].waitTimer = 0;
+ // Play BearCame sound immediately when animatronic starts waiting in front of office
+ if (animatronics[i].waitTimer === 0) {
+ LK.getSound('BearCame').play();
+ }
animatronics[i].waitTimer++;
// 5 seconds = 5*60 = 300 frames
if (animatronics[i].waitTimer === 300) {
- LK.getSound('BearCame').play();
+ // (No need to play BearCame here anymore, already played at waitTimer === 0)
}
} else {
// Reset waitTimer if not in front of office
animatronics[i].waitTimer = 0;
A terrifying very big animatronic.. In-Game asset. 2d. High contrast. No shadows
It says Night 1. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
make a red door open and close button. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
nothing. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Bana bir ofis odası yap. Biraz gerilim salan ama içinde canavar olmayan eski bir karanlık güvenlik ofis odası gibi olsun. In-Game asset. 2d. High contrast. No shadows
A 30-something security guard in a purple uniform, looking tired and vengeful.. In-Game asset. 2d. High contrast. No shadows