User prompt
Şu sorunu artık çözelim: alabileceğimiz ürün sayısı maks a geldiğinde food kategorisindeki tüm ürünlerin çerçevesi ve buy tuşu gri oluyo ya. Ama ürün alırken kapasite dolduğunda çerçeve direkt olarak gri olurken buy tuşu olmuyor.
User prompt
Yemeklerin buy tuşuna bastığımızda ve ürün sayısı maxta ise shoptan otomatik olarak çıkarıyodu ya. Artık shoptan çıkarmasın.
User prompt
Birde artık food kategorisindeki yiyecekleri almaya çalıştığımızda ama ürün sayısı makta ise shoptan atmasın
User prompt
Ürünlere tıkladığımızda "Scanned" geri bildirimi gelmesin
User prompt
Saat 00.00 olduğunda buton otomatik close olsun ve günü bitirene kadar open yapılamasın. Günü bitirmek için doğan ve dükkandan çıkan mğşteri sayısının eşit olması lazım
User prompt
Game over ekranı geldiğinde günümüz sıfırlansın, paramız sıfırlansın. Kısaca yaptığımız herşey, aldığımız herşey gitsin ve 1. Günden başlayalım
User prompt
End day butonunun üstüne bir buton daha ekle. Ona basınca oyunu kaybedelim
User prompt
Şimdi bir günü 4 dakika yap. Yeni bir sistem yapıcaz. Artık saatler okucak ve güne daat 12 de başlıcaz. Akşam 00.00 da işimiz biticek
User prompt
Timer bar ile ilgili her şeyi kaldır.
User prompt
Yüksekliğini azıcık azalt
User prompt
Timer bar fill areanın yüksekliğini frame'nin yüksekliği ile aynı yap
User prompt
Timer bar fill area biraz daha sağdan başlasın
Code edit (1 edits merged)
Please save this source code
User prompt
Timer bar frame i 300x75 yap
User prompt
Birde süreyi 5dk dan 30 saniyeye indirebilir misin. Test için
User prompt
Ya da 60 olsun
User prompt
Timer bar fill areanın yüksekliğini 80 yap
User prompt
Timer bar fill areanın yüksekliğini 130 yapar mısın
User prompt
Timer bar frami 300x130 yapabilir misin
User prompt
Şimdi bu barı içindeki dolu kısmı ve dış kısmı olucak şekilde 2 farklı image oluşturur musun
User prompt
Ya da süreyi 5 dk yap
User prompt
Şimdi oyuna çok büyük bir değişiklik eklemek istiyorum. Artık bir gün marketteki tüm ürünler bitince ve markette hiç kimse kalmayınca yeni güne geçmiycez. Öncelikle ekranın sağ üstüne uzun bir bar ekle. Artık bir gün 2 dakika olucak. Zaman ilerledikçe o bar ilerliycek. Ve 2 dakikaya ulaşınca yeni gğne geçicez.
User prompt
Birde shoptayken shoptan çıkma butonunu da image yapar mısın.
User prompt
Scanner hazır. Şimdi scanner fiyatını geri 25bin TL yapar mısın
User prompt
Ürünleri scannerladığımızda geri bildirim gelmesin
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Customer = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('customer', { anchorX: 0.5, anchorY: 1 }); self.items = []; self.currentItemIndex = 0; self.isBeingServed = false; self.patience = 100; self.maxPatience = 100; self.waitTime = 0; self.isShopping = true; self.targetShelf = null; self.itemsToCollect = Math.floor(Math.random() * 3) + 2; self.upset = false; self.angry = false; self.upsetStartTime = 0; self.paid = false; self.placeItemsOnCounter = function () { var startY = counterY + 50 - self.items.length * 70 / 2; for (var i = 0; i < self.items.length; i++) { var item = self.items[i]; // Don't add item directly, it's already part of customer // Instead, create a new product with the same properties var counterItem = new Product(item.productType); counterItem.value = item.value; counterItem.name = item.name; counterItem.productType = item.productType; counterItem.x = 900; // Move to the left from center counterItem.y = startY + i * 70; // Place items vertically game.addChild(counterItem); // If automatic scanner is owned, make items slide down to scanner if (hasAutomaticScanner) { counterItem.scanned = false; // Start unscanned counterItem.isMoving = true; // Flag to track movement counterItem.targetY = counterY + 200; // Scanner base position counterItem.startY = counterItem.y; // Store starting position counterItem.scanDelay = 0; // All items move together for bread queue counterItem.moveStartTime = LK.ticks; // Track when movement should start counterItem.isPaused = false; // Track if movement is paused } else { // Manual scanning - items don't move counterItem.scanned = false; } // Replace the item in the array with the counter version self.items[i] = counterItem; } // Move scanner to front after placing items to ensure it appears above them if (hasAutomaticScanner && scannerBase && scannerBase.parent) { scannerBase.parent.addChild(scannerBase); // Re-add to parent to bring to front } }; self.allItemsScanned = function () { for (var i = 0; i < self.items.length; i++) { if (!self.items[i].scanned) { return false; } } return true; }; self.getTotalValue = function () { var total = 0; for (var i = 0; i < self.items.length; i++) { total += self.items[i].value; } return total; }; self.completeTransaction = function () { // Mark customer as paid self.paid = true; // If customer was upset, stop shaking animation if (self.upset) { tween.stop(self, { x: true }); self.x = self.originalX; } // Remove items from counter for (var i = 0; i < self.items.length; i++) { if (self.items[i].parent) { self.items[i].destroy(); } } // Add to money var earnings = self.getTotalValue(); money += earnings; dailyEarnings += earnings; scoreTxt.setText(money + '₺'); // Show feedback showFeedback('+' + earnings + '₺', 0x00ff00); // Play sound LK.getSound('cashRegister').play(); // Move customer out tween(self, { x: -200 }, { duration: 1000, onFinish: function onFinish() { totalCustomersExited++; // Increment exit counter self.destroy(); } }); }; self.collectItemFromShelf = function () { if (self.items.length < self.itemsToCollect && self.targetShelf) { var takenProduct = self.targetShelf.takeProduct(); if (takenProduct) { // Store the product data directly without creating a visual product yet self.items.push({ productType: takenProduct.productType, value: takenProduct.value, name: takenProduct.name, scanned: false }); // Visual feedback tween(graphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(graphics, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); // Play sound when customer takes item LK.getSound('customerPurchase').play(); } } }; self.update = function () { // Track wait time for customers being served if (self.isBeingServed && !self.upset && !self.angry && !self.paid) { self.waitTime++; // Check if customer should become upset (10 seconds = 600 frames at 60fps) if (self.waitTime >= 600) { self.upset = true; self.upsetStartTime = 0; // Change color to indicate upset state (slightly darker) graphics.tint = 0x888888; // Show feedback showFeedback('Customer is upset!', 0xffff00); // Start shaking animation self.originalX = self.x; self.shakeAnimation = function () { if (self.upset && !self.angry && !self.paid) { tween(self, { x: self.originalX + (Math.random() - 0.5) * 20 }, { duration: 100, onFinish: function onFinish() { if (self.upset && !self.angry && !self.paid) { self.shakeAnimation(); } } }); } }; self.shakeAnimation(); } } // Track upset time and transition to angry (only if not paid) if (self.upset && !self.angry && !self.paid) { self.upsetStartTime++; // Check if customer should become angry (5 seconds = 300 frames at 60fps) if (self.upsetStartTime >= 300) { self.angry = true; // Show feedback showFeedback('Customer left angry!', 0xff0000); // Stop shaking animation tween.stop(self, { x: true }); self.x = self.originalX; // Change color to red when angry graphics.tint = 0xFF0000; // Remove items from counter when angry customer leaves for (var i = 0; i < self.items.length; i++) { if (self.items[i].parent) { self.items[i].destroy(); } } // Make angry customer leave the store tween(self, { x: -200 }, { duration: 1000, onFinish: function onFinish() { totalCustomersExited++; // Increment exit counter self.destroy(); } }); } } }; return self; }); var Feedback = Container.expand(function (message, color) { var self = Container.call(this); // Create feedback text var feedbackTxt = new Text2(message, { size: 80, fill: 0xff0000 }); feedbackTxt.anchor.set(0.5, 0.5); self.addChild(feedbackTxt); // Start animation self.show = function () { // Start from much higher position self.x = 1024; self.y = 2200; self.alpha = 1; // Animate upward to slightly past center and fade out tween(self, { y: 1200, alpha: 0 }, { duration: 3000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var Product = Container.expand(function (productType) { var self = Container.call(this); // Define product types with their properties var productTypes = [{ asset: 'apple', name: 'Apple', value: 20 }, { asset: 'banana', name: 'Banana', value: 40 }, { asset: 'orange', name: 'Orange', value: 30 }, { asset: 'milk', name: 'Milk', value: 50 }, { asset: 'bread', name: 'Bread', value: 10 }, { asset: 'cheese', name: 'Cheese', value: 30 }]; // Use specified product type or randomly select one var selectedType; if (productType) { // Find the product type that matches the specified type for (var i = 0; i < productTypes.length; i++) { if (productTypes[i].asset === productType) { selectedType = productTypes[i]; break; } } } if (!selectedType) { // Fallback to random selection if no type specified or not found selectedType = productTypes[Math.floor(Math.random() * productTypes.length)]; } var graphics = self.attachAsset(selectedType.asset, { anchorX: 0.5, anchorY: 0.5 }); self.scanned = false; self.value = selectedType.value; self.name = selectedType.name; self.productType = selectedType.asset; // Visual feedback for scanned items self.scan = function () { if (!self.scanned) { self.scanned = true; graphics.alpha = 0.5; // Make transparent when scanned LK.getSound('itemScan').play(); // Show feedback showFeedback('Item scanned!', 0x00ff00); } }; self.down = function (x, y, obj) { if (!shopOpen) { self.scan(); } }; return self; }); var Shelf = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('shelf', { anchorX: 0.5, anchorY: 0.5 }); self.products = []; // Create products on shelf self.createProducts = function () { var rows = 3; var cols = 3; var spacing = 100; var startX = -120; var startY = -120; // Define product types for this shelf var productTypes = [{ asset: 'apple', name: 'Apple', value: 20 }, { asset: 'banana', name: 'Banana', value: 40 }, { asset: 'orange', name: 'Orange', value: 30 }, { asset: 'milk', name: 'Milk', value: 50 }, { asset: 'bread', name: 'Bread', value: 10 }, { asset: 'cheese', name: 'Cheese', value: 30 }]; // Each shelf will have products organized by type in rows var shelfProductTypes = []; var numTypes = Math.min(rows, productTypes.length); // One type per row, max 3 types for (var t = 0; t < numTypes; t++) { var randomType = productTypes[Math.floor(Math.random() * productTypes.length)]; // Make sure we don't duplicate types on same shelf var alreadyExists = false; for (var e = 0; e < shelfProductTypes.length; e++) { if (shelfProductTypes[e].asset === randomType.asset) { alreadyExists = true; break; } } if (!alreadyExists) { shelfProductTypes.push(randomType); } else { t--; // Try again with different type } } for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { // Each row has the same product type var selectedType = shelfProductTypes[row % shelfProductTypes.length]; var product = self.attachAsset(selectedType.asset, { anchorX: 0.5, anchorY: 0.5 }); product.x = startX + col * spacing; product.y = startY + row * (spacing + 20); // Add extra 20px spacing between rows product.available = true; product.productType = selectedType.asset; product.name = selectedType.name; product.value = selectedType.value; self.products.push(product); } } }; // Only create products on Day 1 if (currentDay === 1) { self.createProducts(); } self.takeProduct = function () { for (var i = 0; i < self.products.length; i++) { if (self.products[i].available) { var product = self.products[i]; product.available = false; product.visible = false; return { value: product.value, name: product.name, productType: product.productType }; } } return null; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xfffca1 }); /**** * Game Code ****/ var customers = []; var customerQueue = []; var currentCustomer = null; var spawnTimer = 0; var spawnDelay = Math.floor(Math.random() * (540 - 360 + 1)) + 360; // Random between 6-9 seconds (360-540 frames at 60fps) var counterY = 2300; // Bottom of screen // Load money based on whether we're continuing the same day or starting fresh var money = storage.lastPlayedDay === currentDay ? storage.money : storage.dayStartMoney || 0; var totalCustomersSpawned = 0; // Track total customers spawned var totalCustomersExited = 0; // Track total customers who left the store var currentDay = storage.currentDay || 1; // Current day number var dailyEarnings = 0; // Money earned today var dayStartMoney = storage.dayStartMoney || 0; // Money at the start of the current day var gameOverPaused = false; // Track if game is paused for day summary var storeOpen = false; // Track if store is open or closed - start closed var shopOpen = false; // Track if shop overlay is open var dayJustStarted = true; // Track if day just started to prevent immediate day end var hasAutomaticScanner = storage.hasAutomaticScanner || false; // Track if automatic scanner is purchased // No changes needed - the code already ensures only the customer being served gets angry var shelves = []; // Load shelves from storage or use default positions var totalShelves = storage.totalShelves || 4; var defaultShelfPositions = [{ x: 400, y: 1000 }, { x: 1600, y: 1000 }, { x: 400, y: 1600 }, { x: 1600, y: 1600 }]; for (var i = 0; i < totalShelves; i++) { var shelf = new Shelf(); // Load from storage if available, otherwise use default positions if (storage['shelf' + i + 'X'] !== undefined && storage['shelf' + i + 'Y'] !== undefined) { shelf.x = storage['shelf' + i + 'X']; shelf.y = storage['shelf' + i + 'Y']; } else if (i < defaultShelfPositions.length) { shelf.x = defaultShelfPositions[i].x; shelf.y = defaultShelfPositions[i].y; // Save default positions to storage for future use storage['shelf' + i + 'X'] = shelf.x; storage['shelf' + i + 'Y'] = shelf.y; } else { // New shelf without default position, place at center shelf.x = 1024; shelf.y = 1366; } shelves.push(shelf); game.addChild(shelf); } // Create cash register at bottom center var cashRegister = game.addChild(LK.getAsset('cashRegister', { anchorX: 0.5, anchorY: 0.5 })); cashRegister.x = 1024; // Center of screen cashRegister.y = counterY; // Bottom position // Create scanner base for automatic scanner var scannerBase = null; if (hasAutomaticScanner) { scannerBase = game.addChild(LK.getAsset('scanner', { anchorX: 0.5, anchorY: 0.5 })); scannerBase.x = 900; // Align with where items are placed scannerBase.y = counterY + 200; // Below counter } // Create open/close button below cash register - start with Close image var openCloseBtn = game.addChild(LK.getAsset('Close', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; // Position further below cash register openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; // Handle open/close button click openCloseBtn.down = function () { if (!gameOverPaused && !shopOpen) { // Check if trying to open the store if (!storeOpen && areAllShelvesEmpty()) { // Don't allow opening if no products showFeedback('No products to sell!', 0xff0000); return; } storeOpen = !storeOpen; if (storeOpen) { // Replace with Open image openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Open', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; openCloseBtn.down = arguments.callee; // Re-assign click handler } else { // Replace with Close image openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Close', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; openCloseBtn.down = arguments.callee; // Re-assign click handler } } }; // Create queue line var queueLine = game.addChild(LK.getAsset('queueLine', { anchorX: 0.5, anchorY: 0.5 })); queueLine.x = 1024; // Center of screen queueLine.y = counterY - 300; // Position above cash register // Create black rectangle first (so it appears behind) var blackRect = LK.getAsset('blackRectangle', { anchorX: 0.5, anchorY: 0 }); blackRect.y = 135; // Position behind the money text LK.gui.top.addChild(blackRect); // Create day counter display in top left var dayTxt = new Text2('Day ' + currentDay, { size: 50, fill: 0x000000 }); dayTxt.anchor.set(0, 0); dayTxt.x = 150; // Position to avoid menu icon area LK.gui.topLeft.addChild(dayTxt); // Save initial money for day 1 if not already saved if (!storage.dayStartMoney) { storage.dayStartMoney = money; storage.lastPlayedDay = currentDay; } // Create money display (added after, so it appears on top) var scoreTxt = new Text2('₺' + money, { size: 60, fill: 0x006400 }); scoreTxt.anchor.set(0.5, 0); scoreTxt.y = 150; // Move money display lower LK.gui.top.addChild(scoreTxt); // Create instructions var instructionsTxt = new Text2('Tap items to scan them!', { size: 40, fill: 0x0000 }); instructionsTxt.anchor.set(0.5, 0); instructionsTxt.y = 80; LK.gui.top.addChild(instructionsTxt); // Create customer counter displays in top right var spawnedCounterTxt = new Text2('Spawned: 0', { size: 40, fill: 0x000000 }); spawnedCounterTxt.anchor.set(1, 0); LK.gui.topRight.addChild(spawnedCounterTxt); var exitedCounterTxt = new Text2('Exited: 0', { size: 40, fill: 0x000000 }); exitedCounterTxt.anchor.set(1, 0); exitedCounterTxt.y = 50; LK.gui.topRight.addChild(exitedCounterTxt); function spawnCustomer() { var customer = new Customer(); customer.x = 1024; // Center of screen customer.y = -200; // Above screen customers.push(customer); game.addChild(customer); totalCustomersSpawned++; // Increment customer counter // Customer shopping sequence var shelfIndex = 0; var _visitShelf = function visitShelf() { if (shelfIndex < shelves.length && customer.items.length < customer.itemsToCollect) { // Find shelves with available products var availableShelves = []; for (var s = 0; s < shelves.length; s++) { var shelf = shelves[s]; var hasAvailableProducts = false; for (var p = 0; p < shelf.products.length; p++) { if (shelf.products[p].available) { hasAvailableProducts = true; break; } } if (hasAvailableProducts) { availableShelves.push(shelf); } } // If no shelves have products, customer leaves without shopping if (availableShelves.length === 0) { // Done shopping (forced), join queue with current items customer.isShopping = false; customerQueue.push(customer); var queuePosition = queueLine.x + customerQueue.length * 200; tween(customer, { x: queuePosition, y: queueLine.y }, { duration: 1500 }); return; } // Select random shelf from available ones var targetShelf = availableShelves[Math.floor(Math.random() * availableShelves.length)]; tween(customer, { x: targetShelf.x, y: targetShelf.y + 250 }, { duration: 1500, onFinish: function onFinish() { customer.targetShelf = targetShelf; customer.collectItemFromShelf(); shelfIndex++; LK.setTimeout(function () { if (customer.items.length < customer.itemsToCollect) { _visitShelf(); } else { // Done shopping, join queue customer.isShopping = false; customerQueue.push(customer); var queuePosition = queueLine.x + customerQueue.length * 200; tween(customer, { x: queuePosition, y: queueLine.y }, { duration: 1500 }); } }, 500); } }); } }; // Start shopping by entering store tween(customer, { y: 400 }, { duration: 1000, onFinish: function onFinish() { _visitShelf(); } }); } function areAllShelvesEmpty() { for (var i = 0; i < shelves.length; i++) { var shelf = shelves[i]; for (var j = 0; j < shelf.products.length; j++) { if (shelf.products[j].available) { return false; } } } return true; } function canAcceptMoreProducts(productType) { // First check if we've reached maximum capacity var currentProducts = 0; for (var s = 0; s < shelves.length; s++) { var shelf = shelves[s]; for (var p = 0; p < shelf.products.length; p++) { if (shelf.products[p] && shelf.products[p].available) { currentProducts++; } } } if (currentProducts >= maxProducts) { return false; } // Check if any shelf has empty space for this product type for (var s = 0; s < shelves.length; s++) { var shelf = shelves[s]; // Check each row for empty space for (var row = 0; row < 3; row++) { var rowEmpty = true; // Check if this row is empty for (var col = 0; col < 3; col++) { var index = row * 3 + col; if (shelf.products[index] && shelf.products[index].available) { rowEmpty = false; break; } } // If row is empty, we can accept more products if (rowEmpty) { return true; } } } return false; } function showDaySummary() { gameOverPaused = true; // Set store to closed to prevent customer spawning storeOpen = false; // Make all remaining customers exit the store for (var i = customers.length - 1; i >= 0; i--) { var customer = customers[i]; if (customer.parent) { // Stop any ongoing tweens tween.stop(customer, { x: true, y: true }); // Make customer exit tween(customer, { x: -200 }, { duration: 1000, onFinish: function onFinish() { totalCustomersExited++; customer.destroy(); } }); } } // Clear customer arrays and current customer customers = []; customerQueue = []; currentCustomer = null; // Update open/close button to show Close openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Close', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; // Re-assign click handler openCloseBtn.down = function () { if (!gameOverPaused && !shopOpen) { // Check if trying to open the store if (!storeOpen && areAllShelvesEmpty()) { // Don't allow opening if no products return; } storeOpen = !storeOpen; if (storeOpen) { // Replace with Open image openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Open', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; openCloseBtn.down = arguments.callee; // Re-assign click handler } else { // Replace with Close image openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Close', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; openCloseBtn.down = arguments.callee; // Re-assign click handler } } }; // Create dark overlay var overlay = game.addChild(LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 })); overlay.x = 1024; overlay.y = 1366; overlay.alpha = 0; overlay.tint = 0x000000; // Create summary text var summaryTxt = new Text2('Day ' + currentDay + ' Complete!\n\nCustomers Served: ' + totalCustomersExited, { size: 60, fill: 0xffffff }); summaryTxt.anchor.set(0.5, 0.5); summaryTxt.x = 1024; summaryTxt.y = 1200; summaryTxt.alpha = 0; game.addChild(summaryTxt); // Create earnings display - centered and green var earningsTxt = new Text2(dailyEarnings + '₺', { size: 120, fill: 0x00ff00 }); earningsTxt.anchor.set(0.5, 0.5); earningsTxt.x = 1024; earningsTxt.y = 1700; earningsTxt.alpha = 0; game.addChild(earningsTxt); // Create continue button var continueBtn = game.addChild(LK.getAsset('continueButton', { anchorX: 0.5, anchorY: 0.5 })); continueBtn.x = 1024; continueBtn.y = 2400; continueBtn.alpha = 0; // Fade in animation tween(overlay, { alpha: 0.8 }, { duration: 1000 }); tween(summaryTxt, { alpha: 1 }, { duration: 1000 }); tween(earningsTxt, { alpha: 1 }, { duration: 1000 }); tween(continueBtn, { alpha: 1 }, { duration: 1000 }); // Handle continue button click continueBtn.down = function () { // Fade out animation tween(overlay, { alpha: 0 }, { duration: 1000 }); tween(summaryTxt, { alpha: 0 }, { duration: 1000 }); tween(earningsTxt, { alpha: 0 }, { duration: 1000 }); tween(continueBtn, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { // Remove summary elements after fade out overlay.destroy(); summaryTxt.destroy(); earningsTxt.destroy(); continueBtn.destroy(); gameOverPaused = false; startNextDay(); } }); }; } function startNextDay() { // Reset day variables currentDay++; dailyEarnings = 0; totalCustomersSpawned = 0; totalCustomersExited = 0; spawnTimer = 0; spawnDelay = Math.floor(Math.random() * (540 - 360 + 1)) + 360; // Random between 6-9 seconds // Save all game data to storage when starting next day storage.currentDay = currentDay; storage.dayStartMoney = money; // Save money at start of new day storage.lastPlayedDay = currentDay; // Track which day we're on storage.money = money; // Save shelf positions and count storage.totalShelves = shelves.length; for (var i = 0; i < shelves.length; i++) { storage['shelf' + i + 'X'] = shelves[i].x; storage['shelf' + i + 'Y'] = shelves[i].y; } // Save max products capacity storage.maxProducts = maxProducts; // Update day display dayTxt.setText('Day ' + currentDay); // Don't restock shelves automatically - players must buy from shop // Clear any remaining customers for (var i = customers.length - 1; i >= 0; i--) { customers[i].destroy(); } customers = []; customerQueue = []; currentCustomer = null; // Start spawning customers again dayJustStarted = true; // Set flag to prevent immediate day end // Don't spawn customer immediately, let the spawn timer handle it LK.setTimeout(function () { dayJustStarted = false; // Allow day to end after spawn delay passes }, spawnDelay * 16.67); //{79} // Convert frames to milliseconds (60fps = ~16.67ms per frame) } function showFeedback(message, color) { var feedback = new Feedback(message, color); game.addChild(feedback); feedback.show(); } function serveNextCustomer() { if (customerQueue.length > 0 && !currentCustomer) { currentCustomer = customerQueue.shift(); currentCustomer.isBeingServed = true; // Move customer to cash register tween(currentCustomer, { x: 896, y: queueLine.y }, { duration: 1500, onFinish: function onFinish() { if (currentCustomer && currentCustomer.parent) { currentCustomer.placeItemsOnCounter(); } } }); // Move other customers forward in queue - only move existing queue members for (var i = 0; i < customerQueue.length; i++) { var queuePos = queueLine.x + (i + 1) * 200; tween(customerQueue[i], { x: queuePos, y: queueLine.y }, { duration: 1000 }); } } } // Handle dragging shelf during placement mode game.move = function (x, y, obj) { if (shelfPlacementMode && draggingShelf) { draggingShelf.x = x; draggingShelf.y = y; } }; game.update = function () { // Don't update game logic during day summary or shelf placement if (gameOverPaused || shelfPlacementMode) { return; } // Hide/show instruction text based on shop state instructionsTxt.visible = !shopOpen; // Move money elements to top when shop is open if (shopOpen) { blackRect.y = 10; scoreTxt.y = 25; } else { blackRect.y = 135; scoreTxt.y = 150; } // Check if all shelves are empty and handle customers accordingly if (areAllShelvesEmpty()) { // Automatically close the store when no products available if (storeOpen) { storeOpen = false; // Update button to show Close image openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Close', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; // Re-assign click handler openCloseBtn.down = function () { if (!gameOverPaused && !shopOpen) { // Check if trying to open the store if (!storeOpen && areAllShelvesEmpty()) { // Don't allow opening if no products return; } storeOpen = !storeOpen; if (storeOpen) { // Replace with Open image openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Open', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; openCloseBtn.down = arguments.callee; // Re-assign click handler } else { // Replace with Close image openCloseBtn.destroy(); openCloseBtn = game.addChild(LK.getAsset('Close', { anchorX: 0.5, anchorY: 0.5 })); openCloseBtn.x = 1024; openCloseBtn.y = counterY + 300; openCloseBtn.scaleX = 2; openCloseBtn.scaleY = 2; openCloseBtn.down = arguments.callee; // Re-assign click handler } } }; } // Make customers who are still shopping leave without products for (var i = customers.length - 1; i >= 0; i--) { var customer = customers[i]; if (customer.isShopping && customer.items.length === 0) { // Customer leaves empty-handed tween(customer, { x: -200 }, { duration: 1000, onFinish: function onFinish() { totalCustomersExited++; customer.destroy(); } }); customers.splice(i, 1); } } // Don't spawn new customers when shelves are empty or store is closed } else if (storeOpen) { spawnTimer++; // Spawn new customers if (spawnTimer >= spawnDelay) { spawnCustomer(); spawnTimer = 0; // Set new random spawn delay between 6-9 seconds spawnDelay = Math.floor(Math.random() * (540 - 360 + 1)) + 360; } } // Check if current customer transaction is complete if (currentCustomer && currentCustomer.isBeingServed) { // Handle automatic scanner item movement if (hasAutomaticScanner && currentCustomer.items) { // Move all items together like a bread queue for (var itemIdx = 0; itemIdx < currentCustomer.items.length; itemIdx++) { var item = currentCustomer.items[itemIdx]; // Skip if already scanned if (item.scanned) { continue; } // Check if any item ahead is currently being scanned (paused) var canMove = true; for (var checkIdx = 0; checkIdx < itemIdx; checkIdx++) { var checkItem = currentCustomer.items[checkIdx]; if (checkItem.isPaused) { canMove = false; break; } } // Only move if no items ahead are paused if (!canMove) { continue; } // Check if item is about to touch scanner if (!item.isPaused && item.y + 2 >= item.targetY) { // Item reached scanner, pause this item only item.isPaused = true; item.scanned = true; // Find the graphics child and make it transparent for (var g = 0; g < item.children.length; g++) { if (item.children[g].alpha !== undefined) { item.children[g].alpha = 0.5; break; } } LK.getSound('itemScan').play(); // showFeedback('Item scanned!', 0x00ff00);//{9V} - Removed feedback per request // Resume movement after a short delay LK.setTimeout(function (currentItem) { return function () { currentItem.isPaused = false; }; }(item), 500); } else if (!item.isPaused && item.y < item.targetY) { // Move item down slowly item.y += 2; // Move 2 pixels per frame } } } // Shaking effect is now handled by tween animations instead of direct position manipulation // Only check for scanned items if customer hasn't left if (currentCustomer.parent && currentCustomer.allItemsScanned()) { currentCustomer.completeTransaction(); // Remove from customers array for (var i = customers.length - 1; i >= 0; i--) { if (customers[i] === currentCustomer) { customers.splice(i, 1); break; } } currentCustomer = null; // Serve next customer after a short delay LK.setTimeout(function () { serveNextCustomer(); }, 500); } // Check if customer left angry if (currentCustomer && !currentCustomer.parent) { // Remove from customers array for (var i = customers.length - 1; i >= 0; i--) { if (customers[i] === currentCustomer) { customers.splice(i, 1); break; } } currentCustomer = null; // Serve next customer after a short delay LK.setTimeout(function () { serveNextCustomer(); }, 500); } } // Serve next customer if none is being served if (!currentCustomer) { serveNextCustomer(); } // Update customer counter displays spawnedCounterTxt.setText('Spawned: ' + totalCustomersSpawned); exitedCounterTxt.setText('Exited: ' + totalCustomersExited); // Update buy button colors in real-time if shop is open and showing products category if (shopOpen && currentShopCategory === 'products') { var productItems = [{ name: 'Apple', price: 48 }, { name: 'Banana', price: 96 }, { name: 'Orange', price: 72 }, { name: 'Milk', price: 120 }, { name: 'Bread', price: 24 }, { name: 'Cheese', price: 72 }]; // Update all buy button colors based on current capacity for (var b = 0; b < productItems.length; b++) { var checkItem = productItems[b]; var checkProductType = null; if (checkItem.name === 'Apple') { checkProductType = 'apple'; } else if (checkItem.name === 'Banana') { checkProductType = 'banana'; } else if (checkItem.name === 'Orange') { checkProductType = 'orange'; } else if (checkItem.name === 'Milk') { checkProductType = 'milk'; } else if (checkItem.name === 'Bread') { checkProductType = 'bread'; } else if (checkItem.name === 'Cheese') { checkProductType = 'cheese'; } var canBuyItem = money >= checkItem.price && canAcceptMoreProducts(checkProductType); // Find the corresponding buy button (it's the last item added for each product) var buyButtonIndex = (b + 1) * 5 - 1; // Buy button is 5th item for each product (bg, name, desc, price, buy) if (shopItems[buyButtonIndex]) { // Only gray out if insufficient funds or can't accept more products if (!canBuyItem) { shopItems[buyButtonIndex].tint = 0x888888; // Gray out button // Also gray out the corresponding item background (it's the first item for each product) var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy) if (shopItems[itemBgIndex]) { shopItems[itemBgIndex].tint = 0x888888; // Gray out item background } } else { // Make sure buy button color is updated immediately shopItems[buyButtonIndex].tint = 0xffffff; // Normal color // Also restore normal color for item background var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy) if (shopItems[itemBgIndex]) { shopItems[itemBgIndex].tint = 0xffffff; // Normal color for item background } } } } } // Day end condition - when all shelves are empty and all customers have left (and at least 1 customer visited) if (areAllShelvesEmpty() && totalCustomersSpawned === totalCustomersExited && totalCustomersExited > 0 && !gameOverPaused && !dayJustStarted) { showDaySummary(); } // Game over condition - too many customers waiting if (customerQueue.length >= 5) { LK.showGameOver(); } }; // Create end day button in bottom right var endDayBtn = game.addChild(LK.getAsset('blackRectangle', { anchorX: 0.5, anchorY: 0.5 })); endDayBtn.x = 1748; endDayBtn.y = 2600; endDayBtn.width = 300; endDayBtn.height = 150; endDayBtn.tint = 0x444444; var endDayTxt = new Text2('End Day', { size: 40, fill: 0xffffff }); endDayTxt.anchor.set(0.5, 0.5); endDayTxt.x = 1748; endDayTxt.y = 2600; game.addChild(endDayTxt); // Handle end day button click endDayBtn.down = function () { if (!gameOverPaused && !shopOpen) { showDaySummary(); } }; // Create shop button in bottom left var shopBtn = game.addChild(LK.getAsset('shopButton', { anchorX: 0.5, anchorY: 0.5 })); shopBtn.x = 300; shopBtn.y = 2600; // Shop overlay variables var shopOverlay = null; var shopItems = []; var currentShopCategory = 'products'; // Shelf placement mode variables var shelfPlacementMode = false; var draggingShelf = null; var placementButton = null; var maxProducts = storage.maxProducts || defaultShelfPositions.length * 9; // Load from storage or calculate based on shelf count // Handle shop button click // Shop overlay variables var currentShopCategory = 'products'; shopBtn.down = function () { if (!gameOverPaused && !shopOverlay) { // Check if store is open if (storeOpen) { showFeedback('Close the store first!', 0xff0000); return; } // Check if there are customers in the store if (totalCustomersExited !== totalCustomersSpawned) { showFeedback('Wait for customers to leave!', 0xff0000); return; } shopOpen = true; // Function to clear current category items var clearCategoryItems = function clearCategoryItems() { // Remove category-specific items (keep overlay, title, category buttons, and close button) for (var i = shopItems.length - 1; i >= 0; i--) { if (shopItems[i].isCategoryItem) { shopItems[i].destroy(); shopItems.splice(i, 1); } } }; // Function to show products category var showProducts = function showProducts() { currentShopCategory = 'products'; clearCategoryItems(); var productItems = [{ name: 'Apple', price: 48, description: 'Restocks apple shelf' }, { name: 'Banana', price: 96, description: 'Restocks banana shelf' }, { name: 'Orange', price: 72, description: 'Restocks orange shelf' }, { name: 'Milk', price: 120, description: 'Restocks milk shelf' }, { name: 'Bread', price: 24, description: 'Restocks bread shelf' }, { name: 'Cheese', price: 72, description: 'Restocks cheese shelf' }]; // Create product cards for (var i = 0; i < productItems.length; i++) { var item = productItems[i]; var xPos = 1024 - 600 + i % 3 * 600; // Center horizontally: 1024 is center, -600 to offset for 3 items var yPos = 700 + Math.floor(i / 3) * 500; // Item background var itemBg = game.addChild(LK.getAsset('shopItem', { anchorX: 0.5, anchorY: 0.5 })); itemBg.x = xPos; itemBg.y = yPos; itemBg.width = 400; itemBg.height = 450; itemBg.isCategoryItem = true; shopItems.push(itemBg); // Item name var itemName = new Text2(item.name, { size: 32, fill: 0xffffff }); itemName.anchor.set(0.5, 0.5); itemName.x = xPos; itemName.y = yPos - 100; itemName.isCategoryItem = true; game.addChild(itemName); shopItems.push(itemName); // Item description var itemDesc = new Text2(item.description, { size: 22, fill: 0xffffff }); itemDesc.anchor.set(0.5, 0.5); itemDesc.x = xPos; itemDesc.y = yPos - 50; itemDesc.isCategoryItem = true; game.addChild(itemDesc); shopItems.push(itemDesc); // Item price var itemPrice = new Text2(item.price + '₺', { size: 40, fill: 0x90ee90 }); itemPrice.anchor.set(0.5, 0.5); itemPrice.x = xPos; itemPrice.y = yPos; itemPrice.isCategoryItem = true; game.addChild(itemPrice); shopItems.push(itemPrice); // Buy button var buyBtn = game.addChild(LK.getAsset('buyButton', { anchorX: 0.5, anchorY: 0.5 })); buyBtn.x = xPos; buyBtn.y = yPos + 100; buyBtn.width = 250; buyBtn.height = 125; buyBtn.itemData = item; buyBtn.isCategoryItem = true; shopItems.push(buyBtn); // Check if all shelves are full (all product slots are occupied with available products) var allShelvesFull = true; for (var s = 0; s < shelves.length; s++) { var shelf = shelves[s]; for (var p = 0; p < shelf.products.length; p++) { if (!shelf.products[p] || !shelf.products[p].available) { allShelvesFull = false; break; } } if (!allShelvesFull) break; } // Check if shelves can accept more products of this type var productType = null; if (item.name === 'Apple') { productType = 'apple'; } else if (item.name === 'Banana') { productType = 'banana'; } else if (item.name === 'Orange') { productType = 'orange'; } else if (item.name === 'Milk') { productType = 'milk'; } else if (item.name === 'Bread') { productType = 'bread'; } else if (item.name === 'Cheese') { productType = 'cheese'; } var canBuy = money >= item.price && canAcceptMoreProducts(productType); // Only gray out if insufficient funds or can't accept more products if (!canBuy) { buyBtn.tint = 0x888888; // Gray out button itemBg.tint = 0x888888; // Gray out item background too } else { buyBtn.tint = 0xffffff; // Normal color itemBg.tint = 0xffffff; // Normal color for item background } // Buy button handler buyBtn.down = function () { // Check if we can buy (enough money and shelf space) var productType = null; if (this.itemData.name === 'Apple') { productType = 'apple'; } else if (this.itemData.name === 'Banana') { productType = 'banana'; } else if (this.itemData.name === 'Orange') { productType = 'orange'; } else if (this.itemData.name === 'Milk') { productType = 'milk'; } else if (this.itemData.name === 'Bread') { productType = 'bread'; } else if (this.itemData.name === 'Cheese') { productType = 'cheese'; } if (money >= this.itemData.price && canAcceptMoreProducts(productType)) { money -= this.itemData.price; scoreTxt.setText(money + '₺'); // Flash green to show purchase LK.effects.flashObject(this, 0x00ff00, 500); // Show feedback showFeedback('Purchased ' + this.itemData.name + '!', 0x00ff00); // Restock the appropriate shelf based on product type var productType = null; if (this.itemData.name === 'Apple') { productType = 'apple'; } else if (this.itemData.name === 'Banana') { productType = 'banana'; } else if (this.itemData.name === 'Orange') { productType = 'orange'; } else if (this.itemData.name === 'Milk') { productType = 'milk'; } else if (this.itemData.name === 'Bread') { productType = 'bread'; } else if (this.itemData.name === 'Cheese') { productType = 'cheese'; } if (productType) { // Find a shelf that needs this product type and restock it var restocked = false; for (var s = 0; s < shelves.length; s++) { var shelf = shelves[s]; // Check each row for empty space for (var row = 0; row < 3; row++) { var rowEmpty = true; // Check if this row is empty for (var col = 0; col < 3; col++) { var index = row * 3 + col; if (shelf.products[index] && shelf.products[index].available) { rowEmpty = false; break; } } // If row is empty, fill it with the product if (rowEmpty) { var cols = 3; var spacing = 100; var startX = -120; var startY = -120; for (var col = 0; col < cols; col++) { var index = row * 3 + col; // If product slot exists but is not available, make it visible and available if (shelf.products[index]) { shelf.products[index].destroy(); } var product = shelf.attachAsset(productType, { anchorX: 0.5, anchorY: 0.5 }); product.x = startX + col * spacing; product.y = startY + row * (spacing + 20); product.available = true; product.productType = productType; product.name = this.itemData.name; // Get product name product.value = Math.floor(this.itemData.price / 3 / 0.8); // Set value based on purchase price for 3 items with 20% profit margin shelf.products[index] = product; } restocked = true; break; } } if (restocked) { break; } } // If no empty row found in any shelf, notify player if (!restocked) { // Could add a notification here that all shelves are full } } // After restocking, check if shelves are now full of this product type if (!canAcceptMoreProducts(productType)) { // Remove all shop elements shopOverlay.destroy(); shopOverlay = null; for (var j = 0; j < shopItems.length; j++) { shopItems[j].destroy(); } shopItems = []; shopOpen = false; } // Force immediate update of all buy button colors for (var updateIdx = 0; updateIdx < productItems.length; updateIdx++) { var updateItem = productItems[updateIdx]; var updateProductType = null; if (updateItem.name === 'Apple') { updateProductType = 'apple'; } else if (updateItem.name === 'Banana') { updateProductType = 'banana'; } else if (updateItem.name === 'Orange') { updateProductType = 'orange'; } else if (updateItem.name === 'Milk') { updateProductType = 'milk'; } else if (updateItem.name === 'Bread') { updateProductType = 'bread'; } else if (updateItem.name === 'Cheese') { updateProductType = 'cheese'; } var canBuyUpdate = money >= updateItem.price && canAcceptMoreProducts(updateProductType); // Find the corresponding buy button var updateBuyButtonIndex = (updateIdx + 1) * 5 - 1; if (shopItems[updateBuyButtonIndex]) { if (!canBuyUpdate) { shopItems[updateBuyButtonIndex].tint = 0x888888; // Also gray out the item background var updateItemBgIndex = updateIdx * 5; if (shopItems[updateItemBgIndex]) { shopItems[updateItemBgIndex].tint = 0x888888; } } else { shopItems[updateBuyButtonIndex].tint = 0xffffff; // Also restore item background color var updateItemBgIndex = updateIdx * 5; if (shopItems[updateItemBgIndex]) { shopItems[updateItemBgIndex].tint = 0xffffff; } } } } } else { // Provide feedback for why purchase failed if (money < this.itemData.price) { showFeedback('Not enough money!', 0xff0000); LK.effects.flashObject(this, 0xff0000, 500); } else if (!canAcceptMoreProducts(productType)) { showFeedback('No shelf space available!', 0xff0000); LK.effects.flashObject(this, 0xff0000, 500); } } }; // Update all buy button colors based on current capacity for (var b = 0; b < productItems.length; b++) { var checkItem = productItems[b]; var checkProductType = null; if (checkItem.name === 'Apple') { checkProductType = 'apple'; } else if (checkItem.name === 'Banana') { checkProductType = 'banana'; } else if (checkItem.name === 'Orange') { checkProductType = 'orange'; } else if (checkItem.name === 'Milk') { checkProductType = 'milk'; } else if (checkItem.name === 'Bread') { checkProductType = 'bread'; } else if (checkItem.name === 'Cheese') { checkProductType = 'cheese'; } var canBuyItem = money >= checkItem.price && canAcceptMoreProducts(checkProductType); // Find the corresponding buy button (it's the last item added for each product) var buyButtonIndex = (b + 1) * 5 - 1; // Buy button is 5th item for each product (bg, name, desc, price, buy) if (shopItems[buyButtonIndex]) { // Only gray out if insufficient funds or can't accept more products if (!canBuyItem) { shopItems[buyButtonIndex].tint = 0x888888; // Gray out button // Also gray out the corresponding item background (it's the first item for each product) var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy) if (shopItems[itemBgIndex]) { shopItems[itemBgIndex].tint = 0x888888; // Gray out item background } } else { shopItems[buyButtonIndex].tint = 0xffffff; // Normal color // Also restore normal color for item background var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy) if (shopItems[itemBgIndex]) { shopItems[itemBgIndex].tint = 0xffffff; // Normal color for item background } } } } } }; // Function to show equipment category var showEquipment = function showEquipment() { currentShopCategory = 'equipment'; clearCategoryItems(); var equipmentItems = [{ name: 'Extra Shelf', price: 5000, description: 'Add more shelf space' }, { name: 'Refrigerator', price: 800, description: 'Keep dairy products fresh' }, { name: 'Automatic Scanner', price: 0, description: 'Automatically scan all items' }, { name: 'Security Camera', price: 400, description: 'Reduce theft' }]; // Create equipment cards for (var i = 0; i < equipmentItems.length; i++) { var item = equipmentItems[i]; // Apply progressive pricing for Extra Shelf if (item.name === 'Extra Shelf') { var shelfCount = shelves.length; if (shelfCount === 4) { item.price = 5000; } else if (shelfCount === 5) { item.price = 8000; } else if (shelfCount === 6) { item.price = 10000; } else if (shelfCount === 7) { item.price = 15000; } else if (shelfCount >= 8) { item.price = 20000; } } var xPos = 424 + i % 2 * 600; var yPos = 700 + Math.floor(i / 2) * 500; // Item background var itemBg = game.addChild(LK.getAsset('shopItem', { anchorX: 0.5, anchorY: 0.5 })); itemBg.x = xPos; itemBg.y = yPos; itemBg.width = 400; itemBg.height = 450; itemBg.isCategoryItem = true; shopItems.push(itemBg); // Item name var itemName = new Text2(item.name, { size: 36, fill: 0xffffff }); itemName.anchor.set(0.5, 0.5); itemName.x = xPos; itemName.y = yPos - 100; itemName.isCategoryItem = true; game.addChild(itemName); shopItems.push(itemName); // Item description var itemDesc = new Text2(item.description, { size: 24, fill: 0xffffff }); itemDesc.anchor.set(0.5, 0.5); itemDesc.x = xPos; itemDesc.y = yPos - 50; itemDesc.isCategoryItem = true; game.addChild(itemDesc); shopItems.push(itemDesc); // Item price var itemPrice = new Text2(item.price + '₺', { size: 50, fill: 0x90ee90 }); itemPrice.anchor.set(0.5, 0.5); itemPrice.x = xPos; itemPrice.y = yPos; itemPrice.isCategoryItem = true; game.addChild(itemPrice); shopItems.push(itemPrice); // Buy button var buyBtn = game.addChild(LK.getAsset('buyButton', { anchorX: 0.5, anchorY: 0.5 })); buyBtn.x = xPos; buyBtn.y = yPos + 100; buyBtn.width = 250; buyBtn.height = 125; buyBtn.itemData = item; buyBtn.isCategoryItem = true; shopItems.push(buyBtn); // Check if this is Extra Shelf and we already have 8 shelves var canBuy = money >= item.price; if (item.name === 'Extra Shelf' && shelves.length >= 8) { canBuy = false; } // Check if Automatic Scanner is already purchased if (item.name === 'Automatic Scanner' && hasAutomaticScanner) { canBuy = false; } if (!canBuy) { buyBtn.tint = 0x888888; // Gray out button itemBg.tint = 0x888888; // Gray out item background too } else { buyBtn.tint = 0xffffff; // Normal color itemBg.tint = 0xffffff; // Normal color for item background } // Buy button handler buyBtn.down = function () { if (money >= this.itemData.price) { // Check if trying to buy Extra Shelf and already have 8 shelves if (this.itemData.name === 'Extra Shelf' && shelves.length >= 8) { // Don't allow purchase - flash red instead showFeedback('Maximum shelves reached!', 0xff0000); LK.effects.flashObject(this, 0xff0000, 500); return; } money -= this.itemData.price; scoreTxt.setText(money + '₺'); // Flash green to show purchase LK.effects.flashObject(this, 0x00ff00, 500); // Special handling for Automatic Scanner if (this.itemData.name === 'Automatic Scanner') { // Set global flag for automatic scanning hasAutomaticScanner = true; storage.hasAutomaticScanner = true; // Create scanner base immediately if (!scannerBase) { scannerBase = game.addChild(LK.getAsset('scanner', { anchorX: 0.5, anchorY: 0.5 })); scannerBase.x = 900; // Align with where items are placed scannerBase.y = counterY + 200; // Below counter } // Disable the buy button after purchase this.tint = 0x888888; // Gray out button this.down = function () {}; // Remove click handler } // Special handling for Extra Shelf if (this.itemData.name === 'Extra Shelf') { // Close shop and enter shelf placement mode shopOverlay.destroy(); shopOverlay = null; for (var j = 0; j < shopItems.length; j++) { shopItems[j].destroy(); } shopItems = []; shopOpen = false; shelfPlacementMode = true; maxProducts += 9; // Increase max product capacity // Create draggable transparent shelf draggingShelf = game.addChild(LK.getAsset('shelf', { anchorX: 0.5, anchorY: 0.5 })); draggingShelf.x = 1024; draggingShelf.y = 1366; draggingShelf.alpha = 0.5; // Create green placement button placementButton = game.addChild(LK.getAsset('openCloseButton', { anchorX: 0.5, anchorY: 0.5 })); placementButton.x = 1024; placementButton.y = 2500; placementButton.tint = 0x00ff00; placementButton.scaleX = 2; placementButton.scaleY = 2; // Add placement button text var placementText = new Text2('Place Shelf', { size: 30, fill: 0x000000 }); placementText.anchor.set(0.5, 0.5); placementText.x = 1024; placementText.y = 2500; game.addChild(placementText); // Placement button handler placementButton.down = function () { if (shelfPlacementMode && draggingShelf) { // Extract the new shelf position as literal values var newShelfX = Math.floor(draggingShelf.x); var newShelfY = Math.floor(draggingShelf.y); // Create the new shelf var newShelf = new Shelf(); newShelf.x = newShelfX; newShelf.y = newShelfY; shelves.push(newShelf); game.addChild(newShelf); // Clean up placement mode draggingShelf.destroy(); draggingShelf = null; placementButton.destroy(); placementButton = null; placementText.destroy(); shelfPlacementMode = false; } }; } } else { // Not enough money showFeedback('Not enough money!', 0xff0000); LK.effects.flashObject(this, 0xff0000, 500); } }; } }; // Function to show customization category var showCustomization = function showCustomization() { currentShopCategory = 'customization'; clearCategoryItems(); var customizeItems = [{ name: 'Store Sign', price: 200, description: 'Custom store branding' }, { name: 'Floor Tiles', price: 150, description: 'Improve store appearance' }, { name: 'Lighting', price: 300, description: 'Better store lighting' }, { name: 'Music System', price: 250, description: 'Background music' }]; // Create customization cards for (var i = 0; i < customizeItems.length; i++) { var item = customizeItems[i]; var xPos = 424 + i % 2 * 600; var yPos = 700 + Math.floor(i / 2) * 500; // Item background var itemBg = game.addChild(LK.getAsset('shopItem', { anchorX: 0.5, anchorY: 0.5 })); itemBg.x = xPos; itemBg.y = yPos; itemBg.width = 400; itemBg.height = 450; itemBg.isCategoryItem = true; shopItems.push(itemBg); // Item name var itemName = new Text2(item.name, { size: 36, fill: 0xffffff }); itemName.anchor.set(0.5, 0.5); itemName.x = xPos; itemName.y = yPos - 100; itemName.isCategoryItem = true; game.addChild(itemName); shopItems.push(itemName); // Item description var itemDesc = new Text2(item.description, { size: 24, fill: 0xffffff }); itemDesc.anchor.set(0.5, 0.5); itemDesc.x = xPos; itemDesc.y = yPos - 50; itemDesc.isCategoryItem = true; game.addChild(itemDesc); shopItems.push(itemDesc); // Item price var itemPrice = new Text2(item.price + '₺', { size: 50, fill: 0x90ee90 }); itemPrice.anchor.set(0.5, 0.5); itemPrice.x = xPos; itemPrice.y = yPos; itemPrice.isCategoryItem = true; game.addChild(itemPrice); shopItems.push(itemPrice); // Buy button var buyBtn = game.addChild(LK.getAsset('buyButton', { anchorX: 0.5, anchorY: 0.5 })); buyBtn.x = xPos; buyBtn.y = yPos + 100; buyBtn.width = 250; buyBtn.height = 125; buyBtn.itemData = item; buyBtn.isCategoryItem = true; shopItems.push(buyBtn); // Buy button handler buyBtn.down = function () { if (money >= this.itemData.price) { money -= this.itemData.price; scoreTxt.setText(money + '₺'); // Flash green to show purchase LK.effects.flashObject(this, 0x00ff00, 500); showFeedback('Purchased ' + this.itemData.name + '!', 0x00ff00); } else { // Not enough money showFeedback('Not enough money!', 0xff0000); LK.effects.flashObject(this, 0xff0000, 500); } }; } }; // Category button handlers // Create white overlay shopOverlay = game.addChild(LK.getAsset('shopOverlay', { anchorX: 0.5, anchorY: 0.5 })); shopOverlay.x = 1024; shopOverlay.y = 1366; shopOverlay.alpha = 0.95; // Create shop title var shopTitle = new Text2('Market Shop', { size: 80, fill: 0x000000 }); shopTitle.anchor.set(0.5, 0.5); shopTitle.x = 1024; shopTitle.y = 300; game.addChild(shopTitle); shopItems.push(shopTitle); // Create category buttons var productsBtn = game.addChild(LK.getAsset('productsCategoryImage', { anchorX: 0.5, anchorY: 0.5 })); productsBtn.x = 400; productsBtn.y = 350; productsBtn.width = 250; productsBtn.height = 125; shopItems.push(productsBtn); var equipmentBtn = game.addChild(LK.getAsset('equipmentCategoryImage', { anchorX: 0.5, anchorY: 0.5 })); equipmentBtn.x = 1024; equipmentBtn.y = 350; equipmentBtn.width = 250; equipmentBtn.height = 125; shopItems.push(equipmentBtn); var customizeBtn = game.addChild(LK.getAsset('customizationCategoryImage', { anchorX: 0.5, anchorY: 0.5 })); customizeBtn.x = 1648; customizeBtn.y = 350; customizeBtn.width = 250; customizeBtn.height = 125; shopItems.push(customizeBtn); productsBtn.down = function () { showProducts(); }; equipmentBtn.down = function () { showEquipment(); }; customizeBtn.down = function () { showCustomization(); }; // Show default category (products) showProducts(); // Close button var closeBtn = game.addChild(LK.getAsset('blackRectangle', { anchorX: 0.5, anchorY: 0.5 })); closeBtn.x = 1024; closeBtn.y = 2400; closeBtn.width = 200; closeBtn.height = 100; shopItems.push(closeBtn); var closeText = new Text2('Close', { size: 40, fill: 0xffffff }); closeText.anchor.set(0.5, 0.5); closeText.x = 1024; closeText.y = 2400; game.addChild(closeText); shopItems.push(closeText); // Close button handler closeBtn.down = function () { // Remove all shop elements shopOverlay.destroy(); shopOverlay = null; for (var j = 0; j < shopItems.length; j++) { shopItems[j].destroy(); } shopItems = []; shopOpen = false; }; } }; // Initial customer spawn // Don't spawn customer immediately, let the spawn timer handle it LK.setTimeout(function () { dayJustStarted = false; // Allow day to end after spawn delay passes }, spawnDelay * 16.67); //{dV} // Convert frames to milliseconds (60fps = ~16.67ms per frame) // No changes required - the current implementation already makes angry customers walk out normally through the store entrance using tween animations;;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Customer = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('customer', {
anchorX: 0.5,
anchorY: 1
});
self.items = [];
self.currentItemIndex = 0;
self.isBeingServed = false;
self.patience = 100;
self.maxPatience = 100;
self.waitTime = 0;
self.isShopping = true;
self.targetShelf = null;
self.itemsToCollect = Math.floor(Math.random() * 3) + 2;
self.upset = false;
self.angry = false;
self.upsetStartTime = 0;
self.paid = false;
self.placeItemsOnCounter = function () {
var startY = counterY + 50 - self.items.length * 70 / 2;
for (var i = 0; i < self.items.length; i++) {
var item = self.items[i];
// Don't add item directly, it's already part of customer
// Instead, create a new product with the same properties
var counterItem = new Product(item.productType);
counterItem.value = item.value;
counterItem.name = item.name;
counterItem.productType = item.productType;
counterItem.x = 900; // Move to the left from center
counterItem.y = startY + i * 70; // Place items vertically
game.addChild(counterItem);
// If automatic scanner is owned, make items slide down to scanner
if (hasAutomaticScanner) {
counterItem.scanned = false; // Start unscanned
counterItem.isMoving = true; // Flag to track movement
counterItem.targetY = counterY + 200; // Scanner base position
counterItem.startY = counterItem.y; // Store starting position
counterItem.scanDelay = 0; // All items move together for bread queue
counterItem.moveStartTime = LK.ticks; // Track when movement should start
counterItem.isPaused = false; // Track if movement is paused
} else {
// Manual scanning - items don't move
counterItem.scanned = false;
}
// Replace the item in the array with the counter version
self.items[i] = counterItem;
}
// Move scanner to front after placing items to ensure it appears above them
if (hasAutomaticScanner && scannerBase && scannerBase.parent) {
scannerBase.parent.addChild(scannerBase); // Re-add to parent to bring to front
}
};
self.allItemsScanned = function () {
for (var i = 0; i < self.items.length; i++) {
if (!self.items[i].scanned) {
return false;
}
}
return true;
};
self.getTotalValue = function () {
var total = 0;
for (var i = 0; i < self.items.length; i++) {
total += self.items[i].value;
}
return total;
};
self.completeTransaction = function () {
// Mark customer as paid
self.paid = true;
// If customer was upset, stop shaking animation
if (self.upset) {
tween.stop(self, {
x: true
});
self.x = self.originalX;
}
// Remove items from counter
for (var i = 0; i < self.items.length; i++) {
if (self.items[i].parent) {
self.items[i].destroy();
}
}
// Add to money
var earnings = self.getTotalValue();
money += earnings;
dailyEarnings += earnings;
scoreTxt.setText(money + '₺');
// Show feedback
showFeedback('+' + earnings + '₺', 0x00ff00);
// Play sound
LK.getSound('cashRegister').play();
// Move customer out
tween(self, {
x: -200
}, {
duration: 1000,
onFinish: function onFinish() {
totalCustomersExited++; // Increment exit counter
self.destroy();
}
});
};
self.collectItemFromShelf = function () {
if (self.items.length < self.itemsToCollect && self.targetShelf) {
var takenProduct = self.targetShelf.takeProduct();
if (takenProduct) {
// Store the product data directly without creating a visual product yet
self.items.push({
productType: takenProduct.productType,
value: takenProduct.value,
name: takenProduct.name,
scanned: false
});
// Visual feedback
tween(graphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(graphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
// Play sound when customer takes item
LK.getSound('customerPurchase').play();
}
}
};
self.update = function () {
// Track wait time for customers being served
if (self.isBeingServed && !self.upset && !self.angry && !self.paid) {
self.waitTime++;
// Check if customer should become upset (10 seconds = 600 frames at 60fps)
if (self.waitTime >= 600) {
self.upset = true;
self.upsetStartTime = 0;
// Change color to indicate upset state (slightly darker)
graphics.tint = 0x888888;
// Show feedback
showFeedback('Customer is upset!', 0xffff00);
// Start shaking animation
self.originalX = self.x;
self.shakeAnimation = function () {
if (self.upset && !self.angry && !self.paid) {
tween(self, {
x: self.originalX + (Math.random() - 0.5) * 20
}, {
duration: 100,
onFinish: function onFinish() {
if (self.upset && !self.angry && !self.paid) {
self.shakeAnimation();
}
}
});
}
};
self.shakeAnimation();
}
}
// Track upset time and transition to angry (only if not paid)
if (self.upset && !self.angry && !self.paid) {
self.upsetStartTime++;
// Check if customer should become angry (5 seconds = 300 frames at 60fps)
if (self.upsetStartTime >= 300) {
self.angry = true;
// Show feedback
showFeedback('Customer left angry!', 0xff0000);
// Stop shaking animation
tween.stop(self, {
x: true
});
self.x = self.originalX;
// Change color to red when angry
graphics.tint = 0xFF0000;
// Remove items from counter when angry customer leaves
for (var i = 0; i < self.items.length; i++) {
if (self.items[i].parent) {
self.items[i].destroy();
}
}
// Make angry customer leave the store
tween(self, {
x: -200
}, {
duration: 1000,
onFinish: function onFinish() {
totalCustomersExited++; // Increment exit counter
self.destroy();
}
});
}
}
};
return self;
});
var Feedback = Container.expand(function (message, color) {
var self = Container.call(this);
// Create feedback text
var feedbackTxt = new Text2(message, {
size: 80,
fill: 0xff0000
});
feedbackTxt.anchor.set(0.5, 0.5);
self.addChild(feedbackTxt);
// Start animation
self.show = function () {
// Start from much higher position
self.x = 1024;
self.y = 2200;
self.alpha = 1;
// Animate upward to slightly past center and fade out
tween(self, {
y: 1200,
alpha: 0
}, {
duration: 3000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var Product = Container.expand(function (productType) {
var self = Container.call(this);
// Define product types with their properties
var productTypes = [{
asset: 'apple',
name: 'Apple',
value: 20
}, {
asset: 'banana',
name: 'Banana',
value: 40
}, {
asset: 'orange',
name: 'Orange',
value: 30
}, {
asset: 'milk',
name: 'Milk',
value: 50
}, {
asset: 'bread',
name: 'Bread',
value: 10
}, {
asset: 'cheese',
name: 'Cheese',
value: 30
}];
// Use specified product type or randomly select one
var selectedType;
if (productType) {
// Find the product type that matches the specified type
for (var i = 0; i < productTypes.length; i++) {
if (productTypes[i].asset === productType) {
selectedType = productTypes[i];
break;
}
}
}
if (!selectedType) {
// Fallback to random selection if no type specified or not found
selectedType = productTypes[Math.floor(Math.random() * productTypes.length)];
}
var graphics = self.attachAsset(selectedType.asset, {
anchorX: 0.5,
anchorY: 0.5
});
self.scanned = false;
self.value = selectedType.value;
self.name = selectedType.name;
self.productType = selectedType.asset;
// Visual feedback for scanned items
self.scan = function () {
if (!self.scanned) {
self.scanned = true;
graphics.alpha = 0.5; // Make transparent when scanned
LK.getSound('itemScan').play();
// Show feedback
showFeedback('Item scanned!', 0x00ff00);
}
};
self.down = function (x, y, obj) {
if (!shopOpen) {
self.scan();
}
};
return self;
});
var Shelf = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5
});
self.products = [];
// Create products on shelf
self.createProducts = function () {
var rows = 3;
var cols = 3;
var spacing = 100;
var startX = -120;
var startY = -120;
// Define product types for this shelf
var productTypes = [{
asset: 'apple',
name: 'Apple',
value: 20
}, {
asset: 'banana',
name: 'Banana',
value: 40
}, {
asset: 'orange',
name: 'Orange',
value: 30
}, {
asset: 'milk',
name: 'Milk',
value: 50
}, {
asset: 'bread',
name: 'Bread',
value: 10
}, {
asset: 'cheese',
name: 'Cheese',
value: 30
}];
// Each shelf will have products organized by type in rows
var shelfProductTypes = [];
var numTypes = Math.min(rows, productTypes.length); // One type per row, max 3 types
for (var t = 0; t < numTypes; t++) {
var randomType = productTypes[Math.floor(Math.random() * productTypes.length)];
// Make sure we don't duplicate types on same shelf
var alreadyExists = false;
for (var e = 0; e < shelfProductTypes.length; e++) {
if (shelfProductTypes[e].asset === randomType.asset) {
alreadyExists = true;
break;
}
}
if (!alreadyExists) {
shelfProductTypes.push(randomType);
} else {
t--; // Try again with different type
}
}
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
// Each row has the same product type
var selectedType = shelfProductTypes[row % shelfProductTypes.length];
var product = self.attachAsset(selectedType.asset, {
anchorX: 0.5,
anchorY: 0.5
});
product.x = startX + col * spacing;
product.y = startY + row * (spacing + 20); // Add extra 20px spacing between rows
product.available = true;
product.productType = selectedType.asset;
product.name = selectedType.name;
product.value = selectedType.value;
self.products.push(product);
}
}
};
// Only create products on Day 1
if (currentDay === 1) {
self.createProducts();
}
self.takeProduct = function () {
for (var i = 0; i < self.products.length; i++) {
if (self.products[i].available) {
var product = self.products[i];
product.available = false;
product.visible = false;
return {
value: product.value,
name: product.name,
productType: product.productType
};
}
}
return null;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xfffca1
});
/****
* Game Code
****/
var customers = [];
var customerQueue = [];
var currentCustomer = null;
var spawnTimer = 0;
var spawnDelay = Math.floor(Math.random() * (540 - 360 + 1)) + 360; // Random between 6-9 seconds (360-540 frames at 60fps)
var counterY = 2300; // Bottom of screen
// Load money based on whether we're continuing the same day or starting fresh
var money = storage.lastPlayedDay === currentDay ? storage.money : storage.dayStartMoney || 0;
var totalCustomersSpawned = 0; // Track total customers spawned
var totalCustomersExited = 0; // Track total customers who left the store
var currentDay = storage.currentDay || 1; // Current day number
var dailyEarnings = 0; // Money earned today
var dayStartMoney = storage.dayStartMoney || 0; // Money at the start of the current day
var gameOverPaused = false; // Track if game is paused for day summary
var storeOpen = false; // Track if store is open or closed - start closed
var shopOpen = false; // Track if shop overlay is open
var dayJustStarted = true; // Track if day just started to prevent immediate day end
var hasAutomaticScanner = storage.hasAutomaticScanner || false; // Track if automatic scanner is purchased
// No changes needed - the code already ensures only the customer being served gets angry
var shelves = [];
// Load shelves from storage or use default positions
var totalShelves = storage.totalShelves || 4;
var defaultShelfPositions = [{
x: 400,
y: 1000
}, {
x: 1600,
y: 1000
}, {
x: 400,
y: 1600
}, {
x: 1600,
y: 1600
}];
for (var i = 0; i < totalShelves; i++) {
var shelf = new Shelf();
// Load from storage if available, otherwise use default positions
if (storage['shelf' + i + 'X'] !== undefined && storage['shelf' + i + 'Y'] !== undefined) {
shelf.x = storage['shelf' + i + 'X'];
shelf.y = storage['shelf' + i + 'Y'];
} else if (i < defaultShelfPositions.length) {
shelf.x = defaultShelfPositions[i].x;
shelf.y = defaultShelfPositions[i].y;
// Save default positions to storage for future use
storage['shelf' + i + 'X'] = shelf.x;
storage['shelf' + i + 'Y'] = shelf.y;
} else {
// New shelf without default position, place at center
shelf.x = 1024;
shelf.y = 1366;
}
shelves.push(shelf);
game.addChild(shelf);
}
// Create cash register at bottom center
var cashRegister = game.addChild(LK.getAsset('cashRegister', {
anchorX: 0.5,
anchorY: 0.5
}));
cashRegister.x = 1024; // Center of screen
cashRegister.y = counterY; // Bottom position
// Create scanner base for automatic scanner
var scannerBase = null;
if (hasAutomaticScanner) {
scannerBase = game.addChild(LK.getAsset('scanner', {
anchorX: 0.5,
anchorY: 0.5
}));
scannerBase.x = 900; // Align with where items are placed
scannerBase.y = counterY + 200; // Below counter
}
// Create open/close button below cash register - start with Close image
var openCloseBtn = game.addChild(LK.getAsset('Close', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300; // Position further below cash register
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
// Handle open/close button click
openCloseBtn.down = function () {
if (!gameOverPaused && !shopOpen) {
// Check if trying to open the store
if (!storeOpen && areAllShelvesEmpty()) {
// Don't allow opening if no products
showFeedback('No products to sell!', 0xff0000);
return;
}
storeOpen = !storeOpen;
if (storeOpen) {
// Replace with Open image
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Open', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
openCloseBtn.down = arguments.callee; // Re-assign click handler
} else {
// Replace with Close image
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Close', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
openCloseBtn.down = arguments.callee; // Re-assign click handler
}
}
};
// Create queue line
var queueLine = game.addChild(LK.getAsset('queueLine', {
anchorX: 0.5,
anchorY: 0.5
}));
queueLine.x = 1024; // Center of screen
queueLine.y = counterY - 300; // Position above cash register
// Create black rectangle first (so it appears behind)
var blackRect = LK.getAsset('blackRectangle', {
anchorX: 0.5,
anchorY: 0
});
blackRect.y = 135; // Position behind the money text
LK.gui.top.addChild(blackRect);
// Create day counter display in top left
var dayTxt = new Text2('Day ' + currentDay, {
size: 50,
fill: 0x000000
});
dayTxt.anchor.set(0, 0);
dayTxt.x = 150; // Position to avoid menu icon area
LK.gui.topLeft.addChild(dayTxt);
// Save initial money for day 1 if not already saved
if (!storage.dayStartMoney) {
storage.dayStartMoney = money;
storage.lastPlayedDay = currentDay;
}
// Create money display (added after, so it appears on top)
var scoreTxt = new Text2('₺' + money, {
size: 60,
fill: 0x006400
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.y = 150; // Move money display lower
LK.gui.top.addChild(scoreTxt);
// Create instructions
var instructionsTxt = new Text2('Tap items to scan them!', {
size: 40,
fill: 0x0000
});
instructionsTxt.anchor.set(0.5, 0);
instructionsTxt.y = 80;
LK.gui.top.addChild(instructionsTxt);
// Create customer counter displays in top right
var spawnedCounterTxt = new Text2('Spawned: 0', {
size: 40,
fill: 0x000000
});
spawnedCounterTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(spawnedCounterTxt);
var exitedCounterTxt = new Text2('Exited: 0', {
size: 40,
fill: 0x000000
});
exitedCounterTxt.anchor.set(1, 0);
exitedCounterTxt.y = 50;
LK.gui.topRight.addChild(exitedCounterTxt);
function spawnCustomer() {
var customer = new Customer();
customer.x = 1024; // Center of screen
customer.y = -200; // Above screen
customers.push(customer);
game.addChild(customer);
totalCustomersSpawned++; // Increment customer counter
// Customer shopping sequence
var shelfIndex = 0;
var _visitShelf = function visitShelf() {
if (shelfIndex < shelves.length && customer.items.length < customer.itemsToCollect) {
// Find shelves with available products
var availableShelves = [];
for (var s = 0; s < shelves.length; s++) {
var shelf = shelves[s];
var hasAvailableProducts = false;
for (var p = 0; p < shelf.products.length; p++) {
if (shelf.products[p].available) {
hasAvailableProducts = true;
break;
}
}
if (hasAvailableProducts) {
availableShelves.push(shelf);
}
}
// If no shelves have products, customer leaves without shopping
if (availableShelves.length === 0) {
// Done shopping (forced), join queue with current items
customer.isShopping = false;
customerQueue.push(customer);
var queuePosition = queueLine.x + customerQueue.length * 200;
tween(customer, {
x: queuePosition,
y: queueLine.y
}, {
duration: 1500
});
return;
}
// Select random shelf from available ones
var targetShelf = availableShelves[Math.floor(Math.random() * availableShelves.length)];
tween(customer, {
x: targetShelf.x,
y: targetShelf.y + 250
}, {
duration: 1500,
onFinish: function onFinish() {
customer.targetShelf = targetShelf;
customer.collectItemFromShelf();
shelfIndex++;
LK.setTimeout(function () {
if (customer.items.length < customer.itemsToCollect) {
_visitShelf();
} else {
// Done shopping, join queue
customer.isShopping = false;
customerQueue.push(customer);
var queuePosition = queueLine.x + customerQueue.length * 200;
tween(customer, {
x: queuePosition,
y: queueLine.y
}, {
duration: 1500
});
}
}, 500);
}
});
}
};
// Start shopping by entering store
tween(customer, {
y: 400
}, {
duration: 1000,
onFinish: function onFinish() {
_visitShelf();
}
});
}
function areAllShelvesEmpty() {
for (var i = 0; i < shelves.length; i++) {
var shelf = shelves[i];
for (var j = 0; j < shelf.products.length; j++) {
if (shelf.products[j].available) {
return false;
}
}
}
return true;
}
function canAcceptMoreProducts(productType) {
// First check if we've reached maximum capacity
var currentProducts = 0;
for (var s = 0; s < shelves.length; s++) {
var shelf = shelves[s];
for (var p = 0; p < shelf.products.length; p++) {
if (shelf.products[p] && shelf.products[p].available) {
currentProducts++;
}
}
}
if (currentProducts >= maxProducts) {
return false;
}
// Check if any shelf has empty space for this product type
for (var s = 0; s < shelves.length; s++) {
var shelf = shelves[s];
// Check each row for empty space
for (var row = 0; row < 3; row++) {
var rowEmpty = true;
// Check if this row is empty
for (var col = 0; col < 3; col++) {
var index = row * 3 + col;
if (shelf.products[index] && shelf.products[index].available) {
rowEmpty = false;
break;
}
}
// If row is empty, we can accept more products
if (rowEmpty) {
return true;
}
}
}
return false;
}
function showDaySummary() {
gameOverPaused = true;
// Set store to closed to prevent customer spawning
storeOpen = false;
// Make all remaining customers exit the store
for (var i = customers.length - 1; i >= 0; i--) {
var customer = customers[i];
if (customer.parent) {
// Stop any ongoing tweens
tween.stop(customer, {
x: true,
y: true
});
// Make customer exit
tween(customer, {
x: -200
}, {
duration: 1000,
onFinish: function onFinish() {
totalCustomersExited++;
customer.destroy();
}
});
}
}
// Clear customer arrays and current customer
customers = [];
customerQueue = [];
currentCustomer = null;
// Update open/close button to show Close
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Close', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
// Re-assign click handler
openCloseBtn.down = function () {
if (!gameOverPaused && !shopOpen) {
// Check if trying to open the store
if (!storeOpen && areAllShelvesEmpty()) {
// Don't allow opening if no products
return;
}
storeOpen = !storeOpen;
if (storeOpen) {
// Replace with Open image
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Open', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
openCloseBtn.down = arguments.callee; // Re-assign click handler
} else {
// Replace with Close image
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Close', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
openCloseBtn.down = arguments.callee; // Re-assign click handler
}
}
};
// Create dark overlay
var overlay = game.addChild(LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5
}));
overlay.x = 1024;
overlay.y = 1366;
overlay.alpha = 0;
overlay.tint = 0x000000;
// Create summary text
var summaryTxt = new Text2('Day ' + currentDay + ' Complete!\n\nCustomers Served: ' + totalCustomersExited, {
size: 60,
fill: 0xffffff
});
summaryTxt.anchor.set(0.5, 0.5);
summaryTxt.x = 1024;
summaryTxt.y = 1200;
summaryTxt.alpha = 0;
game.addChild(summaryTxt);
// Create earnings display - centered and green
var earningsTxt = new Text2(dailyEarnings + '₺', {
size: 120,
fill: 0x00ff00
});
earningsTxt.anchor.set(0.5, 0.5);
earningsTxt.x = 1024;
earningsTxt.y = 1700;
earningsTxt.alpha = 0;
game.addChild(earningsTxt);
// Create continue button
var continueBtn = game.addChild(LK.getAsset('continueButton', {
anchorX: 0.5,
anchorY: 0.5
}));
continueBtn.x = 1024;
continueBtn.y = 2400;
continueBtn.alpha = 0;
// Fade in animation
tween(overlay, {
alpha: 0.8
}, {
duration: 1000
});
tween(summaryTxt, {
alpha: 1
}, {
duration: 1000
});
tween(earningsTxt, {
alpha: 1
}, {
duration: 1000
});
tween(continueBtn, {
alpha: 1
}, {
duration: 1000
});
// Handle continue button click
continueBtn.down = function () {
// Fade out animation
tween(overlay, {
alpha: 0
}, {
duration: 1000
});
tween(summaryTxt, {
alpha: 0
}, {
duration: 1000
});
tween(earningsTxt, {
alpha: 0
}, {
duration: 1000
});
tween(continueBtn, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
// Remove summary elements after fade out
overlay.destroy();
summaryTxt.destroy();
earningsTxt.destroy();
continueBtn.destroy();
gameOverPaused = false;
startNextDay();
}
});
};
}
function startNextDay() {
// Reset day variables
currentDay++;
dailyEarnings = 0;
totalCustomersSpawned = 0;
totalCustomersExited = 0;
spawnTimer = 0;
spawnDelay = Math.floor(Math.random() * (540 - 360 + 1)) + 360; // Random between 6-9 seconds
// Save all game data to storage when starting next day
storage.currentDay = currentDay;
storage.dayStartMoney = money; // Save money at start of new day
storage.lastPlayedDay = currentDay; // Track which day we're on
storage.money = money;
// Save shelf positions and count
storage.totalShelves = shelves.length;
for (var i = 0; i < shelves.length; i++) {
storage['shelf' + i + 'X'] = shelves[i].x;
storage['shelf' + i + 'Y'] = shelves[i].y;
}
// Save max products capacity
storage.maxProducts = maxProducts;
// Update day display
dayTxt.setText('Day ' + currentDay);
// Don't restock shelves automatically - players must buy from shop
// Clear any remaining customers
for (var i = customers.length - 1; i >= 0; i--) {
customers[i].destroy();
}
customers = [];
customerQueue = [];
currentCustomer = null;
// Start spawning customers again
dayJustStarted = true; // Set flag to prevent immediate day end
// Don't spawn customer immediately, let the spawn timer handle it
LK.setTimeout(function () {
dayJustStarted = false; // Allow day to end after spawn delay passes
}, spawnDelay * 16.67); //{79} // Convert frames to milliseconds (60fps = ~16.67ms per frame)
}
function showFeedback(message, color) {
var feedback = new Feedback(message, color);
game.addChild(feedback);
feedback.show();
}
function serveNextCustomer() {
if (customerQueue.length > 0 && !currentCustomer) {
currentCustomer = customerQueue.shift();
currentCustomer.isBeingServed = true;
// Move customer to cash register
tween(currentCustomer, {
x: 896,
y: queueLine.y
}, {
duration: 1500,
onFinish: function onFinish() {
if (currentCustomer && currentCustomer.parent) {
currentCustomer.placeItemsOnCounter();
}
}
});
// Move other customers forward in queue - only move existing queue members
for (var i = 0; i < customerQueue.length; i++) {
var queuePos = queueLine.x + (i + 1) * 200;
tween(customerQueue[i], {
x: queuePos,
y: queueLine.y
}, {
duration: 1000
});
}
}
}
// Handle dragging shelf during placement mode
game.move = function (x, y, obj) {
if (shelfPlacementMode && draggingShelf) {
draggingShelf.x = x;
draggingShelf.y = y;
}
};
game.update = function () {
// Don't update game logic during day summary or shelf placement
if (gameOverPaused || shelfPlacementMode) {
return;
}
// Hide/show instruction text based on shop state
instructionsTxt.visible = !shopOpen;
// Move money elements to top when shop is open
if (shopOpen) {
blackRect.y = 10;
scoreTxt.y = 25;
} else {
blackRect.y = 135;
scoreTxt.y = 150;
}
// Check if all shelves are empty and handle customers accordingly
if (areAllShelvesEmpty()) {
// Automatically close the store when no products available
if (storeOpen) {
storeOpen = false;
// Update button to show Close image
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Close', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
// Re-assign click handler
openCloseBtn.down = function () {
if (!gameOverPaused && !shopOpen) {
// Check if trying to open the store
if (!storeOpen && areAllShelvesEmpty()) {
// Don't allow opening if no products
return;
}
storeOpen = !storeOpen;
if (storeOpen) {
// Replace with Open image
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Open', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
openCloseBtn.down = arguments.callee; // Re-assign click handler
} else {
// Replace with Close image
openCloseBtn.destroy();
openCloseBtn = game.addChild(LK.getAsset('Close', {
anchorX: 0.5,
anchorY: 0.5
}));
openCloseBtn.x = 1024;
openCloseBtn.y = counterY + 300;
openCloseBtn.scaleX = 2;
openCloseBtn.scaleY = 2;
openCloseBtn.down = arguments.callee; // Re-assign click handler
}
}
};
}
// Make customers who are still shopping leave without products
for (var i = customers.length - 1; i >= 0; i--) {
var customer = customers[i];
if (customer.isShopping && customer.items.length === 0) {
// Customer leaves empty-handed
tween(customer, {
x: -200
}, {
duration: 1000,
onFinish: function onFinish() {
totalCustomersExited++;
customer.destroy();
}
});
customers.splice(i, 1);
}
}
// Don't spawn new customers when shelves are empty or store is closed
} else if (storeOpen) {
spawnTimer++;
// Spawn new customers
if (spawnTimer >= spawnDelay) {
spawnCustomer();
spawnTimer = 0;
// Set new random spawn delay between 6-9 seconds
spawnDelay = Math.floor(Math.random() * (540 - 360 + 1)) + 360;
}
}
// Check if current customer transaction is complete
if (currentCustomer && currentCustomer.isBeingServed) {
// Handle automatic scanner item movement
if (hasAutomaticScanner && currentCustomer.items) {
// Move all items together like a bread queue
for (var itemIdx = 0; itemIdx < currentCustomer.items.length; itemIdx++) {
var item = currentCustomer.items[itemIdx];
// Skip if already scanned
if (item.scanned) {
continue;
}
// Check if any item ahead is currently being scanned (paused)
var canMove = true;
for (var checkIdx = 0; checkIdx < itemIdx; checkIdx++) {
var checkItem = currentCustomer.items[checkIdx];
if (checkItem.isPaused) {
canMove = false;
break;
}
}
// Only move if no items ahead are paused
if (!canMove) {
continue;
}
// Check if item is about to touch scanner
if (!item.isPaused && item.y + 2 >= item.targetY) {
// Item reached scanner, pause this item only
item.isPaused = true;
item.scanned = true;
// Find the graphics child and make it transparent
for (var g = 0; g < item.children.length; g++) {
if (item.children[g].alpha !== undefined) {
item.children[g].alpha = 0.5;
break;
}
}
LK.getSound('itemScan').play();
// showFeedback('Item scanned!', 0x00ff00);//{9V} - Removed feedback per request
// Resume movement after a short delay
LK.setTimeout(function (currentItem) {
return function () {
currentItem.isPaused = false;
};
}(item), 500);
} else if (!item.isPaused && item.y < item.targetY) {
// Move item down slowly
item.y += 2; // Move 2 pixels per frame
}
}
}
// Shaking effect is now handled by tween animations instead of direct position manipulation
// Only check for scanned items if customer hasn't left
if (currentCustomer.parent && currentCustomer.allItemsScanned()) {
currentCustomer.completeTransaction();
// Remove from customers array
for (var i = customers.length - 1; i >= 0; i--) {
if (customers[i] === currentCustomer) {
customers.splice(i, 1);
break;
}
}
currentCustomer = null;
// Serve next customer after a short delay
LK.setTimeout(function () {
serveNextCustomer();
}, 500);
}
// Check if customer left angry
if (currentCustomer && !currentCustomer.parent) {
// Remove from customers array
for (var i = customers.length - 1; i >= 0; i--) {
if (customers[i] === currentCustomer) {
customers.splice(i, 1);
break;
}
}
currentCustomer = null;
// Serve next customer after a short delay
LK.setTimeout(function () {
serveNextCustomer();
}, 500);
}
}
// Serve next customer if none is being served
if (!currentCustomer) {
serveNextCustomer();
}
// Update customer counter displays
spawnedCounterTxt.setText('Spawned: ' + totalCustomersSpawned);
exitedCounterTxt.setText('Exited: ' + totalCustomersExited);
// Update buy button colors in real-time if shop is open and showing products category
if (shopOpen && currentShopCategory === 'products') {
var productItems = [{
name: 'Apple',
price: 48
}, {
name: 'Banana',
price: 96
}, {
name: 'Orange',
price: 72
}, {
name: 'Milk',
price: 120
}, {
name: 'Bread',
price: 24
}, {
name: 'Cheese',
price: 72
}];
// Update all buy button colors based on current capacity
for (var b = 0; b < productItems.length; b++) {
var checkItem = productItems[b];
var checkProductType = null;
if (checkItem.name === 'Apple') {
checkProductType = 'apple';
} else if (checkItem.name === 'Banana') {
checkProductType = 'banana';
} else if (checkItem.name === 'Orange') {
checkProductType = 'orange';
} else if (checkItem.name === 'Milk') {
checkProductType = 'milk';
} else if (checkItem.name === 'Bread') {
checkProductType = 'bread';
} else if (checkItem.name === 'Cheese') {
checkProductType = 'cheese';
}
var canBuyItem = money >= checkItem.price && canAcceptMoreProducts(checkProductType);
// Find the corresponding buy button (it's the last item added for each product)
var buyButtonIndex = (b + 1) * 5 - 1; // Buy button is 5th item for each product (bg, name, desc, price, buy)
if (shopItems[buyButtonIndex]) {
// Only gray out if insufficient funds or can't accept more products
if (!canBuyItem) {
shopItems[buyButtonIndex].tint = 0x888888; // Gray out button
// Also gray out the corresponding item background (it's the first item for each product)
var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy)
if (shopItems[itemBgIndex]) {
shopItems[itemBgIndex].tint = 0x888888; // Gray out item background
}
} else {
// Make sure buy button color is updated immediately
shopItems[buyButtonIndex].tint = 0xffffff; // Normal color
// Also restore normal color for item background
var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy)
if (shopItems[itemBgIndex]) {
shopItems[itemBgIndex].tint = 0xffffff; // Normal color for item background
}
}
}
}
}
// Day end condition - when all shelves are empty and all customers have left (and at least 1 customer visited)
if (areAllShelvesEmpty() && totalCustomersSpawned === totalCustomersExited && totalCustomersExited > 0 && !gameOverPaused && !dayJustStarted) {
showDaySummary();
}
// Game over condition - too many customers waiting
if (customerQueue.length >= 5) {
LK.showGameOver();
}
};
// Create end day button in bottom right
var endDayBtn = game.addChild(LK.getAsset('blackRectangle', {
anchorX: 0.5,
anchorY: 0.5
}));
endDayBtn.x = 1748;
endDayBtn.y = 2600;
endDayBtn.width = 300;
endDayBtn.height = 150;
endDayBtn.tint = 0x444444;
var endDayTxt = new Text2('End Day', {
size: 40,
fill: 0xffffff
});
endDayTxt.anchor.set(0.5, 0.5);
endDayTxt.x = 1748;
endDayTxt.y = 2600;
game.addChild(endDayTxt);
// Handle end day button click
endDayBtn.down = function () {
if (!gameOverPaused && !shopOpen) {
showDaySummary();
}
};
// Create shop button in bottom left
var shopBtn = game.addChild(LK.getAsset('shopButton', {
anchorX: 0.5,
anchorY: 0.5
}));
shopBtn.x = 300;
shopBtn.y = 2600;
// Shop overlay variables
var shopOverlay = null;
var shopItems = [];
var currentShopCategory = 'products';
// Shelf placement mode variables
var shelfPlacementMode = false;
var draggingShelf = null;
var placementButton = null;
var maxProducts = storage.maxProducts || defaultShelfPositions.length * 9; // Load from storage or calculate based on shelf count
// Handle shop button click
// Shop overlay variables
var currentShopCategory = 'products';
shopBtn.down = function () {
if (!gameOverPaused && !shopOverlay) {
// Check if store is open
if (storeOpen) {
showFeedback('Close the store first!', 0xff0000);
return;
}
// Check if there are customers in the store
if (totalCustomersExited !== totalCustomersSpawned) {
showFeedback('Wait for customers to leave!', 0xff0000);
return;
}
shopOpen = true;
// Function to clear current category items
var clearCategoryItems = function clearCategoryItems() {
// Remove category-specific items (keep overlay, title, category buttons, and close button)
for (var i = shopItems.length - 1; i >= 0; i--) {
if (shopItems[i].isCategoryItem) {
shopItems[i].destroy();
shopItems.splice(i, 1);
}
}
}; // Function to show products category
var showProducts = function showProducts() {
currentShopCategory = 'products';
clearCategoryItems();
var productItems = [{
name: 'Apple',
price: 48,
description: 'Restocks apple shelf'
}, {
name: 'Banana',
price: 96,
description: 'Restocks banana shelf'
}, {
name: 'Orange',
price: 72,
description: 'Restocks orange shelf'
}, {
name: 'Milk',
price: 120,
description: 'Restocks milk shelf'
}, {
name: 'Bread',
price: 24,
description: 'Restocks bread shelf'
}, {
name: 'Cheese',
price: 72,
description: 'Restocks cheese shelf'
}];
// Create product cards
for (var i = 0; i < productItems.length; i++) {
var item = productItems[i];
var xPos = 1024 - 600 + i % 3 * 600; // Center horizontally: 1024 is center, -600 to offset for 3 items
var yPos = 700 + Math.floor(i / 3) * 500;
// Item background
var itemBg = game.addChild(LK.getAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5
}));
itemBg.x = xPos;
itemBg.y = yPos;
itemBg.width = 400;
itemBg.height = 450;
itemBg.isCategoryItem = true;
shopItems.push(itemBg);
// Item name
var itemName = new Text2(item.name, {
size: 32,
fill: 0xffffff
});
itemName.anchor.set(0.5, 0.5);
itemName.x = xPos;
itemName.y = yPos - 100;
itemName.isCategoryItem = true;
game.addChild(itemName);
shopItems.push(itemName);
// Item description
var itemDesc = new Text2(item.description, {
size: 22,
fill: 0xffffff
});
itemDesc.anchor.set(0.5, 0.5);
itemDesc.x = xPos;
itemDesc.y = yPos - 50;
itemDesc.isCategoryItem = true;
game.addChild(itemDesc);
shopItems.push(itemDesc);
// Item price
var itemPrice = new Text2(item.price + '₺', {
size: 40,
fill: 0x90ee90
});
itemPrice.anchor.set(0.5, 0.5);
itemPrice.x = xPos;
itemPrice.y = yPos;
itemPrice.isCategoryItem = true;
game.addChild(itemPrice);
shopItems.push(itemPrice);
// Buy button
var buyBtn = game.addChild(LK.getAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5
}));
buyBtn.x = xPos;
buyBtn.y = yPos + 100;
buyBtn.width = 250;
buyBtn.height = 125;
buyBtn.itemData = item;
buyBtn.isCategoryItem = true;
shopItems.push(buyBtn);
// Check if all shelves are full (all product slots are occupied with available products)
var allShelvesFull = true;
for (var s = 0; s < shelves.length; s++) {
var shelf = shelves[s];
for (var p = 0; p < shelf.products.length; p++) {
if (!shelf.products[p] || !shelf.products[p].available) {
allShelvesFull = false;
break;
}
}
if (!allShelvesFull) break;
}
// Check if shelves can accept more products of this type
var productType = null;
if (item.name === 'Apple') {
productType = 'apple';
} else if (item.name === 'Banana') {
productType = 'banana';
} else if (item.name === 'Orange') {
productType = 'orange';
} else if (item.name === 'Milk') {
productType = 'milk';
} else if (item.name === 'Bread') {
productType = 'bread';
} else if (item.name === 'Cheese') {
productType = 'cheese';
}
var canBuy = money >= item.price && canAcceptMoreProducts(productType);
// Only gray out if insufficient funds or can't accept more products
if (!canBuy) {
buyBtn.tint = 0x888888; // Gray out button
itemBg.tint = 0x888888; // Gray out item background too
} else {
buyBtn.tint = 0xffffff; // Normal color
itemBg.tint = 0xffffff; // Normal color for item background
}
// Buy button handler
buyBtn.down = function () {
// Check if we can buy (enough money and shelf space)
var productType = null;
if (this.itemData.name === 'Apple') {
productType = 'apple';
} else if (this.itemData.name === 'Banana') {
productType = 'banana';
} else if (this.itemData.name === 'Orange') {
productType = 'orange';
} else if (this.itemData.name === 'Milk') {
productType = 'milk';
} else if (this.itemData.name === 'Bread') {
productType = 'bread';
} else if (this.itemData.name === 'Cheese') {
productType = 'cheese';
}
if (money >= this.itemData.price && canAcceptMoreProducts(productType)) {
money -= this.itemData.price;
scoreTxt.setText(money + '₺');
// Flash green to show purchase
LK.effects.flashObject(this, 0x00ff00, 500);
// Show feedback
showFeedback('Purchased ' + this.itemData.name + '!', 0x00ff00);
// Restock the appropriate shelf based on product type
var productType = null;
if (this.itemData.name === 'Apple') {
productType = 'apple';
} else if (this.itemData.name === 'Banana') {
productType = 'banana';
} else if (this.itemData.name === 'Orange') {
productType = 'orange';
} else if (this.itemData.name === 'Milk') {
productType = 'milk';
} else if (this.itemData.name === 'Bread') {
productType = 'bread';
} else if (this.itemData.name === 'Cheese') {
productType = 'cheese';
}
if (productType) {
// Find a shelf that needs this product type and restock it
var restocked = false;
for (var s = 0; s < shelves.length; s++) {
var shelf = shelves[s];
// Check each row for empty space
for (var row = 0; row < 3; row++) {
var rowEmpty = true;
// Check if this row is empty
for (var col = 0; col < 3; col++) {
var index = row * 3 + col;
if (shelf.products[index] && shelf.products[index].available) {
rowEmpty = false;
break;
}
}
// If row is empty, fill it with the product
if (rowEmpty) {
var cols = 3;
var spacing = 100;
var startX = -120;
var startY = -120;
for (var col = 0; col < cols; col++) {
var index = row * 3 + col;
// If product slot exists but is not available, make it visible and available
if (shelf.products[index]) {
shelf.products[index].destroy();
}
var product = shelf.attachAsset(productType, {
anchorX: 0.5,
anchorY: 0.5
});
product.x = startX + col * spacing;
product.y = startY + row * (spacing + 20);
product.available = true;
product.productType = productType;
product.name = this.itemData.name; // Get product name
product.value = Math.floor(this.itemData.price / 3 / 0.8); // Set value based on purchase price for 3 items with 20% profit margin
shelf.products[index] = product;
}
restocked = true;
break;
}
}
if (restocked) {
break;
}
}
// If no empty row found in any shelf, notify player
if (!restocked) {
// Could add a notification here that all shelves are full
}
}
// After restocking, check if shelves are now full of this product type
if (!canAcceptMoreProducts(productType)) {
// Remove all shop elements
shopOverlay.destroy();
shopOverlay = null;
for (var j = 0; j < shopItems.length; j++) {
shopItems[j].destroy();
}
shopItems = [];
shopOpen = false;
}
// Force immediate update of all buy button colors
for (var updateIdx = 0; updateIdx < productItems.length; updateIdx++) {
var updateItem = productItems[updateIdx];
var updateProductType = null;
if (updateItem.name === 'Apple') {
updateProductType = 'apple';
} else if (updateItem.name === 'Banana') {
updateProductType = 'banana';
} else if (updateItem.name === 'Orange') {
updateProductType = 'orange';
} else if (updateItem.name === 'Milk') {
updateProductType = 'milk';
} else if (updateItem.name === 'Bread') {
updateProductType = 'bread';
} else if (updateItem.name === 'Cheese') {
updateProductType = 'cheese';
}
var canBuyUpdate = money >= updateItem.price && canAcceptMoreProducts(updateProductType);
// Find the corresponding buy button
var updateBuyButtonIndex = (updateIdx + 1) * 5 - 1;
if (shopItems[updateBuyButtonIndex]) {
if (!canBuyUpdate) {
shopItems[updateBuyButtonIndex].tint = 0x888888;
// Also gray out the item background
var updateItemBgIndex = updateIdx * 5;
if (shopItems[updateItemBgIndex]) {
shopItems[updateItemBgIndex].tint = 0x888888;
}
} else {
shopItems[updateBuyButtonIndex].tint = 0xffffff;
// Also restore item background color
var updateItemBgIndex = updateIdx * 5;
if (shopItems[updateItemBgIndex]) {
shopItems[updateItemBgIndex].tint = 0xffffff;
}
}
}
}
} else {
// Provide feedback for why purchase failed
if (money < this.itemData.price) {
showFeedback('Not enough money!', 0xff0000);
LK.effects.flashObject(this, 0xff0000, 500);
} else if (!canAcceptMoreProducts(productType)) {
showFeedback('No shelf space available!', 0xff0000);
LK.effects.flashObject(this, 0xff0000, 500);
}
}
};
// Update all buy button colors based on current capacity
for (var b = 0; b < productItems.length; b++) {
var checkItem = productItems[b];
var checkProductType = null;
if (checkItem.name === 'Apple') {
checkProductType = 'apple';
} else if (checkItem.name === 'Banana') {
checkProductType = 'banana';
} else if (checkItem.name === 'Orange') {
checkProductType = 'orange';
} else if (checkItem.name === 'Milk') {
checkProductType = 'milk';
} else if (checkItem.name === 'Bread') {
checkProductType = 'bread';
} else if (checkItem.name === 'Cheese') {
checkProductType = 'cheese';
}
var canBuyItem = money >= checkItem.price && canAcceptMoreProducts(checkProductType);
// Find the corresponding buy button (it's the last item added for each product)
var buyButtonIndex = (b + 1) * 5 - 1; // Buy button is 5th item for each product (bg, name, desc, price, buy)
if (shopItems[buyButtonIndex]) {
// Only gray out if insufficient funds or can't accept more products
if (!canBuyItem) {
shopItems[buyButtonIndex].tint = 0x888888; // Gray out button
// Also gray out the corresponding item background (it's the first item for each product)
var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy)
if (shopItems[itemBgIndex]) {
shopItems[itemBgIndex].tint = 0x888888; // Gray out item background
}
} else {
shopItems[buyButtonIndex].tint = 0xffffff; // Normal color
// Also restore normal color for item background
var itemBgIndex = b * 5; // Item background is 1st item for each product (bg, name, desc, price, buy)
if (shopItems[itemBgIndex]) {
shopItems[itemBgIndex].tint = 0xffffff; // Normal color for item background
}
}
}
}
}
}; // Function to show equipment category
var showEquipment = function showEquipment() {
currentShopCategory = 'equipment';
clearCategoryItems();
var equipmentItems = [{
name: 'Extra Shelf',
price: 5000,
description: 'Add more shelf space'
}, {
name: 'Refrigerator',
price: 800,
description: 'Keep dairy products fresh'
}, {
name: 'Automatic Scanner',
price: 0,
description: 'Automatically scan all items'
}, {
name: 'Security Camera',
price: 400,
description: 'Reduce theft'
}];
// Create equipment cards
for (var i = 0; i < equipmentItems.length; i++) {
var item = equipmentItems[i];
// Apply progressive pricing for Extra Shelf
if (item.name === 'Extra Shelf') {
var shelfCount = shelves.length;
if (shelfCount === 4) {
item.price = 5000;
} else if (shelfCount === 5) {
item.price = 8000;
} else if (shelfCount === 6) {
item.price = 10000;
} else if (shelfCount === 7) {
item.price = 15000;
} else if (shelfCount >= 8) {
item.price = 20000;
}
}
var xPos = 424 + i % 2 * 600;
var yPos = 700 + Math.floor(i / 2) * 500;
// Item background
var itemBg = game.addChild(LK.getAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5
}));
itemBg.x = xPos;
itemBg.y = yPos;
itemBg.width = 400;
itemBg.height = 450;
itemBg.isCategoryItem = true;
shopItems.push(itemBg);
// Item name
var itemName = new Text2(item.name, {
size: 36,
fill: 0xffffff
});
itemName.anchor.set(0.5, 0.5);
itemName.x = xPos;
itemName.y = yPos - 100;
itemName.isCategoryItem = true;
game.addChild(itemName);
shopItems.push(itemName);
// Item description
var itemDesc = new Text2(item.description, {
size: 24,
fill: 0xffffff
});
itemDesc.anchor.set(0.5, 0.5);
itemDesc.x = xPos;
itemDesc.y = yPos - 50;
itemDesc.isCategoryItem = true;
game.addChild(itemDesc);
shopItems.push(itemDesc);
// Item price
var itemPrice = new Text2(item.price + '₺', {
size: 50,
fill: 0x90ee90
});
itemPrice.anchor.set(0.5, 0.5);
itemPrice.x = xPos;
itemPrice.y = yPos;
itemPrice.isCategoryItem = true;
game.addChild(itemPrice);
shopItems.push(itemPrice);
// Buy button
var buyBtn = game.addChild(LK.getAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5
}));
buyBtn.x = xPos;
buyBtn.y = yPos + 100;
buyBtn.width = 250;
buyBtn.height = 125;
buyBtn.itemData = item;
buyBtn.isCategoryItem = true;
shopItems.push(buyBtn);
// Check if this is Extra Shelf and we already have 8 shelves
var canBuy = money >= item.price;
if (item.name === 'Extra Shelf' && shelves.length >= 8) {
canBuy = false;
}
// Check if Automatic Scanner is already purchased
if (item.name === 'Automatic Scanner' && hasAutomaticScanner) {
canBuy = false;
}
if (!canBuy) {
buyBtn.tint = 0x888888; // Gray out button
itemBg.tint = 0x888888; // Gray out item background too
} else {
buyBtn.tint = 0xffffff; // Normal color
itemBg.tint = 0xffffff; // Normal color for item background
}
// Buy button handler
buyBtn.down = function () {
if (money >= this.itemData.price) {
// Check if trying to buy Extra Shelf and already have 8 shelves
if (this.itemData.name === 'Extra Shelf' && shelves.length >= 8) {
// Don't allow purchase - flash red instead
showFeedback('Maximum shelves reached!', 0xff0000);
LK.effects.flashObject(this, 0xff0000, 500);
return;
}
money -= this.itemData.price;
scoreTxt.setText(money + '₺');
// Flash green to show purchase
LK.effects.flashObject(this, 0x00ff00, 500);
// Special handling for Automatic Scanner
if (this.itemData.name === 'Automatic Scanner') {
// Set global flag for automatic scanning
hasAutomaticScanner = true;
storage.hasAutomaticScanner = true;
// Create scanner base immediately
if (!scannerBase) {
scannerBase = game.addChild(LK.getAsset('scanner', {
anchorX: 0.5,
anchorY: 0.5
}));
scannerBase.x = 900; // Align with where items are placed
scannerBase.y = counterY + 200; // Below counter
}
// Disable the buy button after purchase
this.tint = 0x888888; // Gray out button
this.down = function () {}; // Remove click handler
}
// Special handling for Extra Shelf
if (this.itemData.name === 'Extra Shelf') {
// Close shop and enter shelf placement mode
shopOverlay.destroy();
shopOverlay = null;
for (var j = 0; j < shopItems.length; j++) {
shopItems[j].destroy();
}
shopItems = [];
shopOpen = false;
shelfPlacementMode = true;
maxProducts += 9; // Increase max product capacity
// Create draggable transparent shelf
draggingShelf = game.addChild(LK.getAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5
}));
draggingShelf.x = 1024;
draggingShelf.y = 1366;
draggingShelf.alpha = 0.5;
// Create green placement button
placementButton = game.addChild(LK.getAsset('openCloseButton', {
anchorX: 0.5,
anchorY: 0.5
}));
placementButton.x = 1024;
placementButton.y = 2500;
placementButton.tint = 0x00ff00;
placementButton.scaleX = 2;
placementButton.scaleY = 2;
// Add placement button text
var placementText = new Text2('Place Shelf', {
size: 30,
fill: 0x000000
});
placementText.anchor.set(0.5, 0.5);
placementText.x = 1024;
placementText.y = 2500;
game.addChild(placementText);
// Placement button handler
placementButton.down = function () {
if (shelfPlacementMode && draggingShelf) {
// Extract the new shelf position as literal values
var newShelfX = Math.floor(draggingShelf.x);
var newShelfY = Math.floor(draggingShelf.y);
// Create the new shelf
var newShelf = new Shelf();
newShelf.x = newShelfX;
newShelf.y = newShelfY;
shelves.push(newShelf);
game.addChild(newShelf);
// Clean up placement mode
draggingShelf.destroy();
draggingShelf = null;
placementButton.destroy();
placementButton = null;
placementText.destroy();
shelfPlacementMode = false;
}
};
}
} else {
// Not enough money
showFeedback('Not enough money!', 0xff0000);
LK.effects.flashObject(this, 0xff0000, 500);
}
};
}
}; // Function to show customization category
var showCustomization = function showCustomization() {
currentShopCategory = 'customization';
clearCategoryItems();
var customizeItems = [{
name: 'Store Sign',
price: 200,
description: 'Custom store branding'
}, {
name: 'Floor Tiles',
price: 150,
description: 'Improve store appearance'
}, {
name: 'Lighting',
price: 300,
description: 'Better store lighting'
}, {
name: 'Music System',
price: 250,
description: 'Background music'
}];
// Create customization cards
for (var i = 0; i < customizeItems.length; i++) {
var item = customizeItems[i];
var xPos = 424 + i % 2 * 600;
var yPos = 700 + Math.floor(i / 2) * 500;
// Item background
var itemBg = game.addChild(LK.getAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5
}));
itemBg.x = xPos;
itemBg.y = yPos;
itemBg.width = 400;
itemBg.height = 450;
itemBg.isCategoryItem = true;
shopItems.push(itemBg);
// Item name
var itemName = new Text2(item.name, {
size: 36,
fill: 0xffffff
});
itemName.anchor.set(0.5, 0.5);
itemName.x = xPos;
itemName.y = yPos - 100;
itemName.isCategoryItem = true;
game.addChild(itemName);
shopItems.push(itemName);
// Item description
var itemDesc = new Text2(item.description, {
size: 24,
fill: 0xffffff
});
itemDesc.anchor.set(0.5, 0.5);
itemDesc.x = xPos;
itemDesc.y = yPos - 50;
itemDesc.isCategoryItem = true;
game.addChild(itemDesc);
shopItems.push(itemDesc);
// Item price
var itemPrice = new Text2(item.price + '₺', {
size: 50,
fill: 0x90ee90
});
itemPrice.anchor.set(0.5, 0.5);
itemPrice.x = xPos;
itemPrice.y = yPos;
itemPrice.isCategoryItem = true;
game.addChild(itemPrice);
shopItems.push(itemPrice);
// Buy button
var buyBtn = game.addChild(LK.getAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5
}));
buyBtn.x = xPos;
buyBtn.y = yPos + 100;
buyBtn.width = 250;
buyBtn.height = 125;
buyBtn.itemData = item;
buyBtn.isCategoryItem = true;
shopItems.push(buyBtn);
// Buy button handler
buyBtn.down = function () {
if (money >= this.itemData.price) {
money -= this.itemData.price;
scoreTxt.setText(money + '₺');
// Flash green to show purchase
LK.effects.flashObject(this, 0x00ff00, 500);
showFeedback('Purchased ' + this.itemData.name + '!', 0x00ff00);
} else {
// Not enough money
showFeedback('Not enough money!', 0xff0000);
LK.effects.flashObject(this, 0xff0000, 500);
}
};
}
}; // Category button handlers
// Create white overlay
shopOverlay = game.addChild(LK.getAsset('shopOverlay', {
anchorX: 0.5,
anchorY: 0.5
}));
shopOverlay.x = 1024;
shopOverlay.y = 1366;
shopOverlay.alpha = 0.95;
// Create shop title
var shopTitle = new Text2('Market Shop', {
size: 80,
fill: 0x000000
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.x = 1024;
shopTitle.y = 300;
game.addChild(shopTitle);
shopItems.push(shopTitle);
// Create category buttons
var productsBtn = game.addChild(LK.getAsset('productsCategoryImage', {
anchorX: 0.5,
anchorY: 0.5
}));
productsBtn.x = 400;
productsBtn.y = 350;
productsBtn.width = 250;
productsBtn.height = 125;
shopItems.push(productsBtn);
var equipmentBtn = game.addChild(LK.getAsset('equipmentCategoryImage', {
anchorX: 0.5,
anchorY: 0.5
}));
equipmentBtn.x = 1024;
equipmentBtn.y = 350;
equipmentBtn.width = 250;
equipmentBtn.height = 125;
shopItems.push(equipmentBtn);
var customizeBtn = game.addChild(LK.getAsset('customizationCategoryImage', {
anchorX: 0.5,
anchorY: 0.5
}));
customizeBtn.x = 1648;
customizeBtn.y = 350;
customizeBtn.width = 250;
customizeBtn.height = 125;
shopItems.push(customizeBtn);
productsBtn.down = function () {
showProducts();
};
equipmentBtn.down = function () {
showEquipment();
};
customizeBtn.down = function () {
showCustomization();
};
// Show default category (products)
showProducts();
// Close button
var closeBtn = game.addChild(LK.getAsset('blackRectangle', {
anchorX: 0.5,
anchorY: 0.5
}));
closeBtn.x = 1024;
closeBtn.y = 2400;
closeBtn.width = 200;
closeBtn.height = 100;
shopItems.push(closeBtn);
var closeText = new Text2('Close', {
size: 40,
fill: 0xffffff
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 1024;
closeText.y = 2400;
game.addChild(closeText);
shopItems.push(closeText);
// Close button handler
closeBtn.down = function () {
// Remove all shop elements
shopOverlay.destroy();
shopOverlay = null;
for (var j = 0; j < shopItems.length; j++) {
shopItems[j].destroy();
}
shopItems = [];
shopOpen = false;
};
}
};
// Initial customer spawn
// Don't spawn customer immediately, let the spawn timer handle it
LK.setTimeout(function () {
dayJustStarted = false; // Allow day to end after spawn delay passes
}, spawnDelay * 16.67); //{dV} // Convert frames to milliseconds (60fps = ~16.67ms per frame)
// No changes required - the current implementation already makes angry customers walk out normally through the store entrance using tween animations;;
A shiny blue ball. In-Game asset. 2d. High contrast. No shadows
Üzerinde meyve, sebze gibi ürün bulundurmayan; market kasa bankosu. Üstten görünüm.. In-Game asset. 2d. High contrast. No shadows
Shiny apple. In-Game asset. 2d. High contrast. No shadows
Koparılmamış ve ayrılmamış, bir tutam muz. In-Game asset. 2d. High contrast. No shadows
Cheese. In-Game asset. 2d. High contrast. No shadows
Milk. In-Game asset. 2d. High contrast. No shadows
Orange. In-Game asset. 2d. High contrast. No shadows
Shelf. In-Game asset. 2d. High contrast. No shadows
Bread. In-Game asset. 2d. High contrast. No shadows
Continue button. In-Game asset. 2d. High contrast. No shadows
Cut this
Shop button. In-Game asset. 2d. High contrast. No shadows
A green Open button. In-Game asset. 2d. High contrast. No shadows
Rectangle red close button with "close" title. In-Game asset. 2d. High contrast. No shadows
Buy button. In-Game asset. 2d. High contrast. No shadows
Yiyecek kategorisi butonu. In-Game asset. 2d. High contrast. No shadows
Eşya kategorisi butonu. Üstünde "furniture" yazsın. In-Game asset. 2d. High contrast. No shadows
Kişiselleştirme kategorisi butonu. Boyutu 250x125 olsun. Çekiç sembolü olabilir. Rengi turuncu olsun. Yazı ingilizce olsun. Duş çerçevesi siyah olsun.. In-Game asset. 2d. High contrast. No shadows
İtem çerçevesi. In-Game asset. 2d. High contrast. No shadows