/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Customer = Container.expand(function (customerType) { var self = Container.call(this); // Set customer type (default to type 1 if not specified) self.customerType = customerType || 1; // Set patience based on customer type if (self.customerType === 1) { self.maxPatience = 12000; // 12 seconds (unchanged) } else if (self.customerType === 2) { self.maxPatience = 6000; // 6 seconds } else if (self.customerType === 3) { self.maxPatience = Infinity; // No time limit } self.patience = self.maxPatience; self.requestedProduct = productTypes[Math.floor(Math.random() * productTypes.length)]; self.served = false; // Create different appearances based on customer type var customerGraphic; if (self.customerType === 1) { // Original blue customer customerGraphic = self.attachAsset('customer', { anchorX: 0.5, anchorY: 1.0 }); } else if (self.customerType === 2) { // Red customer for impatient type customerGraphic = self.attachAsset('customer2', { anchorX: 0.5, anchorY: 1.0 }); } else if (self.customerType === 3) { // Green customer for patient type customerGraphic = self.attachAsset('customer3', { anchorX: 0.5, anchorY: 1.0 }); } // Request bubble var bubbleBg = self.attachAsset('requestBubble', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -680 }); var requestedProductGraphic = self.addChild(new Product(self.requestedProduct)); requestedProductGraphic.x = 0; requestedProductGraphic.y = -680; requestedProductGraphic.scaleX = 1.2; requestedProductGraphic.scaleY = 1.2; // Patience bar background var patienceBarBg = self.attachAsset('patienceBarBg', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -800 }); // Patience bar var patienceBar = self.attachAsset('patienceBar', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -800 }); // Hide patience bar for customer type 3 (no time limit) if (self.customerType === 3) { patienceBarBg.visible = false; patienceBar.visible = false; } self.updatePatienceBar = function () { var patienceRatio = self.patience / self.maxPatience; patienceBar.scaleX = patienceRatio; // Change color based on patience level if (patienceRatio > 0.6) { patienceBar.tint = 0x00ff00; // Green } else if (patienceRatio > 0.3) { patienceBar.tint = 0xffff00; // Yellow } else { patienceBar.tint = 0xff0000; // Red } }; self.serve = function (productType) { if (self.served) return false; self.served = true; if (productType === self.requestedProduct) { // Correct order LK.setScore(LK.getScore() + 10); LK.getSound('correct').play(); LK.effects.flashObject(self, 0x00ff00, 300); return true; } else { // Wrong order LK.setScore(LK.getScore() - 5); LK.getSound('wrong').play(); LK.effects.flashObject(self, 0xff0000, 300); return false; } }; self.leave = function () { if (!self.served) { // Customer left without being served LK.setScore(LK.getScore() - 3); LK.getSound('customerLeave').play(); } }; self.down = function (x, y, obj) { if (selectedProduct && !self.served) { self.serve(selectedProduct); selectedProduct = null; // Remove customer after serving tween(self, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 500, onFinish: function onFinish() { removeCustomer(self); } }); } }; self.update = function () { if (self.served) return; // Only decrease patience for customer types 1 and 2 if (self.customerType !== 3) { self.patience -= 16.67; // Decrease patience (assuming 60 FPS) self.updatePatienceBar(); if (self.patience <= 0) { // Customer ran out of patience self.leave(); tween(self, { alpha: 0, x: self.x - 200 }, { duration: 500, onFinish: function onFinish() { removeCustomer(self); } }); } } }; return self; }); var InventorySlot = Container.expand(function (productType, slotIndex) { var self = Container.call(this); self.productType = productType; self.slotIndex = slotIndex; var slotBg = self.attachAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5 }); var product = self.addChild(new Product(productType)); self.down = function (x, y, obj) { selectedProduct = self.productType; // Visual feedback for selection tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; return self; }); var Product = Container.expand(function (productType) { var self = Container.call(this); self.productType = productType; var productGraphic = self.attachAsset('product' + productType, { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf0f0f0 }); /**** * Game Code ****/ // Game variables var customers = []; var selectedProduct = null; var customerSpawnTimer = 0; var difficultyTimer = 0; var spawnRate = 180; // frames between spawns (3 seconds at 60fps) var productTypes = ['Apple', 'Bread', 'Milk', 'Cheese', 'Egg', 'Yogurt', 'Water']; // Score display var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xffffff, font: "Impact, 'Arial Black', Tahoma, Verdana, sans-serif" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create single background scene var background = game.addChild(LK.getAsset('shopBackground', { anchorX: 0.5, anchorY: 0, scaleX: 0.2048, scaleY: 0.272 })); background.x = 2048 / 2; background.y = 0; // Create counter var counter = game.addChild(LK.getAsset('counter', { anchorX: 0.5, anchorY: 0.5 })); counter.x = 2048 / 2; counter.y = 1600; // Position counter lower // Create bench for placing items var bench = game.addChild(LK.getAsset('bench', { anchorX: 0.5, anchorY: 0.5 })); bench.x = 2048 / 2; bench.y = 2000; // Position bench lower // Create inventory on top of the bench var inventoryY = bench.y - 100; // Position inventory above the bench var inventoryStartX = 2048 / 2 - productTypes.length * 220 / 2; for (var i = 0; i < productTypes.length; i++) { var slot = game.addChild(new InventorySlot(productTypes[i], i)); slot.x = inventoryStartX + i * 220; slot.y = inventoryY; } // Customer spawn positions (positioned behind counter) var customerPositions = [{ x: 400, y: 1450 }, { x: 800, y: 1450 }, { x: 1200, y: 1450 }, { x: 1600, y: 1450 }]; function spawnCustomer() { if (customers.length >= 4) return; // Max 4 customers at once // Queue system: find the leftmost available position var targetPosition = null; for (var i = 0; i < customerPositions.length; i++) { var positionTaken = false; for (var j = 0; j < customers.length; j++) { if (Math.abs(customers[j].x - customerPositions[i].x) < 50) { positionTaken = true; break; } } if (!positionTaken) { targetPosition = customerPositions[i]; break; // Take the first available position (leftmost) } } if (!targetPosition) return; // Randomly select customer type (1, 2, or 3) var customerType = Math.floor(Math.random() * 3) + 1; var customer = game.addChild(new Customer(customerType)); customer.x = targetPosition.x; customer.y = targetPosition.y; customer.alpha = 0; customers.push(customer); // Animate customer entrance tween(customer, { alpha: 1, y: targetPosition.y - 50 }, { duration: 500 }); } function removeCustomer(customer) { var index = customers.indexOf(customer); if (index > -1) { customers.splice(index, 1); customer.destroy(); // Move remaining customers forward in queue moveCustomersForward(); } } function moveCustomersForward() { // Sort customers by their current x position customers.sort(function (a, b) { return a.x - b.x; }); // Move each customer to the next available position from left to right for (var i = 0; i < customers.length; i++) { var targetX = customerPositions[i].x; if (Math.abs(customers[i].x - targetX) > 10) { // Animate customer moving to new position tween(customers[i], { x: targetX }, { duration: 300 }); } } } // Game update loop game.update = function () { // Update score display scoreTxt.setText('Score: ' + LK.getScore()); // Check game over condition if (LK.getScore() < 0) { LK.showGameOver(); return; } // Spawn customers customerSpawnTimer++; if (customerSpawnTimer >= spawnRate) { spawnCustomer(); customerSpawnTimer = 0; } // Increase difficulty over time difficultyTimer++; if (difficultyTimer >= 1800) { // Every 30 seconds spawnRate = Math.max(60, spawnRate - 20); // Minimum 1 second between spawns difficultyTimer = 0; } // Update customers for (var i = customers.length - 1; i >= 0; i--) { customers[i].update(); } }; // Display tutorial message at game start var tutorialText = new Text2('To give items to customers, first click on the item, then click on the customer.', { size: 80, fill: 0xffffff, font: "Impact, 'Arial Black', Tahoma, Verdana, sans-serif" }); tutorialText.anchor.set(0.5, 0.5); tutorialText.x = 2048 / 2; tutorialText.y = 1200; game.addChild(tutorialText); // Show tutorial message briefly then fade out tween(tutorialText, { alpha: 0 }, { duration: 3000, onFinish: function onFinish() { tutorialText.destroy(); } }); // Initialize game state LK.setScore(50); // Start with some buffer score;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Customer = Container.expand(function (customerType) {
var self = Container.call(this);
// Set customer type (default to type 1 if not specified)
self.customerType = customerType || 1;
// Set patience based on customer type
if (self.customerType === 1) {
self.maxPatience = 12000; // 12 seconds (unchanged)
} else if (self.customerType === 2) {
self.maxPatience = 6000; // 6 seconds
} else if (self.customerType === 3) {
self.maxPatience = Infinity; // No time limit
}
self.patience = self.maxPatience;
self.requestedProduct = productTypes[Math.floor(Math.random() * productTypes.length)];
self.served = false;
// Create different appearances based on customer type
var customerGraphic;
if (self.customerType === 1) {
// Original blue customer
customerGraphic = self.attachAsset('customer', {
anchorX: 0.5,
anchorY: 1.0
});
} else if (self.customerType === 2) {
// Red customer for impatient type
customerGraphic = self.attachAsset('customer2', {
anchorX: 0.5,
anchorY: 1.0
});
} else if (self.customerType === 3) {
// Green customer for patient type
customerGraphic = self.attachAsset('customer3', {
anchorX: 0.5,
anchorY: 1.0
});
}
// Request bubble
var bubbleBg = self.attachAsset('requestBubble', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -680
});
var requestedProductGraphic = self.addChild(new Product(self.requestedProduct));
requestedProductGraphic.x = 0;
requestedProductGraphic.y = -680;
requestedProductGraphic.scaleX = 1.2;
requestedProductGraphic.scaleY = 1.2;
// Patience bar background
var patienceBarBg = self.attachAsset('patienceBarBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -800
});
// Patience bar
var patienceBar = self.attachAsset('patienceBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -800
});
// Hide patience bar for customer type 3 (no time limit)
if (self.customerType === 3) {
patienceBarBg.visible = false;
patienceBar.visible = false;
}
self.updatePatienceBar = function () {
var patienceRatio = self.patience / self.maxPatience;
patienceBar.scaleX = patienceRatio;
// Change color based on patience level
if (patienceRatio > 0.6) {
patienceBar.tint = 0x00ff00; // Green
} else if (patienceRatio > 0.3) {
patienceBar.tint = 0xffff00; // Yellow
} else {
patienceBar.tint = 0xff0000; // Red
}
};
self.serve = function (productType) {
if (self.served) return false;
self.served = true;
if (productType === self.requestedProduct) {
// Correct order
LK.setScore(LK.getScore() + 10);
LK.getSound('correct').play();
LK.effects.flashObject(self, 0x00ff00, 300);
return true;
} else {
// Wrong order
LK.setScore(LK.getScore() - 5);
LK.getSound('wrong').play();
LK.effects.flashObject(self, 0xff0000, 300);
return false;
}
};
self.leave = function () {
if (!self.served) {
// Customer left without being served
LK.setScore(LK.getScore() - 3);
LK.getSound('customerLeave').play();
}
};
self.down = function (x, y, obj) {
if (selectedProduct && !self.served) {
self.serve(selectedProduct);
selectedProduct = null;
// Remove customer after serving
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
removeCustomer(self);
}
});
}
};
self.update = function () {
if (self.served) return;
// Only decrease patience for customer types 1 and 2
if (self.customerType !== 3) {
self.patience -= 16.67; // Decrease patience (assuming 60 FPS)
self.updatePatienceBar();
if (self.patience <= 0) {
// Customer ran out of patience
self.leave();
tween(self, {
alpha: 0,
x: self.x - 200
}, {
duration: 500,
onFinish: function onFinish() {
removeCustomer(self);
}
});
}
}
};
return self;
});
var InventorySlot = Container.expand(function (productType, slotIndex) {
var self = Container.call(this);
self.productType = productType;
self.slotIndex = slotIndex;
var slotBg = self.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
var product = self.addChild(new Product(productType));
self.down = function (x, y, obj) {
selectedProduct = self.productType;
// Visual feedback for selection
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
};
return self;
});
var Product = Container.expand(function (productType) {
var self = Container.call(this);
self.productType = productType;
var productGraphic = self.attachAsset('product' + productType, {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf0f0f0
});
/****
* Game Code
****/
// Game variables
var customers = [];
var selectedProduct = null;
var customerSpawnTimer = 0;
var difficultyTimer = 0;
var spawnRate = 180; // frames between spawns (3 seconds at 60fps)
var productTypes = ['Apple', 'Bread', 'Milk', 'Cheese', 'Egg', 'Yogurt', 'Water'];
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xffffff,
font: "Impact, 'Arial Black', Tahoma, Verdana, sans-serif"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create single background scene
var background = game.addChild(LK.getAsset('shopBackground', {
anchorX: 0.5,
anchorY: 0,
scaleX: 0.2048,
scaleY: 0.272
}));
background.x = 2048 / 2;
background.y = 0;
// Create counter
var counter = game.addChild(LK.getAsset('counter', {
anchorX: 0.5,
anchorY: 0.5
}));
counter.x = 2048 / 2;
counter.y = 1600; // Position counter lower
// Create bench for placing items
var bench = game.addChild(LK.getAsset('bench', {
anchorX: 0.5,
anchorY: 0.5
}));
bench.x = 2048 / 2;
bench.y = 2000; // Position bench lower
// Create inventory on top of the bench
var inventoryY = bench.y - 100; // Position inventory above the bench
var inventoryStartX = 2048 / 2 - productTypes.length * 220 / 2;
for (var i = 0; i < productTypes.length; i++) {
var slot = game.addChild(new InventorySlot(productTypes[i], i));
slot.x = inventoryStartX + i * 220;
slot.y = inventoryY;
}
// Customer spawn positions (positioned behind counter)
var customerPositions = [{
x: 400,
y: 1450
}, {
x: 800,
y: 1450
}, {
x: 1200,
y: 1450
}, {
x: 1600,
y: 1450
}];
function spawnCustomer() {
if (customers.length >= 4) return; // Max 4 customers at once
// Queue system: find the leftmost available position
var targetPosition = null;
for (var i = 0; i < customerPositions.length; i++) {
var positionTaken = false;
for (var j = 0; j < customers.length; j++) {
if (Math.abs(customers[j].x - customerPositions[i].x) < 50) {
positionTaken = true;
break;
}
}
if (!positionTaken) {
targetPosition = customerPositions[i];
break; // Take the first available position (leftmost)
}
}
if (!targetPosition) return;
// Randomly select customer type (1, 2, or 3)
var customerType = Math.floor(Math.random() * 3) + 1;
var customer = game.addChild(new Customer(customerType));
customer.x = targetPosition.x;
customer.y = targetPosition.y;
customer.alpha = 0;
customers.push(customer);
// Animate customer entrance
tween(customer, {
alpha: 1,
y: targetPosition.y - 50
}, {
duration: 500
});
}
function removeCustomer(customer) {
var index = customers.indexOf(customer);
if (index > -1) {
customers.splice(index, 1);
customer.destroy();
// Move remaining customers forward in queue
moveCustomersForward();
}
}
function moveCustomersForward() {
// Sort customers by their current x position
customers.sort(function (a, b) {
return a.x - b.x;
});
// Move each customer to the next available position from left to right
for (var i = 0; i < customers.length; i++) {
var targetX = customerPositions[i].x;
if (Math.abs(customers[i].x - targetX) > 10) {
// Animate customer moving to new position
tween(customers[i], {
x: targetX
}, {
duration: 300
});
}
}
}
// Game update loop
game.update = function () {
// Update score display
scoreTxt.setText('Score: ' + LK.getScore());
// Check game over condition
if (LK.getScore() < 0) {
LK.showGameOver();
return;
}
// Spawn customers
customerSpawnTimer++;
if (customerSpawnTimer >= spawnRate) {
spawnCustomer();
customerSpawnTimer = 0;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 1800) {
// Every 30 seconds
spawnRate = Math.max(60, spawnRate - 20); // Minimum 1 second between spawns
difficultyTimer = 0;
}
// Update customers
for (var i = customers.length - 1; i >= 0; i--) {
customers[i].update();
}
};
// Display tutorial message at game start
var tutorialText = new Text2('To give items to customers, first click on the item, then click on the customer.', {
size: 80,
fill: 0xffffff,
font: "Impact, 'Arial Black', Tahoma, Verdana, sans-serif"
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 2048 / 2;
tutorialText.y = 1200;
game.addChild(tutorialText);
// Show tutorial message briefly then fade out
tween(tutorialText, {
alpha: 0
}, {
duration: 3000,
onFinish: function onFinish() {
tutorialText.destroy();
}
});
// Initialize game state
LK.setScore(50); // Start with some buffer score;
pixelart, up side stone, down side plank, top down. In-Game asset. 2d. High contrast. No shadows
plank, pixelart. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pixelart, bar, green. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pixelart, bar, red. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pixelart, man, half, villager. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bench,plank,pixelart. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pixelart, woman, half, villager. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
basket, top down, pixelart. In-Game asset. 2d. High contrast. No shadows
apple, pixelart. In-Game asset. 2d. High contrast. No shadows
Bread, pixelart. In-Game asset. 2d. High contrast. No shadows
cat human, pixel art, half, adventurer. In-Game asset. 2d. High contrast. No shadows
speek bubble, pixel arth.
Cheese, pixelart. In-Game asset. 2d. High contrast. No shadows
egg,pixelart. In-Game asset. 2d. High contrast. No shadows
milk bucketi pixel art. In-Game asset. 2d. High contrast. No shadows
yogurt bucket, pixelart. In-Game asset. 2d. High contrast. No shadows
iron bucket, pixelart, water. In-Game asset. 2d. High contrast. No shadows