User prompt
Please fix the bug: 'ReferenceError: background is not defined' in or related to this line: 'if (child === background || child === bg2) {' Line Number: 694
User prompt
Please fix the bug: 'groundY is not defined' in or related to this line: 'background3DContainer.y = groundY + 300;' Line Number: 314
User prompt
Please fix the bug: 'centerX is not defined' in or related to this line: 'var underscoreAsset = LK.getAsset('_', {' Line Number: 276
Code edit (6 edits merged)
Please save this source code
User prompt
Place background3DContainer and bgEffect3DContainer 1600 pixels down
User prompt
Gravity works for these assets background3DContainer and bgEffect3DContainer, if only character is moving
User prompt
make character bounded assets unbounded
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'jump')' in or related to this line: 'character.jump();' Line Number: 814
User prompt
Please fix the bug: 'ReferenceError: background is not defined' in or related to this line: 'if (child === background || child === bg2) {' Line Number: 823
User prompt
Please fix the bug: 'character is not defined' in or related to this line: 'background3DContainer.y = (character ? character.y : centerY()) + 500;' Line Number: 433
Code edit (1 edits merged)
Please save this source code
User prompt
Aşağıdaki örnekte, karakter bağlı arka planların (background3DContainer ve bgEffect3DContainer) sadece oyun başladıktan sonra (gameStarted true olduğunda) güncellenmesi için bir koşul ekledim. Böylece, menüdeyken bu dinamik güncelleme yapılmayacak ve arka planlar yerinde kalacak: js Kopyala Düzenle // Oyun döngüsü update fonksiyonunda: game.update = function () { // Karakter bağlı arka planları sadece oyun başladığında güncelle if (gameStarted && !menuOpen && character) { // Her iki arka plan için dinamik y offset'i güncelle background3DContainer.velocityY += background3DContainer.gravity; background3DContainer.offsetY += background3DContainer.velocityY; background3DContainer.y = character.y + 500 + background3DContainer.offsetY; // 500px aşağıda bgEffect3DContainer.velocityY += bgEffect3DContainer.gravity; bgEffect3DContainer.offsetY += bgEffect3DContainer.velocityY; bgEffect3DContainer.y = character.y + 500 + bgEffect3DContainer.offsetY; } else if (character) { // Menüdayken arka planların y konumunu sadece karakterin y'sine göre 500px sabit olarak ayarla background3DContainer.y = character.y + 500; bgEffect3DContainer.y = character.y + 500; } // Diğer güncellemeler... game.children.forEach(function (child) { if (child.update) { child.update(); } // Statik arka planların (background, bg2) hareketi if (child === background || child === bg2) { if (!gameOver && !menuOpen && gameStarted) { child.x -= 7.2; } if (child.x < -2807.2 / 2) { child.x += 2807.2 * 2; } } // Diğer hareket güncellemeleri... }); game.children.sort(function (a, b) { return (a.zIndex || 0) - (b.zIndex || 0); }); }; Ayrıca, karakterin jump fonksiyonunda, arka planlara atanan zıplama etkisinin de sadece oyun başladıktan sonra aktif olmasını sağlayabilirsiniz: js Kopyala Düzenle self.jump = function () { if (!gameOver && gameStarted) { self.velocityY = self.jumpStrength; // Karakter için zıplama LK.getSound('wingeffect').play(); // Arka planlar için ters yönde zıplama, sadece oyun başladığında: background3DContainer.velocityY = -self.jumpStrength; bgEffect3DContainer.velocityY = -self.jumpStrength; } }; Bu değişikliklerle, menüdeyken arka planlar sabit kalacak, oyun başladığında ise karaktere bağlı olarak 500px aşağıda konumlanıp, karakterin zıplama hareketine zıt yönde tepki verecekler.
User prompt
Step 1. Initialize Background Dynamics Right after you create the backgrounds (for example, right after creating and positioning background3DContainer and bgEffect3DContainer), add custom properties for the jump effect: js Kopyala Düzenle // Initialize background dynamics: background3DContainer.offsetY = 0; background3DContainer.velocityY = 0; background3DContainer.gravity = -0.3; // gravity opposite to character's bgEffect3DContainer.offsetY = 0; bgEffect3DContainer.velocityY = 0; bgEffect3DContainer.gravity = -0.3; Step 2. Update the Y Position in the Game Loop In the game’s update loop, update the offset for each container and set its y position relative to the character. Replace or update the current code that sets the y positions with something like this: js Kopyala Düzenle if (character) { // Update background offsets using their own velocity and gravity. background3DContainer.velocityY += background3DContainer.gravity; background3DContainer.offsetY += background3DContainer.velocityY; background3DContainer.y = character.y + 500 + background3DContainer.offsetY; // 500px down bgEffect3DContainer.velocityY += bgEffect3DContainer.gravity; bgEffect3DContainer.offsetY += bgEffect3DContainer.velocityY; bgEffect3DContainer.y = character.y + 500 + bgEffect3DContainer.offsetY; } Step 3. Trigger the Opposite Jump on the Backgrounds When the character jumps, in addition to setting the character’s velocity, set the backgrounds’ velocities so they “jump” in the opposite direction. For example, modify the character’s jump function as follows: js Kopyala Düzenle self.jump = function () { if (!gameOver && gameStarted) { self.velocityY = self.jumpStrength; // typically -12 for the character LK.getSound('wingeffect').play(); // Make the character-bound backgrounds jump in the opposite direction: background3DContainer.velocityY = -self.jumpStrength; // becomes +12 bgEffect3DContainer.velocityY = -self.jumpStrength; } }; Summary Y Offset: We now set each background’s y position to be the character’s y plus 500px plus a dynamic offset. Dynamic Offset: Each container has its own velocityY and gravity (set to –0.3) so that they “float” in the opposite direction. Opposite Jump: When the character jumps (with a negative velocity), the backgrounds receive a positive velocity (the negative of the jump strength).
User prompt
Update the y position of the character-bound backgrounds to be 500px down during game update
User prompt
move justx asset 10 pixel up 15 pixel left
User prompt
move button close 30 pixel down 15 pixel left
Code edit (1 edits merged)
Please save this source code
User prompt
move buton close 30 pixel down
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'attachAsset')' in or related to this line: 'var halo = character.attachAsset('haloAsset', {' Line Number: 255
User prompt
// 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; // Character uses its own gravity and jump strength self.gravity = 0.3; self.jumpStrength = -12; self.width = 350; self.height = 300; self.update = function () { if (gameStarted && !gameOver) { // Update character physics self.velocityY += self.gravity; self.y += self.velocityY; // Invert movement for any attached asset that should follow inverted gravity. // For instance, if you attach an asset with the flag 'invertAssetMotion' self.children.forEach(function(child) { if (child.invertAssetMotion) { // Subtracting the same velocity reverses the effect relative to the character. child.y -= self.velocityY; } }); // Rest of your collision and boundary checks... 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(); } // (Collision checks with tubes and trees remain unchanged) 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 { 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) && !self.preventTreeDeath) { gameOver = true; endGame(); } } } } }); } }; // Modified jump function that only changes character's velocity. // (The attached assets will update automatically in the update loop.) self.jump = function () { if (!gameOver && gameStarted) { self.velocityY = self.jumpStrength; LK.getSound('wingeffect').play(); // Optionally, if you want an immediate effect on attached assets, // you could also update them here: self.children.forEach(function(child) { if (child.invertAssetMotion) { // This makes the asset "jump" oppositely right away. child.y -= self.jumpStrength; } }); } }; return self; }); How to Use This Approach Marking an Asset: When you attach an asset to the character that should have an inverted jump effect, set the flag on that asset. For example: js Kopyala Düzenle var halo = self.attachAsset('haloAsset', { anchorX: 0.5, anchorY: 0.5 }); halo.invertAssetMotion = true; // This flag tells the update loop to move it oppositely. uygula
User prompt
Update the y position of the character-bound backgrounds to be 600px down during game update
User prompt
Update the y position of the character-bound backgrounds to be 500px down during game update
User prompt
Fix the y-position of character-bound backgrounds to be 400px down
User prompt
1. Adjust the Close Button Position (Shift 150px left and 150px down): For example, in your modal functions (e.g. in showVolume, showCredits, and showRecords), change the close button position from something like: js Kopyala Düzenle closeButton.x = bg.x + modalWidth/2 - closeButton.width/2 - 20; closeButton.y = bg.y - modalHeight/2 + closeButton.height/2 + 20; to js Kopyala Düzenle closeButton.x = bg.x + modalWidth/2 - closeButton.width/2 - (20 + 150); // i.e. -170 closeButton.y = bg.y - modalHeight/2 + closeButton.height/2 + (20 + 150); // i.e. +170 2. Fix the Character-bound Backgrounds to be 300px Down: Where you position your 3dlikebackground and 3dbgeffect containers, update their y‐position as follows: js Kopyala Düzenle background3DContainer.y = (character ? character.y : centerY()) + 300; bgEffect3DContainer.y = (character ? character.y : centerY()) + 300;
Code edit (1 edits merged)
Please save this source code
/**** * 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; // Character uses its own gravity and jump strength 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; // Invert movement for any attached asset that should follow inverted gravity. self.children.forEach(function (child) { if (child.invertAssetMotion) { // Subtracting the same velocity reverses the effect relative to the character. child.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 { 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) && !self.preventTreeDeath) { gameOver = true; endGame(); } } } } }); } }; self.jump = function () { if (!gameOver && gameStarted) { self.velocityY = self.jumpStrength; LK.getSound('wingeffect').play(); // Optionally, if you want an immediate effect on attached assets, // you could also update them here: self.children.forEach(function (child) { if (child.invertAssetMotion) { // This makes the asset "jump" oppositely right away. child.y -= 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; 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; 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; if (self.velocityX === 0) { background.velocityX = 0; bg2.velocityX = 0; } 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; 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 halo = character.attachAsset('haloAsset', { anchorX: 0.5, anchorY: 0.5 }); halo.invertAssetMotion = true; // This flag tells the update loop to move it oppositely. // Use a dedicated variable for the background width (the 3dlikebackground width) var backgroundWidth = 2807; // Use a lower scroll speed for smooth movement var backgroundScrollSpeed = 3.6; var musicSequence = ['m_1', 'M_2', 'M_3']; var musicCycle = 0; 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]); } } LK.playMusic(musicSequence[0]); // Add underscore asset var underscoreAsset = LK.getAsset('_', { anchorX: 0.5, anchorY: 0.5, x: centerX() + 1000, y: centerY() }); 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 only the character-bound 3dlikebackground and 3dbgeffect: var background3D = LK.getAsset('3dlikebackground', { anchorX: 0.5, anchorY: 0.5 }); var background3DContainer = new Container(); background3DContainer.addChild(background3D); // Position based on character's y and centerX(), then shift down 300px: background3DContainer.x = centerX(); background3DContainer.y = (character ? character.y : centerY()) + 400; background3DContainer.zIndex = 0.5; game.addChild(background3DContainer); var bgEffect3D = LK.getAsset('3dbgeffect', { anchorX: 0.5, anchorY: 0.5 }); var bgEffect3DContainer = new Container(); bgEffect3DContainer.addChild(bgEffect3D); // Position it immediately to the right of the 3dlikebackground and shift down 300px: bgEffect3DContainer.x = background3DContainer.x + backgroundWidth; bgEffect3DContainer.y = (character ? character.y : centerY()) + 400; bgEffect3DContainer.zIndex = 0.5; game.addChild(bgEffect3DContainer); function createCloseButton() { var closeButtonContainer = new Container(); closeButtonContainer.zIndex = 9999; var closeShape = LK.getAsset('button_close', { anchorX: 0.5, anchorY: 0.5, width: 160 * 0.8, height: 160 * 1.2 }); closeButtonContainer.addChild(closeShape); var closeLabel = LK.getAsset('justX', { anchorX: 0.5, anchorY: 0.5, x: -6, y: 2 }); closeButtonContainer.addChild(closeLabel); return closeButtonContainer; } 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; } 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 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 = []; 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 underscoreTouchCount = 0; 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; 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, 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); 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, 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); 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 * 1.5, 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); 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, 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); 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; game.addChild(background); var bg2 = LK.getAsset('bg2', { anchorX: 0.5, anchorY: 0.5, x: centerX() + 2807.2, y: groundY / 2 }); bg2.zIndex = 0; 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); var character = game.addChild(new Character()); character.x = centerX(); character.y = groundY / 2; 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, y: 16 }); 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("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); game.addChild(creditsContainer); // Add close button as child of creditsContainer: var closeButton = createCommonCloseElements(modalWidth, modalHeight); // Position close button relative to bg (e.g., top-right corner) closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 170; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 170; 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); // Add close button as child of volumeContainer: var closeButton = createCommonCloseElements(modalWidth, modalHeight); closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 170; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 170; 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); // Add close button as child of recordsContainer: var closeButton = createCommonCloseElements(modalWidth, modalHeight); closeButton.x = bg.x + modalWidth / 2 - closeButton.width / 2 - 170; closeButton.y = bg.y - modalHeight / 2 + closeButton.height / 2 + 170; recordsContainer.addChild(closeButton); closeButton.on('down', function () { game.removeChild(recordsContainer); menuOpen = true; menuContainer.visible = true; }); } /**** * End Game & Reset Functions ****/ 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; } }); 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 = groundY / 2; background.x = centerX(); bg2.x = centerX() + 2807.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); } /**** * 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 () { // Update the y position of the character-bound backgrounds: if (character) { background3DContainer.y = character.y + 600; bgEffect3DContainer.y = character.y + 600; } game.children.forEach(function (child) { if (child.update) { child.update(); } // The static backgrounds (background, bg2) move normally: if (child === background || child === bg2) { if (!gameOver && !menuOpen && gameStarted) { child.x -= 7.2; } if (child.x < -2807.2 / 2) { child.x += 2807.2 * 2; } } // The character-bound 3dlikebackground and 3dbgeffect move smoothly: if (child === background3DContainer || child === bgEffect3DContainer) { if (!gameOver && !menuOpen && gameStarted) { child.x -= backgroundScrollSpeed; } 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 getCurrentMusicName() { return musicSequence[currentMusicIndex]; }
===================================================================
--- original.js
+++ change.js
@@ -18,8 +18,15 @@
self.update = function () {
if (gameStarted && !gameOver) {
self.velocityY += self.gravity;
self.y += self.velocityY;
+ // Invert movement for any attached asset that should follow inverted gravity.
+ self.children.forEach(function (child) {
+ if (child.invertAssetMotion) {
+ // Subtracting the same velocity reverses the effect relative to the character.
+ child.y -= self.velocityY;
+ }
+ });
if (self.y > groundY - 100) {
self.y = groundY - 100;
self.velocityY = 0;
if (!self.intersects(underscoreAsset) && !self.preventDeath) {
@@ -71,8 +78,16 @@
self.jump = function () {
if (!gameOver && gameStarted) {
self.velocityY = self.jumpStrength;
LK.getSound('wingeffect').play();
+ // Optionally, if you want an immediate effect on attached assets,
+ // you could also update them here:
+ self.children.forEach(function (child) {
+ if (child.invertAssetMotion) {
+ // This makes the asset "jump" oppositely right away.
+ child.y -= self.jumpStrength;
+ }
+ });
}
};
return self;
});
@@ -204,8 +219,13 @@
/****
* Game Code
****/
+var halo = character.attachAsset('haloAsset', {
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+halo.invertAssetMotion = true; // This flag tells the update loop to move it oppositely.
// Use a dedicated variable for the background width (the 3dlikebackground width)
var backgroundWidth = 2807;
// Use a lower scroll speed for smooth movement
var backgroundScrollSpeed = 3.6;