User prompt
sağ üstteki sayaç 90 a kadar saysın
User prompt
sağ üsteki sayaç 10 a akdar saysın
User prompt
oyunun sonunda 10 puandan aşşağı puan kazanırsak oyunun sonunda F- şekli görünsün
User prompt
araba sağ tarafı geçerse sol tarafdan tekrar çıksın sol tarfa girerse sağ atrafadan geri çıksın
User prompt
sağ üsteki sayacın rengi koyu yeşil olsun
User prompt
sağ üst köşede 1 den başlayıp 90 a kadar ileriye doğru giden bir sayaç ekle o sayaç 90 a gelirse oyunu bitir
User prompt
hareket etmeme sayacını sağ alt köşeye yerleştirin
User prompt
oyun 100000000 puanda bitsin
User prompt
sayaç araba hareket etse bile bir nesneye değmezse çalışsın
User prompt
her turda borular 1 eksiltilerek gelsin
User prompt
oyun 250 puanda bitsin
User prompt
sağ üst köşede 10 dan geriye doğru bir sayaç olsun araba hareket etmezse ya da herhangi bir şeye değmezse o sayaç geriye doğru sayar eğer sayaç 0 a ulaşırsa oyun kaybedilir ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
borular ağaçların içinde yada yakınında olamaz
User prompt
direkler ince uzun bir metaldir ağaç değildir
User prompt
oyunda ağaçalrın yanı sıra direkler olsun ve bunlara çarptığımzda 10 puanımzı eksilsin eğer oyuncu eksi puana düşerse oyunu kaybeder bu direkler bir turda 5 kere çıkar
User prompt
oyunda olan normal ağacın aynısı gibi olan ama altın gibi gözüken ve alındığında 10 puan veren bir ağaç ekle
User prompt
altın ağacın renki değişik olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyunda ekstradan her turda 1 kere çıkan altın ağaç olsun ve o ağaç 10 puan versin
User prompt
oyun 100 puan da bitsin
User prompt
ağçalr birden fazla olsun her seferde
Code edit (1 edits merged)
Please save this source code
User prompt
Çarpışan Arabalar: Ağaç Avı
Initial prompt
bana arabalarla aağaçlara çarpıp puan kazandığımız bir oyun yap
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet class for weapon projectiles var Bullet = Container.expand(function () { var self = Container.call(this); // Create bullet visual (small circle) var bulletAsset = self.attachAsset('manCircle', { anchorX: 0.5, anchorY: 0.5 }); bulletAsset.width = 20; bulletAsset.height = 20; bulletAsset.tint = 0xFFFF00; // Yellow color for bullet self.speed = 12; self.targetX = 0; self.targetY = 0; // Update method for bullet movement towards target self.update = function () { // Move towards target var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Remove bullet if it reaches target or goes off screen if (distance < 30 || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { if (self.parent) { self.parent.removeChild(self); } var index = bullets.indexOf(self); if (index !== -1) { bullets.splice(index, 1); } } }; return self; }); // Car class var Car = Container.expand(function () { var self = Container.call(this); // Attach car asset (red box, 200x120) var carAsset = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); // Set size for car asset carAsset.width = 200; carAsset.height = 120; // For touch feedback self.flash = function () { tween(self, { alpha: 0.5 }, { duration: 80, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 120 }); } }); }; return self; }); // DeadlyTree class for special scene var DeadlyTree = Container.expand(function () { var self = Container.call(this); // Attach tree asset (red tinted, 100x100) var treeAsset = self.attachAsset('tree', { anchorX: 0.5, anchorY: 0.5 }); treeAsset.width = 100; treeAsset.height = 100; treeAsset.tint = 0xFF0000; // Red tint for deadly trees self.speed = 24; // Falling speed (3x faster) self.isFollowing = false; self.followSpeed = 8; // Speed when following player // Start following the player self.startFollowing = function () { self.isFollowing = true; }; // Stop following and disappear with tween self.stopFollowing = function () { self.isFollowing = false; tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { if (self.parent) { self.parent.removeChild(self); } } }); }; // Update method for falling motion or following self.update = function () { if (self.isFollowing && car) { // Move towards car position var dx = car.x - self.x; var dy = car.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.followSpeed; self.y += dy / distance * self.followSpeed; } } else { self.y += self.speed; } }; return self; }); // GoldenTree class var GoldenTree = Container.expand(function () { var self = Container.call(this); // Attach tree asset (golden, 140x140 - slightly bigger) var treeAsset = self.attachAsset('tree', { anchorX: 0.5, anchorY: 0.5 }); treeAsset.width = 140; treeAsset.height = 140; treeAsset.tint = 0xFFD700; // Golden tint color self.pointValue = 10; // Golden tree gives 10 points // Add golden glow effect self.glowEffect = function () { tween(self, { alpha: 0.7 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { self.glowEffect(); // Loop the glow effect } }); } }); }; // Start glow effect immediately self.glowEffect(); // Special golden hit animation self.hitAnim = function () { tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeIn }); } }); }; return self; }); // MultiSkeleton class for fourth scene var MultiSkeleton = Container.expand(function () { var self = Container.call(this); // Create circular shape for the skeleton var skeletonAsset = self.attachAsset('manCircle', { anchorX: 0.5, anchorY: 0.5 }); skeletonAsset.tint = 0x800080; // Purple tint for skeletons self.throwTimer = 0; self.throwInterval = 60; // Fixed 1 second interval (60 ticks) // Update method for throwing trees self.update = function () { self.throwTimer++; if (self.throwTimer >= self.throwInterval) { // Throw either deadly tree or point tree randomly var isDeadly = Math.random() < 0.5; // 50% chance for deadly tree var thrownTree; if (isDeadly) { thrownTree = new DeadlyTree(); } else { thrownTree = new Tree(); } // Find valid position that doesn't overlap with existing trees var validPosition = false; var tries = 0; var targetX, targetY; do { targetX = self.x + (Math.random() - 0.5) * 400; // Random position around skeleton targetY = self.y + 50 + Math.random() * 200; validPosition = true; tries++; // Check distance from all existing fourth scene trees for (var ft = 0; ft < fourthSceneTrees.length; ft++) { var existingTree = fourthSceneTrees[ft]; var dx = targetX - existingTree.x; var dy = targetY - existingTree.y; var distanceToTree = Math.sqrt(dx * dx + dy * dy); if (distanceToTree < 150) { // Minimum distance of 150 pixels validPosition = false; break; } } } while (!validPosition && tries < 10); thrownTree.x = self.x; thrownTree.y = self.y + 50; // Set target towards calculated position thrownTree.targetX = targetX; thrownTree.targetY = targetY; thrownTree.speed = 8; thrownTree.isThrown = true; // Override update to move towards target thrownTree.update = function () { if (thrownTree.isThrown) { var dx = thrownTree.targetX - thrownTree.x; var dy = thrownTree.targetY - thrownTree.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { thrownTree.x += dx / distance * thrownTree.speed; thrownTree.y += dy / distance * thrownTree.speed; } // Remove if goes off screen if (thrownTree.x < -100 || thrownTree.x > 2148 || thrownTree.y < -100 || thrownTree.y > 2832) { if (thrownTree.parent) { thrownTree.parent.removeChild(thrownTree); } var index = fourthSceneTrees.indexOf(thrownTree); if (index !== -1) { fourthSceneTrees.splice(index, 1); lastIntersectingFourthTrees.splice(index, 1); } } } }; fourthSceneTrees.push(thrownTree); lastIntersectingFourthTrees.push(false); game.addChild(thrownTree); self.throwTimer = 0; self.throwInterval = 60; // Reset to 1 second interval } }; return self; }); // Pole class var Pole = Container.expand(function () { var self = Container.call(this); // Attach pole asset (thin metal pole, 30x300) var poleAsset = self.attachAsset('pole', { anchorX: 0.5, anchorY: 0.5 }); self.pointValue = -10; // Pole reduces 10 points // Animate on hit (shake effect) self.hitAnim = function () { tween(self, { rotation: 0.2 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { rotation: -0.2 }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: 0 }, { duration: 80, easing: tween.easeIn }); } }); } }); }; return self; }); // PurpleTree class var PurpleTree = Container.expand(function () { var self = Container.call(this); // Attach tree asset (purple, 140x140 - slightly bigger) var treeAsset = self.attachAsset('tree', { anchorX: 0.5, anchorY: 0.5 }); treeAsset.width = 140; treeAsset.height = 140; treeAsset.tint = 0x8A2BE2; // Purple tint color self.pointValue = 30; // Purple tree gives 30 points // Add purple glow effect self.glowEffect = function () { tween(self, { alpha: 0.6 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { self.glowEffect(); // Loop the glow effect } }); } }); }; // Start glow effect immediately self.glowEffect(); // Special purple hit animation self.hitAnim = function () { tween(self, { scaleX: 1.6, scaleY: 1.6 }, { duration: 180, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 180, easing: tween.easeIn }); } }); }; return self; }); // ThrowingMan class for special scene var ThrowingMan = Container.expand(function () { var self = Container.call(this); // Create circular shape for the man var manAsset = self.attachAsset('manCircle', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Tree class var Tree = Container.expand(function () { var self = Container.call(this); // Attach tree asset (green ellipse, 120x120) var treeAsset = self.attachAsset('tree', { anchorX: 0.5, anchorY: 0.5 }); treeAsset.width = 120; treeAsset.height = 120; treeAsset.tint = 0x228B22; self.pointValue = 1; // Normal tree gives 1 point // Animate on hit self.hitAnim = function () { tween(self, { scaleX: 1.3, scaleY: 1.3 }, { duration: 120, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeIn }); } }); }; return self; }); // Weapon class for special scene var Weapon = Container.expand(function () { var self = Container.call(this); // Create weapon visual using weapon image asset var weaponAsset = self.attachAsset('weapon', { anchorX: 0.5, anchorY: 0.5 }); weaponAsset.rotation = Math.PI / 4; // 45 degree rotation return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // --- Game constants --- var CAR_START_X = 2048 / 2; var CAR_START_Y = 2732 - 350; var TREE_MIN_Y = 350; var TREE_MAX_Y = 2732 - 350; var TREE_MIN_X = 150; var TREE_MAX_X = 2048 - 150; var WIN_SCORE = 100000000; // --- Game state --- var car = null; var trees = []; var poles = []; var score = 0; var scoreTxt = null; var dragNode = null; var lastIntersecting = []; var lastIntersectingPoles = []; var goldenTreeSpawned = false; var treesHitThisRound = 0; var purpleTreeCounter = 0; var polesSpawnedThisRound = 0; var countdownTimer = 10; var countdownTxt = null; var lastCarX = 0; var lastCarY = 0; var lastScore = 0; var upwardCounter = 1; var upwardCounterTxt = null; var specialScene = false; var specialSceneInitialized = false; var throwingMan = null; var deadlyTrees = []; var lastIntersectingDeadly = []; var throwTimer = 0; var followingStartTime = null; var followingDuration = 10000; // 10 seconds in milliseconds var allFollowingTreesGone = false; // Flag to track if all following trees have disappeared var bottomLeftCounter = 150; var bottomLeftCounterTxt = null; var weapon = null; var weaponSpawned = false; var bullets = []; var lastIntersectingWeapon = false; var skeletonHealth = 1000; var skeletonHealthTxt = null; var fourthScene = false; var fourthSceneInitialized = false; var multiSkeletons = []; var fourthSceneTrees = []; var lastIntersectingFourthTrees = []; // --- Create and add car --- car = new Car(); car.x = CAR_START_X; car.y = CAR_START_Y; game.addChild(car); // --- Create and add trees --- for (var i = 0; i < 5; i++) { var tree = new Tree(); tree.x = getRandomTreeX(); tree.y = getRandomTreeY(); trees.push(tree); lastIntersecting.push(false); game.addChild(tree); } // --- Create and add poles --- for (var i = 0; i < 5; i++) { var pole = new Pole(); var tries = 0; var validPosition = false; do { pole.x = getRandomTreeX(); pole.y = getRandomTreeY(); tries++; validPosition = true; // Check distance from car if (distance(car.x, car.y, pole.x, pole.y) < 300) { validPosition = false; } // Check distance from all existing trees for (var t = 0; t < trees.length; t++) { if (distance(pole.x, pole.y, trees[t].x, trees[t].y) < 200) { validPosition = false; break; } } // Check distance from all existing poles for (var p = 0; p < poles.length; p++) { if (distance(pole.x, pole.y, poles[p].x, poles[p].y) < 200) { validPosition = false; break; } } } while (!validPosition && tries < 20); poles.push(pole); lastIntersectingPoles.push(false); game.addChild(pole); } // --- Score text --- scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Countdown timer text --- countdownTxt = new Text2('10', { size: 100, fill: 0xFF0000 }); countdownTxt.anchor.set(1, 1); LK.gui.bottomRight.addChild(countdownTxt); // --- Upward counter text --- upwardCounterTxt = new Text2('1', { size: 100, fill: 0x006400 }); upwardCounterTxt.anchor.set(1, 0); LK.gui.topRight.addChild(upwardCounterTxt); // --- Bottom-left counter text --- bottomLeftCounterTxt = new Text2('150', { size: 100, fill: 0x8B4513 }); bottomLeftCounterTxt.anchor.set(0, 1); LK.gui.bottomLeft.addChild(bottomLeftCounterTxt); // --- Skeleton health bar text --- skeletonHealthTxt = new Text2('ENES BATUR: 1000', { size: 80, fill: 0xFF0000 }); skeletonHealthTxt.anchor.set(0, 0.5); skeletonHealthTxt.visible = false; // Initially hidden until special scene game.addChild(skeletonHealthTxt); // --- Helper functions --- function getRandomTreeX() { return TREE_MIN_X + Math.floor(Math.random() * (TREE_MAX_X - TREE_MIN_X)); } function getRandomTreeY() { return TREE_MIN_Y + Math.floor(Math.random() * (TREE_MAX_Y - TREE_MIN_Y)); } function updateScoreText() { scoreTxt.setText(score); } function updateCountdownText() { countdownTxt.setText(countdownTimer); } function updateUpwardCounterText() { upwardCounterTxt.setText(upwardCounter); } function updateBottomLeftCounterText() { bottomLeftCounterTxt.setText(bottomLeftCounter); } function updateSkeletonHealthText() { skeletonHealthTxt.setText('ENES BATUR: ' + skeletonHealth); } function spawnNewTree() { var newTree; // Spawn purple tree every 40 normal trees (1 in 40 chance) purpleTreeCounter++; if (purpleTreeCounter >= 40) { newTree = new PurpleTree(); purpleTreeCounter = 0; // Reset counter } else if (treesHitThisRound % 5 === 0 && !goldenTreeSpawned) { // Spawn golden tree once every 5 hits if not already spawned this round newTree = new GoldenTree(); goldenTreeSpawned = true; } else { newTree = new Tree(); // Reset golden tree availability after 10 hits if (treesHitThisRound >= 10) { goldenTreeSpawned = false; treesHitThisRound = 0; } } // Position new tree randomly (avoid placing too close to car and existing poles) var tries = 0; var validPosition = false; do { newTree.x = getRandomTreeX(); newTree.y = getRandomTreeY(); tries++; validPosition = true; // Check distance from car if (distance(car.x, car.y, newTree.x, newTree.y) < 300) { validPosition = false; } // Check distance from all existing poles for (var p = 0; p < poles.length; p++) { if (distance(newTree.x, newTree.y, poles[p].x, poles[p].y) < 200) { validPosition = false; break; } } // Check distance from all existing trees for (var t = 0; t < trees.length; t++) { if (distance(newTree.x, newTree.y, trees[t].x, trees[t].y) < 200) { validPosition = false; break; } } } while (!validPosition && tries < 20); trees.push(newTree); lastIntersecting.push(false); game.addChild(newTree); // Calculate current round based on score (every 50 points is a new round) var currentRound = Math.floor(score / 50); var polesPerRound = Math.max(1, 5 - currentRound); // Start with 5, decrease by 1 each round, minimum 1 // Spawn poles (decreasing each round) if (polesSpawnedThisRound < polesPerRound) { var newPole = new Pole(); var tries = 0; var validPolePosition = false; do { newPole.x = getRandomTreeX(); newPole.y = getRandomTreeY(); tries++; validPolePosition = true; // Check distance from car if (distance(car.x, car.y, newPole.x, newPole.y) < 300) { validPolePosition = false; } // Check distance from all existing trees for (var t = 0; t < trees.length; t++) { if (distance(newPole.x, newPole.y, trees[t].x, trees[t].y) < 200) { validPolePosition = false; break; } } // Check distance from all existing poles for (var p = 0; p < poles.length; p++) { if (distance(newPole.x, newPole.y, poles[p].x, poles[p].y) < 200) { validPolePosition = false; break; } } } while (!validPolePosition && tries < 20); poles.push(newPole); lastIntersectingPoles.push(false); game.addChild(newPole); polesSpawnedThisRound++; } // Reset pole counter when round is complete if (polesSpawnedThisRound >= polesPerRound && treesHitThisRound >= 10) { polesSpawnedThisRound = 0; } } // --- Move handler for dragging car --- function handleMove(x, y, obj) { if (dragNode) { var newX = x; var newY = Math.max(200, Math.min(2732 - 100, y)); // Screen wrapping for X axis if (newX > 2048) { newX = 0; // Car exits right, appears on left } else if (newX < 0) { newX = 2048; // Car exits left, appears on right } dragNode.x = newX; dragNode.y = newY; } // Collision detection for all trees for (var i = 0; i < trees.length; i++) { var tree = trees[i]; var currentIntersecting = car.intersects(tree); if (!lastIntersecting[i] && currentIntersecting) { // Car just hit tree score += tree.pointValue; treesHitThisRound++; updateScoreText(); // Update bottom-left counter bottomLeftCounter -= tree.pointValue; if (bottomLeftCounter <= 0) { bottomLeftCounter = 0; bottomLeftCounterTxt.visible = false; } updateBottomLeftCounterText(); // Animate car and tree car.flash(); tree.hitAnim(); // Remove the hit tree game.removeChild(tree); trees.splice(i, 1); lastIntersecting.splice(i, 1); i--; // Adjust index since we removed an element // Spawn new tree (normal or golden based on conditions) spawnNewTree(); // Win condition if (score >= WIN_SCORE) { LK.showYouWin(); } } if (i >= 0 && i < lastIntersecting.length) { lastIntersecting[i] = currentIntersecting; } } // Collision detection for all poles for (var j = 0; j < poles.length; j++) { var pole = poles[j]; var currentIntersectingPole = car.intersects(pole); if (!lastIntersectingPoles[j] && currentIntersectingPole) { // Car just hit pole score += pole.pointValue; // This will subtract 10 points updateScoreText(); // Update bottom-left counter (increase by the amount of points lost) bottomLeftCounter += Math.abs(pole.pointValue); updateBottomLeftCounterText(); // Animate car and pole car.flash(); pole.hitAnim(); // Remove the hit pole game.removeChild(pole); poles.splice(j, 1); lastIntersectingPoles.splice(j, 1); j--; // Adjust index since we removed an element // Check for game over (negative score) if (score < 0) { // Show "eziksin" message for losing with negative score var loserText = new Text2('eziksin', { size: 300, fill: 0x000000 // Black color }); loserText.anchor.set(0.5, 0.5); loserText.x = 2048 / 2; loserText.y = 2732 / 2; game.addChild(loserText); // Show message for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); } } if (j >= 0 && j < lastIntersectingPoles.length) { lastIntersectingPoles[j] = currentIntersectingPole; } } } // --- Utility: distance between two points --- function distance(x1, y1, x2, y2) { var dx = x1 - x2; var dy = y1 - y2; return Math.sqrt(dx * dx + dy * dy); } // --- Touch/drag events --- game.down = function (x, y, obj) { // Only start drag if touch is on car (within 120px radius) var dx = x - car.x; var dy = y - car.y; if (dx * dx + dy * dy < 120 * 120) { dragNode = car; handleMove(x, y, obj); } }; game.move = handleMove; game.up = function (x, y, obj) { dragNode = null; }; // --- Game update loop (not needed for movement, but for future extensibility) --- game.update = function () { // Check for special scene transition (150+ score) if (score >= 150 && !specialScene) { specialScene = true; // Clear existing game elements for (var i = trees.length - 1; i >= 0; i--) { game.removeChild(trees[i]); } trees = []; lastIntersecting = []; for (var j = poles.length - 1; j >= 0; j--) { game.removeChild(poles[j]); } poles = []; lastIntersectingPoles = []; // Change background to darker for special scene game.setBackgroundColor(0x2F4F4F); // Dark gray } // Handle special scene logic if (specialScene && !specialSceneInitialized) { // Initialize special scene throwingMan = new ThrowingMan(); throwingMan.x = 2048 / 2; throwingMan.y = 200; game.addChild(throwingMan); // Show and position skeleton health bar skeletonHealthTxt.visible = true; skeletonHealthTxt.x = throwingMan.x + 100; // Position to the right of skeleton skeletonHealthTxt.y = throwingMan.y; skeletonHealth = 1000; // Reset health updateSkeletonHealthText(); // Spawn weapon immediately in special scene if (!weaponSpawned) { weapon = new Weapon(); weapon.x = Math.random() * (2048 - 200) + 100; // Random X within game bounds weapon.y = Math.random() * (2732 - 400) + 200; // Random Y within game bounds game.addChild(weapon); weaponSpawned = true; } specialSceneInitialized = true; } if (specialScene) { // Initialize following start time when first entering special scene if (followingStartTime === null) { followingStartTime = Date.now(); } // Spawn deadly trees that follow player for 10 seconds, then disappear if (LK.ticks % 120 === 0 && deadlyTrees.length < 10 && !allFollowingTreesGone) { var newDeadlyTree = new DeadlyTree(); newDeadlyTree.x = Math.random() * 2048; newDeadlyTree.y = -100; // Start above screen newDeadlyTree.spawnTime = Date.now(); newDeadlyTree.startFollowing(); deadlyTrees.push(newDeadlyTree); lastIntersectingDeadly.push(false); game.addChild(newDeadlyTree); // Set timer to make tree disappear after 10 seconds LK.setTimeout(function () { if (newDeadlyTree.parent) { newDeadlyTree.stopFollowing(); var index = deadlyTrees.indexOf(newDeadlyTree); if (index !== -1) { deadlyTrees.splice(index, 1); lastIntersectingDeadly.splice(index, 1); } // Check if all deadly trees are gone if (deadlyTrees.length === 0 && !allFollowingTreesGone) { allFollowingTreesGone = true; // Show message near the throwing man var messageText = new Text2('O zaman bunu al', { size: 80, fill: 0xFFFFFF }); messageText.anchor.set(0.5, 0.5); messageText.x = throwingMan.x; messageText.y = throwingMan.y - 100; game.addChild(messageText); // Spawn weapon at random location if (!weaponSpawned) { weapon = new Weapon(); weapon.x = Math.random() * (2048 - 200) + 100; // Random X within game bounds weapon.y = Math.random() * (2732 - 400) + 200; // Random Y within game bounds game.addChild(weapon); weaponSpawned = true; } } } }, 10000); } // Check collision with deadly trees for (var k = deadlyTrees.length - 1; k >= 0; k--) { var deadlyTree = deadlyTrees[k]; var currentIntersectingDeadly = car.intersects(deadlyTree); // Check if tree has been alive for 10 seconds if (deadlyTree.spawnTime && Date.now() - deadlyTree.spawnTime >= 10000) { deadlyTree.stopFollowing(); deadlyTrees.splice(k, 1); lastIntersectingDeadly.splice(k, 1); // Check if all deadly trees are gone if (deadlyTrees.length === 0 && !allFollowingTreesGone) { allFollowingTreesGone = true; // Show message near the throwing man var messageText = new Text2('O zaman bunu al', { size: 80, fill: 0xFFFFFF }); messageText.anchor.set(0.5, 0.5); messageText.x = throwingMan.x; messageText.y = throwingMan.y - 100; // Position above the throwing man game.addChild(messageText); // Spawn weapon at random location if (!weaponSpawned) { weapon = new Weapon(); weapon.x = Math.random() * (2048 - 200) + 100; // Random X within game bounds weapon.y = Math.random() * (2732 - 400) + 200; // Random Y within game bounds game.addChild(weapon); weaponSpawned = true; } } continue; } // Check if tree went off screen (only for non-following trees) if (!deadlyTree.isFollowing && deadlyTree.y > 2732 + 100) { game.removeChild(deadlyTree); deadlyTrees.splice(k, 1); lastIntersectingDeadly.splice(k, 1); continue; } // Check collision - instant death if (!lastIntersectingDeadly[k] && currentIntersectingDeadly) { // Show death message var deathText = new Text2('ÖLDÜN!', { size: 300, fill: 0xFF0000 }); deathText.anchor.set(0.5, 0.5); deathText.x = 2048 / 2; deathText.y = 2732 / 2; game.addChild(deathText); // Show message for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); return; } if (k < lastIntersectingDeadly.length) { lastIntersectingDeadly[k] = currentIntersectingDeadly; } } // Check weapon collision and bullet firing if (weapon && throwingMan) { var currentIntersectingWeapon = car.intersects(weapon); if (!lastIntersectingWeapon && currentIntersectingWeapon) { // Car touched weapon, make weapon follow car weapon.isFollowingCar = true; // Fire bullet at skeleton var newBullet = new Bullet(); newBullet.x = car.x; newBullet.y = car.y; newBullet.targetX = throwingMan.x; newBullet.targetY = throwingMan.y; bullets.push(newBullet); game.addChild(newBullet); } lastIntersectingWeapon = currentIntersectingWeapon; // Make weapon follow car if attached if (weapon.isFollowingCar) { weapon.x = car.x + 60; // Offset to the right of car weapon.y = car.y; } } // Check bullet collisions with skeleton for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; if (throwingMan && bullet.intersects && bullet.intersects(throwingMan)) { // Bullet hit skeleton - reduce health skeletonHealth -= 5; updateSkeletonHealthText(); // Remove bullet game.removeChild(bullet); bullets.splice(b, 1); // Flash skeleton red when hit tween(throwingMan, { tint: 0xFF0000 }, { duration: 200, onFinish: function onFinish() { tween(throwingMan, { tint: 0xFFFFFF }, { duration: 200 }); } }); // Check if skeleton is defeated if (skeletonHealth <= 0) { // Hide health bar skeletonHealthTxt.visible = false; // Show victory message var victoryText = new Text2('Enes batur yenildi', { size: 200, fill: 0x00FF00 }); victoryText.anchor.set(0.5, 0.5); victoryText.x = 2048 / 2; victoryText.y = 2732 / 2; game.addChild(victoryText); // Show victory for 3 seconds then transition to fourth scene LK.setTimeout(function () { // Clear special scene elements game.removeChild(victoryText); if (throwingMan) { game.removeChild(throwingMan); throwingMan = null; } if (weapon) { game.removeChild(weapon); weapon = null; weaponSpawned = false; } // Clear bullets for (var b = bullets.length - 1; b >= 0; b--) { game.removeChild(bullets[b]); } bullets = []; // Clear deadly trees for (var d = deadlyTrees.length - 1; d >= 0; d--) { game.removeChild(deadlyTrees[d]); } deadlyTrees = []; lastIntersectingDeadly = []; // Transition to fourth scene with 6 skeletons specialScene = false; specialSceneInitialized = false; fourthScene = true; fourthSceneInitialized = false; game.setBackgroundColor(0x4B0082); // Dark purple background for fourth scene }, 3000); } } } } // Only run countdown timer logic if not in special scene if (!specialScene) { // Check if player hit something (score changed) var scoreChanged = score !== lastScore; if (scoreChanged) { // Player hit something, reset countdown countdownTimer = 10; updateCountdownText(); } else { // Player didn't hit anything, countdown every second (60 ticks = 1 second) if (LK.ticks % 60 === 0) { countdownTimer--; updateCountdownText(); if (countdownTimer <= 0) { if (score < 10) { // Show F- grade for low score var gradeText = new Text2('F-', { size: 300, fill: 0xFF0000 }); gradeText.anchor.set(0.5, 0.5); gradeText.x = 2048 / 2; gradeText.y = 2732 / 2; game.addChild(gradeText); // Show grade for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); } else if (score >= 10 && score <= 30) { // Show F+ grade for score between 10 and 30 var gradeText = new Text2('F+', { size: 300, fill: 0xFFA500 }); gradeText.anchor.set(0.5, 0.5); gradeText.x = 2048 / 2; gradeText.y = 2732 / 2; game.addChild(gradeText); // Show grade for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); } else if (score >= 30 && score <= 50) { // Show D- grade for score between 30 and 50 var gradeText = new Text2('D-', { size: 300, fill: 0x800080 }); gradeText.anchor.set(0.5, 0.5); gradeText.x = 2048 / 2; gradeText.y = 2732 / 2; game.addChild(gradeText); // Show grade for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); } else { LK.showGameOver(); } } } } } // Only run upward counter logic if not in special scene if (!specialScene) { // Upward counter increments every second (60 ticks = 1 second) if (LK.ticks % 60 === 0) { upwardCounter++; updateUpwardCounterText(); if (upwardCounter >= 90) { if (score < 10) { // Show F- grade for low score var gradeText = new Text2('F-', { size: 300, fill: 0xFF0000 }); gradeText.anchor.set(0.5, 0.5); gradeText.x = 2048 / 2; gradeText.y = 2732 / 2; game.addChild(gradeText); // Show grade for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); } else if (score >= 10 && score <= 30) { // Show F+ grade for score between 10 and 30 var gradeText = new Text2('F+', { size: 300, fill: 0xFFA500 }); gradeText.anchor.set(0.5, 0.5); gradeText.x = 2048 / 2; gradeText.y = 2732 / 2; game.addChild(gradeText); // Show grade for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); } else if (score >= 30 && score <= 50) { // Show D- grade for score between 30 and 50 var gradeText = new Text2('D-', { size: 300, fill: 0x800080 }); gradeText.anchor.set(0.5, 0.5); gradeText.x = 2048 / 2; gradeText.y = 2732 / 2; game.addChild(gradeText); // Show grade for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); } else { LK.showGameOver(); } } } } // Handle fourth scene logic if (fourthScene && !fourthSceneInitialized) { // Initialize fourth scene with 6 skeletons for (var s = 0; s < 6; s++) { var skeleton = new MultiSkeleton(); // Position skeletons in two rows if (s < 3) { skeleton.x = (s + 1) * (2048 / 4); skeleton.y = 200; } else { skeleton.x = (s - 2) * (2048 / 4); skeleton.y = 400; } multiSkeletons.push(skeleton); game.addChild(skeleton); } fourthSceneInitialized = true; } if (fourthScene) { // Check collisions with thrown trees for (var ft = fourthSceneTrees.length - 1; ft >= 0; ft--) { var thrownTree = fourthSceneTrees[ft]; var currentIntersectingFourth = car.intersects(thrownTree); if (!lastIntersectingFourthTrees[ft] && currentIntersectingFourth) { // Check if it's a deadly tree or point tree if (thrownTree.tint === 0xFF0000) { // Deadly tree - instant death var deathText = new Text2('ÖLDÜN!', { size: 300, fill: 0xFF0000 }); deathText.anchor.set(0.5, 0.5); deathText.x = 2048 / 2; deathText.y = 2732 / 2; game.addChild(deathText); // Show message for 2 seconds before game over LK.setTimeout(function () { LK.showGameOver(); }, 2000); return; } else { // Point tree - add points score += thrownTree.pointValue || 1; updateScoreText(); car.flash(); thrownTree.hitAnim(); // Remove the hit tree game.removeChild(thrownTree); fourthSceneTrees.splice(ft, 1); lastIntersectingFourthTrees.splice(ft, 1); // Check win condition for fourth scene if (score >= 400) { LK.showYouWin(); return; } } } if (ft < lastIntersectingFourthTrees.length) { lastIntersectingFourthTrees[ft] = currentIntersectingFourth; } } } // Update tracking variables lastCarX = car.x; lastCarY = car.y; lastScore = score; }; // --- Initialize score --- score = 0; updateScoreText(); // --- Initialize upward counter --- upwardCounter = 1; updateUpwardCounterText(); // --- Initialize bottom-left counter --- bottomLeftCounter = 150; updateBottomLeftCounterText(); // --- Initialize tracking variables --- lastCarX = car.x; lastCarY = car.y; lastScore = score;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bullet class for weapon projectiles
var Bullet = Container.expand(function () {
var self = Container.call(this);
// Create bullet visual (small circle)
var bulletAsset = self.attachAsset('manCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bulletAsset.width = 20;
bulletAsset.height = 20;
bulletAsset.tint = 0xFFFF00; // Yellow color for bullet
self.speed = 12;
self.targetX = 0;
self.targetY = 0;
// Update method for bullet movement towards target
self.update = function () {
// Move towards target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Remove bullet if it reaches target or goes off screen
if (distance < 30 || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
if (self.parent) {
self.parent.removeChild(self);
}
var index = bullets.indexOf(self);
if (index !== -1) {
bullets.splice(index, 1);
}
}
};
return self;
});
// Car class
var Car = Container.expand(function () {
var self = Container.call(this);
// Attach car asset (red box, 200x120)
var carAsset = self.attachAsset('car', {
anchorX: 0.5,
anchorY: 0.5
});
// Set size for car asset
carAsset.width = 200;
carAsset.height = 120;
// For touch feedback
self.flash = function () {
tween(self, {
alpha: 0.5
}, {
duration: 80,
onFinish: function onFinish() {
tween(self, {
alpha: 1
}, {
duration: 120
});
}
});
};
return self;
});
// DeadlyTree class for special scene
var DeadlyTree = Container.expand(function () {
var self = Container.call(this);
// Attach tree asset (red tinted, 100x100)
var treeAsset = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5
});
treeAsset.width = 100;
treeAsset.height = 100;
treeAsset.tint = 0xFF0000; // Red tint for deadly trees
self.speed = 24; // Falling speed (3x faster)
self.isFollowing = false;
self.followSpeed = 8; // Speed when following player
// Start following the player
self.startFollowing = function () {
self.isFollowing = true;
};
// Stop following and disappear with tween
self.stopFollowing = function () {
self.isFollowing = false;
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
// Update method for falling motion or following
self.update = function () {
if (self.isFollowing && car) {
// Move towards car position
var dx = car.x - self.x;
var dy = car.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.followSpeed;
self.y += dy / distance * self.followSpeed;
}
} else {
self.y += self.speed;
}
};
return self;
});
// GoldenTree class
var GoldenTree = Container.expand(function () {
var self = Container.call(this);
// Attach tree asset (golden, 140x140 - slightly bigger)
var treeAsset = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5
});
treeAsset.width = 140;
treeAsset.height = 140;
treeAsset.tint = 0xFFD700; // Golden tint color
self.pointValue = 10; // Golden tree gives 10 points
// Add golden glow effect
self.glowEffect = function () {
tween(self, {
alpha: 0.7
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
alpha: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.glowEffect(); // Loop the glow effect
}
});
}
});
};
// Start glow effect immediately
self.glowEffect();
// Special golden hit animation
self.hitAnim = function () {
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeIn
});
}
});
};
return self;
});
// MultiSkeleton class for fourth scene
var MultiSkeleton = Container.expand(function () {
var self = Container.call(this);
// Create circular shape for the skeleton
var skeletonAsset = self.attachAsset('manCircle', {
anchorX: 0.5,
anchorY: 0.5
});
skeletonAsset.tint = 0x800080; // Purple tint for skeletons
self.throwTimer = 0;
self.throwInterval = 60; // Fixed 1 second interval (60 ticks)
// Update method for throwing trees
self.update = function () {
self.throwTimer++;
if (self.throwTimer >= self.throwInterval) {
// Throw either deadly tree or point tree randomly
var isDeadly = Math.random() < 0.5; // 50% chance for deadly tree
var thrownTree;
if (isDeadly) {
thrownTree = new DeadlyTree();
} else {
thrownTree = new Tree();
}
// Find valid position that doesn't overlap with existing trees
var validPosition = false;
var tries = 0;
var targetX, targetY;
do {
targetX = self.x + (Math.random() - 0.5) * 400; // Random position around skeleton
targetY = self.y + 50 + Math.random() * 200;
validPosition = true;
tries++;
// Check distance from all existing fourth scene trees
for (var ft = 0; ft < fourthSceneTrees.length; ft++) {
var existingTree = fourthSceneTrees[ft];
var dx = targetX - existingTree.x;
var dy = targetY - existingTree.y;
var distanceToTree = Math.sqrt(dx * dx + dy * dy);
if (distanceToTree < 150) {
// Minimum distance of 150 pixels
validPosition = false;
break;
}
}
} while (!validPosition && tries < 10);
thrownTree.x = self.x;
thrownTree.y = self.y + 50;
// Set target towards calculated position
thrownTree.targetX = targetX;
thrownTree.targetY = targetY;
thrownTree.speed = 8;
thrownTree.isThrown = true;
// Override update to move towards target
thrownTree.update = function () {
if (thrownTree.isThrown) {
var dx = thrownTree.targetX - thrownTree.x;
var dy = thrownTree.targetY - thrownTree.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
thrownTree.x += dx / distance * thrownTree.speed;
thrownTree.y += dy / distance * thrownTree.speed;
}
// Remove if goes off screen
if (thrownTree.x < -100 || thrownTree.x > 2148 || thrownTree.y < -100 || thrownTree.y > 2832) {
if (thrownTree.parent) {
thrownTree.parent.removeChild(thrownTree);
}
var index = fourthSceneTrees.indexOf(thrownTree);
if (index !== -1) {
fourthSceneTrees.splice(index, 1);
lastIntersectingFourthTrees.splice(index, 1);
}
}
}
};
fourthSceneTrees.push(thrownTree);
lastIntersectingFourthTrees.push(false);
game.addChild(thrownTree);
self.throwTimer = 0;
self.throwInterval = 60; // Reset to 1 second interval
}
};
return self;
});
// Pole class
var Pole = Container.expand(function () {
var self = Container.call(this);
// Attach pole asset (thin metal pole, 30x300)
var poleAsset = self.attachAsset('pole', {
anchorX: 0.5,
anchorY: 0.5
});
self.pointValue = -10; // Pole reduces 10 points
// Animate on hit (shake effect)
self.hitAnim = function () {
tween(self, {
rotation: 0.2
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
rotation: -0.2
}, {
duration: 80,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0
}, {
duration: 80,
easing: tween.easeIn
});
}
});
}
});
};
return self;
});
// PurpleTree class
var PurpleTree = Container.expand(function () {
var self = Container.call(this);
// Attach tree asset (purple, 140x140 - slightly bigger)
var treeAsset = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5
});
treeAsset.width = 140;
treeAsset.height = 140;
treeAsset.tint = 0x8A2BE2; // Purple tint color
self.pointValue = 30; // Purple tree gives 30 points
// Add purple glow effect
self.glowEffect = function () {
tween(self, {
alpha: 0.6
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
alpha: 1
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.glowEffect(); // Loop the glow effect
}
});
}
});
};
// Start glow effect immediately
self.glowEffect();
// Special purple hit animation
self.hitAnim = function () {
tween(self, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 180,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 180,
easing: tween.easeIn
});
}
});
};
return self;
});
// ThrowingMan class for special scene
var ThrowingMan = Container.expand(function () {
var self = Container.call(this);
// Create circular shape for the man
var manAsset = self.attachAsset('manCircle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Tree class
var Tree = Container.expand(function () {
var self = Container.call(this);
// Attach tree asset (green ellipse, 120x120)
var treeAsset = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5
});
treeAsset.width = 120;
treeAsset.height = 120;
treeAsset.tint = 0x228B22;
self.pointValue = 1; // Normal tree gives 1 point
// Animate on hit
self.hitAnim = function () {
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeIn
});
}
});
};
return self;
});
// Weapon class for special scene
var Weapon = Container.expand(function () {
var self = Container.call(this);
// Create weapon visual using weapon image asset
var weaponAsset = self.attachAsset('weapon', {
anchorX: 0.5,
anchorY: 0.5
});
weaponAsset.rotation = Math.PI / 4; // 45 degree rotation
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Sky blue
});
/****
* Game Code
****/
// --- Game constants ---
var CAR_START_X = 2048 / 2;
var CAR_START_Y = 2732 - 350;
var TREE_MIN_Y = 350;
var TREE_MAX_Y = 2732 - 350;
var TREE_MIN_X = 150;
var TREE_MAX_X = 2048 - 150;
var WIN_SCORE = 100000000;
// --- Game state ---
var car = null;
var trees = [];
var poles = [];
var score = 0;
var scoreTxt = null;
var dragNode = null;
var lastIntersecting = [];
var lastIntersectingPoles = [];
var goldenTreeSpawned = false;
var treesHitThisRound = 0;
var purpleTreeCounter = 0;
var polesSpawnedThisRound = 0;
var countdownTimer = 10;
var countdownTxt = null;
var lastCarX = 0;
var lastCarY = 0;
var lastScore = 0;
var upwardCounter = 1;
var upwardCounterTxt = null;
var specialScene = false;
var specialSceneInitialized = false;
var throwingMan = null;
var deadlyTrees = [];
var lastIntersectingDeadly = [];
var throwTimer = 0;
var followingStartTime = null;
var followingDuration = 10000; // 10 seconds in milliseconds
var allFollowingTreesGone = false; // Flag to track if all following trees have disappeared
var bottomLeftCounter = 150;
var bottomLeftCounterTxt = null;
var weapon = null;
var weaponSpawned = false;
var bullets = [];
var lastIntersectingWeapon = false;
var skeletonHealth = 1000;
var skeletonHealthTxt = null;
var fourthScene = false;
var fourthSceneInitialized = false;
var multiSkeletons = [];
var fourthSceneTrees = [];
var lastIntersectingFourthTrees = [];
// --- Create and add car ---
car = new Car();
car.x = CAR_START_X;
car.y = CAR_START_Y;
game.addChild(car);
// --- Create and add trees ---
for (var i = 0; i < 5; i++) {
var tree = new Tree();
tree.x = getRandomTreeX();
tree.y = getRandomTreeY();
trees.push(tree);
lastIntersecting.push(false);
game.addChild(tree);
}
// --- Create and add poles ---
for (var i = 0; i < 5; i++) {
var pole = new Pole();
var tries = 0;
var validPosition = false;
do {
pole.x = getRandomTreeX();
pole.y = getRandomTreeY();
tries++;
validPosition = true;
// Check distance from car
if (distance(car.x, car.y, pole.x, pole.y) < 300) {
validPosition = false;
}
// Check distance from all existing trees
for (var t = 0; t < trees.length; t++) {
if (distance(pole.x, pole.y, trees[t].x, trees[t].y) < 200) {
validPosition = false;
break;
}
}
// Check distance from all existing poles
for (var p = 0; p < poles.length; p++) {
if (distance(pole.x, pole.y, poles[p].x, poles[p].y) < 200) {
validPosition = false;
break;
}
}
} while (!validPosition && tries < 20);
poles.push(pole);
lastIntersectingPoles.push(false);
game.addChild(pole);
}
// --- Score text ---
scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// --- Countdown timer text ---
countdownTxt = new Text2('10', {
size: 100,
fill: 0xFF0000
});
countdownTxt.anchor.set(1, 1);
LK.gui.bottomRight.addChild(countdownTxt);
// --- Upward counter text ---
upwardCounterTxt = new Text2('1', {
size: 100,
fill: 0x006400
});
upwardCounterTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(upwardCounterTxt);
// --- Bottom-left counter text ---
bottomLeftCounterTxt = new Text2('150', {
size: 100,
fill: 0x8B4513
});
bottomLeftCounterTxt.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(bottomLeftCounterTxt);
// --- Skeleton health bar text ---
skeletonHealthTxt = new Text2('ENES BATUR: 1000', {
size: 80,
fill: 0xFF0000
});
skeletonHealthTxt.anchor.set(0, 0.5);
skeletonHealthTxt.visible = false; // Initially hidden until special scene
game.addChild(skeletonHealthTxt);
// --- Helper functions ---
function getRandomTreeX() {
return TREE_MIN_X + Math.floor(Math.random() * (TREE_MAX_X - TREE_MIN_X));
}
function getRandomTreeY() {
return TREE_MIN_Y + Math.floor(Math.random() * (TREE_MAX_Y - TREE_MIN_Y));
}
function updateScoreText() {
scoreTxt.setText(score);
}
function updateCountdownText() {
countdownTxt.setText(countdownTimer);
}
function updateUpwardCounterText() {
upwardCounterTxt.setText(upwardCounter);
}
function updateBottomLeftCounterText() {
bottomLeftCounterTxt.setText(bottomLeftCounter);
}
function updateSkeletonHealthText() {
skeletonHealthTxt.setText('ENES BATUR: ' + skeletonHealth);
}
function spawnNewTree() {
var newTree;
// Spawn purple tree every 40 normal trees (1 in 40 chance)
purpleTreeCounter++;
if (purpleTreeCounter >= 40) {
newTree = new PurpleTree();
purpleTreeCounter = 0; // Reset counter
} else if (treesHitThisRound % 5 === 0 && !goldenTreeSpawned) {
// Spawn golden tree once every 5 hits if not already spawned this round
newTree = new GoldenTree();
goldenTreeSpawned = true;
} else {
newTree = new Tree();
// Reset golden tree availability after 10 hits
if (treesHitThisRound >= 10) {
goldenTreeSpawned = false;
treesHitThisRound = 0;
}
}
// Position new tree randomly (avoid placing too close to car and existing poles)
var tries = 0;
var validPosition = false;
do {
newTree.x = getRandomTreeX();
newTree.y = getRandomTreeY();
tries++;
validPosition = true;
// Check distance from car
if (distance(car.x, car.y, newTree.x, newTree.y) < 300) {
validPosition = false;
}
// Check distance from all existing poles
for (var p = 0; p < poles.length; p++) {
if (distance(newTree.x, newTree.y, poles[p].x, poles[p].y) < 200) {
validPosition = false;
break;
}
}
// Check distance from all existing trees
for (var t = 0; t < trees.length; t++) {
if (distance(newTree.x, newTree.y, trees[t].x, trees[t].y) < 200) {
validPosition = false;
break;
}
}
} while (!validPosition && tries < 20);
trees.push(newTree);
lastIntersecting.push(false);
game.addChild(newTree);
// Calculate current round based on score (every 50 points is a new round)
var currentRound = Math.floor(score / 50);
var polesPerRound = Math.max(1, 5 - currentRound); // Start with 5, decrease by 1 each round, minimum 1
// Spawn poles (decreasing each round)
if (polesSpawnedThisRound < polesPerRound) {
var newPole = new Pole();
var tries = 0;
var validPolePosition = false;
do {
newPole.x = getRandomTreeX();
newPole.y = getRandomTreeY();
tries++;
validPolePosition = true;
// Check distance from car
if (distance(car.x, car.y, newPole.x, newPole.y) < 300) {
validPolePosition = false;
}
// Check distance from all existing trees
for (var t = 0; t < trees.length; t++) {
if (distance(newPole.x, newPole.y, trees[t].x, trees[t].y) < 200) {
validPolePosition = false;
break;
}
}
// Check distance from all existing poles
for (var p = 0; p < poles.length; p++) {
if (distance(newPole.x, newPole.y, poles[p].x, poles[p].y) < 200) {
validPolePosition = false;
break;
}
}
} while (!validPolePosition && tries < 20);
poles.push(newPole);
lastIntersectingPoles.push(false);
game.addChild(newPole);
polesSpawnedThisRound++;
}
// Reset pole counter when round is complete
if (polesSpawnedThisRound >= polesPerRound && treesHitThisRound >= 10) {
polesSpawnedThisRound = 0;
}
}
// --- Move handler for dragging car ---
function handleMove(x, y, obj) {
if (dragNode) {
var newX = x;
var newY = Math.max(200, Math.min(2732 - 100, y));
// Screen wrapping for X axis
if (newX > 2048) {
newX = 0; // Car exits right, appears on left
} else if (newX < 0) {
newX = 2048; // Car exits left, appears on right
}
dragNode.x = newX;
dragNode.y = newY;
}
// Collision detection for all trees
for (var i = 0; i < trees.length; i++) {
var tree = trees[i];
var currentIntersecting = car.intersects(tree);
if (!lastIntersecting[i] && currentIntersecting) {
// Car just hit tree
score += tree.pointValue;
treesHitThisRound++;
updateScoreText();
// Update bottom-left counter
bottomLeftCounter -= tree.pointValue;
if (bottomLeftCounter <= 0) {
bottomLeftCounter = 0;
bottomLeftCounterTxt.visible = false;
}
updateBottomLeftCounterText();
// Animate car and tree
car.flash();
tree.hitAnim();
// Remove the hit tree
game.removeChild(tree);
trees.splice(i, 1);
lastIntersecting.splice(i, 1);
i--; // Adjust index since we removed an element
// Spawn new tree (normal or golden based on conditions)
spawnNewTree();
// Win condition
if (score >= WIN_SCORE) {
LK.showYouWin();
}
}
if (i >= 0 && i < lastIntersecting.length) {
lastIntersecting[i] = currentIntersecting;
}
}
// Collision detection for all poles
for (var j = 0; j < poles.length; j++) {
var pole = poles[j];
var currentIntersectingPole = car.intersects(pole);
if (!lastIntersectingPoles[j] && currentIntersectingPole) {
// Car just hit pole
score += pole.pointValue; // This will subtract 10 points
updateScoreText();
// Update bottom-left counter (increase by the amount of points lost)
bottomLeftCounter += Math.abs(pole.pointValue);
updateBottomLeftCounterText();
// Animate car and pole
car.flash();
pole.hitAnim();
// Remove the hit pole
game.removeChild(pole);
poles.splice(j, 1);
lastIntersectingPoles.splice(j, 1);
j--; // Adjust index since we removed an element
// Check for game over (negative score)
if (score < 0) {
// Show "eziksin" message for losing with negative score
var loserText = new Text2('eziksin', {
size: 300,
fill: 0x000000 // Black color
});
loserText.anchor.set(0.5, 0.5);
loserText.x = 2048 / 2;
loserText.y = 2732 / 2;
game.addChild(loserText);
// Show message for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
}
if (j >= 0 && j < lastIntersectingPoles.length) {
lastIntersectingPoles[j] = currentIntersectingPole;
}
}
}
// --- Utility: distance between two points ---
function distance(x1, y1, x2, y2) {
var dx = x1 - x2;
var dy = y1 - y2;
return Math.sqrt(dx * dx + dy * dy);
}
// --- Touch/drag events ---
game.down = function (x, y, obj) {
// Only start drag if touch is on car (within 120px radius)
var dx = x - car.x;
var dy = y - car.y;
if (dx * dx + dy * dy < 120 * 120) {
dragNode = car;
handleMove(x, y, obj);
}
};
game.move = handleMove;
game.up = function (x, y, obj) {
dragNode = null;
};
// --- Game update loop (not needed for movement, but for future extensibility) ---
game.update = function () {
// Check for special scene transition (150+ score)
if (score >= 150 && !specialScene) {
specialScene = true;
// Clear existing game elements
for (var i = trees.length - 1; i >= 0; i--) {
game.removeChild(trees[i]);
}
trees = [];
lastIntersecting = [];
for (var j = poles.length - 1; j >= 0; j--) {
game.removeChild(poles[j]);
}
poles = [];
lastIntersectingPoles = [];
// Change background to darker for special scene
game.setBackgroundColor(0x2F4F4F); // Dark gray
}
// Handle special scene logic
if (specialScene && !specialSceneInitialized) {
// Initialize special scene
throwingMan = new ThrowingMan();
throwingMan.x = 2048 / 2;
throwingMan.y = 200;
game.addChild(throwingMan);
// Show and position skeleton health bar
skeletonHealthTxt.visible = true;
skeletonHealthTxt.x = throwingMan.x + 100; // Position to the right of skeleton
skeletonHealthTxt.y = throwingMan.y;
skeletonHealth = 1000; // Reset health
updateSkeletonHealthText();
// Spawn weapon immediately in special scene
if (!weaponSpawned) {
weapon = new Weapon();
weapon.x = Math.random() * (2048 - 200) + 100; // Random X within game bounds
weapon.y = Math.random() * (2732 - 400) + 200; // Random Y within game bounds
game.addChild(weapon);
weaponSpawned = true;
}
specialSceneInitialized = true;
}
if (specialScene) {
// Initialize following start time when first entering special scene
if (followingStartTime === null) {
followingStartTime = Date.now();
}
// Spawn deadly trees that follow player for 10 seconds, then disappear
if (LK.ticks % 120 === 0 && deadlyTrees.length < 10 && !allFollowingTreesGone) {
var newDeadlyTree = new DeadlyTree();
newDeadlyTree.x = Math.random() * 2048;
newDeadlyTree.y = -100; // Start above screen
newDeadlyTree.spawnTime = Date.now();
newDeadlyTree.startFollowing();
deadlyTrees.push(newDeadlyTree);
lastIntersectingDeadly.push(false);
game.addChild(newDeadlyTree);
// Set timer to make tree disappear after 10 seconds
LK.setTimeout(function () {
if (newDeadlyTree.parent) {
newDeadlyTree.stopFollowing();
var index = deadlyTrees.indexOf(newDeadlyTree);
if (index !== -1) {
deadlyTrees.splice(index, 1);
lastIntersectingDeadly.splice(index, 1);
}
// Check if all deadly trees are gone
if (deadlyTrees.length === 0 && !allFollowingTreesGone) {
allFollowingTreesGone = true;
// Show message near the throwing man
var messageText = new Text2('O zaman bunu al', {
size: 80,
fill: 0xFFFFFF
});
messageText.anchor.set(0.5, 0.5);
messageText.x = throwingMan.x;
messageText.y = throwingMan.y - 100;
game.addChild(messageText);
// Spawn weapon at random location
if (!weaponSpawned) {
weapon = new Weapon();
weapon.x = Math.random() * (2048 - 200) + 100; // Random X within game bounds
weapon.y = Math.random() * (2732 - 400) + 200; // Random Y within game bounds
game.addChild(weapon);
weaponSpawned = true;
}
}
}
}, 10000);
}
// Check collision with deadly trees
for (var k = deadlyTrees.length - 1; k >= 0; k--) {
var deadlyTree = deadlyTrees[k];
var currentIntersectingDeadly = car.intersects(deadlyTree);
// Check if tree has been alive for 10 seconds
if (deadlyTree.spawnTime && Date.now() - deadlyTree.spawnTime >= 10000) {
deadlyTree.stopFollowing();
deadlyTrees.splice(k, 1);
lastIntersectingDeadly.splice(k, 1);
// Check if all deadly trees are gone
if (deadlyTrees.length === 0 && !allFollowingTreesGone) {
allFollowingTreesGone = true;
// Show message near the throwing man
var messageText = new Text2('O zaman bunu al', {
size: 80,
fill: 0xFFFFFF
});
messageText.anchor.set(0.5, 0.5);
messageText.x = throwingMan.x;
messageText.y = throwingMan.y - 100; // Position above the throwing man
game.addChild(messageText);
// Spawn weapon at random location
if (!weaponSpawned) {
weapon = new Weapon();
weapon.x = Math.random() * (2048 - 200) + 100; // Random X within game bounds
weapon.y = Math.random() * (2732 - 400) + 200; // Random Y within game bounds
game.addChild(weapon);
weaponSpawned = true;
}
}
continue;
}
// Check if tree went off screen (only for non-following trees)
if (!deadlyTree.isFollowing && deadlyTree.y > 2732 + 100) {
game.removeChild(deadlyTree);
deadlyTrees.splice(k, 1);
lastIntersectingDeadly.splice(k, 1);
continue;
}
// Check collision - instant death
if (!lastIntersectingDeadly[k] && currentIntersectingDeadly) {
// Show death message
var deathText = new Text2('ÖLDÜN!', {
size: 300,
fill: 0xFF0000
});
deathText.anchor.set(0.5, 0.5);
deathText.x = 2048 / 2;
deathText.y = 2732 / 2;
game.addChild(deathText);
// Show message for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
return;
}
if (k < lastIntersectingDeadly.length) {
lastIntersectingDeadly[k] = currentIntersectingDeadly;
}
}
// Check weapon collision and bullet firing
if (weapon && throwingMan) {
var currentIntersectingWeapon = car.intersects(weapon);
if (!lastIntersectingWeapon && currentIntersectingWeapon) {
// Car touched weapon, make weapon follow car
weapon.isFollowingCar = true;
// Fire bullet at skeleton
var newBullet = new Bullet();
newBullet.x = car.x;
newBullet.y = car.y;
newBullet.targetX = throwingMan.x;
newBullet.targetY = throwingMan.y;
bullets.push(newBullet);
game.addChild(newBullet);
}
lastIntersectingWeapon = currentIntersectingWeapon;
// Make weapon follow car if attached
if (weapon.isFollowingCar) {
weapon.x = car.x + 60; // Offset to the right of car
weapon.y = car.y;
}
}
// Check bullet collisions with skeleton
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
if (throwingMan && bullet.intersects && bullet.intersects(throwingMan)) {
// Bullet hit skeleton - reduce health
skeletonHealth -= 5;
updateSkeletonHealthText();
// Remove bullet
game.removeChild(bullet);
bullets.splice(b, 1);
// Flash skeleton red when hit
tween(throwingMan, {
tint: 0xFF0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(throwingMan, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
});
// Check if skeleton is defeated
if (skeletonHealth <= 0) {
// Hide health bar
skeletonHealthTxt.visible = false;
// Show victory message
var victoryText = new Text2('Enes batur yenildi', {
size: 200,
fill: 0x00FF00
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 2048 / 2;
victoryText.y = 2732 / 2;
game.addChild(victoryText);
// Show victory for 3 seconds then transition to fourth scene
LK.setTimeout(function () {
// Clear special scene elements
game.removeChild(victoryText);
if (throwingMan) {
game.removeChild(throwingMan);
throwingMan = null;
}
if (weapon) {
game.removeChild(weapon);
weapon = null;
weaponSpawned = false;
}
// Clear bullets
for (var b = bullets.length - 1; b >= 0; b--) {
game.removeChild(bullets[b]);
}
bullets = [];
// Clear deadly trees
for (var d = deadlyTrees.length - 1; d >= 0; d--) {
game.removeChild(deadlyTrees[d]);
}
deadlyTrees = [];
lastIntersectingDeadly = [];
// Transition to fourth scene with 6 skeletons
specialScene = false;
specialSceneInitialized = false;
fourthScene = true;
fourthSceneInitialized = false;
game.setBackgroundColor(0x4B0082); // Dark purple background for fourth scene
}, 3000);
}
}
}
}
// Only run countdown timer logic if not in special scene
if (!specialScene) {
// Check if player hit something (score changed)
var scoreChanged = score !== lastScore;
if (scoreChanged) {
// Player hit something, reset countdown
countdownTimer = 10;
updateCountdownText();
} else {
// Player didn't hit anything, countdown every second (60 ticks = 1 second)
if (LK.ticks % 60 === 0) {
countdownTimer--;
updateCountdownText();
if (countdownTimer <= 0) {
if (score < 10) {
// Show F- grade for low score
var gradeText = new Text2('F-', {
size: 300,
fill: 0xFF0000
});
gradeText.anchor.set(0.5, 0.5);
gradeText.x = 2048 / 2;
gradeText.y = 2732 / 2;
game.addChild(gradeText);
// Show grade for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else if (score >= 10 && score <= 30) {
// Show F+ grade for score between 10 and 30
var gradeText = new Text2('F+', {
size: 300,
fill: 0xFFA500
});
gradeText.anchor.set(0.5, 0.5);
gradeText.x = 2048 / 2;
gradeText.y = 2732 / 2;
game.addChild(gradeText);
// Show grade for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else if (score >= 30 && score <= 50) {
// Show D- grade for score between 30 and 50
var gradeText = new Text2('D-', {
size: 300,
fill: 0x800080
});
gradeText.anchor.set(0.5, 0.5);
gradeText.x = 2048 / 2;
gradeText.y = 2732 / 2;
game.addChild(gradeText);
// Show grade for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else {
LK.showGameOver();
}
}
}
}
}
// Only run upward counter logic if not in special scene
if (!specialScene) {
// Upward counter increments every second (60 ticks = 1 second)
if (LK.ticks % 60 === 0) {
upwardCounter++;
updateUpwardCounterText();
if (upwardCounter >= 90) {
if (score < 10) {
// Show F- grade for low score
var gradeText = new Text2('F-', {
size: 300,
fill: 0xFF0000
});
gradeText.anchor.set(0.5, 0.5);
gradeText.x = 2048 / 2;
gradeText.y = 2732 / 2;
game.addChild(gradeText);
// Show grade for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else if (score >= 10 && score <= 30) {
// Show F+ grade for score between 10 and 30
var gradeText = new Text2('F+', {
size: 300,
fill: 0xFFA500
});
gradeText.anchor.set(0.5, 0.5);
gradeText.x = 2048 / 2;
gradeText.y = 2732 / 2;
game.addChild(gradeText);
// Show grade for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else if (score >= 30 && score <= 50) {
// Show D- grade for score between 30 and 50
var gradeText = new Text2('D-', {
size: 300,
fill: 0x800080
});
gradeText.anchor.set(0.5, 0.5);
gradeText.x = 2048 / 2;
gradeText.y = 2732 / 2;
game.addChild(gradeText);
// Show grade for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else {
LK.showGameOver();
}
}
}
}
// Handle fourth scene logic
if (fourthScene && !fourthSceneInitialized) {
// Initialize fourth scene with 6 skeletons
for (var s = 0; s < 6; s++) {
var skeleton = new MultiSkeleton();
// Position skeletons in two rows
if (s < 3) {
skeleton.x = (s + 1) * (2048 / 4);
skeleton.y = 200;
} else {
skeleton.x = (s - 2) * (2048 / 4);
skeleton.y = 400;
}
multiSkeletons.push(skeleton);
game.addChild(skeleton);
}
fourthSceneInitialized = true;
}
if (fourthScene) {
// Check collisions with thrown trees
for (var ft = fourthSceneTrees.length - 1; ft >= 0; ft--) {
var thrownTree = fourthSceneTrees[ft];
var currentIntersectingFourth = car.intersects(thrownTree);
if (!lastIntersectingFourthTrees[ft] && currentIntersectingFourth) {
// Check if it's a deadly tree or point tree
if (thrownTree.tint === 0xFF0000) {
// Deadly tree - instant death
var deathText = new Text2('ÖLDÜN!', {
size: 300,
fill: 0xFF0000
});
deathText.anchor.set(0.5, 0.5);
deathText.x = 2048 / 2;
deathText.y = 2732 / 2;
game.addChild(deathText);
// Show message for 2 seconds before game over
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
return;
} else {
// Point tree - add points
score += thrownTree.pointValue || 1;
updateScoreText();
car.flash();
thrownTree.hitAnim();
// Remove the hit tree
game.removeChild(thrownTree);
fourthSceneTrees.splice(ft, 1);
lastIntersectingFourthTrees.splice(ft, 1);
// Check win condition for fourth scene
if (score >= 400) {
LK.showYouWin();
return;
}
}
}
if (ft < lastIntersectingFourthTrees.length) {
lastIntersectingFourthTrees[ft] = currentIntersectingFourth;
}
}
}
// Update tracking variables
lastCarX = car.x;
lastCarY = car.y;
lastScore = score;
};
// --- Initialize score ---
score = 0;
updateScoreText();
// --- Initialize upward counter ---
upwardCounter = 1;
updateUpwardCounterText();
// --- Initialize bottom-left counter ---
bottomLeftCounter = 150;
updateBottomLeftCounterText();
// --- Initialize tracking variables ---
lastCarX = car.x;
lastCarY = car.y;
lastScore = score;