User prompt
Yeni oluşturulan arka plan boyutu diger arkaplan boyutunun 4/1 ölçeğinde ve üst kısıma sabit
User prompt
Arkaplan için yeni bir katman ekle
User prompt
Zemini incelt
User prompt
Zemim varlıgını biraz incelt
User prompt
Zemini olabildigince incelt
User prompt
Bir zemin oluştur
User prompt
Arkaplan için resim varlıgı ekle
User prompt
Arka plan rengini degiştirebilmem için resim varlıgı ekle
User prompt
Bu alanda heryere gidebilen bir oyuncu ekle resim varlıklarıda ekle
User prompt
Arkaplan için varlık için resim varlıgı oluştur
User prompt
Oyındaki herşeyi sil ve sadece kahve rengi bir arkaplan istiyorum
Code edit (1 edits merged)
Please save this source code
User prompt
Toprak Saga - Soil Builder
Initial prompt
Toprak bir alan oluştur
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Enemy = Container.expand(function () { var self = Container.call(this); // Create enemy visual using enemy image asset var enemyBody = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 4.0 }); // Create left leg var leftLeg = self.attachAsset('enemyLeg', { anchorX: 0.5, anchorY: 0, x: -80, y: 200 }); // Create right leg var rightLeg = self.attachAsset('enemyLeg', { anchorX: 0.5, anchorY: 0, x: 160, y: 200 }); // Create right hand var rightHand = self.attachAsset('enemyRightHand', { anchorX: 0.5, anchorY: 0.5, x: 140, y: -20, scaleX: 1.5, scaleY: 1.5 }); // Create left hand var leftHand = self.attachAsset('enemyLeftHand', { anchorX: 0.5, anchorY: 0.5, x: -70, y: -70, scaleX: 1.5, scaleY: 1.5 }); // Initialize animation timer for other effects self.animationTimer = 0; // Create enemy eyes var leftEnemyEye = self.attachAsset('eyeWhite', { anchorX: 0.5, anchorY: 0.5, x: 48, y: -150, scaleX: 0.4, scaleY: 0.4 }); var rightEnemyEye = self.attachAsset('eyeWhite', { anchorX: 0.5, anchorY: 0.5, x: 108, y: -150, scaleX: 0.4, scaleY: 0.4 }); // Create black pupils inside the enemy white eyes var leftEnemyPupil = self.attachAsset('eye', { anchorX: 0.5, anchorY: 0.5, x: 48, y: -150, scaleX: 0.6, scaleY: 0.6 }); var rightEnemyPupil = self.attachAsset('eye', { anchorX: 0.5, anchorY: 0.5, x: 108, y: -150, scaleX: 0.6, scaleY: 0.6 }); // Create enemy mouth var enemyMouth = self.attachAsset('enemyMouthImage', { anchorX: 0.5, anchorY: 0.5, x: 78, y: -100, scaleX: 1.2, scaleY: 1.2, visible: false // Initially hidden }); self.speed = 3; self.baseSpeed = 3; // Store original speed self.direction = 1; self.shootTimer = 0; self.speedChangeTimer = 0; // Timer for speed variations self.shootInterval = 30; // Shoot every 0.5 seconds at 60fps (increased spawn rate) self.walkAnimationTimer = 0; self.isFrozen = false; // Track if enemy is frozen after hitting player with second projectile self.freezeTimer = 0; // Timer for freeze duration self.update = function () { // Handle frozen state if (self.isFrozen) { self.freezeTimer--; if (self.freezeTimer <= 0) { self.isFrozen = false; } return; // Skip all movement and shooting when frozen } // Move horizontally self.x += self.speed * self.direction; // Bounce at screen edges if (self.x <= 100 || self.x >= 1948) { self.direction *= -1; } // Random direction change system - enemy can change direction at any time if (Math.random() < 0.008) { // 0.8% chance per frame to change direction self.direction *= -1; // Reverse current direction } // Random speed variation system self.speedChangeTimer++; if (self.speedChangeTimer >= 120) { // Every 2 seconds at 60fps self.speedChangeTimer = 0; // Randomly vary speed between 2 and 5 self.speed = self.baseSpeed + (Math.random() - 0.5) * 2; if (self.speed < 1) self.speed = 1; // Minimum speed if (self.speed > 6) self.speed = 6; // Maximum speed } // Walking animation - alternate leg positions self.walkAnimationTimer++; if (self.walkAnimationTimer >= 15) { // Change leg position every 15 frames self.walkAnimationTimer = 0; // Animate left leg with walking motion (horizontal and vertical) tween(leftLeg, { x: leftLeg.x === -80 ? -100 : -80, y: leftLeg.y === 200 ? 180 : 200 }, { duration: 200, easing: tween.easeInOut }); // Animate right leg with walking motion (opposite to left leg) tween(rightLeg, { x: rightLeg.x === 160 ? 180 : 160, y: rightLeg.y === 200 ? 180 : 200 }, { duration: 200, easing: tween.easeInOut }); } // Update enemy pupils to track player if (player) { // Calculate angle from enemy pupils to player var leftEyeCenterX = self.x + 48; var leftEyeCenterY = self.y - 150; var rightEyeCenterX = self.x + 108; var rightEyeCenterY = self.y - 150; // Maximum distance pupils can move from center var maxPupilDistance = 8; // Calculate angles from eye centers to player var leftAngle = Math.atan2(player.y - leftEyeCenterY, player.x - leftEyeCenterX); var rightAngle = Math.atan2(player.y - rightEyeCenterY, player.x - rightEyeCenterX); // Position pupils to track player within eye boundaries leftEnemyPupil.x = 48 + Math.cos(leftAngle) * maxPupilDistance; leftEnemyPupil.y = -150 + Math.sin(leftAngle) * maxPupilDistance; rightEnemyPupil.x = 108 + Math.cos(rightAngle) * maxPupilDistance; rightEnemyPupil.y = -150 + Math.sin(rightAngle) * maxPupilDistance; } // General animation timer for other effects self.animationTimer++; if (self.animationTimer >= 5) { self.animationTimer = 0; } // Shooting logic self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shootTimer = 0; // Randomly choose projectile type with increased probability for second projectile if (Math.random() > 0.4) { // Create regular projectile var projectile = new EnemyProjectile(); projectile.x = self.x; projectile.y = self.y + 50; enemyProjectiles.push(projectile); game.addChild(projectile); } else { // Only create EnemyProjectile2 if there are less than 4 on screen if (enemyProjectiles2.length < 4) { // Create new projectile type from right arm area var projectile2 = new EnemyProjectile2(); projectile2.x = self.x + 140; // Position at right arm/hand area projectile2.y = self.y + 50; enemyProjectiles2.push(projectile2); game.addChild(projectile2); } } // Play enemy shooting sound LK.getSound('enemyShoot').play(); } }; // Method to show mouth when player is hit by second projectile self.showMouth = function () { enemyMouth.visible = true; // Play enemy mouth sound LK.getSound('enemyMouthSound').play(); // Hide mouth after 4 seconds using tween tween(enemyMouth, { alpha: 0 }, { duration: 4000, easing: tween.easeOut, onFinish: function onFinish() { enemyMouth.visible = false; enemyMouth.alpha = 1; // Reset alpha for next time } }); }; // Method to freeze enemy when player is hit by second projectile self.freezeEnemy = function () { self.isFrozen = true; self.freezeTimer = shieldDuration; // Freeze for same duration as shield (240 frames = 4 seconds) // Play enemy laughing sound when frozen LK.getSound('enemyLaugh').play(); // Add shaking animation while laughing tween(self, { x: self.x + 10 }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: self.x - 20 }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: self.x + 10 }, { duration: 150, easing: tween.easeInOut }); } }); } }); }; return self; }); var EnemyProjectile = Container.expand(function () { var self = Container.call(this); var projectileBody = self.attachAsset('enemyProjectile', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 6; self.update = function () { self.y += self.speed * gameSpeedMultiplier; }; return self; }); var EnemyProjectile2 = Container.expand(function () { var self = Container.call(this); var projectileBody = self.attachAsset('enemyProjectile2', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.speed = 4; self.sideSpeed = 2; self.direction = Math.random() > 0.5 ? 1 : -1; self.effectTimer = 0; self.update = function () { self.y += self.speed * gameSpeedMultiplier; self.x += self.sideSpeed * self.direction * gameSpeedMultiplier; // Bounce off screen edges if (self.x <= 0 || self.x >= 2048) { self.direction *= -1; } // Create flame and smoke effects self.effectTimer++; if (self.effectTimer >= 5) { self.effectTimer = 0; // Create flame particles if (Math.random() < 0.03) { var flameParticle = game.attachAsset('flame', { anchorX: 0.5, anchorY: 0.5, x: self.x + 35 + (Math.random() - 0.5) * 30, y: self.y - 50 + (Math.random() - 0.5) * 20, scaleX: 0.5 + Math.random() * 0.3, scaleY: 0.5 + Math.random() * 0.3, alpha: 0.8 + Math.random() * 0.2 }); // Animate flame trailing behind projectile tween(flameParticle, { y: flameParticle.y + 40 + Math.random() * 30, x: flameParticle.x + (Math.random() - 0.5) * 20, alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 300 + Math.random() * 200, easing: tween.easeOut, onFinish: function onFinish() { flameParticle.destroy(); } }); } // Create smoke particles if (Math.random() < 0.02) { var smokeParticle = game.attachAsset('smoke', { anchorX: 0.5, anchorY: 0.5, x: self.x + (Math.random() - 0.5) * 25, y: self.y + (Math.random() - 0.5) * 15, scaleX: 0.3 + Math.random() * 0.2, scaleY: 0.3 + Math.random() * 0.2, alpha: 0.6 }); // Animate smoke trailing and dispersing tween(smokeParticle, { y: smokeParticle.y + 50 + Math.random() * 25, x: smokeParticle.x + (Math.random() - 0.5) * 15, alpha: 0, scaleX: 0.8 + Math.random() * 0.4, scaleY: 0.8 + Math.random() * 0.4 }, { duration: 400 + Math.random() * 300, easing: tween.easeOut, onFinish: function onFinish() { smokeParticle.destroy(); } }); } // Create additional particle effects if (Math.random() < 0.01) { var projectileParticle = new Particle(); projectileParticle.x = self.x + (Math.random() - 0.5) * 40; projectileParticle.y = self.y - 10 + (Math.random() - 0.5) * 15; projectileParticle.velocityX = (Math.random() - 0.5) * 6; projectileParticle.velocityY = -Math.random() * 4 - 2; particles.push(projectileParticle); game.addChild(projectileParticle); } } }; return self; }); var Particle = Container.expand(function () { var self = Container.call(this); // Choose random particle color/type var particleTypes = ['redParticle', 'orangeParticle', 'yellowParticle', 'whiteParticle', 'smoke']; var randomType = particleTypes[Math.floor(Math.random() * particleTypes.length)]; var particleBody = self.attachAsset(randomType, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3 + Math.random() * 0.6, scaleY: 0.3 + Math.random() * 0.6 }); // Random particle properties self.velocityX = (Math.random() - 0.5) * 8; self.velocityY = -Math.random() * 6 - 2; self.gravity = 0.2; self.life = 90 + Math.random() * 60; // 1.5-2.5 seconds at 60fps self.maxLife = self.life; self.update = function () { // Apply physics self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; // Fade out over time self.life--; self.alpha = self.life / self.maxLife; // Remove when life is over or off screen if (self.life <= 0 || self.y > 2732 + 100 || self.y < -100 || self.x < -100 || self.x > 2148) { self.destroy(); // Remove from particles array for (var p = particles.length - 1; p >= 0; p--) { if (particles[p] === self) { particles.splice(p, 1); break; } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x8B4513 }); /**** * Game Code ****/ var backgroundImage = game.attachAsset('background', { x: 0, y: 0, width: 2048, height: 2732 }); // Add new background layer var backgroundLayer = game.attachAsset('backgroundLayer', { x: 0, y: 0, width: 2100, height: 700 }); // Create ground terrain var ground = game.attachAsset('ground', { x: 0, y: 2682, // Position at bottom (2732 - 50 = 2682) width: 2048, height: 50 }); // Create and position player on the ground var player = game.attachAsset('player', { x: 2048 / 2, // Center horizontally y: 2682, // Position touching the ground scaleX: 1.0, scaleY: 1.0, anchorX: 0.5, anchorY: 1.0 }); // Scale player to 3.0 using tween animation tween(player, { scaleX: 3.0, scaleY: 3.0 }, { duration: 500, easing: tween.easeOut }); // Create white eyes on the player var leftEye = game.attachAsset('eyeWhite', { x: player.x - 50, y: player.y - 245, anchorX: 0.5, anchorY: 0.5 }); var rightEye = game.attachAsset('eyeWhite', { x: player.x + 10, y: player.y - 245, anchorX: 0.5, anchorY: 0.5 }); // Create black pupils inside the white eyes var leftPupil = game.attachAsset('eye', { x: player.x - 50, y: player.y - 245, anchorX: 0.5, anchorY: 0.5 }); var rightPupil = game.attachAsset('eye', { x: player.x + 10, y: player.y - 245, anchorX: 0.5, anchorY: 0.5 }); // Create player feet var leftFoot = game.attachAsset('playerLeftFoot', { x: player.x - 80, y: player.y + 10, anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); var rightFoot = game.attachAsset('playerRightFoot', { x: player.x + 80, y: player.y + 10, anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); // Create player right hand var playerRightHand = game.attachAsset('playerRightHand', { x: player.x + 120, y: player.y - 120, anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); // Variables for player movement var playerSpeed = 12; var targetX = player.x; var isMoving = false; var playerLives = 3; var isShielded = false; var shieldTimer = 0; var shieldDuration = 240; // 4 seconds at 60fps var isFlying = false; // Track if player is currently flying after being hit var shieldBubble = null; // Shield bubble visual element var walkAnimationTimer = 0; // Timer for walking animation // Game speed system var gameSpeedMultiplier = 1.0; var speedIncreaseTimer = 0; var speedIncreaseInterval = 600; // Increase speed every 10 seconds at 60fps // Create life hearts on the left side var lifeHearts = []; for (var h = 0; h < 3; h++) { // Create heart using image asset var heartImage = game.attachAsset('lifeHeartImage', { x: 150 + h * 100, y: 750, anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }); lifeHearts.push(heartImage); } // Create score display var scoreText = new Text2('PUAN: 0', { size: 120, fill: 0xFFFFFF, font: "'Montserrat', 'Open Sans', 'Lato', 'Source Sans Pro', 'Ubuntu', sans-serif" }); scoreText.anchor.set(0.5, 0); scoreText.x = 2048 / 2; scoreText.y = 850; game.addChild(scoreText); // Enemy and projectile tracking var enemy = null; var enemyProjectiles = []; var enemyProjectiles2 = []; var particles = []; // Create enemy at top of screen enemy = game.addChild(new Enemy()); enemy.x = 1124; // Move slightly to the right enemy.y = 450; // Moved up from previous position // Touch/mouse controls for player movement game.down = function (x, y, obj) { // Set target position to touch/click location targetX = x; isMoving = true; // Keep player within screen bounds if (targetX < 0) targetX = 0; if (targetX > 2048) targetX = 2048; }; // Update player movement game.update = function () { // Update game speed system speedIncreaseTimer++; if (speedIncreaseTimer >= speedIncreaseInterval) { speedIncreaseTimer = 0; gameSpeedMultiplier += 0.1; // Increase speed by 10% every 10 seconds // Cap maximum speed at 3x original speed if (gameSpeedMultiplier > 3.0) { gameSpeedMultiplier = 3.0; } } if (isMoving) { // Calculate distance to target var distance = targetX - player.x; // Move towards target if (Math.abs(distance) > 5) { if (distance > 0) { player.x += playerSpeed; } else { player.x -= playerSpeed; } // Animate walking - move feet up and down alternately walkAnimationTimer++; if (walkAnimationTimer >= 10) { walkAnimationTimer = 0; // Animate left foot up and down tween(leftFoot, { y: leftFoot.y === player.y + 10 ? player.y - 10 : player.y + 10 }, { duration: 150, easing: tween.easeInOut }); // Animate right foot up and down (opposite to left foot) tween(rightFoot, { y: rightFoot.y === player.y + 10 ? player.y - 10 : player.y + 10 }, { duration: 150, easing: tween.easeInOut }); } } else { // Snap to target when close enough player.x = targetX; isMoving = false; } // Keep player within bounds if (player.x < 0) player.x = 0; if (player.x > 2048) player.x = 2048; } // Update feet positions to follow player leftFoot.x = player.x - 80; rightFoot.x = player.x + 80; // Update right hand position to follow player playerRightHand.x = player.x + 120; playerRightHand.y = player.y - 120; // Reset feet position when not moving if (!isMoving) { leftFoot.y = player.y + 10; rightFoot.y = player.y + 10; } // Update shield system if (isShielded) { shieldTimer--; // Hide player right hand when shield is active playerRightHand.visible = false; // Show shield bubble if not already visible if (!shieldBubble) { shieldBubble = game.attachAsset('shieldBubble', { x: player.x, y: player.y - 150, anchorX: 0.5, anchorY: 0.5, alpha: 0.1, tint: 0xffffff }); // Add pulsing animation to shield bubble tween(shieldBubble, { scaleX: 1.1, scaleY: 1.1, alpha: 0.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { if (shieldBubble) { tween(shieldBubble, { scaleX: 1.0, scaleY: 1.0, alpha: 0.05 }, { duration: 500, easing: tween.easeInOut }); } } }); } // Update shield bubble position to follow player if (shieldBubble) { shieldBubble.x = player.x; shieldBubble.y = player.y - 150; } // Flash player blue to indicate shield if (shieldTimer % 20 < 10) { player.tint = 0x00ffff; } else { player.tint = 0xffffff; } // Deactivate shield when timer expires if (shieldTimer <= 0) { isShielded = false; player.tint = 0xffffff; // Show player right hand when shield is deactivated playerRightHand.visible = true; // Stop pupil spinning and reset rotation tween.stop(leftPupil, { rotation: true }); tween.stop(rightPupil, { rotation: true }); leftPupil.rotation = 0; rightPupil.rotation = 0; // Remove shield bubble if (shieldBubble) { shieldBubble.destroy(); shieldBubble = null; } // Clear shield sound interval if (game.shieldSoundInterval) { LK.clearInterval(game.shieldSoundInterval); game.shieldSoundInterval = null; } } } // Update eye positions to follow player leftEye.x = player.x - 50; leftEye.y = player.y - 245; rightEye.x = player.x + 10; rightEye.y = player.y - 245; // Keep pupils centered when not shielded, but track falling projectiles if (!isShielded) { // Default pupil positions (eye centers) var leftEyeCenterX = player.x - 50; var leftEyeCenterY = player.y - 245; var rightEyeCenterX = player.x + 10; var rightEyeCenterY = player.y - 245; // Maximum distance pupils can move from center var maxPupilDistance = 8; // Find closest falling projectile to track var closestProjectile = null; var closestDistance = Infinity; // Check all enemy projectiles for (var p = 0; p < enemyProjectiles.length; p++) { var proj = enemyProjectiles[p]; var distance = Math.sqrt(Math.pow(proj.x - player.x, 2) + Math.pow(proj.y - player.y, 2)); if (distance < closestDistance) { closestDistance = distance; closestProjectile = proj; } } // Check all enemy projectiles type 2 for (var p2 = 0; p2 < enemyProjectiles2.length; p2++) { var proj2 = enemyProjectiles2[p2]; var distance2 = Math.sqrt(Math.pow(proj2.x - player.x, 2) + Math.pow(proj2.y - player.y, 2)); if (distance2 < closestDistance) { closestDistance = distance2; closestProjectile = proj2; } } if (closestProjectile) { // Calculate angles from eye centers to the closest projectile var leftAngle = Math.atan2(closestProjectile.y - leftEyeCenterY, closestProjectile.x - leftEyeCenterX); var rightAngle = Math.atan2(closestProjectile.y - rightEyeCenterY, closestProjectile.x - rightEyeCenterX); // Position pupils within eye boundaries, tracking the projectile leftPupil.x = leftEyeCenterX + Math.cos(leftAngle) * maxPupilDistance; leftPupil.y = leftEyeCenterY + Math.sin(leftAngle) * maxPupilDistance; rightPupil.x = rightEyeCenterX + Math.cos(rightAngle) * maxPupilDistance; rightPupil.y = rightEyeCenterY + Math.sin(rightAngle) * maxPupilDistance; } else { // No projectiles to track, center pupils leftPupil.x = leftEyeCenterX; leftPupil.y = leftEyeCenterY; rightPupil.x = rightEyeCenterX; rightPupil.y = rightEyeCenterY; } } else { // When shield is active, make pupils move diagonally (down-left and diagonally) var leftEyeCenterX = player.x - 50; var leftEyeCenterY = player.y - 245; var rightEyeCenterX = player.x + 10; var rightEyeCenterY = player.y - 245; var maxBounceDistance = 12; // Use diagonal movement patterns based on time var bounceTime = LK.ticks * 0.12; // Create diagonal movements: down-left and cross-diagonal var bounceX = Math.sin(bounceTime) * maxBounceDistance; var bounceY = Math.cos(bounceTime * 0.8) * (maxBounceDistance * 0.7); // Position pupils with diagonal movement patterns leftPupil.x = leftEyeCenterX + bounceX; leftPupil.y = leftEyeCenterY + bounceY; rightPupil.x = rightEyeCenterX - bounceX; // Opposite X movement for variety rightPupil.y = rightEyeCenterY + bounceY; } // Update enemy projectiles for (var i = enemyProjectiles.length - 1; i >= 0; i--) { var projectile = enemyProjectiles[i]; // Remove projectiles that go off screen (any direction) if (projectile.y > 2732 + 100 || projectile.y < -100 || projectile.x < -100 || projectile.x > 2148) { projectile.destroy(); enemyProjectiles.splice(i, 1); continue; } // Check collision with player if (projectile.intersects(player)) { // Check if player is protected by shield if (!isShielded) { // Award points when hit by enemy projectile LK.setScore(LK.getScore() + 10); // Update score display scoreText.setText('PUAN: ' + LK.getScore()); // Play sound effect for first projectile hit LK.getSound('enemyProjectileHit').play(); // Create reduced particle burst effect at player's mouth area for (var particleCount = 0; particleCount < 1; particleCount++) { var particle = new Particle(); particle.x = player.x + (Math.random() - 0.5) * 40; particle.y = player.y - 130 + (Math.random() - 0.5) * 30; // Position higher up from mouth area // Reduce particle velocity for better performance particle.velocityX = (Math.random() - 0.5) * 10; particle.velocityY = -Math.random() * 8 - 3; particles.push(particle); game.addChild(particle); } // Simplified mouth trembling effect tween(player, { scaleX: 3.2, scaleY: 2.8 }, { duration: 150, easing: tween.easeInOut, onFinish: function onFinish() { tween(player, { scaleX: 3.0, scaleY: 3.0 }, { duration: 150, easing: tween.easeOut }); } }); } projectile.destroy(); enemyProjectiles.splice(i, 1); } } // Update enemy projectiles type 2 for (var j = enemyProjectiles2.length - 1; j >= 0; j--) { var projectile2 = enemyProjectiles2[j]; // Remove projectiles that go off screen (any direction) if (projectile2.y > 2732 + 100 || projectile2.y < -100 || projectile2.x < -100 || projectile2.x > 2148) { projectile2.destroy(); enemyProjectiles2.splice(j, 1); continue; } // Check collision with player if (projectile2.intersects(player) && !isShielded && !isFlying) { // Show enemy mouth when hit by second projectile enemy.showMouth(); // Freeze enemy movement and shooting enemy.freezeEnemy(); // Play sound effect for second projectile hit LK.getSound('enemyProjectile2Hit').play(); // Stop current player movement isMoving = false; // Set flying state to true isFlying = true; // Player flies off screen to the left while spinning tween(player, { x: -200, y: player.y - 800, rotation: Math.PI * 4 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Return player from right side after flying off player.x = 2248; player.y = 2682; player.rotation = 0; // Reset flying state isFlying = false; // Activate shield protection isShielded = true; shieldTimer = shieldDuration; // Play shield activation sound LK.getSound('shieldSound').play(); // Set up repeating shield sound during shield duration var shieldSoundInterval = LK.setInterval(function () { if (isShielded && shieldTimer > 0) { LK.getSound('shieldSound').play(); } }, 1750); // Play every 1750ms // Store interval reference for cleanup game.shieldSoundInterval = shieldSoundInterval; // Shield bubble will be created in the shield update section // Animate player returning to screen tween(player, { x: 2048 / 2 }, { duration: 800, easing: tween.easeOut }); } }); // Update feet positions during flight animation tween(leftFoot, { x: -330, y: player.y - 790 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { leftFoot.x = 2168; leftFoot.y = 2692; tween(leftFoot, { x: 2048 / 2 - 80 }, { duration: 800, easing: tween.easeOut }); } }); tween(rightFoot, { x: -120, y: player.y - 790 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { rightFoot.x = 2128; rightFoot.y = 2692; tween(rightFoot, { x: 2048 / 2 + 80 }, { duration: 800, easing: tween.easeOut }); } }); // Update eye positions during flight animation tween(leftEye, { x: -250, y: player.y - 1045 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { leftEye.x = 2198; leftEye.y = 2437; tween(leftEye, { x: 2048 / 2 - 50 }, { duration: 800, easing: tween.easeOut }); } }); tween(rightEye, { x: -190, y: player.y - 1045 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { rightEye.x = 2258; rightEye.y = 2437; tween(rightEye, { x: 2048 / 2 + 10 }, { duration: 800, easing: tween.easeOut }); } }); tween(leftPupil, { x: -250, y: player.y - 1045 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { leftPupil.x = 2198; leftPupil.y = 2437; tween(leftPupil, { x: 2048 / 2 - 50 }, { duration: 800, easing: tween.easeOut }); } }); tween(rightPupil, { x: -190, y: player.y - 1045 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { rightPupil.x = 2258; rightPupil.y = 2437; tween(rightPupil, { x: 2048 / 2 + 10 }, { duration: 800, easing: tween.easeOut }); } }); // Update right hand position during flight animation tween(playerRightHand, { x: -80, y: player.y - 920 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { playerRightHand.x = 2368; playerRightHand.y = 2562; tween(playerRightHand, { x: 2048 / 2 + 120 }, { duration: 800, easing: tween.easeOut }); } }); // Create particle burst effect for (var particleCount = 0; particleCount < 5; particleCount++) { var particle = new Particle(); particle.x = player.x + (Math.random() - 0.5) * 80; particle.y = player.y - 50 + (Math.random() - 0.5) * 70; // Give particles more dramatic velocities for this bigger explosion particle.velocityX = (Math.random() - 0.5) * 18; particle.velocityY = -Math.random() * 12 - 4; particles.push(particle); game.addChild(particle); } // Create smoke and flame effects for (var smokeCount = 0; smokeCount < 2; smokeCount++) { var smoke = game.attachAsset('smoke', { x: player.x + (Math.random() - 0.5) * 200, y: player.y - 100 + (Math.random() - 0.5) * 100, anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); // Animate smoke rising and fading tween(smoke, { y: smoke.y - 200 - Math.random() * 100, alpha: 0, scaleX: 2 + Math.random(), scaleY: 2 + Math.random() }, { duration: 2000 + Math.random() * 1000, easing: tween.easeOut, onFinish: function onFinish() { smoke.destroy(); } }); } for (var flameCount = 0; flameCount < 1; flameCount++) { var flame = game.attachAsset('flame', { x: player.x + (Math.random() - 0.5) * 150, y: player.y - 50 + (Math.random() - 0.5) * 80, anchorX: 0.5, anchorY: 0.5, alpha: 1 }); // Animate flames flickering and rising tween(flame, { y: flame.y - 150 - Math.random() * 50, alpha: 0, scaleX: 1.5 + Math.random() * 0.5, scaleY: 1.5 + Math.random() * 0.5 }, { duration: 1500 + Math.random() * 500, easing: tween.easeOut, onFinish: function onFinish() { flame.destroy(); } }); } // Create fire animation effect on player tween(player, { tint: 0xff4500 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(player, { tint: 0xff0000 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(player, { tint: 0xffffff }, { duration: 300, easing: tween.easeOut }); } }); } }); // Reduce player lives playerLives--; // Update heart visibility based on remaining lives for (var heartIndex = 0; heartIndex < lifeHearts.length; heartIndex++) { if (heartIndex >= playerLives) { // Hide heart with fade out animation tween(lifeHearts[heartIndex], { alpha: 0.2, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); } } if (playerLives <= 0) { // Show game over when no lives left LK.showGameOver(); } projectile2.destroy(); enemyProjectiles2.splice(j, 1); } } // Comprehensive cleanup system - remove all off-screen elements every frame var allChildren = game.children.slice(); // Create a copy to avoid modification during iteration var screenBuffer = 100; // Buffer zone around visible area for (var c = 0; c < allChildren.length; c++) { var child = allChildren[c]; // Skip essential game elements that should always stay if (child === player || child === enemy || child === backgroundImage || child === backgroundLayer || child === ground || child === scoreText || child === leftEye || child === rightEye || child === leftPupil || child === rightPupil || child === leftFoot || child === rightFoot || child === playerRightHand || child === shieldBubble) { continue; } // Skip life hearts var isLifeHeart = false; for (var h = 0; h < lifeHearts.length; h++) { if (child === lifeHearts[h]) { isLifeHeart = true; break; } } if (isLifeHeart) { continue; } // Remove if off screen in any direction with buffer zone if (child.x < -screenBuffer || child.x > 2048 + screenBuffer || child.y < -screenBuffer || child.y > 2732 + screenBuffer) { child.destroy(); } } // Clean up particle arrays - remove destroyed particles for (var p = particles.length - 1; p >= 0; p--) { if (!particles[p] || particles[p].destroyed) { particles.splice(p, 1); } } // Clean up projectile arrays - ensure no destroyed projectiles remain for (var ep = enemyProjectiles.length - 1; ep >= 0; ep--) { if (!enemyProjectiles[ep] || enemyProjectiles[ep].destroyed) { enemyProjectiles.splice(ep, 1); } } for (var ep2 = enemyProjectiles2.length - 1; ep2 >= 0; ep2--) { if (!enemyProjectiles2[ep2] || enemyProjectiles2[ep2].destroyed) { enemyProjectiles2.splice(ep2, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Create enemy visual using enemy image asset
var enemyBody = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 4.0
});
// Create left leg
var leftLeg = self.attachAsset('enemyLeg', {
anchorX: 0.5,
anchorY: 0,
x: -80,
y: 200
});
// Create right leg
var rightLeg = self.attachAsset('enemyLeg', {
anchorX: 0.5,
anchorY: 0,
x: 160,
y: 200
});
// Create right hand
var rightHand = self.attachAsset('enemyRightHand', {
anchorX: 0.5,
anchorY: 0.5,
x: 140,
y: -20,
scaleX: 1.5,
scaleY: 1.5
});
// Create left hand
var leftHand = self.attachAsset('enemyLeftHand', {
anchorX: 0.5,
anchorY: 0.5,
x: -70,
y: -70,
scaleX: 1.5,
scaleY: 1.5
});
// Initialize animation timer for other effects
self.animationTimer = 0;
// Create enemy eyes
var leftEnemyEye = self.attachAsset('eyeWhite', {
anchorX: 0.5,
anchorY: 0.5,
x: 48,
y: -150,
scaleX: 0.4,
scaleY: 0.4
});
var rightEnemyEye = self.attachAsset('eyeWhite', {
anchorX: 0.5,
anchorY: 0.5,
x: 108,
y: -150,
scaleX: 0.4,
scaleY: 0.4
});
// Create black pupils inside the enemy white eyes
var leftEnemyPupil = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5,
x: 48,
y: -150,
scaleX: 0.6,
scaleY: 0.6
});
var rightEnemyPupil = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5,
x: 108,
y: -150,
scaleX: 0.6,
scaleY: 0.6
});
// Create enemy mouth
var enemyMouth = self.attachAsset('enemyMouthImage', {
anchorX: 0.5,
anchorY: 0.5,
x: 78,
y: -100,
scaleX: 1.2,
scaleY: 1.2,
visible: false // Initially hidden
});
self.speed = 3;
self.baseSpeed = 3; // Store original speed
self.direction = 1;
self.shootTimer = 0;
self.speedChangeTimer = 0; // Timer for speed variations
self.shootInterval = 30; // Shoot every 0.5 seconds at 60fps (increased spawn rate)
self.walkAnimationTimer = 0;
self.isFrozen = false; // Track if enemy is frozen after hitting player with second projectile
self.freezeTimer = 0; // Timer for freeze duration
self.update = function () {
// Handle frozen state
if (self.isFrozen) {
self.freezeTimer--;
if (self.freezeTimer <= 0) {
self.isFrozen = false;
}
return; // Skip all movement and shooting when frozen
}
// Move horizontally
self.x += self.speed * self.direction;
// Bounce at screen edges
if (self.x <= 100 || self.x >= 1948) {
self.direction *= -1;
}
// Random direction change system - enemy can change direction at any time
if (Math.random() < 0.008) {
// 0.8% chance per frame to change direction
self.direction *= -1; // Reverse current direction
}
// Random speed variation system
self.speedChangeTimer++;
if (self.speedChangeTimer >= 120) {
// Every 2 seconds at 60fps
self.speedChangeTimer = 0;
// Randomly vary speed between 2 and 5
self.speed = self.baseSpeed + (Math.random() - 0.5) * 2;
if (self.speed < 1) self.speed = 1; // Minimum speed
if (self.speed > 6) self.speed = 6; // Maximum speed
}
// Walking animation - alternate leg positions
self.walkAnimationTimer++;
if (self.walkAnimationTimer >= 15) {
// Change leg position every 15 frames
self.walkAnimationTimer = 0;
// Animate left leg with walking motion (horizontal and vertical)
tween(leftLeg, {
x: leftLeg.x === -80 ? -100 : -80,
y: leftLeg.y === 200 ? 180 : 200
}, {
duration: 200,
easing: tween.easeInOut
});
// Animate right leg with walking motion (opposite to left leg)
tween(rightLeg, {
x: rightLeg.x === 160 ? 180 : 160,
y: rightLeg.y === 200 ? 180 : 200
}, {
duration: 200,
easing: tween.easeInOut
});
}
// Update enemy pupils to track player
if (player) {
// Calculate angle from enemy pupils to player
var leftEyeCenterX = self.x + 48;
var leftEyeCenterY = self.y - 150;
var rightEyeCenterX = self.x + 108;
var rightEyeCenterY = self.y - 150;
// Maximum distance pupils can move from center
var maxPupilDistance = 8;
// Calculate angles from eye centers to player
var leftAngle = Math.atan2(player.y - leftEyeCenterY, player.x - leftEyeCenterX);
var rightAngle = Math.atan2(player.y - rightEyeCenterY, player.x - rightEyeCenterX);
// Position pupils to track player within eye boundaries
leftEnemyPupil.x = 48 + Math.cos(leftAngle) * maxPupilDistance;
leftEnemyPupil.y = -150 + Math.sin(leftAngle) * maxPupilDistance;
rightEnemyPupil.x = 108 + Math.cos(rightAngle) * maxPupilDistance;
rightEnemyPupil.y = -150 + Math.sin(rightAngle) * maxPupilDistance;
}
// General animation timer for other effects
self.animationTimer++;
if (self.animationTimer >= 5) {
self.animationTimer = 0;
}
// Shooting logic
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
// Randomly choose projectile type with increased probability for second projectile
if (Math.random() > 0.4) {
// Create regular projectile
var projectile = new EnemyProjectile();
projectile.x = self.x;
projectile.y = self.y + 50;
enemyProjectiles.push(projectile);
game.addChild(projectile);
} else {
// Only create EnemyProjectile2 if there are less than 4 on screen
if (enemyProjectiles2.length < 4) {
// Create new projectile type from right arm area
var projectile2 = new EnemyProjectile2();
projectile2.x = self.x + 140; // Position at right arm/hand area
projectile2.y = self.y + 50;
enemyProjectiles2.push(projectile2);
game.addChild(projectile2);
}
}
// Play enemy shooting sound
LK.getSound('enemyShoot').play();
}
};
// Method to show mouth when player is hit by second projectile
self.showMouth = function () {
enemyMouth.visible = true;
// Play enemy mouth sound
LK.getSound('enemyMouthSound').play();
// Hide mouth after 4 seconds using tween
tween(enemyMouth, {
alpha: 0
}, {
duration: 4000,
easing: tween.easeOut,
onFinish: function onFinish() {
enemyMouth.visible = false;
enemyMouth.alpha = 1; // Reset alpha for next time
}
});
};
// Method to freeze enemy when player is hit by second projectile
self.freezeEnemy = function () {
self.isFrozen = true;
self.freezeTimer = shieldDuration; // Freeze for same duration as shield (240 frames = 4 seconds)
// Play enemy laughing sound when frozen
LK.getSound('enemyLaugh').play();
// Add shaking animation while laughing
tween(self, {
x: self.x + 10
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: self.x - 20
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: self.x + 10
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
}
});
};
return self;
});
var EnemyProjectile = Container.expand(function () {
var self = Container.call(this);
var projectileBody = self.attachAsset('enemyProjectile', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 6;
self.update = function () {
self.y += self.speed * gameSpeedMultiplier;
};
return self;
});
var EnemyProjectile2 = Container.expand(function () {
var self = Container.call(this);
var projectileBody = self.attachAsset('enemyProjectile2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.speed = 4;
self.sideSpeed = 2;
self.direction = Math.random() > 0.5 ? 1 : -1;
self.effectTimer = 0;
self.update = function () {
self.y += self.speed * gameSpeedMultiplier;
self.x += self.sideSpeed * self.direction * gameSpeedMultiplier;
// Bounce off screen edges
if (self.x <= 0 || self.x >= 2048) {
self.direction *= -1;
}
// Create flame and smoke effects
self.effectTimer++;
if (self.effectTimer >= 5) {
self.effectTimer = 0;
// Create flame particles
if (Math.random() < 0.03) {
var flameParticle = game.attachAsset('flame', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x + 35 + (Math.random() - 0.5) * 30,
y: self.y - 50 + (Math.random() - 0.5) * 20,
scaleX: 0.5 + Math.random() * 0.3,
scaleY: 0.5 + Math.random() * 0.3,
alpha: 0.8 + Math.random() * 0.2
});
// Animate flame trailing behind projectile
tween(flameParticle, {
y: flameParticle.y + 40 + Math.random() * 30,
x: flameParticle.x + (Math.random() - 0.5) * 20,
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300 + Math.random() * 200,
easing: tween.easeOut,
onFinish: function onFinish() {
flameParticle.destroy();
}
});
}
// Create smoke particles
if (Math.random() < 0.02) {
var smokeParticle = game.attachAsset('smoke', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x + (Math.random() - 0.5) * 25,
y: self.y + (Math.random() - 0.5) * 15,
scaleX: 0.3 + Math.random() * 0.2,
scaleY: 0.3 + Math.random() * 0.2,
alpha: 0.6
});
// Animate smoke trailing and dispersing
tween(smokeParticle, {
y: smokeParticle.y + 50 + Math.random() * 25,
x: smokeParticle.x + (Math.random() - 0.5) * 15,
alpha: 0,
scaleX: 0.8 + Math.random() * 0.4,
scaleY: 0.8 + Math.random() * 0.4
}, {
duration: 400 + Math.random() * 300,
easing: tween.easeOut,
onFinish: function onFinish() {
smokeParticle.destroy();
}
});
}
// Create additional particle effects
if (Math.random() < 0.01) {
var projectileParticle = new Particle();
projectileParticle.x = self.x + (Math.random() - 0.5) * 40;
projectileParticle.y = self.y - 10 + (Math.random() - 0.5) * 15;
projectileParticle.velocityX = (Math.random() - 0.5) * 6;
projectileParticle.velocityY = -Math.random() * 4 - 2;
particles.push(projectileParticle);
game.addChild(projectileParticle);
}
}
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
// Choose random particle color/type
var particleTypes = ['redParticle', 'orangeParticle', 'yellowParticle', 'whiteParticle', 'smoke'];
var randomType = particleTypes[Math.floor(Math.random() * particleTypes.length)];
var particleBody = self.attachAsset(randomType, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3 + Math.random() * 0.6,
scaleY: 0.3 + Math.random() * 0.6
});
// Random particle properties
self.velocityX = (Math.random() - 0.5) * 8;
self.velocityY = -Math.random() * 6 - 2;
self.gravity = 0.2;
self.life = 90 + Math.random() * 60; // 1.5-2.5 seconds at 60fps
self.maxLife = self.life;
self.update = function () {
// Apply physics
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
// Fade out over time
self.life--;
self.alpha = self.life / self.maxLife;
// Remove when life is over or off screen
if (self.life <= 0 || self.y > 2732 + 100 || self.y < -100 || self.x < -100 || self.x > 2148) {
self.destroy();
// Remove from particles array
for (var p = particles.length - 1; p >= 0; p--) {
if (particles[p] === self) {
particles.splice(p, 1);
break;
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8B4513
});
/****
* Game Code
****/
var backgroundImage = game.attachAsset('background', {
x: 0,
y: 0,
width: 2048,
height: 2732
});
// Add new background layer
var backgroundLayer = game.attachAsset('backgroundLayer', {
x: 0,
y: 0,
width: 2100,
height: 700
});
// Create ground terrain
var ground = game.attachAsset('ground', {
x: 0,
y: 2682,
// Position at bottom (2732 - 50 = 2682)
width: 2048,
height: 50
});
// Create and position player on the ground
var player = game.attachAsset('player', {
x: 2048 / 2,
// Center horizontally
y: 2682,
// Position touching the ground
scaleX: 1.0,
scaleY: 1.0,
anchorX: 0.5,
anchorY: 1.0
});
// Scale player to 3.0 using tween animation
tween(player, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 500,
easing: tween.easeOut
});
// Create white eyes on the player
var leftEye = game.attachAsset('eyeWhite', {
x: player.x - 50,
y: player.y - 245,
anchorX: 0.5,
anchorY: 0.5
});
var rightEye = game.attachAsset('eyeWhite', {
x: player.x + 10,
y: player.y - 245,
anchorX: 0.5,
anchorY: 0.5
});
// Create black pupils inside the white eyes
var leftPupil = game.attachAsset('eye', {
x: player.x - 50,
y: player.y - 245,
anchorX: 0.5,
anchorY: 0.5
});
var rightPupil = game.attachAsset('eye', {
x: player.x + 10,
y: player.y - 245,
anchorX: 0.5,
anchorY: 0.5
});
// Create player feet
var leftFoot = game.attachAsset('playerLeftFoot', {
x: player.x - 80,
y: player.y + 10,
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
var rightFoot = game.attachAsset('playerRightFoot', {
x: player.x + 80,
y: player.y + 10,
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
// Create player right hand
var playerRightHand = game.attachAsset('playerRightHand', {
x: player.x + 120,
y: player.y - 120,
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
// Variables for player movement
var playerSpeed = 12;
var targetX = player.x;
var isMoving = false;
var playerLives = 3;
var isShielded = false;
var shieldTimer = 0;
var shieldDuration = 240; // 4 seconds at 60fps
var isFlying = false; // Track if player is currently flying after being hit
var shieldBubble = null; // Shield bubble visual element
var walkAnimationTimer = 0; // Timer for walking animation
// Game speed system
var gameSpeedMultiplier = 1.0;
var speedIncreaseTimer = 0;
var speedIncreaseInterval = 600; // Increase speed every 10 seconds at 60fps
// Create life hearts on the left side
var lifeHearts = [];
for (var h = 0; h < 3; h++) {
// Create heart using image asset
var heartImage = game.attachAsset('lifeHeartImage', {
x: 150 + h * 100,
y: 750,
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0,
alpha: 1.0
});
lifeHearts.push(heartImage);
}
// Create score display
var scoreText = new Text2('PUAN: 0', {
size: 120,
fill: 0xFFFFFF,
font: "'Montserrat', 'Open Sans', 'Lato', 'Source Sans Pro', 'Ubuntu', sans-serif"
});
scoreText.anchor.set(0.5, 0);
scoreText.x = 2048 / 2;
scoreText.y = 850;
game.addChild(scoreText);
// Enemy and projectile tracking
var enemy = null;
var enemyProjectiles = [];
var enemyProjectiles2 = [];
var particles = [];
// Create enemy at top of screen
enemy = game.addChild(new Enemy());
enemy.x = 1124; // Move slightly to the right
enemy.y = 450; // Moved up from previous position
// Touch/mouse controls for player movement
game.down = function (x, y, obj) {
// Set target position to touch/click location
targetX = x;
isMoving = true;
// Keep player within screen bounds
if (targetX < 0) targetX = 0;
if (targetX > 2048) targetX = 2048;
};
// Update player movement
game.update = function () {
// Update game speed system
speedIncreaseTimer++;
if (speedIncreaseTimer >= speedIncreaseInterval) {
speedIncreaseTimer = 0;
gameSpeedMultiplier += 0.1; // Increase speed by 10% every 10 seconds
// Cap maximum speed at 3x original speed
if (gameSpeedMultiplier > 3.0) {
gameSpeedMultiplier = 3.0;
}
}
if (isMoving) {
// Calculate distance to target
var distance = targetX - player.x;
// Move towards target
if (Math.abs(distance) > 5) {
if (distance > 0) {
player.x += playerSpeed;
} else {
player.x -= playerSpeed;
}
// Animate walking - move feet up and down alternately
walkAnimationTimer++;
if (walkAnimationTimer >= 10) {
walkAnimationTimer = 0;
// Animate left foot up and down
tween(leftFoot, {
y: leftFoot.y === player.y + 10 ? player.y - 10 : player.y + 10
}, {
duration: 150,
easing: tween.easeInOut
});
// Animate right foot up and down (opposite to left foot)
tween(rightFoot, {
y: rightFoot.y === player.y + 10 ? player.y - 10 : player.y + 10
}, {
duration: 150,
easing: tween.easeInOut
});
}
} else {
// Snap to target when close enough
player.x = targetX;
isMoving = false;
}
// Keep player within bounds
if (player.x < 0) player.x = 0;
if (player.x > 2048) player.x = 2048;
}
// Update feet positions to follow player
leftFoot.x = player.x - 80;
rightFoot.x = player.x + 80;
// Update right hand position to follow player
playerRightHand.x = player.x + 120;
playerRightHand.y = player.y - 120;
// Reset feet position when not moving
if (!isMoving) {
leftFoot.y = player.y + 10;
rightFoot.y = player.y + 10;
}
// Update shield system
if (isShielded) {
shieldTimer--;
// Hide player right hand when shield is active
playerRightHand.visible = false;
// Show shield bubble if not already visible
if (!shieldBubble) {
shieldBubble = game.attachAsset('shieldBubble', {
x: player.x,
y: player.y - 150,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1,
tint: 0xffffff
});
// Add pulsing animation to shield bubble
tween(shieldBubble, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (shieldBubble) {
tween(shieldBubble, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.05
}, {
duration: 500,
easing: tween.easeInOut
});
}
}
});
}
// Update shield bubble position to follow player
if (shieldBubble) {
shieldBubble.x = player.x;
shieldBubble.y = player.y - 150;
}
// Flash player blue to indicate shield
if (shieldTimer % 20 < 10) {
player.tint = 0x00ffff;
} else {
player.tint = 0xffffff;
}
// Deactivate shield when timer expires
if (shieldTimer <= 0) {
isShielded = false;
player.tint = 0xffffff;
// Show player right hand when shield is deactivated
playerRightHand.visible = true;
// Stop pupil spinning and reset rotation
tween.stop(leftPupil, {
rotation: true
});
tween.stop(rightPupil, {
rotation: true
});
leftPupil.rotation = 0;
rightPupil.rotation = 0;
// Remove shield bubble
if (shieldBubble) {
shieldBubble.destroy();
shieldBubble = null;
}
// Clear shield sound interval
if (game.shieldSoundInterval) {
LK.clearInterval(game.shieldSoundInterval);
game.shieldSoundInterval = null;
}
}
}
// Update eye positions to follow player
leftEye.x = player.x - 50;
leftEye.y = player.y - 245;
rightEye.x = player.x + 10;
rightEye.y = player.y - 245;
// Keep pupils centered when not shielded, but track falling projectiles
if (!isShielded) {
// Default pupil positions (eye centers)
var leftEyeCenterX = player.x - 50;
var leftEyeCenterY = player.y - 245;
var rightEyeCenterX = player.x + 10;
var rightEyeCenterY = player.y - 245;
// Maximum distance pupils can move from center
var maxPupilDistance = 8;
// Find closest falling projectile to track
var closestProjectile = null;
var closestDistance = Infinity;
// Check all enemy projectiles
for (var p = 0; p < enemyProjectiles.length; p++) {
var proj = enemyProjectiles[p];
var distance = Math.sqrt(Math.pow(proj.x - player.x, 2) + Math.pow(proj.y - player.y, 2));
if (distance < closestDistance) {
closestDistance = distance;
closestProjectile = proj;
}
}
// Check all enemy projectiles type 2
for (var p2 = 0; p2 < enemyProjectiles2.length; p2++) {
var proj2 = enemyProjectiles2[p2];
var distance2 = Math.sqrt(Math.pow(proj2.x - player.x, 2) + Math.pow(proj2.y - player.y, 2));
if (distance2 < closestDistance) {
closestDistance = distance2;
closestProjectile = proj2;
}
}
if (closestProjectile) {
// Calculate angles from eye centers to the closest projectile
var leftAngle = Math.atan2(closestProjectile.y - leftEyeCenterY, closestProjectile.x - leftEyeCenterX);
var rightAngle = Math.atan2(closestProjectile.y - rightEyeCenterY, closestProjectile.x - rightEyeCenterX);
// Position pupils within eye boundaries, tracking the projectile
leftPupil.x = leftEyeCenterX + Math.cos(leftAngle) * maxPupilDistance;
leftPupil.y = leftEyeCenterY + Math.sin(leftAngle) * maxPupilDistance;
rightPupil.x = rightEyeCenterX + Math.cos(rightAngle) * maxPupilDistance;
rightPupil.y = rightEyeCenterY + Math.sin(rightAngle) * maxPupilDistance;
} else {
// No projectiles to track, center pupils
leftPupil.x = leftEyeCenterX;
leftPupil.y = leftEyeCenterY;
rightPupil.x = rightEyeCenterX;
rightPupil.y = rightEyeCenterY;
}
} else {
// When shield is active, make pupils move diagonally (down-left and diagonally)
var leftEyeCenterX = player.x - 50;
var leftEyeCenterY = player.y - 245;
var rightEyeCenterX = player.x + 10;
var rightEyeCenterY = player.y - 245;
var maxBounceDistance = 12;
// Use diagonal movement patterns based on time
var bounceTime = LK.ticks * 0.12;
// Create diagonal movements: down-left and cross-diagonal
var bounceX = Math.sin(bounceTime) * maxBounceDistance;
var bounceY = Math.cos(bounceTime * 0.8) * (maxBounceDistance * 0.7);
// Position pupils with diagonal movement patterns
leftPupil.x = leftEyeCenterX + bounceX;
leftPupil.y = leftEyeCenterY + bounceY;
rightPupil.x = rightEyeCenterX - bounceX; // Opposite X movement for variety
rightPupil.y = rightEyeCenterY + bounceY;
}
// Update enemy projectiles
for (var i = enemyProjectiles.length - 1; i >= 0; i--) {
var projectile = enemyProjectiles[i];
// Remove projectiles that go off screen (any direction)
if (projectile.y > 2732 + 100 || projectile.y < -100 || projectile.x < -100 || projectile.x > 2148) {
projectile.destroy();
enemyProjectiles.splice(i, 1);
continue;
}
// Check collision with player
if (projectile.intersects(player)) {
// Check if player is protected by shield
if (!isShielded) {
// Award points when hit by enemy projectile
LK.setScore(LK.getScore() + 10);
// Update score display
scoreText.setText('PUAN: ' + LK.getScore());
// Play sound effect for first projectile hit
LK.getSound('enemyProjectileHit').play();
// Create reduced particle burst effect at player's mouth area
for (var particleCount = 0; particleCount < 1; particleCount++) {
var particle = new Particle();
particle.x = player.x + (Math.random() - 0.5) * 40;
particle.y = player.y - 130 + (Math.random() - 0.5) * 30; // Position higher up from mouth area
// Reduce particle velocity for better performance
particle.velocityX = (Math.random() - 0.5) * 10;
particle.velocityY = -Math.random() * 8 - 3;
particles.push(particle);
game.addChild(particle);
}
// Simplified mouth trembling effect
tween(player, {
scaleX: 3.2,
scaleY: 2.8
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 150,
easing: tween.easeOut
});
}
});
}
projectile.destroy();
enemyProjectiles.splice(i, 1);
}
}
// Update enemy projectiles type 2
for (var j = enemyProjectiles2.length - 1; j >= 0; j--) {
var projectile2 = enemyProjectiles2[j];
// Remove projectiles that go off screen (any direction)
if (projectile2.y > 2732 + 100 || projectile2.y < -100 || projectile2.x < -100 || projectile2.x > 2148) {
projectile2.destroy();
enemyProjectiles2.splice(j, 1);
continue;
}
// Check collision with player
if (projectile2.intersects(player) && !isShielded && !isFlying) {
// Show enemy mouth when hit by second projectile
enemy.showMouth();
// Freeze enemy movement and shooting
enemy.freezeEnemy();
// Play sound effect for second projectile hit
LK.getSound('enemyProjectile2Hit').play();
// Stop current player movement
isMoving = false;
// Set flying state to true
isFlying = true;
// Player flies off screen to the left while spinning
tween(player, {
x: -200,
y: player.y - 800,
rotation: Math.PI * 4
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Return player from right side after flying off
player.x = 2248;
player.y = 2682;
player.rotation = 0;
// Reset flying state
isFlying = false;
// Activate shield protection
isShielded = true;
shieldTimer = shieldDuration;
// Play shield activation sound
LK.getSound('shieldSound').play();
// Set up repeating shield sound during shield duration
var shieldSoundInterval = LK.setInterval(function () {
if (isShielded && shieldTimer > 0) {
LK.getSound('shieldSound').play();
}
}, 1750); // Play every 1750ms
// Store interval reference for cleanup
game.shieldSoundInterval = shieldSoundInterval;
// Shield bubble will be created in the shield update section
// Animate player returning to screen
tween(player, {
x: 2048 / 2
}, {
duration: 800,
easing: tween.easeOut
});
}
});
// Update feet positions during flight animation
tween(leftFoot, {
x: -330,
y: player.y - 790
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
leftFoot.x = 2168;
leftFoot.y = 2692;
tween(leftFoot, {
x: 2048 / 2 - 80
}, {
duration: 800,
easing: tween.easeOut
});
}
});
tween(rightFoot, {
x: -120,
y: player.y - 790
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
rightFoot.x = 2128;
rightFoot.y = 2692;
tween(rightFoot, {
x: 2048 / 2 + 80
}, {
duration: 800,
easing: tween.easeOut
});
}
});
// Update eye positions during flight animation
tween(leftEye, {
x: -250,
y: player.y - 1045
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
leftEye.x = 2198;
leftEye.y = 2437;
tween(leftEye, {
x: 2048 / 2 - 50
}, {
duration: 800,
easing: tween.easeOut
});
}
});
tween(rightEye, {
x: -190,
y: player.y - 1045
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
rightEye.x = 2258;
rightEye.y = 2437;
tween(rightEye, {
x: 2048 / 2 + 10
}, {
duration: 800,
easing: tween.easeOut
});
}
});
tween(leftPupil, {
x: -250,
y: player.y - 1045
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
leftPupil.x = 2198;
leftPupil.y = 2437;
tween(leftPupil, {
x: 2048 / 2 - 50
}, {
duration: 800,
easing: tween.easeOut
});
}
});
tween(rightPupil, {
x: -190,
y: player.y - 1045
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
rightPupil.x = 2258;
rightPupil.y = 2437;
tween(rightPupil, {
x: 2048 / 2 + 10
}, {
duration: 800,
easing: tween.easeOut
});
}
});
// Update right hand position during flight animation
tween(playerRightHand, {
x: -80,
y: player.y - 920
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
playerRightHand.x = 2368;
playerRightHand.y = 2562;
tween(playerRightHand, {
x: 2048 / 2 + 120
}, {
duration: 800,
easing: tween.easeOut
});
}
});
// Create particle burst effect
for (var particleCount = 0; particleCount < 5; particleCount++) {
var particle = new Particle();
particle.x = player.x + (Math.random() - 0.5) * 80;
particle.y = player.y - 50 + (Math.random() - 0.5) * 70;
// Give particles more dramatic velocities for this bigger explosion
particle.velocityX = (Math.random() - 0.5) * 18;
particle.velocityY = -Math.random() * 12 - 4;
particles.push(particle);
game.addChild(particle);
}
// Create smoke and flame effects
for (var smokeCount = 0; smokeCount < 2; smokeCount++) {
var smoke = game.attachAsset('smoke', {
x: player.x + (Math.random() - 0.5) * 200,
y: player.y - 100 + (Math.random() - 0.5) * 100,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
// Animate smoke rising and fading
tween(smoke, {
y: smoke.y - 200 - Math.random() * 100,
alpha: 0,
scaleX: 2 + Math.random(),
scaleY: 2 + Math.random()
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
smoke.destroy();
}
});
}
for (var flameCount = 0; flameCount < 1; flameCount++) {
var flame = game.attachAsset('flame', {
x: player.x + (Math.random() - 0.5) * 150,
y: player.y - 50 + (Math.random() - 0.5) * 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 1
});
// Animate flames flickering and rising
tween(flame, {
y: flame.y - 150 - Math.random() * 50,
alpha: 0,
scaleX: 1.5 + Math.random() * 0.5,
scaleY: 1.5 + Math.random() * 0.5
}, {
duration: 1500 + Math.random() * 500,
easing: tween.easeOut,
onFinish: function onFinish() {
flame.destroy();
}
});
}
// Create fire animation effect on player
tween(player, {
tint: 0xff4500
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(player, {
tint: 0xff0000
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(player, {
tint: 0xffffff
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
});
// Reduce player lives
playerLives--;
// Update heart visibility based on remaining lives
for (var heartIndex = 0; heartIndex < lifeHearts.length; heartIndex++) {
if (heartIndex >= playerLives) {
// Hide heart with fade out animation
tween(lifeHearts[heartIndex], {
alpha: 0.2,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
}
}
if (playerLives <= 0) {
// Show game over when no lives left
LK.showGameOver();
}
projectile2.destroy();
enemyProjectiles2.splice(j, 1);
}
}
// Comprehensive cleanup system - remove all off-screen elements every frame
var allChildren = game.children.slice(); // Create a copy to avoid modification during iteration
var screenBuffer = 100; // Buffer zone around visible area
for (var c = 0; c < allChildren.length; c++) {
var child = allChildren[c];
// Skip essential game elements that should always stay
if (child === player || child === enemy || child === backgroundImage || child === backgroundLayer || child === ground || child === scoreText || child === leftEye || child === rightEye || child === leftPupil || child === rightPupil || child === leftFoot || child === rightFoot || child === playerRightHand || child === shieldBubble) {
continue;
}
// Skip life hearts
var isLifeHeart = false;
for (var h = 0; h < lifeHearts.length; h++) {
if (child === lifeHearts[h]) {
isLifeHeart = true;
break;
}
}
if (isLifeHeart) {
continue;
}
// Remove if off screen in any direction with buffer zone
if (child.x < -screenBuffer || child.x > 2048 + screenBuffer || child.y < -screenBuffer || child.y > 2732 + screenBuffer) {
child.destroy();
}
}
// Clean up particle arrays - remove destroyed particles
for (var p = particles.length - 1; p >= 0; p--) {
if (!particles[p] || particles[p].destroyed) {
particles.splice(p, 1);
}
}
// Clean up projectile arrays - ensure no destroyed projectiles remain
for (var ep = enemyProjectiles.length - 1; ep >= 0; ep--) {
if (!enemyProjectiles[ep] || enemyProjectiles[ep].destroyed) {
enemyProjectiles.splice(ep, 1);
}
}
for (var ep2 = enemyProjectiles2.length - 1; ep2 >= 0; ep2--) {
if (!enemyProjectiles2[ep2] || enemyProjectiles2[ep2].destroyed) {
enemyProjectiles2.splice(ep2, 1);
}
}
};
3d köstebek. In-Game asset. 2d. High contrast. No shadows
Elinde havuç olan kızgın bir çiftçi. Karakter ayakkabısı siyah
Havuç. In-Game asset. 2d. High contrast. No shadows
Bomba. In-Game asset. 2d. High contrast. No shadows
Alev. In-Game asset. 2d. High contrast. No shadows
Agız. In-Game asset. 2d. High contrast. No shadows
Kalp 3d. In-Game asset. 2d. High contrast. No shadows