User prompt
Let's add a small version of entity A1 to the progress line and see the remaining distance the character has to it
User prompt
Let's add a small version of entity B1 to the progress line and see the remaining distance of the character to it
User prompt
Let's add a small version of the gem entity to the progress line and see the remaining distance the character has to it
User prompt
Let's name the line lolo1
User prompt
Let's increase the size of the character inside the line a little bit so that it becomes visible to the eye.
User prompt
Let's shorten the distance of the line on the right side
User prompt
Let's enlarge the image of the line but bring it to the left
User prompt
Do not show the remaining distance text on the line no
User prompt
Let's enlarge this line by 100 units and put it at the bottom of the distance meter.
User prompt
Let's add a line to the game and have a mini version of the character on that line and show the remaining distance to move to the 2nd part of the game.
User prompt
Put the map under the distance meter
User prompt
Add a 2D tiny map platformer to the game, let's see the player, let's see A1, let's see B1, let's see the jewel in this map
User prompt
Every time the player collects 50 coins, he gets a new chance
User prompt
Hide god mode for now and teleport
User prompt
Hide god mode and teleport for now
User prompt
Change the font of the number of coins we collect from 1 to 10000 avenir
User prompt
Change the name of the coin icon to wumpa1
User prompt
Rename the coin symbol entity to wumpa1
User prompt
Change the coin symbol to wumpa 1
User prompt
Change the name of the coin asset in the game to wumpa
User prompt
Stop the trees from advancing, let the trees stand still
User prompt
Before the game starts, a screen will appear, just like a black screen, and there will be an asset box that says start.
User prompt
When we move on to the second part of the game, replace the ground asset with the ground2 asset.
User prompt
When we move on to the 2nd part of the game, the background asset should switch to the background2 asset.
User prompt
If the player says continue on the black screen, the game will move on to the second part.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { totalCoins: 0, powerUps: {}, playerName: "Player", lastScore: 0, highScore: 0, gamesPlayed: 0, totalDistance: 0, bestDistance: 0, achievements: {}, settings: { soundEnabled: true, musicEnabled: true, difficulty: "normal" } }); /**** * Classes ****/ var Box = Container.expand(function () { var self = Container.call(this); var boxGraphics = self.attachAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, tint: 0xFFB347 // Bright orange color }); self.speed = gameSpeed; self.broken = false; self.health = 1; // Can be broken in one hit self.update = function () { self.x -= self.speed; }; // Method to break the box and spawn coins self.breakBox = function () { if (!self.broken) { self.broken = true; // Create breaking effect LK.effects.flashObject(self, 0xFFFFFF, 300); // Spawn 2-3 coins around the box var numCoins = 2 + Math.floor(Math.random() * 2); for (var c = 0; c < numCoins; c++) { var coin = new Coin(); coin.x = self.x + (Math.random() - 0.5) * 100; coin.y = self.y + (Math.random() - 0.5) * 80; coins.push(coin); game.addChild(coin); } // Simple fade out without scaling or rotation tween(self, { alpha: 0 }, { duration: 400, onFinish: function onFinish() { self.destroy(); } }); } }; return self; }); var C2 = Container.expand(function () { var self = Container.call(this); var c2Graphics = self.attachAsset('C2', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Set custom hitbox dimensions self.hitboxWidth = 200; self.hitboxHeight = 200; // Override width and height properties for collision detection Object.defineProperty(self, 'width', { get: function get() { return self.hitboxWidth; }, set: function set(value) { self.hitboxWidth = value; } }); Object.defineProperty(self, 'height', { get: function get() { return self.hitboxHeight; }, set: function set(value) { self.hitboxHeight = value; } }); self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var C3 = Container.expand(function () { var self = Container.call(this); var c3Graphics = self.attachAsset('C3', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Set custom hitbox dimensions self.hitboxWidth = 200; self.hitboxHeight = 200; // Override width and height properties for collision detection Object.defineProperty(self, 'width', { get: function get() { return self.hitboxWidth; }, set: function set(value) { self.hitboxWidth = value; } }); Object.defineProperty(self, 'height', { get: function get() { return self.hitboxHeight; }, set: function set(value) { self.hitboxHeight = value; } }); self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var C4 = Container.expand(function () { var self = Container.call(this); var c4Graphics = self.attachAsset('C4', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Set custom hitbox dimensions self.hitboxWidth = 200; self.hitboxHeight = 200; // Override width and height properties for collision detection Object.defineProperty(self, 'width', { get: function get() { return self.hitboxWidth; }, set: function set(value) { self.hitboxWidth = value; } }); Object.defineProperty(self, 'height', { get: function get() { return self.hitboxHeight; }, set: function set(value) { self.hitboxHeight = value; } }); self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var C5 = Container.expand(function () { var self = Container.call(this); var c5Graphics = self.attachAsset('C5', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Set custom hitbox dimensions self.hitboxWidth = 200; self.hitboxHeight = 200; // Override width and height properties for collision detection Object.defineProperty(self, 'width', { get: function get() { return self.hitboxWidth; }, set: function set(value) { self.hitboxWidth = value; } }); Object.defineProperty(self, 'height', { get: function get() { return self.hitboxHeight; }, set: function set(value) { self.hitboxHeight = value; } }); self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var C6 = Container.expand(function () { var self = Container.call(this); var c6Graphics = self.attachAsset('C6', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Set custom hitbox dimensions self.hitboxWidth = 200; self.hitboxHeight = 200; // Override width and height properties for collision detection Object.defineProperty(self, 'width', { get: function get() { return self.hitboxWidth; }, set: function set(value) { self.hitboxWidth = value; } }); Object.defineProperty(self, 'height', { get: function get() { return self.hitboxHeight; }, set: function set(value) { self.hitboxHeight = value; } }); self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('wumpa', { anchorX: 0.5, anchorY: 0.5 }); // Create aura effect var aura = self.attachAsset('wumpa', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.3, tint: 0xFFD700 }); self.speed = gameSpeed; self.collected = false; // Floating animation self.floatOffset = 0; // Start aura pulsing animation function startAuraPulse() { tween(aura, { scaleX: 2.0, scaleY: 2.0, alpha: 0.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(aura, { scaleX: 1.5, scaleY: 1.5, alpha: 0.3 }, { duration: 800, easing: tween.easeInOut, onFinish: startAuraPulse }); } }); } startAuraPulse(); self.update = function () { self.x -= self.speed; // Floating animation self.floatOffset += 0.15; coinGraphics.y = Math.sin(self.floatOffset) * 10; aura.y = Math.sin(self.floatOffset) * 10; // Rotation animation coinGraphics.rotation += 0.1; aura.rotation -= 0.05; // Counter-rotate aura for visual effect }; return self; }); var DamageBox = Container.expand(function () { var self = Container.call(this); var damageBoxGraphics = self.attachAsset('tnt_box', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, tint: 0x8B4513 // Brown box color with TNT styling }); self.speed = gameSpeed; self.damaged = false; self.update = function () { self.x -= self.speed; }; // Method to cause damage to player self.damagePlayer = function () { if (!self.damaged && !player.isInvulnerable && !godModeActive) { self.damaged = true; playerLives--; // Play heart damage sound when lives decrease LK.getSound('Canazalma').play(); // Add screen shake effect var originalX = game.x; var originalY = game.y; var shakeIntensity = 20; var shakeDuration = 300; // Create shake animation sequence tween(game, { x: originalX + shakeIntensity, y: originalY + shakeIntensity * 0.5 }, { duration: shakeDuration / 6, easing: tween.easeOut, onFinish: function onFinish() { tween(game, { x: originalX - shakeIntensity, y: originalY - shakeIntensity * 0.5 }, { duration: shakeDuration / 6, easing: tween.easeOut, onFinish: function onFinish() { tween(game, { x: originalX + shakeIntensity * 0.5, y: originalY + shakeIntensity * 0.3 }, { duration: shakeDuration / 6, easing: tween.easeOut, onFinish: function onFinish() { tween(game, { x: originalX - shakeIntensity * 0.5, y: originalY - shakeIntensity * 0.3 }, { duration: shakeDuration / 6, easing: tween.easeOut, onFinish: function onFinish() { tween(game, { x: originalX, y: originalY }, { duration: shakeDuration / 3, easing: tween.easeOut }); } }); } }); } }); } }); // Update lives counter text with animation livesText.setText(playerLives); // Font is already set in the Text2 constructor, no need to change it here // Animate lives text when taking damage tween(livesText, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(livesText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeIn }); } }); // Flash heart when taking damage if (playerLives > 0) { LK.effects.flashObject(hearts[0], 0xFF0000, 500); } else { hearts[0].alpha = 0.3; } // Make player invulnerable temporarily player.isInvulnerable = true; LK.effects.flashObject(player, 0xFF0000, 1000); // Remove invulnerability after 2 seconds LK.setTimeout(function () { player.isInvulnerable = false; }, 2000); // Check for game over if (playerLives <= 0) { LK.showGameOver(); } // Create explosion effect when damaged self.createExplosion(); } }; // Method to create explosion effect self.createExplosion = function () { // Create explosion particles for (var p = 0; p < 12; p++) { var particle = LK.getAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, alpha: 1.0, x: self.x, y: self.y, tint: 0x654321 }); game.addChild(particle); var angle = p / 12 * Math.PI * 2; var distance = 100 + Math.random() * 80; var targetX = self.x + Math.cos(angle) * distance; var targetY = self.y + Math.sin(angle) * distance; tween(particle, { x: targetX, y: targetY, alpha: 0, scaleX: 0.1, scaleY: 0.1, rotation: Math.PI * 2 * (Math.random() > 0.5 ? 1 : -1) }, { duration: 600 + Math.random() * 200, easing: tween.easeOut, onFinish: function onFinish() { particle.destroy(); } }); } // Flash screen and hide the damage box LK.effects.flashScreen(0xFF0000, 300); tween(self, { alpha: 0, scaleX: 2.0, scaleY: 2.0 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var EndGate = Container.expand(function () { var self = Container.call(this); var gateGraphics = self.attachAsset('B1', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2, tint: 0xFFD700 // Golden color for finish gate }); // Create circular portal effect inside the gate (same as StartingGate) var portalCircle = self.attachAsset('B1', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, x: 0, y: -280, alpha: 0.8, tint: 0x00FFFF }); // Start rotating animation for the portal function startPortalRotation() { // Animation removed - portal remains static } // Add pulsing animation to make portal more dynamic function startPortalPulse() { // Animation removed - portal remains static } // Animation functions removed - portal remains static // Add victory glow effect var victoryGlow = self.attachAsset('B1', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.5, scaleY: 1.5, alpha: 0.4, tint: 0xFFFFFF // White victory glow }); // Start victory glow pulsing animation function startVictoryPulse() { // Animation removed - victory glow remains static } // Animation function removed - victory glow remains static self.speed = gameSpeed; self.crossed = false; self.update = function () { self.x -= self.speed; }; // Method to trigger win condition self.triggerWin = function () { if (!self.crossed) { self.crossed = true; // Game completion var completionMessage = 'GAME COMPLETED!'; var completionColor = 0x00FF00; // Create victory particle effect for (var p = 0; p < 20; p++) { var particle = LK.getAsset('B1', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, alpha: 1.0, x: self.x, y: self.y - 200, tint: p % 3 === 0 ? 0xFFD700 : p % 3 === 1 ? 0xFFFFFF : 0x00FF00 }); game.addChild(particle); var angle = p / 20 * Math.PI * 2; var distance = 200 + Math.random() * 150; var targetX = self.x + Math.cos(angle) * distance; var targetY = self.y - 200 + Math.sin(angle) * distance; tween(particle, { x: targetX, y: targetY, alpha: 0, scaleX: 0.1, scaleY: 0.1, rotation: Math.PI * 3 }, { duration: 1500 + Math.random() * 500, easing: tween.easeOut, onFinish: function onFinish() { particle.destroy(); } }); } // Chapter completion message removed for Chapter 2 // Flash screen with victory colors LK.effects.flashScreen(0xFFD700, 800); // Show collectibles summary after a brief delay LK.setTimeout(function () { showCollectiblesSummary(); }, 800); // Final game completion removed - no "You won the game" screen } }; return self; }); var Gem = Container.expand(function () { var self = Container.call(this); var gemGraphics = self.attachAsset('gem', { anchorX: 0.5, anchorY: 0.5 }); // Create crystalline aura effect var aura1 = self.attachAsset('gem', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 1.3, alpha: 0.4, tint: 0x00FFFF }); var aura2 = self.attachAsset('gem', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.6, scaleY: 1.6, alpha: 0.2, tint: 0x8A2BE2 }); self.speed = gameSpeed; self.collected = false; // Crystal aura remains steady without pulsing animation self.update = function () { self.x -= self.speed; // Crystal remains steady without rotation }; // Method to create particle effect when collected self.createParticles = function () { for (var p = 0; p < 8; p++) { var particle = LK.getAsset('gem', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, alpha: 0.8, x: self.x, y: self.y, tint: p % 2 === 0 ? 0x00FFFF : 0x8A2BE2 }); game.addChild(particle); var angle = p / 8 * Math.PI * 2; var distance = 150 + Math.random() * 100; var targetX = self.x + Math.cos(angle) * distance; var targetY = self.y + Math.sin(angle) * distance; tween(particle, { x: targetX, y: targetY, alpha: 0, scaleX: 0.1, scaleY: 0.1, rotation: Math.PI * 2 }, { duration: 800 + Math.random() * 400, easing: tween.easeOut, onFinish: function onFinish() { particle.destroy(); } }); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var foxGraphics = self.attachAsset('C1', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Set custom hitbox dimensions self.hitboxWidth = 200; self.hitboxHeight = 200; // Override width and height properties for collision detection Object.defineProperty(self, 'width', { get: function get() { return self.hitboxWidth; }, set: function set(value) { self.hitboxWidth = value; } }); Object.defineProperty(self, 'height', { get: function get() { return self.hitboxHeight; }, set: function set(value) { self.hitboxHeight = value; } }); self.isJumping = false; self.velocityY = 0; self.groundY = 2732 - 150 + 20; // Ground level self.jumpPower = -27; self.gravity = 1.2; self.runAnimationTimer = 0; self.isSpinning = false; self.spinDamageRadius = 150; self.jumpsRemaining = 2; // Allow double jump self.jump = function () { if (self.jumpsRemaining > 0) { // First jump or double jump if (!self.isJumping) { self.isJumping = true; } self.velocityY = self.jumpPower; self.jumpsRemaining--; LK.getSound('jump').play(); // Simple jump animation without somersault - just scale effect var jumpDuration = 300; // Shorter duration for simple jump // Different animation for double jump var isDoubleJump = self.jumpsRemaining === 0 && self.isJumping; if (isDoubleJump) { // Double jump animation - enhanced scale effect tween(foxGraphics, { scaleX: 1.4, scaleY: 1.4 }, { duration: jumpDuration, easing: tween.easeOut, onFinish: function onFinish() { tween(foxGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeIn }); } }); } else { // Regular jump animation - simple scale effect tween(foxGraphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: jumpDuration, easing: tween.easeOut, onFinish: function onFinish() { tween(foxGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeIn }); } }); } } }; self.spinAttack = function () { if (!self.isSpinning) { self.isSpinning = true; LK.getSound('jump').play(); // Reuse jump sound for spin // Horizontal rotation animation around character's center tween(foxGraphics, { rotation: Math.PI * 4, // 2 full horizontal rotations scaleX: 1.5, scaleY: 1.5, tint: 0xFF4500 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { self.isSpinning = false; foxGraphics.rotation = 0; foxGraphics.scaleX = 1.0; foxGraphics.scaleY = 1.0; foxGraphics.tint = 0xFFFFFF; } }); } }; self.update = function () { if (self.isJumping) { self.velocityY += self.gravity; self.y += self.velocityY; // Land on ground if (self.y >= self.groundY) { self.y = self.groundY; self.isJumping = false; self.velocityY = 0; self.jumpsRemaining = 2; // Reset double jump when landing // Reset character scale when landing tween(foxGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); } } else { // Running animation when on ground self.runAnimationTimer += 0.2; foxGraphics.y = Math.sin(self.runAnimationTimer) * 3; foxGraphics.scaleX = 1.0 + Math.sin(self.runAnimationTimer * 2) * 0.05; } }; return self; }); var StartingGate = Container.expand(function () { var self = Container.call(this); var gateGraphics = self.attachAsset('A1', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.0, scaleY: 1.0 }); // Create circular portal effect inside the gate var portalCircle = self.attachAsset('A1', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, x: 0, y: -200, alpha: 0.8, tint: 0x00FFFF }); // Start rotating animation for the portal function startPortalRotation() { // Animation removed - portal remains static } // Add pulsing animation to make portal more dynamic function startPortalPulse() { // Animation removed - portal remains static } // Animation functions removed - portal remains static self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var Store = Container.expand(function () { var self = Container.call(this); self.isOpen = false; self.storeItems = [{ id: 'doubleJump', name: 'Super Jump', price: 50, description: 'Higher jumps!', owned: false }, { id: 'coinMagnet', name: 'Coin Magnet', price: 100, description: 'Attract coins!', owned: false }, { id: 'speedBoost', name: 'Speed Boost', price: 75, description: 'Move faster!', owned: false }, { id: 'shield', name: 'Shield', price: 150, description: 'Extra protection!', owned: false }]; // Load owned items from storage for (var i = 0; i < self.storeItems.length; i++) { var item = self.storeItems[i]; item.owned = storage.powerUps[item.id] || false; } self.openStore = function () { if (self.isOpen) return; self.isOpen = true; // Pause the game when store opens LK.pauseGame(); // Create overlay self.overlay = LK.getAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 30, scaleY: 40, alpha: 0.9, tint: 0x000033, x: 1024, y: 1366 }); game.addChild(self.overlay); // Create store panel self.panel = LK.getAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 25, tint: 0x1a1a2e, x: 1024, y: 1366 }); game.addChild(self.panel); // Store title self.titleText = new Text2('POWER-UP STORE', { size: 100, fill: 0xFFD700, font: "Avenir", fontWeight: 'bold' }); self.titleText.anchor.set(0.5, 0.5); self.titleText.x = 1024; self.titleText.y = 600; game.addChild(self.titleText); // Coin display var totalCoins = storage.totalCoins || 0; self.coinDisplay = new Text2('Coins: ' + totalCoins, { size: 60, fill: 0xFFD700, font: "Avenir", fontWeight: 'bold' }); self.coinDisplay.anchor.set(0.5, 0.5); self.coinDisplay.x = 1024; self.coinDisplay.y = 700; game.addChild(self.coinDisplay); // Create store items self.itemElements = []; for (var i = 0; i < self.storeItems.length; i++) { self.createStoreItem(i); } // Close button self.closeButton = LK.getAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, tint: 0xFF4444, x: 1024, y: 2000 }); game.addChild(self.closeButton); self.closeText = new Text2('CLOSE', { size: 50, fill: 0xFFFFFF, font: "Avenir", fontWeight: 'bold' }); self.closeText.anchor.set(0.5, 0.5); self.closeText.x = 1024; self.closeText.y = 2000; game.addChild(self.closeText); // Close button interaction self.closeButton.down = function () { self.closeStore(); }; // Animate store opening tween(self.overlay, { alpha: 0.9 }, { duration: 300 }); tween(self.panel, { scaleX: 20, scaleY: 25 }, { duration: 400, easing: tween.easeOut }); }; self.createStoreItem = function (index) { var item = self.storeItems[index]; var yPos = 850 + index * 180; // Item background var itemBg = LK.getAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 3, tint: item.owned ? 0x004400 : 0x333366, x: 1024, y: yPos }); game.addChild(itemBg); // Item name var nameText = new Text2(item.name, { size: 50, fill: item.owned ? 0x88FF88 : 0xFFFFFF, font: "Avenir", fontWeight: 'bold' }); nameText.anchor.set(0.5, 0.5); nameText.x = 800; nameText.y = yPos - 20; game.addChild(nameText); // Item description var descText = new Text2(item.description, { size: 35, fill: 0xCCCCCC, font: "Avenir" }); descText.anchor.set(0.5, 0.5); descText.x = 800; descText.y = yPos + 20; game.addChild(descText); // Price/Status var priceText = new Text2(item.owned ? 'OWNED' : item.price + ' coins', { size: 45, fill: item.owned ? 0x00FF00 : 0xFFD700, font: "Avenir", fontWeight: 'bold' }); priceText.anchor.set(0.5, 0.5); priceText.x = 1200; priceText.y = yPos; game.addChild(priceText); // Buy button (only if not owned) if (!item.owned) { var buyButton = LK.getAsset('box1', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 1.5, tint: 0x00AA00, x: 1350, y: yPos }); game.addChild(buyButton); var buyText = new Text2('BUY', { size: 40, fill: 0xFFFFFF, font: "Avenir", fontWeight: 'bold' }); buyText.anchor.set(0.5, 0.5); buyText.x = 1350; buyText.y = yPos; game.addChild(buyText); buyButton.down = function () { self.purchaseItem(index); }; self.itemElements.push({ bg: itemBg, name: nameText, desc: descText, price: priceText, buyBtn: buyButton, buyTxt: buyText }); } else { self.itemElements.push({ bg: itemBg, name: nameText, desc: descText, price: priceText }); } }; self.purchaseItem = function (index) { var item = self.storeItems[index]; var totalCoins = storage.totalCoins || 0; if (totalCoins >= item.price && !item.owned) { // Purchase successful storage.totalCoins = totalCoins - item.price; storage.powerUps[item.id] = true; item.owned = true; // Update coin display self.coinDisplay.setText('Coins: ' + storage.totalCoins); // Flash effect LK.effects.flashScreen(0x00FF00, 300); // Update item appearance var elements = self.itemElements[index]; elements.bg.tint = 0x004400; elements.name.fill = 0x88FF88; elements.price.setText('OWNED'); elements.price.fill = 0x00FF00; if (elements.buyBtn) { elements.buyBtn.destroy(); elements.buyTxt.destroy(); } } else { // Not enough coins LK.effects.flashScreen(0xFF0000, 300); } }; self.closeStore = function () { if (!self.isOpen) return; self.isOpen = false; // Resume the game when store closes LK.resumeGame(); // Clean up all store elements if (self.overlay) self.overlay.destroy(); if (self.panel) self.panel.destroy(); if (self.titleText) self.titleText.destroy(); if (self.coinDisplay) self.coinDisplay.destroy(); if (self.closeButton) self.closeButton.destroy(); if (self.closeText) self.closeText.destroy(); for (var i = 0; i < self.itemElements.length; i++) { var elements = self.itemElements[i]; elements.bg.destroy(); elements.name.destroy(); elements.desc.destroy(); elements.price.destroy(); if (elements.buyBtn) elements.buyBtn.destroy(); if (elements.buyTxt) elements.buyTxt.destroy(); } self.itemElements = []; }; return self; }); var Trail = Container.expand(function () { var self = Container.call(this); var trailGraphics = self.attachAsset('C1', { anchorX: 0.5, anchorY: 1.0, scaleX: 0.6, scaleY: 0.6, alpha: 0.7 }); self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var Tree = Container.expand(function () { var self = Container.call(this); // Random tree type (1, 2, or 3) var treeType = Math.floor(Math.random() * 3) + 1; var treeAssetName = 'tree' + treeType; // Define distinct colors for each tree type to make them more distinguishable var treeColors = [0x228B22, // Forest Green for tree1 0x8B4513, // Saddle Brown for tree2 0x006400 // Dark Green for tree3 ]; var treeColor = treeColors[treeType - 1]; // Create tree foliage - position directly on ground without trunk var foliage = self.attachAsset(treeAssetName, { anchorX: 0.5, anchorY: 1.0, y: 0, // Position foliage directly on ground scaleX: 2.2, // Make foliage much larger scaleY: 2.2, // Make foliage much larger tint: treeColor // Apply distinctive color }); // Create shadow effect to make tree more distinct var shadow = self.attachAsset(treeAssetName, { anchorX: 0.5, anchorY: 1.0, y: 5, // Slightly offset shadow scaleX: 2.1, scaleY: 2.0, alpha: 0.3, tint: 0x000000 // Black shadow }); self.speed = gameSpeed; self.breathingOffset = Math.random() * Math.PI * 2; // Random phase for each tree self.breathingSpeed = 0.8 + Math.random() * 0.4; // Slight variation in breathing speed // Trees are now fixed - no breathing animation function startBreathing() { // No animation - trees remain static and fixed to ground } // Trees are now fixed - no swaying animation function startSwaying() { // No animation - trees remain static and fixed to ground } startBreathing(); // No swaying animation call - trees stay fixed self.update = function () { self.x -= self.speed; // Trees are now fixed to ground with no floating animations // Keep foliage and shadow at fixed positions - foliage positioned at top of ground foliage.y = -50; // Position foliage at top area of ground entity shadow.y = -45; // Position shadow slightly below foliage // Keep foliage and shadow at fixed scales foliage.scaleX = 2.2; foliage.scaleY = 2.2; shadow.scaleX = 2.1; shadow.scaleY = 2.0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var player; var coins = []; var gems = []; var boxes = []; var damageBoxes = []; var trails = []; var trees = []; var gameSpeed = 24; var spawnTimer = 0; var coinCount = 0; var gemCount = 0; var distanceScore = 0; var groundY = 2732 - 150 - 2; var playerLives = 3; var trailTimer = 0; var crystalSpawned = false; var endGateSpawned = false; var startingGate; var endGate; var background1, background2; // UI Elements var coinIcon = LK.getAsset('coin_icon', { anchorX: 0.5, anchorY: 0, x: 0, y: 20 }); LK.gui.top.addChild(coinIcon); var coinText = new Text2('0', { size: 120, fill: 0xFFFFFF, font: "Avenir", fontWeight: '900', stroke: 0x000000, strokeThickness: 15 }); coinText.anchor.set(0.5, 0); coinText.x = 0; coinText.y = 90; LK.gui.top.addChild(coinText); // Distance meter var distanceText = new Text2('0m', { size: 140, fill: 0x00FF00, font: "avenir", fontWeight: 'bold', stroke: 0x000000, strokeThickness: 20 }); distanceText.anchor.set(1.0, 0); distanceText.x = 0; distanceText.y = 20; LK.gui.topRight.addChild(distanceText); var gemIcon = null; var gemText = null; // Create heart UI elements - only one heart image with lives counter var hearts = []; // Create single heart image var heart = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, x: 150, y: 193 }); hearts.push(heart); LK.gui.topLeft.addChild(heart); // Create lives counter text var livesText = new Text2('3', { size: 120, fill: 0xFF8C00, font: "Avenir", fontWeight: '900', stroke: 0x000000, strokeThickness: 25 }); livesText.anchor.set(0.5, 0.5); livesText.x = 250; livesText.y = 173; LK.gui.topLeft.addChild(livesText); // Start constant bouncing animation for lives text function startLivesBounce() { tween(livesText, { y: 163 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { tween(livesText, { y: 183 }, { duration: 600, easing: tween.easeInOut, onFinish: startLivesBounce }); } }); } startLivesBounce(); ; // Function to show collectibles summary function showCollectiblesSummary() { // Pause all game movement LK.pauseGame(); // Create matte black screen overlay - add to GUI to stay in front of all assets var blackOverlay = LK.getAsset('ekn1', { anchorX: 0.5, anchorY: 0.5, alpha: 1.0, x: 0, y: 0 }); LK.gui.center.addChild(blackOverlay); // Title text removed // Collectible items removed from black screen summary var summaryItems = []; // Coin icons removed from black screen summary // Gem icons removed from black screen summary // Coins summary text removed // Gems summary text removed // Total score text removed // Save final game statistics var finalDistance = Math.floor(distanceScore / 10); storage.lastScore = coinCount; storage.totalCoins = (storage.totalCoins || 0) + coinCount; if (coinCount > (storage.highScore || 0)) { storage.highScore = coinCount; } if (finalDistance > (storage.bestDistance || 0)) { storage.bestDistance = finalDistance; } storage.gamesPlayed = (storage.gamesPlayed || 0) + 1; // Create main menu buttons after delay LK.setTimeout(function () { // Square box container for buttons removed // Create pause button var pauseButton = LK.getAsset('d2', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, x: -150, y: 200 }); LK.gui.center.addChild(pauseButton); var pauseButtonText = new Text2('PAUSE', { size: 60, fill: 0xFFFFFF, font: "Avenir", fontWeight: 'bold' }); pauseButtonText.anchor.set(0.5, 0.5); pauseButtonText.x = -150; pauseButtonText.y = 200; LK.gui.center.addChild(pauseButtonText); // Create continue button var continueButton = LK.getAsset('d1', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, x: 150, y: 200 }); LK.gui.center.addChild(continueButton); var continueButtonText = new Text2('CONTINUE', { size: 50, fill: 0xFFFFFF, font: "Avenir", fontWeight: 'bold' }); continueButtonText.anchor.set(0.5, 0.5); continueButtonText.x = 150; continueButtonText.y = 200; LK.gui.center.addChild(continueButtonText); // Add button functionality pauseButton.down = function () { LK.pauseGame(); LK.effects.flashScreen(0xFF4444, 300); }; continueButton.down = function () { // Hide continue button and d1 asset immediately continueButton.visible = false; continueButtonText.visible = false; // Clean up all UI elements blackOverlay.destroy(); pauseButton.destroy(); pauseButtonText.destroy(); continueButton.destroy(); continueButtonText.destroy(); // Flash effect and reset game for second part LK.effects.flashScreen(0x00AA00, 300); // Reset game variables for second part distanceScore = 0; coinCount = 0; gemCount = 0; playerLives = 3; gameSpeed = 24; normalSpeed = 24; crystalSpawned = false; endGateSpawned = false; spawnTimer = 0; trailTimer = 0; // Clear all arrays coins.length = 0; gems.length = 0; boxes.length = 0; damageBoxes.length = 0; trails.length = 0; trees.length = 0; // Reset character switching currentCharacterIndex = 0; currentCharacter = characterOrder[currentCharacterIndex]; lastSwapDistance = 0; nextSwapDistance = 2; // Reset player player.x = 400; player.y = groundY + 20; player.isJumping = false; player.velocityY = 0; player.jumpsRemaining = 2; player.isInvulnerable = false; player.isSpinning = false; // Reset graphics to first character player.removeChildAt(0); var newGraphics = player.attachAsset('C1', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Reset UI elements coinText.setText('0'); livesText.setText('3'); distanceText.setText('0m'); // Reset progress line for second part progressChar.x = 200; // Reset gem UI if exists if (gemIcon) { gemIcon.destroy(); gemIcon = null; } if (gemText) { gemText.destroy(); gemText = null; } // Reset hearts hearts[0].alpha = 1.0; // Reset god mode if (godModeActive) { toggleGodMode(); } // Create new starting gate for second part if (startingGate) { startingGate.destroy(); } startingGate = new StartingGate(); startingGate.x = 400 + 3 * 10; startingGate.y = groundY + 75; game.addChild(startingGate); // Switch to background2 for second part background1.destroy(); background2.destroy(); background3.destroy(); // Create new backgrounds using background2 asset background1 = game.addChild(LK.getAsset('background2', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); background2 = game.addChild(LK.getAsset('background2', { anchorX: 0, anchorY: 0, x: 2250, // Position second background at end of first background y: 0 })); background3 = game.addChild(LK.getAsset('background2', { anchorX: 0, anchorY: 0, x: 4500, // Position third background to eliminate gaps during transitions y: 0 })); // Replace ground assets with ground2 for second part ground1.destroy(); ground2.destroy(); ground3.destroy(); // Create new ground elements using ground2 asset ground1 = game.addChild(LK.getAsset('ground2', { anchorX: 0, anchorY: 0, x: 0, y: groundY })); ground2 = game.addChild(LK.getAsset('ground2', { anchorX: 0, anchorY: 0, x: 4008, // Position second ground at end of first ground y: groundY })); ground3 = game.addChild(LK.getAsset('ground2', { anchorX: 0, anchorY: 0, x: 8016, // Position third ground to eliminate gaps during transitions y: groundY })); // Resume game movement LK.resumeGame(); }; }, 2000); } ; ; // Spin button removed // Play background music constantly LK.playMusic('Arkaplanmuzik1'); // Create animated background elements for endless scrolling with third element to fill gaps var background1 = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); var background2 = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 2250, // Position second background at end of first background y: 0 })); var background3 = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 4500, // Position third background to eliminate gaps during transitions y: 0 })); // Create animated ground elements for endless scrolling var ground1 = game.addChild(LK.getAsset('zz1', { anchorX: 0, anchorY: 0, x: 0, y: groundY })); var ground2 = game.addChild(LK.getAsset('zz1', { anchorX: 0, anchorY: 0, x: 4008, // Position second ground at end of first ground y: groundY })); var ground3 = game.addChild(LK.getAsset('zz1', { anchorX: 0, anchorY: 0, x: 8016, // Position third ground to eliminate gaps during transitions y: groundY })); // Ground animation variables var groundAnimationTimer = 0; // Create starting gate startingGate = new StartingGate(); startingGate.x = 400 + 3 * 10; // Position at 3 meters (3m * 10 pixels per meter) startingGate.y = groundY + 75; // Position gate a little higher above the ground game.addChild(startingGate); // Create player (will be added to foreground later) player = new Player(); player.x = 400; player.y = groundY + 20; player.isInvulnerable = false; // Touch controls for swipe up to jump var touchStartY = null; var minSwipeDistance = 100; // Minimum distance for swipe detection game.down = function (x, y, obj) { touchStartY = y; }; game.up = function (x, y, obj) { if (touchStartY !== null) { var swipeDistance = touchStartY - y; // Positive means swipe up if (swipeDistance >= minSwipeDistance) { // Swipe up detected - make player jump player.jump(); } touchStartY = null; } }; // Spin button interaction removed function spawnCoin() { var coin = new Coin(); coin.x = 2048 + 100; // Randomly place coins either high in air or at medium height to avoid ground-level objects var coinHeightOptions = [groundY - 300 - Math.random() * 100, // High in air groundY - 180 - Math.random() * 80 // Medium height ]; coin.y = coinHeightOptions[Math.floor(Math.random() * coinHeightOptions.length)]; coins.push(coin); game.addChild(coin); } function spawnGem() { var gem = new Gem(); gem.x = 2048 + 100; gem.y = groundY - 80 - Math.random() * 200; gems.push(gem); game.addChild(gem); } function spawnBox() { // Randomly decide if this should be a 2-stage box (30% chance) var isTwoStage = Math.random() < 0.3; if (isTwoStage) { // Create bottom box var bottomBox = new Box(); bottomBox.x = 2048 + 100; bottomBox.y = groundY - 45; // Closer to ground level boxes.push(bottomBox); game.addChild(bottomBox); // Create top box var topBox = new Box(); topBox.x = 2048 + 100; topBox.y = groundY - 45 - 120; // Stack on top (120 pixels higher - increased spacing) boxes.push(topBox); game.addChild(topBox); } else { // Create single box as before var box = new Box(); box.x = 2048 + 100; box.y = groundY - 45; // Closer to ground level boxes.push(box); game.addChild(box); } } function spawnDamageBox() { // Create single TNT only var damageBox = new DamageBox(); damageBox.x = 2048 + 100; damageBox.y = groundY - 45; // Position TNT on ground level like boxes damageBoxes.push(damageBox); game.addChild(damageBox); } game.update = function () { // Increase distance score distanceScore += 1.5; // Update distance meter display var currentDistance = Math.floor(distanceScore / 10); distanceText.setText(currentDistance + 'm'); // Update progress line elements var targetDistance = 1500; // Distance to reach 2nd part var progressPercent = Math.min(currentDistance / targetDistance, 1.0); var lineWidth = 1120; // Total width of progress line - shortened // Move mini character along the progress line progressChar.x = 200 + progressPercent * lineWidth; // Remaining distance text updates removed // Update mini character asset to match current player character if (progressChar.children.length > 0) { progressChar.removeChildAt(0); } var miniCharGraphics = progressChar.attachAsset(currentCharacter, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); // Character switching logic - cycle through all 12 characters every 2 meters var currentDistance = Math.floor(distanceScore / 10); if (currentDistance >= nextSwapDistance) { // Move to next character in the cycle currentCharacterIndex = (currentCharacterIndex + 1) % characterOrder.length; currentCharacter = characterOrder[currentCharacterIndex]; // Remove old graphics and add new character graphics player.removeChildAt(0); // Remove current graphics var newGraphics = player.attachAsset(currentCharacter, { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2 }); // Update swap distances lastSwapDistance = currentDistance; nextSwapDistance = currentDistance + 2; // Visual feedback for swap LK.effects.flashObject(player, 0xFFFFFF, 300); } // Gradually increase speed - but respect God mode if (!godModeActive) { gameSpeed = 24 + distanceScore / 1000; normalSpeed = 24 + distanceScore / 1000; // Track normal speed for God mode toggle } else { gameSpeed = normalSpeed * 3; // Maintain high speed in God mode } // Update starting gate if (startingGate && startingGate.parent) { startingGate.speed = gameSpeed; // Remove gate when it goes off screen if (startingGate.x < -200) { startingGate.destroy(); startingGate = null; } } // Update end gate if (endGate && endGate.parent) { endGate.speed = gameSpeed; // Remove gate when it goes off screen (after win condition) if (endGate.x < -400) { endGate.destroy(); endGate = null; } } // Move all background elements with game progression (same speed as ground - no parallax effect) background1.x -= gameSpeed; background2.x -= gameSpeed; background3.x -= gameSpeed; // Reset background positions for endless scrolling with immediate positioning to eliminate gaps if (background1.x <= -2250) { // Find the rightmost background element var rightmostX = Math.max(background2.x, background3.x); // Immediately position to eliminate gaps background1.x = rightmostX + 2250; } if (background2.x <= -2250) { // Find the rightmost background element var rightmostX = Math.max(background1.x, background3.x); // Immediately position to eliminate gaps background2.x = rightmostX + 2250; } if (background3.x <= -2250) { // Find the rightmost background element var rightmostX = Math.max(background1.x, background2.x); // Immediately position to eliminate gaps background3.x = rightmostX + 2250; } // Move all ground elements with game progression ground1.x -= gameSpeed; ground2.x -= gameSpeed; ground3.x -= gameSpeed; // Reset ground positions for endless scrolling with immediate positioning to eliminate gaps if (ground1.x <= -4008) { // Find the rightmost ground element var rightmostX = Math.max(ground2.x, ground3.x); // Immediately position to eliminate gaps ground1.x = rightmostX + 4008; } if (ground2.x <= -4008) { // Find the rightmost ground element var rightmostX = Math.max(ground1.x, ground3.x); // Immediately position to eliminate gaps ground2.x = rightmostX + 4008; } if (ground3.x <= -4008) { // Find the rightmost ground element var rightmostX = Math.max(ground1.x, ground2.x); // Immediately position to eliminate gaps ground3.x = rightmostX + 4008; } // Background animations removed - backgrounds remain static groundAnimationTimer += 0.1; // Keep backgrounds at fixed positions background1.y = 0; background2.y = 0; background3.y = 0; // Keep backgrounds at fixed scale background1.scaleY = 1.0; background2.scaleY = 1.0; background3.scaleY = 1.0; // Ground animations removed - ground remains static // Keep ground at fixed positions ground1.y = groundY; ground2.y = groundY; ground3.y = groundY; // Keep ground at fixed scale ground1.scaleY = 1.0; ground2.scaleY = 1.0; ground3.scaleY = 1.0; // Update spawn timer spawnTimer++; trailTimer++; // Create trail when player is jumping if (player.isJumping && trailTimer % 3 == 0) { var trail = new Trail(); trail.x = player.x; trail.y = player.y; trail.speed = gameSpeed; trails.push(trail); game.addChild(trail); // Fade out trail tween(trail, { alpha: 0, scaleX: 0.3, scaleY: 0.3 }, { duration: 500, onFinish: function onFinish() { trail.destroy(); } }); } // Spawn additional coins with increased frequency to reach 170 coins by game end if (spawnTimer % 35 == 0 && Math.random() < 0.85) { spawnCoin(); } // Spawn boxes occasionally if (spawnTimer % 90 == 0 && Math.random() < 0.6) { spawnBox(); } // Spawn damage boxes occasionally (less frequent than regular boxes) if (spawnTimer % 120 == 0 && Math.random() < 0.4) { spawnDamageBox(); } // Spawn trees with varying density - sometimes dense clusters, sometimes gaps if (spawnTimer % 45 == 0) { // Random density decision: 40% very dense, 30% moderate, 30% sparse/gap var densityRoll = Math.random(); if (densityRoll < 0.4) { // Very dense cluster - 4-7 trees close together var numTrees = 4 + Math.floor(Math.random() * 4); var baseSpacing = 50 + Math.random() * 30; // Tight spacing for dense clusters for (var treeIndex = 0; treeIndex < numTrees; treeIndex++) { var tree = new Tree(); // Close spacing for dense forest effect var randomSpacing = baseSpacing + (Math.random() - 0.5) * 20; tree.x = 2048 + 200 + treeIndex * randomSpacing; tree.y = groundY; // Align all trees to ground level consistently tree.scaleX = 1.0 + Math.random() * 0.8; // Varied sizes in dense clusters tree.scaleY = 1.0 + Math.random() * 0.8; tree.alpha = 0.8 + Math.random() * 0.2; trees.push(tree); game.addChildAt(tree, 3); } } else if (densityRoll < 0.7) { // Moderate density - 2-4 trees with medium spacing var numTrees = 2 + Math.floor(Math.random() * 3); var baseSpacing = 120 + Math.random() * 80; // Medium spacing for (var treeIndex = 0; treeIndex < numTrees; treeIndex++) { var tree = new Tree(); var randomSpacing = baseSpacing + (Math.random() - 0.5) * 40; tree.x = 2048 + 200 + treeIndex * randomSpacing; tree.y = groundY; // Align all trees to ground level consistently tree.scaleX = 1.2 + Math.random() * 0.6; tree.scaleY = 1.2 + Math.random() * 0.6; tree.alpha = 0.9 + Math.random() * 0.1; trees.push(tree); game.addChildAt(tree, 3); } } else { // Sparse or gap - either 1 tree or skip entirely (creating gaps) if (Math.random() < 0.6) { // Single tree var tree = new Tree(); tree.x = 2048 + 200 + Math.random() * 100; // Random position variation tree.y = groundY; // Align all trees to ground level consistently tree.scaleX = 1.4 + Math.random() * 0.4; // Larger standalone trees tree.scaleY = 1.4 + Math.random() * 0.4; tree.alpha = 0.95 + Math.random() * 0.05; trees.push(tree); game.addChildAt(tree, 3); } // If random < 0.4, no trees spawn (creating gaps) } } // Spawn crystal at exactly 500 meters (within 1000 meters) var currentDistance = Math.floor(distanceScore / 10); if (currentDistance >= 500 && !crystalSpawned) { spawnGem(); crystalSpawned = true; } // Spawn end gate at exactly 1500 meters var endGateDistance = 1500; if (currentDistance >= endGateDistance && !endGateSpawned) { endGate = new EndGate(); endGate.x = 2048 + 200; // Spawn off-screen right endGate.y = groundY + 75; // Same position as starting gate game.addChild(endGate); endGateSpawned = true; } // Check if player crosses the end gate if (endGate && endGate.parent && !endGate.crossed) { if (player.x >= endGate.x - 50 && player.x <= endGate.x + 50) { endGate.triggerWin(); } } // Update and check coins for (var j = coins.length - 1; j >= 0; j--) { var coin = coins[j]; coin.speed = gameSpeed; // Check collection or spin attack var distanceX = coin.x - player.x; var distanceY = coin.y - player.y; var distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY); var isInSpinRange = player.isSpinning && distance <= player.spinDamageRadius; if (!coin.collected && (player.intersects(coin) || isInSpinRange)) { coin.collected = true; coinCount++; // Add coin to total persistent storage storage.totalCoins = (storage.totalCoins || 0) + 1; LK.setScore(coinCount); coinText.setText(coinCount); // Font is already set in the Text2 constructor, no need to change it here // Scoreboard update removed // Check if player gets a new chance every 50 coins if (coinCount > 0 && coinCount % 50 === 0) { playerLives++; // Update lives display livesText.setText(playerLives); // Flash effect for new chance LK.effects.flashScreen(0x00FF00, 500); LK.effects.flashObject(hearts[0], 0x00FF00, 800); // Animate lives text for new chance tween(livesText, { scaleX: 2.0, scaleY: 2.0, fill: 0x00FF00 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(livesText, { scaleX: 1.0, scaleY: 1.0, fill: 0xFF8C00 }, { duration: 400, easing: tween.easeIn }); } }); } LK.getSound('coin').play(); // Visual feedback - enhanced for spin attacks if (isInSpinRange) { LK.effects.flashObject(coin, 0xFF4500, 300); } else { LK.effects.flashObject(coin, 0xFFFFFF, 300); } tween(coin, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 300, onFinish: function onFinish() { coin.destroy(); } }); coins.splice(j, 1); continue; } // Remove off-screen coins if (coin.x < -50) { coin.destroy(); coins.splice(j, 1); } } // Update and check gems for (var g = gems.length - 1; g >= 0; g--) { var gem = gems[g]; gem.speed = gameSpeed; // Check collection or spin attack var distanceX = gem.x - player.x; var distanceY = gem.y - player.y; var distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY); var isInSpinRange = player.isSpinning && distance <= player.spinDamageRadius; if (!gem.collected && (player.intersects(gem) || isInSpinRange)) { gem.collected = true; gemCount++; coinCount += 5; // Gems are worth 5 points // Add gem bonus to total coins storage storage.totalCoins = (storage.totalCoins || 0) + 5; LK.setScore(coinCount); coinText.setText(coinCount); // Scoreboard update removed // Create gem UI elements on first gem collection if (!gemIcon) { gemIcon = LK.getAsset('gem_icon', { anchorX: 0.5, anchorY: 0, x: 150, y: 20 }); LK.gui.top.addChild(gemIcon); gemText = new Text2('0', { size: 100, fill: 0xFF69B4, font: "Avenir", fontWeight: '900', stroke: 0x000000, strokeThickness: 15 }); gemText.anchor.set(0.5, 0); gemText.x = 150; gemText.y = 90; LK.gui.top.addChild(gemText); } gemText.setText(gemCount); // Font is already set in the Text2 constructor, no need to change it here LK.getSound('gem_collect').play(); LK.getSound('happy_giggle').play(); // Fade out gem UI elements after 2 seconds LK.setTimeout(function () { if (gemIcon && gemIcon.parent) { tween(gemIcon, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { gemIcon.destroy(); gemIcon = null; } }); } if (gemText && gemText.parent) { tween(gemText, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { gemText.destroy(); gemText = null; } }); } }, 2000); // Visual feedback with particle explosion - enhanced for spin attacks if (isInSpinRange) { LK.effects.flashScreen(0xFF4500, 200); } else { LK.effects.flashScreen(0x00FFFF, 200); } gem.createParticles(); gem.destroy(); gems.splice(g, 1); continue; } // Remove off-screen gems if (gem.x < -50) { gem.destroy(); gems.splice(g, 1); } } // Update and check boxes for (var b = boxes.length - 1; b >= 0; b--) { var box = boxes[b]; box.speed = gameSpeed; // Check collision with player or spin attack var distanceX = box.x - player.x; var distanceY = box.y - player.y; var distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY); var isInSpinRange = player.isSpinning && distance <= player.spinDamageRadius; if (!box.broken && (player.intersects(box) || isInSpinRange)) { box.breakBox(); boxes.splice(b, 1); continue; } // Remove off-screen boxes if (box.x < -50) { box.destroy(); boxes.splice(b, 1); } } // Update and check damage boxes for (var d = damageBoxes.length - 1; d >= 0; d--) { var damageBox = damageBoxes[d]; damageBox.speed = gameSpeed; // Check collision with player (damage boxes can't be destroyed by spin attack) if (!damageBox.damaged && player.intersects(damageBox)) { damageBox.damagePlayer(); damageBoxes.splice(d, 1); continue; } // Remove off-screen damage boxes if (damageBox.x < -50) { damageBox.destroy(); damageBoxes.splice(d, 1); } } // Update and clean up trails for (var k = trails.length - 1; k >= 0; k--) { var trail = trails[k]; trail.speed = gameSpeed; // Remove off-screen or completely faded trails if (trail.x < -100 || trail.alpha <= 0.1) { trail.destroy(); trails.splice(k, 1); } } // Update and clean up trees for (var t = trees.length - 1; t >= 0; t--) { var tree = trees[t]; tree.speed = gameSpeed * 0.8; // Trees move slightly slower for depth effect // Remove off-screen trees if (tree.x < -200) { tree.destroy(); trees.splice(t, 1); } } // Zoom in effect - scale the game container by 10 units game.scaleX = 1.0 + 10 / 1000; // Convert 10 units to scale factor game.scaleY = 1.0 + 10 / 1000; // Convert 10 units to scale factor // Music will transition automatically when first track ends // Ensure player stays in foreground by re-adding it if (player.parent !== game) { game.addChild(player); } else { // Move player to top of render order game.removeChild(player); game.addChild(player); } }; // Scoreboard background removed // Game pause/resume functionality var gamePaused = false; var pausedUpdateFunction = null; LK.pauseGame = function () { if (!gamePaused) { gamePaused = true; pausedUpdateFunction = game.update; game.update = function () { // Game is paused - no updates }; } }; LK.resumeGame = function () { if (gamePaused) { gamePaused = false; if (pausedUpdateFunction) { game.update = pausedUpdateFunction; pausedUpdateFunction = null; } } }; // Initialize store var store = new Store(); // God Mode variables var godModeActive = false; var normalSpeed = 24; // God Mode button - hidden for now // var godModeButton = LK.getAsset('box1', { // anchorX: 0.5, // anchorY: 0.5, // scaleX: 2.5, // scaleY: 2, // tint: 0xFF4444, // x: 0, // y: 400 // }); // LK.gui.topLeft.addChild(godModeButton); // var godModeButtonText = new Text2('GOD MODE', { // size: 35, // fill: 0xFFFFFF, // font: "Avenir", // fontWeight: 'bold' // }); // godModeButtonText.anchor.set(0.5, 0.5); // godModeButtonText.x = 0; // godModeButtonText.y = 400; // LK.gui.topLeft.addChild(godModeButtonText); // God Mode button interaction // godModeButton.down = function () { // toggleGodMode(); // }; // Teleport button - hidden for now // var teleportButton = LK.getAsset('box1', { // anchorX: 0.5, // anchorY: 0.5, // scaleX: 2.5, // scaleY: 2, // tint: 0x8A2BE2, // x: 0, // y: 520 // }); // LK.gui.topLeft.addChild(teleportButton); // var teleportButtonText = new Text2('TELEPORT', { // size: 30, // fill: 0xFFFFFF, // font: "Avenir", // fontWeight: 'bold' // }); // teleportButtonText.anchor.set(0.5, 0.5); // teleportButtonText.x = 0; // teleportButtonText.y = 520; // LK.gui.topLeft.addChild(teleportButtonText); // Teleport button interaction // teleportButton.down = function () { // teleportToLastGate(); // }; // Function to teleport 50 meters away from last gate function teleportToLastGate() { var targetDistance = 1450; // 50 meters before the gate at 1500 meters var currentDistance = Math.floor(distanceScore / 10); if (currentDistance < targetDistance) { // Calculate how much distance to add var distanceToAdd = (targetDistance - currentDistance) * 10; distanceScore += distanceToAdd; // Flash effect when teleporting LK.effects.flashScreen(0x8A2BE2, 500); LK.effects.flashObject(player, 0x8A2BE2, 800); } } // Function to toggle God Mode function toggleGodMode() { godModeActive = !godModeActive; if (godModeActive) { // Activate God Mode player.isInvulnerable = true; gameSpeed = normalSpeed * 3; // Very high speed godModeButton.tint = 0x00FF00; // Green when active godModeButtonText.setText('GOD: ON'); godModeButtonText.fill = 0x00FF00; // Flash effect when activating LK.effects.flashScreen(0xFFD700, 500); LK.effects.flashObject(player, 0xFFD700, 1000); } else { // Deactivate God Mode player.isInvulnerable = false; gameSpeed = normalSpeed + distanceScore / 1000; // Return to normal progression godModeButton.tint = 0xFF4444; // Red when inactive godModeButtonText.setText('GOD MODE'); godModeButtonText.fill = 0xFFFFFF; } } // Store button hidden for now // var storeButton = LK.getAsset('square_button', { // anchorX: 0.5, // anchorY: 0.5, // scaleX: 2, // scaleY: 2, // tint: 0x4444FF, // x: 0, // y: 400 // }); // LK.gui.topLeft.addChild(storeButton); // var storeButtonText = new Text2('STORE', { // size: 40, // fill: 0xFFFFFF, // fontWeight: 'bold' // }); // storeButtonText.anchor.set(0.5, 0.5); // storeButtonText.x = 0; // storeButtonText.y = 400; // LK.gui.topLeft.addChild(storeButtonText); // Store button interaction // storeButton.down = function () { // store.openStore(); // }; // Progress line UI elements var progressLine = LK.getAsset('box1', { anchorX: 0, anchorY: 0.5, scaleX: 14, // Shortened horizontal line scaleY: 0.1, // Thin line tint: 0x444444, x: 200, y: 200 }); LK.gui.top.addChild(progressLine); // Mini character on progress line var progressChar = LK.getAsset('C1', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, x: 200, y: 200 }); LK.gui.top.addChild(progressChar); // Remaining distance text removed // Get player name and last score from storage var playerName = storage.playerName || 'Player'; var lastScore = storage.lastScore || 0; // Character switching variables for C1-C6 cycling every 5 meters var characterOrder = ['C1', 'C2', 'C3', 'C4', 'C5', 'C6']; var currentCharacterIndex = 0; var currentCharacter = characterOrder[currentCharacterIndex]; var lastSwapDistance = 0; var nextSwapDistance = 2; // Player name text removed // Combined score text removed // Scoreboard update function removed // Game variables (single chapter only) var gamePartTitle = "ENDLESS RUNNER"; var gamePartNumber = 1; var isFirstChapter = true;
===================================================================
--- original.js
+++ change.js
@@ -1599,9 +1599,9 @@
distanceText.setText(currentDistance + 'm');
// Update progress line elements
var targetDistance = 1500; // Distance to reach 2nd part
var progressPercent = Math.min(currentDistance / targetDistance, 1.0);
- var lineWidth = 1440; // Total width of progress line - enlarged further
+ var lineWidth = 1120; // Total width of progress line - shortened
// Move mini character along the progress line
progressChar.x = 200 + progressPercent * lineWidth;
// Remaining distance text updates removed
// Update mini character asset to match current player character
@@ -2197,10 +2197,10 @@
// Progress line UI elements
var progressLine = LK.getAsset('box1', {
anchorX: 0,
anchorY: 0.5,
- scaleX: 18,
- // Long horizontal line - enlarged further
+ scaleX: 14,
+ // Shortened horizontal line
scaleY: 0.1,
// Thin line
tint: 0x444444,
x: 200,
Just crystal
Just his head
Background, endless, forest, winter, cartoon. In-Game asset. 2d. High contrast. No shadows
Only the line of the ears and the color of the paws should be gray
Only the line of the ears and the color of the paws should be gray
Let C2 have the character's color
Only the line of the ears and the color of the paws should be gray
Delete the character on it
A version without snow
Koyu mavi elips start butonu. In-Game asset. 2d. High contrast. No shadows. In-Game asset. 2d. High contrast. No shadows
Uçan bir dinazor. In-Game asset. 2d. High contrast. No shadows
Alev topu. In-Game asset. 2d. High contrast. No shadows
Mavi top rasengan top. In-Game asset. 2d. High contrast. No shadows
jump
Sound effect
coin
Sound effect
Arkaplanmuzik
Music
gem_collect
Sound effect
happy_giggle
Sound effect
Canazalma
Sound effect
Arkaplanmuzik1
Music
wumpa1
Sound effect
cancan
Sound effect
box_break
Sound effect
tnt_break
Sound effect
enemy_sound
Sound effect
bullet_sound
Sound effect