User prompt
Please fix the bug: 'Uncaught ReferenceError: duplicateBackgrounds is not defined' in or related to this line: 'duplicateBackgrounds();' Line Number: 907
User prompt
Aşağıda, "ScrollingBackground" sınıfının tanımlandığı, oyuna eklendiği ve game.update fonksiyonu içinde kullanıldığı tek bir kod parçası yer almaktadır: js Kopyala Düzenle /**** ScrollingBackground Class ****/ var ScrollingBackground = Container.expand(function () { var self = Container.call(this); // İlk arka plan (normal görüntü) self.bg1 = LK.getAsset('background', { anchorX: 0, anchorY: 0 }); self.bg1.x = 0; self.bg1.y = 0; self.addChild(self.bg1); // İkinci arka plan (mirrored - yatayda ters çevrilmiş) self.bg2 = LK.getAsset('background', { anchorX: 1, anchorY: 0 }); self.bg2.scaleX = -1; // Mirroring effect self.bg2.x = self.bg1.width; self.bg2.y = 0; self.addChild(self.bg2); // Hız ayarı (Tube, Tree vb. objelerle aynı hıza getirmek için ayarlanabilir) self.speed = 2; self.update = function () { // İki arka planı sola doğru hareket ettir self.bg1.x -= self.speed; self.bg2.x -= self.speed; // Eğer bg1 tamamen ekran dışına çıktıysa, bg2'nin sağına yerleştir if (self.bg1.x + self.bg1.width <= 0) { self.bg1.x = self.bg2.x + self.bg2.width; } // Aynı şekilde bg2 için if (self.bg2.x + self.bg2.width <= 0) { self.bg2.x = self.bg1.x + self.bg1.width; } }; }); /**** Initialize Game ****/ var game = new LK.Game({ width: 2048, height: 2732, backgroundColor: 0x000000 }); /**** Create and Add Scrolling Background ****/ var scrollingBackground = new ScrollingBackground(); game.addChild(scrollingBackground); /**** Example Game Update Loop ****/ game.update = function () { // Güncelleme fonksiyonuna scrollingBackground.update() eklenir scrollingBackground.update(); // Buraya diğer oyun güncelleme kodlarınızı ekleyebilirsiniz... }; LK.stage.addChild(game); Bu kod, oyunun başlangıcında "background" adlı asset’i iki kopya olarak yükler; biri normal, diğeri flipX (ayna yansıması) uygulanmış olarak yerleştirilir. game.update içinde bu kopyalar sola doğru hareket ettirilir; biri tamamen soldan kaydığında, diğerinin sağına yeniden konumlandırılarak kesintisiz bir akış sağlanır. İhtiyacınıza göre hız değerini veya konumlandırma ayarlarını değiştirebilirsiniz.
User prompt
İstediğiniz, verdiğiniz koddaki "ScrollingBackground" sınıfı ile aynı mekanizmayı uygulamaksa, aşağıdaki kod parçasını doğrudan kullanabilirsiniz. Bu sınıf, iki adet arka plan görüntüsünü (biri normal, diğeri yatayda ters çevrilmiş) yan yana yerleştirip, belirlenen hızda sola kaydırır. Bir görüntü tamamen ekran dışına çıktığında, diğerinin hemen sağına yerleştirilir, böylece kesintisiz bir akış elde edilir. js Kopyala Düzenle // ScrollingBackground class var ScrollingBackground = Container.expand(function () { var self = Container.call(this); self.bg1 = LK.getAsset('background', { anchorX: 0, anchorY: 0 }); self.bg1.x = 0; self.bg1.y = 0; self.addChild(self.bg1); self.bg2 = LK.getAsset('background', { anchorX: 1, anchorY: 0 }); // bg2'yi yatayda ters çeviriyoruz (mirrored) self.bg2.scaleX = -1; self.bg2.x = self.bg1.width; self.bg2.y = 0; self.addChild(self.bg2); self.speed = 2; self.update = function () { self.bg1.x -= self.speed; self.bg2.x -= self.speed; // bg1 tamamen solda kaydıysa, bg2'nin sağına yeniden konumlandır if (self.bg1.x + self.bg1.width <= 0) { self.bg1.x = self.bg2.x + self.bg2.width; } // bg2 tamamen solda kaydıysa, bg1'in sağına yeniden konumlandır if (self.bg2.x + self.bg2.width <= 0) { self.bg2.x = self.bg1.x + self.bg1.width; } }; }); Bu sınıfı oyununuzda arka plan mekanizması olarak kullanabilirsiniz. Örneğin, oyuna eklemek için: js Kopyala Düzenle var scrollingBackground = new ScrollingBackground(); game.addChild(scrollingBackground); Daha sonra, oyun döngüsü (game.update) içerisinde scrollingBackground.update() çağrısını yapmayı unutmayın. Bu sayede arka planınız, Tube, Tree veya diğer objelerle uyumlu şekilde hareket edecektir. Eğer arka planın hızı veya diğer parametreleri üzerinde değişiklik yapmak isterseniz, self.speed değerini ihtiyacınıza göre güncelleyebilirsiniz.
User prompt
Below is one example of how you could implement this behavior. In this example, when the menu is closed and the player clicks the screen for the first time, we create a duplicated set of background copies that are placed immediately to the right of the original backgrounds. These duplicates are flipped (mirrored) relative to their “normal” counterparts. Then in the game loop, both the original and duplicated backgrounds are moved to the left at the same speed, and when any background moves off‐screen to the left, it is repositioned to the far right with its flip property updated based on its new “index” so that the mirroring continues. For example, consider the following code: js Kopyala Düzenle // Global flag to check if backgrounds have been duplicated var backgroundsDuplicated = false; // Array to store all background copies (both original and duplicated) var allBackgrounds = []; // Function to create the initial set of background copies function createInitialBackgrounds() { var bgWidth = 2807.2; // width as defined in your asset var totalCopies = 3; // adjust as needed for full screen coverage for (var i = 0; i < totalCopies; i++) { var bg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: centerX() + i * bgWidth, y: groundY / 2, flipX: i % 2 === 1 ? 1 : 0 // alternate mirror effect }); bg.zIndex = 0; allBackgrounds.push(bg); game.addChild(bg); } } // Call this early so you have the initial set on screen. createInitialBackgrounds(); // When the menu is closed and the screen is clicked for the first time, // duplicate the current set of backgrounds to the right. function duplicateBackgrounds() { if (backgroundsDuplicated) return; backgroundsDuplicated = true; var bgWidth = 2807.2; // Get the number of copies in our current array var count = allBackgrounds.length; // Duplicate each background and place them to the right. for (var i = 0; i < count; i++) { var original = allBackgrounds[i]; var duplicate = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, // Place it immediately to the right of the rightmost background. x: original.x + count * bgWidth, y: original.y, // Flip it compared to the original. Here, you can simply reverse the flipX value. flipX: original.flipX ? 0 : 1 }); duplicate.zIndex = 0; allBackgrounds.push(duplicate); game.addChild(duplicate); } } // In your game.down function (or wherever you detect the first click after menu closes): game.down = function(x, y, obj) { if (!menuOpen) { // On the first click after the menu is closed, // duplicate the backgrounds if not done already. duplicateBackgrounds(); // (Other touch handling code, like starting the game, etc.) 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); } return; } // Existing menu-related code ... }; // In your game update loop, move every background copy to the left at the same speed. game.update = function() { // Update game objects (characters, tubes, trees, etc.) game.children.forEach(function(child) { if (child.update) { child.update(); } }); var bgSpeed = 3.6; var bgWidth = 2807.2; // Move each background copy left allBackgrounds.forEach(function(bg) { bg.x -= bgSpeed; }); // Check if any background has moved completely off-screen on the left. // If so, reposition it to the rightmost position. allBackgrounds.forEach(function(bg) { if (bg.x < -bgWidth / 2) { // Find the current maximum x value among all backgrounds. var maxX = Math.max.apply(null, allBackgrounds.map(function(b) { return b.x; })); // Reposition this background just to the right of the furthest one. bg.x = maxX + bgWidth; // Calculate a new index based on its position relative to center var newIndex = Math.round((bg.x - centerX()) / bgWidth); // Update flipX so that the backgrounds continue alternating mirror effect. bg.flipX = newIndex % 2 === 1 ? 1 : 0; } }); // Optional: sort game.children if needed. game.children.sort(function(a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); }; How It Works Initial Setup: The function createInitialBackgrounds() creates (for example) three background copies with alternating flip values (normal, mirrored, normal) and places them sequentially across the screen. First Click After Menu Closes: When the menu is closed and the player clicks for the first time, the duplicateBackgrounds() function is called. This duplicates each of the original backgrounds and places the copies immediately to the right of the current set, flipping their orientation relative to their source. Game Loop Movement: In the game.update loop, every background copy in the allBackgrounds array is moved left by 3.6 pixels per frame (matching the speed of tubes and trees). When a background moves completely off the left side (i.e. its center x is less than –(width/2)), it is repositioned to the right of the current rightmost background and its flipX is recalculated to maintain the mirroring sequence. This solution ensures that once the menu is closed and the game starts (on the first screen click), you have a continuously moving, mirrored sequence of backgrounds that duplicate as they loop around. You may need to tweak parameters like the number of background copies, the bgWidth value, and positions to perfectly match your game’s design.
User prompt
Aşağıdaki örnek kod, arka plan kopyalarını tube ve tree ile aynı hıza getirecek şekilde hareket ettirir; her kopya ekranın solundan çıkınca, en sağdakinin sağına yerleştirilir ve sırayla flip edilerek ayna yansıması efekti oluşturulur. Öncelikle, arka plan varlığını tek başına oluşturmak yerine bir dizi (array) kullanıp kopyaları aşağıdaki gibi ayarlayabilirsiniz: js Kopyala Düzenle // Arka plan varlıklarının genişliği (assets'te tanımlanan değer) var bgWidth = 2807.2; // Arka plan kopyalarının sayısı var totalBackgrounds = 3; var backgrounds = []; for (var i = 0; i < totalBackgrounds; i++) { var bg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: centerX() + i * bgWidth, // Sıralı konumlandırma y: groundY / 2, flipX: i % 2 === 1 ? 1 : 0 // Sıra ile ayna yansıması efekti }); bg.zIndex = 0; backgrounds.push(bg); game.addChild(bg); } Ardından, game update fonksiyonunda her frame’de bu kopyaların aynı hızda (tube ve tree hızıyla -3.6 piksel) sola kaymasını ve ekranın solundan çıkınca sağa tekrar konumlandırılmasını sağlayın: js Kopyala Düzenle game.update = function () { // Diğer güncelleme işlemleri... // Arka plan kopyalarını sola hareket ettir (hız -3.6) backgrounds.forEach(function(bg) { bg.x -= 3.6; }); // Eğer bir arka plan tamamen soldan çıkmışsa, onu sağdaki en son kopyanın hemen sağına yerleştir backgrounds.forEach(function(bg) { if (bg.x < -bgWidth / 2) { // En sağdaki background'un x konumunu bul var maxX = Math.max.apply(null, backgrounds.map(function(b) { return b.x; })); // Bu arka planı, en sağdakinin hemen sağına yerleştir bg.x = maxX + bgWidth; // Yeni index hesaplanarak flipX değeri güncellenir var newIndex = Math.round((bg.x - centerX()) / bgWidth); bg.flipX = newIndex % 2 === 1 ? 1 : 0; } }); // Z-index sıralaması (varsa) game.children.sort(function (a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); }; Açıklamalar: Hareket Hızı: Her frame’de arka planın x değeri –3.6 azaltılarak tube ve tree ile aynı hızda hareket etmesi sağlanır. Yeniden Konumlandırma: Eğer bir arka planın merkezinin x değeri, –(bgWidth/2)’den küçükse (yani tamamen ekranın solundan çıkmışsa), o kopya en sağdaki kopyanın sağına (maxX + bgWidth) taşınır. Ayna Yansıması Efekti: İlk oluşturulurken ve yeniden konumlandırmada, kopyanın “sıra” numarası (hesaplanan newIndex) kullanılarak flipX değeri güncellenir. Böylece sırayla normal ve mirrored (flipX=1) kopyalar elde edilir. Bu şekilde, arka plan kopyaları hem tube ve tree ile aynı hızda hareket eder hem de sırayla ayna yansıması efekti oluşturur. Eğer daha fazla kopya kullanırsanız, ekranın tüm alanı sürekli dolu kalır ve kayma sırasında kopukluk görülmez.
User prompt
Aşağıdaki öneriler, arka planın sürekli tekrarlanan ve sıra ile normal/mirrored (ayna yansıması gibi) görünmesini sağlayacak şekilde düzenlenmesine yardımcı olacaktır: Birden Fazla Kopya Oluşturun: Sadece iki kopya yerine (normal ve mirrored) bir dizi (array) oluşturun. Örneğin, üç ya da dört kopya ekleyip bunları sırayla yerleştirin. Her kopyanın başlangıçta x koordinatını, index’e göre ayarlayın ve flipX değerini index çiftse normal, tekse mirrored olacak şekilde verin. Arka Plan Hızını Tube ve Tree ile Aynı Yapın: Update döngüsünde arka planların x koordinatını her karede –3.6 piksel kadar azaltın. Böylece tube ve tree ile aynı hızda hareket eder. Sürekli Döngü ve Alternatif Flip Ayarlaması: Bir arka plan tamamen soldan ekranın dışına çıktığında (örneğin, x değeri –(width/2)’den küçük olduğunda), onu en sağdaki arka planın sağına yerleştirin. Bu yeniden konumlandırmada, o arka planın “sıra” numarasını (örneğin, ekranın merkezine göre kaçıncı kopya olduğunu) hesaplayarak flipX değerini (index çiftse normal, tekse mirrored) güncelleyin. Aşağıda bu düzenlemeleri içeren örnek bir kod parçası yer almaktadır: js Kopyala Düzenle // 1. Arka plan kopyalarını oluşturmak için bir array kullanalım: var backgrounds = []; var totalBackgrounds = 3; // örneğin 3 kopya kullanalım for (var i = 0; i < totalBackgrounds; i++) { var bg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: centerX() + i * background.width, // ardışık yerleştirme y: groundY / 2, flipX: (i % 2 === 1) ? 1 : 0 // sıra ile ayna yansıması }); bg.zIndex = 0; backgrounds.push(bg); game.addChild(bg); } // 2. Game Loop içerisinde arka planların hareketini güncelleyelim: game.update = function () { // Diğer güncelleme kodları... // Arka planları tube ve tree ile aynı hızda sola kaydır (hız: 3.6) backgrounds.forEach(function(bg) { bg.x -= 3.6; }); // Her bir arka planın ekran dışına çıkıp çıkmadığını kontrol edelim: backgrounds.forEach(function(bg, index) { if (bg.x < -bg.width / 2) { // Şu an ekrandaki en sağdaki arka planın konumunu bulalım: var maxX = Math.max.apply(null, backgrounds.map(function(b) { return b.x; })); // Bu arka planı en sağdakinin sağına yerleştirelim: bg.x = maxX + bg.width; // Yeni "sıra" numarasını hesaplayıp flip ayarını güncelleyelim: var newIndex = Math.floor((bg.x - centerX()) / bg.width); bg.flipX = (newIndex % 2 === 1) ? 1 : 0; } }); // Z-index sıralaması vs. diğer update işlemleri: game.children.sort(function (a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); }; Özet: Kopya Sayısı: Bir dizi kullanarak 3 ya da daha fazla arka plan kopyası oluşturun, böylece sırayla normal ve mirrored görüntü elde edin. Hız: Her kopyanın x koordinatını –3.6 piksel azaltarak tube ve tree ile aynı hıza ulaşın. Yeniden Konumlandırma: Ekranın solundan çıkınca, ilgili arka planı en sağdaki kopyanın hemen sağına yerleştirip, yeni sırası belirlenince flipX özelliğini yeniden ayarlayın. Bu şekilde, ekran boyunca tekrarlanan arka planınız, bir normal bir mirrored sırayla ve tube ile tree ile aynı hızda hareket eder.
User prompt
Kodun arka plan kısmını tree ve tube ile aynı hıza ayarlamak için, arka planın update fonksiyonunda kullanılan hız değerini değiştirmeliyiz. Mevcut kodda arka plan hızı sabit olarak 2 piksel sola doğru kaydırılıyor: js Kopyala Düzenle if (child === background || child === backgroundDuplicate) { child.x -= 2; // Mevcut hız: 2 // Arka plan tamamen görünüm dışına çıktığında konumunu sıfırla if (child.x < -background.width / 2) { child.x += background.width * 2; // Diğer arka planın sağında konumlandır } } Tree ve Tube sınıflarında ise velocityX değeri -3.6 olarak belirlenmiş. Bu durumda, arka planın hızını da -3.6 olarak ayarlamalıyız: js Kopyala Düzenle if (child === background || child === backgroundDuplicate) { child.x -= 3.6; // Hızı tree ve tube ile aynı: 3.6 piksel sola // Arka plan tamamen görünüm dışına çıktığında konumunu sıfırla if (child.x < -background.width / 2) { child.x += background.width * 2; // Diğer arka planın sağında konumlandır } } Ayrıca, arka planın flip edilmiş (mirrored) versiyonu zaten flipX: 1 ayarıyla tanımlanmış. Bu sayede arka planın orijinali ve yansımalı hali yan yana dizilir. Özetle yapmanız gerekenler: Arka Plan Hızını Güncelleyin: child.x -= 2; yerine child.x -= 3.6; kullanın. Arka Plan Reset İşlemi: Arka planın sol kenarı ekran dışına çıktığında, child.x değerine background.width * 2 ekleyerek diğer arka planın hemen sağına yerleştirin. Bu düzenlemeler sayesinde, arka plan sola doğru sürekli hareket edecek, sağında yansıtılmış (mirrored) versiyonu ile birlikte ekranın sonsuz bir şekilde akması sağlanacaktır. Eğer gerekirse, arka plan assetlerinin genişlik ve konumlandırmalarını ekran boyutlarına göre kontrol edip optimize edebilirsiniz.
User prompt
flip et ilk menü normal ikincisi mirrored gibi olsun
User prompt
arka planı duplicate et sonra flip ve backgroundun sağına koy bunu sürekli tekrarla arka plan sola doğru hareket ederken
User prompt
Aşağıdaki kodda, play, volume, credits ve records etiketlerinin fontSize değerlerine %50 büyütme (×1.5) çarpanını ekledim: js Kopyala Düzenle // PLAY Label: %50 büyütülmüş var playLabel = new Text2("PLAY", { fontFamily: "Arial", fontSize: 630.25 * 1.1 * 1.08 * 1.5, // orijinal değere 1.5 çarpanı ekledim fill: 0xffffff }); playLabel.anchorX = 0.5; playLabel.anchorY = 0.5; playLabel.x = playButton.x - 45; playLabel.y = playButton.y - -25; playLabel.visible = true; playLabel.zIndex = 1000; menuContainer.addChild(playLabel); // VOLUME Label: %50 büyütülmüş var volumeLabel = new Text2("VOLUME", { fontFamily: "Arial", fontSize: 63.25 * 1.1 * 1.05 * 1.05 * 1.05 * 1.5, // %50 büyütme fill: 0xffffff }); volumeLabel.anchorX = 0.5; volumeLabel.anchorY = 0.5; volumeLabel.x = volumeButton.x - 58; volumeLabel.y = volumeButton.y + 30; volumeLabel.visible = true; volumeLabel.zIndex = 1000; menuContainer.addChild(volumeLabel); // CREDITS Label: %50 büyütülmüş var creditsLabel = new Text2("CREDITS", { fontFamily: "Arial", fontSize: 630.25 * 1.05 * 1.05 * 1.05 * 1.5, // %50 büyütme fill: 0xffffff }); creditsLabel.anchorX = 0.5; creditsLabel.anchorY = 0.5; creditsLabel.x = creditsButton.x - 60; creditsLabel.y = creditsButton.y + 28; creditsLabel.visible = true; creditsLabel.zIndex = 1000; menuContainer.addChild(creditsLabel); // RECORDS Label: %50 büyütülmüş var recordsLabel = new Text2("RECORDS", { fontFamily: "Arial", fontSize: 150.25 * 1.05 * 1.05 * 1.03 * 1.05 * 1.5, // %50 büyütme fill: 0xffffff }); recordsLabel.anchorX = 0.5; recordsLabel.anchorY = 0.5; recordsLabel.x = recordsButton.x - 67; recordsLabel.y = recordsButton.y + 28; recordsLabel.visible = true; recordsLabel.zIndex = 1000; menuContainer.addChild(recordsLabel); Bu değişikliklerle ilgili metinlerin fontSize değeri %50 artmış olacak. İhtiyacınıza göre konumlandırmalarda da ufak ayarlamalar yapabilirsiniz.
User prompt
if player touches _ asset 5 time disable death for tree asset too
User prompt
okay when touched 5 times to _ asset enable it if not touched for 5 time dont make it work
User prompt
didnt work sky and ground still kills even though i touched _ asset
User prompt
when touched _ asset disable death for ground and sky too
User prompt
prevent death when touvhed _ asset but sky and ground kills fix it it shouldnt kill character
User prompt
character dies when touched to ground or sky
User prompt
i click _ asset and when i touch tube or treee chracter dies
User prompt
character still dies even though i pressed _ asset
User prompt
disable character death when touched _ asset
User prompt
Move the '_' asset 150 pixels to the left
User prompt
Move the '_' asset 350 pixels to the right
User prompt
Move the '_' asset 400 pixels to the right
User prompt
_ assetini 400 pixel sağa itele
User prompt
var underscoreAsset = LK.getAsset('_', { anchorX: 0.5, anchorY: 0.5, x: centerX(), y: centerY() }); underscoreAsset.zIndex = 15000; game.addChild(underscoreAsset); game.children.sort((a, b) => (a.zIndex || 0) - (b.zIndex || 0));
User prompt
game.addChild(Object.assign(LK.getAsset('_', { anchorX: 0.5, anchorY: 0.5, x: centerX(), y: centerY() })), { zIndex: 15000 });
/**** * 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; 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; // Ekran dışına çıkma kontrolü if (characterLeft + self.width / 2 < 0 || characterRight - self.width / 2 > screenRight || characterTop + self.height / 2 < 0 || characterBottom - self.height / 2 > groundY) { gameOver = true; endGame(); } // Çarpışma kontrolü: Tube ve Tree 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) { // Check if not intersecting with underscore asset and preventDeath is not true gameOver = true; endGame(); } else { // If intersecting with underscore asset or preventDeath is true, do not trigger game over return; } } } } 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)) { // Check if not intersecting with underscore asset gameOver = true; endGame(); } } } } }); } }; self.jump = function () { if (!gameOver) { self.velocityY = self.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; // Sırayla ağaç-boru üretimi if (!self.spawned && self.prevX > treeSpawnThreshold && self.x <= treeSpawnThreshold) { self.spawned = true; var newTube = new Tube(); newTube.x = 2048 + 800; game.addChild(newTube); lastSpawner = newTube; } self.prevX = self.x; // Geçme sayacı 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: 300, height: bottomHeight, flipY: false }); self.topTube = self.attachAsset('tube', { anchorX: 0.5, anchorY: 0.5, width: 300, 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; // Sırayla boru-ağaç üretimi if (!self.spawned && self.prevX > tubeSpawnThreshold && self.x <= tubeSpawnThreshold) { self.spawned = true; var newTree = new Tree(); newTree.x = 2048 + 800; game.addChild(newTree); lastSpawner = newTree; } self.prevX = self.x; // Geçme sayacı 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 ****/ var underscoreAsset = LK.getAsset('_', { anchorX: 0.5, anchorY: 0.5, x: centerX() + 1000, y: centerY() }); underscoreAsset.zIndex = 15000; game.addChild(underscoreAsset); // Add click event to underscore asset underscoreAsset.on('down', function () { // Set a flag to prevent character death character.preventDeath = true; }); game.children.sort(function (a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); function createCloseButton() { // Close button’un kendi container’ı: var closeButtonContainer = new Container(); closeButtonContainer.zIndex = 9999; // Diğer her şeyin üstünde olsun // Close butonu için ellipse (shape) var closeShape = LK.getAsset('button_close', { anchorX: 0.5, anchorY: 0.5, width: 160 * 0.8, // Adjusted width to 80% of original height: 160 * 1.2 // Adjusted height to 120% of original }); closeButtonContainer.addChild(closeShape); // “X” metni var closeLabel = LK.getAsset('justX', { anchorX: 0.5, anchorY: 0.5, x: -6, // Moved 4 pixels left y: 2 // Moved 4 pixels up }); closeButtonContainer.addChild(closeLabel); return closeButtonContainer; } function zoomEffect() { // Mevcut scale değeri (örneğin orijinal 1) var originalScale = character.scale.x; // Zoom in: %20 artış character.scale.set(originalScale * 1.2); // 300ms sonra zoom out yap, orijinal scale'e dön LK.setTimeout(function () { character.scale.set(originalScale); }, 300); } // Dünyayı ters döndürme (flip) fonksiyonu – 0.2 saniye boyunca jump/gravity devre dışı function flipWorld() { if (flipped) { return; } flipped = true; // 0.3 saniye boyunca karakterin jump ve gravity etkilerini devre dışı bırak character.gravity = 0; character.jumpStrength = 0; zoomEffect(); LK.setTimeout(function () { // Ters dünyada: gravity -0.3, jumpStrength 12 character.gravity = -0.3; character.jumpStrength = 12; }, 300); // Dünya elemanlarını ters çevir (sadece scale yöntemiyle) background.scale.y *= -1; sky.scale.y *= -1; groundAsset.scale.y *= -1; ground2Asset.scale.y *= -1; } // Dünyayı eski hâline döndürme (unflip) fonksiyonu – 0.2 saniye boyunca jump/gravity devre dışı function unflipWorld() { if (!flipped) { return; } flipped = false; character.gravity = 0; character.jumpStrength = 0; zoomEffect(); LK.setTimeout(function () { // Normal dünyada: gravity 0.3, jumpStrength -12 character.gravity = 0.3; character.jumpStrength = -12; }, 300); // Dünya elemanlarını yeniden ters çevirerek orijinal haline döndür background.scale.y *= -1; sky.scale.y *= -1; groundAsset.scale.y *= -1; ground2Asset.scale.y *= -1; } // Skoru güncelleme fonksiyonu – Her 5 skorda flip/unflip toggle function updateScore() { passCounter++; counterText.setText(passCounter); if (passCounter % 5 === 0) { if (!flipped) { flipWorld(); } else { unflipWorld(); } } } /**** * Global Variables & Helper Functions ****/ var groundY = 2732; var menuOpen = true; var volumeOn = true; var records = []; // En iyi 5 skoru saklar var gapOffset = 400; var gameStarted = false; var gameOver = false; var gameWait = false; // Oyun menüden çıkıp da henüz başlamamışken true olacak. var screenRight = 2048; var totalUnits = 10; var tubeSpawnThreshold, treeSpawnThreshold; var lastSpawner = null; var gameOverText = null; var passCounter = 0; var lastScore = 0; // Global lastScore variable // Flip durumunu takip eden bayrak var flipped = false; function centerX() { return 2048 / 2; } function centerY() { return groundY / 2; } tubeSpawnThreshold = centerX() + (screenRight - centerX()) / 2; treeSpawnThreshold = centerX() + 3 * (screenRight - centerX()) / 4; /**** * Menu Setup ****/ var menuContainer = new Container(); menuContainer.zIndex = 200; // Menü arka planları var menuBackground = LK.getAsset('menu_background', { anchorX: 0.5, anchorY: 0.5, x: centerX(), y: centerY() }); menuBackground.zIndex = 200; menuContainer.addChild(menuBackground); var menuBackgroundPart = LK.getAsset('menu_background_part', { anchorX: 0.5, anchorY: 0.19, x: centerX(), y: centerY() }); menuBackgroundPart.zIndex = menuBackground.zIndex + 1; // 201 menuContainer.addChild(menuBackgroundPart); // Butonlar ve Label’lar // PLAY 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, fill: 0xffffff }); playLabel.anchorX = 0.5; playLabel.anchorY = 0.5; playLabel.x = playButton.x - 45; playLabel.y = playButton.y - -25; playLabel.visible = true; playLabel.zIndex = 1000; menuContainer.addChild(playLabel); // VOLUME var volumeButton = LK.getAsset('button_volume', { anchorX: 0.5, anchorY: 0.5, x: centerX() - 28, y: centerY() + 310 }); volumeButton.visible = false; menuContainer.addChild(volumeButton); var volumeLabel = new Text2("VOLUME", { fontFamily: "Arial", fontSize: 63.25 * 1.1 * 1.05 * 1.05 * 1.05, fill: 0xffffff }); volumeLabel.anchorX = 0.5; volumeLabel.anchorY = 0.5; volumeLabel.x = volumeButton.x - 58; volumeLabel.y = volumeButton.y + 30; volumeLabel.visible = true; volumeLabel.zIndex = 1000; menuContainer.addChild(volumeLabel); // CREDITS 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: 630.25 * 1.05 * 1.05 * 1.05, fill: 0xffffff }); creditsLabel.anchorX = 0.5; creditsLabel.anchorY = 0.5; creditsLabel.x = creditsButton.x - 60; creditsLabel.y = creditsButton.y + 28; creditsLabel.visible = true; creditsLabel.zIndex = 1000; menuContainer.addChild(creditsLabel); // RECORDS 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, fill: 0xffffff }); recordsLabel.anchorX = 0.5; recordsLabel.anchorY = 0.5; recordsLabel.x = recordsButton.x - 67; recordsLabel.y = recordsButton.y + 28; recordsLabel.visible = true; recordsLabel.zIndex = 1000; menuContainer.addChild(recordsLabel); // Ekranda sayacımız 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); // Arkaplanlar var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: centerX(), y: groundY / 2 }); background.zIndex = 0; game.addChild(background); 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.5, x: centerX(), y: groundY - -25 }); groundAsset.zIndex = 4.1; game.addChild(groundAsset); var ground2Asset = LK.getAsset('ground2', { anchorX: 0.5, anchorY: 0.5, x: centerX(), y: groundY - 40 }); ground2Asset.zIndex = 0.5; game.addChild(ground2Asset); // Karakteri ekle var character = game.addChild(new Character()); character.x = centerX(); character.y = groundY / 2; // Menü container'ı biraz aşağı kaydırma 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: 10000, x: 6, // Moved 4 pixels left y: 16 // Moved 4 pixels up }); 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; // Center the button horizontally closeButton.y = 0; // Center the button vertically closeButton.addChild(closeLabel); return { closeLabel: closeLabel, closeButton: closeButton }; } function showCredits() { // Disable menu interaction when modal is opened menuOpen = false; var creditsContainer = new Container(); creditsContainer.zIndex = 300; var modalWidth = 1250, modalHeight = 2000; 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("Game by\nMustafa Talha ŞEN", { fontFamily: "Arial", fontSize: 5000 * 1.03, fill: 0xffffff, align: "center" }); creditsText.anchorX = 0.5; creditsText.anchorY = 0.5; creditsText.x = centerX() - 359; creditsText.y = centerY() - 800 + 40; creditsText.scale.set(3, 3); creditsContainer.addChild(creditsText); // 5) creditsContainer’ı oyuna ekle game.addChild(creditsContainer); // 6) Close butonunu tamamen bağımsız ekle var closeButton = createCloseButton(); // Örneğin, modal’ın sağ üst köşesi olsun closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 160; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 175; // Tıklanınca hem creditsContainer’ı hem close butonunu kaldır closeButton.on('down', function () { game.removeChild(creditsContainer); game.removeChild(closeButton); // Enable menu interaction when modal is closed menuOpen = true; menuContainer.visible = true; }); // Close butonunu da oyuna ekle game.addChild(closeButton); } function showVolume() { // Disable menu interaction when modal is opened menuOpen = false; var volumeContainer = new Container(); volumeContainer.zIndex = 300; var modalWidth = 1250, modalHeight = 2000; 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 volumeText = new Text2("Volume Settings", { fontFamily: "Arial", fontSize: 5000 * 1.03, fill: 0xffffff }); volumeText.scale.set(3, 3); volumeText.anchorX = 0.5; volumeText.anchorY = 0.5; volumeText.x = centerX() - 275; volumeText.y = centerY() - 800 + 85; volumeContainer.addChild(volumeText); // Container’ı oyuna ekle game.addChild(volumeContainer); // Close butonu bağımsız var closeButton = createCloseButton(); closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 159; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 175; closeButton.on('down', function () { game.removeChild(volumeContainer); game.removeChild(closeButton); // Enable menu interaction when modal is closed menuOpen = true; menuContainer.visible = true; }); game.addChild(closeButton); } function showRecords() { // Disable menu interaction when modal is opened 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.03, 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); // Container’ı oyuna ekle game.addChild(recordsContainer); // Close butonu bağımsız var closeButton = createCloseButton(); closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 205; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 195; closeButton.on('down', function () { game.removeChild(recordsContainer); game.removeChild(closeButton); // Enable menu interaction when modal is closed menuOpen = true; menuContainer.visible = true; }); game.addChild(closeButton); } /**** * End Game & Reset Functions ****/ function endGame() { LK.effects.flashScreen(0xFF0000, 500); 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; } }); 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; } // Flip'i eski hâline döndür 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 = groundY / 2; gameStarted = false; gameOver = false; character.preventDeath = false; // Reset preventDeath flag underscoreAsset.preventDeath = false; // Reset preventDeath flag for underscore asset lastSpawner = null; passCounter = 0; counterText.setText(passCounter); } /**** * 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; } // Modal açıkken hover efekti çalışmasın. 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(); } }); game.children.sort(function (a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); };
===================================================================
--- original.js
+++ change.js
@@ -20,10 +20,12 @@
self.y += self.velocityY;
if (self.y > groundY - 100) {
self.y = groundY - 100;
self.velocityY = 0;
- gameOver = true;
- endGame();
+ 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;
@@ -742,8 +744,9 @@
character.y = groundY / 2;
gameStarted = false;
gameOver = false;
character.preventDeath = false; // Reset preventDeath flag
+ underscoreAsset.preventDeath = false; // Reset preventDeath flag for underscore asset
lastSpawner = null;
passCounter = 0;
counterText.setText(passCounter);
}