/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Plant = Container.expand(function (plantType, x, y) { var self = Container.call(this); self.plantType = plantType; self.isSelected = false; self.soundId = plantType + 'Tune'; // Create pot var pot = self.attachAsset('plantPot', { anchorX: 0.5, anchorY: 1 }); pot.y = 0; // Create stem for carrot and catFace var stem = null; if (plantType === 'carrot' || plantType === 'catFace') { stem = self.attachAsset('stem', { anchorX: 0.5, anchorY: 1 }); stem.y = -10; } // Create flower based on type var flower = self.attachAsset(plantType === 'catSunflower' ? 'sunflower' : plantType === 'catMoonflower' ? 'moonflower' : plantType === 'catUltraTulip' ? 'ultraTulip' : plantType === 'invertedLilyOfValley' ? 'lilyOfValley' : plantType === 'catFace' ? 'catFace' : plantType, { anchorX: 0.5, anchorY: 0.5 }); flower.y = -100; // Apply color inversion for inverted lily of valley if (plantType === 'invertedLilyOfValley') { flower.tint = 0x00ff00; // Invert colors by applying green tint } // Add cat face overlay for cat variants var catFace = null; if (plantType === 'catSunflower' || plantType === 'catMoonflower' || plantType === 'catUltraTulip') { catFace = self.attachAsset('catFace', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); catFace.y = -100; } else if (plantType === 'catFace') { catFace = flower; // Use the flower as the cat face itself catFace.alpha = 1; // Set full opacity } // Create highlight (initially hidden) var highlight = self.attachAsset('selectedHighlight', { anchorX: 0.5, anchorY: 1, alpha: 0 }); highlight.y = 20; // Position the plant self.x = x; self.y = y; self.select = function () { self.isSelected = true; tween(highlight, { alpha: 0.3 }, { duration: 300 }); tween(flower, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200 }); if (catFace) { tween(catFace, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200 }); } }; self.deselect = function () { self.isSelected = false; tween(highlight, { alpha: 0 }, { duration: 300 }); tween(flower, { scaleX: 1, scaleY: 1 }, { duration: 200 }); if (catFace) { tween(catFace, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }; self.playPreview = function () { // Play the sound immediately with better error handling try { var sound = LK.getSound(self.soundId); if (sound && typeof sound.play === 'function') { sound.play(); } } catch (e) { console.log('Sound play error for', self.soundId); } // Visual feedback animation tween(flower, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, onFinish: function onFinish() { tween(flower, { scaleX: self.isSelected ? 1.2 : 1, scaleY: self.isSelected ? 1.2 : 1 }, { duration: 100 }); } }); if (catFace) { tween(catFace, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, onFinish: function onFinish() { tween(catFace, { scaleX: self.isSelected ? 1.2 : 1, scaleY: self.isSelected ? 1.2 : 1 }, { duration: 100 }); } }); } }; self.down = function (x, y, obj) { if (selectedPlants.length < 3 && !self.isSelected) { addPlantToSelection(self); } else if (self.isSelected) { removePlantFromSelection(self); } else { // Just play preview if already at max selection self.playPreview(); } }; return self; }); var ResetButton = Container.expand(function () { var self = Container.call(this); var buttonBg = self.attachAsset('resetButton', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2('RESET', { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.x = 2048 / 2; self.y = 2600; self.down = function (x, y, obj) { resetSelection(); tween(buttonBg, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(buttonBg, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Initialize sound assets for each plant type var plants = []; var selectedPlants = []; var playingIntervals = []; var plantTypes = ['sunflower', 'moonflower', 'lilyOfValley', 'redTulip', 'yellowTulip', 'pinkTulip', 'purpleTulip', 'orangeTulip', 'blueTulip', 'catSunflower', 'catMoonflower', 'invertedLilyOfValley', 'carrot', 'catFace', 'ultraTulip', 'catUltraTulip']; // Create title var titleText = new Text2('Plantbox - Musical Garden', { size: 60, fill: 0x2F4F2F }); titleText.anchor.set(0.5, 0); titleText.x = 2048 / 2; titleText.y = 50; game.addChild(titleText); // Create instruction text var instructionText = new Text2('Tap plants to create your musical garden\n(Select up to 3 plants)', { size: 40, fill: 0x556B2F }); instructionText.anchor.set(0.5, 0); instructionText.x = 2048 / 2; instructionText.y = 140; game.addChild(instructionText); // Create selection counter var selectionText = new Text2('Selected: 0/3', { size: 45, fill: 0x8B4513 }); selectionText.anchor.set(0.5, 0); selectionText.x = 2048 / 2; selectionText.y = 220; game.addChild(selectionText); // Create plants in a flexible grid layout (4 rows: 3,3,3,3) var startX = 400; var startY = 400; var spacingX = 416; var spacingY = 280; for (var i = 0; i < plantTypes.length; i++) { var row = Math.floor(i / 3); var col = i % 3; var x = startX + col * spacingX; var y = startY + row * spacingY; var plant = new Plant(plantTypes[i], x, y); plants.push(plant); game.addChild(plant); } // Create reset button var resetButton = new ResetButton(); game.addChild(resetButton); function addPlantToSelection(plant) { if (selectedPlants.length < 3 && !plant.isSelected) { selectedPlants.push(plant); plant.select(); updateSelectionDisplay(); startPlantMusic(); } } function removePlantFromSelection(plant) { var index = selectedPlants.indexOf(plant); if (index > -1) { selectedPlants.splice(index, 1); plant.deselect(); updateSelectionDisplay(); startPlantMusic(); } } function resetSelection() { for (var i = 0; i < selectedPlants.length; i++) { selectedPlants[i].deselect(); } selectedPlants = []; updateSelectionDisplay(); stopAllMusic(); } function updateSelectionDisplay() { selectionText.setText('Selected: ' + selectedPlants.length + '/3'); } function stopAllMusic() { for (var i = 0; i < playingIntervals.length; i++) { LK.clearInterval(playingIntervals[i]); } playingIntervals = []; } function startPlantMusic() { stopAllMusic(); if (selectedPlants.length > 0) { // Play all sounds immediately first for (var i = 0; i < selectedPlants.length; i++) { var sound = LK.getSound(selectedPlants[i].soundId); if (sound) { sound.play(); } } // Set up synchronized looping for all plants var mainInterval = LK.setInterval(function () { for (var j = 0; j < selectedPlants.length; j++) { var sound = LK.getSound(selectedPlants[j].soundId); if (sound) { sound.play(); } } }, 1000); // Consistent 1 second loop for all plants playingIntervals.push(mainInterval); } } game.update = function () { // Game updates handled by individual components };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Plant = Container.expand(function (plantType, x, y) {
var self = Container.call(this);
self.plantType = plantType;
self.isSelected = false;
self.soundId = plantType + 'Tune';
// Create pot
var pot = self.attachAsset('plantPot', {
anchorX: 0.5,
anchorY: 1
});
pot.y = 0;
// Create stem for carrot and catFace
var stem = null;
if (plantType === 'carrot' || plantType === 'catFace') {
stem = self.attachAsset('stem', {
anchorX: 0.5,
anchorY: 1
});
stem.y = -10;
}
// Create flower based on type
var flower = self.attachAsset(plantType === 'catSunflower' ? 'sunflower' : plantType === 'catMoonflower' ? 'moonflower' : plantType === 'catUltraTulip' ? 'ultraTulip' : plantType === 'invertedLilyOfValley' ? 'lilyOfValley' : plantType === 'catFace' ? 'catFace' : plantType, {
anchorX: 0.5,
anchorY: 0.5
});
flower.y = -100;
// Apply color inversion for inverted lily of valley
if (plantType === 'invertedLilyOfValley') {
flower.tint = 0x00ff00; // Invert colors by applying green tint
}
// Add cat face overlay for cat variants
var catFace = null;
if (plantType === 'catSunflower' || plantType === 'catMoonflower' || plantType === 'catUltraTulip') {
catFace = self.attachAsset('catFace', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
catFace.y = -100;
} else if (plantType === 'catFace') {
catFace = flower; // Use the flower as the cat face itself
catFace.alpha = 1; // Set full opacity
}
// Create highlight (initially hidden)
var highlight = self.attachAsset('selectedHighlight', {
anchorX: 0.5,
anchorY: 1,
alpha: 0
});
highlight.y = 20;
// Position the plant
self.x = x;
self.y = y;
self.select = function () {
self.isSelected = true;
tween(highlight, {
alpha: 0.3
}, {
duration: 300
});
tween(flower, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
if (catFace) {
tween(catFace, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
}
};
self.deselect = function () {
self.isSelected = false;
tween(highlight, {
alpha: 0
}, {
duration: 300
});
tween(flower, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
if (catFace) {
tween(catFace, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
};
self.playPreview = function () {
// Play the sound immediately with better error handling
try {
var sound = LK.getSound(self.soundId);
if (sound && typeof sound.play === 'function') {
sound.play();
}
} catch (e) {
console.log('Sound play error for', self.soundId);
}
// Visual feedback animation
tween(flower, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(flower, {
scaleX: self.isSelected ? 1.2 : 1,
scaleY: self.isSelected ? 1.2 : 1
}, {
duration: 100
});
}
});
if (catFace) {
tween(catFace, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(catFace, {
scaleX: self.isSelected ? 1.2 : 1,
scaleY: self.isSelected ? 1.2 : 1
}, {
duration: 100
});
}
});
}
};
self.down = function (x, y, obj) {
if (selectedPlants.length < 3 && !self.isSelected) {
addPlantToSelection(self);
} else if (self.isSelected) {
removePlantFromSelection(self);
} else {
// Just play preview if already at max selection
self.playPreview();
}
};
return self;
});
var ResetButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('resetButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2('RESET', {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.x = 2048 / 2;
self.y = 2600;
self.down = function (x, y, obj) {
resetSelection();
tween(buttonBg, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(buttonBg, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Initialize sound assets for each plant type
var plants = [];
var selectedPlants = [];
var playingIntervals = [];
var plantTypes = ['sunflower', 'moonflower', 'lilyOfValley', 'redTulip', 'yellowTulip', 'pinkTulip', 'purpleTulip', 'orangeTulip', 'blueTulip', 'catSunflower', 'catMoonflower', 'invertedLilyOfValley', 'carrot', 'catFace', 'ultraTulip', 'catUltraTulip'];
// Create title
var titleText = new Text2('Plantbox - Musical Garden', {
size: 60,
fill: 0x2F4F2F
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 50;
game.addChild(titleText);
// Create instruction text
var instructionText = new Text2('Tap plants to create your musical garden\n(Select up to 3 plants)', {
size: 40,
fill: 0x556B2F
});
instructionText.anchor.set(0.5, 0);
instructionText.x = 2048 / 2;
instructionText.y = 140;
game.addChild(instructionText);
// Create selection counter
var selectionText = new Text2('Selected: 0/3', {
size: 45,
fill: 0x8B4513
});
selectionText.anchor.set(0.5, 0);
selectionText.x = 2048 / 2;
selectionText.y = 220;
game.addChild(selectionText);
// Create plants in a flexible grid layout (4 rows: 3,3,3,3)
var startX = 400;
var startY = 400;
var spacingX = 416;
var spacingY = 280;
for (var i = 0; i < plantTypes.length; i++) {
var row = Math.floor(i / 3);
var col = i % 3;
var x = startX + col * spacingX;
var y = startY + row * spacingY;
var plant = new Plant(plantTypes[i], x, y);
plants.push(plant);
game.addChild(plant);
}
// Create reset button
var resetButton = new ResetButton();
game.addChild(resetButton);
function addPlantToSelection(plant) {
if (selectedPlants.length < 3 && !plant.isSelected) {
selectedPlants.push(plant);
plant.select();
updateSelectionDisplay();
startPlantMusic();
}
}
function removePlantFromSelection(plant) {
var index = selectedPlants.indexOf(plant);
if (index > -1) {
selectedPlants.splice(index, 1);
plant.deselect();
updateSelectionDisplay();
startPlantMusic();
}
}
function resetSelection() {
for (var i = 0; i < selectedPlants.length; i++) {
selectedPlants[i].deselect();
}
selectedPlants = [];
updateSelectionDisplay();
stopAllMusic();
}
function updateSelectionDisplay() {
selectionText.setText('Selected: ' + selectedPlants.length + '/3');
}
function stopAllMusic() {
for (var i = 0; i < playingIntervals.length; i++) {
LK.clearInterval(playingIntervals[i]);
}
playingIntervals = [];
}
function startPlantMusic() {
stopAllMusic();
if (selectedPlants.length > 0) {
// Play all sounds immediately first
for (var i = 0; i < selectedPlants.length; i++) {
var sound = LK.getSound(selectedPlants[i].soundId);
if (sound) {
sound.play();
}
}
// Set up synchronized looping for all plants
var mainInterval = LK.setInterval(function () {
for (var j = 0; j < selectedPlants.length; j++) {
var sound = LK.getSound(selectedPlants[j].soundId);
if (sound) {
sound.play();
}
}
}, 1000); // Consistent 1 second loop for all plants
playingIntervals.push(mainInterval);
}
}
game.update = function () {
// Game updates handled by individual components
};
Tulip, blue. In-Game asset. 2d. High contrast. No shadows
Red tulip. In-Game asset. 2d. High contrast. No shadows
Orange tulip. In-Game asset. 2d. High contrast. No shadows
Yellow Tulip. In-Game asset. 2d. High contrast. No shadows
Sunflower. In-Game asset. 2d. High contrast. No shadows
Sunflower, but no petals and gray pollen holder. In-Game asset. 2d. High contrast. No shadows
Lily of the Valley. In-Game asset. 2d. High contrast. No shadows
Pink tulip. In-Game asset. 2d. High contrast. No shadows
Purple tulip. In-Game asset. 2d. High contrast. No shadows
Face of a cat. In-Game asset. 2d. High contrast. No shadows
🥕. In-Game asset. 2d. High contrast. No shadows
Rainbow tulip. In-Game asset. 2d. High contrast. No shadows
sunflowerTune
Sound effect
moonflowerTune
Sound effect
lilyOfValleyTune
Sound effect
redTulipTune
Sound effect
yellowTulipTune
Sound effect
pinkTulipTune
Sound effect
purpleTulipTune
Sound effect
orangeTulipTune
Sound effect
blueTulipTune
Sound effect
catSunflowerTune
Sound effect
catMoonflowerTune
Sound effect
invertedLilyOfValleyTune
Sound effect
emoji1Tune
Sound effect
emoji2Tune
Sound effect
emoji3Tune
Sound effect
emoji4Tune
Sound effect
emoji5Tune
Sound effect
carrotTune
Sound effect
catFaceTune
Sound effect
ultraTulipTune
Sound effect
catUltraTulipTune
Sound effect