/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var CategoryButton = Container.expand(function (categoryName, x, y) { var self = Container.call(this); self.categoryName = categoryName; var bg = self.attachAsset('categoryButton', { anchorX: 0.5, anchorY: 0.5 }); var label = new Text2(categoryName, { size: 30, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); self.x = x; self.y = y; self.down = function (x, y, obj) { currentCategory = self.categoryName; updatePartSelection(); LK.getSound('select').play(); // Visual feedback tween(bg, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); tween(bg, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; return self; }); var ColorPicker = Container.expand(function (color, x, y) { var self = Container.call(this); self.color = color; var colorSwatch = self.attachAsset('colorButton', { anchorX: 0.5, anchorY: 0.5, tint: color }); self.x = x; self.y = y; self.down = function (x, y, obj) { selectedColor = self.color; LK.getSound('select').play(); // Visual feedback tween(colorSwatch, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); tween(colorSwatch, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); }; return self; }); var LabubuPart = Container.expand(function (partType, assetId) { var self = Container.call(this); self.partType = partType; self.assetId = assetId; self.isDragging = false; self.originalX = 0; self.originalY = 0; var graphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.setOriginalPosition = function (x, y) { self.originalX = x; self.originalY = y; self.x = x; self.y = y; }; self.down = function (x, y, obj) { self.isDragging = true; draggedPart = self; LK.getSound('select').play(); }; return self; }); var PartSelector = Container.expand(function (partType, assetId, x, y) { var self = Container.call(this); self.partType = partType; self.assetId = assetId; var bg = self.attachAsset('partButton', { anchorX: 0.5, anchorY: 0.5 }); var preview = LK.getAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); self.addChild(preview); self.x = x; self.y = y; self.down = function (x, y, obj) { selectedPart = self; LK.getSound('select').play(); // Visual feedback tween(bg, { tint: 0xFFFFFF }, { duration: 200 }); tween(bg, { tint: 0x87CEEB }, { duration: 200 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xF0F8FF }); /**** * Game Code ****/ // Game state variables // Base Labubu body // Eyes options // Mouth options // Ears options // Accessories // UI elements // Sounds var currentCategory = 'eyes'; var selectedPart = null; var selectedColor = 0xFFB6C1; var draggedPart = null; // Labubu parts data var partCategories = { eyes: ['eyes1', 'eyes2', 'eyes3'], mouth: ['mouth1', 'mouth2', 'mouth3'], ears: ['ears1', 'ears2', 'ears3'], accessories: ['hat1', 'bow1', 'glasses1'] }; var colorOptions = [0xFFB6C1, 0xFFE4E1, 0xF0E68C, 0x98FB98, 0x87CEEB, 0xDDA0DD, 0xF5DEB3]; // Current Labubu parts var currentLabubu = { body: null, leftEye: null, rightEye: null, mouth: null, leftEar: null, rightEar: null, accessory: null }; // UI containers var categoryContainer = new Container(); var partContainer = new Container(); var colorContainer = new Container(); var labubuContainer = new Container(); game.addChild(categoryContainer); game.addChild(partContainer); game.addChild(colorContainer); game.addChild(labubuContainer); // Position containers labubuContainer.x = 1024; labubuContainer.y = 1366; // Create title var titleText = new Text2('Labubu Maker', { size: 80, fill: 0x4169E1 }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 100; game.addChild(titleText); // Create Labubu body function createLabubuBody() { currentLabubu.body = LK.getAsset('labubuBody', { anchorX: 0.5, anchorY: 0.5, tint: selectedColor }); labubuContainer.addChild(currentLabubu.body); } // Update part based on current selection function updateLabubuPart(partType, assetId) { var positions = { leftEye: { x: -50, y: -80 }, rightEye: { x: 50, y: -80 }, mouth: { x: 0, y: -20 }, leftEar: { x: -120, y: -160 }, rightEar: { x: 120, y: -160 }, accessory: { x: 0, y: -160 } }; // Remove existing part if (currentLabubu[partType]) { labubuContainer.removeChild(currentLabubu[partType]); } // Add new part if (assetId) { currentLabubu[partType] = LK.getAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); if (positions[partType]) { currentLabubu[partType].x = positions[partType].x; currentLabubu[partType].y = positions[partType].y; } labubuContainer.addChild(currentLabubu[partType]); LK.getSound('place').play(); } } // Create category buttons function createCategoryButtons() { var categories = ['eyes', 'mouth', 'ears', 'accessories']; var startX = 200; var startY = 300; for (var i = 0; i < categories.length; i++) { var button = new CategoryButton(categories[i], startX, startY + i * 120); categoryContainer.addChild(button); } } // Create part selection area function updatePartSelection() { // Clear existing parts partContainer.removeChild(); var parts = partCategories[currentCategory]; if (!parts) return; var startX = 200; var startY = 800; for (var i = 0; i < parts.length; i++) { var x = startX + i % 3 * 120; var y = startY + Math.floor(i / 3) * 120; var selector = new PartSelector(currentCategory, parts[i], x, y); partContainer.addChild(selector); } } // Create color picker function createColorPicker() { var startX = 200; var startY = 1200; for (var i = 0; i < colorOptions.length; i++) { var x = startX + i % 4 * 80; var y = startY + Math.floor(i / 4) * 80; var picker = new ColorPicker(colorOptions[i], x, y); colorContainer.addChild(picker); } } // Initialize game elements createLabubuBody(); createCategoryButtons(); updatePartSelection(); createColorPicker(); // Game event handlers game.move = function (x, y, obj) { if (draggedPart) { var localPos = labubuContainer.toLocal({ x: x, y: y }); // Check if dragging over Labubu area if (Math.abs(localPos.x) < 200 && Math.abs(localPos.y) < 250) { // Determine part type based on drag position var partType = null; if (localPos.y < -140) { partType = localPos.x < 0 ? 'leftEar' : 'rightEar'; } else if (localPos.y < -60) { partType = localPos.x < 0 ? 'leftEye' : 'rightEye'; } else if (localPos.y < 20) { partType = 'mouth'; } else if (localPos.y < -140) { partType = 'accessory'; } if (partType && draggedPart.partType === currentCategory) { // Visual feedback if (currentLabubu.body) { currentLabubu.body.alpha = 0.7; } } } } }; game.up = function (x, y, obj) { if (draggedPart) { var localPos = labubuContainer.toLocal({ x: x, y: y }); // Check if dropped over Labubu area if (Math.abs(localPos.x) < 200 && Math.abs(localPos.y) < 250) { // Determine part type and update var partType = null; if (localPos.y < -140) { partType = localPos.x < 0 ? 'leftEar' : 'rightEar'; } else if (localPos.y < -60) { partType = localPos.x < 0 ? 'leftEye' : 'rightEye'; } else if (localPos.y < 20) { partType = 'mouth'; } else if (localPos.y < -140) { partType = 'accessory'; } if (partType && draggedPart.partType === currentCategory) { updateLabubuPart(partType, draggedPart.assetId); } } // Reset visual feedback if (currentLabubu.body) { currentLabubu.body.alpha = 1.0; } draggedPart = null; } // Handle part selection if (selectedPart) { // Apply part to appropriate Labubu locations if (currentCategory === 'eyes') { updateLabubuPart('leftEye', selectedPart.assetId); updateLabubuPart('rightEye', selectedPart.assetId); } else if (currentCategory === 'ears') { updateLabubuPart('leftEar', selectedPart.assetId); updateLabubuPart('rightEar', selectedPart.assetId); } else if (currentCategory === 'mouth') { updateLabubuPart('mouth', selectedPart.assetId); } else if (currentCategory === 'accessories') { updateLabubuPart('accessory', selectedPart.assetId); } selectedPart = null; } // Handle color selection if (selectedColor !== 0xFFB6C1 && currentLabubu.body) { currentLabubu.body.tint = selectedColor; // Also tint ears if they exist if (currentLabubu.leftEar) currentLabubu.leftEar.tint = selectedColor; if (currentLabubu.rightEar) currentLabubu.rightEar.tint = selectedColor; } }; // Instructions var instructionText = new Text2('Select category, then choose parts!', { size: 40, fill: 0x666666 }); instructionText.anchor.set(0.5, 0); instructionText.x = 1024; instructionText.y = 200; game.addChild(instructionText);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var CategoryButton = Container.expand(function (categoryName, x, y) {
var self = Container.call(this);
self.categoryName = categoryName;
var bg = self.attachAsset('categoryButton', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2(categoryName, {
size: 30,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
currentCategory = self.categoryName;
updatePartSelection();
LK.getSound('select').play();
// Visual feedback
tween(bg, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
tween(bg, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
};
return self;
});
var ColorPicker = Container.expand(function (color, x, y) {
var self = Container.call(this);
self.color = color;
var colorSwatch = self.attachAsset('colorButton', {
anchorX: 0.5,
anchorY: 0.5,
tint: color
});
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
selectedColor = self.color;
LK.getSound('select').play();
// Visual feedback
tween(colorSwatch, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100
});
tween(colorSwatch, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
};
return self;
});
var LabubuPart = Container.expand(function (partType, assetId) {
var self = Container.call(this);
self.partType = partType;
self.assetId = assetId;
self.isDragging = false;
self.originalX = 0;
self.originalY = 0;
var graphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.setOriginalPosition = function (x, y) {
self.originalX = x;
self.originalY = y;
self.x = x;
self.y = y;
};
self.down = function (x, y, obj) {
self.isDragging = true;
draggedPart = self;
LK.getSound('select').play();
};
return self;
});
var PartSelector = Container.expand(function (partType, assetId, x, y) {
var self = Container.call(this);
self.partType = partType;
self.assetId = assetId;
var bg = self.attachAsset('partButton', {
anchorX: 0.5,
anchorY: 0.5
});
var preview = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
self.addChild(preview);
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
selectedPart = self;
LK.getSound('select').play();
// Visual feedback
tween(bg, {
tint: 0xFFFFFF
}, {
duration: 200
});
tween(bg, {
tint: 0x87CEEB
}, {
duration: 200
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xF0F8FF
});
/****
* Game Code
****/
// Game state variables
// Base Labubu body
// Eyes options
// Mouth options
// Ears options
// Accessories
// UI elements
// Sounds
var currentCategory = 'eyes';
var selectedPart = null;
var selectedColor = 0xFFB6C1;
var draggedPart = null;
// Labubu parts data
var partCategories = {
eyes: ['eyes1', 'eyes2', 'eyes3'],
mouth: ['mouth1', 'mouth2', 'mouth3'],
ears: ['ears1', 'ears2', 'ears3'],
accessories: ['hat1', 'bow1', 'glasses1']
};
var colorOptions = [0xFFB6C1, 0xFFE4E1, 0xF0E68C, 0x98FB98, 0x87CEEB, 0xDDA0DD, 0xF5DEB3];
// Current Labubu parts
var currentLabubu = {
body: null,
leftEye: null,
rightEye: null,
mouth: null,
leftEar: null,
rightEar: null,
accessory: null
};
// UI containers
var categoryContainer = new Container();
var partContainer = new Container();
var colorContainer = new Container();
var labubuContainer = new Container();
game.addChild(categoryContainer);
game.addChild(partContainer);
game.addChild(colorContainer);
game.addChild(labubuContainer);
// Position containers
labubuContainer.x = 1024;
labubuContainer.y = 1366;
// Create title
var titleText = new Text2('Labubu Maker', {
size: 80,
fill: 0x4169E1
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 100;
game.addChild(titleText);
// Create Labubu body
function createLabubuBody() {
currentLabubu.body = LK.getAsset('labubuBody', {
anchorX: 0.5,
anchorY: 0.5,
tint: selectedColor
});
labubuContainer.addChild(currentLabubu.body);
}
// Update part based on current selection
function updateLabubuPart(partType, assetId) {
var positions = {
leftEye: {
x: -50,
y: -80
},
rightEye: {
x: 50,
y: -80
},
mouth: {
x: 0,
y: -20
},
leftEar: {
x: -120,
y: -160
},
rightEar: {
x: 120,
y: -160
},
accessory: {
x: 0,
y: -160
}
};
// Remove existing part
if (currentLabubu[partType]) {
labubuContainer.removeChild(currentLabubu[partType]);
}
// Add new part
if (assetId) {
currentLabubu[partType] = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
if (positions[partType]) {
currentLabubu[partType].x = positions[partType].x;
currentLabubu[partType].y = positions[partType].y;
}
labubuContainer.addChild(currentLabubu[partType]);
LK.getSound('place').play();
}
}
// Create category buttons
function createCategoryButtons() {
var categories = ['eyes', 'mouth', 'ears', 'accessories'];
var startX = 200;
var startY = 300;
for (var i = 0; i < categories.length; i++) {
var button = new CategoryButton(categories[i], startX, startY + i * 120);
categoryContainer.addChild(button);
}
}
// Create part selection area
function updatePartSelection() {
// Clear existing parts
partContainer.removeChild();
var parts = partCategories[currentCategory];
if (!parts) return;
var startX = 200;
var startY = 800;
for (var i = 0; i < parts.length; i++) {
var x = startX + i % 3 * 120;
var y = startY + Math.floor(i / 3) * 120;
var selector = new PartSelector(currentCategory, parts[i], x, y);
partContainer.addChild(selector);
}
}
// Create color picker
function createColorPicker() {
var startX = 200;
var startY = 1200;
for (var i = 0; i < colorOptions.length; i++) {
var x = startX + i % 4 * 80;
var y = startY + Math.floor(i / 4) * 80;
var picker = new ColorPicker(colorOptions[i], x, y);
colorContainer.addChild(picker);
}
}
// Initialize game elements
createLabubuBody();
createCategoryButtons();
updatePartSelection();
createColorPicker();
// Game event handlers
game.move = function (x, y, obj) {
if (draggedPart) {
var localPos = labubuContainer.toLocal({
x: x,
y: y
});
// Check if dragging over Labubu area
if (Math.abs(localPos.x) < 200 && Math.abs(localPos.y) < 250) {
// Determine part type based on drag position
var partType = null;
if (localPos.y < -140) {
partType = localPos.x < 0 ? 'leftEar' : 'rightEar';
} else if (localPos.y < -60) {
partType = localPos.x < 0 ? 'leftEye' : 'rightEye';
} else if (localPos.y < 20) {
partType = 'mouth';
} else if (localPos.y < -140) {
partType = 'accessory';
}
if (partType && draggedPart.partType === currentCategory) {
// Visual feedback
if (currentLabubu.body) {
currentLabubu.body.alpha = 0.7;
}
}
}
}
};
game.up = function (x, y, obj) {
if (draggedPart) {
var localPos = labubuContainer.toLocal({
x: x,
y: y
});
// Check if dropped over Labubu area
if (Math.abs(localPos.x) < 200 && Math.abs(localPos.y) < 250) {
// Determine part type and update
var partType = null;
if (localPos.y < -140) {
partType = localPos.x < 0 ? 'leftEar' : 'rightEar';
} else if (localPos.y < -60) {
partType = localPos.x < 0 ? 'leftEye' : 'rightEye';
} else if (localPos.y < 20) {
partType = 'mouth';
} else if (localPos.y < -140) {
partType = 'accessory';
}
if (partType && draggedPart.partType === currentCategory) {
updateLabubuPart(partType, draggedPart.assetId);
}
}
// Reset visual feedback
if (currentLabubu.body) {
currentLabubu.body.alpha = 1.0;
}
draggedPart = null;
}
// Handle part selection
if (selectedPart) {
// Apply part to appropriate Labubu locations
if (currentCategory === 'eyes') {
updateLabubuPart('leftEye', selectedPart.assetId);
updateLabubuPart('rightEye', selectedPart.assetId);
} else if (currentCategory === 'ears') {
updateLabubuPart('leftEar', selectedPart.assetId);
updateLabubuPart('rightEar', selectedPart.assetId);
} else if (currentCategory === 'mouth') {
updateLabubuPart('mouth', selectedPart.assetId);
} else if (currentCategory === 'accessories') {
updateLabubuPart('accessory', selectedPart.assetId);
}
selectedPart = null;
}
// Handle color selection
if (selectedColor !== 0xFFB6C1 && currentLabubu.body) {
currentLabubu.body.tint = selectedColor;
// Also tint ears if they exist
if (currentLabubu.leftEar) currentLabubu.leftEar.tint = selectedColor;
if (currentLabubu.rightEar) currentLabubu.rightEar.tint = selectedColor;
}
};
// Instructions
var instructionText = new Text2('Select category, then choose parts!', {
size: 40,
fill: 0x666666
});
instructionText.anchor.set(0.5, 0);
instructionText.x = 1024;
instructionText.y = 200;
game.addChild(instructionText);
Pink labubu no eyes no ears. In-Game asset. 2d. High contrast. No shadows no hair
Labubu eye. In-Game asset. 2d. High contrast. No shadows oval
Pink rabbit ear. In-Game asset. 2d. High contrast. No shadows
Open happy mouth with round teeth. In-Game asset. 2d. High contrast. No shadows
Screaming mouth. In-Game asset. 2d. High contrast. No shadows
Closed mouth. In-Game asset. 2d. High contrast. No shadows
Fox ear. In-Game asset. 2d. High contrast. No shadows
Dog ear. In-Game asset. 2d. High contrast. No shadows
Glasses. In-Game asset. 2d. High contrast. No shadows
Bow. In-Game asset. 2d. High contrast. No shadows that you can wear for girls
Brown hat. In-Game asset. 2d. High contrast. No shadows