/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var LanguageButton = Container.expand(function () { var self = Container.call(this); var button = self.attachAsset('languageButton', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); switchLanguage(); }; self.up = function (x, y, obj) { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); }; return self; }); var Microphone = Container.expand(function () { var self = Container.call(this); var micBody = self.attachAsset('microphone', { anchorX: 0.5, anchorY: 1.0 }); var micTop = self.attachAsset('microphoneTop', { anchorX: 0.5, anchorY: 1.0, y: -180 }); self.isHeld = false; self.down = function (x, y, obj) { self.isHeld = true; micHeld = true; tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut }); LK.getSound('chime').play(); }; self.up = function (x, y, obj) { self.isHeld = false; micHeld = false; tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut }); }; return self; }); var RainbowStripe = Container.expand(function () { var self = Container.call(this); var stripe = self.attachAsset('rainbowStripe', { anchorX: 0.5, anchorY: 0.5 }); self.setColor = function (color) { stripe.tint = color; }; self.show = function () { self.alpha = 0; self.scaleX = 0; tween(self, { alpha: 1, scaleX: 1 }, { duration: 500, easing: tween.easeOut }); }; self.hide = function () { tween(self, { alpha: 0, scaleX: 0 }, { duration: 300, easing: tween.easeIn }); }; return self; }); var SingButton = Container.expand(function () { var self = Container.call(this); var button = self.attachAsset('singButton', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut }); startSinging(); }; self.up = function (x, y, obj) { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); }; return self; }); var SulaCharacter = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('sula', { anchorX: 0.5, anchorY: 0.5 }); self.bounce = function () { tween(self, { scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game variables var micHeld = false; var isSinging = false; var currentLanguage = 0; // 0: English, 1: Italian, 2: Spanish var songTimer = 0; var rainbowColors = [0x800080, 0x4B0082, 0x0000FF, 0x008000, 0xFFFF00]; // Purple, Indigo, Blue, Green, Yellow var currentColorIndex = 0; var rainbowStripes = []; var volumeThreshold = 0.2; // Song lyrics in different languages var songLyrics = [["Pretty", "Purple", "Indigo", "Blue", "and", "Green", "and", "Bright", "Yellow"], // English ["Bello", "Viola", "Indaco", "Blu", "e", "Verde", "e", "Giallo", "Brillante"], // Italian ["Bonito", "Morado", "Índigo", "Azul", "y", "Verde", "y", "Amarillo", "Brillante"] // Spanish ]; var languageNames = ["English", "Italiano", "Español"]; // Create UI elements var scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var languageText = new Text2('Language: English', { size: 60, fill: 0xFFFFFF }); languageText.anchor.set(0, 0); languageText.x = 150; languageText.y = 50; LK.gui.topLeft.addChild(languageText); var instructionText = new Text2('Hold microphone and sing with Sula!', { size: 70, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0.5); LK.gui.center.addChild(instructionText); // Create game objects var sula = game.addChild(new SulaCharacter()); sula.x = 1024; sula.y = 800; var microphone = game.addChild(new Microphone()); microphone.x = 1024; microphone.y = 2200; var singButton = game.addChild(new SingButton()); singButton.x = 1024; singButton.y = 1800; var languageButton = game.addChild(new LanguageButton()); languageButton.x = 1024; languageButton.y = 1950; // Create rainbow stripes for (var i = 0; i < 5; i++) { var stripe = game.addChild(new RainbowStripe()); stripe.x = 1024; stripe.y = 1200 + i * 80; stripe.setColor(rainbowColors[i]); stripe.alpha = 0; rainbowStripes.push(stripe); } // Button labels var singButtonText = new Text2('Sing!', { size: 50, fill: 0xFFFFFF }); singButtonText.anchor.set(0.5, 0.5); singButtonText.x = singButton.x; singButtonText.y = singButton.y; game.addChild(singButtonText); var languageButtonText = new Text2('Language', { size: 40, fill: 0xFFFFFF }); languageButtonText.anchor.set(0.5, 0.5); languageButtonText.x = languageButton.x; languageButtonText.y = languageButton.y; game.addChild(languageButtonText); // Game functions function startSinging() { if (!isSinging) { isSinging = true; songTimer = 0; currentColorIndex = 0; instructionText.setText('Sing along: ' + songLyrics[currentLanguage].join(' ')); sula.bounce(); } } function switchLanguage() { currentLanguage = (currentLanguage + 1) % 3; languageText.setText('Language: ' + languageNames[currentLanguage]); LK.getSound('chime').play(); } function showRainbowColor(colorIndex) { if (colorIndex >= 0 && colorIndex < rainbowStripes.length) { rainbowStripes[colorIndex].show(); // Hide after 1 second LK.setTimeout(function () { rainbowStripes[colorIndex].hide(); }, 1000); } } function updateScore() { LK.setScore(LK.getScore() + 10); scoreText.setText('Score: ' + LK.getScore()); } // Main game update loop game.update = function () { if (isSinging && micHeld) { songTimer++; // Show rainbow colors in sequence if (songTimer % 120 === 0 && currentColorIndex < rainbowColors.length) { showRainbowColor(currentColorIndex); currentColorIndex++; sula.bounce(); } // Check for voice input if (facekit.volume > volumeThreshold) { updateScore(); // Create sparkle effect on Sula tween(sula, { scaleX: 1.1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(sula, { scaleX: 1.0 }, { duration: 100, easing: tween.easeIn }); } }); } // End singing sequence after showing all colors if (songTimer > 600) { isSinging = false; songTimer = 0; currentColorIndex = 0; instructionText.setText('Great singing! Press Sing to go again!'); // Hide all rainbow stripes for (var i = 0; i < rainbowStripes.length; i++) { rainbowStripes[i].hide(); } } } // Visual feedback for microphone volume if (micHeld && facekit.volume > 0.1) { var volumeScale = 1.0 + facekit.volume * 0.3; microphone.scaleX = volumeScale; microphone.scaleY = volumeScale; } else if (micHeld) { microphone.scaleX = 1.1; microphone.scaleY = 1.1; } else { microphone.scaleX = 1.0; microphone.scaleY = 1.0; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var LanguageButton = Container.expand(function () {
var self = Container.call(this);
var button = self.attachAsset('languageButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
switchLanguage();
};
self.up = function (x, y, obj) {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
};
return self;
});
var Microphone = Container.expand(function () {
var self = Container.call(this);
var micBody = self.attachAsset('microphone', {
anchorX: 0.5,
anchorY: 1.0
});
var micTop = self.attachAsset('microphoneTop', {
anchorX: 0.5,
anchorY: 1.0,
y: -180
});
self.isHeld = false;
self.down = function (x, y, obj) {
self.isHeld = true;
micHeld = true;
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut
});
LK.getSound('chime').play();
};
self.up = function (x, y, obj) {
self.isHeld = false;
micHeld = false;
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
};
return self;
});
var RainbowStripe = Container.expand(function () {
var self = Container.call(this);
var stripe = self.attachAsset('rainbowStripe', {
anchorX: 0.5,
anchorY: 0.5
});
self.setColor = function (color) {
stripe.tint = color;
};
self.show = function () {
self.alpha = 0;
self.scaleX = 0;
tween(self, {
alpha: 1,
scaleX: 1
}, {
duration: 500,
easing: tween.easeOut
});
};
self.hide = function () {
tween(self, {
alpha: 0,
scaleX: 0
}, {
duration: 300,
easing: tween.easeIn
});
};
return self;
});
var SingButton = Container.expand(function () {
var self = Container.call(this);
var button = self.attachAsset('singButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
startSinging();
};
self.up = function (x, y, obj) {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
};
return self;
});
var SulaCharacter = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('sula', {
anchorX: 0.5,
anchorY: 0.5
});
self.bounce = function () {
tween(self, {
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var micHeld = false;
var isSinging = false;
var currentLanguage = 0; // 0: English, 1: Italian, 2: Spanish
var songTimer = 0;
var rainbowColors = [0x800080, 0x4B0082, 0x0000FF, 0x008000, 0xFFFF00]; // Purple, Indigo, Blue, Green, Yellow
var currentColorIndex = 0;
var rainbowStripes = [];
var volumeThreshold = 0.2;
// Song lyrics in different languages
var songLyrics = [["Pretty", "Purple", "Indigo", "Blue", "and", "Green", "and", "Bright", "Yellow"],
// English
["Bello", "Viola", "Indaco", "Blu", "e", "Verde", "e", "Giallo", "Brillante"],
// Italian
["Bonito", "Morado", "Índigo", "Azul", "y", "Verde", "y", "Amarillo", "Brillante"] // Spanish
];
var languageNames = ["English", "Italiano", "Español"];
// Create UI elements
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var languageText = new Text2('Language: English', {
size: 60,
fill: 0xFFFFFF
});
languageText.anchor.set(0, 0);
languageText.x = 150;
languageText.y = 50;
LK.gui.topLeft.addChild(languageText);
var instructionText = new Text2('Hold microphone and sing with Sula!', {
size: 70,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionText);
// Create game objects
var sula = game.addChild(new SulaCharacter());
sula.x = 1024;
sula.y = 800;
var microphone = game.addChild(new Microphone());
microphone.x = 1024;
microphone.y = 2200;
var singButton = game.addChild(new SingButton());
singButton.x = 1024;
singButton.y = 1800;
var languageButton = game.addChild(new LanguageButton());
languageButton.x = 1024;
languageButton.y = 1950;
// Create rainbow stripes
for (var i = 0; i < 5; i++) {
var stripe = game.addChild(new RainbowStripe());
stripe.x = 1024;
stripe.y = 1200 + i * 80;
stripe.setColor(rainbowColors[i]);
stripe.alpha = 0;
rainbowStripes.push(stripe);
}
// Button labels
var singButtonText = new Text2('Sing!', {
size: 50,
fill: 0xFFFFFF
});
singButtonText.anchor.set(0.5, 0.5);
singButtonText.x = singButton.x;
singButtonText.y = singButton.y;
game.addChild(singButtonText);
var languageButtonText = new Text2('Language', {
size: 40,
fill: 0xFFFFFF
});
languageButtonText.anchor.set(0.5, 0.5);
languageButtonText.x = languageButton.x;
languageButtonText.y = languageButton.y;
game.addChild(languageButtonText);
// Game functions
function startSinging() {
if (!isSinging) {
isSinging = true;
songTimer = 0;
currentColorIndex = 0;
instructionText.setText('Sing along: ' + songLyrics[currentLanguage].join(' '));
sula.bounce();
}
}
function switchLanguage() {
currentLanguage = (currentLanguage + 1) % 3;
languageText.setText('Language: ' + languageNames[currentLanguage]);
LK.getSound('chime').play();
}
function showRainbowColor(colorIndex) {
if (colorIndex >= 0 && colorIndex < rainbowStripes.length) {
rainbowStripes[colorIndex].show();
// Hide after 1 second
LK.setTimeout(function () {
rainbowStripes[colorIndex].hide();
}, 1000);
}
}
function updateScore() {
LK.setScore(LK.getScore() + 10);
scoreText.setText('Score: ' + LK.getScore());
}
// Main game update loop
game.update = function () {
if (isSinging && micHeld) {
songTimer++;
// Show rainbow colors in sequence
if (songTimer % 120 === 0 && currentColorIndex < rainbowColors.length) {
showRainbowColor(currentColorIndex);
currentColorIndex++;
sula.bounce();
}
// Check for voice input
if (facekit.volume > volumeThreshold) {
updateScore();
// Create sparkle effect on Sula
tween(sula, {
scaleX: 1.1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(sula, {
scaleX: 1.0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
// End singing sequence after showing all colors
if (songTimer > 600) {
isSinging = false;
songTimer = 0;
currentColorIndex = 0;
instructionText.setText('Great singing! Press Sing to go again!');
// Hide all rainbow stripes
for (var i = 0; i < rainbowStripes.length; i++) {
rainbowStripes[i].hide();
}
}
}
// Visual feedback for microphone volume
if (micHeld && facekit.volume > 0.1) {
var volumeScale = 1.0 + facekit.volume * 0.3;
microphone.scaleX = volumeScale;
microphone.scaleY = volumeScale;
} else if (micHeld) {
microphone.scaleX = 1.1;
microphone.scaleY = 1.1;
} else {
microphone.scaleX = 1.0;
microphone.scaleY = 1.0;
}
};