User prompt
kalp butonu yeni bölüm başlarında hiçbir zaman soluk olmasın !
User prompt
asalik ve ikiside assetleri de random bir şekilde çalan listeye eklensin !
User prompt
asalik be ikiside isimli sound assetlerimi de oyuna ekle .
User prompt
anaBeat müziğim birinci bölümden itibaren oyunda beri çalsın . müzik bitince tekrardan sıfırdan başlasın ve oyunda çalmaya devam etsin
User prompt
anaBeat müziğim 2. bölümün başından itibaran oynumumda çalmaya başlasın !
User prompt
anaBeat müziğimi oyuna ekle . 2. bölümden sonra anaBeatteki müzik çalmaya başlasın !
User prompt
Oyunun ilk bölümünü biraz daha yavaşlat . Oyuncuların oyuna girmesi daha kolay olsun . Diğer bölümler aynı şekilde kalsın !
User prompt
eger assetindeki görseli oyuna düşman olarak ekle .
User prompt
vefasizAsalik assetindeki görseli oyuna düşman olarak ekle !
User prompt
oyunun kapak fotoğrafını boss görselindeki resim yap !
User prompt
canımızın yazdığu % lik kısmı kalın yap !
User prompt
"Introyu Geçmek İçin Kanaryaya Dokunun" yazısını kaldır
User prompt
intro bölümünde olan "Introyu Geçmek İçin Kanaryaya Dokunun" yazısı ekranda 3nye dursun sonra kaybolsun ekrandan !
User prompt
"Introyu Geçmek İçin Kanaryaya Dokunun" yazısı intro bölümünde belli bir süre sonra ekrandan kaybolsun . ekranda 3snye dursun sonra kaybolsun !
Code edit (1 edits merged)
Please save this source code
User prompt
sadece boss bölümünü oynat !
User prompt
kupa asseti ekrana gelirken 3 tane boss asseti de ekranda olsun . karaketerimizin kaçabileceği tek bir yer olsun ! Bu şekilde hızla alakalı bir zorluk eklemiş olalım !
User prompt
sadece boss bölümünü oynat !
User prompt
boss bölümünde bossların geliş sıklığı çok daha artsın !
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Obstacle class: colored square, moves down, can be lane or boss var Obstacle = Container.expand(function () { var self = Container.call(this); // Default: normal obstacle self.isBoss = false; self.lane = 0; // 0-3 self.speed = 10; // will be set per stage // Removed color property; asset color is now determined by image asset only self.size = 220; // will be set per obstacle self.passed = false; // for boss logic // Attach asset (always use image asset for obstacles) // The color property is not used; asset key must be set by caller after construction var box = null; self.setAsset = function (assetKey) { // Defensive: ensure assetKey is a string and not undefined/null if (typeof assetKey !== "string" || !assetKey || assetKey.length === 0) { // fallback to a default asset to avoid crash assetKey = "obstacle_0x007aff"; } self.removeChildren(); box = self.attachAsset(assetKey, { width: self.size, height: self.size, anchorX: 0.5, anchorY: 0.5 }); }; // For boss, we will override asset in code // Update per tick self.update = function () { self.y += self.speed; }; // For boss, we can flash or animate self.flash = function () { tween(box, { tint: 0xffffff }, { duration: 100, onFinish: function onFinish() { tween(box, { tint: self.color }, { duration: 200 }); } }); }; return self; }); // Player class: colored square, can switch lanes var Player = Container.expand(function () { var self = Container.call(this); self.lane = 1; // 0-3, start in lane 1 (second from left) self.size = 180; // Removed color property; asset color is now determined by image asset only var playerBox = self.attachAsset('player', { width: self.size, height: self.size, anchorX: 0.5, anchorY: 0.5 }); // Head direction: 1 = right, -1 = left self.headDirection = 1; // Flip head to right self.lookRight = function () { if (self.headDirection !== 1) { playerBox.scaleX = 1; self.headDirection = 1; } }; // Flip head to left self.lookLeft = function () { if (self.headDirection !== -1) { playerBox.scaleX = -1; self.headDirection = -1; } }; // Move to lane (0-3) self.moveToLane = function (lane) { self.lane = lane; self.x = laneToX(lane); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Use the original asset at its native resolution and scale to fit the screen for best quality // Define 18 unique obstacle assets, one for each color // --- BACKGROUND IMAGE --- var arkaPlanBg = LK.getAsset('arkaPlan', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChildAt(arkaPlanBg, 0); // Add as the very first child so it's always behind // --- LANE SYSTEM --- var NUM_LANES = 4; var LANE_WIDTH = 400; // 2048/4 = 512, but leave margin var LANE_MARGIN = (2048 - NUM_LANES * LANE_WIDTH) / 2; // center lanes function laneToX(lane) { // Center of each lane return LANE_MARGIN + LANE_WIDTH * lane + LANE_WIDTH / 2; } // --- PLAYER --- var player = new Player(); player.y = 2732 - 550; // 350px from bottom player.moveToLane(1); // Start in lane 1 game.addChild(player); // --- PLAYER CLICK BONUS (+50 health on 3rd click, only once) --- var playerClickCount = 0; var playerBonusGiven = false; player.down = function (x, y, obj) { // If in enemy intro, skip intro and start game immediately if (enemyIntroActive && currentStage === ENEMY_INTRO_STAGE) { // Remove current intro asset and text if present if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") { enemyIntroDisplay.destroy(); enemyIntroDisplay = null; } if (enemyIntroText && typeof enemyIntroText.destroy === "function") { enemyIntroText.destroy(); enemyIntroText = null; } enemyIntroActive = false; enemyIntroDone = true; currentStage = 0; // Show first stage image for (var si = 0; si < stageImageAssets.length; si++) { stageImageAssets[si].visible = si === 0; } // Reset kalp asset alpha to fully visible at the start of stage 1 kalpImg.alpha = 1.0; return; } if (gameOver || youWin || durdurmaEkraniOverlay) { return; } if (playerBonusGiven) { return; } // Removed +50 health bonus on 3rd click as requested playerClickCount++; }; // --- HEALTH --- var maxHealth = 100; var health = maxHealth; // Health bar image and health percent text // Center canBari image vertically in top bar, and enlarge health percent text var canBariImg = LK.getAsset('canBari', { anchorX: 0.75, anchorY: 0.5, x: 120, y: 120, // move down a bit for better centering width: 480, height: 180 }); LK.gui.top.addChild(canBariImg); // Make health percent text much larger and vertically centered with canBari image var healthTxt = new Text2('100%', { size: 50, fill: 0xFFFFFF }); // healthTxt.anchor.set(4, 0.50); // Bu satırı değiştireceğiz. healthTxt.anchor.set(3.6, 0.5); // Metni sola hizala ve dikeyde ortala // Place health text to the right of the canBari image, vertically centered healthTxt.x = canBariImg.x + canBariImg.width * 0.75 + 40; // canBariImg'nin sağ tarafına göre ayarla healthTxt.y = canBariImg.y; LK.gui.top.addChild(healthTxt); // --- OBSTACLE PASS COUNTER --- var obstaclesPassed = 0; var passCounterTxt = new Text2('0', { size: 70, fill: 0xffff00, font: "italic bold Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); passCounterTxt.anchor.set(1, 0); // right align LK.gui.topRight.addChild(passCounterTxt); // --- STAGE IMAGE DISPLAY (bottom left) --- var stageImageKeys = ['bolum1', 'bolum2', 'bolum3', 'bolum4', 'bossGorsel']; var stageImageAssets = []; for (var i = 0; i < stageImageKeys.length; i++) { var img = LK.getAsset(stageImageKeys[i], { anchorX: -3.5, anchorY: 9, x: 0, y: 0, width: 300, height: 220 }); img.visible = false; stageImageAssets.push(img); LK.gui.bottomLeft.addChild(img); } // Show the first stage image stageImageAssets[0].visible = true; // --- MENU BILGI ICON (bottom left) --- var menuBilgiImg = LK.getAsset('menuBilgi', { anchorX: 0, anchorY: 1, x: 20, y: 0, width: 220, height: 120 }); LK.gui.bottomLeft.addChild(menuBilgiImg); // --- DURDURMA EKRANI (pause overlay) --- var durdurmaEkraniOverlay = null; var isPausedByMenu = false; function showDurdurmaEkrani() { if (durdurmaEkraniOverlay) { return; } isPausedByMenu = true; // LK.pauseGame() is not needed; LK will automatically pause the game when an overlay is shown. // Create overlay asset, full screen durdurmaEkraniOverlay = LK.getAsset('durdurmaEkrani', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2080, height: 2732 }); // Overlay should be on top of everything game.addChild(durdurmaEkraniOverlay); // Clicking anywhere on overlay resumes game durdurmaEkraniOverlay.down = function (x, y, obj) { hideDurdurmaEkrani(); }; } function hideDurdurmaEkrani() { if (!durdurmaEkraniOverlay) { return; } // Remove overlay durdurmaEkraniOverlay.destroy(); durdurmaEkraniOverlay = null; isPausedByMenu = false; // No need to call LK.resumeGame(); LK will automatically resume when overlay is removed } // Click handler for menuBilgi icon menuBilgiImg.down = function (x, y, obj) { if (!durdurmaEkraniOverlay) { showDurdurmaEkrani(); } }; // --- SOUND OFF ICON (bottom right) --- var sesKapamaImg = LK.getAsset('sesKapama', { anchorX: 1, anchorY: 1, x: 0, y: 0, width: 280, height: 180 }); LK.gui.bottomRight.addChild(sesKapamaImg); // --- KALP ICON (bottom center, between menu and volume) --- var kalpImg = LK.getAsset('kalp', { anchorX: 0.5, anchorY: 1, x: 0, y: 0, width: 220, height: 180 }); LK.gui.bottom.addChild(kalpImg); // --- KALP CLICK: +50 health per stage, only once per stage --- var kalpUsedPerStage = [false, false, false, false, false]; // 4 stages + boss kalpImg.down = function (x, y, obj) { if (gameOver || youWin || durdurmaEkraniOverlay) { return; } // Boss mode is stage 4 var stageIdx = bossMode ? 4 : currentStage; if (kalpUsedPerStage[stageIdx]) { return; } // If health is already full, do not allow kalp to be used if (health >= maxHealth) { return; } kalpUsedPerStage[stageIdx] = true; kalpImg.alpha = 0.4; // Fade kalp asset after use, just like volume icon var prevHealth = health; health = Math.min(maxHealth, health + 50); updateHealthText(); // Animate health bar green if health increased if (health > prevHealth) { tween.stop(healthTxt, { tint: true, scaleX: true, scaleY: true }); healthTxt.scale.set(1, 1); var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF; healthTxt.tint = 0x00ff00; tween(healthTxt, { scaleX: 1.5, scaleY: 1.5 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { tween(healthTxt, { scaleX: 1, scaleY: 1 }, { duration: 220, easing: tween.cubicIn }); } }); tween(healthTxt, { tint: originalTint }, { duration: 400, easing: tween.linear }); } }; // --- SOUND MUTE STATE --- var isMuted = false; // Helper: set mute state for all sounds function setMuteState(mute) { isMuted = mute; // Set alpha for sesKapama icon sesKapamaImg.alpha = mute ? 0.4 : 1.0; // Mute/unmute all sounds var soundKeys = []; if (LK.assets && LK.assets.sounds) { soundKeys = Object.keys(LK.assets.sounds); } for (var i = 0; i < soundKeys.length; i++) { var s = LK.getSound(soundKeys[i]); if (s && typeof s.mute === "function") { s.mute(mute); } else if (s && typeof s.setVolume === "function") { s.setVolume(mute ? 0 : 1); } } // Mute/unmute all music var musicKeys = []; if (LK.assets && LK.assets.music) { musicKeys = Object.keys(LK.assets.music); } for (var j = 0; j < musicKeys.length; j++) { var m = LK.getMusic ? LK.getMusic(musicKeys[j]) : null; if (m && typeof m.mute === "function") { m.mute(mute); } else if (m && typeof m.setVolume === "function") { m.setVolume(mute ? 0 : 1); } } } // Initial state: not muted setMuteState(false); // Click handler for sesKapama icon sesKapamaImg.down = function (x, y, obj) { setMuteState(!isMuted); }; // --- OBSTACLES --- var obstacles = []; // Removed obstacleColors array; asset is determined by image asset only // --- STAGES --- var STAGES = [ // [numObstacles, speed, damage, minGap, maxGap] // All stages are now harder: more obstacles, higher speed, more damage, shorter spawn intervals { count: 65, // was 45 speed: 14, // was 10 damage: 16, // was 10 minGap: 260, // was 420 maxGap: 400 // was 600 }, { count: 90, // was 65 speed: 18, // was 13 damage: 22, // was 15 minGap: 180, // was 370 maxGap: 320 // was 540 }, { count: 160, // was 120 speed: 24, // was 18 damage: 28, // was 20 minGap: 110, // was 220 maxGap: 200 // was 340 }, { count: 240, // was 180 speed: 30, // was 22 damage: 36, // was 25 minGap: 70, // was 160 maxGap: 140 // was 260 }]; // --- ENEMY INTRO STAGE (before Stage 1) --- var ENEMY_INTRO_STAGE = -1; var enemyIntroActive = true; var enemyIntroIndex = 0; var enemyIntroAssets = [ // All unique enemy asset keys (obstacle images and special images) 'obstacle_0x007aff', 'obstacle_0x22223b', 'obstacle_0x30b0c7', 'obstacle_0x34c759', 'obstacle_0x393e46', 'obstacle_0x4cd964', 'obstacle_0x5856d6', 'obstacle_0x5ac8fa', 'obstacle_0x8e8e93', 'obstacle_0x9d4edd', 'obstacle_0xaf52de', 'obstacle_0xe94f37', 'obstacle_0xf28d35', 'obstacle_0xfad02e', 'obstacle_0xff2d55', 'obstacle_0xff3b30', 'obstacle_0xff9500', 'baskanKamera', 'pradaMont', 'beFair', 'mZajc', 'gsLogo']; var enemyIntroDisplay = null; var enemyIntroText = null; var enemyIntroTimer = 0; var enemyIntroDelay = 120; // ~2s per enemy at 60fps (slower intro) var enemyIntroDone = false; var currentStage = ENEMY_INTRO_STAGE; // Start at intro stage var obstaclesSpawned = 0; var stageObstacleTypes = 18; // 18 unique types var stageInProgress = true; var bossMode = false; var bossHits = 0; // Boss section is harder: require more boss dodges to win // Zorluk arttırıldı: Her stage için gereken boss sayısı yükseltildi var bossRequiredByStage = [22, 28, 36, 55]; var bossRequired = bossRequiredByStage[currentStage] || 55; // --- SPAWN CONTROL --- var spawnTimer = 0; var spawnInterval = 40; // ticks between spawns, will be randomized per stage function randomInt(a, b) { return a + Math.floor(Math.random() * (b - a + 1)); } // --- BOSS --- var bossObstacle = null; var bossActive = false; // Boss daha sık gelsin: cooldown daha kısa başlasın var bossCooldown = 0; // --- GAME STATE --- var gameOver = false; var youWin = false; // --- INIT OBSTACLE ASSETS (shapes) --- // (No obstacleColors array needed; assets are initialized in Assets section) // --- SPAWN OBSTACLE --- // --- Randomize enemy order for each stage --- if (typeof obstacleTypeOrder === "undefined" || obstaclesSpawned === 0) { // 18 color obstacles + 5 image enemies (added mZajc, gsLogo) var colorKeys = ['0x007aff', '0x22223b', '0x30b0c7', '0x34c759', '0x393e46', '0x4cd964', '0x5856d6', '0x5ac8fa', '0x8e8e93', '0x9d4edd', '0xaf52de', '0xe94f37', '0xf28d35', '0xfad02e', '0xff2d55', '0xff3b30', '0xff9500', 'baskanKamera', 'pradaMont', 'beFair', 'mZajc', 'gsLogo']; // Shuffle colorKeys to create a random order obstacleTypeOrder = []; for (var i = 0; i < colorKeys.length; i++) { obstacleTypeOrder.push(colorKeys[i]); } // Fisher-Yates shuffle for (var i = obstacleTypeOrder.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = obstacleTypeOrder[i]; obstacleTypeOrder[i] = obstacleTypeOrder[j]; obstacleTypeOrder[j] = temp; } obstacleTypeOrderIdx = 0; } function spawnObstacle(stage) { var o = new Obstacle(); // Pick random lane var lane = randomInt(0, NUM_LANES - 1); o.lane = lane; o.x = laneToX(lane); o.y = -120; // just above screen // Use randomized order for obstacle types if (typeof obstacleTypeOrder === "undefined" || typeof obstacleTypeOrderIdx === "undefined") { // fallback in case of error obstacleTypeOrder = ['0x007aff']; obstacleTypeOrderIdx = 0; } var colorKeys = obstacleTypeOrder; var colorIdx = obstacleTypeOrderIdx % colorKeys.length; var key = colorKeys[colorIdx]; obstacleTypeOrderIdx++; // If key is a color, use obstacle_ prefix, else use as image asset if (key === 'baskanKamera' || key === 'pradaMont' || key === 'beFair' || key === 'mZajc' || key === 'gsLogo') { o.size = 340; // Slightly larger for image-based enemies o.speed = stage.speed; o.setAsset(key); } else { o.size = 320; o.speed = stage.speed; o.setAsset('obstacle_' + key); } obstacles.push(o); game.addChild(o); obstaclesSpawned++; } // --- SPAWN BOSS --- function spawnBoss() { var o = new Obstacle(); o.isBoss = true; o.size = 520; // Increased from 320 to 520 for a much larger boss // Removed color assignment; asset is determined by image asset only o.speed = 32; // Boss lane: random o.lane = randomInt(0, NUM_LANES - 1); o.x = laneToX(o.lane); o.y = -180; o.setAsset('boss'); bossObstacle = o; bossActive = true; game.addChild(o); } // --- HEALTH UPDATE --- function updateHealthText() { var pct = Math.max(0, Math.round(health)); healthTxt.setText(pct + "%"); } // --- GAME OVER --- function triggerGameOver() { if (gameOver) { return; } gameOver = true; LK.effects.flashScreen(0xff0000, 800); // Show obstacles passed on game over screen LK.showGameOver({ score: obstaclesPassed }); } // --- YOU WIN --- function triggerYouWin() { if (youWin) { return; } youWin = true; LK.effects.flashScreen(0x00ff00, 800); LK.showYouWin(); } // --- PLAYER INPUT: LANE SWITCHING --- // Touch/click left/right half of screen to move game.down = function (x, y, obj) { if (gameOver || youWin || durdurmaEkraniOverlay) { return; } // Convert to game coordinates var lane = player.lane; if (x < 2048 / 2) { // Move left if (lane > 0) { lane--; } player.lookLeft && player.lookLeft(); } else { // Move right if (lane < NUM_LANES - 1) { lane++; } player.lookRight && player.lookRight(); } player.moveToLane(lane); }; // --- GAME UPDATE --- game.update = function () { if (gameOver || youWin) { return; } // --- ENEMY INTRO STAGE LOGIC --- if (enemyIntroActive && currentStage === ENEMY_INTRO_STAGE) { // On first frame, create display asset if (!enemyIntroDisplay) { // Defensive: remove any previous if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") { enemyIntroDisplay.destroy(); } if (enemyIntroText && typeof enemyIntroText.destroy === "function") { enemyIntroText.destroy(); } // Show first enemy asset, centered var assetKey = enemyIntroAssets[enemyIntroIndex]; var isImage = assetKey === 'baskanKamera' || assetKey === 'pradaMont' || assetKey === 'beFair' || assetKey === 'mZajc' || assetKey === 'gsLogo'; var size = isImage ? 820 : 720; enemyIntroDisplay = LK.getAsset(assetKey, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 80, width: size, height: size }); game.addChild(enemyIntroDisplay); // Show instruction text below the asset in intro enemyIntroText = new Text2("Introyu Geçmek İçin Kanaryaya Dokunun", { size: 90, fill: 0xFFF700, font: "bold Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); enemyIntroText.anchor.set(0.5, 0); // center horizontally, top edge enemyIntroText.x = 2048 / 2; enemyIntroText.y = 2732 / 2 + size / 2 + 40; // just below the asset game.addChild(enemyIntroText); enemyIntroTimer = 0; } // Wait for delay, then show next enemy enemyIntroTimer++; if (enemyIntroTimer > enemyIntroDelay) { // Remove current asset and text if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") { enemyIntroDisplay.destroy(); enemyIntroDisplay = null; } if (enemyIntroText && typeof enemyIntroText.destroy === "function") { enemyIntroText.destroy(); enemyIntroText = null; } enemyIntroIndex++; enemyIntroTimer = 0; if (enemyIntroIndex >= enemyIntroAssets.length) { // Intro done, start Stage 1 enemyIntroActive = false; enemyIntroDone = true; currentStage = 0; // Show first stage image for (var si = 0; si < stageImageAssets.length; si++) { stageImageAssets[si].visible = si === 0; } // Reset kalp asset alpha to fully visible at the start of stage 1 kalpImg.alpha = 1.0; // Remove any lingering intro asset/text if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") { enemyIntroDisplay.destroy(); enemyIntroDisplay = null; } if (enemyIntroText && typeof enemyIntroText.destroy === "function") { enemyIntroText.destroy(); enemyIntroText = null; } return; } // Show next enemy asset var assetKey = enemyIntroAssets[enemyIntroIndex]; var isImage = assetKey === 'baskanKamera' || assetKey === 'pradaMont' || assetKey === 'beFair' || assetKey === 'mZajc' || assetKey === 'gsLogo'; var size = isImage ? 820 : 720; enemyIntroDisplay = LK.getAsset(assetKey, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 80, width: size, height: size }); game.addChild(enemyIntroDisplay); // Show instruction text below the asset in intro enemyIntroText = new Text2("Introyu Geçmek İçin Kanaryaya Dokunun", { size: 90, fill: 0xFFF700, font: "bold Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); enemyIntroText.anchor.set(0.5, 0); // center horizontally, top edge enemyIntroText.x = 2048 / 2; enemyIntroText.y = 2732 / 2 + size / 2 + 40; // just below the asset game.addChild(enemyIntroText); } // Block normal gameplay during intro return; } // Pause all game logic if durdurmaEkrani overlay is visible if (durdurmaEkraniOverlay) { return; } // --- SPAWN OBSTACLES --- if (!bossMode) { var stage = STAGES[currentStage]; if (obstaclesSpawned < stage.count) { if (spawnTimer <= 0) { spawnObstacle(stage); // Randomize next spawn interval spawnInterval = randomInt(stage.minGap, stage.maxGap) / stage.speed; spawnTimer = Math.max(18, Math.floor(spawnInterval)); } else { spawnTimer--; } } else if (obstacles.length === 0) { // Stage complete, next stage or boss if (currentStage < STAGES.length - 1) { // fenerBogasi sound removed as requested currentStage++; obstaclesSpawned = 0; // Update stage image visibility for (var si = 0; si < stageImageAssets.length; si++) { stageImageAssets[si].visible = si === currentStage; } // Health bonus at the start of each stage if health is not 100% if (health < maxHealth) { var healthBefore = health; if (currentStage === 1) { health = Math.min(maxHealth, health + 20); } else if (currentStage === 2) { health = Math.min(maxHealth, health + 30); } else if (currentStage === 3) { health = Math.min(maxHealth, health + 40); } updateHealthText(); // Reset kalp asset alpha to fully visible at the start of each stage kalpImg.alpha = 1.0; // Animate health bar green if health increased if (health > healthBefore) { tween.stop(healthTxt, { tint: true, scaleX: true, scaleY: true }); healthTxt.scale.set(1, 1); var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF; healthTxt.tint = 0x00ff00; tween(healthTxt, { scaleX: 1.5, scaleY: 1.5 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { tween(healthTxt, { scaleX: 1, scaleY: 1 }, { duration: 220, easing: tween.cubicIn }); } }); tween(healthTxt, { tint: originalTint }, { duration: 400, easing: tween.linear }); } } // Update bossRequired for new stage bossRequired = bossRequiredByStage[currentStage] || 22; } else { // All stages done, boss time! // fenerBogasi sound removed as requested // Boss health bonus if not 100% if (health < maxHealth) { var healthBefore = health; health = Math.min(maxHealth, health + 50); updateHealthText(); // Animate health bar green if health increased if (health > healthBefore) { tween.stop(healthTxt, { tint: true, scaleX: true, scaleY: true }); healthTxt.scale.set(1, 1); var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF; healthTxt.tint = 0x00ff00; tween(healthTxt, { scaleX: 1.5, scaleY: 1.5 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { tween(healthTxt, { scaleX: 1, scaleY: 1 }, { duration: 220, easing: tween.cubicIn }); } }); tween(healthTxt, { tint: originalTint }, { duration: 400, easing: tween.linear }); } } bossMode = true; bossHits = 0; bossCooldown = 30; // Reset kalp asset alpha to fully visible at the start of boss stage kalpImg.alpha = 1.0; // Update stage image visibility for boss for (var si = 0; si < stageImageAssets.length; si++) { stageImageAssets[si].visible = si === 4; } // Set bossRequired for final stage if not already set bossRequired = bossRequiredByStage[STAGES.length - 1] || 55; } } } // --- OBSTACLE MOVEMENT & COLLISION --- for (var i = obstacles.length - 1; i >= 0; i--) { var o = obstacles[i]; o.update(); // Remove if off screen if (o.y > 2732 + 120) { o.destroy(); obstacles.splice(i, 1); obstaclesPassed++; passCounterTxt.setText(obstaclesPassed + ""); // --- Play random sound (except kartal) every 40 obstaclesPassed --- if (typeof lastSoundTrigger === "undefined") { lastSoundTrigger = 0; } if (obstaclesPassed > 0 && obstaclesPassed % 30 === 0 && lastSoundTrigger !== obstaclesPassed && !isMuted) { // List of all sound keys except 'kartal' var allSoundKeys = ['ahmetAbi', 'buSeneSampFener', 'dikDurEgilme', 'elNesiri', 'fenerBogasi', 'gitme', 'isteBuBe', 'osimhenOzel', 'oyleBirTakim', 'tekBasima']; // Pick a random sound var idx = Math.floor(Math.random() * allSoundKeys.length); var soundKey = allSoundKeys[idx]; var soundObj = LK.getSound(soundKey); if (soundObj && typeof soundObj.play === "function") { soundObj.play(); } lastSoundTrigger = obstaclesPassed; } // Play isteBuBe sound only at 300 obstacles passed if (obstaclesPassed === 300 && !isMuted) { var isteBuBeSound = LK.getSound('isteBuBe'); if (isteBuBeSound && typeof isteBuBeSound.play === "function") { isteBuBeSound.play(); } } continue; } // Collision with player if (!o.isBoss && o.lane === player.lane) { // Check overlap in y var dy = Math.abs(o.y - player.y); if (dy < (o.size + player.size) / 2 - 10) { // Hit! var prevHealth = health; health -= STAGES[currentStage].damage; // Animate health bar red for health decrease tween.stop(healthTxt, { tint: true, scaleX: true, scaleY: true }); healthTxt.scale.set(1, 1); var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF; healthTxt.tint = 0xff0000; tween(healthTxt, { scaleX: 1.5, scaleY: 1.5 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { tween(healthTxt, { scaleX: 1, scaleY: 1 }, { duration: 220, easing: tween.cubicIn }); } }); tween(healthTxt, { tint: originalTint }, { duration: 400, easing: tween.linear }); updateHealthText(); o.destroy(); obstacles.splice(i, 1); if (health <= 0) { triggerGameOver(); return; } } } } // --- BOSS LOGIC --- if (bossMode) { // Boss çok daha sık gelsin: cooldown neredeyse anında (ör: 1 frame) if (!bossActive && bossCooldown <= 0) { spawnBoss(); } else if (bossCooldown > 0) { // Reduce cooldown for ultra high boss spawn frequency (was 32, now 10, now 4, now 1) bossCooldown--; } if (bossActive && bossObstacle) { bossObstacle.update(); // --- Play kartal sound at the middle of boss section, only once --- if (typeof kartalSoundPlayed === "undefined") { kartalSoundPlayed = false; } // Play at 23rd boss (middle of 45), only once if (!kartalSoundPlayed && bossHits === 22 && !isMuted) { var kartalSound = LK.getSound('kartal'); if (kartalSound && typeof kartalSound.play === "function") { kartalSound.play(); } kartalSoundPlayed = true; } // Remove if off screen if (bossObstacle.y > 2732 + 200) { // Player dodged boss bossHits++; bossActive = false; bossObstacle.destroy(); bossObstacle = null; // Boss daha sık gelsin: cooldown çok kısa (ör: 4 frame) bossCooldown = 4; // --- KUPA LOGIC: Show kupa after last boss dodged --- if (bossHits === bossRequired) { // Add kupa image to the game, centered in the lane of the player if (typeof kupaImage === "undefined" || !kupaImage) { kupaImage = LK.getAsset('kupa', { anchorX: 0.5, anchorY: 0.5, // Make kupa image very large to cover the screen width: 2048, height: 2743, // keep aspect ratio, 2048/1000*1340 ≈ 2743 x: 2048 / 2, y: -1371.5 // start above screen, center vertically }); kupaImage.isKupa = true; game.addChild(kupaImage); } kupaActive = true; } // Require bossRequired bosses to win in boss section (now handled by kupa) //if (bossHits >= bossRequired) { // triggerYouWin(); // return; } else { // Collision with player if (bossObstacle.lane === player.lane) { var dy = Math.abs(bossObstacle.y - player.y); if (dy < (bossObstacle.size + player.size) / 2 - 10) { // Boss hit: instant game over LK.effects.flashObject(player, 0xff0000, 600); triggerGameOver(); return; } } } } // --- KUPA LOGIC: Move kupa image and trigger win when passed --- if (typeof kupaActive !== "undefined" && kupaActive && typeof kupaImage !== "undefined" && kupaImage) { // Move kupa down kupaImage.y += 32; // same as boss speed // Check if kupa is visible and not yet passed if (!kupaImage.kupaPassed) { // If kupa is off screen (player passed it), trigger win if (kupaImage.y > 2732 + 400) { kupaImage.kupaPassed = true; kupaActive = false; kupaImage.destroy(); kupaImage = null; triggerYouWin(); return; } // Kupa does NOT damage player, so no collision check } } } }; // --- INITIAL HEALTH DISPLAY --- updateHealthText();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Obstacle class: colored square, moves down, can be lane or boss
var Obstacle = Container.expand(function () {
var self = Container.call(this);
// Default: normal obstacle
self.isBoss = false;
self.lane = 0; // 0-3
self.speed = 10; // will be set per stage
// Removed color property; asset color is now determined by image asset only
self.size = 220; // will be set per obstacle
self.passed = false; // for boss logic
// Attach asset (always use image asset for obstacles)
// The color property is not used; asset key must be set by caller after construction
var box = null;
self.setAsset = function (assetKey) {
// Defensive: ensure assetKey is a string and not undefined/null
if (typeof assetKey !== "string" || !assetKey || assetKey.length === 0) {
// fallback to a default asset to avoid crash
assetKey = "obstacle_0x007aff";
}
self.removeChildren();
box = self.attachAsset(assetKey, {
width: self.size,
height: self.size,
anchorX: 0.5,
anchorY: 0.5
});
};
// For boss, we will override asset in code
// Update per tick
self.update = function () {
self.y += self.speed;
};
// For boss, we can flash or animate
self.flash = function () {
tween(box, {
tint: 0xffffff
}, {
duration: 100,
onFinish: function onFinish() {
tween(box, {
tint: self.color
}, {
duration: 200
});
}
});
};
return self;
});
// Player class: colored square, can switch lanes
var Player = Container.expand(function () {
var self = Container.call(this);
self.lane = 1; // 0-3, start in lane 1 (second from left)
self.size = 180;
// Removed color property; asset color is now determined by image asset only
var playerBox = self.attachAsset('player', {
width: self.size,
height: self.size,
anchorX: 0.5,
anchorY: 0.5
});
// Head direction: 1 = right, -1 = left
self.headDirection = 1;
// Flip head to right
self.lookRight = function () {
if (self.headDirection !== 1) {
playerBox.scaleX = 1;
self.headDirection = 1;
}
};
// Flip head to left
self.lookLeft = function () {
if (self.headDirection !== -1) {
playerBox.scaleX = -1;
self.headDirection = -1;
}
};
// Move to lane (0-3)
self.moveToLane = function (lane) {
self.lane = lane;
self.x = laneToX(lane);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Use the original asset at its native resolution and scale to fit the screen for best quality
// Define 18 unique obstacle assets, one for each color
// --- BACKGROUND IMAGE ---
var arkaPlanBg = LK.getAsset('arkaPlan', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChildAt(arkaPlanBg, 0); // Add as the very first child so it's always behind
// --- LANE SYSTEM ---
var NUM_LANES = 4;
var LANE_WIDTH = 400; // 2048/4 = 512, but leave margin
var LANE_MARGIN = (2048 - NUM_LANES * LANE_WIDTH) / 2; // center lanes
function laneToX(lane) {
// Center of each lane
return LANE_MARGIN + LANE_WIDTH * lane + LANE_WIDTH / 2;
}
// --- PLAYER ---
var player = new Player();
player.y = 2732 - 550; // 350px from bottom
player.moveToLane(1); // Start in lane 1
game.addChild(player);
// --- PLAYER CLICK BONUS (+50 health on 3rd click, only once) ---
var playerClickCount = 0;
var playerBonusGiven = false;
player.down = function (x, y, obj) {
// If in enemy intro, skip intro and start game immediately
if (enemyIntroActive && currentStage === ENEMY_INTRO_STAGE) {
// Remove current intro asset and text if present
if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") {
enemyIntroDisplay.destroy();
enemyIntroDisplay = null;
}
if (enemyIntroText && typeof enemyIntroText.destroy === "function") {
enemyIntroText.destroy();
enemyIntroText = null;
}
enemyIntroActive = false;
enemyIntroDone = true;
currentStage = 0;
// Show first stage image
for (var si = 0; si < stageImageAssets.length; si++) {
stageImageAssets[si].visible = si === 0;
}
// Reset kalp asset alpha to fully visible at the start of stage 1
kalpImg.alpha = 1.0;
return;
}
if (gameOver || youWin || durdurmaEkraniOverlay) {
return;
}
if (playerBonusGiven) {
return;
}
// Removed +50 health bonus on 3rd click as requested
playerClickCount++;
};
// --- HEALTH ---
var maxHealth = 100;
var health = maxHealth;
// Health bar image and health percent text
// Center canBari image vertically in top bar, and enlarge health percent text
var canBariImg = LK.getAsset('canBari', {
anchorX: 0.75,
anchorY: 0.5,
x: 120,
y: 120,
// move down a bit for better centering
width: 480,
height: 180
});
LK.gui.top.addChild(canBariImg);
// Make health percent text much larger and vertically centered with canBari image
var healthTxt = new Text2('100%', {
size: 50,
fill: 0xFFFFFF
});
// healthTxt.anchor.set(4, 0.50); // Bu satırı değiştireceğiz.
healthTxt.anchor.set(3.6, 0.5); // Metni sola hizala ve dikeyde ortala
// Place health text to the right of the canBari image, vertically centered
healthTxt.x = canBariImg.x + canBariImg.width * 0.75 + 40; // canBariImg'nin sağ tarafına göre ayarla
healthTxt.y = canBariImg.y;
LK.gui.top.addChild(healthTxt);
// --- OBSTACLE PASS COUNTER ---
var obstaclesPassed = 0;
var passCounterTxt = new Text2('0', {
size: 70,
fill: 0xffff00,
font: "italic bold Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
passCounterTxt.anchor.set(1, 0); // right align
LK.gui.topRight.addChild(passCounterTxt);
// --- STAGE IMAGE DISPLAY (bottom left) ---
var stageImageKeys = ['bolum1', 'bolum2', 'bolum3', 'bolum4', 'bossGorsel'];
var stageImageAssets = [];
for (var i = 0; i < stageImageKeys.length; i++) {
var img = LK.getAsset(stageImageKeys[i], {
anchorX: -3.5,
anchorY: 9,
x: 0,
y: 0,
width: 300,
height: 220
});
img.visible = false;
stageImageAssets.push(img);
LK.gui.bottomLeft.addChild(img);
}
// Show the first stage image
stageImageAssets[0].visible = true;
// --- MENU BILGI ICON (bottom left) ---
var menuBilgiImg = LK.getAsset('menuBilgi', {
anchorX: 0,
anchorY: 1,
x: 20,
y: 0,
width: 220,
height: 120
});
LK.gui.bottomLeft.addChild(menuBilgiImg);
// --- DURDURMA EKRANI (pause overlay) ---
var durdurmaEkraniOverlay = null;
var isPausedByMenu = false;
function showDurdurmaEkrani() {
if (durdurmaEkraniOverlay) {
return;
}
isPausedByMenu = true;
// LK.pauseGame() is not needed; LK will automatically pause the game when an overlay is shown.
// Create overlay asset, full screen
durdurmaEkraniOverlay = LK.getAsset('durdurmaEkrani', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2080,
height: 2732
});
// Overlay should be on top of everything
game.addChild(durdurmaEkraniOverlay);
// Clicking anywhere on overlay resumes game
durdurmaEkraniOverlay.down = function (x, y, obj) {
hideDurdurmaEkrani();
};
}
function hideDurdurmaEkrani() {
if (!durdurmaEkraniOverlay) {
return;
}
// Remove overlay
durdurmaEkraniOverlay.destroy();
durdurmaEkraniOverlay = null;
isPausedByMenu = false;
// No need to call LK.resumeGame(); LK will automatically resume when overlay is removed
}
// Click handler for menuBilgi icon
menuBilgiImg.down = function (x, y, obj) {
if (!durdurmaEkraniOverlay) {
showDurdurmaEkrani();
}
};
// --- SOUND OFF ICON (bottom right) ---
var sesKapamaImg = LK.getAsset('sesKapama', {
anchorX: 1,
anchorY: 1,
x: 0,
y: 0,
width: 280,
height: 180
});
LK.gui.bottomRight.addChild(sesKapamaImg);
// --- KALP ICON (bottom center, between menu and volume) ---
var kalpImg = LK.getAsset('kalp', {
anchorX: 0.5,
anchorY: 1,
x: 0,
y: 0,
width: 220,
height: 180
});
LK.gui.bottom.addChild(kalpImg);
// --- KALP CLICK: +50 health per stage, only once per stage ---
var kalpUsedPerStage = [false, false, false, false, false]; // 4 stages + boss
kalpImg.down = function (x, y, obj) {
if (gameOver || youWin || durdurmaEkraniOverlay) {
return;
}
// Boss mode is stage 4
var stageIdx = bossMode ? 4 : currentStage;
if (kalpUsedPerStage[stageIdx]) {
return;
}
// If health is already full, do not allow kalp to be used
if (health >= maxHealth) {
return;
}
kalpUsedPerStage[stageIdx] = true;
kalpImg.alpha = 0.4; // Fade kalp asset after use, just like volume icon
var prevHealth = health;
health = Math.min(maxHealth, health + 50);
updateHealthText();
// Animate health bar green if health increased
if (health > prevHealth) {
tween.stop(healthTxt, {
tint: true,
scaleX: true,
scaleY: true
});
healthTxt.scale.set(1, 1);
var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF;
healthTxt.tint = 0x00ff00;
tween(healthTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 180,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(healthTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 220,
easing: tween.cubicIn
});
}
});
tween(healthTxt, {
tint: originalTint
}, {
duration: 400,
easing: tween.linear
});
}
};
// --- SOUND MUTE STATE ---
var isMuted = false;
// Helper: set mute state for all sounds
function setMuteState(mute) {
isMuted = mute;
// Set alpha for sesKapama icon
sesKapamaImg.alpha = mute ? 0.4 : 1.0;
// Mute/unmute all sounds
var soundKeys = [];
if (LK.assets && LK.assets.sounds) {
soundKeys = Object.keys(LK.assets.sounds);
}
for (var i = 0; i < soundKeys.length; i++) {
var s = LK.getSound(soundKeys[i]);
if (s && typeof s.mute === "function") {
s.mute(mute);
} else if (s && typeof s.setVolume === "function") {
s.setVolume(mute ? 0 : 1);
}
}
// Mute/unmute all music
var musicKeys = [];
if (LK.assets && LK.assets.music) {
musicKeys = Object.keys(LK.assets.music);
}
for (var j = 0; j < musicKeys.length; j++) {
var m = LK.getMusic ? LK.getMusic(musicKeys[j]) : null;
if (m && typeof m.mute === "function") {
m.mute(mute);
} else if (m && typeof m.setVolume === "function") {
m.setVolume(mute ? 0 : 1);
}
}
}
// Initial state: not muted
setMuteState(false);
// Click handler for sesKapama icon
sesKapamaImg.down = function (x, y, obj) {
setMuteState(!isMuted);
};
// --- OBSTACLES ---
var obstacles = [];
// Removed obstacleColors array; asset is determined by image asset only
// --- STAGES ---
var STAGES = [
// [numObstacles, speed, damage, minGap, maxGap]
// All stages are now harder: more obstacles, higher speed, more damage, shorter spawn intervals
{
count: 65,
// was 45
speed: 14,
// was 10
damage: 16,
// was 10
minGap: 260,
// was 420
maxGap: 400 // was 600
}, {
count: 90,
// was 65
speed: 18,
// was 13
damage: 22,
// was 15
minGap: 180,
// was 370
maxGap: 320 // was 540
}, {
count: 160,
// was 120
speed: 24,
// was 18
damage: 28,
// was 20
minGap: 110,
// was 220
maxGap: 200 // was 340
}, {
count: 240,
// was 180
speed: 30,
// was 22
damage: 36,
// was 25
minGap: 70,
// was 160
maxGap: 140 // was 260
}];
// --- ENEMY INTRO STAGE (before Stage 1) ---
var ENEMY_INTRO_STAGE = -1;
var enemyIntroActive = true;
var enemyIntroIndex = 0;
var enemyIntroAssets = [
// All unique enemy asset keys (obstacle images and special images)
'obstacle_0x007aff', 'obstacle_0x22223b', 'obstacle_0x30b0c7', 'obstacle_0x34c759', 'obstacle_0x393e46', 'obstacle_0x4cd964', 'obstacle_0x5856d6', 'obstacle_0x5ac8fa', 'obstacle_0x8e8e93', 'obstacle_0x9d4edd', 'obstacle_0xaf52de', 'obstacle_0xe94f37', 'obstacle_0xf28d35', 'obstacle_0xfad02e', 'obstacle_0xff2d55', 'obstacle_0xff3b30', 'obstacle_0xff9500', 'baskanKamera', 'pradaMont', 'beFair', 'mZajc', 'gsLogo'];
var enemyIntroDisplay = null;
var enemyIntroText = null;
var enemyIntroTimer = 0;
var enemyIntroDelay = 120; // ~2s per enemy at 60fps (slower intro)
var enemyIntroDone = false;
var currentStage = ENEMY_INTRO_STAGE; // Start at intro stage
var obstaclesSpawned = 0;
var stageObstacleTypes = 18; // 18 unique types
var stageInProgress = true;
var bossMode = false;
var bossHits = 0;
// Boss section is harder: require more boss dodges to win
// Zorluk arttırıldı: Her stage için gereken boss sayısı yükseltildi
var bossRequiredByStage = [22, 28, 36, 55];
var bossRequired = bossRequiredByStage[currentStage] || 55;
// --- SPAWN CONTROL ---
var spawnTimer = 0;
var spawnInterval = 40; // ticks between spawns, will be randomized per stage
function randomInt(a, b) {
return a + Math.floor(Math.random() * (b - a + 1));
}
// --- BOSS ---
var bossObstacle = null;
var bossActive = false;
// Boss daha sık gelsin: cooldown daha kısa başlasın
var bossCooldown = 0;
// --- GAME STATE ---
var gameOver = false;
var youWin = false;
// --- INIT OBSTACLE ASSETS (shapes) ---
// (No obstacleColors array needed; assets are initialized in Assets section)
// --- SPAWN OBSTACLE ---
// --- Randomize enemy order for each stage ---
if (typeof obstacleTypeOrder === "undefined" || obstaclesSpawned === 0) {
// 18 color obstacles + 5 image enemies (added mZajc, gsLogo)
var colorKeys = ['0x007aff', '0x22223b', '0x30b0c7', '0x34c759', '0x393e46', '0x4cd964', '0x5856d6', '0x5ac8fa', '0x8e8e93', '0x9d4edd', '0xaf52de', '0xe94f37', '0xf28d35', '0xfad02e', '0xff2d55', '0xff3b30', '0xff9500', 'baskanKamera', 'pradaMont', 'beFair', 'mZajc', 'gsLogo'];
// Shuffle colorKeys to create a random order
obstacleTypeOrder = [];
for (var i = 0; i < colorKeys.length; i++) {
obstacleTypeOrder.push(colorKeys[i]);
}
// Fisher-Yates shuffle
for (var i = obstacleTypeOrder.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = obstacleTypeOrder[i];
obstacleTypeOrder[i] = obstacleTypeOrder[j];
obstacleTypeOrder[j] = temp;
}
obstacleTypeOrderIdx = 0;
}
function spawnObstacle(stage) {
var o = new Obstacle();
// Pick random lane
var lane = randomInt(0, NUM_LANES - 1);
o.lane = lane;
o.x = laneToX(lane);
o.y = -120; // just above screen
// Use randomized order for obstacle types
if (typeof obstacleTypeOrder === "undefined" || typeof obstacleTypeOrderIdx === "undefined") {
// fallback in case of error
obstacleTypeOrder = ['0x007aff'];
obstacleTypeOrderIdx = 0;
}
var colorKeys = obstacleTypeOrder;
var colorIdx = obstacleTypeOrderIdx % colorKeys.length;
var key = colorKeys[colorIdx];
obstacleTypeOrderIdx++;
// If key is a color, use obstacle_ prefix, else use as image asset
if (key === 'baskanKamera' || key === 'pradaMont' || key === 'beFair' || key === 'mZajc' || key === 'gsLogo') {
o.size = 340; // Slightly larger for image-based enemies
o.speed = stage.speed;
o.setAsset(key);
} else {
o.size = 320;
o.speed = stage.speed;
o.setAsset('obstacle_' + key);
}
obstacles.push(o);
game.addChild(o);
obstaclesSpawned++;
}
// --- SPAWN BOSS ---
function spawnBoss() {
var o = new Obstacle();
o.isBoss = true;
o.size = 520; // Increased from 320 to 520 for a much larger boss
// Removed color assignment; asset is determined by image asset only
o.speed = 32;
// Boss lane: random
o.lane = randomInt(0, NUM_LANES - 1);
o.x = laneToX(o.lane);
o.y = -180;
o.setAsset('boss');
bossObstacle = o;
bossActive = true;
game.addChild(o);
}
// --- HEALTH UPDATE ---
function updateHealthText() {
var pct = Math.max(0, Math.round(health));
healthTxt.setText(pct + "%");
}
// --- GAME OVER ---
function triggerGameOver() {
if (gameOver) {
return;
}
gameOver = true;
LK.effects.flashScreen(0xff0000, 800);
// Show obstacles passed on game over screen
LK.showGameOver({
score: obstaclesPassed
});
}
// --- YOU WIN ---
function triggerYouWin() {
if (youWin) {
return;
}
youWin = true;
LK.effects.flashScreen(0x00ff00, 800);
LK.showYouWin();
}
// --- PLAYER INPUT: LANE SWITCHING ---
// Touch/click left/right half of screen to move
game.down = function (x, y, obj) {
if (gameOver || youWin || durdurmaEkraniOverlay) {
return;
}
// Convert to game coordinates
var lane = player.lane;
if (x < 2048 / 2) {
// Move left
if (lane > 0) {
lane--;
}
player.lookLeft && player.lookLeft();
} else {
// Move right
if (lane < NUM_LANES - 1) {
lane++;
}
player.lookRight && player.lookRight();
}
player.moveToLane(lane);
};
// --- GAME UPDATE ---
game.update = function () {
if (gameOver || youWin) {
return;
}
// --- ENEMY INTRO STAGE LOGIC ---
if (enemyIntroActive && currentStage === ENEMY_INTRO_STAGE) {
// On first frame, create display asset
if (!enemyIntroDisplay) {
// Defensive: remove any previous
if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") {
enemyIntroDisplay.destroy();
}
if (enemyIntroText && typeof enemyIntroText.destroy === "function") {
enemyIntroText.destroy();
}
// Show first enemy asset, centered
var assetKey = enemyIntroAssets[enemyIntroIndex];
var isImage = assetKey === 'baskanKamera' || assetKey === 'pradaMont' || assetKey === 'beFair' || assetKey === 'mZajc' || assetKey === 'gsLogo';
var size = isImage ? 820 : 720;
enemyIntroDisplay = LK.getAsset(assetKey, {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 80,
width: size,
height: size
});
game.addChild(enemyIntroDisplay);
// Show instruction text below the asset in intro
enemyIntroText = new Text2("Introyu Geçmek İçin Kanaryaya Dokunun", {
size: 90,
fill: 0xFFF700,
font: "bold Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
enemyIntroText.anchor.set(0.5, 0); // center horizontally, top edge
enemyIntroText.x = 2048 / 2;
enemyIntroText.y = 2732 / 2 + size / 2 + 40; // just below the asset
game.addChild(enemyIntroText);
enemyIntroTimer = 0;
}
// Wait for delay, then show next enemy
enemyIntroTimer++;
if (enemyIntroTimer > enemyIntroDelay) {
// Remove current asset and text
if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") {
enemyIntroDisplay.destroy();
enemyIntroDisplay = null;
}
if (enemyIntroText && typeof enemyIntroText.destroy === "function") {
enemyIntroText.destroy();
enemyIntroText = null;
}
enemyIntroIndex++;
enemyIntroTimer = 0;
if (enemyIntroIndex >= enemyIntroAssets.length) {
// Intro done, start Stage 1
enemyIntroActive = false;
enemyIntroDone = true;
currentStage = 0;
// Show first stage image
for (var si = 0; si < stageImageAssets.length; si++) {
stageImageAssets[si].visible = si === 0;
}
// Reset kalp asset alpha to fully visible at the start of stage 1
kalpImg.alpha = 1.0;
// Remove any lingering intro asset/text
if (enemyIntroDisplay && typeof enemyIntroDisplay.destroy === "function") {
enemyIntroDisplay.destroy();
enemyIntroDisplay = null;
}
if (enemyIntroText && typeof enemyIntroText.destroy === "function") {
enemyIntroText.destroy();
enemyIntroText = null;
}
return;
}
// Show next enemy asset
var assetKey = enemyIntroAssets[enemyIntroIndex];
var isImage = assetKey === 'baskanKamera' || assetKey === 'pradaMont' || assetKey === 'beFair' || assetKey === 'mZajc' || assetKey === 'gsLogo';
var size = isImage ? 820 : 720;
enemyIntroDisplay = LK.getAsset(assetKey, {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 80,
width: size,
height: size
});
game.addChild(enemyIntroDisplay);
// Show instruction text below the asset in intro
enemyIntroText = new Text2("Introyu Geçmek İçin Kanaryaya Dokunun", {
size: 90,
fill: 0xFFF700,
font: "bold Arial, 'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
enemyIntroText.anchor.set(0.5, 0); // center horizontally, top edge
enemyIntroText.x = 2048 / 2;
enemyIntroText.y = 2732 / 2 + size / 2 + 40; // just below the asset
game.addChild(enemyIntroText);
}
// Block normal gameplay during intro
return;
}
// Pause all game logic if durdurmaEkrani overlay is visible
if (durdurmaEkraniOverlay) {
return;
}
// --- SPAWN OBSTACLES ---
if (!bossMode) {
var stage = STAGES[currentStage];
if (obstaclesSpawned < stage.count) {
if (spawnTimer <= 0) {
spawnObstacle(stage);
// Randomize next spawn interval
spawnInterval = randomInt(stage.minGap, stage.maxGap) / stage.speed;
spawnTimer = Math.max(18, Math.floor(spawnInterval));
} else {
spawnTimer--;
}
} else if (obstacles.length === 0) {
// Stage complete, next stage or boss
if (currentStage < STAGES.length - 1) {
// fenerBogasi sound removed as requested
currentStage++;
obstaclesSpawned = 0;
// Update stage image visibility
for (var si = 0; si < stageImageAssets.length; si++) {
stageImageAssets[si].visible = si === currentStage;
}
// Health bonus at the start of each stage if health is not 100%
if (health < maxHealth) {
var healthBefore = health;
if (currentStage === 1) {
health = Math.min(maxHealth, health + 20);
} else if (currentStage === 2) {
health = Math.min(maxHealth, health + 30);
} else if (currentStage === 3) {
health = Math.min(maxHealth, health + 40);
}
updateHealthText();
// Reset kalp asset alpha to fully visible at the start of each stage
kalpImg.alpha = 1.0;
// Animate health bar green if health increased
if (health > healthBefore) {
tween.stop(healthTxt, {
tint: true,
scaleX: true,
scaleY: true
});
healthTxt.scale.set(1, 1);
var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF;
healthTxt.tint = 0x00ff00;
tween(healthTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 180,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(healthTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 220,
easing: tween.cubicIn
});
}
});
tween(healthTxt, {
tint: originalTint
}, {
duration: 400,
easing: tween.linear
});
}
}
// Update bossRequired for new stage
bossRequired = bossRequiredByStage[currentStage] || 22;
} else {
// All stages done, boss time!
// fenerBogasi sound removed as requested
// Boss health bonus if not 100%
if (health < maxHealth) {
var healthBefore = health;
health = Math.min(maxHealth, health + 50);
updateHealthText();
// Animate health bar green if health increased
if (health > healthBefore) {
tween.stop(healthTxt, {
tint: true,
scaleX: true,
scaleY: true
});
healthTxt.scale.set(1, 1);
var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF;
healthTxt.tint = 0x00ff00;
tween(healthTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 180,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(healthTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 220,
easing: tween.cubicIn
});
}
});
tween(healthTxt, {
tint: originalTint
}, {
duration: 400,
easing: tween.linear
});
}
}
bossMode = true;
bossHits = 0;
bossCooldown = 30;
// Reset kalp asset alpha to fully visible at the start of boss stage
kalpImg.alpha = 1.0;
// Update stage image visibility for boss
for (var si = 0; si < stageImageAssets.length; si++) {
stageImageAssets[si].visible = si === 4;
}
// Set bossRequired for final stage if not already set
bossRequired = bossRequiredByStage[STAGES.length - 1] || 55;
}
}
}
// --- OBSTACLE MOVEMENT & COLLISION ---
for (var i = obstacles.length - 1; i >= 0; i--) {
var o = obstacles[i];
o.update();
// Remove if off screen
if (o.y > 2732 + 120) {
o.destroy();
obstacles.splice(i, 1);
obstaclesPassed++;
passCounterTxt.setText(obstaclesPassed + "");
// --- Play random sound (except kartal) every 40 obstaclesPassed ---
if (typeof lastSoundTrigger === "undefined") {
lastSoundTrigger = 0;
}
if (obstaclesPassed > 0 && obstaclesPassed % 30 === 0 && lastSoundTrigger !== obstaclesPassed && !isMuted) {
// List of all sound keys except 'kartal'
var allSoundKeys = ['ahmetAbi', 'buSeneSampFener', 'dikDurEgilme', 'elNesiri', 'fenerBogasi', 'gitme', 'isteBuBe', 'osimhenOzel', 'oyleBirTakim', 'tekBasima'];
// Pick a random sound
var idx = Math.floor(Math.random() * allSoundKeys.length);
var soundKey = allSoundKeys[idx];
var soundObj = LK.getSound(soundKey);
if (soundObj && typeof soundObj.play === "function") {
soundObj.play();
}
lastSoundTrigger = obstaclesPassed;
}
// Play isteBuBe sound only at 300 obstacles passed
if (obstaclesPassed === 300 && !isMuted) {
var isteBuBeSound = LK.getSound('isteBuBe');
if (isteBuBeSound && typeof isteBuBeSound.play === "function") {
isteBuBeSound.play();
}
}
continue;
}
// Collision with player
if (!o.isBoss && o.lane === player.lane) {
// Check overlap in y
var dy = Math.abs(o.y - player.y);
if (dy < (o.size + player.size) / 2 - 10) {
// Hit!
var prevHealth = health;
health -= STAGES[currentStage].damage;
// Animate health bar red for health decrease
tween.stop(healthTxt, {
tint: true,
scaleX: true,
scaleY: true
});
healthTxt.scale.set(1, 1);
var originalTint = typeof healthTxt.tint !== "undefined" ? healthTxt.tint : 0xFFFFFF;
healthTxt.tint = 0xff0000;
tween(healthTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 180,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(healthTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 220,
easing: tween.cubicIn
});
}
});
tween(healthTxt, {
tint: originalTint
}, {
duration: 400,
easing: tween.linear
});
updateHealthText();
o.destroy();
obstacles.splice(i, 1);
if (health <= 0) {
triggerGameOver();
return;
}
}
}
}
// --- BOSS LOGIC ---
if (bossMode) {
// Boss çok daha sık gelsin: cooldown neredeyse anında (ör: 1 frame)
if (!bossActive && bossCooldown <= 0) {
spawnBoss();
} else if (bossCooldown > 0) {
// Reduce cooldown for ultra high boss spawn frequency (was 32, now 10, now 4, now 1)
bossCooldown--;
}
if (bossActive && bossObstacle) {
bossObstacle.update();
// --- Play kartal sound at the middle of boss section, only once ---
if (typeof kartalSoundPlayed === "undefined") {
kartalSoundPlayed = false;
}
// Play at 23rd boss (middle of 45), only once
if (!kartalSoundPlayed && bossHits === 22 && !isMuted) {
var kartalSound = LK.getSound('kartal');
if (kartalSound && typeof kartalSound.play === "function") {
kartalSound.play();
}
kartalSoundPlayed = true;
}
// Remove if off screen
if (bossObstacle.y > 2732 + 200) {
// Player dodged boss
bossHits++;
bossActive = false;
bossObstacle.destroy();
bossObstacle = null;
// Boss daha sık gelsin: cooldown çok kısa (ör: 4 frame)
bossCooldown = 4;
// --- KUPA LOGIC: Show kupa after last boss dodged ---
if (bossHits === bossRequired) {
// Add kupa image to the game, centered in the lane of the player
if (typeof kupaImage === "undefined" || !kupaImage) {
kupaImage = LK.getAsset('kupa', {
anchorX: 0.5,
anchorY: 0.5,
// Make kupa image very large to cover the screen
width: 2048,
height: 2743,
// keep aspect ratio, 2048/1000*1340 ≈ 2743
x: 2048 / 2,
y: -1371.5 // start above screen, center vertically
});
kupaImage.isKupa = true;
game.addChild(kupaImage);
}
kupaActive = true;
}
// Require bossRequired bosses to win in boss section (now handled by kupa)
//if (bossHits >= bossRequired) {
// triggerYouWin();
// return;
} else {
// Collision with player
if (bossObstacle.lane === player.lane) {
var dy = Math.abs(bossObstacle.y - player.y);
if (dy < (bossObstacle.size + player.size) / 2 - 10) {
// Boss hit: instant game over
LK.effects.flashObject(player, 0xff0000, 600);
triggerGameOver();
return;
}
}
}
}
// --- KUPA LOGIC: Move kupa image and trigger win when passed ---
if (typeof kupaActive !== "undefined" && kupaActive && typeof kupaImage !== "undefined" && kupaImage) {
// Move kupa down
kupaImage.y += 32; // same as boss speed
// Check if kupa is visible and not yet passed
if (!kupaImage.kupaPassed) {
// If kupa is off screen (player passed it), trigger win
if (kupaImage.y > 2732 + 400) {
kupaImage.kupaPassed = true;
kupaActive = false;
kupaImage.destroy();
kupaImage = null;
triggerYouWin();
return;
}
// Kupa does NOT damage player, so no collision check
}
}
}
};
// --- INITIAL HEALTH DISPLAY ---
updateHealthText();
A very sweet yellow canary bird. In-Game asset. 2d. High contrast. No shadows
Create an image that says The Special One. The words should be written one under the other. It should be in a retro theme. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Create a visual that says 15 Million Euros. All the words should be written under each other. It should be in a retro theme. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Sarı kırmızı çizgili forma oluştur , formanın arkasında "A.KOC " yazsın , numarası da 25 numara olsun . Retro temada olsun . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Create a big skyscraper. Make it yellow, red and navy blue. Write "YAPI" underneath. Make it retro themed. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Bana can barı oluştur . Yatay bir şekilde tüp şeklinde olsun . tüpte can barı full dolu olsun. Yanları oval olsun , klasik oyunlarda ki can barına da benzer bir yapıda olsun . Retro temada olsun . . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Arka planı olmayan bir volume yazısı ses resmi oluştur , retro temada olsun. renkleri sarı lacivert olsun . yatay olsun olabildiğince dikey olmasın In-Game asset. 2d. High contrast. No shadows
Menu yazan yatay bir resim oluştur . Arka Planı olmasın . Sarı Lacivert bir resim olsun. retro temada olsun. In-Game asset. 2d. High contrast. No shadows
siyah renk prada montlu bir adam görseli oluştur , bu montu giyen adam sarı şapkalı , siyah güneş gözlüklü , hafif kirli sakallı bir tip olsun. prada yerine görselde "BRADA" yazsın In-Game asset. 2d. High contrast. No shadows
2025 - 2026 Türkiye Süper Ligi Şampiyonu Kupası oluştur , kupanınn üstünde FENERBAHÇE yazsın. soluk renklerde olsun , retro temada olsun In-Game asset. 2d. High contrast. No shadows
taraftarlarla kavga eden bir fenerbahce başkanı oluştur , başkan takım elbise giyiyor olsun , başkanın tipi ali koca benzesin . taraftarlar da sarı fb forması giyen taraftar olsunlar. In-Game asset. 2d. High contrast. No shadows
Oto yıkama ile alakalı bir görsel oluştur . Bu görselin altında 3.5M Euro yazsın. Retro temada bir görsel olsun .. In-Game asset. 2d. High contrast. No shadows
Beyaz bir megafon görseli oluştur . Retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
Fenerbahçe logosuna benzer bir logo oluştur ama telif haklarından logonun aynısı olmasın Logoda Fenerbahçe değilde Fener yazsın sadece . Bu logonun üstüne de 5 yıldız koy . retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
"22 Yıl" bordo renk "20 Yıl" kırmızı renk "15 Yıl" beyaz renk şeklinde bir görsel oluştur , üstü X şeklinde olsun . retro temada olsun !. In-Game asset. 2d. High contrast. No shadows. 2
Bir adet şampiyonluk kupası oluştur , bu kupa full kırmzı renkte olsun . Kupanın boynuzları olsun , şeytanın boynuzları gibi . retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
Bir şampiyonluk kupası oluştur , kupanın altında 7 yazsın , kupanın üstü de çarpı şeklinde olsun . 7 yıldır şampiyon olunmuyoru anlatan bir tarzda olsun . retro temada olsun .. In-Game asset. 2d. High contrast. No shadows
Sarı lacivert bir doğum günü pastası oluştur , 2 tane mumlu . Bu pastanın üstünde "25 Bin Kişi" yazsın . retro temada olsun .. In-Game asset. 2d. High contrast. No shadows
Bir uçak bileti oluştur . Yolcunun adı T.T.S olsun . Uçak bileti siyah beyaz olsun . Ucağın rotası Adana -> Kadıköy olsun . Yolcunun fotosu kartal olsun . retro temada olsun .. In-Game asset. 2d. High contrast. No shadows
Fener adlı mavi tikli bir twitter sayfasının adana kebab paylaştığı bir görsel oluştur . retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
2011 futbol şampiyonluk kupası resmi oluştur . Bu kupayı alttan birden fazla el kaldırıyor olsun . kupa altın sarısı renkte olsun . retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
Beyaz plastik sandalye ve masa da oturan volkan demiren görseli oluştur . bu görsel de volkan demirel Lacivert eşofman takımı giyiyor olsun . retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
Beyaz bir t-shirt oluştur . üsütünde beFair yazsın t-shirtün . be beyaz Fair mor renkte olsun . retro temada olsun. In-Game asset. 2d. High contrast. No shadows
Borsa grafiği oluştur grafiğin yönü aşağı yönde olsun .Altında "4.8 SOLD" şeklinde bir yazı yazsın . retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
Galatasaray logosuna benzer bir logo oluştur "Gala" yazsın . Üstünde de 5 yıldız olsun . retro temada olsun .. In-Game asset. 2d. High contrast. No shadows
Kalp şeklinde görsel oluştur , kırmızı şeklinde olsun kalp . retro tasarımda olsun .. In-Game asset. 2d. High contrast. No shadows
Her el kalbe tıklayarak +50 can alabilirsiniz." yazan bir yazı oluştur . Dikey formatta olsun . Retro temada olsun , arka plan soluk renklerde sarı lacivert olsun . Yazı formatı çok büyük olmasın . Yazılar ekranda rahat rahat okunabilsin . Yazılar tüm ekranı kaplamasın . Oluşturacağın görselin alt ve üstünde boşluklar olsun , yazı ortada olsun görselde ! In-Game asset. 2d. High contrast. No shadows
Kara bir yazı tahtası oluştur , bu tahtada "Kadıköy Hatırası " yazsın . retro temada olsun .. In-Game asset. 2d. High contrast. No shadows
Bir iş adamı karakteri oluştur , Acun ılıcalıya benzesin karakter. Karakterin üstünde konuşma balonuna benzer bir balon olsun. Bu balonun içinde "Eğer seçilemezsek başkan hayatına devam e..." yazsın . Görsel Retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
Ali Koça Sinirle konuşan bir başkan karakteri oluştur . Bu karakter Ali Koça benzesin . Bu karakterin tepesinde bir konuşma baloncuğu olsun . Bu baloncukta "Vefasızlar , Aşağılık , Ciğeri beş para etmeyenler " yazsın . Retro temada olsun !. In-Game asset. 2d. High contrast. No shadows
fenerBogasi
Sound effect
isteBuBe
Sound effect
ahmetAbi
Sound effect
buSeneSampFener
Sound effect
dikDurEgilme
Sound effect
elNesiri
Sound effect
gitme
Sound effect
kartal
Sound effect
osimhenOzel
Sound effect
oyleBirTakim
Sound effect
tekBasima
Sound effect
asalik
Sound effect
ikiside
Sound effect