/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ /**** * Character: Dokunulduğunda zıplar. ****/ var Character = Container.expand(function () { var self = Container.call(this); self.attachAsset('character', { anchorX: 0.5, anchorY: 0.5 }); self.zIndex = 4; self.velocityY = 0; self.gravity = 0.3; self.jumpStrength = -12.1; self.width = 350; self.height = 300; self.update = function () { if (gameStarted && !gameOver) { self.velocityY += self.gravity; self.y += self.velocityY; if (self.y > groundY - 100) { self.y = groundY - 100; self.velocityY = 0; if (!self.intersects(underscoreAsset) && !self.preventDeath) { gameOver = true; endGame(); } } var characterLeft = self.x - self.width / 2; var characterRight = self.x + self.width / 2; var characterTop = self.y - self.height / 2; var characterBottom = self.y + self.height / 2; if (characterLeft + self.width / 2 < 0 || characterRight - self.width / 2 > screenRight || characterTop + self.height / 2 < 0 || characterBottom - self.height / 2 > groundY) { gameOver = true; endGame(); } game.children.forEach(function (child) { if (child instanceof Tube) { var tubeLeft = child.x - child.bottomTube.width / 2; var tubeRight = child.x + child.bottomTube.width / 2; var safeGapLowerEdge = child.y - child.bottomTube.height; var safeGapUpperEdge = -gapOffset + child.topTube.height; if (self.x + self.width / 2 > tubeLeft && self.x - self.width / 2 < tubeRight) { if (self.y < safeGapUpperEdge || self.y > safeGapLowerEdge) { if (!self.intersects(underscoreAsset) && !self.preventDeath) { gameOver = true; endGame(); } } } } else if (child instanceof Tree) { var treeLeft = child.x - child.bottomTree.width / 2; var treeRight = child.x + child.bottomTree.width / 2; var safeGapLowerEdge = child.y - child.bottomTree.height; var safeGapUpperEdge = -gapOffset + child.topTree.height; if (self.x + self.width / 2 > treeLeft && self.x - self.width / 2 < treeRight) { if (self.y < safeGapUpperEdge || self.y > safeGapLowerEdge) { if (!self.intersects(underscoreAsset) && !self.preventTreeDeath) { gameOver = true; endGame(); } } } } }); } }; self.jump = function () { if (!gameOver && gameStarted) { self.velocityY = self.jumpStrength; LK.getSound('wingeffect').play(); // Karakter zıpladığında background ve bg2'ye de jump etkisi uyguluyoruz: background.velocityY = background.jumpStrength; bg2.velocityY = bg2.jumpStrength; background3DContainer.velocityY = background3DContainer.jumpStrength; bgEffect3DContainer.velocityY = bgEffect3DContainer.jumpStrength; } }; return self; }); /**** * GameOverText class ****/ var GameOverText = Container.expand(function () { var self = Container.call(this); self.text = new Text2("GAME OVER", { fontFamily: "Arial", fontSize: 2250, fill: 0xFF0000, align: "center", fontWeight: "bold" }); self.text.anchorX = 0.5; self.text.anchorY = 0.5; self.addChild(self.text); self.zIndex = 100; return self; }); /**** * Tree class: Üst ve alt ağaç oluşturma ****/ var Tree = Container.expand(function () { var self = Container.call(this); var bottomUnit = Math.floor(Math.random() * 8) + 1; var topUnit = 9 - bottomUnit; var unitSize = groundY / totalUnits; var bottomHeight = bottomUnit * unitSize; var topHeight = topUnit * unitSize; self.y = groundY; self.bottomTree = self.attachAsset('tree', { anchorX: 0.5, anchorY: 1, width: 300, height: bottomHeight, flipY: false }); self.topTree = self.attachAsset('tree', { anchorX: 0.5, anchorY: 0.5, width: 300, height: topHeight, flipY: false }); self.topTree.rotation = Math.PI; self.topTree.y = -groundY - gapOffset + topHeight / 2; self.zIndex = 1; self.x = 2048 + 800; self.velocityX = -3.6; self.spawned = false; self.prevX = self.x; self.update = function () { if (gameStarted && !gameOver) { self.x += self.velocityX; if (!self.spawned && self.prevX > objectSpawnThreshold && self.x <= objectSpawnThreshold) { self.spawned = true; var newTube = new Tube(); newTube.x = 2048 + 640; game.addChild(newTube); lastSpawner = newTube; } self.prevX = self.x; if (!self.passed && character.x > self.x + self.bottomTree.width / 2) { self.passed = true; updateScore(); } } }; return self; }); /**** * Tube class: Üst ve alt boru oluşturma ****/ var Tube = Container.expand(function () { var self = Container.call(this); var bottomUnit = Math.floor(Math.random() * 8) + 1; var topUnit = 9 - bottomUnit; var unitSize = groundY / totalUnits; var bottomHeight = bottomUnit * unitSize; var topHeight = topUnit * unitSize; self.y = groundY; self.bottomTube = self.attachAsset('tube', { anchorX: 0.5, anchorY: 1, width: 285, //{1C} // 5% thinner height: bottomHeight, flipY: false }); self.topTube = self.attachAsset('tube', { anchorX: 0.5, anchorY: 0.5, width: 285, //{1I} // 5% thinner height: topHeight, flipY: false }); self.topTube.rotation = Math.PI; self.topTube.y = -groundY - gapOffset + topHeight / 2; self.zIndex = 1; self.x = 2048 + 800; self.velocityX = -3.6; self.spawned = false; self.prevX = self.x; self.update = function () { if (gameStarted && !gameOver) { self.x += self.velocityX; if (self.velocityX === 0) { background.velocityX = 0; bg2.velocityX = 0; } if (!self.spawned && self.prevX > objectSpawnThreshold && self.x <= objectSpawnThreshold) { self.spawned = true; var newTree = new Tree(); newTree.x = 2048 + 640; game.addChild(newTree); lastSpawner = newTree; } self.prevX = self.x; if (!self.passed && character.x > self.x + self.bottomTube.width / 2) { self.passed = true; updateScore(); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ /**** * Global Variables & Helper Functions ****/ var groundY = 2732; var menuOpen = true; var volumeOn = true; var records = []; var gapOffset = 400; var gameStarted = false; var gameOver = false; var gameWait = false; var screenRight = 2048; var totalUnits = 10; var tubeSpawnThreshold, treeSpawnThreshold; var lastSpawner = null; var gameOverText = null; var passCounter = 0; var lastScore = 0; var backgroundScrollSpeed = 7.2; var containerScrollSpeed = 5; // Tanımlandı var underscoreTouchCount = 0; var flipped = false; function centerX() { return 2048 / 2; } function centerY() { return groundY / 2; } var objectSpawnThreshold = centerX() + (screenRight - centerX()) / 2; // Örnek container oluşturuluyor var myContainer = new Container(); myContainer.x = centerX(); // Ekranın yatay ortasında myContainer.y = 1900; // Başlangıçta y = 2000 (örneğin en üst sınır) // Sabit yukarı doğru hareket hızı (update fonksiyonunda uygulanacak) var containerUpwardSpeed = -0.5; // Her tıklamada ek olarak uygulanacak aşağı doğru kayma miktarı var extraDownDelta = 50; // Container'ın update fonksiyonu: her frame sabit hızda aşağıya doğru hareket eder myContainer.update = function () { // Oyun başlamışsa yukarı doğru hareket et if (gameStarted) { this.y += containerUpwardSpeed; // Minimum y sınırını 100 olarak ayarlıyoruz if (this.y < 100) { this.y = 100; } } }; // Container'a tıklama (touch/down) olayı ekliyoruz myContainer.on('down', function () { // Tıklamada ekstra aşağı kayma ekliyoruz this.y += extraDownDelta; if (this.y > 2600) { this.y = 2600; } }); // Oluşturulan container'ı oyuna ekleyelim game.addChild(myContainer); var menuContainer = new Container(); menuContainer.zIndex = 200; var menuBackground = LK.getAsset('menu_background', { anchorX: 0.5, anchorY: 0.5, x: centerX(), y: centerY() + 625 }); menuBackground.zIndex = 1000; menuContainer.addChild(menuBackground); var menuBackgroundPart = LK.getAsset('menu_background_part', { anchorX: 0.5, anchorY: 0.19, x: centerX() - 1030, y: centerY() - 2866 }); menuBackgroundPart.zIndex = menuBackground.zIndex + 1; menuBackground.addChild(menuBackgroundPart); var playButton = LK.getAsset('button_play', { anchorX: 0.5, anchorY: 0.5, x: centerX() - 20, y: centerY() + 205 }); playButton.visible = false; menuContainer.addChild(playButton); var playLabel = new Text2("PLAY", { fontFamily: "Arial", fontSize: 630.25 * 1.1 * 1.08 * 1.5 * 1.15 * 1.12, // Biraz daha büyütüldü fill: 0xffff00, // Sarı, daha görünür fontWeight: "bold", align: "center", stroke: 0x000000, strokeThickness: 18 }); playLabel.anchorX = 0.5; playLabel.anchorY = 0.5; // Yıldızın (menuBackground) tam ortasına hizala, biraz sola kaydır playLabel.x = menuBackground.x - 55; playLabel.y = playButton.y + 10; playLabel.visible = true; playLabel.zIndex = 1000; menuContainer.addChild(playLabel); var volumeButton = LK.getAsset('button_volume', { anchorX: 0.5, anchorY: 0.5, x: centerX() - 28, y: centerY() + 320 }); volumeButton.visible = false; menuContainer.addChild(volumeButton); var volumeLabel = new Text2("VOLUME", { fontFamily: "Arial", fontSize: 63.25 * 1.1 * 1.05 * 1.05 * 1.05 * 1.5 * 2.2 * 1.12, // Biraz daha büyütüldü fill: 0xffff00, // Sarı, daha görünür fontWeight: "bold", align: "center", stroke: 0x000000, strokeThickness: 12 }); volumeLabel.anchorX = 0.5; volumeLabel.anchorY = 0.5; volumeLabel.x = menuBackground.x - 55; volumeLabel.y = volumeButton.y + 10; volumeLabel.visible = true; volumeLabel.zIndex = 1000; menuContainer.addChild(volumeLabel); var creditsButton = LK.getAsset('button_credits', { anchorX: 0.5, anchorY: 0.5, x: centerX() - 30, y: centerY() + 429 }); creditsButton.visible = false; menuContainer.addChild(creditsButton); var creditsLabel = new Text2("CREDITS", { fontFamily: "Arial", fontSize: 150.25 * 1.05 * 1.05 * 1.03 * 1.05 * 1.5 * 2.2 * 1.12, // Biraz daha büyütüldü fill: 0xffff00, // Sarı, daha görünür fontWeight: "bold", align: "center", stroke: 0x000000, strokeThickness: 12 }); creditsLabel.anchorX = 0.5; creditsLabel.anchorY = 0.5; creditsLabel.x = menuBackground.x - 55; creditsLabel.y = creditsButton.y + 10; creditsLabel.visible = true; creditsLabel.zIndex = 1000; menuContainer.addChild(creditsLabel); var recordsButton = LK.getAsset('button_records', { anchorX: 0.5, anchorY: 0.5, x: centerX() - 30, y: centerY() + 540 }); recordsButton.visible = false; menuContainer.addChild(recordsButton); var recordsLabel = new Text2("RECORDS", { fontFamily: "Arial", fontSize: 150.25 * 1.05 * 1.05 * 1.03 * 1.05 * 1.5 * 2.2 * 1.12, // Biraz daha büyütüldü fill: 0xffff00, // Sarı, daha görünür fontWeight: "bold", align: "center", stroke: 0x000000, strokeThickness: 12 }); recordsLabel.anchorX = 0.5; recordsLabel.anchorY = 0.5; recordsLabel.x = menuBackground.x - 55; recordsLabel.y = recordsButton.y + 10; recordsLabel.visible = true; recordsLabel.zIndex = 1000; menuContainer.addChild(recordsLabel); var counterText = new Text2('0', { size: 124.2, fill: 0xFFFFFF }); counterText.anchor.set(0, 0); counterText.x = 1315; counterText.y = 15; LK.gui.topLeft.addChild(counterText); var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: centerX(), y: groundY / 2 }); background.zIndex = 0; background.velocityY = 0; background.gravity = 0.033; // 0'a çok yakın bir değer background.jumpStrength = 0.66; // 0'dan daha uzak ama azıcık game.addChild(background); var bg2 = LK.getAsset('bg2', { anchorX: 0.5, anchorY: 0.5, x: centerX() + 2807.2, y: groundY / 2 }); bg2.zIndex = 0; bg2.velocityY = 0; bg2.gravity = 0.033; bg2.jumpStrength = 0.66; game.addChild(bg2); var sky = LK.getAsset('sky', { anchorX: 0.5, anchorY: 0, x: centerX(), y: 0 }); sky.zIndex = 2; game.addChild(sky); var groundAsset = LK.getAsset('ground', { anchorX: 0.5, anchorY: 0.4, x: centerX(), y: groundY - -25 }); groundAsset.zIndex = 4.1; game.addChild(groundAsset); var ground2Asset = LK.getAsset('ground2', { anchorX: 0.5, anchorY: 0.05, x: centerX(), y: groundY - 40 }); ground2Asset.zIndex = 0.5; game.addChild(ground2Asset); function updateScore() { passCounter++; counterText.setText(passCounter); if (passCounter > 9) { counterText.x = 1315 - 25; // Move 25 pixels to the left } else { counterText.x = 1315; // Reset to original position } } // Karakter bağlı 3D arka plan ve efekt – başlangıçta container y = 2400 (en alt sınır) var background3D = LK.getAsset('3dlikebackground', { anchorX: 0.5, anchorY: 0.5 }); var background3DContainer = new Container(); background3DContainer.offsetY = 0; background3DContainer.velocityY = 0; background3DContainer.gravity = 0.3 * 0.178; //0.6 Ay atmosferi benzeri yer çekimi background3DContainer.jumpStrength = 2.15; // Daha hafif yer çekimi için zıplama kuvveti background3DContainer.isInverted = false; background3DContainer.addChild(background3D); background3DContainer.x = centerX(); // Başlangıçta container'lar en altta (2400) background3DContainer.y = 2350; // Container update: oyun başladığında gravity uygulanır, ve y değeri 2000 ile 2400 arasında clamp edilir. background3DContainer.update = function () { if (!gameStarted) { return; } this.velocityY -= this.gravity; this.y += this.velocityY; this.y = Math.max(1900, Math.min(this.y, 2900)); }; game.addChild(background3DContainer); var bgEffect3D = LK.getAsset('3dbgeffect', { anchorX: 0.5, anchorY: 0.5 }); var bgEffect3DContainer = new Container(); bgEffect3DContainer.offsetY = 0; bgEffect3DContainer.velocityY = 0; bgEffect3DContainer.gravity = 0.3 * 0.178; //0.6 Ay atmosferi benzeri yer çekimi bgEffect3DContainer.jumpStrength = 2.15; // Daha hafif yer çekimi için zıplama kuvveti bgEffect3DContainer.isInverted = false; bgEffect3DContainer.addChild(bgEffect3D); bgEffect3DContainer.x = background3DContainer.x + 2807; bgEffect3DContainer.y = 2350; bgEffect3DContainer.update = function () { if (!gameStarted) { return; } this.velocityY -= this.gravity; this.y += this.velocityY; this.y = Math.max(1900, Math.min(this.y, 2900)); }; game.addChild(bgEffect3DContainer); var underscoreAsset = LK.getAsset('_', { anchorX: 0.5, anchorY: 0.5, x: centerX() + 1000, y: centerY() - 1500 // Moved 500 pixels up }); underscoreAsset.zIndex = 15000; game.addChild(underscoreAsset); underscoreAsset.on('down', function () { underscoreTouchCount++; if (underscoreTouchCount >= 5) { character.preventDeath = true; character.preventTreeDeath = true; } }); game.children.sort(function (a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); // Create and add the character var character = game.addChild(new Character()); character.x = centerX(); character.y = centerY(); // Karakterin soluna ve yakınına birkaç tane daha parıltı efekti (halo) ekle var halos = []; var haloConfigs = [ // Ana halo (orijinal) { dx: -25, dy: 10, scale: 1, alpha: 0.7, rotateSpeed: 0.04, delay: 0 }, // Biraz yukarı ve sola, daha küçük ve daha soluk { dx: -40, dy: -10, scale: 0.7, alpha: 0.5, rotateSpeed: 0.03, delay: 200 }, // Biraz aşağı ve sola, daha küçük ve daha soluk { dx: -35, dy: 25, scale: 0.6, alpha: 0.4, rotateSpeed: -0.025, delay: 400 }, // Azıcık daha aşağıya, daha küçük ve daha soluk yeni halo { dx: -30, dy: 45, scale: 0.5, alpha: 0.32, rotateSpeed: 0.018, delay: 600 }, // DAHA AŞAĞIYA yeni halo { dx: -28, dy: 80, scale: 1, // İlk parıltı ile aynı büyüklükte alpha: 0.22, rotateSpeed: -0.012, delay: 800 }, // En alttaki yıldızın sol aşağı çaprazına yeni yıldız { dx: -60, // daha sola dy: 110, // daha aşağıya scale: 0.8, alpha: 0.28, rotateSpeed: 0.015, delay: 1000 }]; for (var i = 0; i < haloConfigs.length; i++) { var cfg = haloConfigs[i]; // Halo boyutlarını ve oranlarını texture ile daha dengeli yapmak için: // Orijinal asset oranı: 100x110 (en/boy = 0.91) // Her bir halo için width ve height ayrı ayrı scale edilecek şekilde ayarlanıyor. // Texture oranı korunacak şekilde height = width * 1.1 var baseWidth = 60 * cfg.scale; var baseHeight = baseWidth * 1.1; var halo = LK.getAsset('haloAsset', { anchorX: 0.5, anchorY: 0.5, width: baseWidth, height: baseHeight, x: character.x - character.width / 2 + cfg.dx, y: character.y + cfg.dy }); halo.zIndex = character.zIndex - 1; halo.alpha = cfg.alpha; halo._haloConfig = cfg; game.addChild(halo); halos.push(halo); } // Her halo için ayrı animasyon fonksiyonu function animateHaloIdx(idx) { var halo = halos[idx]; var cfg = halo._haloConfig; tween(halo, { alpha: cfg.alpha * 0.3 }, { duration: 400, onFinish: function onFinish() { tween(halo, { alpha: cfg.alpha }, { duration: 400, onFinish: function onFinish() { animateHaloIdx(idx); } }); } }); } // Animasyonları başlat (her biri farklı gecikmeyle) for (var i = 0; i < halos.length; i++) { (function (idx) { LK.setTimeout(function () { animateHaloIdx(idx); }, haloConfigs[idx].delay); })(i); } // Her halo karakteri takip etsin ve döndürsün for (var i = 0; i < halos.length; i++) { (function (idx) { var halo = halos[idx]; var cfg = halo._haloConfig; halo.update = function () { this.x = character.x - character.width / 2 + cfg.dx; this.y = character.y + cfg.dy; this.rotation += cfg.rotateSpeed; }; })(i); } // Menü konumunu ayarla menuContainer.y += 100; game.addChild(menuContainer); /**** * Helper Functions: Credits, Volume & Records ****/ function createCommonCloseElements(modalWidth, modalHeight) { var closeLabel = LK.getAsset('justX', { anchorX: 0.5, anchorY: 0.5, zIndex: 100000, x: -9, y: 6 }); var radius = 50; var closeButton = LK.getAsset('button_close', { anchorX: 0.5, anchorY: 0.5, width: radius * 2.3 * 1.2, height: radius * 2.3 * 1.2 }); closeButton.zIndex = 10000; closeButton.x = 0; closeButton.y = 0; closeButton.addChild(closeLabel); return closeButton; } function showCredits() { menuOpen = false; var creditsContainer = new Container(); creditsContainer.zIndex = 300; var modalWidth = 1500, modalHeight = 2200; var bg = LK.getAsset('second_menu', { anchorX: 0.5, anchorY: 0.5, width: modalWidth, height: modalHeight, color: 0x000000 }); bg.x = centerX(); bg.y = centerY(); creditsContainer.addChild(bg); var creditsText = new Text2("yiğit emre şahin", { fontFamily: "Arial", fontSize: 1200, // Baya bir büyük boyut fill: 0xffffff, align: "center" }); creditsText.anchorX = 0.5; creditsText.anchorY = 0.5; // Modalın tam ortasına yerleştir creditsText.x = centerX(); creditsText.y = centerY(); creditsContainer.addChild(creditsText); game.addChild(creditsContainer); var closeButton = createCommonCloseElements(modalWidth, modalHeight); closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 185; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 230; creditsContainer.addChild(closeButton); closeButton.on('down', function () { game.removeChild(creditsContainer); menuOpen = true; menuContainer.visible = true; }); } function showVolume() { menuOpen = false; var volumeContainer = new Container(); volumeContainer.zIndex = 300; var modalWidth = 1500, modalHeight = 2200; var bg = LK.getAsset('second_menu', { anchorX: 0.5, anchorY: 0.5, width: modalWidth, height: modalHeight, color: 0x000000 }); bg.x = centerX(); bg.y = centerY(); volumeContainer.addChild(bg); var currentMusicName = new Text2("Next Music", { fontFamily: "Arial", fontSize: 5000 * 1.103, fill: 0xffffff, align: "center" }); currentMusicName.anchorX = 0.5; currentMusicName.anchorY = 0.5; currentMusicName.x = centerX() - 250; currentMusicName.y = centerY() - 650 + 40 - 300 + 100; currentMusicName.scale.set(3, 3); volumeContainer.addChild(currentMusicName); var musicButton = LK.getAsset('Musicbutton', { anchorX: 0.5, anchorY: 0.5, x: centerX() - 280 + 250, y: centerY() - 350 + 40 - 150 }); musicButton.on('down', function () { playNextMusic(); }); volumeContainer.addChild(musicButton); game.addChild(volumeContainer); var closeButton = createCommonCloseElements(modalWidth, modalHeight); closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 185; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 230; volumeContainer.addChild(closeButton); closeButton.on('down', function () { game.removeChild(volumeContainer); menuOpen = true; menuContainer.visible = true; }); } function showRecords() { menuOpen = false; var recordsContainer = new Container(); recordsContainer.zIndex = 300; var modalWidth = 1500, modalHeight = 2200; var bg = LK.getAsset('second_menu', { anchorX: 0.5, anchorY: 0.5, width: modalWidth, height: modalHeight, color: 0x000000 }); bg.x = centerX(); bg.y = centerY(); recordsContainer.addChild(bg); var recordsTextStr = "Top Scores:\n"; for (var i = 0; i < records.length; i++) { recordsTextStr += i + 1 + ". " + records[i].score + " (Attempt " + records[i].attempt + ")\n"; } if (records.length === 0) { recordsTextStr += "No records yet."; } recordsTextStr += "\nAttempts: " + records.length; recordsTextStr += "\nLast Score: " + lastScore; var recordsText = new Text2(recordsTextStr, { fontFamily: "Arial", fontSize: 5000 * 1.103, fill: 0xffffff, align: "center" }); recordsText.anchorX = 0.5; recordsText.anchorY = 0.5; recordsText.x = centerX() - 280; recordsText.y = centerY() - 850 + 40; recordsText.scale.set(3, 3); recordsContainer.addChild(recordsText); game.addChild(recordsContainer); var closeButton = createCommonCloseElements(modalWidth, modalHeight); closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 185; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 230; recordsContainer.addChild(closeButton); closeButton.on('down', function () { game.removeChild(recordsContainer); menuOpen = true; menuContainer.visible = true; }); } /**** * End Game & Reset Functions ****/ function playNextMusic() { musicCycle++; if (musicCycle === 1) { LK.stopMusic(); LK.playMusic(musicSequence[1]); } else if (musicCycle === 2) { LK.stopMusic(); LK.playMusic(musicSequence[2]); } else if (musicCycle === 3) { LK.stopMusic(); } else { musicCycle = 0; LK.stopMusic(); LK.playMusic(musicSequence[0]); } } var musicSequence = ['m_1', 'M_2', 'M_3']; var musicCycle = 0; LK.playMusic(musicSequence[0]); function endGame() { LK.effects.flashScreen(0xFF0000, 500); LK.getSound('deatheffect').play(); character.velocityY = character.jumpStrength; character.update = function () { if (gameOver) { character.velocityY += character.gravity; character.y += character.velocityY; if (character.y > groundY + character.height) { character.y = groundY + character.height; character.velocityY = 0; } } }; game.children.forEach(function (child) { if (child.velocityX) { child.velocityX = 0; } if (child === background || child === bg2) { LK.setTimeout(function () { child.velocityY = 0; }, 300); } }); game.touchDisabled = true; lastScore = passCounter; records.push({ score: passCounter, attempt: records.length + 1 }); records.sort(function (a, b) { return b.score - a.score; }); if (records.length > 5) { records = records.slice(0, 5); } LK.setTimeout(function () { game.touchDisabled = false; menuOpen = true; menuContainer.visible = true; var startY = groundY + 100; var endY = centerY() - 1270; var animationDuration = 16.5 * 5 / 1.5; var startTime = Date.now(); function animateMenu() { var currentTime = Date.now(); var elapsedTime = currentTime - startTime; var progress = Math.min(elapsedTime / animationDuration, 1); menuContainer.y = startY + (endY - startY) * progress; if (progress < 1) { LK.setTimeout(animateMenu, 16); } } animateMenu(); }, 1700); LK.setTimeout(function () { resetGame(); }, 1750); } function resetGame() { if (gameOverText) { game.removeChild(gameOverText); gameOverText = null; } unflipWorld(); var objectsToRemove = []; game.children.forEach(function (child) { if (child instanceof Tree || child instanceof Tube) { objectsToRemove.push(child); } }); objectsToRemove.forEach(function (obj) { game.removeChild(obj); }); game.removeChild(character); character = game.addChild(new Character()); character.x = centerX(); character.y = centerY(); background.x = centerX(); background.y = groundY / 2; bg2.x = centerX() + 2807.2; bg2.y = groundY / 2; background.velocityX = -3.6; bg2.velocityX = -3.6; bg2.scale.x = 1; gameStarted = false; gameOver = false; character.preventDeath = false; underscoreAsset.preventDeath = false; lastSpawner = null; passCounter = 0; underscoreTouchCount = 0; counterText.setText(passCounter); // Reset container'ların konumunu ve velocity değerlerini background3DContainer.y = 2350; bgEffect3DContainer.y = 2350; background3DContainer.velocityY = 0; bgEffect3DContainer.velocityY = 0; } /**** * Eliptik hit testi için yardımcı fonksiyon ****/ function checkEllipseHover(button, lx, ly) { var scaleFactorX = 1; var scaleFactorY = 0.53; var offsetY = 40; var dx = lx - button.x; var dy = ly - (button.y + offsetY); var rx = button.width / 2 * scaleFactorX; var ry = button.height / 2 * scaleFactorY; return dx * dx / (rx * rx) + dy * dy / (ry * ry) <= 1; } /**** * Fare hareketinde hover kontrolü ****/ game.move = function (x, y, obj) { if (!menuOpen) { return; } var localX = x - menuContainer.x; var localY = y - menuContainer.y; playButton.visible = checkEllipseHover(playButton, localX, localY); volumeButton.visible = checkEllipseHover(volumeButton, localX, localY); creditsButton.visible = checkEllipseHover(creditsButton, localX, localY); recordsButton.visible = checkEllipseHover(recordsButton, localX, localY); }; /**** * Touch Event ****/ game.down = function (x, y, obj) { if (menuOpen) { var localX = x - menuContainer.x; var localY = y - menuContainer.y; if (checkEllipseHover(playButton, localX, localY)) { var _animateMenu = function animateMenu() { var currentTime = Date.now(); var elapsedTime = currentTime - startTime; var progress = Math.min(elapsedTime / animationDuration, 1); menuContainer.y = startY + (endY - startY) * progress; if (progress < 1) { LK.setTimeout(_animateMenu, 1); } else { menuOpen = false; menuContainer.visible = false; gameWait = true; } }; var animationDuration = 16.5 * 5 * 2 / 1.5; var startTime = Date.now(); var startY = menuContainer.y; var endY = centerY() + 100; _animateMenu(); return; } else if (checkEllipseHover(volumeButton, localX, localY)) { showVolume(); } else if (checkEllipseHover(creditsButton, localX, localY)) { showCredits(); } else if (checkEllipseHover(recordsButton, localX, localY)) { showRecords(); } return; } else if (gameOver) { if (!game.touchDisabled) { menuOpen = true; menuContainer.visible = true; resetGame(); } } else { if (gameWait) { gameWait = false; gameStarted = true; var initialTube = new Tube(); game.addChild(initialTube); lastSpawner = initialTube; character.jump(); } else { character.jump(); character.rotation = 0.1; LK.setTimeout(function () { character.rotation = 0; }, 200); } } }; /**** * Game Loop ****/ game.update = function () { game.children.forEach(function (child) { if (child.update) { child.update(); } if (child === background || child === bg2) { if (!gameOver && !menuOpen && gameStarted) { child.x -= 3.0; child.velocityY -= child.gravity; child.y += child.velocityY; } if (child.x < -2807.2 / 2) { child.x += 2807.2 * 2; } } if (child === background3DContainer || child === bgEffect3DContainer) { if (!gameOver && !menuOpen && gameStarted) { child.x -= containerScrollSpeed * 1.2; } if (child.x < -2807.2 / 2) { child.x += 2807.2 * 2; } } }); game.children.sort(function (a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); }; function unflipWorld() { if (!flipped) { return; } flipped = false; character.gravity = 0; character.jumpStrength = 0; zoomEffect(); LK.setTimeout(function () { character.gravity = 0.3; character.jumpStrength = -12; }, 300); background.scale.y *= -1; bg2.scale.y *= -1; sky.scale.y *= -1; groundAsset.scale.y *= -1; ground2Asset.scale.y *= -1; } function zoomEffect() { var originalScale = character.scale.x; character.scale.set(originalScale * 1.2); LK.setTimeout(function () { character.scale.set(originalScale); }, 300); } function flipWorld() { if (flipped) { return; } flipped = true; character.gravity = 0; character.jumpStrength = 0; zoomEffect(); LK.setTimeout(function () { character.gravity = 0.3; character.jumpStrength = -12; }, 300); background.scale.y *= -1; bg2.scale.y *= -1; sky.scale.y *= -1; groundAsset.scale.y *= -1; ground2Asset.scale.y *= -1; }
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
/****
* Character: Dokunulduğunda zıplar.
****/
var Character = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.zIndex = 4;
self.velocityY = 0;
self.gravity = 0.3;
self.jumpStrength = -12.1;
self.width = 350;
self.height = 300;
self.update = function () {
if (gameStarted && !gameOver) {
self.velocityY += self.gravity;
self.y += self.velocityY;
if (self.y > groundY - 100) {
self.y = groundY - 100;
self.velocityY = 0;
if (!self.intersects(underscoreAsset) && !self.preventDeath) {
gameOver = true;
endGame();
}
}
var characterLeft = self.x - self.width / 2;
var characterRight = self.x + self.width / 2;
var characterTop = self.y - self.height / 2;
var characterBottom = self.y + self.height / 2;
if (characterLeft + self.width / 2 < 0 || characterRight - self.width / 2 > screenRight || characterTop + self.height / 2 < 0 || characterBottom - self.height / 2 > groundY) {
gameOver = true;
endGame();
}
game.children.forEach(function (child) {
if (child instanceof Tube) {
var tubeLeft = child.x - child.bottomTube.width / 2;
var tubeRight = child.x + child.bottomTube.width / 2;
var safeGapLowerEdge = child.y - child.bottomTube.height;
var safeGapUpperEdge = -gapOffset + child.topTube.height;
if (self.x + self.width / 2 > tubeLeft && self.x - self.width / 2 < tubeRight) {
if (self.y < safeGapUpperEdge || self.y > safeGapLowerEdge) {
if (!self.intersects(underscoreAsset) && !self.preventDeath) {
gameOver = true;
endGame();
}
}
}
} else if (child instanceof Tree) {
var treeLeft = child.x - child.bottomTree.width / 2;
var treeRight = child.x + child.bottomTree.width / 2;
var safeGapLowerEdge = child.y - child.bottomTree.height;
var safeGapUpperEdge = -gapOffset + child.topTree.height;
if (self.x + self.width / 2 > treeLeft && self.x - self.width / 2 < treeRight) {
if (self.y < safeGapUpperEdge || self.y > safeGapLowerEdge) {
if (!self.intersects(underscoreAsset) && !self.preventTreeDeath) {
gameOver = true;
endGame();
}
}
}
}
});
}
};
self.jump = function () {
if (!gameOver && gameStarted) {
self.velocityY = self.jumpStrength;
LK.getSound('wingeffect').play();
// Karakter zıpladığında background ve bg2'ye de jump etkisi uyguluyoruz:
background.velocityY = background.jumpStrength;
bg2.velocityY = bg2.jumpStrength;
background3DContainer.velocityY = background3DContainer.jumpStrength;
bgEffect3DContainer.velocityY = bgEffect3DContainer.jumpStrength;
}
};
return self;
});
/****
* GameOverText class
****/
var GameOverText = Container.expand(function () {
var self = Container.call(this);
self.text = new Text2("GAME OVER", {
fontFamily: "Arial",
fontSize: 2250,
fill: 0xFF0000,
align: "center",
fontWeight: "bold"
});
self.text.anchorX = 0.5;
self.text.anchorY = 0.5;
self.addChild(self.text);
self.zIndex = 100;
return self;
});
/****
* Tree class: Üst ve alt ağaç oluşturma
****/
var Tree = Container.expand(function () {
var self = Container.call(this);
var bottomUnit = Math.floor(Math.random() * 8) + 1;
var topUnit = 9 - bottomUnit;
var unitSize = groundY / totalUnits;
var bottomHeight = bottomUnit * unitSize;
var topHeight = topUnit * unitSize;
self.y = groundY;
self.bottomTree = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1,
width: 300,
height: bottomHeight,
flipY: false
});
self.topTree = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: topHeight,
flipY: false
});
self.topTree.rotation = Math.PI;
self.topTree.y = -groundY - gapOffset + topHeight / 2;
self.zIndex = 1;
self.x = 2048 + 800;
self.velocityX = -3.6;
self.spawned = false;
self.prevX = self.x;
self.update = function () {
if (gameStarted && !gameOver) {
self.x += self.velocityX;
if (!self.spawned && self.prevX > objectSpawnThreshold && self.x <= objectSpawnThreshold) {
self.spawned = true;
var newTube = new Tube();
newTube.x = 2048 + 640;
game.addChild(newTube);
lastSpawner = newTube;
}
self.prevX = self.x;
if (!self.passed && character.x > self.x + self.bottomTree.width / 2) {
self.passed = true;
updateScore();
}
}
};
return self;
});
/****
* Tube class: Üst ve alt boru oluşturma
****/
var Tube = Container.expand(function () {
var self = Container.call(this);
var bottomUnit = Math.floor(Math.random() * 8) + 1;
var topUnit = 9 - bottomUnit;
var unitSize = groundY / totalUnits;
var bottomHeight = bottomUnit * unitSize;
var topHeight = topUnit * unitSize;
self.y = groundY;
self.bottomTube = self.attachAsset('tube', {
anchorX: 0.5,
anchorY: 1,
width: 285,
//{1C} // 5% thinner
height: bottomHeight,
flipY: false
});
self.topTube = self.attachAsset('tube', {
anchorX: 0.5,
anchorY: 0.5,
width: 285,
//{1I} // 5% thinner
height: topHeight,
flipY: false
});
self.topTube.rotation = Math.PI;
self.topTube.y = -groundY - gapOffset + topHeight / 2;
self.zIndex = 1;
self.x = 2048 + 800;
self.velocityX = -3.6;
self.spawned = false;
self.prevX = self.x;
self.update = function () {
if (gameStarted && !gameOver) {
self.x += self.velocityX;
if (self.velocityX === 0) {
background.velocityX = 0;
bg2.velocityX = 0;
}
if (!self.spawned && self.prevX > objectSpawnThreshold && self.x <= objectSpawnThreshold) {
self.spawned = true;
var newTree = new Tree();
newTree.x = 2048 + 640;
game.addChild(newTree);
lastSpawner = newTree;
}
self.prevX = self.x;
if (!self.passed && character.x > self.x + self.bottomTube.width / 2) {
self.passed = true;
updateScore();
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
/****
* Global Variables & Helper Functions
****/
var groundY = 2732;
var menuOpen = true;
var volumeOn = true;
var records = [];
var gapOffset = 400;
var gameStarted = false;
var gameOver = false;
var gameWait = false;
var screenRight = 2048;
var totalUnits = 10;
var tubeSpawnThreshold, treeSpawnThreshold;
var lastSpawner = null;
var gameOverText = null;
var passCounter = 0;
var lastScore = 0;
var backgroundScrollSpeed = 7.2;
var containerScrollSpeed = 5; // Tanımlandı
var underscoreTouchCount = 0;
var flipped = false;
function centerX() {
return 2048 / 2;
}
function centerY() {
return groundY / 2;
}
var objectSpawnThreshold = centerX() + (screenRight - centerX()) / 2;
// Örnek container oluşturuluyor
var myContainer = new Container();
myContainer.x = centerX(); // Ekranın yatay ortasında
myContainer.y = 1900; // Başlangıçta y = 2000 (örneğin en üst sınır)
// Sabit yukarı doğru hareket hızı (update fonksiyonunda uygulanacak)
var containerUpwardSpeed = -0.5;
// Her tıklamada ek olarak uygulanacak aşağı doğru kayma miktarı
var extraDownDelta = 50;
// Container'ın update fonksiyonu: her frame sabit hızda aşağıya doğru hareket eder
myContainer.update = function () {
// Oyun başlamışsa yukarı doğru hareket et
if (gameStarted) {
this.y += containerUpwardSpeed;
// Minimum y sınırını 100 olarak ayarlıyoruz
if (this.y < 100) {
this.y = 100;
}
}
};
// Container'a tıklama (touch/down) olayı ekliyoruz
myContainer.on('down', function () {
// Tıklamada ekstra aşağı kayma ekliyoruz
this.y += extraDownDelta;
if (this.y > 2600) {
this.y = 2600;
}
});
// Oluşturulan container'ı oyuna ekleyelim
game.addChild(myContainer);
var menuContainer = new Container();
menuContainer.zIndex = 200;
var menuBackground = LK.getAsset('menu_background', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX(),
y: centerY() + 625
});
menuBackground.zIndex = 1000;
menuContainer.addChild(menuBackground);
var menuBackgroundPart = LK.getAsset('menu_background_part', {
anchorX: 0.5,
anchorY: 0.19,
x: centerX() - 1030,
y: centerY() - 2866
});
menuBackgroundPart.zIndex = menuBackground.zIndex + 1;
menuBackground.addChild(menuBackgroundPart);
var playButton = LK.getAsset('button_play', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX() - 20,
y: centerY() + 205
});
playButton.visible = false;
menuContainer.addChild(playButton);
var playLabel = new Text2("PLAY", {
fontFamily: "Arial",
fontSize: 630.25 * 1.1 * 1.08 * 1.5 * 1.15 * 1.12,
// Biraz daha büyütüldü
fill: 0xffff00,
// Sarı, daha görünür
fontWeight: "bold",
align: "center",
stroke: 0x000000,
strokeThickness: 18
});
playLabel.anchorX = 0.5;
playLabel.anchorY = 0.5;
// Yıldızın (menuBackground) tam ortasına hizala, biraz sola kaydır
playLabel.x = menuBackground.x - 55;
playLabel.y = playButton.y + 10;
playLabel.visible = true;
playLabel.zIndex = 1000;
menuContainer.addChild(playLabel);
var volumeButton = LK.getAsset('button_volume', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX() - 28,
y: centerY() + 320
});
volumeButton.visible = false;
menuContainer.addChild(volumeButton);
var volumeLabel = new Text2("VOLUME", {
fontFamily: "Arial",
fontSize: 63.25 * 1.1 * 1.05 * 1.05 * 1.05 * 1.5 * 2.2 * 1.12,
// Biraz daha büyütüldü
fill: 0xffff00,
// Sarı, daha görünür
fontWeight: "bold",
align: "center",
stroke: 0x000000,
strokeThickness: 12
});
volumeLabel.anchorX = 0.5;
volumeLabel.anchorY = 0.5;
volumeLabel.x = menuBackground.x - 55;
volumeLabel.y = volumeButton.y + 10;
volumeLabel.visible = true;
volumeLabel.zIndex = 1000;
menuContainer.addChild(volumeLabel);
var creditsButton = LK.getAsset('button_credits', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX() - 30,
y: centerY() + 429
});
creditsButton.visible = false;
menuContainer.addChild(creditsButton);
var creditsLabel = new Text2("CREDITS", {
fontFamily: "Arial",
fontSize: 150.25 * 1.05 * 1.05 * 1.03 * 1.05 * 1.5 * 2.2 * 1.12,
// Biraz daha büyütüldü
fill: 0xffff00,
// Sarı, daha görünür
fontWeight: "bold",
align: "center",
stroke: 0x000000,
strokeThickness: 12
});
creditsLabel.anchorX = 0.5;
creditsLabel.anchorY = 0.5;
creditsLabel.x = menuBackground.x - 55;
creditsLabel.y = creditsButton.y + 10;
creditsLabel.visible = true;
creditsLabel.zIndex = 1000;
menuContainer.addChild(creditsLabel);
var recordsButton = LK.getAsset('button_records', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX() - 30,
y: centerY() + 540
});
recordsButton.visible = false;
menuContainer.addChild(recordsButton);
var recordsLabel = new Text2("RECORDS", {
fontFamily: "Arial",
fontSize: 150.25 * 1.05 * 1.05 * 1.03 * 1.05 * 1.5 * 2.2 * 1.12,
// Biraz daha büyütüldü
fill: 0xffff00,
// Sarı, daha görünür
fontWeight: "bold",
align: "center",
stroke: 0x000000,
strokeThickness: 12
});
recordsLabel.anchorX = 0.5;
recordsLabel.anchorY = 0.5;
recordsLabel.x = menuBackground.x - 55;
recordsLabel.y = recordsButton.y + 10;
recordsLabel.visible = true;
recordsLabel.zIndex = 1000;
menuContainer.addChild(recordsLabel);
var counterText = new Text2('0', {
size: 124.2,
fill: 0xFFFFFF
});
counterText.anchor.set(0, 0);
counterText.x = 1315;
counterText.y = 15;
LK.gui.topLeft.addChild(counterText);
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX(),
y: groundY / 2
});
background.zIndex = 0;
background.velocityY = 0;
background.gravity = 0.033; // 0'a çok yakın bir değer
background.jumpStrength = 0.66; // 0'dan daha uzak ama azıcık
game.addChild(background);
var bg2 = LK.getAsset('bg2', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX() + 2807.2,
y: groundY / 2
});
bg2.zIndex = 0;
bg2.velocityY = 0;
bg2.gravity = 0.033;
bg2.jumpStrength = 0.66;
game.addChild(bg2);
var sky = LK.getAsset('sky', {
anchorX: 0.5,
anchorY: 0,
x: centerX(),
y: 0
});
sky.zIndex = 2;
game.addChild(sky);
var groundAsset = LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.4,
x: centerX(),
y: groundY - -25
});
groundAsset.zIndex = 4.1;
game.addChild(groundAsset);
var ground2Asset = LK.getAsset('ground2', {
anchorX: 0.5,
anchorY: 0.05,
x: centerX(),
y: groundY - 40
});
ground2Asset.zIndex = 0.5;
game.addChild(ground2Asset);
function updateScore() {
passCounter++;
counterText.setText(passCounter);
if (passCounter > 9) {
counterText.x = 1315 - 25; // Move 25 pixels to the left
} else {
counterText.x = 1315; // Reset to original position
}
}
// Karakter bağlı 3D arka plan ve efekt – başlangıçta container y = 2400 (en alt sınır)
var background3D = LK.getAsset('3dlikebackground', {
anchorX: 0.5,
anchorY: 0.5
});
var background3DContainer = new Container();
background3DContainer.offsetY = 0;
background3DContainer.velocityY = 0;
background3DContainer.gravity = 0.3 * 0.178; //0.6 Ay atmosferi benzeri yer çekimi
background3DContainer.jumpStrength = 2.15; // Daha hafif yer çekimi için zıplama kuvveti
background3DContainer.isInverted = false;
background3DContainer.addChild(background3D);
background3DContainer.x = centerX();
// Başlangıçta container'lar en altta (2400)
background3DContainer.y = 2350;
// Container update: oyun başladığında gravity uygulanır, ve y değeri 2000 ile 2400 arasında clamp edilir.
background3DContainer.update = function () {
if (!gameStarted) {
return;
}
this.velocityY -= this.gravity;
this.y += this.velocityY;
this.y = Math.max(1900, Math.min(this.y, 2900));
};
game.addChild(background3DContainer);
var bgEffect3D = LK.getAsset('3dbgeffect', {
anchorX: 0.5,
anchorY: 0.5
});
var bgEffect3DContainer = new Container();
bgEffect3DContainer.offsetY = 0;
bgEffect3DContainer.velocityY = 0;
bgEffect3DContainer.gravity = 0.3 * 0.178; //0.6 Ay atmosferi benzeri yer çekimi
bgEffect3DContainer.jumpStrength = 2.15; // Daha hafif yer çekimi için zıplama kuvveti
bgEffect3DContainer.isInverted = false;
bgEffect3DContainer.addChild(bgEffect3D);
bgEffect3DContainer.x = background3DContainer.x + 2807;
bgEffect3DContainer.y = 2350;
bgEffect3DContainer.update = function () {
if (!gameStarted) {
return;
}
this.velocityY -= this.gravity;
this.y += this.velocityY;
this.y = Math.max(1900, Math.min(this.y, 2900));
};
game.addChild(bgEffect3DContainer);
var underscoreAsset = LK.getAsset('_', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX() + 1000,
y: centerY() - 1500 // Moved 500 pixels up
});
underscoreAsset.zIndex = 15000;
game.addChild(underscoreAsset);
underscoreAsset.on('down', function () {
underscoreTouchCount++;
if (underscoreTouchCount >= 5) {
character.preventDeath = true;
character.preventTreeDeath = true;
}
});
game.children.sort(function (a, b) {
return (a.zIndex || 0) - (b.zIndex || 0);
});
// Create and add the character
var character = game.addChild(new Character());
character.x = centerX();
character.y = centerY();
// Karakterin soluna ve yakınına birkaç tane daha parıltı efekti (halo) ekle
var halos = [];
var haloConfigs = [
// Ana halo (orijinal)
{
dx: -25,
dy: 10,
scale: 1,
alpha: 0.7,
rotateSpeed: 0.04,
delay: 0
},
// Biraz yukarı ve sola, daha küçük ve daha soluk
{
dx: -40,
dy: -10,
scale: 0.7,
alpha: 0.5,
rotateSpeed: 0.03,
delay: 200
},
// Biraz aşağı ve sola, daha küçük ve daha soluk
{
dx: -35,
dy: 25,
scale: 0.6,
alpha: 0.4,
rotateSpeed: -0.025,
delay: 400
},
// Azıcık daha aşağıya, daha küçük ve daha soluk yeni halo
{
dx: -30,
dy: 45,
scale: 0.5,
alpha: 0.32,
rotateSpeed: 0.018,
delay: 600
},
// DAHA AŞAĞIYA yeni halo
{
dx: -28,
dy: 80,
scale: 1,
// İlk parıltı ile aynı büyüklükte
alpha: 0.22,
rotateSpeed: -0.012,
delay: 800
},
// En alttaki yıldızın sol aşağı çaprazına yeni yıldız
{
dx: -60,
// daha sola
dy: 110,
// daha aşağıya
scale: 0.8,
alpha: 0.28,
rotateSpeed: 0.015,
delay: 1000
}];
for (var i = 0; i < haloConfigs.length; i++) {
var cfg = haloConfigs[i];
// Halo boyutlarını ve oranlarını texture ile daha dengeli yapmak için:
// Orijinal asset oranı: 100x110 (en/boy = 0.91)
// Her bir halo için width ve height ayrı ayrı scale edilecek şekilde ayarlanıyor.
// Texture oranı korunacak şekilde height = width * 1.1
var baseWidth = 60 * cfg.scale;
var baseHeight = baseWidth * 1.1;
var halo = LK.getAsset('haloAsset', {
anchorX: 0.5,
anchorY: 0.5,
width: baseWidth,
height: baseHeight,
x: character.x - character.width / 2 + cfg.dx,
y: character.y + cfg.dy
});
halo.zIndex = character.zIndex - 1;
halo.alpha = cfg.alpha;
halo._haloConfig = cfg;
game.addChild(halo);
halos.push(halo);
}
// Her halo için ayrı animasyon fonksiyonu
function animateHaloIdx(idx) {
var halo = halos[idx];
var cfg = halo._haloConfig;
tween(halo, {
alpha: cfg.alpha * 0.3
}, {
duration: 400,
onFinish: function onFinish() {
tween(halo, {
alpha: cfg.alpha
}, {
duration: 400,
onFinish: function onFinish() {
animateHaloIdx(idx);
}
});
}
});
}
// Animasyonları başlat (her biri farklı gecikmeyle)
for (var i = 0; i < halos.length; i++) {
(function (idx) {
LK.setTimeout(function () {
animateHaloIdx(idx);
}, haloConfigs[idx].delay);
})(i);
}
// Her halo karakteri takip etsin ve döndürsün
for (var i = 0; i < halos.length; i++) {
(function (idx) {
var halo = halos[idx];
var cfg = halo._haloConfig;
halo.update = function () {
this.x = character.x - character.width / 2 + cfg.dx;
this.y = character.y + cfg.dy;
this.rotation += cfg.rotateSpeed;
};
})(i);
}
// Menü konumunu ayarla
menuContainer.y += 100;
game.addChild(menuContainer);
/****
* Helper Functions: Credits, Volume & Records
****/
function createCommonCloseElements(modalWidth, modalHeight) {
var closeLabel = LK.getAsset('justX', {
anchorX: 0.5,
anchorY: 0.5,
zIndex: 100000,
x: -9,
y: 6
});
var radius = 50;
var closeButton = LK.getAsset('button_close', {
anchorX: 0.5,
anchorY: 0.5,
width: radius * 2.3 * 1.2,
height: radius * 2.3 * 1.2
});
closeButton.zIndex = 10000;
closeButton.x = 0;
closeButton.y = 0;
closeButton.addChild(closeLabel);
return closeButton;
}
function showCredits() {
menuOpen = false;
var creditsContainer = new Container();
creditsContainer.zIndex = 300;
var modalWidth = 1500,
modalHeight = 2200;
var bg = LK.getAsset('second_menu', {
anchorX: 0.5,
anchorY: 0.5,
width: modalWidth,
height: modalHeight,
color: 0x000000
});
bg.x = centerX();
bg.y = centerY();
creditsContainer.addChild(bg);
var creditsText = new Text2("yiğit emre şahin", {
fontFamily: "Arial",
fontSize: 1200,
// Baya bir büyük boyut
fill: 0xffffff,
align: "center"
});
creditsText.anchorX = 0.5;
creditsText.anchorY = 0.5;
// Modalın tam ortasına yerleştir
creditsText.x = centerX();
creditsText.y = centerY();
creditsContainer.addChild(creditsText);
game.addChild(creditsContainer);
var closeButton = createCommonCloseElements(modalWidth, modalHeight);
closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 185;
closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 230;
creditsContainer.addChild(closeButton);
closeButton.on('down', function () {
game.removeChild(creditsContainer);
menuOpen = true;
menuContainer.visible = true;
});
}
function showVolume() {
menuOpen = false;
var volumeContainer = new Container();
volumeContainer.zIndex = 300;
var modalWidth = 1500,
modalHeight = 2200;
var bg = LK.getAsset('second_menu', {
anchorX: 0.5,
anchorY: 0.5,
width: modalWidth,
height: modalHeight,
color: 0x000000
});
bg.x = centerX();
bg.y = centerY();
volumeContainer.addChild(bg);
var currentMusicName = new Text2("Next Music", {
fontFamily: "Arial",
fontSize: 5000 * 1.103,
fill: 0xffffff,
align: "center"
});
currentMusicName.anchorX = 0.5;
currentMusicName.anchorY = 0.5;
currentMusicName.x = centerX() - 250;
currentMusicName.y = centerY() - 650 + 40 - 300 + 100;
currentMusicName.scale.set(3, 3);
volumeContainer.addChild(currentMusicName);
var musicButton = LK.getAsset('Musicbutton', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX() - 280 + 250,
y: centerY() - 350 + 40 - 150
});
musicButton.on('down', function () {
playNextMusic();
});
volumeContainer.addChild(musicButton);
game.addChild(volumeContainer);
var closeButton = createCommonCloseElements(modalWidth, modalHeight);
closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 185;
closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 230;
volumeContainer.addChild(closeButton);
closeButton.on('down', function () {
game.removeChild(volumeContainer);
menuOpen = true;
menuContainer.visible = true;
});
}
function showRecords() {
menuOpen = false;
var recordsContainer = new Container();
recordsContainer.zIndex = 300;
var modalWidth = 1500,
modalHeight = 2200;
var bg = LK.getAsset('second_menu', {
anchorX: 0.5,
anchorY: 0.5,
width: modalWidth,
height: modalHeight,
color: 0x000000
});
bg.x = centerX();
bg.y = centerY();
recordsContainer.addChild(bg);
var recordsTextStr = "Top Scores:\n";
for (var i = 0; i < records.length; i++) {
recordsTextStr += i + 1 + ". " + records[i].score + " (Attempt " + records[i].attempt + ")\n";
}
if (records.length === 0) {
recordsTextStr += "No records yet.";
}
recordsTextStr += "\nAttempts: " + records.length;
recordsTextStr += "\nLast Score: " + lastScore;
var recordsText = new Text2(recordsTextStr, {
fontFamily: "Arial",
fontSize: 5000 * 1.103,
fill: 0xffffff,
align: "center"
});
recordsText.anchorX = 0.5;
recordsText.anchorY = 0.5;
recordsText.x = centerX() - 280;
recordsText.y = centerY() - 850 + 40;
recordsText.scale.set(3, 3);
recordsContainer.addChild(recordsText);
game.addChild(recordsContainer);
var closeButton = createCommonCloseElements(modalWidth, modalHeight);
closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 185;
closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 230;
recordsContainer.addChild(closeButton);
closeButton.on('down', function () {
game.removeChild(recordsContainer);
menuOpen = true;
menuContainer.visible = true;
});
}
/****
* End Game & Reset Functions
****/
function playNextMusic() {
musicCycle++;
if (musicCycle === 1) {
LK.stopMusic();
LK.playMusic(musicSequence[1]);
} else if (musicCycle === 2) {
LK.stopMusic();
LK.playMusic(musicSequence[2]);
} else if (musicCycle === 3) {
LK.stopMusic();
} else {
musicCycle = 0;
LK.stopMusic();
LK.playMusic(musicSequence[0]);
}
}
var musicSequence = ['m_1', 'M_2', 'M_3'];
var musicCycle = 0;
LK.playMusic(musicSequence[0]);
function endGame() {
LK.effects.flashScreen(0xFF0000, 500);
LK.getSound('deatheffect').play();
character.velocityY = character.jumpStrength;
character.update = function () {
if (gameOver) {
character.velocityY += character.gravity;
character.y += character.velocityY;
if (character.y > groundY + character.height) {
character.y = groundY + character.height;
character.velocityY = 0;
}
}
};
game.children.forEach(function (child) {
if (child.velocityX) {
child.velocityX = 0;
}
if (child === background || child === bg2) {
LK.setTimeout(function () {
child.velocityY = 0;
}, 300);
}
});
game.touchDisabled = true;
lastScore = passCounter;
records.push({
score: passCounter,
attempt: records.length + 1
});
records.sort(function (a, b) {
return b.score - a.score;
});
if (records.length > 5) {
records = records.slice(0, 5);
}
LK.setTimeout(function () {
game.touchDisabled = false;
menuOpen = true;
menuContainer.visible = true;
var startY = groundY + 100;
var endY = centerY() - 1270;
var animationDuration = 16.5 * 5 / 1.5;
var startTime = Date.now();
function animateMenu() {
var currentTime = Date.now();
var elapsedTime = currentTime - startTime;
var progress = Math.min(elapsedTime / animationDuration, 1);
menuContainer.y = startY + (endY - startY) * progress;
if (progress < 1) {
LK.setTimeout(animateMenu, 16);
}
}
animateMenu();
}, 1700);
LK.setTimeout(function () {
resetGame();
}, 1750);
}
function resetGame() {
if (gameOverText) {
game.removeChild(gameOverText);
gameOverText = null;
}
unflipWorld();
var objectsToRemove = [];
game.children.forEach(function (child) {
if (child instanceof Tree || child instanceof Tube) {
objectsToRemove.push(child);
}
});
objectsToRemove.forEach(function (obj) {
game.removeChild(obj);
});
game.removeChild(character);
character = game.addChild(new Character());
character.x = centerX();
character.y = centerY();
background.x = centerX();
background.y = groundY / 2;
bg2.x = centerX() + 2807.2;
bg2.y = groundY / 2;
background.velocityX = -3.6;
bg2.velocityX = -3.6;
bg2.scale.x = 1;
gameStarted = false;
gameOver = false;
character.preventDeath = false;
underscoreAsset.preventDeath = false;
lastSpawner = null;
passCounter = 0;
underscoreTouchCount = 0;
counterText.setText(passCounter);
// Reset container'ların konumunu ve velocity değerlerini
background3DContainer.y = 2350;
bgEffect3DContainer.y = 2350;
background3DContainer.velocityY = 0;
bgEffect3DContainer.velocityY = 0;
}
/****
* Eliptik hit testi için yardımcı fonksiyon
****/
function checkEllipseHover(button, lx, ly) {
var scaleFactorX = 1;
var scaleFactorY = 0.53;
var offsetY = 40;
var dx = lx - button.x;
var dy = ly - (button.y + offsetY);
var rx = button.width / 2 * scaleFactorX;
var ry = button.height / 2 * scaleFactorY;
return dx * dx / (rx * rx) + dy * dy / (ry * ry) <= 1;
}
/****
* Fare hareketinde hover kontrolü
****/
game.move = function (x, y, obj) {
if (!menuOpen) {
return;
}
var localX = x - menuContainer.x;
var localY = y - menuContainer.y;
playButton.visible = checkEllipseHover(playButton, localX, localY);
volumeButton.visible = checkEllipseHover(volumeButton, localX, localY);
creditsButton.visible = checkEllipseHover(creditsButton, localX, localY);
recordsButton.visible = checkEllipseHover(recordsButton, localX, localY);
};
/****
* Touch Event
****/
game.down = function (x, y, obj) {
if (menuOpen) {
var localX = x - menuContainer.x;
var localY = y - menuContainer.y;
if (checkEllipseHover(playButton, localX, localY)) {
var _animateMenu = function animateMenu() {
var currentTime = Date.now();
var elapsedTime = currentTime - startTime;
var progress = Math.min(elapsedTime / animationDuration, 1);
menuContainer.y = startY + (endY - startY) * progress;
if (progress < 1) {
LK.setTimeout(_animateMenu, 1);
} else {
menuOpen = false;
menuContainer.visible = false;
gameWait = true;
}
};
var animationDuration = 16.5 * 5 * 2 / 1.5;
var startTime = Date.now();
var startY = menuContainer.y;
var endY = centerY() + 100;
_animateMenu();
return;
} else if (checkEllipseHover(volumeButton, localX, localY)) {
showVolume();
} else if (checkEllipseHover(creditsButton, localX, localY)) {
showCredits();
} else if (checkEllipseHover(recordsButton, localX, localY)) {
showRecords();
}
return;
} else if (gameOver) {
if (!game.touchDisabled) {
menuOpen = true;
menuContainer.visible = true;
resetGame();
}
} else {
if (gameWait) {
gameWait = false;
gameStarted = true;
var initialTube = new Tube();
game.addChild(initialTube);
lastSpawner = initialTube;
character.jump();
} else {
character.jump();
character.rotation = 0.1;
LK.setTimeout(function () {
character.rotation = 0;
}, 200);
}
}
};
/****
* Game Loop
****/
game.update = function () {
game.children.forEach(function (child) {
if (child.update) {
child.update();
}
if (child === background || child === bg2) {
if (!gameOver && !menuOpen && gameStarted) {
child.x -= 3.0;
child.velocityY -= child.gravity;
child.y += child.velocityY;
}
if (child.x < -2807.2 / 2) {
child.x += 2807.2 * 2;
}
}
if (child === background3DContainer || child === bgEffect3DContainer) {
if (!gameOver && !menuOpen && gameStarted) {
child.x -= containerScrollSpeed * 1.2;
}
if (child.x < -2807.2 / 2) {
child.x += 2807.2 * 2;
}
}
});
game.children.sort(function (a, b) {
return (a.zIndex || 0) - (b.zIndex || 0);
});
};
function unflipWorld() {
if (!flipped) {
return;
}
flipped = false;
character.gravity = 0;
character.jumpStrength = 0;
zoomEffect();
LK.setTimeout(function () {
character.gravity = 0.3;
character.jumpStrength = -12;
}, 300);
background.scale.y *= -1;
bg2.scale.y *= -1;
sky.scale.y *= -1;
groundAsset.scale.y *= -1;
ground2Asset.scale.y *= -1;
}
function zoomEffect() {
var originalScale = character.scale.x;
character.scale.set(originalScale * 1.2);
LK.setTimeout(function () {
character.scale.set(originalScale);
}, 300);
}
function flipWorld() {
if (flipped) {
return;
}
flipped = true;
character.gravity = 0;
character.jumpStrength = 0;
zoomEffect();
LK.setTimeout(function () {
character.gravity = 0.3;
character.jumpStrength = -12;
}, 300);
background.scale.y *= -1;
bg2.scale.y *= -1;
sky.scale.y *= -1;
groundAsset.scale.y *= -1;
ground2Asset.scale.y *= -1;
}
“High-quality 2D pixel art of a witch girl flying on a magic broomstick. She has fair skin, bright green eyes, and long orange braided hair. She is wearing a classic witch hat and outfit. She is sitting sideways on the broom (her body facing the viewer, but her head turned to look forward in the direction of flight). The background is a clear sky or night sky with stars. The art should have a magical, whimsical feeling with detailed shading and vibrant colors.”. In-Game asset. 2d. High contrast. No shadows
"High-quality 2D pixel art background set at night, with a dark purple atmosphere and eerie lighting. The environment features twisted, dead and infected trees in dark purple and black tones, their branches gnarled like claws. Emerging from the landscape are large, shadowy octopus-like tentacles in shades of violet, wrapping through the trees and terrain. Red glowing eyes are scattered throughout the darkness, hiding within the shadows and between the branches. The scene is ominous and unsettling, perfect for a dark fantasy or horror-themed RPG. Style is detailed 16-bit pixel art, with strong contrast and a moody color palette. In-Game asset. 2d. High contrast. No shadows
Purple tentacles pixel art and red eyes 2d. In-Game asset. 2d. High contrast. No shadows
2d pixel art high quality enfected mutant purple and red tentacle. In-Game asset. 2d. High contrast. No shadows
High-quality 2D pixel art of a young witch girl facing forward with her arms open, palms visible. She has vibrant orange hair, fair white skin, and bright green eyes. She is wearing a classic witch outfit: a wide-brimmed witch hat and a matching dress with magical details. The style is detailed 16-bit pixel art, with clean shading and strong contrast. The pose is welcoming or spellcasting, and she is directly facing the viewer. Transparent background.. In-Game asset. 2d. High contrast. No shadows
2d pixel art high quality yellow glowing one big star In-Game asset. 2d. High contrast. No shadows
High-quality 2D pixel art of an empty parchment scroll. The scroll is slightly aged, with soft yellowed paper tones, curled edges, and subtle wrinkles and texture details. The ends are rolled and slightly shadowed for depth. The parchment is unrolled and centered, with no text or symbols on it. Style is clean and classic 16-bit pixel art, suitable for use in a fantasy RPG inventory or dialogue box. Transparent background.". In-Game asset. 2d. High contrast. No shadows
2d pixel art high quality enfected mutant purple and red tentacle. In-Game asset. 2d. High contrast. No shadows
High-quality 2D pixel art of two small sparkle effects side by side with a small gap between them. Each sparkle is star-shaped or cross-shaped, emitting a soft glow in white or pale yellow tones. The sparkles are symmetrical and minimal, designed for UI highlights, magical effects, or item glimmers. The pixel art style is clean and detailed, in 16-bit fantasy aesthetic. Transparent background.". In-Game asset. 2d. High contrast. No shadows
2d pixel art high quality, brown X. In-Game asset. 2d. High contrast. No shadows
"High-quality 2D pixel art of a corrupted, infected soil tile designed as a horizontal strip. The terrain appears as a thin, straight line of dark purple, violet, and magenta tones, resembling infected earth. Cracks, glowing purple veins, and subtle texture details give it a diseased, magical look. The line is seamless and tileable, ideal for use as a corrupted ground border or floor edge in a fantasy RPG. Style is clean and detailed 16-bit pixel art. Transparent background
2d pixel art sparkle. In-Game asset. 2d. High contrast. No shadows
hand 2d pixel art high quality. No background. Transparent background. purple clothes girl hand Blank background. No shadows. 2d. In-Game asset. flat
Purple tentacles pixel art and red eyes 2d. In-Game asset. 2d. High contrast. No shadows