User prompt
Rengini turuncu yap
User prompt
Make the number of lives text animated ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the game is over, the replay screen will not appear.
User prompt
When the game is over, transfer me to another screen and make it a black screen
User prompt
Let this be a chapter of everything we do.
User prompt
When the game is over, let it take us to a screen and create a level system from there. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
When the button is pressed, the meter moves faster
User prompt
When the button is pressed, the game goes faster in the same way
User prompt
Make a round button, when you press and hold it the character will go very fast ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Speed up character by 100 units
User prompt
Speed up character by 5 units
User prompt
Add immortal character for now, remove it whenever I want
User prompt
Slightly reduce the animation of the end gate ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Increase the duration ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Do the same for the coin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Stop appearing after a while after collection ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
No, do not display the gem icon on the screen without collecting it.
User prompt
Make a happy giggle sound when the character collects the gem
User prompt
When the character touches the ground after a somersault, he returns to his previous state. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the model return to its original state from the right side ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the character flips, the model should return to its previous state. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add an animation to the character so that it looks like it's doing a somersault every time it jumps ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Delete the start button in the game
User prompt
The game will automatically start when the button is pressed
User prompt
The game will start when the start button on the screen is pressed.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Box = Container.expand(function () { var self = Container.call(this); var boxGraphics = self.attachAsset('square_button', { 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 Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); // Create aura effect var aura = self.attachAsset('coin', { 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('danger_box', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, tint: 0xFF4444 // Bright red color to indicate danger }); 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) { self.damaged = true; playerLives--; // Update lives counter text livesText.setText(playerLives); // 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('danger_box', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, alpha: 1.0, x: self.x, y: self.y, tint: 0x8B0000 }); 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('end_gate', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 1.2, tint: 0xFFD700 // Golden color for finish gate }); // Add victory glow effect var victoryGlow = self.attachAsset('end_gate', { 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() { tween(victoryGlow, { scaleX: 1.8, scaleY: 1.8, alpha: 0.1 }, { duration: 1200, easing: tween.easeInOut, onFinish: function onFinish() { tween(victoryGlow, { scaleX: 1.5, scaleY: 1.5, alpha: 0.4 }, { duration: 1200, easing: tween.easeInOut, onFinish: startVictoryPulse }); } }); } startVictoryPulse(); 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; // Create victory particle effect for (var p = 0; p < 20; p++) { var particle = LK.getAsset('end_gate', { 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(); } }); } // Flash screen with victory colors LK.effects.flashScreen(0xFFD700, 800); // Show collectibles summary after a brief delay LK.setTimeout(function () { showCollectiblesSummary(); }, 800); // Show you win after showing collectibles LK.setTimeout(function () { LK.showYouWin(); }, 3000); } }; 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('fox', { anchorX: 0.5, anchorY: 1.0 }); self.isJumping = false; self.velocityY = 0; self.groundY = 2732 - 150 - 3; // 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(); // Different animation for double jump var isDoubleJump = self.jumpsRemaining === 0 && self.isJumping; if (isDoubleJump) { // Double jump animation - more dramatic spin tween(foxGraphics, { scaleX: 1.3, scaleY: 1.3, rotation: -0.6 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(foxGraphics, { scaleX: 1.0, scaleY: 1.0, rotation: 0 }, { duration: 250, easing: tween.easeIn }); } }); } else { // Regular jump animation tween(foxGraphics, { scaleX: 1.2, scaleY: 1.2, rotation: -0.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(foxGraphics, { scaleX: 1.0, scaleY: 1.0, rotation: 0 }, { duration: 300, 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 } } 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('gate', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.0, scaleY: 1.0 }); self.speed = gameSpeed; self.update = function () { self.x -= self.speed; }; return self; }); var Trail = Container.expand(function () { var self = Container.call(this); var trailGraphics = self.attachAsset('fox', { 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var player; var coins = []; var gems = []; var boxes = []; var damageBoxes = []; var trails = []; var gameSpeed = 8; var spawnTimer = 0; var coinCount = 0; var gemCount = 0; var distanceScore = 0; var groundY = 2732 - 150; 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: 60, fill: 0xFFFFFF, font: "'Arial Black', 'Impact', 'Trebuchet MS', sans-serif", fontWeight: '900', stroke: 0x000000, strokeThickness: 15 }); coinText.anchor.set(0.5, 0); coinText.x = 0; coinText.y = 110; LK.gui.top.addChild(coinText); var gemIcon = LK.getAsset('gem_icon', { anchorX: 0.5, anchorY: 0, x: 150, y: 20 }); LK.gui.top.addChild(gemIcon); var gemText = new Text2('0', { size: 60, fill: 0xFF69B4, font: "'Arial Black', 'Impact', 'Trebuchet MS', sans-serif", fontWeight: '900', stroke: 0x000000, strokeThickness: 15 }); gemText.anchor.set(0.5, 0); gemText.x = 150; gemText.y = 110; LK.gui.top.addChild(gemText); var scoreText = new Text2('Distance: 0', { size: 90, fill: 0xFFFFFF, fontStyle: 'italic', fontWeight: 'bold' }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); // 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: 60, fill: 0xFFFFFF, font: "'Arial Black', 'Impact', 'Trebuchet MS', sans-serif", fontWeight: '900', stroke: 0x000000, strokeThickness: 15 }); livesText.anchor.set(0.5, 0.5); livesText.x = 250; livesText.y = 193; LK.gui.topLeft.addChild(livesText); ; // Function to show collectibles summary function showCollectiblesSummary() { // Create dark overlay var overlay = LK.getAsset('square_button', { anchorX: 0.5, anchorY: 0.5, scaleX: 30, scaleY: 40, alpha: 0.8, tint: 0x000000, x: 1024, y: 1366 }); game.addChild(overlay); // Create summary panel var summaryPanel = LK.getAsset('square_button', { anchorX: 0.5, anchorY: 0.5, scaleX: 18, scaleY: 15, tint: 0x2F4F4F, x: 1024, y: 1366 }); game.addChild(summaryPanel); // Title text var titleText = new Text2('COLLECTIBLES GATHERED', { size: 80, fill: 0xFFD700, fontWeight: 'bold' }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 900; game.addChild(titleText); // Create animated collectible items that can be picked up var summaryItems = []; // Create multiple coin items based on coinCount (max 10 for display) var coinsToShow = Math.min(coinCount, 10); for (var c = 0; c < coinsToShow; c++) { var summaryCoins = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: 600 + c % 5 * 100, y: 1100 + Math.floor(c / 5) * 80, alpha: 0 }); game.addChild(summaryCoins); summaryItems.push(summaryCoins); // Add floating animation var floatOffset = c * 0.5; tween(summaryCoins, { alpha: 1, y: summaryCoins.y - 20 }, { duration: 500 + c * 100, easing: tween.easeOut, onFinish: function onFinish() { // Continuous floating animation function floatAnimation(coin, offset) { tween(coin, { y: coin.y + 15, rotation: coin.rotation + 0.3 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(coin, { y: coin.y - 15, rotation: coin.rotation + 0.3 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { floatAnimation(coin, offset); } }); } }); } floatAnimation(summaryCoins, floatOffset); } }); } // Create multiple gem items based on gemCount (max 5 for display) var gemsToShow = Math.min(gemCount, 5); for (var g = 0; g < gemsToShow; g++) { var summaryGems = LK.getAsset('gem', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, x: 700 + g * 120, y: 1350, alpha: 0 }); game.addChild(summaryGems); summaryItems.push(summaryGems); // Add sparkling animation tween(summaryGems, { alpha: 1, scaleX: 0.8, scaleY: 0.8 }, { duration: 600 + g * 150, easing: tween.easeOut, onFinish: function onFinish() { // Continuous sparkling animation function sparkleAnimation(gem) { tween(gem, { alpha: 0.7, scaleX: 0.9, scaleY: 0.9, tint: 0x00FFFF }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(gem, { alpha: 1, scaleX: 0.8, scaleY: 0.8, tint: 0xFFFFFF }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { sparkleAnimation(gem); } }); } }); } sparkleAnimation(summaryGems); } }); } // Coins summary text var coinSummaryText = new Text2('Coins Collected: ' + coinCount, { size: 60, fill: 0xFFD700, fontWeight: 'bold' }); coinSummaryText.anchor.set(0.5, 0.5); coinSummaryText.x = 1024; coinSummaryText.y = 1050; game.addChild(coinSummaryText); // Gems summary text var gemSummaryText = new Text2('Gems Found: ' + gemCount, { size: 60, fill: 0xFF69B4, fontWeight: 'bold' }); gemSummaryText.anchor.set(0.5, 0.5); gemSummaryText.x = 1024; gemSummaryText.y = 1300; game.addChild(gemSummaryText); // Total score var totalText = new Text2('TOTAL SCORE: ' + coinCount, { size: 70, fill: 0x00FF00, fontWeight: 'bold' }); totalText.anchor.set(0.5, 0.5); totalText.x = 1024; totalText.y = 1600; game.addChild(totalText); // Add instruction text var instructionText = new Text2('Your collected treasures!', { size: 50, fill: 0xFFFFFF, fontStyle: 'italic' }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 1500; game.addChild(instructionText); // Animate elements appearing tween(overlay, { alpha: 0.8 }, { duration: 500 }); tween(summaryPanel, { scaleX: 18, scaleY: 15 }, { duration: 600, easing: tween.easeOut }); // Clean up summary after delay LK.setTimeout(function () { overlay.destroy(); summaryPanel.destroy(); titleText.destroy(); coinSummaryText.destroy(); gemSummaryText.destroy(); totalText.destroy(); instructionText.destroy(); // Clean up all summary items for (var i = 0; i < summaryItems.length; i++) { summaryItems[i].destroy(); } }, 2500); } ; ; // Spin button removed // Game state management var gameState = 'start'; // 'start', 'playing', 'ended' var startScreen; var playButton; // Function to show start screen function showStartScreen() { // Create start screen background startScreen = game.addChild(LK.getAsset('screen', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 })); // Create play button playButton = game.addChild(LK.getAsset('square_button', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 2, x: 1024, y: 1600, tint: 0x00FF00 })); // Create play button text var playText = new Text2('START', { size: 80, fill: 0xFFFFFF, fontWeight: 'bold' }); playText.anchor.set(0.5, 0.5); playText.x = 1024; playText.y = 1600; game.addChild(playText); // Create title text var titleText = new Text2('ENDLESS RUNNER', { size: 120, fill: 0xFFD700, fontWeight: 'bold' }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 800; game.addChild(titleText); // Add button interaction playButton.down = function (x, y, obj) { startGame(); }; } // Function to start the actual game function startGame() { gameState = 'playing'; // Remove start screen elements if (startScreen) startScreen.destroy(); if (playButton) playButton.destroy(); // Remove title and play text elements var titleElements = game.children.filter(function (child) { return child instanceof Text2; }); for (var i = 0; i < titleElements.length; i++) { titleElements[i].destroy(); } // Play background music LK.playMusic('Arkaplanmuzik'); // Initialize game elements that were previously created immediately initializeGameElements(); } // Function to initialize game elements function initializeGameElements() { // Create endless scrolling background background1 = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); background2 = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 2048, y: 0 })); // Create animated ground elements for endless scrolling var ground1 = game.addChild(LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: groundY })); var ground2 = game.addChild(LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 4008, // Position second ground at end of first ground y: groundY })); // Create starting gate startingGate = new StartingGate(); startingGate.x = 400 + 40 * 10; // Position at 40 meters (40m * 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 - 3; player.isInvulnerable = false; game.addChild(player); } // Show start screen initially showStartScreen(); // Ground animation variables var groundAnimationTimer = 0; var ground1, ground2; // Touch controls for swipe up to jump var touchStartY = null; var minSwipeDistance = 100; // Minimum distance for swipe detection game.down = function (x, y, obj) { if (gameState === 'playing') { touchStartY = y; } }; game.up = function (x, y, obj) { if (gameState === 'playing' && 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; coin.y = groundY - 100 - Math.random() * 150; 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 - 90; // Stack on top (90 pixels higher - closer 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() { var damageBox = new DamageBox(); damageBox.x = 2048 + 100; damageBox.y = groundY - 45; // Same level as regular boxes damageBoxes.push(damageBox); game.addChild(damageBox); } game.update = function () { // Only update game logic when actually playing if (gameState !== 'playing') { return; } // Increase distance score distanceScore += 1; scoreText.setText(Math.floor(distanceScore / 10) + 'm'); // Gradually increase speed gameSpeed = 8 + distanceScore / 2000; // 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 background with game progression background1.x -= gameSpeed * 0.3; // Slower parallax effect background2.x -= gameSpeed * 0.3; // Reset background positions for endless scrolling if (background1.x <= -2048) { background1.x = background2.x + 2048; } if (background2.x <= -2048) { background2.x = background1.x + 2048; } // Move both ground elements with game progression ground1.x -= gameSpeed; ground2.x -= gameSpeed; // Reset ground positions for endless scrolling if (ground1.x <= -4008) { ground1.x = ground2.x + 4008; } if (ground2.x <= -4008) { ground2.x = ground1.x + 4008; } // Animate ground with subtle movement groundAnimationTimer += 0.1; var groundOffset = Math.sin(groundAnimationTimer) * 2; ground1.y = groundY + groundOffset; ground2.y = groundY + groundOffset; // Add slight scale animation to ground var scaleAnimation = 1.0 + Math.sin(groundAnimationTimer * 0.5) * 0.02; ground1.scaleY = scaleAnimation; ground2.scaleY = scaleAnimation; // 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 if (spawnTimer % 60 == 0 && Math.random() < 0.8) { 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 crystal at exactly 100 meters var currentDistance = Math.floor(distanceScore / 10); if (currentDistance >= 100 && !crystalSpawned) { spawnGem(); crystalSpawned = true; } // Spawn end gate at exactly 150 meters if (currentDistance >= 150 && !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++; LK.setScore(coinCount); coinText.setText(coinCount); 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 LK.setScore(coinCount); coinText.setText(coinCount); gemText.setText(gemCount); LK.getSound('gem_collect').play(); // 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); } } // 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); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Box = Container.expand(function () {
var self = Container.call(this);
var boxGraphics = self.attachAsset('square_button', {
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 Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Create aura effect
var aura = self.attachAsset('coin', {
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('danger_box', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
tint: 0xFF4444 // Bright red color to indicate danger
});
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) {
self.damaged = true;
playerLives--;
// Update lives counter text
livesText.setText(playerLives);
// 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('danger_box', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
alpha: 1.0,
x: self.x,
y: self.y,
tint: 0x8B0000
});
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('end_gate', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFD700 // Golden color for finish gate
});
// Add victory glow effect
var victoryGlow = self.attachAsset('end_gate', {
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() {
tween(victoryGlow, {
scaleX: 1.8,
scaleY: 1.8,
alpha: 0.1
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(victoryGlow, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.4
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: startVictoryPulse
});
}
});
}
startVictoryPulse();
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;
// Create victory particle effect
for (var p = 0; p < 20; p++) {
var particle = LK.getAsset('end_gate', {
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();
}
});
}
// Flash screen with victory colors
LK.effects.flashScreen(0xFFD700, 800);
// Show collectibles summary after a brief delay
LK.setTimeout(function () {
showCollectiblesSummary();
}, 800);
// Show you win after showing collectibles
LK.setTimeout(function () {
LK.showYouWin();
}, 3000);
}
};
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('fox', {
anchorX: 0.5,
anchorY: 1.0
});
self.isJumping = false;
self.velocityY = 0;
self.groundY = 2732 - 150 - 3; // 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();
// Different animation for double jump
var isDoubleJump = self.jumpsRemaining === 0 && self.isJumping;
if (isDoubleJump) {
// Double jump animation - more dramatic spin
tween(foxGraphics, {
scaleX: 1.3,
scaleY: 1.3,
rotation: -0.6
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(foxGraphics, {
scaleX: 1.0,
scaleY: 1.0,
rotation: 0
}, {
duration: 250,
easing: tween.easeIn
});
}
});
} else {
// Regular jump animation
tween(foxGraphics, {
scaleX: 1.2,
scaleY: 1.2,
rotation: -0.3
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(foxGraphics, {
scaleX: 1.0,
scaleY: 1.0,
rotation: 0
}, {
duration: 300,
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
}
} 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('gate', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.0,
scaleY: 1.0
});
self.speed = gameSpeed;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Trail = Container.expand(function () {
var self = Container.call(this);
var trailGraphics = self.attachAsset('fox', {
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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var player;
var coins = [];
var gems = [];
var boxes = [];
var damageBoxes = [];
var trails = [];
var gameSpeed = 8;
var spawnTimer = 0;
var coinCount = 0;
var gemCount = 0;
var distanceScore = 0;
var groundY = 2732 - 150;
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: 60,
fill: 0xFFFFFF,
font: "'Arial Black', 'Impact', 'Trebuchet MS', sans-serif",
fontWeight: '900',
stroke: 0x000000,
strokeThickness: 15
});
coinText.anchor.set(0.5, 0);
coinText.x = 0;
coinText.y = 110;
LK.gui.top.addChild(coinText);
var gemIcon = LK.getAsset('gem_icon', {
anchorX: 0.5,
anchorY: 0,
x: 150,
y: 20
});
LK.gui.top.addChild(gemIcon);
var gemText = new Text2('0', {
size: 60,
fill: 0xFF69B4,
font: "'Arial Black', 'Impact', 'Trebuchet MS', sans-serif",
fontWeight: '900',
stroke: 0x000000,
strokeThickness: 15
});
gemText.anchor.set(0.5, 0);
gemText.x = 150;
gemText.y = 110;
LK.gui.top.addChild(gemText);
var scoreText = new Text2('Distance: 0', {
size: 90,
fill: 0xFFFFFF,
fontStyle: 'italic',
fontWeight: 'bold'
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
// 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: 60,
fill: 0xFFFFFF,
font: "'Arial Black', 'Impact', 'Trebuchet MS', sans-serif",
fontWeight: '900',
stroke: 0x000000,
strokeThickness: 15
});
livesText.anchor.set(0.5, 0.5);
livesText.x = 250;
livesText.y = 193;
LK.gui.topLeft.addChild(livesText);
;
// Function to show collectibles summary
function showCollectiblesSummary() {
// Create dark overlay
var overlay = LK.getAsset('square_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 30,
scaleY: 40,
alpha: 0.8,
tint: 0x000000,
x: 1024,
y: 1366
});
game.addChild(overlay);
// Create summary panel
var summaryPanel = LK.getAsset('square_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 18,
scaleY: 15,
tint: 0x2F4F4F,
x: 1024,
y: 1366
});
game.addChild(summaryPanel);
// Title text
var titleText = new Text2('COLLECTIBLES GATHERED', {
size: 80,
fill: 0xFFD700,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 900;
game.addChild(titleText);
// Create animated collectible items that can be picked up
var summaryItems = [];
// Create multiple coin items based on coinCount (max 10 for display)
var coinsToShow = Math.min(coinCount, 10);
for (var c = 0; c < coinsToShow; c++) {
var summaryCoins = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
x: 600 + c % 5 * 100,
y: 1100 + Math.floor(c / 5) * 80,
alpha: 0
});
game.addChild(summaryCoins);
summaryItems.push(summaryCoins);
// Add floating animation
var floatOffset = c * 0.5;
tween(summaryCoins, {
alpha: 1,
y: summaryCoins.y - 20
}, {
duration: 500 + c * 100,
easing: tween.easeOut,
onFinish: function onFinish() {
// Continuous floating animation
function floatAnimation(coin, offset) {
tween(coin, {
y: coin.y + 15,
rotation: coin.rotation + 0.3
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(coin, {
y: coin.y - 15,
rotation: coin.rotation + 0.3
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
floatAnimation(coin, offset);
}
});
}
});
}
floatAnimation(summaryCoins, floatOffset);
}
});
}
// Create multiple gem items based on gemCount (max 5 for display)
var gemsToShow = Math.min(gemCount, 5);
for (var g = 0; g < gemsToShow; g++) {
var summaryGems = LK.getAsset('gem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
x: 700 + g * 120,
y: 1350,
alpha: 0
});
game.addChild(summaryGems);
summaryItems.push(summaryGems);
// Add sparkling animation
tween(summaryGems, {
alpha: 1,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 600 + g * 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Continuous sparkling animation
function sparkleAnimation(gem) {
tween(gem, {
alpha: 0.7,
scaleX: 0.9,
scaleY: 0.9,
tint: 0x00FFFF
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(gem, {
alpha: 1,
scaleX: 0.8,
scaleY: 0.8,
tint: 0xFFFFFF
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
sparkleAnimation(gem);
}
});
}
});
}
sparkleAnimation(summaryGems);
}
});
}
// Coins summary text
var coinSummaryText = new Text2('Coins Collected: ' + coinCount, {
size: 60,
fill: 0xFFD700,
fontWeight: 'bold'
});
coinSummaryText.anchor.set(0.5, 0.5);
coinSummaryText.x = 1024;
coinSummaryText.y = 1050;
game.addChild(coinSummaryText);
// Gems summary text
var gemSummaryText = new Text2('Gems Found: ' + gemCount, {
size: 60,
fill: 0xFF69B4,
fontWeight: 'bold'
});
gemSummaryText.anchor.set(0.5, 0.5);
gemSummaryText.x = 1024;
gemSummaryText.y = 1300;
game.addChild(gemSummaryText);
// Total score
var totalText = new Text2('TOTAL SCORE: ' + coinCount, {
size: 70,
fill: 0x00FF00,
fontWeight: 'bold'
});
totalText.anchor.set(0.5, 0.5);
totalText.x = 1024;
totalText.y = 1600;
game.addChild(totalText);
// Add instruction text
var instructionText = new Text2('Your collected treasures!', {
size: 50,
fill: 0xFFFFFF,
fontStyle: 'italic'
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 1500;
game.addChild(instructionText);
// Animate elements appearing
tween(overlay, {
alpha: 0.8
}, {
duration: 500
});
tween(summaryPanel, {
scaleX: 18,
scaleY: 15
}, {
duration: 600,
easing: tween.easeOut
});
// Clean up summary after delay
LK.setTimeout(function () {
overlay.destroy();
summaryPanel.destroy();
titleText.destroy();
coinSummaryText.destroy();
gemSummaryText.destroy();
totalText.destroy();
instructionText.destroy();
// Clean up all summary items
for (var i = 0; i < summaryItems.length; i++) {
summaryItems[i].destroy();
}
}, 2500);
}
;
;
// Spin button removed
// Game state management
var gameState = 'start'; // 'start', 'playing', 'ended'
var startScreen;
var playButton;
// Function to show start screen
function showStartScreen() {
// Create start screen background
startScreen = game.addChild(LK.getAsset('screen', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create play button
playButton = game.addChild(LK.getAsset('square_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 2,
x: 1024,
y: 1600,
tint: 0x00FF00
}));
// Create play button text
var playText = new Text2('START', {
size: 80,
fill: 0xFFFFFF,
fontWeight: 'bold'
});
playText.anchor.set(0.5, 0.5);
playText.x = 1024;
playText.y = 1600;
game.addChild(playText);
// Create title text
var titleText = new Text2('ENDLESS RUNNER', {
size: 120,
fill: 0xFFD700,
fontWeight: 'bold'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
game.addChild(titleText);
// Add button interaction
playButton.down = function (x, y, obj) {
startGame();
};
}
// Function to start the actual game
function startGame() {
gameState = 'playing';
// Remove start screen elements
if (startScreen) startScreen.destroy();
if (playButton) playButton.destroy();
// Remove title and play text elements
var titleElements = game.children.filter(function (child) {
return child instanceof Text2;
});
for (var i = 0; i < titleElements.length; i++) {
titleElements[i].destroy();
}
// Play background music
LK.playMusic('Arkaplanmuzik');
// Initialize game elements that were previously created immediately
initializeGameElements();
}
// Function to initialize game elements
function initializeGameElements() {
// Create endless scrolling background
background1 = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
background2 = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 2048,
y: 0
}));
// Create animated ground elements for endless scrolling
var ground1 = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: groundY
}));
var ground2 = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 4008,
// Position second ground at end of first ground
y: groundY
}));
// Create starting gate
startingGate = new StartingGate();
startingGate.x = 400 + 40 * 10; // Position at 40 meters (40m * 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 - 3;
player.isInvulnerable = false;
game.addChild(player);
}
// Show start screen initially
showStartScreen();
// Ground animation variables
var groundAnimationTimer = 0;
var ground1, ground2;
// Touch controls for swipe up to jump
var touchStartY = null;
var minSwipeDistance = 100; // Minimum distance for swipe detection
game.down = function (x, y, obj) {
if (gameState === 'playing') {
touchStartY = y;
}
};
game.up = function (x, y, obj) {
if (gameState === 'playing' && 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;
coin.y = groundY - 100 - Math.random() * 150;
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 - 90; // Stack on top (90 pixels higher - closer 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() {
var damageBox = new DamageBox();
damageBox.x = 2048 + 100;
damageBox.y = groundY - 45; // Same level as regular boxes
damageBoxes.push(damageBox);
game.addChild(damageBox);
}
game.update = function () {
// Only update game logic when actually playing
if (gameState !== 'playing') {
return;
}
// Increase distance score
distanceScore += 1;
scoreText.setText(Math.floor(distanceScore / 10) + 'm');
// Gradually increase speed
gameSpeed = 8 + distanceScore / 2000;
// 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 background with game progression
background1.x -= gameSpeed * 0.3; // Slower parallax effect
background2.x -= gameSpeed * 0.3;
// Reset background positions for endless scrolling
if (background1.x <= -2048) {
background1.x = background2.x + 2048;
}
if (background2.x <= -2048) {
background2.x = background1.x + 2048;
}
// Move both ground elements with game progression
ground1.x -= gameSpeed;
ground2.x -= gameSpeed;
// Reset ground positions for endless scrolling
if (ground1.x <= -4008) {
ground1.x = ground2.x + 4008;
}
if (ground2.x <= -4008) {
ground2.x = ground1.x + 4008;
}
// Animate ground with subtle movement
groundAnimationTimer += 0.1;
var groundOffset = Math.sin(groundAnimationTimer) * 2;
ground1.y = groundY + groundOffset;
ground2.y = groundY + groundOffset;
// Add slight scale animation to ground
var scaleAnimation = 1.0 + Math.sin(groundAnimationTimer * 0.5) * 0.02;
ground1.scaleY = scaleAnimation;
ground2.scaleY = scaleAnimation;
// 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
if (spawnTimer % 60 == 0 && Math.random() < 0.8) {
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 crystal at exactly 100 meters
var currentDistance = Math.floor(distanceScore / 10);
if (currentDistance >= 100 && !crystalSpawned) {
spawnGem();
crystalSpawned = true;
}
// Spawn end gate at exactly 150 meters
if (currentDistance >= 150 && !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++;
LK.setScore(coinCount);
coinText.setText(coinCount);
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
LK.setScore(coinCount);
coinText.setText(coinCount);
gemText.setText(gemCount);
LK.getSound('gem_collect').play();
// 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);
}
}
// 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);
}
};
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