User prompt
Animatronik kulaklarını kaldır
User prompt
Kafayı biraz küçültüp yukarı çıkar
User prompt
Karıncalanma efektini tekrar düzenle
User prompt
Karıncalanma efektini geri düzenle ve karıncalanmada renk değişimi olmasın
User prompt
Çene animatronik kafasının arkasında dursun
User prompt
Gözleri ve burnunu kaldır
User prompt
Please fix the bug: 'ReferenceError: eyeL is not defined' in or related to this line: 'eyeL.x = 250 + headTilt * 10;' Line Number: 74
User prompt
Please fix the bug: 'ReferenceError: earL is not defined' in or related to this line: 'earL.rotation = headTilt * 0.10;' Line Number: 57
User prompt
Gözü burnunu ve kulakları kaldır
User prompt
Çene kafa modelinin arkasında dursun
User prompt
Animatroniği biraz yukarı çıkar
User prompt
Animatroniği ortala ve boyutunu iki katına çıkar
User prompt
Oyuna başladığımızda animatronik görükmesin
Code edit (1 edits merged)
Please save this source code
User prompt
FNAF: GECE VARDİYASI
Initial prompt
Bana bir fnaf fan oyunu yap. Oyunda ana menü olmalı. Yukarıda oyunun ismi büyük harflerle yazılmalı altında ise yeni oyun ve devam et yazmalı sadece yazı olacak ama arkada bir görsel olmamalı. Ekranda vhs kaseti gibi hafif bir karıncalanma efekti olmalı. Ekranın aşağısında karıncalanmanın ardında ise ekranın yüzde kırkını kaplayan oynak bir animatronik olmalı ağzını açıp kapamalı kafasını falan eğmeli ama animasyonsuz. Düz bakışı biraz uzun sürmeli diğer duruşları karelik şekilde glitch gibi anlık gelmeli . Oyun için ise başlat butonuna basınca başlamalı. Ve ekranda ani bir parlayıp biraz daha yavaş bi şekilde sönen yazı olmalı. Saati ve günü söylemeli. 12 ÖS ve hangi gecedeysek mesela üçüncü gecedeyiz: GECE 3 :12 Ö.S. demeli. Şu anlık test amaçlı oyun başladığında geceyi bitirmesi gereken bir tuş olmalı bastığımızda ise ekranda 06:00 yazmalı ve sonra ana menüye dönmeliyiz. Devam et tuşunun yanında daha küçük harflerle bir sonraki geceyi söylemeli. Ana menüdeki yazılar beyaz renk olmalı. Animatroniğin çenesi olmalı
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Animatronic class
var Animatronic = Container.expand(function () {
var self = Container.call(this);
// Add animatronic body (behind jaw and head)
var body = self.attachAsset('animatronicBody', {
anchorX: 0.5,
anchorY: 0,
x: 350,
y: 570
});
// Jaw (behind head)
var jaw = self.attachAsset('animatronicJaw', {
anchorX: 0.5,
anchorY: 0,
x: 350,
y: 400
});
// Head (in front of jaw)
var head = self.attachAsset('animatronicHead', {
anchorX: 0.5,
anchorY: 0.5,
x: 350,
y: 250
});
// (Eyes, pupils, and nose removed)
// State
self.jawOpen = 0; // 0 closed, 1 open
self.headTilt = 0; // -1 left, 0 center, 1 right
self.glitchTimer = 0;
self.glitching = false;
self.glitchState = 0;
self.glitchDuration = 0;
self.glitchCooldown = 0;
// Helper: set pose
self.setPose = function (jawOpen, headTilt) {
self.jawOpen = jawOpen;
self.headTilt = headTilt;
// Jaw open/close
jaw.y = 400 + 60 * jawOpen;
// Head tilt
head.rotation = headTilt * 0.12;
// (Ears removed)
// (Eyes, pupils, and nose removed)
};
// Helper: set pupils offset (for glitch)
self.setPupilOffset = function (dx, dy) {
// (Pupil offset removed)
};
// Helper: set head position offset (for glitch)
self.setHeadOffset = function (dx, dy) {
self.x = self.baseX + dx;
self.y = self.baseY + dy;
};
// Helper: reset all offsets
self.resetOffsets = function () {
self.setHeadOffset(0, 0);
};
// Animate jaw open/close
self.animateJaw = function (open) {
tween(self, {
jawOpen: open
}, {
duration: 180,
easing: tween.cubicInOut
});
};
// Animate head tilt
self.animateTilt = function (target) {
tween(self, {
headTilt: target
}, {
duration: 220,
easing: tween.cubicInOut
});
};
// Glitch effect: random pose, random offset, short duration
self.triggerGlitch = function () {
self.glitching = true;
self.glitchState = Math.floor(Math.random() * 3);
self.glitchDuration = 6 + Math.floor(Math.random() * 6); // 6-12 frames
self.glitchCooldown = 30 + Math.floor(Math.random() * 60); // 0.5-1.5s
// Random pose
var jaw = Math.random() > 0.5 ? 1 : 0;
var tilt = [-1, 0, 1][Math.floor(Math.random() * 3)];
self.setPose(jaw, tilt);
// Random offset
var dx = -10 + Math.random() * 20;
var dy = -10 + Math.random() * 20;
self.setHeadOffset(dx, dy);
// (Random pupils removed)
};
// Update
self.update = function () {
// Animate jaw and tilt
self.setPose(self.jawOpen, self.headTilt);
// Glitch logic
if (self.glitching) {
self.glitchDuration--;
if (self.glitchDuration <= 0) {
self.glitching = false;
self.resetOffsets();
}
} else {
self.glitchCooldown--;
if (self.glitchCooldown <= 0) {
self.triggerGlitch();
}
}
};
// For centering
self.baseX = 0;
self.baseY = 0;
return self;
});
// Button class
var MenuButton = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('buttonRect', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
bg.alpha = 0.0;
self.label = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
self.label.anchor.set(0.5, 0.5);
self.addChild(self.label);
self.setText = function (txt) {
self.label.setText(txt);
};
self.setActive = function (active) {
bg.alpha = 0.0;
self.label.alpha = active ? 1 : 0.7;
};
return self;
});
// VHS Static overlay class
var VHSStatic = Container.expand(function () {
var self = Container.call(this);
var staticNode = self.attachAsset('vhsStatic', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
staticNode.alpha = 0.08;
// Add horizontal noise lines
var noiseLines = [];
for (var i = 0; i < 8; i++) {
var line = self.attachAsset('vhsStatic', {
anchorX: 0,
anchorY: 0,
x: 0,
y: Math.random() * 2732,
width: 2048,
height: 8,
color: 0xffffff
});
line.alpha = 0.08 + Math.random() * 0.10;
noiseLines.push(line);
}
self.update = function () {
// Animate static flicker
staticNode.alpha = 0.06 + Math.random() * 0.10;
// Animate noise lines: randomize y and alpha for each line
for (var i = 0; i < noiseLines.length; i++) {
var line = noiseLines[i];
// Move line vertically, wrap around
line.y += 32 + Math.random() * 32;
if (line.y > 2732) line.y = -8;
// Flicker alpha
line.alpha = 0.08 + Math.random() * 0.12;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Button shape
// VHS static overlay
// Animatronic nose
// Animatronic right ear
// Animatronic left ear
// Animatronic right pupil
// Animatronic left pupil
// Animatronic right eye
// Animatronic left eye
// Animatronic jaw
// Animatronic body (main head)
// Game state
var STATE_MENU = 0;
var STATE_PLAY = 1;
var STATE_NIGHTEND = 2;
var state = STATE_MENU;
// Night and hour
var currentNight = 1;
var currentHour = 12;
// Animatronic
var animatronic = new Animatronic();
// Kuklanın tüm parçalarını biraz küçült ve daha yukarı taşı
var animatronicScale = 1.25; // daha küçük
// Head asset is 700px wide, 500px tall, so center based on that
animatronic.baseX = 2048 / 2 - 700 * animatronicScale / 2;
// Daha yukarı taşı: 420 yerine 700 px yukarıda
animatronic.baseY = 2732 - 500 * animatronicScale - 700;
animatronic.x = animatronic.baseX;
animatronic.y = animatronic.baseY;
animatronic.scaleX = animatronicScale;
animatronic.scaleY = animatronicScale;
game.addChild(animatronic);
// VHS static overlay
var vhsStatic = new VHSStatic();
game.addChild(vhsStatic);
// Menu UI
var titleText = new Text2('', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 220;
// Set initial title text to English regardless of language
titleText.setText('FNAF : FINISH THE NIGHT');
var btnNewGame = new MenuButton();
btnNewGame.x = 2048 / 2;
btnNewGame.y = 600;
btnNewGame.setText('YENİ OYUN');
var btnContinue = new MenuButton();
btnContinue.x = 2048 / 2;
btnContinue.y = 800;
btnContinue.setText('DEVAM ET');
// Leaderboard button
var btnLeaderboard = new MenuButton();
// Move to left side, but not in the top left 100x100 area (avoid platform menu)
// Place at x=400, y=1000 (moved right from 200 to 400)
btnLeaderboard.x = 400;
btnLeaderboard.y = 1000;
btnLeaderboard.setText('SKOR TABLOSU');
// Language select button (now below continue)
var btnLang = new MenuButton();
btnLang.x = 2048 / 2;
// Calculate vertical gap between continue and new game buttons
var menuButtonGap = btnContinue.y - btnNewGame.y;
// Place language button the same gap below continue button
btnLang.y = btnContinue.y + menuButtonGap;
btnLang.setText('DİL: Türkçe');
var continueNightText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
continueNightText.anchor.set(0, 0.5);
continueNightText.x = btnContinue.x + 380;
continueNightText.y = btnContinue.y;
// Leaderboard UI
var leaderboardText = new Text2('', {
size: 60,
fill: 0xFFFF00
});
leaderboardText.anchor.set(0.5, 0);
leaderboardText.x = 2048 / 2;
leaderboardText.y = 300;
leaderboardText.visible = false;
// Leaderboard close button
var btnLeaderboardClose = new MenuButton();
btnLeaderboardClose.x = 2048 / 2;
btnLeaderboardClose.y = 2200;
btnLeaderboardClose.setText('KAPAT');
btnLeaderboardClose.visible = false;
// Menu selection
var menuSelected = 0; // 0: new game, 1: continue
// Night info UI
var nightText = new Text2('', {
size: 110,
fill: 0xFFFFFF
});
nightText.anchor.set(0.5, 0.5);
nightText.x = 2048 / 2;
nightText.y = 400;
nightText.alpha = 0;
var hourText = new Text2('', {
size: 90,
fill: 0xFFFFFF
});
hourText.anchor.set(0.5, 0.5);
hourText.x = 2048 / 2;
hourText.y = 540;
hourText.alpha = 0;
// Test: End night button
var btnEndNight = new MenuButton();
btnEndNight.x = 2048 / 2;
btnEndNight.y = 1200;
btnEndNight.setText('GECEYİ BİTİR');
btnEndNight.visible = false;
// 6:00 screen
var sixText = new Text2('06:00', {
size: 180,
fill: 0xFFFFFF
});
sixText.anchor.set(0.5, 0.5);
sixText.x = 2048 / 2;
sixText.y = 700;
sixText.alpha = 0;
// Add menu UI to game
game.addChild(titleText);
game.addChild(btnNewGame);
game.addChild(btnContinue);
game.addChild(btnLeaderboard);
game.addChild(btnLang);
game.addChild(continueNightText);
game.addChild(leaderboardText);
game.addChild(btnLeaderboardClose);
// Leaderboard storage setup
var leaderboard = storage; // Use storage as leaderboard for getTop/submit
// Leaderboard button logic
btnLeaderboard.down = function (x, y, obj) {
// Show leaderboard UI, but do NOT auto-close after click
titleText.visible = false;
btnNewGame.visible = false;
btnContinue.visible = false;
btnLeaderboard.visible = false;
btnLang.visible = false;
continueNightText.visible = false;
leaderboardText.visible = true;
btnLeaderboardClose.visible = true;
// Fetch and show leaderboard (sadece en yüksek skor gösterilecek)
var text = languages[currentLangIndex].code === 'en' ? 'LEADERBOARD\n' : 'SKOR TABLOSU\n';
var leaderboardFlat = storage.leaderboardEntries || [];
if (leaderboardFlat.length < 2 || typeof leaderboardFlat[1] !== "number" || leaderboardFlat[1] === 0) {
// No score yet, show "Gece içinde" or "Night in progress"
text += languages[currentLangIndex].code === 'en' ? 'Night in progress' : 'Gece içinde';
} else {
var name = typeof leaderboardFlat[0] === "string" ? leaderboardFlat[0] : "Anonim";
var score = leaderboardFlat[1];
text += '1. ' + name + ' - ' + score + '\n';
}
leaderboardText.setText(text);
// Do not close leaderboard automatically; user must press KAPAT
// (No code here to auto-close or hide leaderboard)
};
// Leaderboard close button logic
btnLeaderboardClose.down = function (x, y, obj) {
leaderboardText.visible = false;
btnLeaderboardClose.visible = false;
showMenu();
};
// Add night info and test UI
game.addChild(nightText);
game.addChild(hourText);
game.addChild(btnEndNight);
game.addChild(sixText);
// Hide all except menu
function showMenu() {
state = STATE_MENU;
titleText.visible = true;
btnNewGame.visible = true;
btnLang.visible = true;
btnContinue.visible = true;
btnLeaderboard.visible = true;
continueNightText.visible = true;
nightText.visible = false;
hourText.visible = false;
btnEndNight.visible = false;
sixText.visible = false;
menuSelected = 0;
btnNewGame.setActive(true);
btnContinue.setActive(false);
updateContinueNight();
// Set menu button texts to correct language
if (languages[currentLangIndex].code === 'en') {
// titleText.setText('FNAF : FINISH THE NIGHT');
btnNewGame.setText('NEW GAME');
btnContinue.setText('CONTINUE');
btnEndNight.setText('FINISH NIGHT');
} else {
// titleText.setText('FNAF : GECEYİ BİTİR');
btnNewGame.setText('YENİ OYUN');
btnContinue.setText('DEVAM ET');
btnEndNight.setText('GECEYİ BİTİR');
}
// Do not change titleText here; always English
// Show animatronic in menu
animatronic.visible = true;
// Show VHS static overlay in menu
vhsStatic.visible = true;
// Play looping menu music
LK.playMusic('musicId', {
loop: true
});
}
function showNight() {
state = STATE_PLAY;
titleText.visible = false;
btnNewGame.visible = false;
btnLang.visible = false;
btnContinue.visible = false;
continueNightText.visible = false;
btnLeaderboard.visible = false;
nightText.visible = true;
hourText.visible = true;
btnEndNight.visible = true;
sixText.visible = false;
// Hide VHS static overlay during gameplay
vhsStatic.visible = false;
// Stop menu music
LK.stopMusic();
// Set night and hour text
if (languages[currentLangIndex].code === 'en') {
nightText.setText('NIGHT ' + currentNight);
} else {
nightText.setText('GECE ' + currentNight);
}
hourText.setText(currentHour + ':00');
nightText.alpha = 0;
hourText.alpha = 0;
// Animate in
tween(nightText, {
alpha: 1
}, {
duration: 400,
easing: tween.cubicOut
});
tween(hourText, {
alpha: 1
}, {
duration: 400,
easing: tween.cubicOut
});
// Animatronic: look at player, jaw closed
animatronic.animateJaw(0);
animatronic.animateTilt(0);
// Hide animatronic during gameplay
animatronic.visible = false;
}
function showNightEnd() {
state = STATE_NIGHTEND;
titleText.visible = false;
btnNewGame.visible = false;
btnLang.visible = false;
btnContinue.visible = false;
continueNightText.visible = false;
btnLeaderboard.visible = false;
nightText.visible = false;
hourText.visible = false;
btnEndNight.visible = false;
sixText.visible = true;
sixText.alpha = 0;
// Hide VHS static overlay during night end
vhsStatic.visible = false;
// Stop menu music
LK.stopMusic();
tween(sixText, {
alpha: 1
}, {
duration: 600,
easing: tween.cubicOut
});
// Animatronic: jaw open, head tilt
animatronic.animateJaw(1);
animatronic.animateTilt(1);
// Hide animatronic in night end
animatronic.visible = false;
// Skoru leaderboard'a gönder (en yüksek gece)
// Sadece hesabın en yüksek skorunu sakla
var leaderboardFlat = storage.leaderboardEntries || [];
var maxScore = 0;
for (var i = 0; i < leaderboardFlat.length; i += 2) {
var score = typeof leaderboardFlat[i + 1] === "number" ? leaderboardFlat[i + 1] : 0;
if (score > maxScore) maxScore = score;
}
var newScore = currentNight - 1;
if (newScore > maxScore) {
// Replace with new high score
storage.leaderboardEntries = ['Anonim', newScore];
} else if (leaderboardFlat.length === 0) {
// No previous score, store this one
storage.leaderboardEntries = ['Anonim', newScore];
} else {
// Keep the previous high score
storage.leaderboardEntries = ['Anonim', maxScore];
}
// Geceyi geçince geceyi yükselt
currentNight += 1;
// Reduce waiting period for btnEndNight: -120ms per night until 6, then 40% reduction per night, min 500ms
if (currentNight <= 7) {
btnEndNightWaitPeriod = Math.max(500, btnEndNightWaitPeriod - 120);
} else {
btnEndNightWaitPeriod = Math.max(500, Math.floor(btnEndNightWaitPeriod * 0.6));
}
}
// Update continue night text
function updateContinueNight() {
continueNightText.setText('gece ' + currentNight);
}
// Menu button touch logic
btnNewGame.down = function (x, y, obj) {
menuSelected = 0;
btnNewGame.setActive(true);
btnContinue.setActive(false);
// Start new game
currentNight = 1;
currentHour = 12;
showNight();
};
// Language selection logic
var languages = [{
code: 'tr',
label: 'Türkçe'
}, {
code: 'en',
label: 'English'
}];
var currentLangIndex = 0;
btnLang.down = function (x, y, obj) {
currentLangIndex = (currentLangIndex + 1) % languages.length;
btnLang.setText('DİL: ' + languages[currentLangIndex].label);
// Update menu button texts based on language
if (languages[currentLangIndex].code === 'en') {
// titleText.setText('FNAF : FINISH THE NIGHT');
btnNewGame.setText('NEW GAME');
btnContinue.setText('CONTINUE');
btnEndNight.setText('FINISH NIGHT');
} else {
// titleText.setText('FNAF : GECEYİ BİTİR');
btnNewGame.setText('YENİ OYUN');
btnContinue.setText('DEVAM ET');
btnEndNight.setText('GECEYİ BİTİR');
}
// Do not change titleText here; always English
// Here you could add logic to update all UI text if you implement localization
};
btnContinue.down = function (x, y, obj) {
menuSelected = 1;
btnNewGame.setActive(false);
btnContinue.setActive(true);
// Continue game
currentHour = 12;
showNight();
};
// Track waiting state and timer for btnEndNight
var btnEndNightPressCount = 0;
var btnEndNightWaitTimeout = null;
var btnEndNightWaiting = false;
// Waiting period for btnEndNight (in ms), decreases each night, min 500ms
var btnEndNightWaitPeriod = 1200;
btnEndNight.down = function (x, y, obj) {
if (!btnEndNightWaiting) {
// First press: start waiting period
btnEndNightWaiting = true;
btnEndNightPressCount = 1;
// Start a timer (decreasing period)
btnEndNightWaitTimeout = LK.setTimeout(function () {
// If timer expires and no second press, trigger jump scare/game over
if (btnEndNightWaiting && btnEndNightPressCount === 1) {
// Play jump scare sound
var jumpscareSound = LK.getSound('jumpscare');
if (jumpscareSound) {
jumpscareSound.play();
} else {
// Defensive: always try to play jumpscare sound
var jumpscareSound2 = LK.getSound('jumpscare');
if (jumpscareSound2) jumpscareSound2.play();
}
// Flash screen red for 1 second to indicate death
LK.effects.flashScreen(0xff0000, 1000);
// Show animatronic jumpscare in the center of the screen
var jumpscareAnim = new Animatronic();
jumpscareAnim.baseX = 2048 / 2 - 700 * animatronicScale / 2;
jumpscareAnim.baseY = 2732 / 2 - 500 * animatronicScale / 2 - 100;
jumpscareAnim.x = jumpscareAnim.baseX;
jumpscareAnim.y = jumpscareAnim.baseY;
jumpscareAnim.scaleX = animatronicScale * 1.25;
jumpscareAnim.scaleY = animatronicScale * 1.25;
jumpscareAnim.visible = true;
game.addChild(jumpscareAnim);
// Animate jaw open and head forward for jumpscare
jumpscareAnim.animateJaw(1);
jumpscareAnim.animateTilt(0);
// Show localized game over text in the center of the screen
var gameOverText = new Text2(languages[currentLangIndex].code === 'en' ? 'GAME OVER' : 'OYUN BİTTİ', {
size: 220,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2 + 400;
game.addChild(gameOverText);
// After 1.2s, remove jumpscare and text, then return to menu (no extra 'Game Over'/'Oyun Bitti' text)
LK.setTimeout(function () {
if (gameOverText && gameOverText.parent) {
gameOverText.parent.removeChild(gameOverText);
}
if (jumpscareAnim && jumpscareAnim.parent) {
jumpscareAnim.parent.removeChild(jumpscareAnim);
}
showMenu();
// Reset for next night
currentNight = 1; // Gece sıfırla (reset nights on death)
btnEndNightPressCount = 0;
btnEndNightWaiting = false;
btnEndNightWaitTimeout = null;
}, 1200);
}
// Reset waiting state if not already reset
btnEndNightWaiting = false;
btnEndNightWaitTimeout = null;
}, 1200);
} else if (btnEndNightWaiting && btnEndNightPressCount === 1) {
// Second press during waiting: pass the night
btnEndNightPressCount = 2;
// Cancel the jump scare timer
if (btnEndNightWaitTimeout !== null) {
LK.clearTimeout(btnEndNightWaitTimeout);
btnEndNightWaitTimeout = null;
}
btnEndNightWaiting = false;
// End night, show 6:00
showNightEnd();
// After 2s, return to menu
LK.setTimeout(function () {
showMenu();
// Reset for next night
btnEndNightPressCount = 0;
}, 2000);
}
};
// Touch navigation for menu (disable all except button areas)
game.down = function (x, y, obj) {
// Only allow button interactions, do nothing here
return;
};
// Touch up: disable all except button areas
game.up = function (x, y, obj) {
// Only allow button interactions, do nothing here
return;
};
// Animate animatronic idle (jaw open/close, head tilt)
var animTimer = 0;
function animatronicIdleAnim() {
if (state !== STATE_MENU && state !== STATE_PLAY) return;
animTimer++;
if (animTimer % 90 === 0) {
// Open jaw
animatronic.animateJaw(1);
} else if (animTimer % 90 === 30) {
// Close jaw
animatronic.animateJaw(0);
}
if (animTimer % 180 === 0) {
// Tilt head randomly
var tilt = [-1, 0, 1][Math.floor(Math.random() * 3)];
animatronic.animateTilt(tilt);
}
}
// VHS static overlay always on top
game.children.sort(function (a, b) {
if (a === vhsStatic) return 1;
if (b === vhsStatic) return -1;
return 0;
});
// Main update
game.update = function () {
animatronic.update();
vhsStatic.update();
animatronicIdleAnim();
};
// Start at menu
showMenu(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Animatronic class
var Animatronic = Container.expand(function () {
var self = Container.call(this);
// Add animatronic body (behind jaw and head)
var body = self.attachAsset('animatronicBody', {
anchorX: 0.5,
anchorY: 0,
x: 350,
y: 570
});
// Jaw (behind head)
var jaw = self.attachAsset('animatronicJaw', {
anchorX: 0.5,
anchorY: 0,
x: 350,
y: 400
});
// Head (in front of jaw)
var head = self.attachAsset('animatronicHead', {
anchorX: 0.5,
anchorY: 0.5,
x: 350,
y: 250
});
// (Eyes, pupils, and nose removed)
// State
self.jawOpen = 0; // 0 closed, 1 open
self.headTilt = 0; // -1 left, 0 center, 1 right
self.glitchTimer = 0;
self.glitching = false;
self.glitchState = 0;
self.glitchDuration = 0;
self.glitchCooldown = 0;
// Helper: set pose
self.setPose = function (jawOpen, headTilt) {
self.jawOpen = jawOpen;
self.headTilt = headTilt;
// Jaw open/close
jaw.y = 400 + 60 * jawOpen;
// Head tilt
head.rotation = headTilt * 0.12;
// (Ears removed)
// (Eyes, pupils, and nose removed)
};
// Helper: set pupils offset (for glitch)
self.setPupilOffset = function (dx, dy) {
// (Pupil offset removed)
};
// Helper: set head position offset (for glitch)
self.setHeadOffset = function (dx, dy) {
self.x = self.baseX + dx;
self.y = self.baseY + dy;
};
// Helper: reset all offsets
self.resetOffsets = function () {
self.setHeadOffset(0, 0);
};
// Animate jaw open/close
self.animateJaw = function (open) {
tween(self, {
jawOpen: open
}, {
duration: 180,
easing: tween.cubicInOut
});
};
// Animate head tilt
self.animateTilt = function (target) {
tween(self, {
headTilt: target
}, {
duration: 220,
easing: tween.cubicInOut
});
};
// Glitch effect: random pose, random offset, short duration
self.triggerGlitch = function () {
self.glitching = true;
self.glitchState = Math.floor(Math.random() * 3);
self.glitchDuration = 6 + Math.floor(Math.random() * 6); // 6-12 frames
self.glitchCooldown = 30 + Math.floor(Math.random() * 60); // 0.5-1.5s
// Random pose
var jaw = Math.random() > 0.5 ? 1 : 0;
var tilt = [-1, 0, 1][Math.floor(Math.random() * 3)];
self.setPose(jaw, tilt);
// Random offset
var dx = -10 + Math.random() * 20;
var dy = -10 + Math.random() * 20;
self.setHeadOffset(dx, dy);
// (Random pupils removed)
};
// Update
self.update = function () {
// Animate jaw and tilt
self.setPose(self.jawOpen, self.headTilt);
// Glitch logic
if (self.glitching) {
self.glitchDuration--;
if (self.glitchDuration <= 0) {
self.glitching = false;
self.resetOffsets();
}
} else {
self.glitchCooldown--;
if (self.glitchCooldown <= 0) {
self.triggerGlitch();
}
}
};
// For centering
self.baseX = 0;
self.baseY = 0;
return self;
});
// Button class
var MenuButton = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('buttonRect', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
bg.alpha = 0.0;
self.label = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
self.label.anchor.set(0.5, 0.5);
self.addChild(self.label);
self.setText = function (txt) {
self.label.setText(txt);
};
self.setActive = function (active) {
bg.alpha = 0.0;
self.label.alpha = active ? 1 : 0.7;
};
return self;
});
// VHS Static overlay class
var VHSStatic = Container.expand(function () {
var self = Container.call(this);
var staticNode = self.attachAsset('vhsStatic', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
staticNode.alpha = 0.08;
// Add horizontal noise lines
var noiseLines = [];
for (var i = 0; i < 8; i++) {
var line = self.attachAsset('vhsStatic', {
anchorX: 0,
anchorY: 0,
x: 0,
y: Math.random() * 2732,
width: 2048,
height: 8,
color: 0xffffff
});
line.alpha = 0.08 + Math.random() * 0.10;
noiseLines.push(line);
}
self.update = function () {
// Animate static flicker
staticNode.alpha = 0.06 + Math.random() * 0.10;
// Animate noise lines: randomize y and alpha for each line
for (var i = 0; i < noiseLines.length; i++) {
var line = noiseLines[i];
// Move line vertically, wrap around
line.y += 32 + Math.random() * 32;
if (line.y > 2732) line.y = -8;
// Flicker alpha
line.alpha = 0.08 + Math.random() * 0.12;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Button shape
// VHS static overlay
// Animatronic nose
// Animatronic right ear
// Animatronic left ear
// Animatronic right pupil
// Animatronic left pupil
// Animatronic right eye
// Animatronic left eye
// Animatronic jaw
// Animatronic body (main head)
// Game state
var STATE_MENU = 0;
var STATE_PLAY = 1;
var STATE_NIGHTEND = 2;
var state = STATE_MENU;
// Night and hour
var currentNight = 1;
var currentHour = 12;
// Animatronic
var animatronic = new Animatronic();
// Kuklanın tüm parçalarını biraz küçült ve daha yukarı taşı
var animatronicScale = 1.25; // daha küçük
// Head asset is 700px wide, 500px tall, so center based on that
animatronic.baseX = 2048 / 2 - 700 * animatronicScale / 2;
// Daha yukarı taşı: 420 yerine 700 px yukarıda
animatronic.baseY = 2732 - 500 * animatronicScale - 700;
animatronic.x = animatronic.baseX;
animatronic.y = animatronic.baseY;
animatronic.scaleX = animatronicScale;
animatronic.scaleY = animatronicScale;
game.addChild(animatronic);
// VHS static overlay
var vhsStatic = new VHSStatic();
game.addChild(vhsStatic);
// Menu UI
var titleText = new Text2('', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 220;
// Set initial title text to English regardless of language
titleText.setText('FNAF : FINISH THE NIGHT');
var btnNewGame = new MenuButton();
btnNewGame.x = 2048 / 2;
btnNewGame.y = 600;
btnNewGame.setText('YENİ OYUN');
var btnContinue = new MenuButton();
btnContinue.x = 2048 / 2;
btnContinue.y = 800;
btnContinue.setText('DEVAM ET');
// Leaderboard button
var btnLeaderboard = new MenuButton();
// Move to left side, but not in the top left 100x100 area (avoid platform menu)
// Place at x=400, y=1000 (moved right from 200 to 400)
btnLeaderboard.x = 400;
btnLeaderboard.y = 1000;
btnLeaderboard.setText('SKOR TABLOSU');
// Language select button (now below continue)
var btnLang = new MenuButton();
btnLang.x = 2048 / 2;
// Calculate vertical gap between continue and new game buttons
var menuButtonGap = btnContinue.y - btnNewGame.y;
// Place language button the same gap below continue button
btnLang.y = btnContinue.y + menuButtonGap;
btnLang.setText('DİL: Türkçe');
var continueNightText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
continueNightText.anchor.set(0, 0.5);
continueNightText.x = btnContinue.x + 380;
continueNightText.y = btnContinue.y;
// Leaderboard UI
var leaderboardText = new Text2('', {
size: 60,
fill: 0xFFFF00
});
leaderboardText.anchor.set(0.5, 0);
leaderboardText.x = 2048 / 2;
leaderboardText.y = 300;
leaderboardText.visible = false;
// Leaderboard close button
var btnLeaderboardClose = new MenuButton();
btnLeaderboardClose.x = 2048 / 2;
btnLeaderboardClose.y = 2200;
btnLeaderboardClose.setText('KAPAT');
btnLeaderboardClose.visible = false;
// Menu selection
var menuSelected = 0; // 0: new game, 1: continue
// Night info UI
var nightText = new Text2('', {
size: 110,
fill: 0xFFFFFF
});
nightText.anchor.set(0.5, 0.5);
nightText.x = 2048 / 2;
nightText.y = 400;
nightText.alpha = 0;
var hourText = new Text2('', {
size: 90,
fill: 0xFFFFFF
});
hourText.anchor.set(0.5, 0.5);
hourText.x = 2048 / 2;
hourText.y = 540;
hourText.alpha = 0;
// Test: End night button
var btnEndNight = new MenuButton();
btnEndNight.x = 2048 / 2;
btnEndNight.y = 1200;
btnEndNight.setText('GECEYİ BİTİR');
btnEndNight.visible = false;
// 6:00 screen
var sixText = new Text2('06:00', {
size: 180,
fill: 0xFFFFFF
});
sixText.anchor.set(0.5, 0.5);
sixText.x = 2048 / 2;
sixText.y = 700;
sixText.alpha = 0;
// Add menu UI to game
game.addChild(titleText);
game.addChild(btnNewGame);
game.addChild(btnContinue);
game.addChild(btnLeaderboard);
game.addChild(btnLang);
game.addChild(continueNightText);
game.addChild(leaderboardText);
game.addChild(btnLeaderboardClose);
// Leaderboard storage setup
var leaderboard = storage; // Use storage as leaderboard for getTop/submit
// Leaderboard button logic
btnLeaderboard.down = function (x, y, obj) {
// Show leaderboard UI, but do NOT auto-close after click
titleText.visible = false;
btnNewGame.visible = false;
btnContinue.visible = false;
btnLeaderboard.visible = false;
btnLang.visible = false;
continueNightText.visible = false;
leaderboardText.visible = true;
btnLeaderboardClose.visible = true;
// Fetch and show leaderboard (sadece en yüksek skor gösterilecek)
var text = languages[currentLangIndex].code === 'en' ? 'LEADERBOARD\n' : 'SKOR TABLOSU\n';
var leaderboardFlat = storage.leaderboardEntries || [];
if (leaderboardFlat.length < 2 || typeof leaderboardFlat[1] !== "number" || leaderboardFlat[1] === 0) {
// No score yet, show "Gece içinde" or "Night in progress"
text += languages[currentLangIndex].code === 'en' ? 'Night in progress' : 'Gece içinde';
} else {
var name = typeof leaderboardFlat[0] === "string" ? leaderboardFlat[0] : "Anonim";
var score = leaderboardFlat[1];
text += '1. ' + name + ' - ' + score + '\n';
}
leaderboardText.setText(text);
// Do not close leaderboard automatically; user must press KAPAT
// (No code here to auto-close or hide leaderboard)
};
// Leaderboard close button logic
btnLeaderboardClose.down = function (x, y, obj) {
leaderboardText.visible = false;
btnLeaderboardClose.visible = false;
showMenu();
};
// Add night info and test UI
game.addChild(nightText);
game.addChild(hourText);
game.addChild(btnEndNight);
game.addChild(sixText);
// Hide all except menu
function showMenu() {
state = STATE_MENU;
titleText.visible = true;
btnNewGame.visible = true;
btnLang.visible = true;
btnContinue.visible = true;
btnLeaderboard.visible = true;
continueNightText.visible = true;
nightText.visible = false;
hourText.visible = false;
btnEndNight.visible = false;
sixText.visible = false;
menuSelected = 0;
btnNewGame.setActive(true);
btnContinue.setActive(false);
updateContinueNight();
// Set menu button texts to correct language
if (languages[currentLangIndex].code === 'en') {
// titleText.setText('FNAF : FINISH THE NIGHT');
btnNewGame.setText('NEW GAME');
btnContinue.setText('CONTINUE');
btnEndNight.setText('FINISH NIGHT');
} else {
// titleText.setText('FNAF : GECEYİ BİTİR');
btnNewGame.setText('YENİ OYUN');
btnContinue.setText('DEVAM ET');
btnEndNight.setText('GECEYİ BİTİR');
}
// Do not change titleText here; always English
// Show animatronic in menu
animatronic.visible = true;
// Show VHS static overlay in menu
vhsStatic.visible = true;
// Play looping menu music
LK.playMusic('musicId', {
loop: true
});
}
function showNight() {
state = STATE_PLAY;
titleText.visible = false;
btnNewGame.visible = false;
btnLang.visible = false;
btnContinue.visible = false;
continueNightText.visible = false;
btnLeaderboard.visible = false;
nightText.visible = true;
hourText.visible = true;
btnEndNight.visible = true;
sixText.visible = false;
// Hide VHS static overlay during gameplay
vhsStatic.visible = false;
// Stop menu music
LK.stopMusic();
// Set night and hour text
if (languages[currentLangIndex].code === 'en') {
nightText.setText('NIGHT ' + currentNight);
} else {
nightText.setText('GECE ' + currentNight);
}
hourText.setText(currentHour + ':00');
nightText.alpha = 0;
hourText.alpha = 0;
// Animate in
tween(nightText, {
alpha: 1
}, {
duration: 400,
easing: tween.cubicOut
});
tween(hourText, {
alpha: 1
}, {
duration: 400,
easing: tween.cubicOut
});
// Animatronic: look at player, jaw closed
animatronic.animateJaw(0);
animatronic.animateTilt(0);
// Hide animatronic during gameplay
animatronic.visible = false;
}
function showNightEnd() {
state = STATE_NIGHTEND;
titleText.visible = false;
btnNewGame.visible = false;
btnLang.visible = false;
btnContinue.visible = false;
continueNightText.visible = false;
btnLeaderboard.visible = false;
nightText.visible = false;
hourText.visible = false;
btnEndNight.visible = false;
sixText.visible = true;
sixText.alpha = 0;
// Hide VHS static overlay during night end
vhsStatic.visible = false;
// Stop menu music
LK.stopMusic();
tween(sixText, {
alpha: 1
}, {
duration: 600,
easing: tween.cubicOut
});
// Animatronic: jaw open, head tilt
animatronic.animateJaw(1);
animatronic.animateTilt(1);
// Hide animatronic in night end
animatronic.visible = false;
// Skoru leaderboard'a gönder (en yüksek gece)
// Sadece hesabın en yüksek skorunu sakla
var leaderboardFlat = storage.leaderboardEntries || [];
var maxScore = 0;
for (var i = 0; i < leaderboardFlat.length; i += 2) {
var score = typeof leaderboardFlat[i + 1] === "number" ? leaderboardFlat[i + 1] : 0;
if (score > maxScore) maxScore = score;
}
var newScore = currentNight - 1;
if (newScore > maxScore) {
// Replace with new high score
storage.leaderboardEntries = ['Anonim', newScore];
} else if (leaderboardFlat.length === 0) {
// No previous score, store this one
storage.leaderboardEntries = ['Anonim', newScore];
} else {
// Keep the previous high score
storage.leaderboardEntries = ['Anonim', maxScore];
}
// Geceyi geçince geceyi yükselt
currentNight += 1;
// Reduce waiting period for btnEndNight: -120ms per night until 6, then 40% reduction per night, min 500ms
if (currentNight <= 7) {
btnEndNightWaitPeriod = Math.max(500, btnEndNightWaitPeriod - 120);
} else {
btnEndNightWaitPeriod = Math.max(500, Math.floor(btnEndNightWaitPeriod * 0.6));
}
}
// Update continue night text
function updateContinueNight() {
continueNightText.setText('gece ' + currentNight);
}
// Menu button touch logic
btnNewGame.down = function (x, y, obj) {
menuSelected = 0;
btnNewGame.setActive(true);
btnContinue.setActive(false);
// Start new game
currentNight = 1;
currentHour = 12;
showNight();
};
// Language selection logic
var languages = [{
code: 'tr',
label: 'Türkçe'
}, {
code: 'en',
label: 'English'
}];
var currentLangIndex = 0;
btnLang.down = function (x, y, obj) {
currentLangIndex = (currentLangIndex + 1) % languages.length;
btnLang.setText('DİL: ' + languages[currentLangIndex].label);
// Update menu button texts based on language
if (languages[currentLangIndex].code === 'en') {
// titleText.setText('FNAF : FINISH THE NIGHT');
btnNewGame.setText('NEW GAME');
btnContinue.setText('CONTINUE');
btnEndNight.setText('FINISH NIGHT');
} else {
// titleText.setText('FNAF : GECEYİ BİTİR');
btnNewGame.setText('YENİ OYUN');
btnContinue.setText('DEVAM ET');
btnEndNight.setText('GECEYİ BİTİR');
}
// Do not change titleText here; always English
// Here you could add logic to update all UI text if you implement localization
};
btnContinue.down = function (x, y, obj) {
menuSelected = 1;
btnNewGame.setActive(false);
btnContinue.setActive(true);
// Continue game
currentHour = 12;
showNight();
};
// Track waiting state and timer for btnEndNight
var btnEndNightPressCount = 0;
var btnEndNightWaitTimeout = null;
var btnEndNightWaiting = false;
// Waiting period for btnEndNight (in ms), decreases each night, min 500ms
var btnEndNightWaitPeriod = 1200;
btnEndNight.down = function (x, y, obj) {
if (!btnEndNightWaiting) {
// First press: start waiting period
btnEndNightWaiting = true;
btnEndNightPressCount = 1;
// Start a timer (decreasing period)
btnEndNightWaitTimeout = LK.setTimeout(function () {
// If timer expires and no second press, trigger jump scare/game over
if (btnEndNightWaiting && btnEndNightPressCount === 1) {
// Play jump scare sound
var jumpscareSound = LK.getSound('jumpscare');
if (jumpscareSound) {
jumpscareSound.play();
} else {
// Defensive: always try to play jumpscare sound
var jumpscareSound2 = LK.getSound('jumpscare');
if (jumpscareSound2) jumpscareSound2.play();
}
// Flash screen red for 1 second to indicate death
LK.effects.flashScreen(0xff0000, 1000);
// Show animatronic jumpscare in the center of the screen
var jumpscareAnim = new Animatronic();
jumpscareAnim.baseX = 2048 / 2 - 700 * animatronicScale / 2;
jumpscareAnim.baseY = 2732 / 2 - 500 * animatronicScale / 2 - 100;
jumpscareAnim.x = jumpscareAnim.baseX;
jumpscareAnim.y = jumpscareAnim.baseY;
jumpscareAnim.scaleX = animatronicScale * 1.25;
jumpscareAnim.scaleY = animatronicScale * 1.25;
jumpscareAnim.visible = true;
game.addChild(jumpscareAnim);
// Animate jaw open and head forward for jumpscare
jumpscareAnim.animateJaw(1);
jumpscareAnim.animateTilt(0);
// Show localized game over text in the center of the screen
var gameOverText = new Text2(languages[currentLangIndex].code === 'en' ? 'GAME OVER' : 'OYUN BİTTİ', {
size: 220,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2 + 400;
game.addChild(gameOverText);
// After 1.2s, remove jumpscare and text, then return to menu (no extra 'Game Over'/'Oyun Bitti' text)
LK.setTimeout(function () {
if (gameOverText && gameOverText.parent) {
gameOverText.parent.removeChild(gameOverText);
}
if (jumpscareAnim && jumpscareAnim.parent) {
jumpscareAnim.parent.removeChild(jumpscareAnim);
}
showMenu();
// Reset for next night
currentNight = 1; // Gece sıfırla (reset nights on death)
btnEndNightPressCount = 0;
btnEndNightWaiting = false;
btnEndNightWaitTimeout = null;
}, 1200);
}
// Reset waiting state if not already reset
btnEndNightWaiting = false;
btnEndNightWaitTimeout = null;
}, 1200);
} else if (btnEndNightWaiting && btnEndNightPressCount === 1) {
// Second press during waiting: pass the night
btnEndNightPressCount = 2;
// Cancel the jump scare timer
if (btnEndNightWaitTimeout !== null) {
LK.clearTimeout(btnEndNightWaitTimeout);
btnEndNightWaitTimeout = null;
}
btnEndNightWaiting = false;
// End night, show 6:00
showNightEnd();
// After 2s, return to menu
LK.setTimeout(function () {
showMenu();
// Reset for next night
btnEndNightPressCount = 0;
}, 2000);
}
};
// Touch navigation for menu (disable all except button areas)
game.down = function (x, y, obj) {
// Only allow button interactions, do nothing here
return;
};
// Touch up: disable all except button areas
game.up = function (x, y, obj) {
// Only allow button interactions, do nothing here
return;
};
// Animate animatronic idle (jaw open/close, head tilt)
var animTimer = 0;
function animatronicIdleAnim() {
if (state !== STATE_MENU && state !== STATE_PLAY) return;
animTimer++;
if (animTimer % 90 === 0) {
// Open jaw
animatronic.animateJaw(1);
} else if (animTimer % 90 === 30) {
// Close jaw
animatronic.animateJaw(0);
}
if (animTimer % 180 === 0) {
// Tilt head randomly
var tilt = [-1, 0, 1][Math.floor(Math.random() * 3)];
animatronic.animateTilt(tilt);
}
}
// VHS static overlay always on top
game.children.sort(function (a, b) {
if (a === vhsStatic) return 1;
if (b === vhsStatic) return -1;
return 0;
});
// Main update
game.update = function () {
animatronic.update();
vhsStatic.update();
animatronicIdleAnim();
};
// Start at menu
showMenu();