User prompt
make it so on the 3rd cycle the background turns yellow
User prompt
make the newer plants not die until the next cycle
User prompt
make it so that the cycle restarts for newer plants
User prompt
make it so after a cycle the plant dies
User prompt
make it so lichen can be dragged and deleted
User prompt
change the lichen icon into its texture
User prompt
retexture the lichen organisim
User prompt
make the lichen organisim its own class
User prompt
rename to Donothing organisim into lichen
User prompt
put the organisim in the selection bar
User prompt
put the organisim in the selection bar
User prompt
add a new organisim that does NOTHING
User prompt
make a bottom selection area for abiotic things like rocks
User prompt
move the delete button a bit down
User prompt
put the deleting button under the cycle counter
User prompt
make a new button that when clicked makes the player into deleting mode and when you are in deleting mode they click any organism to remove them and click the deleting button again to disable deleting mod
User prompt
Make it so that they cycle button pauses ALL activity
User prompt
Move it a bit down
User prompt
Move the button under the cycle counter
User prompt
Make a button that pauses the cycle and all creatures and organisms will freeze! Nothing can die eat ect until unpaused
User prompt
Remove the lifespan for fungi
User prompt
Remove the barrier that is around the carnivore that prevents the herbivore from running
User prompt
Make it so when a carnivore gets tired the herbivore its chasing charges away until its far enough
User prompt
Make a new text that is a timer that will countdown when the cycle will finish! And put it under the cycle counter
User prompt
Make it so that if the herbivore doesn’t eat in 2 cycles AKA 80 seconds they starve and die
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Carnivore class var Carnivore = Container.expand(function () { var self = Container.call(this); var carnAsset = self.attachAsset('carnivore', { anchorX: 0.5, anchorY: 0.5 }); self.target = null; self.speed = 1.5 + Math.random() * 1.2; self.eaten = false; self._chaseTime = 0; // How long we've been chasing a herbivore self._tired = false; // Are we tired? self._tiredTimer = 0; // How long left to rest // --- State management for wandering/hungry --- self.state = "hungry"; // "wandering" or "hungry" self._eatCooldown = 0; // frames left in wandering after eating self.update = function () { if (self.eaten) return; // Handle tired state if (self._tired) { self._tiredTimer--; if (self._tiredTimer <= 0) { self._tired = false; self._chaseTime = 0; } // While tired, don't chase or wander, just stand still return; } // Handle eat cooldown (wandering after eating) if (self._eatCooldown > 0) { self._eatCooldown--; if (self._eatCooldown === 0) { self.state = "hungry"; } } // State: wandering (ignore prey) if (self.state === "wandering") { self.target = null; // Don't chase // --- Random wandering when not chasing herbivores --- if (!self._wanderTimer || self._wanderTimer <= 0) { var angle = Math.random() * Math.PI * 2; self._wanderAngle = angle; self._wanderTimer = 60 + Math.floor(Math.random() * 60); } if (typeof self._wanderAngle === "number") { self.x += Math.cos(self._wanderAngle) * self.speed * 0.5; self.y += Math.sin(self._wanderAngle) * self.speed * 0.5; self._wanderTimer--; // Keep inside map bounds (strictly) var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; if (self.y < minY) self.y = minY; if (self.y > maxY) self.y = maxY; } self._chaseTime = 0; // Not chasing, reset chase timer return; } // State: hungry (look for prey) if (self.state === "hungry") { // Find nearest herbivore or pollinator if not already targeting if (!self.target || self.target.eaten) { var minDist = 999999, closest = null; // Check herbivores for (var i = 0; i < herbivores.length; i++) { var h = herbivores[i]; if (h.eaten) continue; var dx = h.x - self.x, dy = h.y - self.y; var dist = dx * dx + dy * dy; if (dist < minDist) { minDist = dist; closest = h; } } // (Carnivores ignore pollinators) self.target = closest; } // --- Random wandering when not chasing herbivores --- if ((!self.target || self.target.eaten) && (!self._wanderTimer || self._wanderTimer <= 0)) { var angle = Math.random() * Math.PI * 2; self._wanderAngle = angle; self._wanderTimer = 60 + Math.floor(Math.random() * 60); } if (!self.target || self.target.eaten) { if (typeof self._wanderAngle === "number") { self.x += Math.cos(self._wanderAngle) * self.speed * 0.5; self.y += Math.sin(self._wanderAngle) * self.speed * 0.5; self._wanderTimer--; var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; if (self.y < minY) self.y = minY; if (self.y > maxY) self.y = maxY; } self._chaseTime = 0; // Not chasing, reset chase timer } // Move toward target herbivore if (self.target && !self.target.eaten) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 1) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Track how long we've been chasing self._chaseTime++; // If we've been chasing for more than 6 seconds (360 frames), get tired if (self._chaseTime > 360) { self._tired = true; self._tiredTimer = 600; // 10 seconds at 60fps self._chaseTime = 0; return; } // Eat herbivore or pollinator if close enough if (dist < 60 && !self.target.eaten) { // Remove from correct array if pollinator if (pollinators.indexOf(self.target) !== -1) { self.target.die(); // Remove from pollinators array in main update loop, not here } else { self.target.die(); } // Move away from the eaten herbivore if (self.target) { var awayDX = self.x - self.target.x; var awayDY = self.y - self.target.y; var awayDist = Math.sqrt(awayDX * awayDX + awayDY * awayDY); if (awayDist > 0) { // Move 100px away in the opposite direction self.x += awayDX / awayDist * 100; self.y += awayDY / awayDist * 100; // Clamp to map area var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; if (self.y < minY) self.y = minY; if (self.y > maxY) self.y = maxY; } } // Track herbivores eaten for egg laying self._herbivoresEaten = (self._herbivoresEaten || 0) + 1; // Lay an egg if 3 herbivores have been eaten, then reset counter if (self._herbivoresEaten >= 3) { var egg = new Egg(); egg.x = self.x; egg.y = self.y; egg.scaleX = 0.5; egg.scaleY = 0.5; egg.alpha = 1; egg._isCarnivoreEgg = true; egg._carnivoreHatch = true; if (self.parent) self.parent.addChild(egg); if (typeof eggs !== "undefined") eggs.push(egg); self._herbivoresEaten = 0; } self.target = null; self._chaseTime = 0; // Reset chase timer after eating // Animate carnivore "eating" tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 120, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeIn }); } }); // After eating, enter wandering state for 1 minute (3600 frames) self.state = "wandering"; self._eatCooldown = 3600; } } } // end hungry state }; // Carnivores are not eaten in this MVP return self; }); // Egg class var Egg = Container.expand(function () { var self = Container.call(this); // Always use carnivore_egg asset if this is a carnivore egg, pollinator_egg if pollinator, else normal egg var eggAsset; if (self._isCarnivoreEgg === true || self._carnivoreHatch === true) { eggAsset = self.attachAsset('carnivore_egg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); } else if (self._isPollinatorEgg === true || self._pollinatorHatch === true) { eggAsset = self.attachAsset('pollinator_egg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); } else { eggAsset = self.attachAsset('egg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); } self.hatched = false; self._hatchTimer = 420 + Math.floor(Math.random() * 180); // 7-10 seconds self.update = function () { if (self.hatched) return; self._hatchTimer--; if (self._hatchTimer <= 0) { self.hatched = true; // Animate egg hatching tween(self, { scaleX: 1.2, scaleY: 1.2, alpha: 0.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Spawn a new carnivore if this is a carnivore egg, pollinator if pollinator egg, otherwise herbivore if (self._isCarnivoreEgg && self._carnivoreHatch) { var carn = new Carnivore(); carn.x = self.x; carn.y = self.y; carn.scaleX = 1; carn.scaleY = 1; carn.alpha = 1; if (self.parent) self.parent.addChild(carn); if (typeof carnivores !== "undefined") carnivores.push(carn); } else if (self._isPollinatorEgg && self._pollinatorHatch) { var poll = new Pollinator(); poll.x = self.x; poll.y = self.y; poll.scaleX = 1; poll.scaleY = 1; poll.alpha = 1; if (self.parent) self.parent.addChild(poll); if (typeof pollinators !== "undefined") pollinators.push(poll); } else { // Spawn a new Nummer at this position var herb = new Nummer(); herb.x = self.x; herb.y = self.y; herb.scaleX = 1; herb.scaleY = 1; herb.alpha = 1; if (self.parent) self.parent.addChild(herb); herbivores.push(herb); } self.destroy(); } }); } }; return self; }); // Fungi class var Fungi = Container.expand(function () { var self = Container.call(this); // Use fungi asset var fungiAsset = self.attachAsset('fungi', { anchorX: 0.5, anchorY: 0.5 }); // Fungi AI: shoot spores at nearby herbivores self._sporeCooldown = 0; self.update = function () { // Only shoot if cooldown is 0 if (self._sporeCooldown > 0) { self._sporeCooldown--; return; } // Find nearest herbivore within 400px var minDist = 999999, closest = null; for (var i = 0; i < herbivores.length; i++) { var h = herbivores[i]; if (h.eaten || h.spored) continue; var dx = h.x - self.x, dy = h.y - self.y; var dist = dx * dx + dy * dy; if (dist < minDist && Math.sqrt(dist) < 400) { minDist = dist; closest = h; } } if (closest) { // Shoot a spore at the herbivore var spore = new FungiSpore(); spore.x = self.x; spore.y = self.y; spore.target = closest; game.addChild(spore); if (!fungiSpores) fungiSpores = []; fungiSpores.push(spore); self._sporeCooldown = 120 + Math.floor(Math.random() * 60); // 2-3 seconds cooldown } }; return self; }); // Nummer class (formerly Herbivore) var Nummer = Container.expand(function () { var self = Container.call(this); self.spored = false; // Track if this Nummer was hit by a spore var herbAsset = self.attachAsset('herbivore', { anchorX: 0.5, anchorY: 0.5 }); self.target = null; self.speed = 1.2 + Math.random() * 1.0; self.eaten = false; // Track number of plants eaten for egg laying self._plantsEaten = 0; // --- State management for hungry/sleepy --- self.state = "hungry"; // "hungry" or "sleepy" self._sleepTimer = 0; // frames left in sleepy state // --- Starvation timer: die if not eating for 2 cycles (80 seconds = 4800 frames) --- self._starveTimer = 4800; // 80 seconds at 60fps self.update = function () { if (self.eaten) return; // Starvation logic: decrement timer if alive and hungry/wandering if (self.state === "hungry" || self.state === "wandering") { self._starveTimer--; if (self._starveTimer <= 0 && !self.eaten) { // Starve and die self.die(); return; } } // Handle infected state if (self.infected) { self.infectedTimer = (self.infectedTimer || 0) + 1; // Future: add infected behavior here (e.g. slow, animation, etc) } // Handle sleepy state if (self.state === "sleepy") { // Check for nearby carnivore and possibly wake up var nearestCarn = null; var minCarnDist = 999999; for (var ci = 0; ci < carnivores.length; ci++) { var carn = carnivores[ci]; if (carn.eaten) continue; var cdx = carn.x - self.x; var cdy = carn.y - self.y; var cdist = cdx * cdx + cdy * cdy; if (cdist < minCarnDist) { minCarnDist = cdist; nearestCarn = carn; } } // If carnivore is within 300px, 50% chance to wake up and run away if (nearestCarn && Math.sqrt(minCarnDist) < 300) { // Only try to wake up once per frame if still sleepy if (!self._triedWakeThisFrame) { self._triedWakeThisFrame = true; if (Math.random() < 0.5) { // Wake up and run away from carnivore self.state = "hungry"; // Move away from carnivore immediately var dx = self.x - nearestCarn.x; var dy = self.y - nearestCarn.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 1) { // Move a burst away (3x speed for one frame) self.x += dx / dist * (self.speed * 3); self.y += dy / dist * (self.speed * 3); } // Clamp to map area var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; if (self.y < minY) self.y = minY; if (self.y > maxY) self.y = maxY; // Don't continue sleeping return; } } } else { self._triedWakeThisFrame = false; } self._sleepTimer--; if (self._sleepTimer <= 0) { self.state = "wandering"; self._wanderAfterSleepTimer = 600; // 10 seconds at 60fps } // While sleepy, don't move or seek food return; } // Wandering state after sleep: ignore plants, just wander for 10s, then become hungry if (self.state === "wandering") { if (typeof self._wanderAfterSleepTimer === "undefined") self._wanderAfterSleepTimer = 600; self._wanderAfterSleepTimer--; // --- Random wandering --- if (!self._wanderTimer || self._wanderTimer <= 0) { var angle = Math.random() * Math.PI * 2; self._wanderAngle = angle; self._wanderTimer = 60 + Math.floor(Math.random() * 60); } if (typeof self._wanderAngle === "number") { self.x += Math.cos(self._wanderAngle) * self.speed * 0.5; self.y += Math.sin(self._wanderAngle) * self.speed * 0.5; self._wanderTimer--; // Keep inside map bounds (strictly) var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; if (self.y < minY) self.y = minY; if (self.y > maxY) self.y = maxY; } if (self._wanderAfterSleepTimer <= 0) { self.state = "hungry"; } return; } // Only seek food if hungry if (self.state === "hungry") { // Find nearest plant if not already targeting if (!self.target || self.target.eaten) { var minDist = 999999, closest = null; for (var i = 0; i < plants.length; i++) { var p = plants[i]; if (p.eaten) continue; var dx = p.x - self.x, dy = p.y - self.y; var dist = dx * dx + dy * dy; if (dist < minDist) { minDist = dist; closest = p; } } self.target = closest; } // Nummer can walk over fungi as if it is not there: do not treat fungi as obstacles, so do not check for collision or avoid them at all in movement logic. // Check for nearest carnivore var nearestCarn = null; var minCarnDist = 999999; var tiredCarnivore = null; var tiredCarnDist = 999999; for (var ci = 0; ci < carnivores.length; ci++) { var carn = carnivores[ci]; if (carn.eaten) continue; var cdx = carn.x - self.x; var cdy = carn.y - self.y; var cdist = cdx * cdx + cdy * cdy; if (cdist < minCarnDist) { minCarnDist = cdist; nearestCarn = carn; } // Track tired carnivore chasing this herbivore if (carn._tired && carn.target === self && cdist < tiredCarnDist) { tiredCarnivore = carn; tiredCarnDist = cdist; } } var carnivoreTooClose = false; var carnDist = 0; var runAwayDX = 0, runAwayDY = 0; if (nearestCarn) { carnDist = Math.sqrt((nearestCarn.x - self.x) * (nearestCarn.x - self.x) + (nearestCarn.y - self.y) * (nearestCarn.y - self.y)); if (carnDist < 300) { // If carnivore is within 300px, run away carnivoreTooClose = true; runAwayDX = self.x - nearestCarn.x; runAwayDY = self.y - nearestCarn.y; } } // --- New: If a tired carnivore was chasing this herbivore, charge away until far enough --- // (Removed barrier logic: herbivores can always run away from tired carnivores) if (carnivoreTooClose && carnDist > 1) { // Run away from carnivore self.x += runAwayDX / carnDist * (self.speed * 1.5); self.y += runAwayDY / carnDist * (self.speed * 1.5); } else { // --- Random wandering when not chasing plant --- if ((!self.target || self.target.eaten) && (!self._wanderTimer || self._wanderTimer <= 0)) { // Pick a new random direction every 60-120 frames var angle = Math.random() * Math.PI * 2; self._wanderAngle = angle; self._wanderTimer = 60 + Math.floor(Math.random() * 60); } if (!self.target || self.target.eaten) { // Wander in the chosen direction if (typeof self._wanderAngle === "number") { self.x += Math.cos(self._wanderAngle) * self.speed * 0.5; self.y += Math.sin(self._wanderAngle) * self.speed * 0.5; self._wanderTimer--; // Keep inside map bounds (strictly) var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; if (self.y < minY) self.y = minY; if (self.y > maxY) self.y = maxY; } } // Move toward target plant if (self.target && !self.target.eaten) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 1) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Eat plant if close enough if (dist < 60 && !self.target.eaten) { var eatenPlant = self.target; self.target.die(); self.target = null; // Animate Nummer "eating" tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 120, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeIn }); } }); // After eating, enter sleepy state for 10 seconds (600 frames) self.state = "sleepy"; self._sleepTimer = 600; // Reset starvation timer after eating self._starveTimer = 4800; // 80 seconds at 60fps // Increment plants eaten counter self._plantsEaten = (self._plantsEaten || 0) + 1; // Lay an egg if 4 plants have been eaten, then reset counter if (self._plantsEaten >= 4) { var egg = new Egg(); egg.x = self.x; egg.y = self.y; egg.scaleX = 0.5; egg.scaleY = 0.5; egg.alpha = 1; if (self.parent) self.parent.addChild(egg); if (typeof eggs !== "undefined") eggs.push(egg); self._plantsEaten = 0; } } } } } }; // Called when eaten by carnivore self.die = function (_onFinish) { if (self.eaten) return; self.eaten = true; // If infected, spawn a fungi at this position if (self.infected) { var newFungi = new Fungi(); newFungi.x = self.x; newFungi.y = self.y; newFungi.scaleX = 1; newFungi.scaleY = 1; newFungi.alpha = 1; if (self.parent) self.parent.addChild(newFungi); if (typeof fungis !== "undefined") fungis.push(newFungi); } tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); if (_onFinish) _onFinish(); } }); }; // Called when hit by a spore self.sporeHit = function () { if (self.spored) return; // Only allow once self.spored = true; // Enter infected state self.infected = true; self.infectedTimer = 0; // Tint permanently purple tween(self, { tint: 0xbb88ff }, { duration: 80 }); }; return self; }); // Plant class var Plant = Container.expand(function () { var self = Container.call(this); var plantAsset = self.attachAsset('plant', { anchorX: 0.5, anchorY: 0.5 }); // Plants are static, but we can animate them when eaten self.eaten = false; self.die = function (_onFinish2) { if (self.eaten) return; self.eaten = true; tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); if (_onFinish2) _onFinish2(); } }); }; return self; }); // Pollinator class var Pollinator = Container.expand(function () { var self = Container.call(this); var pollAsset = self.attachAsset('pollinator', { anchorX: 0.5, anchorY: 0.5 }); self.state = "seek"; // "seek", "scatter", "planting" self.target = null; self.speed = 2 + Math.random(); self._scatterTimer = 0; self._scatterAngle = 0; self._plantSeedTimer = 0; self._hasSeed = true; self.eaten = false; self.lastWasTouchingPlant = false; // --- Pollination counter for egg laying --- self._pollinations = 0; self._layingEgg = false; self._eggObj = null; // Add a lifetime timer (1 minute = 3600 frames) self._lifetime = 3600; self.update = function () { if (self.eaten) return; // Pollinator dies after 1 minute self._lifetime--; if (self._lifetime <= 0) { // Animate and destroy pollinator tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); // Prevent further updates self.update = function () {}; return; } // If currently laying an egg, wait for egg to hatch before continuing if (self._layingEgg && self._eggObj) { // Wait for egg to hatch, then continue pollinating if (self._eggObj.hatched) { // Spawn a new pollinator at egg position var newPoll = new Pollinator(); newPoll.x = self._eggObj.x; newPoll.y = self._eggObj.y; newPoll.scaleX = 1; newPoll.scaleY = 1; newPoll.alpha = 1; if (self.parent) self.parent.addChild(newPoll); if (typeof pollinators !== "undefined") pollinators.push(newPoll); // Remove egg from global eggs array var idx = eggs.indexOf(self._eggObj); if (idx !== -1) eggs.splice(idx, 1); self._eggObj.destroy(); self._eggObj = null; self._layingEgg = false; self._pollinations = 0; // Reset counter } else { // Wait for egg to hatch, do nothing else return; } } // SEEK: Find nearest plant and move to it, but run from carnivores if close if (self.state === "seek") { // Check for nearest carnivore var nearestCarn = null; var minCarnDist = 999999; for (var ci = 0; ci < carnivores.length; ci++) { var carn = carnivores[ci]; if (carn.eaten) continue; var cdx = carn.x - self.x; var cdy = carn.y - self.y; var cdist = cdx * cdx + cdy * cdy; if (cdist < minCarnDist) { minCarnDist = cdist; nearestCarn = carn; } } var carnivoreTooClose = false; var carnDist = 0; var runAwayDX = 0, runAwayDY = 0; if (nearestCarn) { carnDist = Math.sqrt((nearestCarn.x - self.x) * (nearestCarn.x - self.x) + (nearestCarn.y - self.y) * (nearestCarn.y - self.y)); if (carnDist < 220) { // Run if carnivore is within 220px carnivoreTooClose = true; runAwayDX = self.x - nearestCarn.x; runAwayDY = self.y - nearestCarn.y; } } if (carnivoreTooClose && carnDist > 1) { // Run away from carnivore (burst speed) self.x += runAwayDX / carnDist * (self.speed * 2.2); self.y += runAwayDY / carnDist * (self.speed * 2.2); } else { // Find nearest plant if (!self.target || self.target.eaten) { var minDist = 999999, closest = null; for (var i = 0; i < plants.length; i++) { var p = plants[i]; if (p.eaten) continue; var dx = p.x - self.x, dy = p.y - self.y; var dist = dx * dx + dy * dy; if (dist < minDist) { minDist = dist; closest = p; } } self.target = closest; } // Move toward target plant if (self.target && !self.target.eaten) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 1) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Check for touching plant (within 60px) var isTouching = dist < 60; if (!self.lastWasTouchingPlant && isTouching) { // Just touched plant self._pollinations = (self._pollinations || 0) + 1; // If pollinated 3 times, lay an egg and wait for it to hatch if (self._pollinations >= 3 && !self._layingEgg) { // Lay a pollinator egg at current position var egg = new Egg(); egg.x = self.x; egg.y = self.y; egg.scaleX = 0.5; egg.scaleY = 0.5; egg.alpha = 1; egg._isPollinatorEgg = true; egg._pollinatorHatch = true; if (self.parent) self.parent.addChild(egg); if (typeof eggs !== "undefined") eggs.push(egg); self._eggObj = egg; self._layingEgg = true; // Wait for egg to hatch before continuing return; } self.state = "scatter"; self._scatterTimer = 60 + Math.floor(Math.random() * 60); // 1-2 seconds self._scatterAngle = Math.random() * Math.PI * 2; } self.lastWasTouchingPlant = isTouching; } else { // No plant to go to, wander randomly if (!self._wanderTimer || self._wanderTimer <= 0) { self._wanderAngle = Math.random() * Math.PI * 2; self._wanderTimer = 60 + Math.floor(Math.random() * 60); } if (typeof self._wanderAngle === "number") { self.x += Math.cos(self._wanderAngle) * self.speed * 0.5; self.y += Math.sin(self._wanderAngle) * self.speed * 0.5; self._wanderTimer--; } } } } // SCATTER: Move in a random direction for a short time else if (self.state === "scatter") { self.x += Math.cos(self._scatterAngle) * self.speed * 2; self.y += Math.sin(self._scatterAngle) * self.speed * 2; self._scatterTimer--; if (self._scatterTimer <= 0) { self.state = "planting"; self._plantSeedTimer = 30 + Math.floor(Math.random() * 30); // short pause before planting } } // PLANTING: Pause, then plant a seed else if (self.state === "planting") { self._plantSeedTimer--; if (self._plantSeedTimer <= 0 && self._hasSeed) { // Place a seed at current position var seed = new Seed(); seed.x = self.x; seed.y = self.y; seed.scaleX = 0.4; seed.scaleY = 0.4; seed.alpha = 1; seeds.push(seed); if (self.parent) self.parent.addChild(seed); self._hasSeed = false; // After planting, look for another plant self.state = "seek"; self.target = null; self._hasSeed = true; } } // Keep inside map bounds var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; if (self.x < minX) self.x = minX; if (self.x > maxX) self.x = maxX; if (self.y < minY) self.y = minY; if (self.y > maxY) self.y = maxY; }; self.die = function () { if (self.eaten) return; self.eaten = true; tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); // Seed class var Seed = Container.expand(function () { var self = Container.call(this); // Use dedicated brown seed asset var seedAsset = self.attachAsset('seed', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4 }); self.growing = false; self.eaten = false; self._growTimer = 600; // 10 seconds at 60fps self.update = function () { if (self.eaten) return; if (!self.growing) { self._growTimer--; if (self._growTimer <= 0) { self.growing = true; // Animate seed growing into plant tween(self, { scaleX: 1, scaleY: 1, alpha: 0.7 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Replace seed with a new plant at same position var newPlant = new Plant(); newPlant.x = self.x; newPlant.y = self.y; newPlant.scaleX = 1; newPlant.scaleY = 1; newPlant.alpha = 1; plants.push(newPlant); if (self.parent) self.parent.addChild(newPlant); self.eaten = true; self.destroy(); } }); } } }; // If something eats the seed (future-proof) self.die = function () { if (self.eaten) return; self.eaten = true; tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); // Spore class (projectile shot by fungi) var Spore = Container.expand(function () { var self = Container.call(this); // Use a simple green circle for the spore var sporeAsset = self.attachAsset('plant', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.25, scaleY: 0.25 }); self.target = null; self.speed = 2.5; self._alive = true; self.update = function () { if (!self.target || self.target.eaten || !self._alive) { self.destroy(); self._alive = false; return; } var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 1) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Check collision with target herbivore if (!self._lastIntersecting && self.intersects(self.target)) { // "Hit" the herbivore: destroy spore, animate herbivore, but do not kill if (self.target && typeof self.target.sporeHit === "function") { self.target.sporeHit(); } self.destroy(); self._alive = false; } self._lastIntersecting = self.intersects(self.target); }; return self; }); // FungiSpore class for future extensibility (could add poison, etc) // Modified: FungiSpore now takes a straight path (direction set at spawn) var FungiSpore = Spore.expand(function () { var self = Spore.call(this); // Store initial direction at spawn self._vx = 0; self._vy = 0; // Set direction only once at spawn, toward target self.setDirection = function () { if (self.target) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self._vx = dx / dist * self.speed; self._vy = dy / dist * self.speed; } else { self._vx = 0; self._vy = 0; } } else { self._vx = 0; self._vy = 0; } }; // Call setDirection at spawn self.setDirection(); // Override update to move in a straight line self.update = function () { if (!self.target || self.target.eaten || !self._alive) { self.destroy(); self._alive = false; return; } self.x += self._vx; self.y += self._vy; // Check collision with target herbivore if (!self._lastIntersecting && self.intersects(self.target)) { if (self.target && typeof self.target.sporeHit === "function") { self.target.sporeHit(); } self.destroy(); self._alive = false; } self._lastIntersecting = self.intersects(self.target); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2ecc40 //{7C} // Set to a green background }); /**** * Game Code ****/ // Add a cycle counter at the bottom of the screen that increments every 50 seconds (3000 frames at 60fps) // --- Cycle Counter --- var cycleCount = 0; var cycleTxt = new Text2("Cycle: 0", { size: 80, fill: "#fff" }); cycleTxt.anchor.set(0.5, 0); // Place at top left, but not in the top 100px reserved area LK.gui.top.addChild(cycleTxt); cycleTxt.x = 500; cycleTxt.y = 120; // --- Cycle Countdown Timer Text --- var cycleDurationMs = 50000; // 50,000 ms = 50 seconds var cycleTimeLeftMs = cycleDurationMs; var cycleTimerTxt = new Text2("Next cycle: 50s", { size: 60, fill: "#fff" }); cycleTimerTxt.anchor.set(0.5, 0); LK.gui.top.addChild(cycleTimerTxt); cycleTimerTxt.x = 500; cycleTimerTxt.y = cycleTxt.y + 80; // Place under the cycle counter // Timer to increment cycle every 50 seconds var cycleInterval = null; // Will be started after first organism is placed var cycleCountdownInterval = null; // For updating the countdown text function startCycleInterval() { if (cycleInterval !== null) return; cycleTimeLeftMs = cycleDurationMs; cycleTimerTxt.setText("Next cycle: " + Math.ceil(cycleTimeLeftMs / 1000) + "s"); cycleInterval = LK.setInterval(function () { cycleCount++; cycleTxt.setText("Cycle: " + cycleCount); cycleTimeLeftMs = cycleDurationMs; cycleTimerTxt.setText("Next cycle: " + Math.ceil(cycleTimeLeftMs / 1000) + "s"); }, cycleDurationMs); // Start countdown updater (every 100ms for smoothness) if (cycleCountdownInterval === null) { cycleCountdownInterval = LK.setInterval(function () { if (cycleTimeLeftMs > 0) { cycleTimeLeftMs -= 100; if (cycleTimeLeftMs < 0) cycleTimeLeftMs = 0; cycleTimerTxt.setText("Next cycle: " + Math.ceil(cycleTimeLeftMs / 1000) + "s"); } }, 100); } } // --- End of Game Code ---;; // --- Asset Initialization --- // new carnivore egg texture var plants = []; var herbivores = []; var carnivores = []; var seeds = []; var eggs = []; // Track all eggs globally var pollinators = []; var fungis = []; // Track all fungi globally var fungiSpores = []; // Track all spores shot by fungi // --- Palette UI --- var paletteY = 180; // y position for palette var paletteSpacing = 260; var paletteItems = []; // --- Delete Mode Button --- var deleteMode = false; var deleteBtn = new Container(); var deleteBtnBox = deleteBtn.attachAsset('box', { anchorX: 0.5, anchorY: 0.5, width: 220, height: 100, color: 0xcc3333, shape: 'box' }); var deleteBtnTxt = new Text2("Delete: OFF", { size: 54, fill: "#fff" }); deleteBtnTxt.anchor.set(0.5, 0.5); deleteBtn.addChild(deleteBtnTxt); // Place delete button under the cycle counter and timer deleteBtn.x = 500; deleteBtn.y = cycleTimerTxt.y + 140; // Move further down (was 90px, now 140px below the timer text) deleteBtn.interactive = true; deleteBtn.visible = true; deleteBtn.down = function () { deleteMode = !deleteMode; deleteBtnBox.color = deleteMode ? 0xff4444 : 0xcc3333; deleteBtnTxt.setText(deleteMode ? "Delete: ON" : "Delete: OFF"); }; LK.gui.top.addChild(deleteBtn); // Shift the palette even further left so it is not offscreen var paletteTotalWidth = paletteSpacing * 2; var paletteXStart = 2048 / 2 - paletteTotalWidth / 2 - 1300; // Create palette items for drag-and-drop function createPaletteItem(type, x, y) { var assetId, color, label; if (type === 'plant') { assetId = 'plant'; color = 0x6adf60; label = 'Fern'; } else if (type === 'herbivore') { assetId = 'herbivore'; color = 0xf7e26b; label = 'Nummer'; } else if (type === 'pollinator') { assetId = 'pollinator'; color = 0xffc300; label = 'Pollinator'; } else if (type === 'fungi') { assetId = 'fungi'; color = 0xbb88ff; label = 'Shroom'; } else { assetId = 'carnivore'; color = 0xe74c3c; label = 'Hunter'; } ; // Update all eggs for (var i = eggs.length - 1; i >= 0; i--) { var e = eggs[i]; if (!e.parent || e.hatched) { eggs.splice(i, 1); continue; } if (e.update) e.update(); } ; // Update all pollinators for (var i = pollinators.length - 1; i >= 0; i--) { var p = pollinators[i]; if (p.eaten) { pollinators.splice(i, 1); continue; } if (p.update) p.update(); } var node = new Container(); var icon = node.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); node.x = x; node.y = y; node.type = type; // Add label var txt = new Text2(label, { size: 60, fill: "#fff" }); txt.anchor.set(0.5, 0); txt.y = 60; node.addChild(txt); // Add to GUI overlay (so it stays on top) LK.gui.top.addChild(node); paletteItems.push(node); return node; } // --- Palette Scroll Bar --- // All available organism types in palette var paletteTypes = ['plant', 'herbivore', 'carnivore', 'pollinator', 'fungi']; var paletteScrollOffset = 0; // How much the palette is scrolled (in px) var paletteScrollMin = 0; var paletteScrollMax = Math.max(0, paletteTypes.length * paletteSpacing - paletteSpacing * 3); // Show 3 at a time // Remove old palette items if any for (var i = 0; i < paletteItems.length; i++) { if (paletteItems[i].parent) paletteItems[i].parent.removeChild(paletteItems[i]); } paletteItems = []; // Helper to render palette items based on scroll offset function renderPaletteItems() { // Remove all current palette items from GUI for (var i = 0; i < paletteItems.length; i++) { if (paletteItems[i].parent) paletteItems[i].parent.removeChild(paletteItems[i]); } paletteItems = []; // Only show up to 3 at a time, centered var visibleCount = 3; var startIdx = Math.floor(paletteScrollOffset / paletteSpacing); var offsetPx = paletteScrollOffset % paletteSpacing; for (var i = 0; i < visibleCount; i++) { var idx = startIdx + i; if (idx >= 0 && idx < paletteTypes.length) { var px = paletteXStart + i * paletteSpacing - offsetPx; var node = createPaletteItem(paletteTypes[idx], px, paletteY); paletteItems.push(node); } } // Draw left/right scroll buttons if (!window.paletteLeftBtn) { window.paletteLeftBtn = new Container(); var leftIcon = window.paletteLeftBtn.attachAsset('box', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 120, color: 0x444444, shape: 'box' }); var leftArrow = new Text2("<", { size: 80, fill: "#fff" }); leftArrow.anchor.set(0.5, 0.5); leftArrow.x = 0; leftArrow.y = 0; window.paletteLeftBtn.addChild(leftArrow); window.paletteLeftBtn.x = paletteXStart - 120; window.paletteLeftBtn.y = paletteY; window.paletteLeftBtn.interactive = true; LK.gui.top.addChild(window.paletteLeftBtn); window.paletteLeftBtn.visible = false; } if (!window.paletteRightBtn) { window.paletteRightBtn = new Container(); var rightIcon = window.paletteRightBtn.attachAsset('box', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 120, color: 0x444444, shape: 'box' }); var rightArrow = new Text2(">", { size: 80, fill: "#fff" }); rightArrow.anchor.set(0.5, 0.5); rightArrow.x = 0; rightArrow.y = 0; window.paletteRightBtn.addChild(rightArrow); window.paletteRightBtn.x = paletteXStart + paletteSpacing * visibleCount + 40; window.paletteRightBtn.y = paletteY; window.paletteRightBtn.interactive = true; LK.gui.top.addChild(window.paletteRightBtn); window.paletteRightBtn.visible = false; } // Show/hide buttons window.paletteLeftBtn.visible = paletteScrollOffset > paletteScrollMin; window.paletteRightBtn.visible = paletteScrollOffset < paletteScrollMax; } renderPaletteItems(); // --- Palette Scroll Button Handlers --- window.paletteLeftBtn.down = function () { if (paletteScrollOffset > paletteScrollMin) { paletteScrollOffset -= paletteSpacing; if (paletteScrollOffset < paletteScrollMin) paletteScrollOffset = paletteScrollMin; renderPaletteItems(); } }; window.paletteRightBtn.down = function () { if (paletteScrollOffset < paletteScrollMax) { paletteScrollOffset += paletteSpacing; if (paletteScrollOffset > paletteScrollMax) paletteScrollOffset = paletteScrollMax; renderPaletteItems(); } }; // --- End Palette Scroll Bar --- // --- Drag and Drop Logic --- var dragging = null; // {type, node, paletteRef} var dragOffsetX = 0, dragOffsetY = 0; // Helper: create organism at x,y function createOrganism(type, x, y) { var obj; if (type === 'plant') { obj = new Plant(); plants.push(obj); } else if (type === 'herbivore') { obj = new Nummer(); herbivores.push(obj); } else if (type === 'pollinator') { obj = new Pollinator(); pollinators.push(obj); } else if (type === 'fungi') { obj = new Fungi(); fungis.push(obj); } else { obj = new Carnivore(); carnivores.push(obj); } obj.x = x; obj.y = y; obj.scaleX = 1; obj.scaleY = 1; obj.alpha = 1; game.addChild(obj); // Start the cycle interval if not already started if (typeof startCycleInterval === "function") startCycleInterval(); return obj; } // Helper: check if point is inside a palette item function isInPalette(x, y, node) { var bounds = { x: node.x - 60, y: node.y - 60, w: 120, h: 120 }; return x >= bounds.x && x <= bounds.x + bounds.w && y >= bounds.y && y <= bounds.y + bounds.h; } // --- Event Handlers --- // Down: start drag if on palette game.down = function (x, y, obj) { // If delete mode is ON, check if click is on an organism and delete it if (deleteMode) { var allOrganisms = plants.concat(herbivores, carnivores, pollinators, fungis); for (var i = allOrganisms.length - 1; i >= 0; i--) { var org = allOrganisms[i]; var dx = x - org.x; var dy = y - org.y; var dist = Math.sqrt(dx * dx + dy * dy); var isFungi = fungis.indexOf(org) !== -1; var canDelete = isFungi || !org.eaten; if (canDelete && dist < 60) { // Remove from correct array if (plants.indexOf(org) !== -1) { var idx = plants.indexOf(org); if (idx !== -1) plants.splice(idx, 1); } else if (herbivores.indexOf(org) !== -1) { var idx = herbivores.indexOf(org); if (idx !== -1) herbivores.splice(idx, 1); } else if (carnivores.indexOf(org) !== -1) { var idx = carnivores.indexOf(org); if (idx !== -1) carnivores.splice(idx, 1); } else if (pollinators.indexOf(org) !== -1) { var idx = pollinators.indexOf(org); if (idx !== -1) pollinators.splice(idx, 1); } else if (fungis.indexOf(org) !== -1) { var idx = fungis.indexOf(org); if (idx !== -1) fungis.splice(idx, 1); } if (typeof org.die === "function") { org.die(); } else if (typeof org.destroy === "function") { org.destroy(); } return; } } // If not on an organism, do nothing in delete mode return; } // Check if touch/click is on a palette item for (var i = 0; i < paletteItems.length; i++) { var p = paletteItems[i]; // Convert GUI coordinates to game coordinates var guiPos = LK.gui.top.toLocal({ x: x, y: y }, game); if (isInPalette(guiPos.x, guiPos.y, p)) { // Start dragging a new organism dragging = { type: p.type, node: createOrganism(p.type, x, y), paletteRef: p }; dragOffsetX = 0; dragOffsetY = 0; // Make it semi-transparent while dragging dragging.node.alpha = 0.7; return; } } // If not on palette, check if on an organism to move it // Check if touch/click is on an organism to move it var found = false; var allOrganisms = plants.concat(herbivores, carnivores, pollinators, fungis); for (var i = allOrganisms.length - 1; i >= 0; i--) { var org = allOrganisms[i]; // Only allow moving if not eaten and touch is within 60px radius of center var dx = x - org.x; var dy = y - org.y; var dist = Math.sqrt(dx * dx + dy * dy); // Fungi do not have .eaten, so check for undefined or false var isFungi = fungis.indexOf(org) !== -1; var canDrag = isFungi || !org.eaten; if (canDrag && dist < 60) { var type; if (plants.indexOf(org) !== -1) type = 'plant';else if (herbivores.indexOf(org) !== -1) type = 'herbivore';else if (carnivores.indexOf(org) !== -1) type = 'carnivore';else if (pollinators.indexOf(org) !== -1) type = 'pollinator';else if (fungis.indexOf(org) !== -1) type = 'fungi'; // (UI label is handled in createPaletteItem, so no change needed here for type) dragging = { type: type, node: org, paletteRef: null }; dragOffsetX = org.x - x; dragOffsetY = org.y - y; org.alpha = 0.7; found = true; break; } } if (!found) { dragging = null; } }; // Move: update drag position game.move = function (x, y, obj) { if (dragging && dragging.node) { var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; var newX = x + dragOffsetX; var newY = y + dragOffsetY; // Clamp to map area if (newX < minX) newX = minX; if (newX > maxX) newX = maxX; if (newY < minY) newY = minY; if (newY > maxY) newY = maxY; dragging.node.x = newX; dragging.node.y = newY; } }; // Up: drop organism if dragging game.up = function (x, y, obj) { if (dragging && dragging.node) { // If dropped inside palette area, destroy (cancel) var guiPos = LK.gui.top.toLocal({ x: x, y: y }, game); var cancel = false; for (var i = 0; i < paletteItems.length; i++) { if (isInPalette(guiPos.x, guiPos.y, paletteItems[i])) { cancel = true; break; } } if (cancel) { // Remove organism dragging.node.destroy(); if (dragging.type === 'plant') { var idx = plants.indexOf(dragging.node); if (idx !== -1) plants.splice(idx, 1); } else if (dragging.type === 'herbivore') { var idx = herbivores.indexOf(dragging.node); if (idx !== -1) herbivores.splice(idx, 1); } else if (dragging.type === 'carnivore') { var idx = carnivores.indexOf(dragging.node); if (idx !== -1) carnivores.splice(idx, 1); } else if (dragging.type === 'pollinator') { var idx = pollinators.indexOf(dragging.node); if (idx !== -1) pollinators.splice(idx, 1); } else if (dragging.type === 'fungi') { var idx = fungis.indexOf(dragging.node); if (idx !== -1) fungis.splice(idx, 1); } } else { // Place organism: snap alpha to 1 dragging.node.alpha = 1; } dragging = null; } }; // --- Main Update Loop --- game.update = function () { // Update all herbivores for (var i = herbivores.length - 1; i >= 0; i--) { var h = herbivores[i]; if (h.eaten) { herbivores.splice(i, 1); continue; } if (h.update) h.update(); } // Update all carnivores for (var i = carnivores.length - 1; i >= 0; i--) { var c = carnivores[i]; if (c.eaten) { carnivores.splice(i, 1); continue; } if (c.update) c.update(); } // Clean up dead plants for (var i = plants.length - 1; i >= 0; i--) { var p = plants[i]; if (p.eaten) { plants.splice(i, 1); } } // Update all seeds for (var i = seeds.length - 1; i >= 0; i--) { var s = seeds[i]; if (s.eaten) { seeds.splice(i, 1); continue; } if (s.update) s.update(); } ; // Update all fungi for (var i = fungis.length - 1; i >= 0; i--) { var f = fungis[i]; if (f.update) f.update(); } // Update all fungi spores for (var i = fungiSpores.length - 1; i >= 0; i--) { var s = fungiSpores[i]; if (!s.parent || !s._alive) { fungiSpores.splice(i, 1); continue; } if (s.update) s.update(); } }; // --- Instructions Text --- // --- Random seed spawning around the map if there are any plants --- var randomSeedSpawnTimer = null; function startRandomSeedSpawning() { if (randomSeedSpawnTimer !== null) return; randomSeedSpawnTimer = LK.setInterval(function () { // Only spawn if there are any plants if (plants.length > 0) { // 40% chance per interval to spawn a seed if (Math.random() < 0.4) { // Pick a random position inside the map area var minX = 124 + 60; var maxX = 124 + 1800 - 60; var minY = paletteY + 320 + 60; var maxY = paletteY + 320 + 2000 - 60; var sx = minX + Math.random() * (maxX - minX); var sy = minY + Math.random() * (maxY - minY); var seed = new Seed(); seed.x = sx; seed.y = sy; seed.scaleX = 0.4; seed.scaleY = 0.4; seed.alpha = 1; seeds.push(seed); game.addChild(seed); } } // If no plants, stop spawning if (plants.length === 0 && randomSeedSpawnTimer !== null) { LK.clearInterval(randomSeedSpawnTimer); randomSeedSpawnTimer = null; } }, 120); // Try every 2 seconds } // Start random seed spawning at game start startRandomSeedSpawning(); // --- Map Area Border (for visual feedback) --- // Use a simple colored rectangle instead of a plant asset for the map border background var mapBorder = LK.getAsset('box', { anchorX: 0, anchorY: 0, width: 1800, height: 2000, color: 0x2e8b57, shape: 'box' }); mapBorder.alpha = 0.12; game.addChild(mapBorder); mapBorder.x = 124; mapBorder.y = paletteY + 320; // --- Add invisible border walls to prevent creatures from exiting the map area --- var borderThickness = 40; var borderAlpha = 0; // fully invisible // Left border var borderLeft = LK.getAsset('box', { anchorX: 0, anchorY: 0, width: borderThickness, height: 2000, color: 0x000000, shape: 'box' }); borderLeft.alpha = borderAlpha; game.addChild(borderLeft); borderLeft.x = 124 - borderThickness; borderLeft.y = paletteY + 320; // Right border var borderRight = LK.getAsset('box', { anchorX: 0, anchorY: 0, width: borderThickness, height: 2000, color: 0x000000, shape: 'box' }); borderRight.alpha = borderAlpha; game.addChild(borderRight); borderRight.x = 124 + 1800; borderRight.y = paletteY + 320; // Top border var borderTop = LK.getAsset('box', { anchorX: 0, anchorY: 0, width: 1800 + borderThickness * 2, height: borderThickness, color: 0x000000, shape: 'box' }); borderTop.alpha = borderAlpha; game.addChild(borderTop); borderTop.x = 124 - borderThickness; borderTop.y = paletteY + 320 - borderThickness; // Bottom border var borderBottom = LK.getAsset('box', { anchorX: 0, anchorY: 0, width: 1800 + borderThickness * 2, height: borderThickness, color: 0x000000, shape: 'box' }); borderBottom.alpha = borderAlpha; game.addChild(borderBottom); borderBottom.x = 124 - borderThickness; borderBottom.y = paletteY + 320 + 2000; // --- End of Game Code ---;
===================================================================
--- original.js
+++ change.js
@@ -1101,108 +1101,12 @@
var eggs = []; // Track all eggs globally
var pollinators = [];
var fungis = []; // Track all fungi globally
var fungiSpores = []; // Track all spores shot by fungi
-// --- Abiotic objects array ---
-var abioticObjects = [];
-// Helper: create abiotic object at x,y
-function createAbioticObject(type, x, y) {
- var obj;
- if (type === 'rock') {
- obj = new Container();
- var rockAsset = obj.attachAsset('box', {
- anchorX: 0.5,
- anchorY: 0.5,
- width: 120,
- height: 120,
- color: 0x888888,
- shape: 'box'
- });
- obj.type = 'rock';
- } else {
- obj = new Container();
- var asset = obj.attachAsset('box', {
- anchorX: 0.5,
- anchorY: 0.5,
- width: 100,
- height: 100,
- color: 0x888888,
- shape: 'box'
- });
- obj.type = type;
- }
- obj.x = x;
- obj.y = y;
- obj.scaleX = 1;
- obj.scaleY = 1;
- obj.alpha = 1;
- game.addChild(obj);
- abioticObjects.push(obj);
- return obj;
-}
// --- Palette UI ---
var paletteY = 180; // y position for palette
var paletteSpacing = 260;
var paletteItems = [];
-// --- Abiotic Palette UI (Bottom Selection Area) ---
-var abioticPaletteY = 2732 - 220; // y position for abiotic palette (bottom of screen, above border)
-var abioticPaletteSpacing = 260;
-var abioticPaletteItems = [];
-var abioticPaletteTypes = ['rock']; // Add more abiotic types here as needed
-// Helper to create abiotic palette item
-function createAbioticPaletteItem(type, x, y) {
- var assetId, color, label;
- if (type === 'rock') {
- assetId = 'box';
- color = 0x888888;
- label = 'Rock';
- } else {
- assetId = 'box';
- color = 0x888888;
- label = 'Abiotic';
- }
- var node = new Container();
- var icon = node.attachAsset(assetId, {
- anchorX: 0.5,
- anchorY: 0.5,
- width: 100,
- height: 100,
- color: color,
- shape: 'box'
- });
- node.x = x;
- node.y = y;
- node.type = type;
- // Add label
- var txt = new Text2(label, {
- size: 54,
- fill: "#fff"
- });
- txt.anchor.set(0.5, 0);
- txt.y = 60;
- node.addChild(txt);
- LK.gui.top.addChild(node);
- abioticPaletteItems.push(node);
- return node;
-}
-// Render abiotic palette items (bottom area)
-function renderAbioticPaletteItems() {
- // Remove all current abiotic palette items from GUI
- for (var i = 0; i < abioticPaletteItems.length; i++) {
- if (abioticPaletteItems[i].parent) abioticPaletteItems[i].parent.removeChild(abioticPaletteItems[i]);
- }
- abioticPaletteItems = [];
- // Only show up to 3 at a time, centered
- var visibleCount = 3;
- var abioticPaletteTotalWidth = abioticPaletteSpacing * visibleCount;
- var abioticPaletteXStart = 2048 / 2 - abioticPaletteTotalWidth / 2;
- for (var i = 0; i < abioticPaletteTypes.length; i++) {
- var px = abioticPaletteXStart + i * abioticPaletteSpacing;
- var node = createAbioticPaletteItem(abioticPaletteTypes[i], px, abioticPaletteY);
- abioticPaletteItems.push(node);
- }
-}
-renderAbioticPaletteItems();
// --- Delete Mode Button ---
var deleteMode = false;
var deleteBtn = new Container();
var deleteBtnBox = deleteBtn.attachAsset('box', {
@@ -1479,22 +1383,9 @@
}
return;
}
}
- // Check abiotic objects for deletion
- for (var i = abioticObjects.length - 1; i >= 0; i--) {
- var obj = abioticObjects[i];
- var dx = x - obj.x;
- var dy = y - obj.y;
- var dist = Math.sqrt(dx * dx + dy * dy);
- if (dist < 60) {
- var idx = abioticObjects.indexOf(obj);
- if (idx !== -1) abioticObjects.splice(idx, 1);
- if (typeof obj.destroy === "function") obj.destroy();
- return;
- }
- }
- // If not on an organism or abiotic, do nothing in delete mode
+ // If not on an organism, do nothing in delete mode
return;
}
// Check if touch/click is on a palette item
for (var i = 0; i < paletteItems.length; i++) {
@@ -1517,28 +1408,8 @@
dragging.node.alpha = 0.7;
return;
}
}
- // Check if touch/click is on an abiotic palette item
- for (var i = 0; i < abioticPaletteItems.length; i++) {
- var p = abioticPaletteItems[i];
- var guiPos = LK.gui.top.toLocal({
- x: x,
- y: y
- }, game);
- if (isInPalette(guiPos.x, guiPos.y, p)) {
- // Start dragging a new abiotic object (e.g. rock)
- dragging = {
- type: p.type,
- node: createAbioticObject(p.type, x, y),
- paletteRef: p
- };
- dragOffsetX = 0;
- dragOffsetY = 0;
- dragging.node.alpha = 0.7;
- return;
- }
- }
// If not on palette, check if on an organism to move it
// Check if touch/click is on an organism to move it
var found = false;
var allOrganisms = plants.concat(herbivores, carnivores, pollinators, fungis);
@@ -1604,9 +1475,9 @@
break;
}
}
if (cancel) {
- // Remove organism or abiotic object
+ // Remove organism
dragging.node.destroy();
if (dragging.type === 'plant') {
var idx = plants.indexOf(dragging.node);
if (idx !== -1) plants.splice(idx, 1);
@@ -1621,14 +1492,11 @@
if (idx !== -1) pollinators.splice(idx, 1);
} else if (dragging.type === 'fungi') {
var idx = fungis.indexOf(dragging.node);
if (idx !== -1) fungis.splice(idx, 1);
- } else if (dragging.type === 'rock') {
- var idx = abioticObjects.indexOf(dragging.node);
- if (idx !== -1) abioticObjects.splice(idx, 1);
}
} else {
- // Place organism or abiotic object: snap alpha to 1
+ // Place organism: snap alpha to 1
dragging.node.alpha = 1;
}
dragging = null;
}
tentacled red circle with a mouth and no eyes. In-Game asset. 2d. High contrast. No shadows. Very simple
A plant. In-Game asset. 2d. High contrast. No shadows. Very simple
Brown Seed. In-Game asset. 2d. High contrast. No shadows. Very simple
A small orange circle with spider legs 1 cute eye and no mouth. In-Game asset. 2d. High contrast. No shadows. Very very simple
Make a red egg with dark red spots. In-Game asset. 2d. High contrast. No shadows
Purple mushroom. In-Game asset. 2d. High contrast. No shadows. Very simple
A green shiny orb with a black circle. In-Game asset. 2d. High contrast. No shadows. Very simple
make a cyan lichen. In-Game asset. 2d. High contrast. No shadows. very simple
Just the color blue filling the entire space. In-Game asset. 2d. High contrast. No shadows
A brown circle with bug like antennas and bug legs with bug jaws and no eyes. In-Game asset. 2d. High contrast. No shadows. Very simple
A venus flytrap with one mouth and is looking up side view. In-Game asset. 2d. High contrast. No shadows VERY SIMPLE
Short brown worm. In-Game asset. 2d. High contrast. No shadows. Very simple
Pile of dirt. In-Game asset. 2d. High contrast. No shadows. Very simple
A yellow circle with 3 eyes no mouth and the eyes are in a triangle orientation. In-Game asset. 2d. High contrast. No shadows
Shrub. In-Game asset. 2d. High contrast. No shadows. Very simple