User prompt
Right now you’re showing "Drift Limb: HINT TEXT". Instead, we’ll just show the hint: // OLD: patientDiv.innerText = `${illness.name}: ${illness.hint}`; // NEW: patientDiv.innerText = illness.hint; patientDiv.style.color = "black"; // also fixes the black text request . Fix Hint Text Overflow If the hint is too long and runs off screen, wrap it inside a scrollable box. For example: #patientHint { max-width: 400px; /* keep within screen */ max-height: 120px; /* limit vertical space */ overflow-y: auto; /* add scroll if too long */ padding: 8px; background: #fff; border-radius: 12px; color: black; font-size: 14px; } // wrap text inside the div patientDiv.innerHTML = `
User prompt
Remove elements object entirely. We’ll replace it with teaBases. Define Tea Bases: const teaBases = { Wind: { name: "Uplifting Tea Base", element: "Wind" }, Earth: { name: "Earthy Tea Base", element: "Earth" }, Water: { name: "Cooling Tea Base", element: "Water" }, Fire: { name: "Spicy Tea Base", element: "Fire" } }; Update Herbs list so each herb has an element property: const herbs = { demetersArrow: { name: "Demeter’s Arrow", element: "Wind" }, fuzzyPeeper: { name: "Fuzzy Peeper", element: "Wind" }, kittyMitten: { name: "Kitty Mitten", element: "Fire" }, devilsLantern: { name: "Devil’s Lantern", element: "Fire" }, // etc. for Earth + Water herbs }; Crafting rule: Check: first item = Tea Base Next 2 items = herbs of the same element as that base If match → valid tea cures illness. function brewTea(base, herb1, herb2) { if (herb1.element === base.element && herb2.element === base.element && herb1 !== herb2) { return { name: `${base.name} + ${herb1.name} + ${herb2.name}`, element: base.element }; } return null; // invalid tea } llness definitions: Each illness should be linked to an element, not a specific fixed recipe. const illnesses = { driftLimb: { name: "Drift Limb", element: "Wind", hint: "I’ve been working so hard lately, my arms feel so heavy..." }, // Fire, Earth, Water illnesses... }; Checking cures: If brewedTea.element === illness.element → cured ✅
User prompt
We’ll add a Herbalist’s Journal object (or just a JS data structure for now), and give it one illness entry (Feverish Glow) plus the herbs you’ve already got. Then we can render that in a simple scrollable popup. Here’s a working setup you can drop into your existing code:
“A heat that rises from the soles like creeping ivy, leaving the brow slick and the mind hazy.”
Causes: Overexertion, getting caught in the rain, too many fire herbs.
Symptoms (what patients might say):
Cure: Brew Water-aligned tea with River Leek or Frogwick.
User prompt
2. How the cure works within the matrix Each illness is secretly defined by imbalances in your existing system. Example with Feverish Glow: Causes: Overexertion, rain exposure, or too many fire herbs. Hidden State: Body = “overheated / too much fire element.” Cure Rule: Counter fire → prescribe water element + a cooling herb. So in your data: { "id": "feverish_glow", "description": "A heat that rises from the soles...", "symptoms": [ "I’ve been working late into the night, and now I can’t stop sweating.", "Is it hot in here?", "Have you ever had a Devil’s Lantern?..." ], "element_imbalance": "fire", "cure": { "required_element": "water", "preferred_herbs": ["moonleaf", "dewpetal", "cooling_mint"], "base": "any" // flexible, unless you want special restrictions } }
User prompt
// ✅ 2) Add "behind counter" graphic let behindCounter = scene.add.image(scene.cameras.main.centerX, 500, "behindCounter"); behindCounter.setDepth(1); // Assume your main counter graphic is already added counter.setDepth(2); cauldron.setDepth(3); // ✅ 3) Reposition cauldron // Move it lower so it looks like it sits ON the counter cauldron.setPosition(scene.cameras.main.centerX, 520); cauldron.setDepth(3); // Ensure it's above the counter // ✅ 4) Remove Shop UI if (shopUI) { shopUI.destroy(true); // remove container + children shopUI = null; } // ✅ 5) Make herbs box text white let herbsLabel = scene.add.text(50, 100, "Herbs", { fontSize: "26px", color: "#ffffff", // White text fontStyle: "bold" });
User prompt
5) Reliable “tap for description” vs “drag to brew” + visible drag ghost Replace the popup part of your input handlers with the following. (Leave the “regular inventory” branch as-is.) // === Tap vs Drag state === var downItemCandidate = null; var downStartX = 0, downStartY = 0; var DRAG_THRESHOLD = 22; // px movement to start dragging var dragGhost = null; // helper: rectangular hit test function hitRect(x, y, cx, cy, halfW, halfH) { return Math.abs(x - cx) <= halfW && Math.abs(y - cy) <= halfH; } function createDragGhostFromMenu(name, color, cost, startX, startY) { var ghost = new Container(); ghost.x = startX; ghost.y = startY; game.addChild(ghost); var bg = ghost.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, tint: color, width: 220, height: 100 }); var txt = new Text2(name, { size: 44, fill: 0xFFFFFF }); txt.anchor.set(0.5,0.5); txt.x = 0; txt.y = 0; ghost.addChild(txt); ghost.name = name; ghost.isDragging = true; ghost.isMenuPurchase = true; ghost.cost = cost; ghost.dragOffsetX = 0; ghost.dragOffsetY = 0; // subtle pop so it feels grabbed tween(ghost, { scaleX: 1.08, scaleY: 1.08 }, { duration: 120 }); return ghost; } game.down = function (x, y, obj) { // If popup visible, prefer its items if (popupMenu.isVisible) { downItemCandidate = null; for (var i = popupMenu.menuItems.length - 1; i >= 0; i--) { var it = popupMenu.menuItems[i]; // rectangular hit for reliability var hw = (it.hitW || 120) / 2; var hh = (it.hitH || 120) / 2; if (hitRect(x, y, it.x, it.y, hw, hh)) { downItemCandidate = it; break; } } downStartX = x; downStartY = y; return; // wait to see if this becomes a tap or a drag } // Regular inventory items (unchanged) for (var i = inventoryItems.length - 1; i >= 0; i--) { var item = inventoryItems[i]; var dx = x - item.x, dy = y - item.y; var distance = Math.sqrt(dx*dx + dy*dy); if (distance < 50) { heldItem = item; item.isDragging = true; item.dragOffsetX = x - item.x; item.dragOffsetY = y - item.y; break; } } }; game.move = function (x, y, obj) { // If we have a candidate from popup and movement crosses threshold, start drag with a visible ghost if (downItemCandidate && !heldItem) { var moved = Math.sqrt((x - downStartX)*(x - downStartX) + (y - downStartY)*(y - downStartY)); if (moved > DRAG_THRESHOLD) { // check funds before allowing drag if (goldAmount >= downItemCandidate.cost) { var tint = downItemCandidate.children[0] ? downItemCandidate.children[0].tint : 0x1565C0; heldItem = dragGhost = createDragGhostFromMenu(downItemCandidate.name, tint, downItemCandidate.cost, x, y); heldItem.dragOffsetX = 0; heldItem.dragOffsetY = 0; } else { patientStatusText.setText('Not enough gold! Need ' + downItemCandidate.cost + ' gold.'); downItemCandidate = null; } } } // Move the active drag item (ghost or regular) if (heldItem && heldItem.isDragging) { heldItem.x = x - (heldItem.dragOffsetX || 0); heldItem.y = y - (heldItem.dragOffsetY || 0); } }; game.up = function (x, y, obj) { // TAP on popup item -> show details (no drag started) if (downItemCandidate && !heldItem) { popupMenu.showDetails(downItemCandidate.name); downItemCandidate = null; return; } downItemCandidate = null; // DROP logic (ghost from menu or regular inventory) if (heldItem) { heldItem.isDragging = false; // Calculate distance to cauldron var dx = heldItem.x - cauldron.x; var dy = heldItem.y - cauldron.y; var distance = Math.sqrt(dx*dx + dy*dy); // Menu purchase ghost dropped on cauldron if (heldItem.isMenuPurchase) { if (distance < 200 && cauldron.ingredients.length < 3) { goldAmount -= heldItem.cost; goldText.setText('Gold: ' + goldAmount); cauldron.ingredients.push(heldItem.name); updateCauldronDisplay(); tween(cauldron, { tint: 0x44FF44 }, { duration: 200, onFinish: function() { tween(cauldron, { tint: 0xFFFFFF }, { duration: 200 }); }}); // remove ghost, keep popup open for multiple adds game.removeChild(heldItem); } else { // Not dropped in valid area -> cancel purchase, remove ghost game.removeChild(heldItem); } heldItem = null; dragGhost = null; return; } // Regular inventory item drop (unchanged) if (distance < 200 && cauldron.ingredients.length < 3) { cauldron.ingredients.push(heldItem.name); updateCauldronDisplay(); tween(cauldron, { tint: 0x44FF44 }, { duration: 200, onFinish: function() { tween(cauldron, { tint: 0xFFFFFF }, { duration: 200 }); }}); var itemIndex = inventoryItems.indexOf(heldItem); if (itemIndex > -1) { game.removeChild(heldItem); inventoryItems.splice(itemIndex, 1); } } else { tween(cauldron, { tint: 0xFF4444 }, { duration: 200, onFinish: function() { tween(cauldron, { tint: 0xFFFFFF }, { duration: 200 }); }}); resetItem(heldItem); } heldItem = null; } }; ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
4) Make menu items big, readable, and easy to hit (replace your createInventoryItem) function createInventoryItem(name, x, y, color, isMenuItem) { var container = new Container(); container.x = x; container.y = y; game.addChild(container); // Use big rounded rectangles for menu items; bottles for inventory var assetType = isMenuItem ? 'craftButton' : 'potionBottle'; var item = container.attachAsset(assetType, { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, tint: color }); if (isMenuItem) { item.width = 220; item.height = 100; } else { // inventory representation can stay as-is } var label = new Text2(name, { size: isMenuItem ? 44 : 24, // 👈 bigger menu text fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); label.x = 0; label.y = 0; container.addChild(label); // attach metadata (if this is a herb, we have more info) container.name = name; container.meta = HERB_DATA[name] || null; container.draggable = true; container.type = 'ingredient'; container.isDragging = false; container.originalX = x; container.originalY = y; // for rectangular hit test container.hitW = isMenuItem ? item.width : 120; container.hitH = isMenuItem ? item.height : 120; return container; }
User prompt
let’s make the herb-description popup reliable on tap and make all the text much larger, plus give you a visible drag ghost so the player can clearly see what they’re holding. Below are surgical code edits you can paste into your current file. I’m only touching the parts needed: /**** * Herb Data & Helpers ****/ var HERB_DATA = { "Sheep Bane": { type:"Plant", alignment:"Earth", description:"A nourishing plant with small white flowers found in lush meadows with plenty of sunshine." }, "Fuzzy Peeper": { type:"Plant", alignment:"Wind", description:"A pale puffball perched on a long stem; it turns gently to face any breeze, no matter how faint." }, "Sommeral": { type:"Plant", alignment:"Fire", description:"A spiny red blossom that thrives in sun-scorched fields; its petals crackle faintly when crushed." }, "Common Snupe": { type:"Plant", alignment:"Earth", description:"A squat, stubby herb with ridged leaves and a sharp nutty scent—grows best near compost heaps and pig pens." }, "Geneva’s Dewdrop": { type:"Plant", alignment:"Water", description:"Delicate blue bulbs that drip a perpetual cool dew; said to be first planted by a weeping maiden." }, "Brindleroot": { type:"Plant", alignment:"Fire", description:"A twisted root that glows faintly from within—often brewed to stoke warmth into cold limbs." }, "Frogwick": { type:"Plant", alignment:"Water", description:"Rubbery, semi-aquatic herb found near marshes—tastes awful but soothes the throat like magic." }, "Demeter’s Arrow": { type:"Plant", alignment:"Wind", description:"Thin silvery leaves that grow in spirals. When burned, they produce a vapor that clears the lungs and bowels." }, "River Leek": { type:"Plant", alignment:"Water", description:"A long, fragrant stalk that grows in riverside soil; its boiled leaves soothe fevers and dampen restlessness." }, "Pipeweed": { type:"Plant", alignment:"Wind", description:"Fragrant and slightly numbing, this herb is often smoked by hill witches and daydreaming farmhands." }, "Kitty Mitten": { type:"Plant", alignment:"Fire", description:"Soft red-orange fuzz covers these leaves, which are pleasantly warm to the touch. Cats love to nap on them." }, "Malicious Bule": { type:"Fungus", alignment:"Wind", description:"A pale fungus with twisting gills and a sweet, spoiled smell. It’s said to whisper when the wind passes through a grove." }, "False Dunny Cap": { type:"Fungus", alignment:"Earth", description:"Often mistaken for its edible cousin, this fungus has a thick gray stalk and a damp cellar scent. Caution advised." }, "Callum’s Perch": { type:"Fungus", alignment:"Earth", description:"Named for the druid who first brewed it into a sleep tonic, this squat, mossy mushroom grows on dead stumps in shadow." }, "Pinwort": { type:"Fungus", alignment:"Water", description:"Soft and glossy with lilac-speckled caps, these fungi flourish in damp caves and give off a faint minty aroma." }, "Devil’s Lantern": { type:"Fungus", alignment:"Fire", description:"This bioluminescent red fungus pulses with warmth. It grows in deep caverns and is rumored to attract fire spirits." }, "Lady’s Teacup": { type:"Fungus", alignment:"Water", description:"Shaped like a delicate bowl, often found filled with morning dew. Some fae insist it must only be harvested under moonlight." }, "Dead Man’s Toe": { type:"Fungus", alignment:"Earth", description:"Black and bulbous, it pushes up from graveyard soil and smells of rust. Disturbing in appearance, yet grounding when dried." }, "Agarium": { type:"Fungus", alignment:"Earth", description:"Smooth and tan, with a satisfying snap when broken. This dependable fungus is a staple in many earthy decoctions." }, "Thimbliss": { type:"Fungus", alignment:"Wind", description:"Tiny, translucent caps that grow in clusters beneath bird nests. Harmless alone, but intensify the effects of other herbs." }, "Lesser Bluecap": { type:"Fungus", alignment:"Water", description:"Short and stubby with a dusty blue top, this unassuming mushroom has mild cooling properties and is common in boggy woods." } }; // ordered list for the Herbs popup var herbItems = Object.keys(HERB_DATA); function colorForAlignment(align) { if (align === "Fire") return 0xFF6B6B; if (align === "Water") return 0x6BB6FF; if (align === "Earth") return 0x8B8F6B; if (align === "Wind") return 0xBEE3F8; return 0xADFF2F; } function wrapTextByWords(str, maxLen) { var words = str.split(' '); var lines = []; var current = ''; for (var i = 0; i < words.length; i++) { var tryLine = current.length ? (current + ' ' + words[i]) : words[i]; if (tryLine.length > maxLen) { if (current.length) lines.push(current); current = words[i]; } else { current = tryLine; } } if (current.length) lines.push(current); return lines.join('\n'); }
User prompt
Step 2: Create the Popup Window This will be a floating div that appears when an herb is tapped.
User prompt
const herbs = { "Sheep Bane": { element: "Earth", description: "A nourishing plant with small white flowers found in lush meadows with plenty of sunshine.", sprite: "sheepbane.png" }, "Fuzzy Peeper": { element: "Wind", description: "A pale puffball perched on a long stem; it turns gently to face any breeze, no matter how faint.", sprite: "fuzzypeeper.png" }, // ... continue for all herbs };
User prompt
fully replace the placeholder herbs in your game. Here’s how we can integrate them cleanly: Step 1. Structure the herb data It’s best to keep all herb info in a single object/array, so you can easily pull alignment, description, etc., when the player selects one. Example: // herbs.js const herbs = [ { name: "Sheep Bane", type: "Plant", alignment: "Earth", description: "A nourishing plant with small white flowers found in lush meadows with plenty of sunshine." }, { name: "Fuzzy Peeper", type: "Plant", alignment: "Wind", description: "A pale puffball perched on a long stem; it turns gently to face any breeze, no matter how faint." }, { name: "Sommeral", type: "Plant", alignment: "Fire", description: "A spiny red blossom that thrives in sun-scorched fields; its petals crackle faintly when crushed." }, { name: "Common Snupe", type: "Plant", alignment: "Earth", description: "A squat, stubby herb with ridged leaves and a sharp nutty scent—grows best near compost heaps and pig pens." }, { name: "Geneva’s Dewdrop", type: "Plant", alignment: "Water", description: "Delicate blue bulbs that drip a perpetual cool dew; said to be first planted by a weeping maiden." }, { name: "Brindleroot", type: "Plant", alignment: "Fire", description: "A twisted root that glows faintly from within—often brewed to stoke warmth into cold limbs." }, { name: "Frogwick", type: "Plant", alignment: "Water", description: "Rubbery, semi-aquatic herb found near marshes—tastes awful but soothes the throat like magic." }, { name: "Demeter’s Arrow", type: "Plant", alignment: "Wind", description: "Thin silvery leaves that grow in spirals. When burned, they produce a vapor that clears the lungs and bowels." }, { name: "River Leek", type: "Plant", alignment: "Water", description: "A long, fragrant stalk that grows in riverside soil; its boiled leaves soothe fevers and dampen restlessness." }, { name: "Pipeweed", type: "Plant", alignment: "Wind", description: "Fragrant and slightly numbing, this herb is often smoked by hill witches and daydreaming farmhands." }, { name: "Kitty Mitten", type: "Plant", alignment: "Fire", description: "Soft red-orange fuzz covers these leaves, which are pleasantly warm to the touch. Cats love to nap on them." }, { name: "Malicious Bule", type: "Fungus", alignment: "Wind", description: "A pale fungus with twisting gills and a sweet, spoiled smell. It’s said to whisper when the wind passes through a grove." }, { name: "False Dunny Cap", type: "Fungus", alignment: "Earth", description: "Often mistaken for its edible cousin, this fungus has a thick gray stalk and a damp cellar scent. Caution advised." }, { name: "Callum’s Perch", type: "Fungus", alignment: "Earth", description: "Named for the druid who first brewed it into a sleep tonic, this squat, mossy mushroom grows on dead stumps in shadow." }, { name: "Pinwort", type: "Fungus", alignment: "Water", description: "Soft and glossy with lilac-speckled caps, these fungi flourish in damp caves and give off a faint minty aroma." }, { name: "Devil’s Lantern", type: "Fungus", alignment: "Fire", description: "This biolum
User prompt
Movie the notification status like "a new patient has arrived!" so the bottom of the screen.
User prompt
move the craft potion button so it's visible at the bottom of the screen.
User prompt
Here’s a rewritten version of your drawIngredientMenu that makes the menus look like proper pop-up windows with centered text buttons:
User prompt
apply the same centering and font logic inside the popup menu rendering function. Here’s a template fix for that part:
User prompt
Enlarging the buttons. Increasing the font size. Centering them horizontally within the brown panel. Adding some spacing so they’re not squished together. Here’s an example in JavaScript + CSS (LK.js / Canvas style) that would give you bigger, centered, more visible buttons:
User prompt
move the bases, elements, and herbs buttons down under the wood plank counter so that they dont overlap
User prompt
increase text size for ingredients for better readbility
User prompt
ChatGPT said: Got it — to make the UI less “stacked and cluttered,” we want to restructure it into three layers/containers: HUD / Top Bar (Gold, Score, Buttons) Center (Patient + Cauldron + Dialogue) Bottom (Ingredient Buttons + Craft Button) Here’s a clean way to handle this in LK.js (your setup looks a lot like p5.js / JS canvas style code):
User prompt
🔨 Plan for the Ingredient Menus Remove the bottles from the main play area → No potion bottle graphics cluttering the bottom. Ingredients won’t appear unless you open their category menu. Add three clean buttons under the cauldron BASES ELEMENTS HERBS Clicking a button opens a pop-up menu (overlay window) This window lists the available ingredients for that category. Each ingredient appears as a draggable text button (or a small icon if you want later), not potion bottle art. Example:
User prompt
✅ Step 1: Add Menu Buttons We’ll place three buttons above the counter.
User prompt
✅ Step 3: Generate Ingredient Items inside the Window We’ll reuse createInventoryItem, but change it to use simple colored boxes instead of potion bottles.
User prompt
✅ Step 2: Create a Pop-up Menu Window This is a box that appears when a button is pressed, with draggable ingredient items inside.
User prompt
✅ Step 1: Add Menu Buttons We’ll place three buttons above the counter.
User prompt
✅ 2. Potion bottle only appears after all 3 ingredients are added Right now, the PotionBottle is always on screen (game.addChild(new PotionBottle())). We need to: Start hidden (visible = false). Show it only when cauldron.ingredients.length === 3. Code Edit (PotionBottle instance):
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var HerbPopup = Container.expand(function () { var self = Container.call(this); // Semi-transparent background overlay var overlay = self.attachAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732, alpha: 0.8, tint: 0x000000 }); // Main popup window - larger and centered var popupWindow = self.attachAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, width: 1600, height: 1000, tint: 0x8B4513 }); // Close button (X) - larger var closeButton = self.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 1700, y: 950, width: 120, height: 120, tint: 0xFF0000 }); var closeButtonText = new Text2('X', { size: 80, fill: 0xFFFFFF }); closeButtonText.anchor.set(0.5, 0.5); closeButtonText.x = 1700; closeButtonText.y = 950; self.addChild(closeButtonText); // Herb name title - much larger var nameText = new Text2('', { size: 72, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.x = 1024; nameText.y = 1050; self.addChild(nameText); // Type text (Plant/Fungus) var typeText = new Text2('', { size: 48, fill: 0xFFD700 }); typeText.anchor.set(0.5, 0.5); typeText.x = 1024; typeText.y = 1150; self.addChild(typeText); // Element text - larger var elementText = new Text2('', { size: 52, fill: 0xFFFFFF }); elementText.anchor.set(0.5, 0.5); elementText.x = 1024; elementText.y = 1250; self.addChild(elementText); // Description text - much larger and wrapped var descriptionText = new Text2('', { size: 40, fill: 0xFFFFFF }); descriptionText.anchor.set(0.5, 0.5); descriptionText.x = 1024; descriptionText.y = 1500; self.addChild(descriptionText); self.isVisible = false; self.showPopup = function (herbName, x, y) { var herbData = HERB_DATA[herbName]; if (!herbData) return; nameText.setText(herbName); typeText.setText(herbData.type); elementText.setText('Element: ' + herbData.alignment); // Wrap long descriptions var wrappedDesc = wrapTextByWords(herbData.description, 50); descriptionText.setText(wrappedDesc); // Color the element text based on alignment var color = colorForAlignment(herbData.alignment); elementText.tint = color; self.visible = true; self.isVisible = true; }; self.hidePopup = function () { self.visible = false; self.isVisible = false; }; // Close button handler closeButton.down = function (x, y, obj) { self.hidePopup(); }; // Overlay click to close overlay.down = function (x, y, obj) { self.hidePopup(); }; // Start hidden self.visible = false; return self; }); var Patient = Container.expand(function () { var self = Container.call(this); var patientBody = self.attachAsset('patient', { anchorX: 0.5, anchorY: 0.5 }); // symptomGlow moved to main game - reference will be set externally self.symptomGlow = null; self.symptomType = ''; self.requiredBase = ''; self.requiredElement = ''; self.requiredHerb = ''; self.goldReward = 0; self.setSymptom = function (type) { self.symptomType = type; if (type === 'redrose') { if (self.symptomGlow) self.symptomGlow.tint = 0xFF4444; self.requiredBase = 'infusion'; self.requiredElement = 'water'; self.requiredHerb = 'Geneva\'s Dewdrop'; self.goldReward = 100; } else if (type === 'bluemist') { if (self.symptomGlow) self.symptomGlow.tint = 0x4444FF; self.requiredBase = 'broth'; self.requiredElement = 'fire'; self.requiredHerb = 'Sommeral'; self.goldReward = 120; } else if (type === 'emeraldveil') { if (self.symptomGlow) self.symptomGlow.tint = 0x44FF44; self.requiredBase = 'infusion'; self.requiredElement = 'earth'; self.requiredHerb = 'Common Snupe'; self.goldReward = 150; } }; self.reactToPotion = function (base, element, herb) { var correctCount = 0; if (base === self.requiredBase) correctCount++; if (element === self.requiredElement) correctCount++; if (herb === self.requiredHerb) correctCount++; if (correctCount === 3) { tween(patientBody, { tint: 0x90EE90 }, { duration: 1000 }); LK.getSound('success').play(); return self.goldReward; } else if (correctCount >= 1) { tween(patientBody, { tint: 0xFFFF99 }, { duration: 1000 }); return Math.floor(self.goldReward * 0.5); } else { tween(patientBody, { tint: 0xFF6666 }, { duration: 1000 }); LK.getSound('failure').play(); return -20; } }; return self; }); var PopupMenu = Container.expand(function () { var self = Container.call(this); // Semi-transparent background overlay var overlay = self.attachAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732, alpha: 0.7, tint: 0x000000 }); // Main popup window var popupWindow = self.attachAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, width: 1400, height: 1000, tint: 0x8B4513 }); // Close button (X) var closeButton = self.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 1600, y: 600, width: 80, height: 80, tint: 0xFF0000 }); var closeButtonText = new Text2('X', { size: 40, fill: 0xFFFFFF }); closeButtonText.anchor.set(0.5, 0.5); closeButtonText.x = 1600; closeButtonText.y = 600; self.addChild(closeButtonText); // Title text var titleText = new Text2('', { size: 50, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 700; self.addChild(titleText); self.menuItems = []; self.isVisible = false; self.showMenu = function (title, items, itemColors) { titleText.setText(title); self.visible = true; self.isVisible = true; // Clear existing menu items for (var i = 0; i < self.menuItems.length; i++) { game.removeChild(self.menuItems[i]); } self.menuItems = []; // Create proper button-style menu items - centered layout var itemsPerRow = 3; var buttonWidth = 300; var buttonHeight = 100; var buttonSpacing = 50; var totalRowWidth = itemsPerRow * buttonWidth + (itemsPerRow - 1) * buttonSpacing; var startX = 1024 - totalRowWidth / 2 + buttonWidth / 2; // Center within screen var startY = 950; var rowSpacing = 130; for (var i = 0; i < items.length; i++) { var row = Math.floor(i / itemsPerRow); var col = i % itemsPerRow; var x = startX + col * (buttonWidth + buttonSpacing); var y = startY + row * rowSpacing; // Create button-style container var menuItem = new Container(); menuItem.x = x; menuItem.y = y; game.addChild(menuItem); // Create button background var buttonBg = menuItem.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, width: buttonWidth, height: buttonHeight, tint: itemColors[i] || 0x8B4513 }); // Create centered button text var buttonText = new Text2(items[i], { size: 28, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 0; buttonText.y = 0; menuItem.addChild(buttonText); menuItem.name = items[i]; menuItem.draggable = true; menuItem.type = 'ingredient'; menuItem.isDragging = false; menuItem.originalX = x; menuItem.originalY = y; menuItem.isMenuPurchase = true; menuItem.cost = 50; // Cost to purchase from menu self.menuItems.push(menuItem); } }; self.hideMenu = function () { self.visible = false; self.isVisible = false; // Remove menu items for (var i = 0; i < self.menuItems.length; i++) { game.removeChild(self.menuItems[i]); } self.menuItems = []; }; self.showDetails = function (itemName) { if (HERB_DATA[itemName]) { herbPopup.showPopup(itemName, 0, 0); } }; // Close button handler closeButton.down = function (x, y, obj) { self.hideMenu(); }; // Overlay click to close overlay.down = function (x, y, obj) { self.hideMenu(); }; // Start hidden self.visible = false; return self; }); var PotionBottle = Container.expand(function () { var self = Container.call(this); var bottle = self.attachAsset('potionBottle', { anchorX: 0.5, anchorY: 0.5 }); self.setColor = function (base, element, herb) { var color = 0x87CEEB; if (element === 'fire') color = 0xFF6B6B;else if (element === 'water') color = 0x6BB6FF;else if (element === 'earth') color = 0x8B4513;else if (element === 'wind') color = 0xE6E6FA; bottle.tint = color; tween(bottle, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(bottle, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F4F2F }); /**** * Game Code ****/ var gameBackground = game.attachAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); // === Tap vs Drag state === var downItemCandidate = null; var downStartX = 0, downStartY = 0; var DRAG_THRESHOLD = 22; // px movement to start dragging // helper: rectangular hit test function hitRect(x, y, cx, cy, halfW, halfH) { return Math.abs(x - cx) <= halfW && Math.abs(y - cy) <= halfH; } function createDragGhostFromMenu(name, color, cost, startX, startY) { var ghost = new Container(); ghost.x = startX; ghost.y = startY; game.addChild(ghost); var bg = ghost.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, tint: color, width: 220, height: 100 }); var txt = new Text2(name, { size: 44, fill: 0xFFFFFF }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; ghost.addChild(txt); ghost.name = name; ghost.isDragging = true; ghost.isMenuPurchase = true; ghost.cost = cost; ghost.dragOffsetX = 0; ghost.dragOffsetY = 0; // subtle pop so it feels grabbed tween(ghost, { scaleX: 1.08, scaleY: 1.08 }, { duration: 120 }); return ghost; } var goldAmount = 500; var currentScore = 0; var currentPatient = null; var isProcessingTreatment = false; // Menu buttons are already implemented at the top of the screen: // - Instructions button (blue) at x=400, y=100 // - New Game button (red) at x=1024, y=100 // - Shop button (green) at x=1648, y=100 // All buttons have proper styling, text labels, and event handlers // HUD / TOP BAR LAYER var goldText = new Text2('Gold: ' + goldAmount, { size: 60, fill: 0xFFD700 }); goldText.anchor.set(0, 0); goldText.x = 120; goldText.y = 50; LK.gui.topLeft.addChild(goldText); var scoreText = new Text2('Score: ' + currentScore, { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); var patientStatusText = new Text2('Welcome! A patient awaits...', { size: 50, fill: 0xFFFFFF }); patientStatusText.anchor.set(0.5, 1); LK.gui.bottom.addChild(patientStatusText); // CENTER LAYER - Patient + Cauldron + Dialogue var patient = game.addChild(new Patient()); patient.x = 1024; patient.y = 500; // Create symptom indicator positioned near patient var symptomIndicator = game.attachAsset('symptomIndicator', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 500 }); // Link symptom indicator to patient patient.symptomGlow = symptomIndicator; // Potion Bottle positioned near cauldron var potionBottle = game.addChild(new PotionBottle()); potionBottle.x = 1024; potionBottle.y = 950; potionBottle.visible = false; // Start hidden // BOTTOM LAYER - Ingredient Buttons + Craft Button // Craft Button positioned at the bottom of the screen var craftButton = game.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2500, width: 300, height: 80 }); var craftButtonText = new Text2('CRAFT POTION', { size: 32, fill: 0xFFFFFF }); craftButtonText.anchor.set(0.5, 0.5); craftButtonText.x = 1024; craftButtonText.y = 2500; game.addChild(craftButtonText); // Wheel labels and selection display removed var symptoms = ['redrose', 'bluemist', 'emeraldveil']; var patientTimer = 0; var treatmentTimer = 0; function spawnNewPatient() { if (currentPatient) return; var randomSymptom = symptoms[Math.floor(Math.random() * symptoms.length)]; patient.setSymptom(randomSymptom); currentPatient = randomSymptom; patientStatusText.setText('A new patient has arrived!'); tween(patient, { scaleX: 1.1, scaleY: 1.1 }, { duration: 500, onFinish: function onFinish() { tween(patient, { scaleX: 1, scaleY: 1 }, { duration: 500 }); } }); } // updateSelectionDisplay function removed function craftPotion() { if (!currentPatient || isProcessingTreatment || cauldron.ingredients.length !== 3) return; isProcessingTreatment = true; var base = cauldron.ingredients[0]; var element = cauldron.ingredients[1]; var herb = cauldron.ingredients[2]; var goldEarned = patient.reactToPotion(base, element, herb); goldAmount += goldEarned; currentScore += Math.max(0, goldEarned); // Update UI and reset cauldron goldText.setText('Gold: ' + goldAmount); scoreText.setText('Score: ' + currentScore); cauldron.ingredients = []; updateCauldronDisplay(); if (goldEarned > 0) { if (goldEarned >= 100) { patientStatusText.setText('Perfect cure! +' + goldEarned + ' gold'); } else { patientStatusText.setText('Partial success! +' + goldEarned + ' gold'); } } else { patientStatusText.setText('Treatment failed! ' + goldEarned + ' gold'); } treatmentTimer = LK.ticks + 120; // 2 seconds } craftButton.down = function (x, y, obj) { craftPotion(); }; var heldItem = null; var dragGhost = null; game.down = function (x, y, obj) { // If popup visible, prefer its items if (popupMenu.isVisible) { downItemCandidate = null; for (var i = popupMenu.menuItems.length - 1; i >= 0; i--) { var it = popupMenu.menuItems[i]; // rectangular hit for reliability var hw = (it.hitW || 120) / 2; var hh = (it.hitH || 120) / 2; if (hitRect(x, y, it.x, it.y, hw, hh)) { downItemCandidate = it; break; } } downStartX = x; downStartY = y; return; // wait to see if this becomes a tap or a drag } // Regular inventory items (unchanged) for (var i = inventoryItems.length - 1; i >= 0; i--) { var item = inventoryItems[i]; var dx = x - item.x, dy = y - item.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 50) { heldItem = item; item.isDragging = true; item.dragOffsetX = x - item.x; item.dragOffsetY = y - item.y; break; } } }; game.move = function (x, y, obj) { // If we have a candidate from popup and movement crosses threshold, start drag with a visible ghost if (downItemCandidate && !heldItem) { var moved = Math.sqrt((x - downStartX) * (x - downStartX) + (y - downStartY) * (y - downStartY)); if (moved > DRAG_THRESHOLD) { // check funds before allowing drag if (goldAmount >= downItemCandidate.cost) { var tint = downItemCandidate.children[0] ? downItemCandidate.children[0].tint : 0x1565C0; heldItem = dragGhost = createDragGhostFromMenu(downItemCandidate.name, tint, downItemCandidate.cost, x, y); heldItem.dragOffsetX = 0; heldItem.dragOffsetY = 0; } else { patientStatusText.setText('Not enough gold! Need ' + downItemCandidate.cost + ' gold.'); downItemCandidate = null; } } } // Move the active drag item (ghost or regular) if (heldItem && heldItem.isDragging) { heldItem.x = x - (heldItem.dragOffsetX || 0); heldItem.y = y - (heldItem.dragOffsetY || 0); } }; function createDragGhost(item) { if (dragGhost) { game.removeChild(dragGhost); } dragGhost = new Container(); dragGhost.x = item.x; dragGhost.y = item.y; game.addChild(dragGhost); // Ghost background with transparency var ghostBg = dragGhost.attachAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, width: 150, height: 150, alpha: 0.7, tint: 0x444444 }); // Ghost text var ghostText = new Text2(item.name, { size: 28, fill: 0xFFFFFF }); ghostText.anchor.set(0.5, 0.5); ghostText.x = 0; ghostText.y = 0; dragGhost.addChild(ghostText); } function removeDragGhost() { if (dragGhost) { game.removeChild(dragGhost); dragGhost = null; } } game.up = function (x, y, obj) { // TAP on popup item -> show details (no drag started) if (downItemCandidate && !heldItem) { if (HERB_DATA[downItemCandidate.name]) { herbPopup.showPopup(downItemCandidate.name, x, y); } downItemCandidate = null; return; } downItemCandidate = null; // DROP logic (ghost from menu or regular inventory) if (heldItem) { heldItem.isDragging = false; // Calculate distance to cauldron var dx = heldItem.x - cauldron.x; var dy = heldItem.y - cauldron.y; var distance = Math.sqrt(dx * dx + dy * dy); // Menu purchase ghost dropped on cauldron if (heldItem.isMenuPurchase) { if (distance < 200 && cauldron.ingredients.length < 3) { goldAmount -= heldItem.cost; goldText.setText('Gold: ' + goldAmount); cauldron.ingredients.push(heldItem.name); updateCauldronDisplay(); tween(cauldron, { tint: 0x44FF44 }, { duration: 200, onFinish: function onFinish() { tween(cauldron, { tint: 0xFFFFFF }, { duration: 200 }); } }); // remove ghost, keep popup open for multiple adds game.removeChild(heldItem); } else { // Not dropped in valid area -> cancel purchase, remove ghost game.removeChild(heldItem); } heldItem = null; dragGhost = null; return; } // Regular inventory item drop (unchanged) if (distance < 200 && cauldron.ingredients.length < 3) { cauldron.ingredients.push(heldItem.name); updateCauldronDisplay(); tween(cauldron, { tint: 0x44FF44 }, { duration: 200, onFinish: function onFinish() { tween(cauldron, { tint: 0xFFFFFF }, { duration: 200 }); } }); var itemIndex = inventoryItems.indexOf(heldItem); if (itemIndex > -1) { game.removeChild(heldItem); inventoryItems.splice(itemIndex, 1); } } else { tween(cauldron, { tint: 0xFF4444 }, { duration: 200, onFinish: function onFinish() { tween(cauldron, { tint: 0xFFFFFF }, { duration: 200 }); } }); resetItem(heldItem); } heldItem = null; } }; game.update = function () { patientTimer++; // Spawn new patient every 8 seconds if none exists if (!currentPatient && patientTimer % 480 === 0) { spawnNewPatient(); } // Clear patient after treatment if (isProcessingTreatment && LK.ticks >= treatmentTimer) { isProcessingTreatment = false; currentPatient = null; patientStatusText.setText('Next patient incoming...'); patientTimer = 0; } // Selection display update removed // Check for game over condition (bankruptcy) if (goldAmount < -100) { LK.showGameOver(); } // Check for win condition (high score) if (currentScore >= 2000) { LK.showYouWin(); } }; // Create draggable inventory items function createInventoryItem(name, x, y, color, isMenuItem) { var container = new Container(); container.x = x; container.y = y; game.addChild(container); // Use big rounded rectangles for menu items; bottles for inventory var assetType = isMenuItem ? 'craftButton' : 'potionBottle'; var item = container.attachAsset(assetType, { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, tint: color }); if (isMenuItem) { item.width = 220; item.height = 100; } else { // inventory representation can stay as-is } var label = new Text2(name, { size: isMenuItem ? 44 : 24, // bigger menu text fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); label.x = 0; label.y = 0; container.addChild(label); // attach metadata (if this is a herb, we have more info) container.name = name; container.meta = HERB_DATA[name] || null; container.draggable = true; container.type = 'ingredient'; container.isDragging = false; container.originalX = x; container.originalY = y; // for rectangular hit test container.hitW = isMenuItem ? item.width : 120; container.hitH = isMenuItem ? item.height : 120; return container; } // Inventory labels removed - ingredients now accessed through category buttons var inventoryItems = []; var baseItems = ['infusion', 'broth', 'tonic']; var elementItems = ['fire', 'water', 'earth', 'wind']; /**** * Herb Data & Helpers ****/ var HERB_DATA = { "Sheep Bane": { type: "Plant", alignment: "Earth", description: "A nourishing plant with small white flowers found in lush meadows with plenty of sunshine." }, "Fuzzy Peeper": { type: "Plant", alignment: "Wind", description: "A pale puffball perched on a long stem; it turns gently to face any breeze, no matter how faint." }, "Sommeral": { type: "Plant", alignment: "Fire", description: "A spiny red blossom that thrives in sun-scorched fields; its petals crackle faintly when crushed." }, "Common Snupe": { type: "Plant", alignment: "Earth", description: "A squat, stubby herb with ridged leaves and a sharp nutty scent—grows best near compost heaps and pig pens." }, "Geneva's Dewdrop": { type: "Plant", alignment: "Water", description: "Delicate blue bulbs that drip a perpetual cool dew; said to be first planted by a weeping maiden." }, "Brindleroot": { type: "Plant", alignment: "Fire", description: "A twisted root that glows faintly from within—often brewed to stoke warmth into cold limbs." }, "Frogwick": { type: "Plant", alignment: "Water", description: "Rubbery, semi-aquatic herb found near marshes—tastes awful but soothes the throat like magic." }, "Demeter's Arrow": { type: "Plant", alignment: "Wind", description: "Thin silvery leaves that grow in spirals. When burned, they produce a vapor that clears the lungs and bowels." }, "River Leek": { type: "Plant", alignment: "Water", description: "A long, fragrant stalk that grows in riverside soil; its boiled leaves soothe fevers and dampen restlessness." }, "Pipeweed": { type: "Plant", alignment: "Wind", description: "Fragrant and slightly numbing, this herb is often smoked by hill witches and daydreaming farmhands." }, "Kitty Mitten": { type: "Plant", alignment: "Fire", description: "Soft red-orange fuzz covers these leaves, which are pleasantly warm to the touch. Cats love to nap on them." }, "Malicious Bule": { type: "Fungus", alignment: "Wind", description: "A pale fungus with twisting gills and a sweet, spoiled smell. It's said to whisper when the wind passes through a grove." }, "False Dunny Cap": { type: "Fungus", alignment: "Earth", description: "Often mistaken for its edible cousin, this fungus has a thick gray stalk and a damp cellar scent. Caution advised." }, "Callum's Perch": { type: "Fungus", alignment: "Earth", description: "Named for the druid who first brewed it into a sleep tonic, this squat, mossy mushroom grows on dead stumps in shadow." }, "Pinwort": { type: "Fungus", alignment: "Water", description: "Soft and glossy with lilac-speckled caps, these fungi flourish in damp caves and give off a faint minty aroma." }, "Devil's Lantern": { type: "Fungus", alignment: "Fire", description: "This bioluminescent red fungus pulses with warmth. It grows in deep caverns and is rumored to attract fire spirits." }, "Lady's Teacup": { type: "Fungus", alignment: "Water", description: "Shaped like a delicate bowl, often found filled with morning dew. Some fae insist it must only be harvested under moonlight." }, "Dead Man's Toe": { type: "Fungus", alignment: "Earth", description: "Black and bulbous, it pushes up from graveyard soil and smells of rust. Disturbing in appearance, yet grounding when dried." }, "Agarium": { type: "Fungus", alignment: "Earth", description: "Smooth and tan, with a satisfying snap when broken. This dependable fungus is a staple in many earthy decoctions." }, "Thimbliss": { type: "Fungus", alignment: "Wind", description: "Tiny, translucent caps that grow in clusters beneath bird nests. Harmless alone, but intensify the effects of other herbs." }, "Lesser Bluecap": { type: "Fungus", alignment: "Water", description: "Short and stubby with a dusty blue top, this unassuming mushroom has mild cooling properties and is common in boggy woods." } }; // ordered list for the Herbs popup var herbItems = Object.keys(HERB_DATA); function colorForAlignment(align) { if (align === "Fire") return 0xFF6B6B; if (align === "Water") return 0x6BB6FF; if (align === "Earth") return 0x8B8F6B; if (align === "Wind") return 0xBEE3F8; return 0xADFF2F; } function wrapTextByWords(str, maxLen) { var words = str.split(' '); var lines = []; var current = ''; for (var i = 0; i < words.length; i++) { var tryLine = current.length ? current + ' ' + words[i] : words[i]; if (tryLine.length > maxLen) { if (current.length) lines.push(current); current = words[i]; } else { current = tryLine; } } if (current.length) lines.push(current); return lines.join('\n'); } // Keep backward compatibility with old herbs object var herbs = {}; for (var herbName in HERB_DATA) { if (HERB_DATA.hasOwnProperty(herbName)) { herbs[herbName] = { element: HERB_DATA[herbName].alignment, type: HERB_DATA[herbName].type, description: HERB_DATA[herbName].description }; } } // Behind counter graphic in bottom layer (depth 1) var behindCounter = game.attachAsset('behind_Counter', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1700, width: 2048, height: 600 }); // Wooden counter in bottom layer (depth 2, above behind counter) var counter = game.attachAsset('counterTop', { anchorX: 0.5, anchorY: 1, x: 1024, y: 1750 }); // Cauldron in center layer (depth 3, positioned lower on counter) var cauldron = game.attachAsset('cauldronZone', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1520 }); cauldron.ingredients = []; // Cauldron ingredients display var cauldronLabel = new Text2('Cauldron: Empty', { size: 35, fill: 0xFFFFFF }); cauldronLabel.anchor.set(0.5, 0.5); cauldronLabel.x = 1024; cauldronLabel.y = 750; game.addChild(cauldronLabel); function updateCauldronDisplay() { if (cauldron.ingredients.length === 0) { cauldronLabel.setText('Cauldron: Empty'); } else { cauldronLabel.setText('Added: ' + cauldron.ingredients.join(', ')); } // Show/hide potion bottle based on ingredient count if (cauldron.ingredients.length === 3) { potionBottle.visible = true; } else { potionBottle.visible = false; } } function resetItem(item) { tween(item, { x: item.originalX, y: item.originalY }, { duration: 300 }); } // Inventory items are now only created through menu purchases // No default items in main play area // Ingredient category buttons in bottom layer - positioned below counter // Larger buttons with better spacing, centered horizontally var buttonWidth = 350; var buttonHeight = 120; var buttonSpacing = 80; var totalWidth = buttonWidth * 3 + buttonSpacing * 2; var startX = (2048 - totalWidth) / 2 + buttonWidth / 2; var basesButton = game.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: startX, y: 1900, width: buttonWidth, height: buttonHeight, tint: 0xDAA520 }); var basesButtonText = new Text2('BASES', { size: 48, fill: 0xFFFFFF }); basesButtonText.anchor.set(0.5, 0.5); basesButtonText.x = startX; basesButtonText.y = 1900; game.addChild(basesButtonText); var elementsButton = game.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: startX + buttonWidth + buttonSpacing, y: 1900, width: buttonWidth, height: buttonHeight, tint: 0x20B2AA }); var elementsButtonText = new Text2('ELEMENTS', { size: 48, fill: 0xFFFFFF }); elementsButtonText.anchor.set(0.5, 0.5); elementsButtonText.x = startX + buttonWidth + buttonSpacing; elementsButtonText.y = 1900; game.addChild(elementsButtonText); var herbsButton = game.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: startX + (buttonWidth + buttonSpacing) * 2, y: 1900, width: buttonWidth, height: buttonHeight, tint: 0xADFF2F }); var herbsButtonText = new Text2('HERBS', { size: 48, fill: 0xFFFFFF }); herbsButtonText.anchor.set(0.5, 0.5); herbsButtonText.x = startX + (buttonWidth + buttonSpacing) * 2; herbsButtonText.y = 1900; game.addChild(herbsButtonText); // Menu buttons in HUD layer (repositioned to avoid top-left 100x100 area) var instructionsButton = game.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 450, y: 80, width: 180, height: 60, tint: 0x4169E1 }); var instructionsButtonText = new Text2('GUIDE', { size: 24, fill: 0xFFFFFF }); instructionsButtonText.anchor.set(0.5, 0.5); instructionsButtonText.x = 450; instructionsButtonText.y = 80; game.addChild(instructionsButtonText); var resetButton = game.attachAsset('craftButton', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 80, width: 180, height: 60, tint: 0xFF6347 }); var resetButtonText = new Text2('RESET', { size: 24, fill: 0xFFFFFF }); resetButtonText.anchor.set(0.5, 0.5); resetButtonText.x = 1024; resetButtonText.y = 80; game.addChild(resetButtonText); // Shop button removed per requirements // Create popup menu var popupMenu = game.addChild(new PopupMenu()); // Create herb details popup var herbPopup = game.addChild(new HerbPopup()); // Category button event handlers basesButton.down = function (x, y, obj) { var baseColors = []; for (var i = 0; i < baseItems.length; i++) { baseColors.push(0xDAA520); } popupMenu.showMenu('BASES - 50 Gold Each', baseItems, baseColors); }; elementsButton.down = function (x, y, obj) { var elementColors = []; for (var i = 0; i < elementItems.length; i++) { elementColors.push(0x20B2AA); } popupMenu.showMenu('ELEMENTS - 50 Gold Each', elementItems, elementColors); }; herbsButton.down = function (x, y, obj) { var herbColors = []; for (var i = 0; i < herbItems.length; i++) { herbColors.push(0xADFF2F); } popupMenu.showMenu('HERBS - 50 Gold Each', herbItems, herbColors); }; // Button event handlers instructionsButton.down = function (x, y, obj) { var allItems = baseItems.concat(elementItems).concat(herbItems); var allColors = []; // Base colors for (var i = 0; i < baseItems.length; i++) { allColors.push(0xDAA520); } // Element colors for (var i = 0; i < elementItems.length; i++) { allColors.push(0x20B2AA); } // Herb colors for (var i = 0; i < herbItems.length; i++) { allColors.push(0xADFF2F); } popupMenu.showMenu('INGREDIENT GUIDE', allItems, allColors); }; resetButton.down = function (x, y, obj) { goldAmount = 500; currentScore = 0; goldText.setText('Gold: ' + goldAmount); scoreText.setText('Score: ' + currentScore); patientStatusText.setText('Game Reset! Welcome to the Alchemy Shop!'); }; // Shop button event handler removed per requirements // Initialize first patient spawnNewPatient();
===================================================================
--- original.js
+++ change.js
@@ -921,21 +921,30 @@
description: HERB_DATA[herbName].description
};
}
}
-// Wooden counter in bottom layer
+// Behind counter graphic in bottom layer (depth 1)
+var behindCounter = game.attachAsset('behind_Counter', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1700,
+ width: 2048,
+ height: 600
+});
+// Wooden counter in bottom layer (depth 2, above behind counter)
var counter = game.attachAsset('counterTop', {
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 1750
});
-// Cauldron in center layer
+// Cauldron in center layer (depth 3, positioned lower on counter)
var cauldron = game.attachAsset('cauldronZone', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
- y: 850
+ y: 1520
});
cauldron.ingredients = [];
// Cauldron ingredients display
var cauldronLabel = new Text2('Cauldron: Empty', {
@@ -1020,9 +1029,9 @@
tint: 0xADFF2F
});
var herbsButtonText = new Text2('HERBS', {
size: 48,
- fill: 0x000000
+ fill: 0xFFFFFF
});
herbsButtonText.anchor.set(0.5, 0.5);
herbsButtonText.x = startX + (buttonWidth + buttonSpacing) * 2;
herbsButtonText.y = 1900;
@@ -1061,25 +1070,9 @@
resetButtonText.anchor.set(0.5, 0.5);
resetButtonText.x = 1024;
resetButtonText.y = 80;
game.addChild(resetButtonText);
-var shopButton = game.attachAsset('craftButton', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: 1598,
- y: 80,
- width: 180,
- height: 60,
- tint: 0x32CD32
-});
-var shopButtonText = new Text2('SHOP', {
- size: 24,
- fill: 0xFFFFFF
-});
-shopButtonText.anchor.set(0.5, 0.5);
-shopButtonText.x = 1598;
-shopButtonText.y = 80;
-game.addChild(shopButtonText);
+// Shop button removed per requirements
// Create popup menu
var popupMenu = game.addChild(new PopupMenu());
// Create herb details popup
var herbPopup = game.addChild(new HerbPopup());
@@ -1129,11 +1122,7 @@
goldText.setText('Gold: ' + goldAmount);
scoreText.setText('Score: ' + currentScore);
patientStatusText.setText('Game Reset! Welcome to the Alchemy Shop!');
};
-shopButton.down = function (x, y, obj) {
- var shopItems = ['infusion', 'broth', 'fire', 'water', 'Geneva\'s Dewdrop', 'Sommeral', 'Common Snupe', 'Brindleroot'];
- var shopColors = [0xDAA520, 0xDAA520, 0x20B2AA, 0x20B2AA, 0xADFF2F, 0xADFF2F, 0xADFF2F, 0xADFF2F];
- popupMenu.showMenu('SHOP - 50 Gold Each', shopItems, shopColors);
-};
+// Shop button event handler removed per requirements
// Initialize first patient
spawnNewPatient();
\ No newline at end of file