User prompt
no like I’m a tester can you add a button only for me
User prompt
make it so if you’re testing, you can go back to the game at any time
User prompt
no make it so there’s no stop menu if you got jump scared before and there’s still the tomato staring into your soul
User prompt
make it so in the normal game, there’s a button in the stock menu you make it so there’s a start menu first OK
User prompt
make sure if you wait some seconds you get text that says you don’t own. This game in the text starts multiplying so much until it flooded your screen every single couple seconds.
User prompt
make it so it’s not permanent unless you get jump scared
User prompt
make it so there’s just no game over screen and you just get the eyes forever not even if you do that five times anymore
User prompt
make it so if you load five times with the eyes, then it brings you back to the original game
User prompt
no, after the jumpscare
User prompt
Next time you load up the game, it’s just not even any texts from before. It’s just a black box with the tomato that the creepy tomato staring into your soul with black eyes.
Code edit (1 edits merged)
Please save this source code
User prompt
Feed the Tomato: The Hungry Return
Initial prompt
add a game about a tomato that wants to get fed that doesn’t have any hands so he says he needs to get fed by his self so she says that he wants to eat some foods that’s on a table and if you give him the right foods he would say he wants to come back like if you give him the right foods a lot. He will say he wants to come back tomorrow and then once you press the stop button tomorrow then he’ll be back but if you get all of them wrong 10 times then his med level will go up 10 and he will become creepy with teeth sharp thief and he will say that he’s gonna give you one more chance of a creepy voice and then you have to feed him creepy food like creepy food that like creepy people eat or just yeah I don’t know then once you’re done feeding the creepy food she will jump scare you and next time you try and load up the game after he jump scared you then they will just be a tomato staring into your soul
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { creepy: false }); /**** * Classes ****/ // Food class var Food = Container.expand(function () { var self = Container.call(this); self.foodId = null; self.isGood = true; self.isCreepy = false; self.asset = null; self.eaten = false; self.init = function (foodId, isGood, isCreepy) { self.foodId = foodId; self.isGood = isGood; self.isCreepy = isCreepy; self.asset = self.attachAsset(foodId, { anchorX: 0.5, anchorY: 0.5 }); }; // Animate food being eaten self.eat = function (_onFinish) { if (self.eaten) return; self.eaten = true; tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 350, easing: tween.easeIn, onFinish: function onFinish() { if (_onFinish) _onFinish(); self.destroy(); } }); }; // Touch event self.down = function (x, y, obj) { if (game.state !== 'playing' && game.state !== 'creepy') return; game.handleFoodSelect(self); }; return self; }); // Knife class var Knife = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('fork', { anchorX: 0.5, anchorY: 0.5 }); self.stabbing = false; self.target = null; self.update = function () { // Animate knife toward tomato if stabbing if (self.stabbing && self.target) { var dx = self.target.x - self.x; var dy = self.target.y - 120 - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 30) { self.x += dx * 0.25; self.y += dy * 0.25; self.rotation = Math.atan2(dy, dx) + Math.PI / 2; } else { // Hit! self.stabbing = false; self.visible = false; if (typeof self.onStab === "function") self.onStab(); self.destroy(); } } }; return self; }); // Tomato class var Tomato = Container.expand(function () { var self = Container.call(this); self.face = null; self.creepy = false; self.jumpscare = false; self.init = function () { self.face = self.attachAsset('tomatoNormal', { anchorX: 0.5, anchorY: 1 }); }; self.setNormal = function () { self.creepy = false; self.jumpscare = false; self.face.assetId = 'tomatoNormal'; self.face.setAsset('tomatoNormal'); }; self.setCreepy = function () { self.creepy = true; self.jumpscare = false; self.face.assetId = 'tomatoCreepy'; self.face.setAsset('tomatoCreepy'); }; self.setJumpscare = function () { self.jumpscare = true; self.face.assetId = 'tomatoJumpscare'; self.face.setAsset('tomatoJumpscare'); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf7e7c1 }); /**** * Game Code ****/ // --- GLOBALS --- // Tomato (normal) // Tomato (creepy) // Tomato (jumpscare) // Table // Plate // Fork // Spoon // Good foods // Bad foods // Creepy foods // Sounds // Music var tomato = null; var table = null; var plate = null; var utensils = []; var foodObjs = []; var foodSlots = []; var messageTxt = null; var scoreTxt = null; var stateTxt = null; var jumpscareTimeout = null; var mistakeCount = 0; var correctCount = 0; var maxMistakes = 10; var maxCorrect = 5; var isJumpscare = false; var isHaunted = false; var lastFoodIds = []; var creepyFoodsFed = 0; var creepyFoodsNeeded = 3; var foodY = 2000; var foodSlotY = 2000; var foodSlotXStart = 524; var foodSlotSpacing = 250; var foodSlotCount = 5; var foodTypes = [{ id: 'foodApple', isGood: true, isCreepy: false }, { id: 'foodCheese', isGood: true, isCreepy: false }, { id: 'foodBread', isGood: true, isCreepy: false }, { id: 'foodEgg', isGood: true, isCreepy: false }, { id: 'foodCarrot', isGood: true, isCreepy: false }, { id: 'foodSoap', isGood: false, isCreepy: false }, { id: 'foodRock', isGood: false, isCreepy: false }, { id: 'foodBattery', isGood: false, isCreepy: false }, { id: 'foodShoe', isGood: false, isCreepy: false }, { id: 'foodBug', isGood: false, isCreepy: false }]; var creepyFoodTypes = [{ id: 'foodEyeball', isGood: false, isCreepy: true }, { id: 'foodWorm', isGood: false, isCreepy: true }, { id: 'foodFingertip', isGood: false, isCreepy: true }, { id: 'foodTooth', isGood: false, isCreepy: true }, { id: 'foodHeart', isGood: false, isCreepy: true }]; // --- HAUNTED STATE --- if (storage.creepy) { isHaunted = true; } // --- SETUP SCENE --- function setupScene() { // Table table = LK.getAsset('table', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2200 }); game.addChild(table); // Plate plate = LK.getAsset('plate', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2100 }); game.addChild(plate); // Utensils var fork = LK.getAsset('fork', { anchorX: 0.5, anchorY: 0.5, x: 900, y: 2180 }); var spoon = LK.getAsset('spoon', { anchorX: 0.5, anchorY: 0.5, x: 1150, y: 2180 }); utensils = [fork, spoon]; game.addChild(fork); game.addChild(spoon); // Tomato tomato = new Tomato(); tomato.init(); tomato.x = 1024; tomato.y = 900; game.addChild(tomato); // Message text messageTxt = new Text2('', { size: 90, fill: 0x222222 }); messageTxt.anchor.set(0.5, 0); LK.gui.top.addChild(messageTxt); // Score text (hidden, but used for state) scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.topRight.addChild(scoreTxt); // Console button var consoleBtn = new Text2('console', { size: 60, fill: 0x333333 }); consoleBtn.anchor.set(1, 0); consoleBtn.x = -20; consoleBtn.y = 20; LK.gui.topRight.addChild(consoleBtn); // Shop button var shopBtn = new Text2('shop', { size: 60, fill: 0x333333 }); shopBtn.anchor.set(1, 0); shopBtn.x = -20; shopBtn.y = 110; LK.gui.topRight.addChild(shopBtn); // --- SHOP STATE --- var shopOverlay = null; var shopKnives = typeof storage.knives === "number" ? storage.knives : 0; // Shop button handler shopBtn.down = function (x, y, obj) { if (shopOverlay) return; shopOverlay = new Container(); game.addChild(shopOverlay); // Dimmed background var shopBg = LK.getAsset('table', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 30, x: 1024, y: 1366 }); shopBg.tint = 0x222222; shopBg.alpha = 0.85; shopOverlay.addChild(shopBg); // Shop title var shopTitle = new Text2('Shop', { size: 160, fill: 0xffffff }); shopTitle.anchor.set(0.5, 0.5); shopTitle.x = 1024; shopTitle.y = 400; shopOverlay.addChild(shopTitle); // Knives icon var knifeIcon = LK.getAsset('fork', { anchorX: 0.5, anchorY: 0.5, x: 900, y: 700, scaleX: 1.2, scaleY: 1.2 }); shopOverlay.addChild(knifeIcon); // Knives label var knifeLabel = new Text2('Knives: ' + shopKnives, { size: 90, fill: 0xffffff }); knifeLabel.anchor.set(0, 0.5); knifeLabel.x = 1000; knifeLabel.y = 700; shopOverlay.addChild(knifeLabel); // Buy knife button var buyBtn = new Text2('Buy Knife (Free!)', { size: 80, fill: 0x00ff00 }); buyBtn.anchor.set(0.5, 0.5); buyBtn.x = 1024; buyBtn.y = 950; shopOverlay.addChild(buyBtn); buyBtn.down = function () { shopKnives++; storage.knives = shopKnives; knifeLabel.setText('Knives: ' + shopKnives); showMessage("You bought a knife!"); }; // --- ID SHOP ITEM --- // Only allow one free ID ever var hasId = !!storage.hasId; var idIcon = LK.getAsset('googleBlock', { anchorX: 0.5, anchorY: 0.5, x: 900, y: 1050, scaleX: 0.18, scaleY: 0.18 }); shopOverlay.addChild(idIcon); var idLabel = new Text2('ID: ' + (hasId ? 'Owned' : 'Not owned'), { size: 90, fill: 0xffffff }); idLabel.anchor.set(0, 0.5); idLabel.x = 1000; idLabel.y = 1050; shopOverlay.addChild(idLabel); var buyIdBtn = new Text2(hasId ? 'ID Claimed' : 'Claim ID (Free!)', { size: 80, fill: hasId ? 0x888888 : 0x00ffff }); buyIdBtn.anchor.set(0.5, 0.5); buyIdBtn.x = 1024; buyIdBtn.y = 1200; shopOverlay.addChild(buyIdBtn); buyIdBtn.down = function () { if (!hasId) { storage.hasId = true; hasId = true; idLabel.setText('ID: Owned'); buyIdBtn.setText('ID Claimed'); buyIdBtn.fill = 0x888888; showMessage("You got the ID! Try the console..."); } else { showMessage("You already have the ID."); } }; // Use knife button var useKnifeBtn = new Text2('Use Knife', { size: 80, fill: 0xff0000 }); useKnifeBtn.anchor.set(0.5, 0.5); useKnifeBtn.x = 1024; useKnifeBtn.y = 1350; shopOverlay.addChild(useKnifeBtn); useKnifeBtn.down = function () { if (shopKnives > 0 && tomato && !isHaunted && game.state !== 'jumpscare' && game.state !== 'haunt' && game.state !== 'blocked') { shopKnives--; storage.knives = shopKnives; knifeLabel.setText('Knives: ' + shopKnives); shopOverlay.destroy(); shopOverlay = null; stabTomato(); } else if (shopKnives <= 0) { showMessage("You have no knives!"); } }; // Close button var closeBtn = new Text2('Close', { size: 80, fill: 0xff4444 }); closeBtn.anchor.set(0.5, 0.5); closeBtn.x = 1024; closeBtn.y = 1500; shopOverlay.addChild(closeBtn); closeBtn.down = function () { if (shopOverlay) { shopOverlay.destroy(); shopOverlay = null; } }; }; // Console variables var consoleOverlay = null; var consoleBg = null; var consoleText = null; var consoleVisible = false; var keyboardVisible = false; var currentInput = ""; var deletingFiles = false; var deleteProgress = 0; var deleteTimeout = null; // Console button click handler consoleBtn.down = function (x, y, obj) { if (!consoleVisible) { showConsole(); } else { hideConsole(); } }; // Show console function function showConsole() { if (consoleOverlay) return; consoleVisible = true; // Create console overlay container covering full screen consoleOverlay = new Container(); game.addChild(consoleOverlay); // Full screen black background consoleBg = LK.getAsset('table', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 30, x: 1024, y: 1366 }); consoleBg.tint = 0x000000; consoleOverlay.addChild(consoleBg); // Console text centered consoleText = new Text2('hello user', { size: 180, fill: 0xFFFFFF }); consoleText.anchor.set(0.5, 0.5); consoleText.x = 1024; consoleText.y = 800; consoleOverlay.addChild(consoleText); // Create virtual keyboard buttons var keyboardKeys = [['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'], ['a', 's', 'd', 'e', 'l', 'e', 't', 'e'], ['z', 'x', 'c', 'v', 'b', 'n', 'm'], ['backspace', 'enter']]; var keyButtons = []; var startY = 1200; for (var row = 0; row < keyboardKeys.length; row++) { for (var col = 0; col < keyboardKeys[row].length; col++) { var key = keyboardKeys[row][col]; var keyBtn = new Text2(key, { size: 80, fill: 0xFFFFFF }); keyBtn.anchor.set(0.5, 0.5); // Special spacing for bottom row to prevent overlap if (row === 3) { keyBtn.x = 400 + col * 300; } else { keyBtn.x = 200 + col * 160; } keyBtn.y = startY + row * 120; keyBtn.keyValue = key; keyBtn.down = function (x, y, obj) { if (keyboardVisible) { handleKeyInput(this.keyValue); } }; consoleOverlay.addChild(keyBtn); keyButtons.push(keyBtn); } } // Make console clickable to show keyboard consoleBg.down = function (x, y, obj) { showKeyboard(); }; } // Hide console function function hideConsole() { if (consoleOverlay) { consoleOverlay.destroy(); consoleOverlay = null; consoleBg = null; consoleText = null; consoleVisible = false; keyboardVisible = false; currentInput = ""; deletingFiles = false; deleteProgress = 0; if (deleteTimeout) { LK.clearTimeout(deleteTimeout); deleteTimeout = null; } } } // Show keyboard function function showKeyboard() { if (keyboardVisible) return; keyboardVisible = true; updateConsoleText(); } // Update console text with current input function updateConsoleText() { if (!consoleText) return; var displayText = "hello user\n> " + currentInput; if (deletingFiles) { displayText = "hello user\n> delete\nDeleting files... " + Math.floor(deleteProgress) + "%"; } consoleText.setText(displayText); } // Handle keyboard input function handleKeyInput(key) { if (!keyboardVisible || deletingFiles) return; // Only allow typing/deleting if player owns the ID if (!storage.hasId) { if (key === "delete" || key === "backspace" || key === "enter" || key.length === 1) { showMessage("You need the ID from the shop to use the console."); return; } } if (key === "delete") { currentInput = ""; startDeleteSequence(); } else if (key === "enter") { if (currentInput.toLowerCase() === "delete") { startDeleteSequence(); } else if (currentInput.toLowerCase() === "play") { // Hide console and restart game hideConsole(); isHaunted = false; storage.creepy = false; startGame(); } else { updateConsoleText(); } } else if (key === "backspace") { if (currentInput.length > 0) { currentInput = currentInput.slice(0, -1); updateConsoleText(); } } else if (key.length === 1) { currentInput += key; updateConsoleText(); } } // Start delete file sequence function startDeleteSequence() { deletingFiles = true; deleteProgress = 0; updateConsoleText(); var deleteInterval = LK.setInterval(function () { deleteProgress += Math.random() * 15 + 5; if (deleteProgress >= 95) { deleteProgress = 95; LK.clearInterval(deleteInterval); // Show tomato when almost done deleteTimeout = LK.setTimeout(function () { showTomatoInConsole(); }, 500); } updateConsoleText(); }, 200); } // Show tomato appearing in console function showTomatoInConsole() { if (!consoleOverlay) return; // Create tomato in console var consoleTomato = new Tomato(); consoleTomato.init(); consoleTomato.x = 1024; consoleTomato.y = 1000; consoleTomato.scaleX = 2; consoleTomato.scaleY = 2; consoleOverlay.addChild(consoleTomato); // Play Mr. Tomato's special voice line (use 'creepy' or 'jumpscare' sound for effect) LK.getSound('creepy').play(); // After a short delay, try to "crash" the game, or show error text if not possible LK.setTimeout(function () { if (consoleOverlay) { // Try to crash: show error text and block all input consoleOverlay.destroy(); consoleOverlay = null; consoleBg = null; consoleText = null; consoleVisible = false; keyboardVisible = false; currentInput = ""; deletingFiles = false; deleteProgress = 0; if (deleteTimeout) { LK.clearTimeout(deleteTimeout); deleteTimeout = null; } // Show a fake crash/error overlay var crashOverlay = new Container(); game.addChild(crashOverlay); var crashBg = LK.getAsset('table', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 30, x: 1024, y: 1366 }); crashBg.tint = 0x000000; crashOverlay.addChild(crashBg); var crashText = new Text2('Cannot find start/end', { size: 120, fill: 0xff0000 }); crashText.anchor.set(0.5, 0.5); crashText.x = 1024; crashText.y = 900; crashOverlay.addChild(crashText); // Show Mr. Tomato jumpscare on top var crashTomato = new Tomato(); crashTomato.init(); crashTomato.setJumpscare(); crashTomato.x = 1024; crashTomato.y = 1300; crashTomato.scaleX = 2.5; crashTomato.scaleY = 2.5; crashOverlay.addChild(crashTomato); // Play jumpscare sound LK.getSound('jumpscare').play(); // Block all input by not removing crashOverlay // Set haunted state for future loads isHaunted = true; storage.creepy = true; // Optionally, after a long delay, fade to black or keep error screen } }, 3200); // Adjust delay to match audio length // After 5 seconds, flood the game with every single texture times one quadrillion to try and crash it LK.setTimeout(function () { if (!game || !game.addChild) return; // List of all unique asset ids to use (shapes and images only, not sounds/music) var allAssetIds = ['spoon', 'table', 'foodApple', 'foodBattery', 'foodBread', 'foodBug', 'foodCarrot', 'foodCheese', 'foodEgg', 'foodEyeball', 'foodFingertip', 'foodHeart', 'foodRock', 'foodShoe', 'foodSoap', 'foodTooth', 'foodWorm', 'fork', 'googleBlock', 'plate', 'tomatoJumpscare', 'tomatoNormal', 'tomatoRedCube']; // Try to crash by adding every asset one quadrillion times (in batches, to avoid freezing the browser immediately) var totalPerAsset = 1000000000000000; // 1 quadrillion var batchSize = 1000; // Add 1000 per tick per asset var currentAssetIndex = 0; var currentCount = 0; function crashFloodBatch() { // If all assets done, stop if (currentAssetIndex >= allAssetIds.length) return; var assetId = allAssetIds[currentAssetIndex]; for (var i = 0; i < batchSize; ++i) { var obj = LK.getAsset(assetId, { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: Math.random() * 2732, scaleX: 2 + Math.random() * 2, scaleY: 2 + Math.random() * 2 }); game.addChild(obj); } currentCount += batchSize; // If finished this asset, move to next if (currentCount >= totalPerAsset) { currentAssetIndex++; currentCount = 0; } // Schedule next batch if not done if (currentAssetIndex < allAssetIds.length) { LK.setTimeout(crashFloodBatch, 1); } } crashFloodBatch(); }, 5000); } // State text (for jumpscare/haunt) stateTxt = new Text2('', { size: 120, fill: 0xFF0000 }); stateTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(stateTxt); stateTxt.visible = false; } // --- GAME STATE --- game.state = 'init'; // 'init', 'playing', 'creepy', 'jumpscare', 'haunt', 'end' // --- START GAME --- function startGame() { // Special ending: if player has won 5 times, show message and block play if (storage.specialEnding === true && !isHaunted) { // Show special message and game over tomato.setCreepy(); showMessage("Well, you’ve did all I needed for you to do. Now I don’t need you anymore. Do not open up this game anymore."); stateTxt.setText("GAME OVER"); stateTxt.visible = true; clearFoods(); game.state = 'end'; // Set haunted state for next launch storage.creepy = true; isHaunted = true; // After a short delay, show game over LK.setTimeout(function () { LK.showGameOver(); }, 3500); return; } // Reset mistakeCount = 0; correctCount = 0; isJumpscare = false; creepyFoodsFed = 0; lastFoodIds = []; scoreTxt.setText('0'); stateTxt.visible = false; // If knife ending, block all foods/tomato if (storage.knifeEnding === true) { clearFoods(); if (tomato && tomato.destroy) { tomato.destroy(); tomato = null; } showMessage(""); stateTxt.setText(""); stateTxt.visible = false; game.state = 'blocked'; return; } tomato.setNormal(); game.state = isHaunted ? 'haunt' : 'playing'; if (isHaunted) { showHaunt(); } else { showMessage("Help me eat! Feed me the right foods."); spawnFoods(); LK.playMusic('bgm', { loop: true }); } } // --- SHOW MESSAGE --- function showMessage(msg) { messageTxt.setText(msg); } // --- SPAWN FOODS --- function spawnFoods() { clearFoods(); foodObjs = []; foodSlots = []; var used = {}; var pool = game.state === 'creepy' ? creepyFoodTypes : foodTypes; // Pick 5 foods, at least 1 correct (if not creepy) var foods = []; if (game.state === 'playing') { // At least 1 good food var good = []; var bad = []; for (var i = 0; i < pool.length; ++i) { if (pool[i].isGood) good.push(pool[i]);else bad.push(pool[i]); } var goodFood = good[Math.floor(Math.random() * good.length)]; foods.push(goodFood); // Fill rest while (foods.length < foodSlotCount) { var arr = Math.random() < 0.5 ? bad : good; var f = arr[Math.floor(Math.random() * arr.length)]; // Avoid duplicates var dupe = false; for (var j = 0; j < foods.length; ++j) if (foods[j].id === f.id) dupe = true; if (!dupe) foods.push(f); } } else { // Creepy: all from creepyFoodTypes, random while (foods.length < foodSlotCount) { var f = pool[Math.floor(Math.random() * pool.length)]; var dupe = false; for (var j = 0; j < foods.length; ++j) if (foods[j].id === f.id) dupe = true; if (!dupe) foods.push(f); } } // Shuffle for (var i = foods.length - 1; i > 0; --i) { var k = Math.floor(Math.random() * (i + 1)); var tmp = foods[i]; foods[i] = foods[k]; foods[k] = tmp; } // Place foods for (var i = 0; i < foodSlotCount; ++i) { var slotX = foodSlotXStart + i * foodSlotSpacing; var food = new Food(); food.init(foods[i].id, foods[i].isGood, foods[i].isCreepy); food.x = slotX; food.y = foodSlotY; food.scaleX = 1; food.scaleY = 1; food.alpha = 1; foodObjs.push(food); foodSlots.push({ x: slotX, y: foodSlotY }); game.addChild(food); } } // --- CLEAR FOODS --- function clearFoods() { for (var i = 0; i < foodObjs.length; ++i) { if (foodObjs[i] && foodObjs[i].destroy) foodObjs[i].destroy(); } foodObjs = []; foodSlots = []; } // --- KNIFE STAB FUNCTION --- function stabTomato() { // Only allow stabbing in normal/playing/creepy state if (!tomato || isHaunted || game.state === 'jumpscare' || game.state === 'haunt' || game.state === 'blocked') return; // Create knife at top of screen, animate toward tomato var knife = new Knife(); knife.x = tomato.x; knife.y = 0; knife.scaleX = 2.2; knife.scaleY = 2.2; knife.stabbing = true; knife.target = tomato; knife.onStab = function () { // Play knife voice line LK.getSound('knifeVoice').play(); // Remove tomato after voice line, then show win if (tomato && tomato.destroy) { tomato.destroy(); tomato = null; } showMessage(""); stateTxt.setText(""); stateTxt.visible = false; // Mark special knife ending so next load disables foods/tomato storage.knifeEnding = true; }; game.addChild(knife); } // --- HANDLE FOOD SELECT --- game.handleFoodSelect = function (foodObj) { // If in haunt state but player has typed play and started feeding, restore overlays and normal text if (game.state === 'haunt') { // Restore background and overlays game.setBackgroundColor(0xf7e7c1); if (table) table.visible = true; if (plate) plate.visible = true; for (var j = 0; j < utensils.length; ++j) { if (utensils[j]) utensils[j].visible = true; } if (tomato.leftEye) tomato.leftEye.visible = false; if (tomato.rightEye) tomato.rightEye.visible = false; tomato.setNormal(); messageTxt.setText("Help me eat! Feed me the right foods."); scoreTxt.setText(correctCount); stateTxt.setText(""); stateTxt.visible = false; game.state = 'playing'; spawnFoods(); return; } if (game.state !== 'playing' && game.state !== 'creepy') return; if (foodObj.eaten) return; // Animate food to tomato mouth var mouthX = tomato.x; var mouthY = tomato.y - 200; tween(foodObj, { x: mouthX, y: mouthY, scaleX: 0.3, scaleY: 0.3, alpha: 0.7 }, { duration: 350, easing: tween.easeIn, onFinish: function onFinish() { foodObj.eat(); if (game.state === 'playing') { if (foodObj.isGood) { correctCount++; LK.getSound('eat').play(); LK.effects.flashObject(tomato, 0x9bff4a, 400); showMessage("Yum! Thank you."); scoreTxt.setText(correctCount); if (correctCount >= maxCorrect) { // If player wins with 5 anger, trigger creepy win sequence if (mistakeCount === 5) { // Spinning eyes effect: overlay two spinning ellipses on tomato if (!tomato.leftSpinEye) { tomato.leftSpinEye = LK.getAsset('foodEyeball', { anchorX: 0.5, anchorY: 0.5, x: -70, y: -180, scaleX: 0.7, scaleY: 1.1 }); tomato.addChild(tomato.leftSpinEye); } if (!tomato.rightSpinEye) { tomato.rightSpinEye = LK.getAsset('foodEyeball', { anchorX: 0.5, anchorY: 0.5, x: 70, y: -180, scaleX: 0.7, scaleY: 1.1 }); tomato.addChild(tomato.rightSpinEye); } tomato.leftSpinEye.visible = true; tomato.rightSpinEye.visible = true; // Animate spinning var spinTicks = 0; var spinTween = LK.setInterval(function () { spinTicks++; if (tomato.leftSpinEye) tomato.leftSpinEye.rotation += 0.3; if (tomato.rightSpinEye) tomato.rightSpinEye.rotation -= 0.3; if (spinTicks > 20) { LK.clearInterval(spinTween); } }, 30); // Set creepy face tomato.setCreepy(); showMessage(""); stateTxt.setText("You fed me but not good enough."); stateTxt.visible = true; // Play creepy sound LK.getSound('creepy').play(); // After a short delay, jumpscare and haunt LK.setTimeout(function () { // Hide spinning eyes if (tomato.leftSpinEye) tomato.leftSpinEye.visible = false; if (tomato.rightSpinEye) tomato.rightSpinEye.visible = false; // Jumpscare tomato.setJumpscare(); showMessage(""); stateTxt.setText(""); stateTxt.visible = true; LK.getSound('jumpscare').play(); LK.effects.flashScreen(0xff0000, 1200); storage.creepy = true; // After a moment, show haunt jumpscareTimeout = LK.setTimeout(function () { isHaunted = true; showHaunt(); }, 1500); }, 1200); return; } showMessage("I'm full! See you tomorrow!"); LK.setTimeout(function () { LK.showYouWin(); }, 1200); return; } } else { mistakeCount++; LK.getSound('wrong').play(); LK.effects.flashObject(tomato, 0xff0000, 400); showMessage("Yuck! That's not food."); if (mistakeCount >= maxMistakes) { // Go creepy LK.getSound('creepy').play(); goCreepy(); return; } } // Next round LK.setTimeout(function () { showMessage("Feed me the right foods."); spawnFoods(); }, 700); } else if (game.state === 'creepy') { // Only creepy foods accepted if (foodObj.isCreepy) { creepyFoodsFed++; LK.getSound('eat').play(); LK.effects.flashObject(tomato, 0xff0000, 400); showMessage("More. Feed me more..."); if (creepyFoodsFed >= creepyFoodsNeeded) { // Jumpscare LK.setTimeout(function () { jumpscare(); }, 700); return; } } else { LK.getSound('wrong').play(); LK.effects.flashObject(tomato, 0x000000, 400); showMessage("NO! Give me what I want."); } LK.setTimeout(function () { spawnFoods(); }, 700); } } }); }; // --- GO CREEPY --- function goCreepy() { game.state = 'creepy'; tomato.setCreepy(); showMessage("You made me angry. Feed me what I want..."); LK.effects.flashScreen(0x000000, 1200); LK.setTimeout(function () { spawnFoods(); }, 1200); } // --- JUMPSCARE --- function jumpscare() { game.state = 'jumpscare'; isJumpscare = true; clearFoods(); tomato.setJumpscare(); showMessage(""); stateTxt.setText("👁️"); stateTxt.visible = true; LK.getSound('jumpscare').play(); LK.effects.flashScreen(0xff0000, 1200); // Save haunted state storage.creepy = true; // After a moment, show game over jumpscareTimeout = LK.setTimeout(function () { LK.showGameOver(); }, 1500); } // --- SHOW HAUNTED STATE --- function showHaunt() { game.state = 'haunt'; clearFoods(); // Set background to black game.setBackgroundColor(0x000000); // Remove all GUI overlays messageTxt.setText(""); scoreTxt.setText(""); stateTxt.setText(""); stateTxt.visible = false; // Set tomato to creepy and move to center tomato.setCreepy(); tomato.x = 1024; tomato.y = 1366; // Make tomato's face black-eyed (simulate by overlaying two black ellipses for eyes) if (!tomato.leftEye) { tomato.leftEye = LK.getAsset('foodRock', { anchorX: 0.5, anchorY: 0.5, x: -70, y: -180, scaleX: 0.7, scaleY: 1.1 }); tomato.rightEye = LK.getAsset('foodRock', { anchorX: 0.5, anchorY: 0.5, x: 70, y: -180, scaleX: 0.7, scaleY: 1.1 }); tomato.addChild(tomato.leftEye); tomato.addChild(tomato.rightEye); } tomato.leftEye.visible = true; tomato.rightEye.visible = true; // Hide table, plate, utensils if (table) table.visible = false; if (plate) plate.visible = false; for (var i = 0; i < utensils.length; ++i) { if (utensils[i]) utensils[i].visible = false; } // Special message if player triggered special ending if (storage.specialEnding === true && typeof storage.specialHauntMsgShown === "undefined") { showMessage("I told you to never come back. I just said never come back. You want to break the rules? Well, I don’t allow rule breakers."); stateTxt.setText(""); stateTxt.visible = false; storage.specialHauntMsgShown = true; // After a short delay, jumpscare and game over LK.setTimeout(function () { tomato.setJumpscare(); showMessage(""); stateTxt.setText(""); stateTxt.visible = true; LK.getSound('jumpscare').play(); LK.effects.flashScreen(0xff0000, 1200); // After a moment, show game over LK.setTimeout(function () { LK.showGameOver(); }, 1500); }, 3200); return; } // No interaction, no text, just the tomato staring // Allow console button to escape the haunt sequence if (typeof LK !== "undefined" && LK.gui && LK.gui.topRight && LK.gui.topRight.children) { for (var i = 0; i < LK.gui.topRight.children.length; ++i) { var child = LK.gui.topRight.children[i]; if (child && child.setText && child.setText.toString().indexOf("console") !== -1) { // This is the consoleBtn child.down = function (x, y, obj) { // Escape haunt and show console if (game.state === 'haunt') { // Restore background and overlays game.setBackgroundColor(0xf7e7c1); if (table) table.visible = true; if (plate) plate.visible = true; for (var j = 0; j < utensils.length; ++j) { if (utensils[j]) utensils[j].visible = true; } tomato.leftEye.visible = false; tomato.rightEye.visible = false; tomato.setNormal(); game.state = 'init'; showConsole(); } else if (!consoleVisible) { showConsole(); } else { hideConsole(); } }; break; } } } } // --- GAME INIT --- setupScene(); // If knife ending, block all foods/tomato on load if (storage.knifeEnding === true) { clearFoods(); if (tomato && tomato.destroy) { tomato.destroy(); tomato = null; } game.setBackgroundColor(0x000000); messageTxt.setText(""); scoreTxt.setText(""); stateTxt.setText(""); stateTxt.visible = false; // Hide table, plate, utensils if (table) table.visible = false; if (plate) plate.visible = false; for (var i = 0; i < utensils.length; ++i) { if (utensils[i]) utensils[i].visible = false; } game.state = 'blocked'; } else if (storage.specialHauntMsgShown === true && storage.specialEnding === true) { // Show black background and message game.setBackgroundColor(0x000000); clearFoods(); tomato.setCreepy(); tomato.x = 1024; tomato.y = 1366; messageTxt.setText("Don't come back"); scoreTxt.setText(""); stateTxt.setText(""); stateTxt.visible = false; // Hide table, plate, utensils if (table) table.visible = false; if (plate) plate.visible = false; for (var i = 0; i < utensils.length; ++i) { if (utensils[i]) utensils[i].visible = false; } game.state = 'blocked'; } else { startGame(); } // --- GAME EVENTS --- game.update = function () { // No per-frame logic needed for this game }; game.down = function (x, y, obj) { // No drag, but allow food selection // (handled by Food.down) }; game.move = function (x, y, obj) { // No drag }; game.up = function (x, y, obj) { // No drag }; // --- RESET ON GAME OVER --- LK.on('gameover', function () { // Reset haunted state if not jumpscare if (!isJumpscare) { storage.creepy = false; } }); // --- WIN HANDLER --- LK.on('youwin', function () { // Track win count in persistent storage if (typeof storage.winCount !== "number") storage.winCount = 0; storage.winCount++; storage.creepy = false; // If player has won 5 times, set special flag if (storage.winCount >= 5) { storage.specialEnding = true; } }); // --- MUSIC --- LK.playMusic('bgm', { loop: true });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
creepy: false
});
/****
* Classes
****/
// Food class
var Food = Container.expand(function () {
var self = Container.call(this);
self.foodId = null;
self.isGood = true;
self.isCreepy = false;
self.asset = null;
self.eaten = false;
self.init = function (foodId, isGood, isCreepy) {
self.foodId = foodId;
self.isGood = isGood;
self.isCreepy = isCreepy;
self.asset = self.attachAsset(foodId, {
anchorX: 0.5,
anchorY: 0.5
});
};
// Animate food being eaten
self.eat = function (_onFinish) {
if (self.eaten) return;
self.eaten = true;
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 350,
easing: tween.easeIn,
onFinish: function onFinish() {
if (_onFinish) _onFinish();
self.destroy();
}
});
};
// Touch event
self.down = function (x, y, obj) {
if (game.state !== 'playing' && game.state !== 'creepy') return;
game.handleFoodSelect(self);
};
return self;
});
// Knife class
var Knife = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('fork', {
anchorX: 0.5,
anchorY: 0.5
});
self.stabbing = false;
self.target = null;
self.update = function () {
// Animate knife toward tomato if stabbing
if (self.stabbing && self.target) {
var dx = self.target.x - self.x;
var dy = self.target.y - 120 - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 30) {
self.x += dx * 0.25;
self.y += dy * 0.25;
self.rotation = Math.atan2(dy, dx) + Math.PI / 2;
} else {
// Hit!
self.stabbing = false;
self.visible = false;
if (typeof self.onStab === "function") self.onStab();
self.destroy();
}
}
};
return self;
});
// Tomato class
var Tomato = Container.expand(function () {
var self = Container.call(this);
self.face = null;
self.creepy = false;
self.jumpscare = false;
self.init = function () {
self.face = self.attachAsset('tomatoNormal', {
anchorX: 0.5,
anchorY: 1
});
};
self.setNormal = function () {
self.creepy = false;
self.jumpscare = false;
self.face.assetId = 'tomatoNormal';
self.face.setAsset('tomatoNormal');
};
self.setCreepy = function () {
self.creepy = true;
self.jumpscare = false;
self.face.assetId = 'tomatoCreepy';
self.face.setAsset('tomatoCreepy');
};
self.setJumpscare = function () {
self.jumpscare = true;
self.face.assetId = 'tomatoJumpscare';
self.face.setAsset('tomatoJumpscare');
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf7e7c1
});
/****
* Game Code
****/
// --- GLOBALS ---
// Tomato (normal)
// Tomato (creepy)
// Tomato (jumpscare)
// Table
// Plate
// Fork
// Spoon
// Good foods
// Bad foods
// Creepy foods
// Sounds
// Music
var tomato = null;
var table = null;
var plate = null;
var utensils = [];
var foodObjs = [];
var foodSlots = [];
var messageTxt = null;
var scoreTxt = null;
var stateTxt = null;
var jumpscareTimeout = null;
var mistakeCount = 0;
var correctCount = 0;
var maxMistakes = 10;
var maxCorrect = 5;
var isJumpscare = false;
var isHaunted = false;
var lastFoodIds = [];
var creepyFoodsFed = 0;
var creepyFoodsNeeded = 3;
var foodY = 2000;
var foodSlotY = 2000;
var foodSlotXStart = 524;
var foodSlotSpacing = 250;
var foodSlotCount = 5;
var foodTypes = [{
id: 'foodApple',
isGood: true,
isCreepy: false
}, {
id: 'foodCheese',
isGood: true,
isCreepy: false
}, {
id: 'foodBread',
isGood: true,
isCreepy: false
}, {
id: 'foodEgg',
isGood: true,
isCreepy: false
}, {
id: 'foodCarrot',
isGood: true,
isCreepy: false
}, {
id: 'foodSoap',
isGood: false,
isCreepy: false
}, {
id: 'foodRock',
isGood: false,
isCreepy: false
}, {
id: 'foodBattery',
isGood: false,
isCreepy: false
}, {
id: 'foodShoe',
isGood: false,
isCreepy: false
}, {
id: 'foodBug',
isGood: false,
isCreepy: false
}];
var creepyFoodTypes = [{
id: 'foodEyeball',
isGood: false,
isCreepy: true
}, {
id: 'foodWorm',
isGood: false,
isCreepy: true
}, {
id: 'foodFingertip',
isGood: false,
isCreepy: true
}, {
id: 'foodTooth',
isGood: false,
isCreepy: true
}, {
id: 'foodHeart',
isGood: false,
isCreepy: true
}];
// --- HAUNTED STATE ---
if (storage.creepy) {
isHaunted = true;
}
// --- SETUP SCENE ---
function setupScene() {
// Table
table = LK.getAsset('table', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2200
});
game.addChild(table);
// Plate
plate = LK.getAsset('plate', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2100
});
game.addChild(plate);
// Utensils
var fork = LK.getAsset('fork', {
anchorX: 0.5,
anchorY: 0.5,
x: 900,
y: 2180
});
var spoon = LK.getAsset('spoon', {
anchorX: 0.5,
anchorY: 0.5,
x: 1150,
y: 2180
});
utensils = [fork, spoon];
game.addChild(fork);
game.addChild(spoon);
// Tomato
tomato = new Tomato();
tomato.init();
tomato.x = 1024;
tomato.y = 900;
game.addChild(tomato);
// Message text
messageTxt = new Text2('', {
size: 90,
fill: 0x222222
});
messageTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(messageTxt);
// Score text (hidden, but used for state)
scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.topRight.addChild(scoreTxt);
// Console button
var consoleBtn = new Text2('console', {
size: 60,
fill: 0x333333
});
consoleBtn.anchor.set(1, 0);
consoleBtn.x = -20;
consoleBtn.y = 20;
LK.gui.topRight.addChild(consoleBtn);
// Shop button
var shopBtn = new Text2('shop', {
size: 60,
fill: 0x333333
});
shopBtn.anchor.set(1, 0);
shopBtn.x = -20;
shopBtn.y = 110;
LK.gui.topRight.addChild(shopBtn);
// --- SHOP STATE ---
var shopOverlay = null;
var shopKnives = typeof storage.knives === "number" ? storage.knives : 0;
// Shop button handler
shopBtn.down = function (x, y, obj) {
if (shopOverlay) return;
shopOverlay = new Container();
game.addChild(shopOverlay);
// Dimmed background
var shopBg = LK.getAsset('table', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 30,
x: 1024,
y: 1366
});
shopBg.tint = 0x222222;
shopBg.alpha = 0.85;
shopOverlay.addChild(shopBg);
// Shop title
var shopTitle = new Text2('Shop', {
size: 160,
fill: 0xffffff
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.x = 1024;
shopTitle.y = 400;
shopOverlay.addChild(shopTitle);
// Knives icon
var knifeIcon = LK.getAsset('fork', {
anchorX: 0.5,
anchorY: 0.5,
x: 900,
y: 700,
scaleX: 1.2,
scaleY: 1.2
});
shopOverlay.addChild(knifeIcon);
// Knives label
var knifeLabel = new Text2('Knives: ' + shopKnives, {
size: 90,
fill: 0xffffff
});
knifeLabel.anchor.set(0, 0.5);
knifeLabel.x = 1000;
knifeLabel.y = 700;
shopOverlay.addChild(knifeLabel);
// Buy knife button
var buyBtn = new Text2('Buy Knife (Free!)', {
size: 80,
fill: 0x00ff00
});
buyBtn.anchor.set(0.5, 0.5);
buyBtn.x = 1024;
buyBtn.y = 950;
shopOverlay.addChild(buyBtn);
buyBtn.down = function () {
shopKnives++;
storage.knives = shopKnives;
knifeLabel.setText('Knives: ' + shopKnives);
showMessage("You bought a knife!");
};
// --- ID SHOP ITEM ---
// Only allow one free ID ever
var hasId = !!storage.hasId;
var idIcon = LK.getAsset('googleBlock', {
anchorX: 0.5,
anchorY: 0.5,
x: 900,
y: 1050,
scaleX: 0.18,
scaleY: 0.18
});
shopOverlay.addChild(idIcon);
var idLabel = new Text2('ID: ' + (hasId ? 'Owned' : 'Not owned'), {
size: 90,
fill: 0xffffff
});
idLabel.anchor.set(0, 0.5);
idLabel.x = 1000;
idLabel.y = 1050;
shopOverlay.addChild(idLabel);
var buyIdBtn = new Text2(hasId ? 'ID Claimed' : 'Claim ID (Free!)', {
size: 80,
fill: hasId ? 0x888888 : 0x00ffff
});
buyIdBtn.anchor.set(0.5, 0.5);
buyIdBtn.x = 1024;
buyIdBtn.y = 1200;
shopOverlay.addChild(buyIdBtn);
buyIdBtn.down = function () {
if (!hasId) {
storage.hasId = true;
hasId = true;
idLabel.setText('ID: Owned');
buyIdBtn.setText('ID Claimed');
buyIdBtn.fill = 0x888888;
showMessage("You got the ID! Try the console...");
} else {
showMessage("You already have the ID.");
}
};
// Use knife button
var useKnifeBtn = new Text2('Use Knife', {
size: 80,
fill: 0xff0000
});
useKnifeBtn.anchor.set(0.5, 0.5);
useKnifeBtn.x = 1024;
useKnifeBtn.y = 1350;
shopOverlay.addChild(useKnifeBtn);
useKnifeBtn.down = function () {
if (shopKnives > 0 && tomato && !isHaunted && game.state !== 'jumpscare' && game.state !== 'haunt' && game.state !== 'blocked') {
shopKnives--;
storage.knives = shopKnives;
knifeLabel.setText('Knives: ' + shopKnives);
shopOverlay.destroy();
shopOverlay = null;
stabTomato();
} else if (shopKnives <= 0) {
showMessage("You have no knives!");
}
};
// Close button
var closeBtn = new Text2('Close', {
size: 80,
fill: 0xff4444
});
closeBtn.anchor.set(0.5, 0.5);
closeBtn.x = 1024;
closeBtn.y = 1500;
shopOverlay.addChild(closeBtn);
closeBtn.down = function () {
if (shopOverlay) {
shopOverlay.destroy();
shopOverlay = null;
}
};
};
// Console variables
var consoleOverlay = null;
var consoleBg = null;
var consoleText = null;
var consoleVisible = false;
var keyboardVisible = false;
var currentInput = "";
var deletingFiles = false;
var deleteProgress = 0;
var deleteTimeout = null;
// Console button click handler
consoleBtn.down = function (x, y, obj) {
if (!consoleVisible) {
showConsole();
} else {
hideConsole();
}
};
// Show console function
function showConsole() {
if (consoleOverlay) return;
consoleVisible = true;
// Create console overlay container covering full screen
consoleOverlay = new Container();
game.addChild(consoleOverlay);
// Full screen black background
consoleBg = LK.getAsset('table', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 30,
x: 1024,
y: 1366
});
consoleBg.tint = 0x000000;
consoleOverlay.addChild(consoleBg);
// Console text centered
consoleText = new Text2('hello user', {
size: 180,
fill: 0xFFFFFF
});
consoleText.anchor.set(0.5, 0.5);
consoleText.x = 1024;
consoleText.y = 800;
consoleOverlay.addChild(consoleText);
// Create virtual keyboard buttons
var keyboardKeys = [['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'], ['a', 's', 'd', 'e', 'l', 'e', 't', 'e'], ['z', 'x', 'c', 'v', 'b', 'n', 'm'], ['backspace', 'enter']];
var keyButtons = [];
var startY = 1200;
for (var row = 0; row < keyboardKeys.length; row++) {
for (var col = 0; col < keyboardKeys[row].length; col++) {
var key = keyboardKeys[row][col];
var keyBtn = new Text2(key, {
size: 80,
fill: 0xFFFFFF
});
keyBtn.anchor.set(0.5, 0.5);
// Special spacing for bottom row to prevent overlap
if (row === 3) {
keyBtn.x = 400 + col * 300;
} else {
keyBtn.x = 200 + col * 160;
}
keyBtn.y = startY + row * 120;
keyBtn.keyValue = key;
keyBtn.down = function (x, y, obj) {
if (keyboardVisible) {
handleKeyInput(this.keyValue);
}
};
consoleOverlay.addChild(keyBtn);
keyButtons.push(keyBtn);
}
}
// Make console clickable to show keyboard
consoleBg.down = function (x, y, obj) {
showKeyboard();
};
}
// Hide console function
function hideConsole() {
if (consoleOverlay) {
consoleOverlay.destroy();
consoleOverlay = null;
consoleBg = null;
consoleText = null;
consoleVisible = false;
keyboardVisible = false;
currentInput = "";
deletingFiles = false;
deleteProgress = 0;
if (deleteTimeout) {
LK.clearTimeout(deleteTimeout);
deleteTimeout = null;
}
}
}
// Show keyboard function
function showKeyboard() {
if (keyboardVisible) return;
keyboardVisible = true;
updateConsoleText();
}
// Update console text with current input
function updateConsoleText() {
if (!consoleText) return;
var displayText = "hello user\n> " + currentInput;
if (deletingFiles) {
displayText = "hello user\n> delete\nDeleting files... " + Math.floor(deleteProgress) + "%";
}
consoleText.setText(displayText);
}
// Handle keyboard input
function handleKeyInput(key) {
if (!keyboardVisible || deletingFiles) return;
// Only allow typing/deleting if player owns the ID
if (!storage.hasId) {
if (key === "delete" || key === "backspace" || key === "enter" || key.length === 1) {
showMessage("You need the ID from the shop to use the console.");
return;
}
}
if (key === "delete") {
currentInput = "";
startDeleteSequence();
} else if (key === "enter") {
if (currentInput.toLowerCase() === "delete") {
startDeleteSequence();
} else if (currentInput.toLowerCase() === "play") {
// Hide console and restart game
hideConsole();
isHaunted = false;
storage.creepy = false;
startGame();
} else {
updateConsoleText();
}
} else if (key === "backspace") {
if (currentInput.length > 0) {
currentInput = currentInput.slice(0, -1);
updateConsoleText();
}
} else if (key.length === 1) {
currentInput += key;
updateConsoleText();
}
}
// Start delete file sequence
function startDeleteSequence() {
deletingFiles = true;
deleteProgress = 0;
updateConsoleText();
var deleteInterval = LK.setInterval(function () {
deleteProgress += Math.random() * 15 + 5;
if (deleteProgress >= 95) {
deleteProgress = 95;
LK.clearInterval(deleteInterval);
// Show tomato when almost done
deleteTimeout = LK.setTimeout(function () {
showTomatoInConsole();
}, 500);
}
updateConsoleText();
}, 200);
}
// Show tomato appearing in console
function showTomatoInConsole() {
if (!consoleOverlay) return;
// Create tomato in console
var consoleTomato = new Tomato();
consoleTomato.init();
consoleTomato.x = 1024;
consoleTomato.y = 1000;
consoleTomato.scaleX = 2;
consoleTomato.scaleY = 2;
consoleOverlay.addChild(consoleTomato);
// Play Mr. Tomato's special voice line (use 'creepy' or 'jumpscare' sound for effect)
LK.getSound('creepy').play();
// After a short delay, try to "crash" the game, or show error text if not possible
LK.setTimeout(function () {
if (consoleOverlay) {
// Try to crash: show error text and block all input
consoleOverlay.destroy();
consoleOverlay = null;
consoleBg = null;
consoleText = null;
consoleVisible = false;
keyboardVisible = false;
currentInput = "";
deletingFiles = false;
deleteProgress = 0;
if (deleteTimeout) {
LK.clearTimeout(deleteTimeout);
deleteTimeout = null;
}
// Show a fake crash/error overlay
var crashOverlay = new Container();
game.addChild(crashOverlay);
var crashBg = LK.getAsset('table', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 30,
x: 1024,
y: 1366
});
crashBg.tint = 0x000000;
crashOverlay.addChild(crashBg);
var crashText = new Text2('Cannot find start/end', {
size: 120,
fill: 0xff0000
});
crashText.anchor.set(0.5, 0.5);
crashText.x = 1024;
crashText.y = 900;
crashOverlay.addChild(crashText);
// Show Mr. Tomato jumpscare on top
var crashTomato = new Tomato();
crashTomato.init();
crashTomato.setJumpscare();
crashTomato.x = 1024;
crashTomato.y = 1300;
crashTomato.scaleX = 2.5;
crashTomato.scaleY = 2.5;
crashOverlay.addChild(crashTomato);
// Play jumpscare sound
LK.getSound('jumpscare').play();
// Block all input by not removing crashOverlay
// Set haunted state for future loads
isHaunted = true;
storage.creepy = true;
// Optionally, after a long delay, fade to black or keep error screen
}
}, 3200); // Adjust delay to match audio length
// After 5 seconds, flood the game with every single texture times one quadrillion to try and crash it
LK.setTimeout(function () {
if (!game || !game.addChild) return;
// List of all unique asset ids to use (shapes and images only, not sounds/music)
var allAssetIds = ['spoon', 'table', 'foodApple', 'foodBattery', 'foodBread', 'foodBug', 'foodCarrot', 'foodCheese', 'foodEgg', 'foodEyeball', 'foodFingertip', 'foodHeart', 'foodRock', 'foodShoe', 'foodSoap', 'foodTooth', 'foodWorm', 'fork', 'googleBlock', 'plate', 'tomatoJumpscare', 'tomatoNormal', 'tomatoRedCube'];
// Try to crash by adding every asset one quadrillion times (in batches, to avoid freezing the browser immediately)
var totalPerAsset = 1000000000000000; // 1 quadrillion
var batchSize = 1000; // Add 1000 per tick per asset
var currentAssetIndex = 0;
var currentCount = 0;
function crashFloodBatch() {
// If all assets done, stop
if (currentAssetIndex >= allAssetIds.length) return;
var assetId = allAssetIds[currentAssetIndex];
for (var i = 0; i < batchSize; ++i) {
var obj = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
scaleX: 2 + Math.random() * 2,
scaleY: 2 + Math.random() * 2
});
game.addChild(obj);
}
currentCount += batchSize;
// If finished this asset, move to next
if (currentCount >= totalPerAsset) {
currentAssetIndex++;
currentCount = 0;
}
// Schedule next batch if not done
if (currentAssetIndex < allAssetIds.length) {
LK.setTimeout(crashFloodBatch, 1);
}
}
crashFloodBatch();
}, 5000);
}
// State text (for jumpscare/haunt)
stateTxt = new Text2('', {
size: 120,
fill: 0xFF0000
});
stateTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(stateTxt);
stateTxt.visible = false;
}
// --- GAME STATE ---
game.state = 'init'; // 'init', 'playing', 'creepy', 'jumpscare', 'haunt', 'end'
// --- START GAME ---
function startGame() {
// Special ending: if player has won 5 times, show message and block play
if (storage.specialEnding === true && !isHaunted) {
// Show special message and game over
tomato.setCreepy();
showMessage("Well, you’ve did all I needed for you to do. Now I don’t need you anymore. Do not open up this game anymore.");
stateTxt.setText("GAME OVER");
stateTxt.visible = true;
clearFoods();
game.state = 'end';
// Set haunted state for next launch
storage.creepy = true;
isHaunted = true;
// After a short delay, show game over
LK.setTimeout(function () {
LK.showGameOver();
}, 3500);
return;
}
// Reset
mistakeCount = 0;
correctCount = 0;
isJumpscare = false;
creepyFoodsFed = 0;
lastFoodIds = [];
scoreTxt.setText('0');
stateTxt.visible = false;
// If knife ending, block all foods/tomato
if (storage.knifeEnding === true) {
clearFoods();
if (tomato && tomato.destroy) {
tomato.destroy();
tomato = null;
}
showMessage("");
stateTxt.setText("");
stateTxt.visible = false;
game.state = 'blocked';
return;
}
tomato.setNormal();
game.state = isHaunted ? 'haunt' : 'playing';
if (isHaunted) {
showHaunt();
} else {
showMessage("Help me eat! Feed me the right foods.");
spawnFoods();
LK.playMusic('bgm', {
loop: true
});
}
}
// --- SHOW MESSAGE ---
function showMessage(msg) {
messageTxt.setText(msg);
}
// --- SPAWN FOODS ---
function spawnFoods() {
clearFoods();
foodObjs = [];
foodSlots = [];
var used = {};
var pool = game.state === 'creepy' ? creepyFoodTypes : foodTypes;
// Pick 5 foods, at least 1 correct (if not creepy)
var foods = [];
if (game.state === 'playing') {
// At least 1 good food
var good = [];
var bad = [];
for (var i = 0; i < pool.length; ++i) {
if (pool[i].isGood) good.push(pool[i]);else bad.push(pool[i]);
}
var goodFood = good[Math.floor(Math.random() * good.length)];
foods.push(goodFood);
// Fill rest
while (foods.length < foodSlotCount) {
var arr = Math.random() < 0.5 ? bad : good;
var f = arr[Math.floor(Math.random() * arr.length)];
// Avoid duplicates
var dupe = false;
for (var j = 0; j < foods.length; ++j) if (foods[j].id === f.id) dupe = true;
if (!dupe) foods.push(f);
}
} else {
// Creepy: all from creepyFoodTypes, random
while (foods.length < foodSlotCount) {
var f = pool[Math.floor(Math.random() * pool.length)];
var dupe = false;
for (var j = 0; j < foods.length; ++j) if (foods[j].id === f.id) dupe = true;
if (!dupe) foods.push(f);
}
}
// Shuffle
for (var i = foods.length - 1; i > 0; --i) {
var k = Math.floor(Math.random() * (i + 1));
var tmp = foods[i];
foods[i] = foods[k];
foods[k] = tmp;
}
// Place foods
for (var i = 0; i < foodSlotCount; ++i) {
var slotX = foodSlotXStart + i * foodSlotSpacing;
var food = new Food();
food.init(foods[i].id, foods[i].isGood, foods[i].isCreepy);
food.x = slotX;
food.y = foodSlotY;
food.scaleX = 1;
food.scaleY = 1;
food.alpha = 1;
foodObjs.push(food);
foodSlots.push({
x: slotX,
y: foodSlotY
});
game.addChild(food);
}
}
// --- CLEAR FOODS ---
function clearFoods() {
for (var i = 0; i < foodObjs.length; ++i) {
if (foodObjs[i] && foodObjs[i].destroy) foodObjs[i].destroy();
}
foodObjs = [];
foodSlots = [];
}
// --- KNIFE STAB FUNCTION ---
function stabTomato() {
// Only allow stabbing in normal/playing/creepy state
if (!tomato || isHaunted || game.state === 'jumpscare' || game.state === 'haunt' || game.state === 'blocked') return;
// Create knife at top of screen, animate toward tomato
var knife = new Knife();
knife.x = tomato.x;
knife.y = 0;
knife.scaleX = 2.2;
knife.scaleY = 2.2;
knife.stabbing = true;
knife.target = tomato;
knife.onStab = function () {
// Play knife voice line
LK.getSound('knifeVoice').play();
// Remove tomato after voice line, then show win
if (tomato && tomato.destroy) {
tomato.destroy();
tomato = null;
}
showMessage("");
stateTxt.setText("");
stateTxt.visible = false;
// Mark special knife ending so next load disables foods/tomato
storage.knifeEnding = true;
};
game.addChild(knife);
}
// --- HANDLE FOOD SELECT ---
game.handleFoodSelect = function (foodObj) {
// If in haunt state but player has typed play and started feeding, restore overlays and normal text
if (game.state === 'haunt') {
// Restore background and overlays
game.setBackgroundColor(0xf7e7c1);
if (table) table.visible = true;
if (plate) plate.visible = true;
for (var j = 0; j < utensils.length; ++j) {
if (utensils[j]) utensils[j].visible = true;
}
if (tomato.leftEye) tomato.leftEye.visible = false;
if (tomato.rightEye) tomato.rightEye.visible = false;
tomato.setNormal();
messageTxt.setText("Help me eat! Feed me the right foods.");
scoreTxt.setText(correctCount);
stateTxt.setText("");
stateTxt.visible = false;
game.state = 'playing';
spawnFoods();
return;
}
if (game.state !== 'playing' && game.state !== 'creepy') return;
if (foodObj.eaten) return;
// Animate food to tomato mouth
var mouthX = tomato.x;
var mouthY = tomato.y - 200;
tween(foodObj, {
x: mouthX,
y: mouthY,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
}, {
duration: 350,
easing: tween.easeIn,
onFinish: function onFinish() {
foodObj.eat();
if (game.state === 'playing') {
if (foodObj.isGood) {
correctCount++;
LK.getSound('eat').play();
LK.effects.flashObject(tomato, 0x9bff4a, 400);
showMessage("Yum! Thank you.");
scoreTxt.setText(correctCount);
if (correctCount >= maxCorrect) {
// If player wins with 5 anger, trigger creepy win sequence
if (mistakeCount === 5) {
// Spinning eyes effect: overlay two spinning ellipses on tomato
if (!tomato.leftSpinEye) {
tomato.leftSpinEye = LK.getAsset('foodEyeball', {
anchorX: 0.5,
anchorY: 0.5,
x: -70,
y: -180,
scaleX: 0.7,
scaleY: 1.1
});
tomato.addChild(tomato.leftSpinEye);
}
if (!tomato.rightSpinEye) {
tomato.rightSpinEye = LK.getAsset('foodEyeball', {
anchorX: 0.5,
anchorY: 0.5,
x: 70,
y: -180,
scaleX: 0.7,
scaleY: 1.1
});
tomato.addChild(tomato.rightSpinEye);
}
tomato.leftSpinEye.visible = true;
tomato.rightSpinEye.visible = true;
// Animate spinning
var spinTicks = 0;
var spinTween = LK.setInterval(function () {
spinTicks++;
if (tomato.leftSpinEye) tomato.leftSpinEye.rotation += 0.3;
if (tomato.rightSpinEye) tomato.rightSpinEye.rotation -= 0.3;
if (spinTicks > 20) {
LK.clearInterval(spinTween);
}
}, 30);
// Set creepy face
tomato.setCreepy();
showMessage("");
stateTxt.setText("You fed me but not good enough.");
stateTxt.visible = true;
// Play creepy sound
LK.getSound('creepy').play();
// After a short delay, jumpscare and haunt
LK.setTimeout(function () {
// Hide spinning eyes
if (tomato.leftSpinEye) tomato.leftSpinEye.visible = false;
if (tomato.rightSpinEye) tomato.rightSpinEye.visible = false;
// Jumpscare
tomato.setJumpscare();
showMessage("");
stateTxt.setText("");
stateTxt.visible = true;
LK.getSound('jumpscare').play();
LK.effects.flashScreen(0xff0000, 1200);
storage.creepy = true;
// After a moment, show haunt
jumpscareTimeout = LK.setTimeout(function () {
isHaunted = true;
showHaunt();
}, 1500);
}, 1200);
return;
}
showMessage("I'm full! See you tomorrow!");
LK.setTimeout(function () {
LK.showYouWin();
}, 1200);
return;
}
} else {
mistakeCount++;
LK.getSound('wrong').play();
LK.effects.flashObject(tomato, 0xff0000, 400);
showMessage("Yuck! That's not food.");
if (mistakeCount >= maxMistakes) {
// Go creepy
LK.getSound('creepy').play();
goCreepy();
return;
}
}
// Next round
LK.setTimeout(function () {
showMessage("Feed me the right foods.");
spawnFoods();
}, 700);
} else if (game.state === 'creepy') {
// Only creepy foods accepted
if (foodObj.isCreepy) {
creepyFoodsFed++;
LK.getSound('eat').play();
LK.effects.flashObject(tomato, 0xff0000, 400);
showMessage("More. Feed me more...");
if (creepyFoodsFed >= creepyFoodsNeeded) {
// Jumpscare
LK.setTimeout(function () {
jumpscare();
}, 700);
return;
}
} else {
LK.getSound('wrong').play();
LK.effects.flashObject(tomato, 0x000000, 400);
showMessage("NO! Give me what I want.");
}
LK.setTimeout(function () {
spawnFoods();
}, 700);
}
}
});
};
// --- GO CREEPY ---
function goCreepy() {
game.state = 'creepy';
tomato.setCreepy();
showMessage("You made me angry. Feed me what I want...");
LK.effects.flashScreen(0x000000, 1200);
LK.setTimeout(function () {
spawnFoods();
}, 1200);
}
// --- JUMPSCARE ---
function jumpscare() {
game.state = 'jumpscare';
isJumpscare = true;
clearFoods();
tomato.setJumpscare();
showMessage("");
stateTxt.setText("👁️");
stateTxt.visible = true;
LK.getSound('jumpscare').play();
LK.effects.flashScreen(0xff0000, 1200);
// Save haunted state
storage.creepy = true;
// After a moment, show game over
jumpscareTimeout = LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
// --- SHOW HAUNTED STATE ---
function showHaunt() {
game.state = 'haunt';
clearFoods();
// Set background to black
game.setBackgroundColor(0x000000);
// Remove all GUI overlays
messageTxt.setText("");
scoreTxt.setText("");
stateTxt.setText("");
stateTxt.visible = false;
// Set tomato to creepy and move to center
tomato.setCreepy();
tomato.x = 1024;
tomato.y = 1366;
// Make tomato's face black-eyed (simulate by overlaying two black ellipses for eyes)
if (!tomato.leftEye) {
tomato.leftEye = LK.getAsset('foodRock', {
anchorX: 0.5,
anchorY: 0.5,
x: -70,
y: -180,
scaleX: 0.7,
scaleY: 1.1
});
tomato.rightEye = LK.getAsset('foodRock', {
anchorX: 0.5,
anchorY: 0.5,
x: 70,
y: -180,
scaleX: 0.7,
scaleY: 1.1
});
tomato.addChild(tomato.leftEye);
tomato.addChild(tomato.rightEye);
}
tomato.leftEye.visible = true;
tomato.rightEye.visible = true;
// Hide table, plate, utensils
if (table) table.visible = false;
if (plate) plate.visible = false;
for (var i = 0; i < utensils.length; ++i) {
if (utensils[i]) utensils[i].visible = false;
}
// Special message if player triggered special ending
if (storage.specialEnding === true && typeof storage.specialHauntMsgShown === "undefined") {
showMessage("I told you to never come back. I just said never come back. You want to break the rules? Well, I don’t allow rule breakers.");
stateTxt.setText("");
stateTxt.visible = false;
storage.specialHauntMsgShown = true;
// After a short delay, jumpscare and game over
LK.setTimeout(function () {
tomato.setJumpscare();
showMessage("");
stateTxt.setText("");
stateTxt.visible = true;
LK.getSound('jumpscare').play();
LK.effects.flashScreen(0xff0000, 1200);
// After a moment, show game over
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}, 3200);
return;
}
// No interaction, no text, just the tomato staring
// Allow console button to escape the haunt sequence
if (typeof LK !== "undefined" && LK.gui && LK.gui.topRight && LK.gui.topRight.children) {
for (var i = 0; i < LK.gui.topRight.children.length; ++i) {
var child = LK.gui.topRight.children[i];
if (child && child.setText && child.setText.toString().indexOf("console") !== -1) {
// This is the consoleBtn
child.down = function (x, y, obj) {
// Escape haunt and show console
if (game.state === 'haunt') {
// Restore background and overlays
game.setBackgroundColor(0xf7e7c1);
if (table) table.visible = true;
if (plate) plate.visible = true;
for (var j = 0; j < utensils.length; ++j) {
if (utensils[j]) utensils[j].visible = true;
}
tomato.leftEye.visible = false;
tomato.rightEye.visible = false;
tomato.setNormal();
game.state = 'init';
showConsole();
} else if (!consoleVisible) {
showConsole();
} else {
hideConsole();
}
};
break;
}
}
}
}
// --- GAME INIT ---
setupScene();
// If knife ending, block all foods/tomato on load
if (storage.knifeEnding === true) {
clearFoods();
if (tomato && tomato.destroy) {
tomato.destroy();
tomato = null;
}
game.setBackgroundColor(0x000000);
messageTxt.setText("");
scoreTxt.setText("");
stateTxt.setText("");
stateTxt.visible = false;
// Hide table, plate, utensils
if (table) table.visible = false;
if (plate) plate.visible = false;
for (var i = 0; i < utensils.length; ++i) {
if (utensils[i]) utensils[i].visible = false;
}
game.state = 'blocked';
} else if (storage.specialHauntMsgShown === true && storage.specialEnding === true) {
// Show black background and message
game.setBackgroundColor(0x000000);
clearFoods();
tomato.setCreepy();
tomato.x = 1024;
tomato.y = 1366;
messageTxt.setText("Don't come back");
scoreTxt.setText("");
stateTxt.setText("");
stateTxt.visible = false;
// Hide table, plate, utensils
if (table) table.visible = false;
if (plate) plate.visible = false;
for (var i = 0; i < utensils.length; ++i) {
if (utensils[i]) utensils[i].visible = false;
}
game.state = 'blocked';
} else {
startGame();
}
// --- GAME EVENTS ---
game.update = function () {
// No per-frame logic needed for this game
};
game.down = function (x, y, obj) {
// No drag, but allow food selection
// (handled by Food.down)
};
game.move = function (x, y, obj) {
// No drag
};
game.up = function (x, y, obj) {
// No drag
};
// --- RESET ON GAME OVER ---
LK.on('gameover', function () {
// Reset haunted state if not jumpscare
if (!isJumpscare) {
storage.creepy = false;
}
});
// --- WIN HANDLER ---
LK.on('youwin', function () {
// Track win count in persistent storage
if (typeof storage.winCount !== "number") storage.winCount = 0;
storage.winCount++;
storage.creepy = false;
// If player has won 5 times, set special flag
if (storage.winCount >= 5) {
storage.specialEnding = true;
}
});
// --- MUSIC ---
LK.playMusic('bgm', {
loop: true
});
Modern App Store icon, high definition, square with rounded corners, for a game titled "Feed the Tomato: The Hungry Return" and with the description "Help a tomato eat by choosing the right foods. Too many mistakes turn it creepy, leading to a jumpscare and a haunting return.". No text on icon!
Apple. In-Game asset. 2d. High contrast. No shadows
bratery. In-Game asset. 2d. High contrast. No shadows
Bread. In-Game asset. 2d. High contrast. No shadows
cheese. In-Game asset. 2d. High contrast. No shadows
Bug. In-Game asset. 2d. High contrast. No shadows
Egg. In-Game asset. 2d. High contrast. No shadows
Eyeball. In-Game asset. 2d. High contrast. No shadows
Fingertip. In-Game asset. 2d. High contrast. No shadows
A real heart. In-Game asset. 2d. High contrast. No shadows
Rock. In-Game asset. 2d. High contrast. No shadows
Shoe. In-Game asset. 2d. High contrast. No shadows
Tooth. In-Game asset. 2d. High contrast. No shadows
Plate. In-Game asset. 2d. High contrast. No shadows
Soap. In-Game asset. 2d. High contrast. No shadows
Fork. In-Game asset. 2d. High contrast. No shadows
Carrot. In-Game asset. 2d. High contrast. No shadows
Worm. In-Game asset. 2d. High contrast. No shadows
tomato with eyes. In-Game asset. 2d. High contrast. No shadows
Error. In-Game asset. 2d. High contrast. No shadows