/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Ingredient class var Ingredient = Container.expand(function () { var self = Container.call(this); // Properties: type, assetId self.type = null; self.assetId = null; self.isDragging = false; // Attach asset self.init = function (type, assetId) { self.type = type; self.assetId = assetId; var asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.width = asset.width; self.height = asset.height; // Always set spawnX and spawnY to current position self.spawnX = self.x; self.spawnY = self.y; }; // For drag and drop self.spawnX = 0; self.spawnY = 0; self.down = function (x, y, obj) { self.isDragging = true; dragNode = self; dragOffsetX = x - self.x; dragOffsetY = y - self.y; // Store spawn position if not set if (self.spawnX === 0 && self.spawnY === 0) { self.spawnX = self.x; self.spawnY = self.y; } }; self.up = function (x, y, obj) { self.isDragging = false; }; return self; }); // Order class var Order = Container.expand(function () { var self = Container.call(this); self.recipe = null; // Array of ingredient types self.assetNodes = []; // Attach order visual (plate + ingredients) self.init = function (recipe) { self.recipe = recipe; // Plate visual var plateAsset = self.attachAsset('orderPlate', { anchorX: 0.5, anchorY: 0.5, y: 0 }); // Ingredient visuals (small icons) for (var i = 0; i < recipe.length; i++) { var ingAsset = LK.getAsset(ingredientTypeToAsset[recipe[i]], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, x: -((recipe.length - 1) * 50) / 2 + i * 50, y: -10 }); self.addChild(ingAsset); self.assetNodes.push(ingAsset); } }; return self; }); /**** * Game Variables ****/ // Ingredient types and their asset ids // Plate class var Plate = Container.expand(function () { var self = Container.call(this); self.ingredientTypes = []; // Types of ingredients currently on plate self.ingredientNodes = []; // Ingredient objects on plate // Attach plate asset self.init = function (assetId) { var asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 1.3 }); self.width = asset.width; self.height = asset.height; }; // Add ingredient to plate self.addIngredient = function (ingredient) { if (self.ingredientNodes.length >= maxIngredientsPerPlate) return false; // Prevent adding the same ingredient multiple times if (self.ingredientNodes.indexOf(ingredient) !== -1) return false; // Place ingredient visually on plate ingredient.x = self.x; ingredient.y = self.y - 40 - self.ingredientNodes.length * 55; ingredient.isDragging = false; self.ingredientTypes.push(ingredient.type); self.ingredientNodes.push(ingredient); return true; }; // Remove all ingredients from plate self.clearPlate = function () { for (var i = 0; i < self.ingredientNodes.length; i++) { self.ingredientNodes[i].destroy(); } self.ingredientTypes = []; self.ingredientNodes = []; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ // No title, no description // Always backgroundColor is black backgroundColor: 0x000000 }); /**** * Game Code ****/ // Ingredient types and their asset ids /**** * Game Variables ****/ // --- Asset Initialization (shapes for MVP) --- var ingredientTypes = ['lettuce', 'tomato', 'cheese', 'meat', 'bun', 'bun']; var ingredientTypeToAsset = { 'lettuce': 'lettuceAsset', 'tomato': 'tomatoAsset', 'cheese': 'cheeseAsset', 'meat': 'meatAsset', 'bun': 'bunAsset' }; // Plate asset id var plateAssetId = 'plateAsset'; // Order plate asset id var orderPlateAssetId = 'orderPlate'; // Recipes (each recipe is an array of ingredient types) // Add one more bun to each recipe (top and bottom bun) var recipes = [['bun', 'meat', 'bun'], ['bun', 'lettuce', 'tomato', 'bun'], ['bun', 'cheese', 'meat', 'bun'], ['bun', 'lettuce', 'cheese', 'meat', 'bun'], ['bun', 'tomato', 'lettuce', 'cheese', 'bun'], ['bun', 'meat', 'bun', 'bun'], ['bun', 'lettuce', 'tomato', 'bun', 'bun'], ['bun', 'cheese', 'meat', 'bun', 'bun'], ['bun', 'lettuce', 'cheese', 'meat', 'bun', 'bun'], ['bun', 'tomato', 'lettuce', 'cheese', 'bun', 'bun']]; // Game state var ingredients = []; var plates = []; var orders = []; var currentOrder = null; var dragNode = null; var dragOffsetX = 0; var dragOffsetY = 0; var scoreTxt = null; var timerTxt = null; var timeLeft = 60; // seconds var timerInterval = null; var maxIngredientsPerPlate = 6; var ingredientSpawnY = 2300; var ingredientAreaY = 2300; var plateY = 1850; var orderY = 420; var orderX = 2048 / 2; var gameActive = true; // --- GUI Elements --- scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); timerTxt = new Text2('60', { size: 100, fill: 0xFFFFFF }); timerTxt.anchor.set(0.5, 0); // Move timer a little to the left (e.g. -120px) timerTxt.x = -120; LK.gui.topRight.addChild(timerTxt); // --- Add Background --- // Use a large scale to ensure the background covers the entire game area var background = LK.getAsset('backgroundAsset', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 2048 / 100, scaleY: 2732 / 100 }); // Add background as the first child so it appears behind all other elements game.addChildAt(background, 0); // --- Create Plate --- var plate = new Plate(); plate.init(plateAssetId); plate.x = 2048 / 2; plate.y = plateY; game.addChild(plate); plates.push(plate); // --- Spawn Ingredients --- function spawnIngredients() { // Remove old ingredients for (var i = 0; i < ingredients.length; i++) { ingredients[i].destroy(); } ingredients = []; // Spawn 5 random ingredients var spacing = 2048 / (ingredientTypes.length + 1); for (var i = 0; i < ingredientTypes.length; i++) { var type = ingredientTypes[i]; var ing = new Ingredient(); ing.init(type, ingredientTypeToAsset[type]); ing.x = spacing * (i + 1); ing.y = ingredientAreaY; ing.spawnX = ing.x; ing.spawnY = ing.y; game.addChild(ing); ingredients.push(ing); } } spawnIngredients(); // --- Generate New Order --- function generateOrder() { // Remove old order if (currentOrder) { currentOrder.destroy(); } // Pick a random recipe and clone it to avoid reference mutation var recipe = recipes[Math.floor(Math.random() * recipes.length)]; var recipeClone = []; for (var i = 0; i < recipe.length; i++) { recipeClone.push(recipe[i]); } var order = new Order(); order.init(recipeClone); order.x = orderX; order.y = orderY; game.addChild(order); currentOrder = order; } generateOrder(); // --- Timer --- function startTimer() { timeLeft = 60; timerTxt.setText(timeLeft); if (timerInterval) LK.clearInterval(timerInterval); timerInterval = LK.setInterval(function () { if (!gameActive) return; timeLeft--; timerTxt.setText(timeLeft); if (timeLeft <= 0) { endGame(); } }, 1000); } startTimer(); // --- Score --- function setScore(val) { LK.setScore(val); scoreTxt.setText(val); } setScore(0); // --- Drag and Drop Logic --- function handleMove(x, y, obj) { if (!gameActive) return; if (dragNode && dragNode.isDragging) { dragNode.x = x - dragOffsetX; dragNode.y = y - dragOffsetY; } } game.move = handleMove; game.down = function (x, y, obj) { if (!gameActive) return; // Check if an ingredient is pressed for (var i = 0; i < ingredients.length; i++) { var ing = ingredients[i]; if (pointInObject(x, y, ing)) { ing.down(x, y, obj); return; } } // Check if ingredient on plate is pressed (to allow removing) for (var i = 0; i < plate.ingredientNodes.length; i++) { var ing = plate.ingredientNodes[i]; if (pointInObject(x, y, ing)) { // Remove from plate and respawn in ingredient area plate.ingredientTypes.splice(i, 1); plate.ingredientNodes.splice(i, 1); // Prevent duplicate in ingredient area if (ingredients.indexOf(ing) === -1) { ing.x = ing.spawnX || 2048 / 2; ing.y = ing.spawnY || ingredientAreaY; game.addChild(ing); ingredients.push(ing); } return; } } }; game.up = function (x, y, obj) { if (!gameActive) return; if (dragNode && dragNode.isDragging) { // Check if released over plate if (pointInObject(x, y, plate)) { // Add to plate if not already max and not already present if (plate.ingredientNodes.length < maxIngredientsPerPlate && plate.ingredientNodes.indexOf(dragNode) === -1) { // Remove from ingredient area var idx = ingredients.indexOf(dragNode); if (idx !== -1) ingredients.splice(idx, 1); plate.addIngredient(dragNode); } else { // Snap back to ingredient area dragNode.x = dragNode.spawnX || 2048 / 2; dragNode.y = dragNode.spawnY || ingredientAreaY; } } else { // Snap back to ingredient area dragNode.x = dragNode.spawnX || 2048 / 2; dragNode.y = dragNode.spawnY || ingredientAreaY; } dragNode.isDragging = false; dragNode = null; } }; // --- Serve Button --- var serveBtn = new Text2('SERVE', { size: 100, fill: 0xFFFFFF }); serveBtn.anchor.set(0.5, 0.5); // Attach serve button to GUI (bottom center) serveBtn.x = 0; serveBtn.y = -150; LK.gui.bottom.addChild(serveBtn); serveBtn.down = function (x, y, obj) { if (!gameActive) return; // Check if plate matches order var correct = false; if (currentOrder && arraysEqual(plate.ingredientTypes, currentOrder.recipe)) { correct = true; } if (correct) { setScore(LK.getScore() + 1); LK.effects.flashObject(serveBtn, 0x2ecc71, 400); plate.clearPlate(); generateOrder(); spawnIngredients(); timeLeft = 60; timerTxt.setText(timeLeft); } else { // Penalty: lose 5 seconds timeLeft = Math.max(0, timeLeft - 5); timerTxt.setText(timeLeft); LK.effects.flashObject(serveBtn, 0xe74c3c, 400); if (timeLeft <= 0) { endGame(); } } }; // --- Utility Functions --- function pointInObject(x, y, obj) { // Simple bounding box check var left = obj.x - obj.width / 2; var right = obj.x + obj.width / 2; var top = obj.y - obj.height / 2; var bottom = obj.y + obj.height / 2; return x >= left && x <= right && y >= top && y <= bottom; } function arraysEqual(a, b) { if (!a || !b) return false; if (a.length !== b.length) return false; for (var i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; } function endGame() { gameActive = false; LK.effects.flashScreen(0xe74c3c, 1000); LK.showGameOver(); } // --- Game Update Loop --- game.update = function () { // No per-frame logic needed for MVP }; // --- Attach serve button to GUI (bottom center) --- LK.gui.bottom.addChild(serveBtn);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Ingredient class
var Ingredient = Container.expand(function () {
var self = Container.call(this);
// Properties: type, assetId
self.type = null;
self.assetId = null;
self.isDragging = false;
// Attach asset
self.init = function (type, assetId) {
self.type = type;
self.assetId = assetId;
var asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.width = asset.width;
self.height = asset.height;
// Always set spawnX and spawnY to current position
self.spawnX = self.x;
self.spawnY = self.y;
};
// For drag and drop
self.spawnX = 0;
self.spawnY = 0;
self.down = function (x, y, obj) {
self.isDragging = true;
dragNode = self;
dragOffsetX = x - self.x;
dragOffsetY = y - self.y;
// Store spawn position if not set
if (self.spawnX === 0 && self.spawnY === 0) {
self.spawnX = self.x;
self.spawnY = self.y;
}
};
self.up = function (x, y, obj) {
self.isDragging = false;
};
return self;
});
// Order class
var Order = Container.expand(function () {
var self = Container.call(this);
self.recipe = null; // Array of ingredient types
self.assetNodes = [];
// Attach order visual (plate + ingredients)
self.init = function (recipe) {
self.recipe = recipe;
// Plate visual
var plateAsset = self.attachAsset('orderPlate', {
anchorX: 0.5,
anchorY: 0.5,
y: 0
});
// Ingredient visuals (small icons)
for (var i = 0; i < recipe.length; i++) {
var ingAsset = LK.getAsset(ingredientTypeToAsset[recipe[i]], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
x: -((recipe.length - 1) * 50) / 2 + i * 50,
y: -10
});
self.addChild(ingAsset);
self.assetNodes.push(ingAsset);
}
};
return self;
});
/****
* Game Variables
****/
// Ingredient types and their asset ids
// Plate class
var Plate = Container.expand(function () {
var self = Container.call(this);
self.ingredientTypes = []; // Types of ingredients currently on plate
self.ingredientNodes = []; // Ingredient objects on plate
// Attach plate asset
self.init = function (assetId) {
var asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.3,
scaleY: 1.3
});
self.width = asset.width;
self.height = asset.height;
};
// Add ingredient to plate
self.addIngredient = function (ingredient) {
if (self.ingredientNodes.length >= maxIngredientsPerPlate) return false;
// Prevent adding the same ingredient multiple times
if (self.ingredientNodes.indexOf(ingredient) !== -1) return false;
// Place ingredient visually on plate
ingredient.x = self.x;
ingredient.y = self.y - 40 - self.ingredientNodes.length * 55;
ingredient.isDragging = false;
self.ingredientTypes.push(ingredient.type);
self.ingredientNodes.push(ingredient);
return true;
};
// Remove all ingredients from plate
self.clearPlate = function () {
for (var i = 0; i < self.ingredientNodes.length; i++) {
self.ingredientNodes[i].destroy();
}
self.ingredientTypes = [];
self.ingredientNodes = [];
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
// No title, no description
// Always backgroundColor is black
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Ingredient types and their asset ids
/****
* Game Variables
****/
// --- Asset Initialization (shapes for MVP) ---
var ingredientTypes = ['lettuce', 'tomato', 'cheese', 'meat', 'bun', 'bun'];
var ingredientTypeToAsset = {
'lettuce': 'lettuceAsset',
'tomato': 'tomatoAsset',
'cheese': 'cheeseAsset',
'meat': 'meatAsset',
'bun': 'bunAsset'
};
// Plate asset id
var plateAssetId = 'plateAsset';
// Order plate asset id
var orderPlateAssetId = 'orderPlate';
// Recipes (each recipe is an array of ingredient types)
// Add one more bun to each recipe (top and bottom bun)
var recipes = [['bun', 'meat', 'bun'], ['bun', 'lettuce', 'tomato', 'bun'], ['bun', 'cheese', 'meat', 'bun'], ['bun', 'lettuce', 'cheese', 'meat', 'bun'], ['bun', 'tomato', 'lettuce', 'cheese', 'bun'], ['bun', 'meat', 'bun', 'bun'], ['bun', 'lettuce', 'tomato', 'bun', 'bun'], ['bun', 'cheese', 'meat', 'bun', 'bun'], ['bun', 'lettuce', 'cheese', 'meat', 'bun', 'bun'], ['bun', 'tomato', 'lettuce', 'cheese', 'bun', 'bun']];
// Game state
var ingredients = [];
var plates = [];
var orders = [];
var currentOrder = null;
var dragNode = null;
var dragOffsetX = 0;
var dragOffsetY = 0;
var scoreTxt = null;
var timerTxt = null;
var timeLeft = 60; // seconds
var timerInterval = null;
var maxIngredientsPerPlate = 6;
var ingredientSpawnY = 2300;
var ingredientAreaY = 2300;
var plateY = 1850;
var orderY = 420;
var orderX = 2048 / 2;
var gameActive = true;
// --- GUI Elements ---
scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
timerTxt = new Text2('60', {
size: 100,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0.5, 0);
// Move timer a little to the left (e.g. -120px)
timerTxt.x = -120;
LK.gui.topRight.addChild(timerTxt);
// --- Add Background ---
// Use a large scale to ensure the background covers the entire game area
var background = LK.getAsset('backgroundAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 2048 / 100,
scaleY: 2732 / 100
});
// Add background as the first child so it appears behind all other elements
game.addChildAt(background, 0);
// --- Create Plate ---
var plate = new Plate();
plate.init(plateAssetId);
plate.x = 2048 / 2;
plate.y = plateY;
game.addChild(plate);
plates.push(plate);
// --- Spawn Ingredients ---
function spawnIngredients() {
// Remove old ingredients
for (var i = 0; i < ingredients.length; i++) {
ingredients[i].destroy();
}
ingredients = [];
// Spawn 5 random ingredients
var spacing = 2048 / (ingredientTypes.length + 1);
for (var i = 0; i < ingredientTypes.length; i++) {
var type = ingredientTypes[i];
var ing = new Ingredient();
ing.init(type, ingredientTypeToAsset[type]);
ing.x = spacing * (i + 1);
ing.y = ingredientAreaY;
ing.spawnX = ing.x;
ing.spawnY = ing.y;
game.addChild(ing);
ingredients.push(ing);
}
}
spawnIngredients();
// --- Generate New Order ---
function generateOrder() {
// Remove old order
if (currentOrder) {
currentOrder.destroy();
}
// Pick a random recipe and clone it to avoid reference mutation
var recipe = recipes[Math.floor(Math.random() * recipes.length)];
var recipeClone = [];
for (var i = 0; i < recipe.length; i++) {
recipeClone.push(recipe[i]);
}
var order = new Order();
order.init(recipeClone);
order.x = orderX;
order.y = orderY;
game.addChild(order);
currentOrder = order;
}
generateOrder();
// --- Timer ---
function startTimer() {
timeLeft = 60;
timerTxt.setText(timeLeft);
if (timerInterval) LK.clearInterval(timerInterval);
timerInterval = LK.setInterval(function () {
if (!gameActive) return;
timeLeft--;
timerTxt.setText(timeLeft);
if (timeLeft <= 0) {
endGame();
}
}, 1000);
}
startTimer();
// --- Score ---
function setScore(val) {
LK.setScore(val);
scoreTxt.setText(val);
}
setScore(0);
// --- Drag and Drop Logic ---
function handleMove(x, y, obj) {
if (!gameActive) return;
if (dragNode && dragNode.isDragging) {
dragNode.x = x - dragOffsetX;
dragNode.y = y - dragOffsetY;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameActive) return;
// Check if an ingredient is pressed
for (var i = 0; i < ingredients.length; i++) {
var ing = ingredients[i];
if (pointInObject(x, y, ing)) {
ing.down(x, y, obj);
return;
}
}
// Check if ingredient on plate is pressed (to allow removing)
for (var i = 0; i < plate.ingredientNodes.length; i++) {
var ing = plate.ingredientNodes[i];
if (pointInObject(x, y, ing)) {
// Remove from plate and respawn in ingredient area
plate.ingredientTypes.splice(i, 1);
plate.ingredientNodes.splice(i, 1);
// Prevent duplicate in ingredient area
if (ingredients.indexOf(ing) === -1) {
ing.x = ing.spawnX || 2048 / 2;
ing.y = ing.spawnY || ingredientAreaY;
game.addChild(ing);
ingredients.push(ing);
}
return;
}
}
};
game.up = function (x, y, obj) {
if (!gameActive) return;
if (dragNode && dragNode.isDragging) {
// Check if released over plate
if (pointInObject(x, y, plate)) {
// Add to plate if not already max and not already present
if (plate.ingredientNodes.length < maxIngredientsPerPlate && plate.ingredientNodes.indexOf(dragNode) === -1) {
// Remove from ingredient area
var idx = ingredients.indexOf(dragNode);
if (idx !== -1) ingredients.splice(idx, 1);
plate.addIngredient(dragNode);
} else {
// Snap back to ingredient area
dragNode.x = dragNode.spawnX || 2048 / 2;
dragNode.y = dragNode.spawnY || ingredientAreaY;
}
} else {
// Snap back to ingredient area
dragNode.x = dragNode.spawnX || 2048 / 2;
dragNode.y = dragNode.spawnY || ingredientAreaY;
}
dragNode.isDragging = false;
dragNode = null;
}
};
// --- Serve Button ---
var serveBtn = new Text2('SERVE', {
size: 100,
fill: 0xFFFFFF
});
serveBtn.anchor.set(0.5, 0.5);
// Attach serve button to GUI (bottom center)
serveBtn.x = 0;
serveBtn.y = -150;
LK.gui.bottom.addChild(serveBtn);
serveBtn.down = function (x, y, obj) {
if (!gameActive) return;
// Check if plate matches order
var correct = false;
if (currentOrder && arraysEqual(plate.ingredientTypes, currentOrder.recipe)) {
correct = true;
}
if (correct) {
setScore(LK.getScore() + 1);
LK.effects.flashObject(serveBtn, 0x2ecc71, 400);
plate.clearPlate();
generateOrder();
spawnIngredients();
timeLeft = 60;
timerTxt.setText(timeLeft);
} else {
// Penalty: lose 5 seconds
timeLeft = Math.max(0, timeLeft - 5);
timerTxt.setText(timeLeft);
LK.effects.flashObject(serveBtn, 0xe74c3c, 400);
if (timeLeft <= 0) {
endGame();
}
}
};
// --- Utility Functions ---
function pointInObject(x, y, obj) {
// Simple bounding box check
var left = obj.x - obj.width / 2;
var right = obj.x + obj.width / 2;
var top = obj.y - obj.height / 2;
var bottom = obj.y + obj.height / 2;
return x >= left && x <= right && y >= top && y <= bottom;
}
function arraysEqual(a, b) {
if (!a || !b) return false;
if (a.length !== b.length) return false;
for (var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}
function endGame() {
gameActive = false;
LK.effects.flashScreen(0xe74c3c, 1000);
LK.showGameOver();
}
// --- Game Update Loop ---
game.update = function () {
// No per-frame logic needed for MVP
};
// --- Attach serve button to GUI (bottom center) ---
LK.gui.bottom.addChild(serveBtn);
sandwich bread . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pixel art chedar. In-Game asset. 2d. High contrast. No shadows
pixel art burger paty. In-Game asset. 2d. High contrast. No shadows
tomato slice pixel art. In-Game asset. 2d. High contrast. No shadows
pixel art plate. In-Game asset. 2d. High contrast. No shadows
lettuce pixel art . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Kitchen backround pixel art high resolutiong