/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BodyPart = Container.expand(function () { var self = Container.call(this); var bodyPart = self.attachAsset('head', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, tint: 0x00FFFF // Cyan tint for better visibility }); // Add animation properties self.originalScale = 1.2; // Larger scale self.isAnimating = false; self.animationDirection = 1; // Rotate the body part based on direction self.setDirection = function (direction) { if (direction === 'up') { bodyPart.rotation = 0; } else if (direction === 'down') { bodyPart.rotation = Math.PI; } else if (direction === 'left') { bodyPart.rotation = -Math.PI / 2; } else if (direction === 'right') { bodyPart.rotation = Math.PI / 2; } }; // Start wiggle animation for body parts self.startWiggleAnimation = function () { if (self.isAnimating) return; self.isAnimating = true; self.animateWiggle(); }; // Stop wiggle animation self.stopWiggleAnimation = function () { self.isAnimating = false; tween.stop(bodyPart, { scaleX: true, scaleY: true }); bodyPart.scaleX = self.originalScale; bodyPart.scaleY = self.originalScale; }; // Animate wiggle effect self.animateWiggle = function () { if (!self.isAnimating) return; var scaleOffset = 0.05; var duration = 250; // Determine which axis to animate based on direction var direction = self.animationDirection; var targetScaleX = self.originalScale; var targetScaleY = self.originalScale; // Wiggle based on body orientation if (bodyPart.rotation === 0 || bodyPart.rotation === Math.PI) { // For up/down movement, wiggle horizontally targetScaleX = self.originalScale + scaleOffset * direction; } else { // For left/right movement, wiggle vertically targetScaleY = self.originalScale + scaleOffset * direction; } tween(bodyPart, { scaleX: targetScaleX, scaleY: targetScaleY }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { self.animationDirection *= -1; if (self.isAnimating) { self.animateWiggle(); } } }); }; return self; }); var Bomb = Container.expand(function () { var self = Container.call(this); // Create a bomb obstacle using rock image asset with red tint var bomb = self.attachAsset('rock', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF0000, // Red tint to distinguish from rocks scaleX: 0.8, scaleY: 0.8 }); return self; }); var BonusFood = Container.expand(function () { var self = Container.call(this); // Create the bonus food var bonusFood = self.attachAsset('bonusFood', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Food = Container.expand(function () { var self = Container.call(this); // Create the food var food = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var HealthBar = Container.expand(function () { var self = Container.call(this); // Create the health bar container box var barContainer = self.attachAsset('healbar', { anchorX: 0.5, anchorY: 0.5, tint: 0x000000, alpha: 0.7, scaleX: 2, scaleY: 0.5 }); // Create the bar background (red) var barBg = self.attachAsset('healbar', { anchorX: 0, anchorY: 0.5, tint: 0xFF0000, scaleX: 1.9, scaleY: 0.4, x: -barContainer.width / 2 + 5, y: 0 }); // Create the health indicator (green) var healthIndicator = self.attachAsset('healbar', { anchorX: 0, anchorY: 0.5, tint: 0x00FF00, scaleX: 1.9, scaleY: 0.4, x: -barContainer.width / 2 + 5, y: 0 }); self.updateHealth = function (health) { // Health ranges from 0 to 200, convert to scale between 0 and 1.9 (max bar width) var healthWidth = health / 200 * 1.9; healthIndicator.scaleX = healthWidth; }; return self; }); var KOCAM = Container.expand(function () { var self = Container.call(this); // Create the life var life = self.attachAsset('life', { anchorX: 0.5, anchorY: 0.5 }); }); var LevelUpMessage = Container.expand(function () { var self = Container.call(this); // Create the level up message background var background = self.attachAsset('healbar', { anchorX: 0.5, anchorY: 0.5, tint: 0x000000, alpha: 0.8, scaleX: 20, scaleY: 8 }); // Create the level up message text var message = new Text2('', { size: 64, fill: 0xFFFFFF }); message.anchor.set(0.5, 0.5); self.addChild(message); // Method to update the text self.setLevel = function (level) { message.setText('Çok yeteneklisin bebi'); }; // Method to show the message with animation self.show = function () { self.alpha = 0; self.scaleX = 0.5; self.scaleY = 0.5; // Animate message appearance tween(self, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeOutElastic }); }; // Method to hide the message with animation self.hide = function (callback) { tween(self, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { if (callback) callback(); } }); }; return self; }); var Pause = Container.expand(function () { var self = Container.call(this); // Create the pause button var pause = self.attachAsset('pause', { anchorX: 0.5, anchorY: 0.5 }); // Event handler called when a press happens on element. self.down = function (x, y, obj) { if (!game.paused) { game.paused = true; pause.id = 'resume'; } else { game.paused = false; pause.id = 'pause'; } }; return self; }); // Poison class has been removed var Rock = Container.expand(function () { var self = Container.call(this); // Create a rock obstacle using rock image asset var rock = self.attachAsset('rock', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); return self; }); var Snake = Container.expand(function () { var self = Container.call(this); // Create the head of the snake var head = self.attachAsset('head', { anchorX: 0.5, anchorY: 0.5 }); // Initialize the snake's direction and speed self.direction = 'up'; self.speed = 5; self.previousPositions = []; // Update the head rotation based on direction self.updateHeadRotation = function () { if (self.direction === 'up') { head.rotation = 0; } else if (self.direction === 'down') { head.rotation = Math.PI; } else if (self.direction === 'left') { head.rotation = -Math.PI / 2; } else if (self.direction === 'right') { head.rotation = Math.PI / 2; } }; self.moveHead = function (newDirection) { if (newDirection === 'up' && this.direction !== 'down') { this.direction = 'up'; self.updateHeadRotation(); } else if (newDirection === 'down' && this.direction !== 'up') { this.direction = 'down'; self.updateHeadRotation(); } else if (newDirection === 'left' && this.direction !== 'right') { this.direction = 'left'; self.updateHeadRotation(); } else if (newDirection === 'right' && this.direction !== 'left') { this.direction = 'right'; self.updateHeadRotation(); } }; // Initialize with the correct rotation self.updateHeadRotation(); return self; }); var StarTrail = Container.expand(function () { var self = Container.call(this); // Create a star-like shape using an asset var star = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // Set initial properties self.alpha = 1; self.fadeSpeed = 0.03; // Slower fade for more visibility self.rotationSpeed = 0.1; self.tailLength = 0; self.maxTailLength = 45; // Longer tail self.growSpeed = 0.8; // Grow faster self.tailColor = 0xFFFF00; // Bright yellow for tail star.tint = 0xFFFFFF; // White for star head // Update method to handle fading, rotation and tail growth self.update = function () { // Rotate the star star.rotation += self.rotationSpeed; // Fade out more slowly self.alpha -= self.fadeSpeed; // Grow tail initially if (self.tailLength < self.maxTailLength) { self.tailLength += self.growSpeed; } // If fully transparent, mark for removal if (self.alpha <= 0) { self.shouldRemove = true; } }; return self; }); /**** * Initialize Game ****/ //<Assets used in the game will automatically appear here> var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ // Add a background to the game // Import tween plugin for animations var background = game.addChildAt(LK.getAsset('newBackground', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.7 // Reduce opacity to improve visibility of game elements }), 0); // Add background as the bottom-most layer // Start playing background music as soon as the game begins LK.playMusic('gameOverMusic'); // Initialize pause button var pause = game.addChild(new Pause()); // Position the pause button a little to the left from the top right corner of the game pause.x = 2048 - pause.width; pause.y = 50; // Move the pause button a little down var snake = game.addChild(new Snake()); snake.body = []; // Position the snake at the center of the game snake.x = 2048 / 2; snake.y = 2732 / 2; // Initialize food var food = game.addChild(new Food()); // Position the food at a random location within the game food.x = Math.random() * 2048; food.y = Math.random() * 2732; // Initialize poison var bonusFood = game.addChild(new BonusFood()); // Poison food item has been removed bonusFood.x = -100; bonusFood.y = -100; var life = game.addChild(new KOCAM()); // Hide the life when the game starts life.x = -100; life.y = -100; // Hide the poison when the game starts game.update = function () { if (game.paused) { return; } // Update the snake's position based on its direction and speed if (snake.direction === 'up') { snake.y -= snake.speed * 2.25; } else if (snake.direction === 'down') { snake.y += snake.speed * 2.25; } else if (snake.direction === 'left') { snake.x -= snake.speed * 2.25; } else if (snake.direction === 'right') { snake.x += snake.speed * 2.25; } // Level 2+ mechanics - Moving bombs if (enableMovingBombs && bombs.length > 0) { for (var mb = 0; mb < bombs.length; mb++) { // Move bombs toward snake occasionally if (LK.ticks % 60 === 0) { // Target the snake with a chance if (Math.random() < 0.5) { // Calculate direction toward snake var dx = snake.x - bombs[mb].x; var dy = snake.y - bombs[mb].y; // Normalize and apply speed var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { bombs[mb].x += dx / dist * bombSpeed; bombs[mb].y += dy / dist * bombSpeed; } } else { // Random movement bombs[mb].x += (Math.random() * 2 - 1) * bombSpeed * 2; bombs[mb].y += (Math.random() * 2 - 1) * bombSpeed * 2; } } } } // Level 2+ mechanics - Teleporting food if (enableFoodTeleport && LK.ticks % 180 === 0 && food && food.parent) { // 5% chance food will teleport every 3 seconds if (Math.random() < 0.05) { // Teleport food to a new location do { food.x = Math.random() * (2048 - food.width) + food.width / 2; food.y = Math.random() * (2732 - food.height) + food.height / 2; } while ( // Ensure food doesn't spawn at the border (food.x < 100 || food.x > 1948) && (food.y < 100 || food.y > 2632) || // Ensure food doesn't overlap with other game objects checkOverlap(food, bonusFood, 100) || checkOverlap(food, life, 100) || positionOverlapsAny(food.x, food.y, [rocks, bombs], 100)); // Visual effect for teleportation LK.effects.flashObject(food, 0x00FFFF, 300); } } // Level 2+ mechanics - Random rock spawning based on level if (level >= 2 && Math.random() < rockSpawnRate && !game.paused) { var randomRock = new Rock(); do { randomRock.x = Math.random() * (2048 - 200) + 100; randomRock.y = Math.random() * (2732 - 200) + 100; } while ( // Ensure random rock doesn't spawn near snake Math.abs(randomRock.x - snake.x) < 200 && Math.abs(randomRock.y - snake.y) < 200 || // Ensure random rock doesn't overlap with other game objects checkOverlap(randomRock, food, 100) || checkOverlap(randomRock, bonusFood, 100) || checkOverlap(randomRock, life, 100) || positionOverlapsAny(randomRock.x, randomRock.y, [rocks, bombs], 100)); game.addChild(randomRock); rocks.push(randomRock); // Remove the rock after the current item duration LK.setTimeout(function () { if (rocks.includes(randomRock) && randomRock.parent) { // Remove rock from array and game for (var i = 0; i < rocks.length; i++) { if (rocks[i] === randomRock) { rocks[i].destroy(); rocks.splice(i, 1); break; } } } }, itemDuration / 2); // Half duration for random rocks to make them more challenging } // Store the current position of the snake head snake.previousPositions.unshift({ x: snake.x, y: snake.y, direction: snake.direction }); // Limit the previous positions array to the length of the body plus some buffer if (snake.previousPositions.length > snake.body.length + 10) { snake.previousPositions.pop(); } // Update the position of the body parts to follow the head's previous positions for (var i = 0; i < snake.body.length; i++) { if (i + 1 < snake.previousPositions.length) { // Make sure the body part is added to the game at the bottom layer // to ensure it stays behind the head game.addChildAt(snake.body[i], 0); // Position the body part based on the previous position of the head snake.body[i].x = snake.previousPositions[i + 1].x; snake.body[i].y = snake.previousPositions[i + 1].y; snake.body[i].setDirection(snake.previousPositions[i + 1].direction); // Manage animation for body parts // Start animation if not already animating if (!snake.body[i].isAnimating) { snake.body[i].startWiggleAnimation(); } // Set animation phase offset based on position in snake body // This creates a wave-like effect through the snake's body snake.body[i].animationDirection = i % 2 === 0 ? 1 : -1; // Create star trail effect behind each body part for more visibility (once every few frames) if (LK.ticks % 2 === 0) { // More frequent trails var star = new StarTrail(); star.x = snake.body[i].x; star.y = snake.body[i].y; // Less randomness for more consistent tail appearance star.x += Math.random() * 6 - 3; star.y += Math.random() * 6 - 3; // Place star trail behind the snake but above the background game.addChildAt(star, game.getChildIndex(background) + 1); if (!starTrails) { starTrails = []; } starTrails.push(star); } } } // Update and clean up star trails if (starTrails) { for (var j = starTrails.length - 1; j >= 0; j--) { starTrails[j].update(); // Create comet trail effect with gradual color change if (starTrails[j].tailLength > 0 && LK.ticks % 2 === 0) { // Calculate color based on alpha var colorIntensity = Math.floor(starTrails[j].alpha * 255); var tailColor = colorIntensity << 16 | colorIntensity << 8 | Math.floor(colorIntensity * 0.7); // Apply color tint to create glowing effect if (starTrails[j].children[0]) { starTrails[j].children[0].tint = tailColor; } // Scale effect for comet-like appearance var scaleFactor = 0.5 + starTrails[j].alpha * 0.5; starTrails[j].scaleX = scaleFactor; starTrails[j].scaleY = scaleFactor; } if (starTrails[j].shouldRemove) { starTrails[j].destroy(); starTrails.splice(j, 1); } } } // Check if the snake's head intersects with the food if (snake.intersects(food)) { // Increase the score by 50 instead of 10 score += 50; // Update the score text scoreTxt.setText('Score: ' + score); // Check if player reached 800 points to win if (score >= 800) { // Show win message var winMessage = new LevelUpMessage(); winMessage.setLevel(level); winMessage.x = 2048 / 2; winMessage.y = 2732 / 2; game.addChild(winMessage); winMessage.show(); // Flash screen green for win LK.effects.flashScreen(0x00FF00, 500); // Show "You win" with custom message LK.showYouWin("Eline sağlık yavrum kazandın"); return; } // Check for level up (every 500 points) if (!isLevelingUp && score >= lastLevelUpScore + 500) { // Level up! level++; lastLevelUpScore = Math.floor(score / 500) * 500; // Increase item duration by 5 seconds per level itemDuration = baseItemDuration + (level - 1) * 5000; // Increase food spawn count with level foodSpawnCount = Math.min(level, 4); // Cap at 4 food items // Pause the game during level up game.paused = true; isLevelingUp = true; // Create and display level up message var levelMessage = new LevelUpMessage(); levelMessage.setLevel(level); levelMessage.x = 2048 / 2; levelMessage.y = 2732 / 2; game.addChild(levelMessage); levelMessage.show(); // Update level text updateLevelText(); // Flash screen green for level up LK.effects.flashScreen(0x00FF00, 300); // If reaching level 2 or higher, apply more challenging behaviors if (level >= 2) { // Update bomb speed increases bombSpeed = 3; // Enable moving bombs enableMovingBombs = true; // Enable food teleportation enableFoodTeleport = true; // Make rock spawning more frequent rockSpawnRate = 0.01; } // Resume game after 2 seconds LK.setTimeout(function () { levelMessage.hide(function () { levelMessage.destroy(); game.paused = false; isLevelingUp = false; // Spawn additional food based on level spawnMultipleFood(); }); }, 2000); } // Increase the food consumed count foodConsumed += 1; // Track normal food items for poison spawning normalFoodCount += 1; // Every 3 normal food items, trigger spawning of 3 poison items if (normalFoodCount >= 3) { poisonToSpawn += 3; normalFoodCount = 0; } // Increase health by 10, up to maximum 200 health = Math.min(health + 10, 200); // Update health bar updateHealthBar(); // Add a new body part to the snake var newBodyPart = new BodyPart(); // Set the direction of the new body part newBodyPart.setDirection(snake.direction); // If no previous positions exist, create initial position if (snake.previousPositions.length <= snake.body.length) { var lastPos; if (snake.body.length === 0) { lastPos = { x: snake.x, y: snake.y }; } else { var lastBodyPart = snake.body[snake.body.length - 1]; lastPos = { x: lastBodyPart.x, y: lastBodyPart.y }; } // Calculate position based on direction if (snake.direction === 'up') { newBodyPart.x = lastPos.x; newBodyPart.y = lastPos.y + 50; // Use a fixed offset } else if (snake.direction === 'down') { newBodyPart.x = lastPos.x; newBodyPart.y = lastPos.y - 50; } else if (snake.direction === 'left') { newBodyPart.x = lastPos.x + 50; newBodyPart.y = lastPos.y; } else if (snake.direction === 'right') { newBodyPart.x = lastPos.x - 50; newBodyPart.y = lastPos.y; } } else { // Use the position from previous positions array var pos = snake.previousPositions[snake.body.length]; newBodyPart.x = pos.x; newBodyPart.y = pos.y; } // Initialize animation properties and start animation for the new body part newBodyPart.startWiggleAnimation(); // Add scale animation when adding new body part newBodyPart.scaleX = 0; newBodyPart.scaleY = 0; tween(newBodyPart, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOutElastic }); snake.body.push(newBodyPart); game.addChild(newBodyPart); // Create an initial burst of star trail when a new body part is added for (var s = 0; s < 10; s++) { var star = new StarTrail(); star.x = newBodyPart.x + (Math.random() * 60 - 30); star.y = newBodyPart.y + (Math.random() * 60 - 30); star.alpha = 0.8 + Math.random() * 0.2; star.fadeSpeed = 0.03 + Math.random() * 0.02; star.rotationSpeed = 0.05 + Math.random() * 0.1; // Place star above background but below game elements game.addChildAt(star, game.getChildIndex(background) + 1); starTrails.push(star); } // Check if it's time to show the bonus food if (score % 150 === 0) { // Position the bonus food at a new random location within the game, ensuring it does not appear on the border or overlap other objects do { bonusFood.x = Math.random() * (2048 - bonusFood.width) + bonusFood.width / 2; bonusFood.y = Math.random() * (2732 - bonusFood.height) + bonusFood.height / 2; } while ( // Ensure bonus food doesn't spawn at the border (bonusFood.x < 100 || bonusFood.x > 1948) && (bonusFood.y < 100 || bonusFood.y > 2632) || // Ensure bonus food doesn't overlap with other game objects checkOverlap(bonusFood, food, 100) || checkOverlap(bonusFood, life, 100) || positionOverlapsAny(bonusFood.x, bonusFood.y, [rocks, bombs], 100)); // Show the bonus food for the current item duration LK.setTimeout(function () { bonusFood.x = -100; bonusFood.y = -100; }, itemDuration); } // Display "Seni seviyorum" message inside the health bar if (score >= 300 && !messageDisplayed) { // Create a flag to track whether the message has been displayed messageDisplayed = true; // Show the message inside the health bar var loveMessage = new Text2('Seni seviyorum', { size: 32, fill: 0xFFFFFF }); // Center the message loveMessage.anchor.set(0.5, 0.5); // Add message to the health bar healthBar.addChild(loveMessage); // Start with zero scale and fade in loveMessage.scaleX = 0; loveMessage.scaleY = 0; loveMessage.alpha = 0; // Animate the message appearance tween(loveMessage, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 500, easing: tween.elasticOut }); // Keep the message visible permanently } // Check if it's time to show the life - increased frequency from every 100 points to every 50 points if (score !== 0 && score % 50 === 0 && score != previousScore) { previousScore = score; // Position the life at a new random location within the game, ensuring it does not appear on the border or overlap other objects do { life.x = Math.random() * (2048 - life.width) + life.width / 2; life.y = Math.random() * (2732 - life.height) + life.height / 2; } while ( // Ensure life doesn't spawn at the border (life.x < 100 || life.x > 1948) && (life.y < 100 || life.y > 2632) || // Ensure life doesn't overlap with other game objects checkOverlap(life, food, 100) || checkOverlap(life, bonusFood, 100) || positionOverlapsAny(life.x, life.y, [rocks, bombs], 100)); // Show the life for the current item duration LK.setTimeout(function () { life.x = -100; life.y = -100; }, itemDuration); } // Randomly spawn additional life items during gameplay (independent of score) if (Math.random() < 0.005 && !game.paused) { // 0.5% chance per frame var randomLife = new KOCAM(); do { randomLife.x = Math.random() * (2048 - 200) + 100; randomLife.y = Math.random() * (2732 - 200) + 100; } while ( // Ensure random life doesn't spawn near snake Math.abs(randomLife.x - snake.x) < 200 && Math.abs(randomLife.y - snake.y) < 200 || // Ensure random life doesn't overlap with other game objects checkOverlap(randomLife, food, 100) || checkOverlap(randomLife, bonusFood, 100) || checkOverlap(randomLife, life, 100) || positionOverlapsAny(randomLife.x, randomLife.y, [rocks, bombs], 100)); game.addChild(randomLife); // Remove the life after the current item duration if not collected LK.setTimeout(function () { randomLife.destroy(); }, itemDuration); } // Poison spawning has been removed // Spawn rocks and bombs when score passes various thresholds, starting with fewer and increasing if (score > 100 && score < 200 && rocks.length === 0) { // Start with fewer rocks (2 initially) and increase with score var rockCount = 2; // Adjust rock count based on score if (score > 150) rockCount = 3; // Spawn rocks in random positions for (var r = 0; r < rockCount; r++) { var rock = new Rock(); // Position rocks randomly but avoid placing directly on snake do { rock.x = Math.random() * (2048 - 200) + 100; rock.y = Math.random() * (2732 - 200) + 100; } while ( // Ensure rock doesn't spawn near snake Math.abs(rock.x - snake.x) < 200 && Math.abs(rock.y - snake.y) < 200 || // Ensure rock doesn't overlap with other game objects checkOverlap(rock, food, 100) || checkOverlap(rock, bonusFood, 100) || checkOverlap(rock, life, 100) || positionOverlapsAny(rock.x, rock.y, [rocks, bombs], 100)); game.addChild(rock); rocks.push(rock); // Set timeout to remove rock after the current item duration if not collided with LK.setTimeout(function () { // Check if rock still exists in the array and game if (rocks.includes(rock) && rock.parent) { // Remove rock from array and game for (var i = 0; i < rocks.length; i++) { if (rocks[i] === rock) { rocks[i].destroy(); rocks.splice(i, 1); break; } } } }, itemDuration); } // Gradually increase bomb count based on score var bombCount = 2; // Start with fewer bombs // Adjust bomb count based on score if (score > 150) bombCount = 3; // Add bomb obstacles for (var b = 0; b < bombCount; b++) { var bomb = new Bomb(); // Position bombs randomly but avoid placing directly on snake do { bomb.x = Math.random() * (2048 - 200) + 100; bomb.y = Math.random() * (2732 - 200) + 100; } while ( // Ensure bomb doesn't spawn near snake Math.abs(bomb.x - snake.x) < 200 && Math.abs(bomb.y - snake.y) < 200 || // Ensure bomb doesn't overlap with other game objects checkOverlap(bomb, food, 100) || checkOverlap(bomb, bonusFood, 100) || checkOverlap(bomb, life, 100) || positionOverlapsAny(bomb.x, bomb.y, [rocks, bombs], 100)); game.addChild(bomb); bombs.push(bomb); } } // Additional bombs when score reaches higher thresholds - with reduced initial counts if (score > 200 && score < 300 && !bombsSpawned200 || score > 300 && score < 400 && !bombsSpawned300 || score > 400 && !bombsSpawned400) { // Set the appropriate flag if (score > 200 && score < 300) bombsSpawned200 = true;else if (score > 300 && score < 400) bombsSpawned300 = true;else if (score > 400) bombsSpawned400 = true; // Number of bombs increases with score, but starts lower var bombCount = 3; // Start with fewer bombs at 200 points if (score > 300) bombCount = 5; // Moderate increase at 300 points if (score > 400) bombCount = 8; // Larger increase at 400 points // Spawn bombs for (var b = 0; b < bombCount; b++) { var difficultyBomb = new Bomb(); do { difficultyBomb.x = Math.random() * (2048 - 200) + 100; difficultyBomb.y = Math.random() * (2732 - 200) + 100; } while ( // Ensure difficulty bomb doesn't spawn near snake Math.abs(difficultyBomb.x - snake.x) < 200 && Math.abs(difficultyBomb.y - snake.y) < 200 || // Ensure difficulty bomb doesn't overlap with other game objects checkOverlap(difficultyBomb, food, 100) || checkOverlap(difficultyBomb, bonusFood, 100) || checkOverlap(difficultyBomb, life, 100) || positionOverlapsAny(difficultyBomb.x, difficultyBomb.y, [rocks, bombs], 100)); game.addChild(difficultyBomb); bombs.push(difficultyBomb); } } // Remove rocks when score reaches 200 if (score >= 200 && rocks.length > 0) { // Remove all rocks for (var i = rocks.length - 1; i >= 0; i--) { rocks[i].destroy(); rocks.splice(i, 1); } } // Spawn bombs at milestone scores, with increasing frequency as score increases if (score > 100 && score % 50 === 0 && score !== previousBombScore) { previousBombScore = score; // Start with fewer bombs and increase with score var bombCount; if (score <= 150) { bombCount = 1; // Just 1 bomb initially } else if (score <= 250) { bombCount = 1 + Math.floor(Math.random() * 2); // 1-2 bombs } else if (score <= 350) { bombCount = 2; // 2 bombs } else { bombCount = 2 + Math.floor(Math.random() * 2); // 2-3 bombs } for (var i = 0; i < bombCount; i++) { var bomb = new Bomb(); // Position the bomb randomly but avoid placing directly on snake do { bomb.x = Math.random() * (2048 - 200) + 100; bomb.y = Math.random() * (2732 - 200) + 100; } while ( // Ensure bomb doesn't spawn near snake Math.abs(bomb.x - snake.x) < 200 && Math.abs(bomb.y - snake.y) < 200 || // Ensure bomb doesn't overlap with other game objects checkOverlap(bomb, food, 100) || checkOverlap(bomb, bonusFood, 100) || checkOverlap(bomb, life, 100) || positionOverlapsAny(bomb.x, bomb.y, [rocks, bombs], 100)); game.addChild(bomb); bombs.push(bomb); // Remove the bomb after the current item duration LK.setTimeout(function () { if (bombs.length > 0) { for (var i = 0; i < bombs.length; i++) { if (bombs[i] === bomb) { bombs[i].destroy(); bombs.splice(i, 1); break; } } } }, itemDuration); } } // Randomly spawn additional bombs during gameplay with probability based on score if (Math.random() < getBombSpawnProbability() && !game.paused) { // Dynamic probability based on score var randomBomb = new Bomb(); do { randomBomb.x = Math.random() * (2048 - 200) + 100; randomBomb.y = Math.random() * (2732 - 200) + 100; } while ( // Ensure random bomb doesn't spawn near snake Math.abs(randomBomb.x - snake.x) < 200 && Math.abs(randomBomb.y - snake.y) < 200 || // Ensure random bomb doesn't overlap with other game objects checkOverlap(randomBomb, food, 100) || checkOverlap(randomBomb, bonusFood, 100) || checkOverlap(randomBomb, life, 100) || positionOverlapsAny(randomBomb.x, randomBomb.y, [rocks, bombs], 100)); game.addChild(randomBomb); bombs.push(randomBomb); // Remove the bomb after the current item duration LK.setTimeout(function () { if (bombs.length > 0) { for (var j = 0; j < bombs.length; j++) { if (bombs[j] === randomBomb) { bombs[j].destroy(); bombs.splice(j, 1); break; } } } }, itemDuration); } // Position the food at a new random location within the game, ensuring it does not appear on the border or overlap with other objects do { food.x = Math.random() * (2048 - food.width) + food.width / 2; food.y = Math.random() * (2732 - food.height) + food.height / 2; } while ( // Ensure food doesn't spawn at the border (food.x < 100 || food.x > 1948) && (food.y < 100 || food.y > 2632) || // Ensure food doesn't overlap with other game objects checkOverlap(food, bonusFood, 100) || checkOverlap(food, life, 100) || positionOverlapsAny(food.x, food.y, [rocks, bombs], 100)); // Set a timeout to remove food after the current item duration if not eaten LK.setTimeout(function () { // Only reposition if the food is still in the game (hasn't been eaten) if (food && food.parent) { // Position food offscreen food.x = -100; food.y = -100; // Spawn new food do { food.x = Math.random() * (2048 - food.width) + food.width / 2; food.y = Math.random() * (2732 - food.height) + food.height / 2; } while ( // Ensure food doesn't spawn at the border (food.x < 100 || food.x > 1948) && (food.y < 100 || food.y > 2632) || // Ensure food doesn't overlap with other game objects checkOverlap(food, bonusFood, 100) || checkOverlap(food, life, 100) || positionOverlapsAny(food.x, food.y, [rocks, bombs], 100)); } }, itemDuration); // Play baby sound when food is eaten LK.getSound('yiyecek').play(); } // Check if the snake's head intersects with the bonus food if (snake.intersects(bonusFood)) { // Increase the score by 50 score += 50; // Update the score text scoreTxt.setText('Score: ' + score); // Play the bonus food sound LK.getSound('bonusfood').play(); // In level 2+, destroy the bonus food rather than just hiding it if (level >= 2) { // Create a replacement bonus food bonusFood.destroy(); bonusFood = game.addChild(new BonusFood()); bonusFood.x = -100; bonusFood.y = -100; } else { // Hide the bonus food bonusFood.x = -100; bonusFood.y = -100; } } // Check if the snake's head intersects with the life if (snake.intersects(life)) { // Increase the lives by 1, up to a maximum of 8 if (lives < 8) { lives += 1; // Update the lives text livesTxt.setText('Lives: ' + lives); // Update health bar updateHealthBar(); // Play the life sound LK.getSound('life').play(); } // In level 2+, destroy the life rather than just hiding it if (level >= 2) { // Create a replacement life life.destroy(); life = game.addChild(new KOCAM()); life.x = -100; life.y = -100; } else { // Hide the life life.x = -100; life.y = -100; } } // Poison food item has been removed // Check if the snake's head has moved out of the screen if (snake.x < 0) { snake.x = 2048; } else if (snake.x > 2048) { snake.x = 0; } else if (snake.y < 0) { snake.y = 2732; } else if (snake.y > 2732) { snake.y = 0; } // Check for collision with rocks for (var r = 0; r < rocks.length; r++) { if (snake.intersects(rocks[r])) { // Play cat sound when snake hits rocks LK.getSound('cat').play(); // Track if this is the first or second collision if (!snake.rockCollision) { // First collision - reduce health by 70 snake.rockCollision = true; health -= 70; // Ensure health doesn't go below 0 if (health < 0) health = 0; // Update the health bar updateHealthBar(); // Flash screen red for visual feedback LK.effects.flashScreen(0xFF0000, 300); // Push snake back a bit from the rock if (snake.direction === 'up') { snake.y += 50; } else if (snake.direction === 'down') { snake.y -= 50; } else if (snake.direction === 'left') { snake.x += 50; } else if (snake.direction === 'right') { snake.x -= 50; } // Make the rock disappear rocks[r].destroy(); rocks.splice(r, 1); } else { // Second collision - snake dies // Stop any currently playing music LK.stopMusic(); // Play game over music that will continue until player presses Play Again LK.playMusic('gameOverMusic'); // Flash screen red for visual feedback LK.effects.flashScreen(0xFF0000, 500); LK.showGameOver(); } break; } } // Check for collision with bombs for (var b = 0; b < bombs.length; b++) { if (snake.intersects(bombs[b])) { // Increase damage - decrease health by 30 for bomb collision (up from 20) health -= 30; // Ensure health doesn't go below 0 if (health < 0) health = 0; // Update health bar updateHealthBar(); // Flash screen red for visual feedback with longer duration LK.effects.flashScreen(0xFF0000, 300); // Play the poison sound LK.getSound('poison').play(); // Make bomb explosion effect LK.effects.flashObject(bombs[b], 0xFF0000, 200); // Remove the bomb after collision bombs[b].destroy(); bombs.splice(b, 1); // Check if health has hit 0 if (health === 0) { // Stop any currently playing music LK.stopMusic(); // Play game over music that will continue until player presses Play Again LK.playMusic('gameOverMusic'); // Show game over screen LK.showGameOver(); } break; } } }; // Initialize lives, score, food consumed var lives = 3; var score = 0; var previousScore = 0; var previousBombScore = 0; var foodConsumed = 0; var normalFoodCount = 0; // Initialize normalFoodCount var poisonToSpawn = 0; // Initialize poisonToSpawn var starTrails = []; var rocks = []; // Array to hold rock obstacles var bombs = []; // Array to hold bomb obstacles var messageDisplayed = false; // Flag to track if "I love you" message has been displayed // Variables to track bomb spawning at different score thresholds var bombsSpawned200 = false; var bombsSpawned300 = false; var bombsSpawned400 = false; var lastBombSpawnTime = 0; // Track when bombs were last spawned // Level system variables - level increases every 500 points var level = 1; var lastLevelUpScore = 0; var isLevelingUp = false; var baseItemDuration = 7000; // Base duration for items in milliseconds var itemDuration = baseItemDuration; // Current duration for items, will increase with level var foodSpawnCount = 1; // Number of food items to spawn // Level 2+ difficulty variables var bombSpeed = 0; // Speed at which bombs move var enableMovingBombs = false; // Whether bombs should move var enableFoodTeleport = false; // Whether food should teleport var rockSpawnRate = 0.002; // Base rate for spawning rocks var lastFoodTeleportTime = 0; // Track when food last teleported // Function to check if two objects overlap function checkOverlap(obj1, obj2, minDistance) { if (!obj1 || !obj2) return false; var dx = Math.abs(obj1.x - obj2.x); var dy = Math.abs(obj1.y - obj2.y); return dx < minDistance && dy < minDistance; } // Function to check if a position overlaps with any objects in arrays function positionOverlapsAny(x, y, objectArrays, minDistance) { for (var i = 0; i < objectArrays.length; i++) { var array = objectArrays[i]; if (!array) continue; for (var j = 0; j < array.length; j++) { var obj = array[j]; if (!obj) continue; var dx = Math.abs(x - obj.x); var dy = Math.abs(y - obj.y); if (dx < minDistance && dy < minDistance) { return true; } } } return false; } // Create lives text var livesTxt = new Text2('Lives: ' + lives, { size: 32, fill: 0xFFFFFF }); livesTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(livesTxt); // Create score text var scoreTxt = new Text2('Score: ' + score, { size: 32, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create level text var levelTxt = new Text2('Level: ' + level, { size: 32, fill: 0xFFFFFF }); levelTxt.anchor.set(1, 0); levelTxt.x = -10; // Offset from right edge LK.gui.topRight.addChild(levelTxt); // Initialize health var health = 200; // Create and position health bar var healthBar = game.addChild(new HealthBar()); healthBar.x = 2048 / 2; healthBar.y = 50; // Function to update health bar function updateHealthBar() { healthBar.updateHealth(health); } // Function to calculate bomb spawn probability based on score function getBombSpawnProbability() { // Start with a very low probability if (score < 100) { return 0.001; // 0.1% chance } else if (score < 200) { return 0.003; // 0.3% chance } else if (score < 300) { return 0.005; // 0.5% chance } else if (score < 400) { return 0.007; // 0.7% chance } else { return 0.01; // 1% chance - same as original } } // Function to spawn multiple food items based on the current level function spawnMultipleFood() { // We always keep the main food item // Spawn additional food items based on level for (var i = 0; i < foodSpawnCount - 1; i++) { // Create additional food item var additionalFood = new Food(); // Position at random location that doesn't overlap with other objects do { additionalFood.x = Math.random() * (2048 - additionalFood.width) + additionalFood.width / 2; additionalFood.y = Math.random() * (2732 - additionalFood.height) + additionalFood.height / 2; } while ( // Ensure food doesn't spawn at the border (additionalFood.x < 100 || additionalFood.x > 1948) && (additionalFood.y < 100 || additionalFood.y > 2632) || // Ensure food doesn't overlap with other game objects checkOverlap(additionalFood, food, 100) || checkOverlap(additionalFood, bonusFood, 100) || checkOverlap(additionalFood, life, 100) || positionOverlapsAny(additionalFood.x, additionalFood.y, [rocks, bombs], 100)); // Add food to game game.addChild(additionalFood); // Set timeout to remove food after the current item duration LK.setTimeout(function () { if (additionalFood && additionalFood.parent) { additionalFood.destroy(); } }, itemDuration); } } // Function to update level text function updateLevelText() { levelTxt.setText('Level: ' + level); } // Initialize health bar display updateHealthBar(); // Initialize level text updateLevelText(); game.down = function (x, y, obj) { if (game.paused) { return; } // Change the snake's direction to always move in the direction of the front area of the snake head which is not connected to the snake body if (x > snake.x && snake.direction !== 'left' && snake.direction !== 'right') { snake.moveHead('right'); } else if (x < snake.x && snake.direction !== 'right' && snake.direction !== 'left') { snake.moveHead('left'); } else if (y > snake.y && snake.direction !== 'up' && snake.direction !== 'down') { snake.moveHead('down'); } else if (y < snake.y && snake.direction !== 'down' && snake.direction !== 'up') { snake.moveHead('up'); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BodyPart = Container.expand(function () {
var self = Container.call(this);
var bodyPart = self.attachAsset('head', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0x00FFFF // Cyan tint for better visibility
});
// Add animation properties
self.originalScale = 1.2; // Larger scale
self.isAnimating = false;
self.animationDirection = 1;
// Rotate the body part based on direction
self.setDirection = function (direction) {
if (direction === 'up') {
bodyPart.rotation = 0;
} else if (direction === 'down') {
bodyPart.rotation = Math.PI;
} else if (direction === 'left') {
bodyPart.rotation = -Math.PI / 2;
} else if (direction === 'right') {
bodyPart.rotation = Math.PI / 2;
}
};
// Start wiggle animation for body parts
self.startWiggleAnimation = function () {
if (self.isAnimating) return;
self.isAnimating = true;
self.animateWiggle();
};
// Stop wiggle animation
self.stopWiggleAnimation = function () {
self.isAnimating = false;
tween.stop(bodyPart, {
scaleX: true,
scaleY: true
});
bodyPart.scaleX = self.originalScale;
bodyPart.scaleY = self.originalScale;
};
// Animate wiggle effect
self.animateWiggle = function () {
if (!self.isAnimating) return;
var scaleOffset = 0.05;
var duration = 250;
// Determine which axis to animate based on direction
var direction = self.animationDirection;
var targetScaleX = self.originalScale;
var targetScaleY = self.originalScale;
// Wiggle based on body orientation
if (bodyPart.rotation === 0 || bodyPart.rotation === Math.PI) {
// For up/down movement, wiggle horizontally
targetScaleX = self.originalScale + scaleOffset * direction;
} else {
// For left/right movement, wiggle vertically
targetScaleY = self.originalScale + scaleOffset * direction;
}
tween(bodyPart, {
scaleX: targetScaleX,
scaleY: targetScaleY
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.animationDirection *= -1;
if (self.isAnimating) {
self.animateWiggle();
}
}
});
};
return self;
});
var Bomb = Container.expand(function () {
var self = Container.call(this);
// Create a bomb obstacle using rock image asset with red tint
var bomb = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFF0000,
// Red tint to distinguish from rocks
scaleX: 0.8,
scaleY: 0.8
});
return self;
});
var BonusFood = Container.expand(function () {
var self = Container.call(this);
// Create the bonus food
var bonusFood = self.attachAsset('bonusFood', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Food = Container.expand(function () {
var self = Container.call(this);
// Create the food
var food = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var HealthBar = Container.expand(function () {
var self = Container.call(this);
// Create the health bar container box
var barContainer = self.attachAsset('healbar', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000,
alpha: 0.7,
scaleX: 2,
scaleY: 0.5
});
// Create the bar background (red)
var barBg = self.attachAsset('healbar', {
anchorX: 0,
anchorY: 0.5,
tint: 0xFF0000,
scaleX: 1.9,
scaleY: 0.4,
x: -barContainer.width / 2 + 5,
y: 0
});
// Create the health indicator (green)
var healthIndicator = self.attachAsset('healbar', {
anchorX: 0,
anchorY: 0.5,
tint: 0x00FF00,
scaleX: 1.9,
scaleY: 0.4,
x: -barContainer.width / 2 + 5,
y: 0
});
self.updateHealth = function (health) {
// Health ranges from 0 to 200, convert to scale between 0 and 1.9 (max bar width)
var healthWidth = health / 200 * 1.9;
healthIndicator.scaleX = healthWidth;
};
return self;
});
var KOCAM = Container.expand(function () {
var self = Container.call(this);
// Create the life
var life = self.attachAsset('life', {
anchorX: 0.5,
anchorY: 0.5
});
});
var LevelUpMessage = Container.expand(function () {
var self = Container.call(this);
// Create the level up message background
var background = self.attachAsset('healbar', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000,
alpha: 0.8,
scaleX: 20,
scaleY: 8
});
// Create the level up message text
var message = new Text2('', {
size: 64,
fill: 0xFFFFFF
});
message.anchor.set(0.5, 0.5);
self.addChild(message);
// Method to update the text
self.setLevel = function (level) {
message.setText('Çok yeteneklisin bebi');
};
// Method to show the message with animation
self.show = function () {
self.alpha = 0;
self.scaleX = 0.5;
self.scaleY = 0.5;
// Animate message appearance
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeOutElastic
});
};
// Method to hide the message with animation
self.hide = function (callback) {
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
if (callback) callback();
}
});
};
return self;
});
var Pause = Container.expand(function () {
var self = Container.call(this);
// Create the pause button
var pause = self.attachAsset('pause', {
anchorX: 0.5,
anchorY: 0.5
});
// Event handler called when a press happens on element.
self.down = function (x, y, obj) {
if (!game.paused) {
game.paused = true;
pause.id = 'resume';
} else {
game.paused = false;
pause.id = 'pause';
}
};
return self;
});
// Poison class has been removed
var Rock = Container.expand(function () {
var self = Container.call(this);
// Create a rock obstacle using rock image asset
var rock = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
return self;
});
var Snake = Container.expand(function () {
var self = Container.call(this);
// Create the head of the snake
var head = self.attachAsset('head', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize the snake's direction and speed
self.direction = 'up';
self.speed = 5;
self.previousPositions = [];
// Update the head rotation based on direction
self.updateHeadRotation = function () {
if (self.direction === 'up') {
head.rotation = 0;
} else if (self.direction === 'down') {
head.rotation = Math.PI;
} else if (self.direction === 'left') {
head.rotation = -Math.PI / 2;
} else if (self.direction === 'right') {
head.rotation = Math.PI / 2;
}
};
self.moveHead = function (newDirection) {
if (newDirection === 'up' && this.direction !== 'down') {
this.direction = 'up';
self.updateHeadRotation();
} else if (newDirection === 'down' && this.direction !== 'up') {
this.direction = 'down';
self.updateHeadRotation();
} else if (newDirection === 'left' && this.direction !== 'right') {
this.direction = 'left';
self.updateHeadRotation();
} else if (newDirection === 'right' && this.direction !== 'left') {
this.direction = 'right';
self.updateHeadRotation();
}
};
// Initialize with the correct rotation
self.updateHeadRotation();
return self;
});
var StarTrail = Container.expand(function () {
var self = Container.call(this);
// Create a star-like shape using an asset
var star = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
// Set initial properties
self.alpha = 1;
self.fadeSpeed = 0.03; // Slower fade for more visibility
self.rotationSpeed = 0.1;
self.tailLength = 0;
self.maxTailLength = 45; // Longer tail
self.growSpeed = 0.8; // Grow faster
self.tailColor = 0xFFFF00; // Bright yellow for tail
star.tint = 0xFFFFFF; // White for star head
// Update method to handle fading, rotation and tail growth
self.update = function () {
// Rotate the star
star.rotation += self.rotationSpeed;
// Fade out more slowly
self.alpha -= self.fadeSpeed;
// Grow tail initially
if (self.tailLength < self.maxTailLength) {
self.tailLength += self.growSpeed;
}
// If fully transparent, mark for removal
if (self.alpha <= 0) {
self.shouldRemove = true;
}
};
return self;
});
/****
* Initialize Game
****/
//<Assets used in the game will automatically appear here>
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
// Add a background to the game
// Import tween plugin for animations
var background = game.addChildAt(LK.getAsset('newBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.7 // Reduce opacity to improve visibility of game elements
}), 0); // Add background as the bottom-most layer
// Start playing background music as soon as the game begins
LK.playMusic('gameOverMusic');
// Initialize pause button
var pause = game.addChild(new Pause());
// Position the pause button a little to the left from the top right corner of the game
pause.x = 2048 - pause.width;
pause.y = 50; // Move the pause button a little down
var snake = game.addChild(new Snake());
snake.body = [];
// Position the snake at the center of the game
snake.x = 2048 / 2;
snake.y = 2732 / 2;
// Initialize food
var food = game.addChild(new Food());
// Position the food at a random location within the game
food.x = Math.random() * 2048;
food.y = Math.random() * 2732;
// Initialize poison
var bonusFood = game.addChild(new BonusFood());
// Poison food item has been removed
bonusFood.x = -100;
bonusFood.y = -100;
var life = game.addChild(new KOCAM());
// Hide the life when the game starts
life.x = -100;
life.y = -100;
// Hide the poison when the game starts
game.update = function () {
if (game.paused) {
return;
}
// Update the snake's position based on its direction and speed
if (snake.direction === 'up') {
snake.y -= snake.speed * 2.25;
} else if (snake.direction === 'down') {
snake.y += snake.speed * 2.25;
} else if (snake.direction === 'left') {
snake.x -= snake.speed * 2.25;
} else if (snake.direction === 'right') {
snake.x += snake.speed * 2.25;
}
// Level 2+ mechanics - Moving bombs
if (enableMovingBombs && bombs.length > 0) {
for (var mb = 0; mb < bombs.length; mb++) {
// Move bombs toward snake occasionally
if (LK.ticks % 60 === 0) {
// Target the snake with a chance
if (Math.random() < 0.5) {
// Calculate direction toward snake
var dx = snake.x - bombs[mb].x;
var dy = snake.y - bombs[mb].y;
// Normalize and apply speed
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
bombs[mb].x += dx / dist * bombSpeed;
bombs[mb].y += dy / dist * bombSpeed;
}
} else {
// Random movement
bombs[mb].x += (Math.random() * 2 - 1) * bombSpeed * 2;
bombs[mb].y += (Math.random() * 2 - 1) * bombSpeed * 2;
}
}
}
}
// Level 2+ mechanics - Teleporting food
if (enableFoodTeleport && LK.ticks % 180 === 0 && food && food.parent) {
// 5% chance food will teleport every 3 seconds
if (Math.random() < 0.05) {
// Teleport food to a new location
do {
food.x = Math.random() * (2048 - food.width) + food.width / 2;
food.y = Math.random() * (2732 - food.height) + food.height / 2;
} while (
// Ensure food doesn't spawn at the border
(food.x < 100 || food.x > 1948) && (food.y < 100 || food.y > 2632) ||
// Ensure food doesn't overlap with other game objects
checkOverlap(food, bonusFood, 100) || checkOverlap(food, life, 100) || positionOverlapsAny(food.x, food.y, [rocks, bombs], 100));
// Visual effect for teleportation
LK.effects.flashObject(food, 0x00FFFF, 300);
}
}
// Level 2+ mechanics - Random rock spawning based on level
if (level >= 2 && Math.random() < rockSpawnRate && !game.paused) {
var randomRock = new Rock();
do {
randomRock.x = Math.random() * (2048 - 200) + 100;
randomRock.y = Math.random() * (2732 - 200) + 100;
} while (
// Ensure random rock doesn't spawn near snake
Math.abs(randomRock.x - snake.x) < 200 && Math.abs(randomRock.y - snake.y) < 200 ||
// Ensure random rock doesn't overlap with other game objects
checkOverlap(randomRock, food, 100) || checkOverlap(randomRock, bonusFood, 100) || checkOverlap(randomRock, life, 100) || positionOverlapsAny(randomRock.x, randomRock.y, [rocks, bombs], 100));
game.addChild(randomRock);
rocks.push(randomRock);
// Remove the rock after the current item duration
LK.setTimeout(function () {
if (rocks.includes(randomRock) && randomRock.parent) {
// Remove rock from array and game
for (var i = 0; i < rocks.length; i++) {
if (rocks[i] === randomRock) {
rocks[i].destroy();
rocks.splice(i, 1);
break;
}
}
}
}, itemDuration / 2); // Half duration for random rocks to make them more challenging
}
// Store the current position of the snake head
snake.previousPositions.unshift({
x: snake.x,
y: snake.y,
direction: snake.direction
});
// Limit the previous positions array to the length of the body plus some buffer
if (snake.previousPositions.length > snake.body.length + 10) {
snake.previousPositions.pop();
}
// Update the position of the body parts to follow the head's previous positions
for (var i = 0; i < snake.body.length; i++) {
if (i + 1 < snake.previousPositions.length) {
// Make sure the body part is added to the game at the bottom layer
// to ensure it stays behind the head
game.addChildAt(snake.body[i], 0);
// Position the body part based on the previous position of the head
snake.body[i].x = snake.previousPositions[i + 1].x;
snake.body[i].y = snake.previousPositions[i + 1].y;
snake.body[i].setDirection(snake.previousPositions[i + 1].direction);
// Manage animation for body parts
// Start animation if not already animating
if (!snake.body[i].isAnimating) {
snake.body[i].startWiggleAnimation();
}
// Set animation phase offset based on position in snake body
// This creates a wave-like effect through the snake's body
snake.body[i].animationDirection = i % 2 === 0 ? 1 : -1;
// Create star trail effect behind each body part for more visibility (once every few frames)
if (LK.ticks % 2 === 0) {
// More frequent trails
var star = new StarTrail();
star.x = snake.body[i].x;
star.y = snake.body[i].y;
// Less randomness for more consistent tail appearance
star.x += Math.random() * 6 - 3;
star.y += Math.random() * 6 - 3;
// Place star trail behind the snake but above the background
game.addChildAt(star, game.getChildIndex(background) + 1);
if (!starTrails) {
starTrails = [];
}
starTrails.push(star);
}
}
}
// Update and clean up star trails
if (starTrails) {
for (var j = starTrails.length - 1; j >= 0; j--) {
starTrails[j].update();
// Create comet trail effect with gradual color change
if (starTrails[j].tailLength > 0 && LK.ticks % 2 === 0) {
// Calculate color based on alpha
var colorIntensity = Math.floor(starTrails[j].alpha * 255);
var tailColor = colorIntensity << 16 | colorIntensity << 8 | Math.floor(colorIntensity * 0.7);
// Apply color tint to create glowing effect
if (starTrails[j].children[0]) {
starTrails[j].children[0].tint = tailColor;
}
// Scale effect for comet-like appearance
var scaleFactor = 0.5 + starTrails[j].alpha * 0.5;
starTrails[j].scaleX = scaleFactor;
starTrails[j].scaleY = scaleFactor;
}
if (starTrails[j].shouldRemove) {
starTrails[j].destroy();
starTrails.splice(j, 1);
}
}
}
// Check if the snake's head intersects with the food
if (snake.intersects(food)) {
// Increase the score by 50 instead of 10
score += 50;
// Update the score text
scoreTxt.setText('Score: ' + score);
// Check if player reached 800 points to win
if (score >= 800) {
// Show win message
var winMessage = new LevelUpMessage();
winMessage.setLevel(level);
winMessage.x = 2048 / 2;
winMessage.y = 2732 / 2;
game.addChild(winMessage);
winMessage.show();
// Flash screen green for win
LK.effects.flashScreen(0x00FF00, 500);
// Show "You win" with custom message
LK.showYouWin("Eline sağlık yavrum kazandın");
return;
}
// Check for level up (every 500 points)
if (!isLevelingUp && score >= lastLevelUpScore + 500) {
// Level up!
level++;
lastLevelUpScore = Math.floor(score / 500) * 500;
// Increase item duration by 5 seconds per level
itemDuration = baseItemDuration + (level - 1) * 5000;
// Increase food spawn count with level
foodSpawnCount = Math.min(level, 4); // Cap at 4 food items
// Pause the game during level up
game.paused = true;
isLevelingUp = true;
// Create and display level up message
var levelMessage = new LevelUpMessage();
levelMessage.setLevel(level);
levelMessage.x = 2048 / 2;
levelMessage.y = 2732 / 2;
game.addChild(levelMessage);
levelMessage.show();
// Update level text
updateLevelText();
// Flash screen green for level up
LK.effects.flashScreen(0x00FF00, 300);
// If reaching level 2 or higher, apply more challenging behaviors
if (level >= 2) {
// Update bomb speed increases
bombSpeed = 3;
// Enable moving bombs
enableMovingBombs = true;
// Enable food teleportation
enableFoodTeleport = true;
// Make rock spawning more frequent
rockSpawnRate = 0.01;
}
// Resume game after 2 seconds
LK.setTimeout(function () {
levelMessage.hide(function () {
levelMessage.destroy();
game.paused = false;
isLevelingUp = false;
// Spawn additional food based on level
spawnMultipleFood();
});
}, 2000);
}
// Increase the food consumed count
foodConsumed += 1;
// Track normal food items for poison spawning
normalFoodCount += 1;
// Every 3 normal food items, trigger spawning of 3 poison items
if (normalFoodCount >= 3) {
poisonToSpawn += 3;
normalFoodCount = 0;
}
// Increase health by 10, up to maximum 200
health = Math.min(health + 10, 200);
// Update health bar
updateHealthBar();
// Add a new body part to the snake
var newBodyPart = new BodyPart();
// Set the direction of the new body part
newBodyPart.setDirection(snake.direction);
// If no previous positions exist, create initial position
if (snake.previousPositions.length <= snake.body.length) {
var lastPos;
if (snake.body.length === 0) {
lastPos = {
x: snake.x,
y: snake.y
};
} else {
var lastBodyPart = snake.body[snake.body.length - 1];
lastPos = {
x: lastBodyPart.x,
y: lastBodyPart.y
};
}
// Calculate position based on direction
if (snake.direction === 'up') {
newBodyPart.x = lastPos.x;
newBodyPart.y = lastPos.y + 50; // Use a fixed offset
} else if (snake.direction === 'down') {
newBodyPart.x = lastPos.x;
newBodyPart.y = lastPos.y - 50;
} else if (snake.direction === 'left') {
newBodyPart.x = lastPos.x + 50;
newBodyPart.y = lastPos.y;
} else if (snake.direction === 'right') {
newBodyPart.x = lastPos.x - 50;
newBodyPart.y = lastPos.y;
}
} else {
// Use the position from previous positions array
var pos = snake.previousPositions[snake.body.length];
newBodyPart.x = pos.x;
newBodyPart.y = pos.y;
}
// Initialize animation properties and start animation for the new body part
newBodyPart.startWiggleAnimation();
// Add scale animation when adding new body part
newBodyPart.scaleX = 0;
newBodyPart.scaleY = 0;
tween(newBodyPart, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOutElastic
});
snake.body.push(newBodyPart);
game.addChild(newBodyPart);
// Create an initial burst of star trail when a new body part is added
for (var s = 0; s < 10; s++) {
var star = new StarTrail();
star.x = newBodyPart.x + (Math.random() * 60 - 30);
star.y = newBodyPart.y + (Math.random() * 60 - 30);
star.alpha = 0.8 + Math.random() * 0.2;
star.fadeSpeed = 0.03 + Math.random() * 0.02;
star.rotationSpeed = 0.05 + Math.random() * 0.1;
// Place star above background but below game elements
game.addChildAt(star, game.getChildIndex(background) + 1);
starTrails.push(star);
}
// Check if it's time to show the bonus food
if (score % 150 === 0) {
// Position the bonus food at a new random location within the game, ensuring it does not appear on the border or overlap other objects
do {
bonusFood.x = Math.random() * (2048 - bonusFood.width) + bonusFood.width / 2;
bonusFood.y = Math.random() * (2732 - bonusFood.height) + bonusFood.height / 2;
} while (
// Ensure bonus food doesn't spawn at the border
(bonusFood.x < 100 || bonusFood.x > 1948) && (bonusFood.y < 100 || bonusFood.y > 2632) ||
// Ensure bonus food doesn't overlap with other game objects
checkOverlap(bonusFood, food, 100) || checkOverlap(bonusFood, life, 100) || positionOverlapsAny(bonusFood.x, bonusFood.y, [rocks, bombs], 100));
// Show the bonus food for the current item duration
LK.setTimeout(function () {
bonusFood.x = -100;
bonusFood.y = -100;
}, itemDuration);
}
// Display "Seni seviyorum" message inside the health bar
if (score >= 300 && !messageDisplayed) {
// Create a flag to track whether the message has been displayed
messageDisplayed = true;
// Show the message inside the health bar
var loveMessage = new Text2('Seni seviyorum', {
size: 32,
fill: 0xFFFFFF
});
// Center the message
loveMessage.anchor.set(0.5, 0.5);
// Add message to the health bar
healthBar.addChild(loveMessage);
// Start with zero scale and fade in
loveMessage.scaleX = 0;
loveMessage.scaleY = 0;
loveMessage.alpha = 0;
// Animate the message appearance
tween(loveMessage, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 500,
easing: tween.elasticOut
});
// Keep the message visible permanently
}
// Check if it's time to show the life - increased frequency from every 100 points to every 50 points
if (score !== 0 && score % 50 === 0 && score != previousScore) {
previousScore = score;
// Position the life at a new random location within the game, ensuring it does not appear on the border or overlap other objects
do {
life.x = Math.random() * (2048 - life.width) + life.width / 2;
life.y = Math.random() * (2732 - life.height) + life.height / 2;
} while (
// Ensure life doesn't spawn at the border
(life.x < 100 || life.x > 1948) && (life.y < 100 || life.y > 2632) ||
// Ensure life doesn't overlap with other game objects
checkOverlap(life, food, 100) || checkOverlap(life, bonusFood, 100) || positionOverlapsAny(life.x, life.y, [rocks, bombs], 100));
// Show the life for the current item duration
LK.setTimeout(function () {
life.x = -100;
life.y = -100;
}, itemDuration);
}
// Randomly spawn additional life items during gameplay (independent of score)
if (Math.random() < 0.005 && !game.paused) {
// 0.5% chance per frame
var randomLife = new KOCAM();
do {
randomLife.x = Math.random() * (2048 - 200) + 100;
randomLife.y = Math.random() * (2732 - 200) + 100;
} while (
// Ensure random life doesn't spawn near snake
Math.abs(randomLife.x - snake.x) < 200 && Math.abs(randomLife.y - snake.y) < 200 ||
// Ensure random life doesn't overlap with other game objects
checkOverlap(randomLife, food, 100) || checkOverlap(randomLife, bonusFood, 100) || checkOverlap(randomLife, life, 100) || positionOverlapsAny(randomLife.x, randomLife.y, [rocks, bombs], 100));
game.addChild(randomLife);
// Remove the life after the current item duration if not collected
LK.setTimeout(function () {
randomLife.destroy();
}, itemDuration);
}
// Poison spawning has been removed
// Spawn rocks and bombs when score passes various thresholds, starting with fewer and increasing
if (score > 100 && score < 200 && rocks.length === 0) {
// Start with fewer rocks (2 initially) and increase with score
var rockCount = 2;
// Adjust rock count based on score
if (score > 150) rockCount = 3;
// Spawn rocks in random positions
for (var r = 0; r < rockCount; r++) {
var rock = new Rock();
// Position rocks randomly but avoid placing directly on snake
do {
rock.x = Math.random() * (2048 - 200) + 100;
rock.y = Math.random() * (2732 - 200) + 100;
} while (
// Ensure rock doesn't spawn near snake
Math.abs(rock.x - snake.x) < 200 && Math.abs(rock.y - snake.y) < 200 ||
// Ensure rock doesn't overlap with other game objects
checkOverlap(rock, food, 100) || checkOverlap(rock, bonusFood, 100) || checkOverlap(rock, life, 100) || positionOverlapsAny(rock.x, rock.y, [rocks, bombs], 100));
game.addChild(rock);
rocks.push(rock);
// Set timeout to remove rock after the current item duration if not collided with
LK.setTimeout(function () {
// Check if rock still exists in the array and game
if (rocks.includes(rock) && rock.parent) {
// Remove rock from array and game
for (var i = 0; i < rocks.length; i++) {
if (rocks[i] === rock) {
rocks[i].destroy();
rocks.splice(i, 1);
break;
}
}
}
}, itemDuration);
}
// Gradually increase bomb count based on score
var bombCount = 2; // Start with fewer bombs
// Adjust bomb count based on score
if (score > 150) bombCount = 3;
// Add bomb obstacles
for (var b = 0; b < bombCount; b++) {
var bomb = new Bomb();
// Position bombs randomly but avoid placing directly on snake
do {
bomb.x = Math.random() * (2048 - 200) + 100;
bomb.y = Math.random() * (2732 - 200) + 100;
} while (
// Ensure bomb doesn't spawn near snake
Math.abs(bomb.x - snake.x) < 200 && Math.abs(bomb.y - snake.y) < 200 ||
// Ensure bomb doesn't overlap with other game objects
checkOverlap(bomb, food, 100) || checkOverlap(bomb, bonusFood, 100) || checkOverlap(bomb, life, 100) || positionOverlapsAny(bomb.x, bomb.y, [rocks, bombs], 100));
game.addChild(bomb);
bombs.push(bomb);
}
}
// Additional bombs when score reaches higher thresholds - with reduced initial counts
if (score > 200 && score < 300 && !bombsSpawned200 || score > 300 && score < 400 && !bombsSpawned300 || score > 400 && !bombsSpawned400) {
// Set the appropriate flag
if (score > 200 && score < 300) bombsSpawned200 = true;else if (score > 300 && score < 400) bombsSpawned300 = true;else if (score > 400) bombsSpawned400 = true;
// Number of bombs increases with score, but starts lower
var bombCount = 3; // Start with fewer bombs at 200 points
if (score > 300) bombCount = 5; // Moderate increase at 300 points
if (score > 400) bombCount = 8; // Larger increase at 400 points
// Spawn bombs
for (var b = 0; b < bombCount; b++) {
var difficultyBomb = new Bomb();
do {
difficultyBomb.x = Math.random() * (2048 - 200) + 100;
difficultyBomb.y = Math.random() * (2732 - 200) + 100;
} while (
// Ensure difficulty bomb doesn't spawn near snake
Math.abs(difficultyBomb.x - snake.x) < 200 && Math.abs(difficultyBomb.y - snake.y) < 200 ||
// Ensure difficulty bomb doesn't overlap with other game objects
checkOverlap(difficultyBomb, food, 100) || checkOverlap(difficultyBomb, bonusFood, 100) || checkOverlap(difficultyBomb, life, 100) || positionOverlapsAny(difficultyBomb.x, difficultyBomb.y, [rocks, bombs], 100));
game.addChild(difficultyBomb);
bombs.push(difficultyBomb);
}
}
// Remove rocks when score reaches 200
if (score >= 200 && rocks.length > 0) {
// Remove all rocks
for (var i = rocks.length - 1; i >= 0; i--) {
rocks[i].destroy();
rocks.splice(i, 1);
}
}
// Spawn bombs at milestone scores, with increasing frequency as score increases
if (score > 100 && score % 50 === 0 && score !== previousBombScore) {
previousBombScore = score;
// Start with fewer bombs and increase with score
var bombCount;
if (score <= 150) {
bombCount = 1; // Just 1 bomb initially
} else if (score <= 250) {
bombCount = 1 + Math.floor(Math.random() * 2); // 1-2 bombs
} else if (score <= 350) {
bombCount = 2; // 2 bombs
} else {
bombCount = 2 + Math.floor(Math.random() * 2); // 2-3 bombs
}
for (var i = 0; i < bombCount; i++) {
var bomb = new Bomb();
// Position the bomb randomly but avoid placing directly on snake
do {
bomb.x = Math.random() * (2048 - 200) + 100;
bomb.y = Math.random() * (2732 - 200) + 100;
} while (
// Ensure bomb doesn't spawn near snake
Math.abs(bomb.x - snake.x) < 200 && Math.abs(bomb.y - snake.y) < 200 ||
// Ensure bomb doesn't overlap with other game objects
checkOverlap(bomb, food, 100) || checkOverlap(bomb, bonusFood, 100) || checkOverlap(bomb, life, 100) || positionOverlapsAny(bomb.x, bomb.y, [rocks, bombs], 100));
game.addChild(bomb);
bombs.push(bomb);
// Remove the bomb after the current item duration
LK.setTimeout(function () {
if (bombs.length > 0) {
for (var i = 0; i < bombs.length; i++) {
if (bombs[i] === bomb) {
bombs[i].destroy();
bombs.splice(i, 1);
break;
}
}
}
}, itemDuration);
}
}
// Randomly spawn additional bombs during gameplay with probability based on score
if (Math.random() < getBombSpawnProbability() && !game.paused) {
// Dynamic probability based on score
var randomBomb = new Bomb();
do {
randomBomb.x = Math.random() * (2048 - 200) + 100;
randomBomb.y = Math.random() * (2732 - 200) + 100;
} while (
// Ensure random bomb doesn't spawn near snake
Math.abs(randomBomb.x - snake.x) < 200 && Math.abs(randomBomb.y - snake.y) < 200 ||
// Ensure random bomb doesn't overlap with other game objects
checkOverlap(randomBomb, food, 100) || checkOverlap(randomBomb, bonusFood, 100) || checkOverlap(randomBomb, life, 100) || positionOverlapsAny(randomBomb.x, randomBomb.y, [rocks, bombs], 100));
game.addChild(randomBomb);
bombs.push(randomBomb);
// Remove the bomb after the current item duration
LK.setTimeout(function () {
if (bombs.length > 0) {
for (var j = 0; j < bombs.length; j++) {
if (bombs[j] === randomBomb) {
bombs[j].destroy();
bombs.splice(j, 1);
break;
}
}
}
}, itemDuration);
}
// Position the food at a new random location within the game, ensuring it does not appear on the border or overlap with other objects
do {
food.x = Math.random() * (2048 - food.width) + food.width / 2;
food.y = Math.random() * (2732 - food.height) + food.height / 2;
} while (
// Ensure food doesn't spawn at the border
(food.x < 100 || food.x > 1948) && (food.y < 100 || food.y > 2632) ||
// Ensure food doesn't overlap with other game objects
checkOverlap(food, bonusFood, 100) || checkOverlap(food, life, 100) || positionOverlapsAny(food.x, food.y, [rocks, bombs], 100));
// Set a timeout to remove food after the current item duration if not eaten
LK.setTimeout(function () {
// Only reposition if the food is still in the game (hasn't been eaten)
if (food && food.parent) {
// Position food offscreen
food.x = -100;
food.y = -100;
// Spawn new food
do {
food.x = Math.random() * (2048 - food.width) + food.width / 2;
food.y = Math.random() * (2732 - food.height) + food.height / 2;
} while (
// Ensure food doesn't spawn at the border
(food.x < 100 || food.x > 1948) && (food.y < 100 || food.y > 2632) ||
// Ensure food doesn't overlap with other game objects
checkOverlap(food, bonusFood, 100) || checkOverlap(food, life, 100) || positionOverlapsAny(food.x, food.y, [rocks, bombs], 100));
}
}, itemDuration);
// Play baby sound when food is eaten
LK.getSound('yiyecek').play();
}
// Check if the snake's head intersects with the bonus food
if (snake.intersects(bonusFood)) {
// Increase the score by 50
score += 50;
// Update the score text
scoreTxt.setText('Score: ' + score);
// Play the bonus food sound
LK.getSound('bonusfood').play();
// In level 2+, destroy the bonus food rather than just hiding it
if (level >= 2) {
// Create a replacement bonus food
bonusFood.destroy();
bonusFood = game.addChild(new BonusFood());
bonusFood.x = -100;
bonusFood.y = -100;
} else {
// Hide the bonus food
bonusFood.x = -100;
bonusFood.y = -100;
}
}
// Check if the snake's head intersects with the life
if (snake.intersects(life)) {
// Increase the lives by 1, up to a maximum of 8
if (lives < 8) {
lives += 1;
// Update the lives text
livesTxt.setText('Lives: ' + lives);
// Update health bar
updateHealthBar();
// Play the life sound
LK.getSound('life').play();
}
// In level 2+, destroy the life rather than just hiding it
if (level >= 2) {
// Create a replacement life
life.destroy();
life = game.addChild(new KOCAM());
life.x = -100;
life.y = -100;
} else {
// Hide the life
life.x = -100;
life.y = -100;
}
}
// Poison food item has been removed
// Check if the snake's head has moved out of the screen
if (snake.x < 0) {
snake.x = 2048;
} else if (snake.x > 2048) {
snake.x = 0;
} else if (snake.y < 0) {
snake.y = 2732;
} else if (snake.y > 2732) {
snake.y = 0;
}
// Check for collision with rocks
for (var r = 0; r < rocks.length; r++) {
if (snake.intersects(rocks[r])) {
// Play cat sound when snake hits rocks
LK.getSound('cat').play();
// Track if this is the first or second collision
if (!snake.rockCollision) {
// First collision - reduce health by 70
snake.rockCollision = true;
health -= 70;
// Ensure health doesn't go below 0
if (health < 0) health = 0;
// Update the health bar
updateHealthBar();
// Flash screen red for visual feedback
LK.effects.flashScreen(0xFF0000, 300);
// Push snake back a bit from the rock
if (snake.direction === 'up') {
snake.y += 50;
} else if (snake.direction === 'down') {
snake.y -= 50;
} else if (snake.direction === 'left') {
snake.x += 50;
} else if (snake.direction === 'right') {
snake.x -= 50;
}
// Make the rock disappear
rocks[r].destroy();
rocks.splice(r, 1);
} else {
// Second collision - snake dies
// Stop any currently playing music
LK.stopMusic();
// Play game over music that will continue until player presses Play Again
LK.playMusic('gameOverMusic');
// Flash screen red for visual feedback
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
}
break;
}
}
// Check for collision with bombs
for (var b = 0; b < bombs.length; b++) {
if (snake.intersects(bombs[b])) {
// Increase damage - decrease health by 30 for bomb collision (up from 20)
health -= 30;
// Ensure health doesn't go below 0
if (health < 0) health = 0;
// Update health bar
updateHealthBar();
// Flash screen red for visual feedback with longer duration
LK.effects.flashScreen(0xFF0000, 300);
// Play the poison sound
LK.getSound('poison').play();
// Make bomb explosion effect
LK.effects.flashObject(bombs[b], 0xFF0000, 200);
// Remove the bomb after collision
bombs[b].destroy();
bombs.splice(b, 1);
// Check if health has hit 0
if (health === 0) {
// Stop any currently playing music
LK.stopMusic();
// Play game over music that will continue until player presses Play Again
LK.playMusic('gameOverMusic');
// Show game over screen
LK.showGameOver();
}
break;
}
}
};
// Initialize lives, score, food consumed
var lives = 3;
var score = 0;
var previousScore = 0;
var previousBombScore = 0;
var foodConsumed = 0;
var normalFoodCount = 0; // Initialize normalFoodCount
var poisonToSpawn = 0; // Initialize poisonToSpawn
var starTrails = [];
var rocks = []; // Array to hold rock obstacles
var bombs = []; // Array to hold bomb obstacles
var messageDisplayed = false; // Flag to track if "I love you" message has been displayed
// Variables to track bomb spawning at different score thresholds
var bombsSpawned200 = false;
var bombsSpawned300 = false;
var bombsSpawned400 = false;
var lastBombSpawnTime = 0; // Track when bombs were last spawned
// Level system variables - level increases every 500 points
var level = 1;
var lastLevelUpScore = 0;
var isLevelingUp = false;
var baseItemDuration = 7000; // Base duration for items in milliseconds
var itemDuration = baseItemDuration; // Current duration for items, will increase with level
var foodSpawnCount = 1; // Number of food items to spawn
// Level 2+ difficulty variables
var bombSpeed = 0; // Speed at which bombs move
var enableMovingBombs = false; // Whether bombs should move
var enableFoodTeleport = false; // Whether food should teleport
var rockSpawnRate = 0.002; // Base rate for spawning rocks
var lastFoodTeleportTime = 0; // Track when food last teleported
// Function to check if two objects overlap
function checkOverlap(obj1, obj2, minDistance) {
if (!obj1 || !obj2) return false;
var dx = Math.abs(obj1.x - obj2.x);
var dy = Math.abs(obj1.y - obj2.y);
return dx < minDistance && dy < minDistance;
}
// Function to check if a position overlaps with any objects in arrays
function positionOverlapsAny(x, y, objectArrays, minDistance) {
for (var i = 0; i < objectArrays.length; i++) {
var array = objectArrays[i];
if (!array) continue;
for (var j = 0; j < array.length; j++) {
var obj = array[j];
if (!obj) continue;
var dx = Math.abs(x - obj.x);
var dy = Math.abs(y - obj.y);
if (dx < minDistance && dy < minDistance) {
return true;
}
}
}
return false;
}
// Create lives text
var livesTxt = new Text2('Lives: ' + lives, {
size: 32,
fill: 0xFFFFFF
});
livesTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(livesTxt);
// Create score text
var scoreTxt = new Text2('Score: ' + score, {
size: 32,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create level text
var levelTxt = new Text2('Level: ' + level, {
size: 32,
fill: 0xFFFFFF
});
levelTxt.anchor.set(1, 0);
levelTxt.x = -10; // Offset from right edge
LK.gui.topRight.addChild(levelTxt);
// Initialize health
var health = 200;
// Create and position health bar
var healthBar = game.addChild(new HealthBar());
healthBar.x = 2048 / 2;
healthBar.y = 50;
// Function to update health bar
function updateHealthBar() {
healthBar.updateHealth(health);
}
// Function to calculate bomb spawn probability based on score
function getBombSpawnProbability() {
// Start with a very low probability
if (score < 100) {
return 0.001; // 0.1% chance
} else if (score < 200) {
return 0.003; // 0.3% chance
} else if (score < 300) {
return 0.005; // 0.5% chance
} else if (score < 400) {
return 0.007; // 0.7% chance
} else {
return 0.01; // 1% chance - same as original
}
}
// Function to spawn multiple food items based on the current level
function spawnMultipleFood() {
// We always keep the main food item
// Spawn additional food items based on level
for (var i = 0; i < foodSpawnCount - 1; i++) {
// Create additional food item
var additionalFood = new Food();
// Position at random location that doesn't overlap with other objects
do {
additionalFood.x = Math.random() * (2048 - additionalFood.width) + additionalFood.width / 2;
additionalFood.y = Math.random() * (2732 - additionalFood.height) + additionalFood.height / 2;
} while (
// Ensure food doesn't spawn at the border
(additionalFood.x < 100 || additionalFood.x > 1948) && (additionalFood.y < 100 || additionalFood.y > 2632) ||
// Ensure food doesn't overlap with other game objects
checkOverlap(additionalFood, food, 100) || checkOverlap(additionalFood, bonusFood, 100) || checkOverlap(additionalFood, life, 100) || positionOverlapsAny(additionalFood.x, additionalFood.y, [rocks, bombs], 100));
// Add food to game
game.addChild(additionalFood);
// Set timeout to remove food after the current item duration
LK.setTimeout(function () {
if (additionalFood && additionalFood.parent) {
additionalFood.destroy();
}
}, itemDuration);
}
}
// Function to update level text
function updateLevelText() {
levelTxt.setText('Level: ' + level);
}
// Initialize health bar display
updateHealthBar();
// Initialize level text
updateLevelText();
game.down = function (x, y, obj) {
if (game.paused) {
return;
}
// Change the snake's direction to always move in the direction of the front area of the snake head which is not connected to the snake body
if (x > snake.x && snake.direction !== 'left' && snake.direction !== 'right') {
snake.moveHead('right');
} else if (x < snake.x && snake.direction !== 'right' && snake.direction !== 'left') {
snake.moveHead('left');
} else if (y > snake.y && snake.direction !== 'up' && snake.direction !== 'down') {
snake.moveHead('down');
} else if (y < snake.y && snake.direction !== 'down' && snake.direction !== 'up') {
snake.moveHead('up');
}
};
Pause icon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
havuç. In-Game asset. 2d. High contrast. No shadows
çilek. In-Game asset. 2d. High contrast. No shadows
boynuna bir kurdele ve eline de uçan bir balon
böğürtlen ormanı. In-Game asset. 2d. High contrast. No shadows
taş. In-Game asset. 2d. High contrast. No shadows
mesaj kutusu. In-Game asset. 2d. High contrast. No shadows