/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ginger = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('ginger', {
anchorX: 0.5,
anchorY: 1.0
});
var head = self.attachAsset('gingerHead', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -350
});
var mic = self.attachAsset('micIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: -150,
rotation: 0.3
});
var micTop = self.attachAsset('micTop', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: -250
});
self.animationTimer = 0;
self.update = function () {
self.animationTimer += 1;
head.y = -350 + Math.sin(self.animationTimer * 0.1) * 10;
mic.rotation = 0.3 + Math.sin(self.animationTimer * 0.15) * 0.2;
};
self.celebrate = function () {
tween(head, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut
});
tween(head, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeIn
});
};
return self;
});
var LanguageButton = Container.expand(function (language, displayText) {
var self = Container.call(this);
var button = self.attachAsset('languageButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(displayText, {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.language = language;
self.isSelected = false;
self.setSelected = function (selected) {
self.isSelected = selected;
if (selected) {
button.tint = 0x2980b9;
buttonText.fill = "#f1c40f";
} else {
button.tint = 0x3498db;
buttonText.fill = "#ffffff";
}
};
self.down = function (x, y, obj) {
if (gameState === 'languageSelect') {
selectedLanguage = self.language;
updateLanguageButtons();
LK.getSound('ding').play();
}
};
return self;
});
var VolumeVisualizer = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('volumeBar', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
var indicator = self.attachAsset('volumeIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
self.updateVolume = function (volume) {
var barWidth = 380;
var position = volume * barWidth - barWidth / 2;
indicator.x = Math.max(-190, Math.min(190, position));
if (volume > 0.3) {
indicator.tint = 0x27ae60;
} else if (volume > 0.1) {
indicator.tint = 0xf39c12;
} else {
indicator.tint = 0xe74c3c;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x9b59b6
});
/****
* Game Code
****/
var gameState = 'start'; // 'start', 'languageSelect', 'singing', 'completed'
var selectedLanguage = 'english';
var ginger;
var languageButtons = [];
var startButton;
var volumeVisualizer;
var lyricsText;
var instructionText;
var scoreText;
var currentScore = 0;
var singingTimer = 0;
var songDuration = 10000; // 10 seconds for demo
var minVolumeThreshold = 0.1;
var goodVolumeThreshold = 0.3;
// Song lyrics in different languages
var lyrics = {
english: ["The sun has got his hat on", "Hip-hip-hip hooray!", "The sun has got his hat on", "And he's coming out today!"],
french: ["Le soleil a mis son chapeau", "Hip-hip-hip hourra!", "Le soleil a mis son chapeau", "Et il sort aujourd'hui!"],
spanish: ["El sol se ha puesto su sombrero", "¡Hip-hip-hip hurra!", "El sol se ha puesto su sombrero", "¡Y sale hoy!"]
};
var currentLyricIndex = 0;
var lyricTimer = 0;
var lyricDuration = 2500; // 2.5 seconds per line
// Initialize UI elements
function initializeGame() {
// Create Ginger character
ginger = game.addChild(new Ginger());
ginger.x = 1024;
ginger.y = 1800;
ginger.visible = false;
// Create language buttons
var englishBtn = game.addChild(new LanguageButton('english', 'English'));
englishBtn.x = 1024;
englishBtn.y = 1200;
englishBtn.visible = false;
languageButtons.push(englishBtn);
var frenchBtn = game.addChild(new LanguageButton('french', 'Français'));
frenchBtn.x = 1024;
frenchBtn.y = 1350;
frenchBtn.visible = false;
languageButtons.push(frenchBtn);
var spanishBtn = game.addChild(new LanguageButton('spanish', 'Español'));
spanishBtn.x = 1024;
spanishBtn.y = 1500;
spanishBtn.visible = false;
languageButtons.push(spanishBtn);
// Create start button
var startButtonShape = LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
startButton = game.addChild(startButtonShape);
startButton.x = 1024;
startButton.y = 1400;
var startText = new Text2('TAP TO START SINGING!', {
size: 50,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startButton.addChild(startText);
// Create volume visualizer
volumeVisualizer = game.addChild(new VolumeVisualizer());
volumeVisualizer.x = 1024;
volumeVisualizer.y = 2200;
volumeVisualizer.visible = false;
// Create text elements
lyricsText = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
lyricsText.anchor.set(0.5, 0.5);
game.addChild(lyricsText);
lyricsText.x = 1024;
lyricsText.y = 1000;
lyricsText.visible = false;
instructionText = new Text2('Hold your device like a microphone and sing!', {
size: 60,
fill: 0xF1C40F
});
instructionText.anchor.set(0.5, 0.5);
game.addChild(instructionText);
instructionText.x = 1024;
instructionText.y = 500;
instructionText.visible = false;
// Create score display
scoreText = new Text2('Score: 0', {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
scoreText.y = 100;
}
function updateLanguageButtons() {
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].setSelected(languageButtons[i].language === selectedLanguage);
}
}
function startLanguageSelection() {
gameState = 'languageSelect';
startButton.visible = false;
ginger.visible = true;
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].visible = true;
}
updateLanguageButtons();
instructionText.setText('Choose your language:');
instructionText.visible = true;
}
function startSinging() {
gameState = 'singing';
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].visible = false;
}
volumeVisualizer.visible = true;
lyricsText.visible = true;
instructionText.setText('Hold your device like a microphone and sing!');
currentLyricIndex = 0;
lyricTimer = 0;
singingTimer = 0;
currentScore = 0;
updateLyrics();
LK.playMusic('backgroundMusic');
}
function updateLyrics() {
var currentLyrics = lyrics[selectedLanguage];
if (currentLyricIndex < currentLyrics.length) {
lyricsText.setText(currentLyrics[currentLyricIndex]);
// Animate lyrics appearance
lyricsText.alpha = 0;
tween(lyricsText, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
}
}
function completeSong() {
gameState = 'completed';
lyricsText.setText('Great performance!');
instructionText.setText('Tap to sing again!');
volumeVisualizer.visible = false;
ginger.celebrate();
LK.getSound('applause').play();
LK.stopMusic();
// Save high score
var highScore = storage.highScore || 0;
if (currentScore > highScore) {
storage.highScore = currentScore;
}
LK.setTimeout(function () {
gameState = 'start';
startButton.visible = true;
lyricsText.visible = false;
instructionText.visible = false;
ginger.visible = false;
}, 3000);
}
// Initialize the game
initializeGame();
// Start button click handler
startButton.down = function (x, y, obj) {
if (gameState === 'start') {
startLanguageSelection();
LK.getSound('ding').play();
} else if (gameState === 'completed') {
startLanguageSelection();
LK.getSound('ding').play();
}
};
// Continue button for language selection
game.down = function (x, y, obj) {
if (gameState === 'languageSelect' && selectedLanguage) {
startSinging();
}
};
// Main game loop
game.update = function () {
if (gameState === 'singing') {
singingTimer += 16; // Assuming 60 FPS
lyricTimer += 16;
// Update volume visualization
var volume = facekit.volume || 0;
volumeVisualizer.updateVolume(volume);
// Award points for singing
if (volume > minVolumeThreshold) {
if (volume > goodVolumeThreshold) {
currentScore += 3; // More points for louder singing
} else {
currentScore += 1;
}
LK.setScore(currentScore);
scoreText.setText('Score: ' + currentScore);
}
// Update lyrics
if (lyricTimer >= lyricDuration) {
lyricTimer = 0;
currentLyricIndex++;
if (currentLyricIndex < lyrics[selectedLanguage].length) {
updateLyrics();
} else {
// Song completed
completeSong();
}
}
// Check if song duration is complete
if (singingTimer >= songDuration) {
completeSong();
}
}
};
// Show initial instruction
instructionText.setText('Welcome to Karaoke Star!');
instructionText.visible = true; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ginger = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('ginger', {
anchorX: 0.5,
anchorY: 1.0
});
var head = self.attachAsset('gingerHead', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -350
});
var mic = self.attachAsset('micIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: -150,
rotation: 0.3
});
var micTop = self.attachAsset('micTop', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: -250
});
self.animationTimer = 0;
self.update = function () {
self.animationTimer += 1;
head.y = -350 + Math.sin(self.animationTimer * 0.1) * 10;
mic.rotation = 0.3 + Math.sin(self.animationTimer * 0.15) * 0.2;
};
self.celebrate = function () {
tween(head, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut
});
tween(head, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeIn
});
};
return self;
});
var LanguageButton = Container.expand(function (language, displayText) {
var self = Container.call(this);
var button = self.attachAsset('languageButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(displayText, {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.language = language;
self.isSelected = false;
self.setSelected = function (selected) {
self.isSelected = selected;
if (selected) {
button.tint = 0x2980b9;
buttonText.fill = "#f1c40f";
} else {
button.tint = 0x3498db;
buttonText.fill = "#ffffff";
}
};
self.down = function (x, y, obj) {
if (gameState === 'languageSelect') {
selectedLanguage = self.language;
updateLanguageButtons();
LK.getSound('ding').play();
}
};
return self;
});
var VolumeVisualizer = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('volumeBar', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
var indicator = self.attachAsset('volumeIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
self.updateVolume = function (volume) {
var barWidth = 380;
var position = volume * barWidth - barWidth / 2;
indicator.x = Math.max(-190, Math.min(190, position));
if (volume > 0.3) {
indicator.tint = 0x27ae60;
} else if (volume > 0.1) {
indicator.tint = 0xf39c12;
} else {
indicator.tint = 0xe74c3c;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x9b59b6
});
/****
* Game Code
****/
var gameState = 'start'; // 'start', 'languageSelect', 'singing', 'completed'
var selectedLanguage = 'english';
var ginger;
var languageButtons = [];
var startButton;
var volumeVisualizer;
var lyricsText;
var instructionText;
var scoreText;
var currentScore = 0;
var singingTimer = 0;
var songDuration = 10000; // 10 seconds for demo
var minVolumeThreshold = 0.1;
var goodVolumeThreshold = 0.3;
// Song lyrics in different languages
var lyrics = {
english: ["The sun has got his hat on", "Hip-hip-hip hooray!", "The sun has got his hat on", "And he's coming out today!"],
french: ["Le soleil a mis son chapeau", "Hip-hip-hip hourra!", "Le soleil a mis son chapeau", "Et il sort aujourd'hui!"],
spanish: ["El sol se ha puesto su sombrero", "¡Hip-hip-hip hurra!", "El sol se ha puesto su sombrero", "¡Y sale hoy!"]
};
var currentLyricIndex = 0;
var lyricTimer = 0;
var lyricDuration = 2500; // 2.5 seconds per line
// Initialize UI elements
function initializeGame() {
// Create Ginger character
ginger = game.addChild(new Ginger());
ginger.x = 1024;
ginger.y = 1800;
ginger.visible = false;
// Create language buttons
var englishBtn = game.addChild(new LanguageButton('english', 'English'));
englishBtn.x = 1024;
englishBtn.y = 1200;
englishBtn.visible = false;
languageButtons.push(englishBtn);
var frenchBtn = game.addChild(new LanguageButton('french', 'Français'));
frenchBtn.x = 1024;
frenchBtn.y = 1350;
frenchBtn.visible = false;
languageButtons.push(frenchBtn);
var spanishBtn = game.addChild(new LanguageButton('spanish', 'Español'));
spanishBtn.x = 1024;
spanishBtn.y = 1500;
spanishBtn.visible = false;
languageButtons.push(spanishBtn);
// Create start button
var startButtonShape = LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
startButton = game.addChild(startButtonShape);
startButton.x = 1024;
startButton.y = 1400;
var startText = new Text2('TAP TO START SINGING!', {
size: 50,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startButton.addChild(startText);
// Create volume visualizer
volumeVisualizer = game.addChild(new VolumeVisualizer());
volumeVisualizer.x = 1024;
volumeVisualizer.y = 2200;
volumeVisualizer.visible = false;
// Create text elements
lyricsText = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
lyricsText.anchor.set(0.5, 0.5);
game.addChild(lyricsText);
lyricsText.x = 1024;
lyricsText.y = 1000;
lyricsText.visible = false;
instructionText = new Text2('Hold your device like a microphone and sing!', {
size: 60,
fill: 0xF1C40F
});
instructionText.anchor.set(0.5, 0.5);
game.addChild(instructionText);
instructionText.x = 1024;
instructionText.y = 500;
instructionText.visible = false;
// Create score display
scoreText = new Text2('Score: 0', {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
scoreText.y = 100;
}
function updateLanguageButtons() {
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].setSelected(languageButtons[i].language === selectedLanguage);
}
}
function startLanguageSelection() {
gameState = 'languageSelect';
startButton.visible = false;
ginger.visible = true;
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].visible = true;
}
updateLanguageButtons();
instructionText.setText('Choose your language:');
instructionText.visible = true;
}
function startSinging() {
gameState = 'singing';
for (var i = 0; i < languageButtons.length; i++) {
languageButtons[i].visible = false;
}
volumeVisualizer.visible = true;
lyricsText.visible = true;
instructionText.setText('Hold your device like a microphone and sing!');
currentLyricIndex = 0;
lyricTimer = 0;
singingTimer = 0;
currentScore = 0;
updateLyrics();
LK.playMusic('backgroundMusic');
}
function updateLyrics() {
var currentLyrics = lyrics[selectedLanguage];
if (currentLyricIndex < currentLyrics.length) {
lyricsText.setText(currentLyrics[currentLyricIndex]);
// Animate lyrics appearance
lyricsText.alpha = 0;
tween(lyricsText, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
}
}
function completeSong() {
gameState = 'completed';
lyricsText.setText('Great performance!');
instructionText.setText('Tap to sing again!');
volumeVisualizer.visible = false;
ginger.celebrate();
LK.getSound('applause').play();
LK.stopMusic();
// Save high score
var highScore = storage.highScore || 0;
if (currentScore > highScore) {
storage.highScore = currentScore;
}
LK.setTimeout(function () {
gameState = 'start';
startButton.visible = true;
lyricsText.visible = false;
instructionText.visible = false;
ginger.visible = false;
}, 3000);
}
// Initialize the game
initializeGame();
// Start button click handler
startButton.down = function (x, y, obj) {
if (gameState === 'start') {
startLanguageSelection();
LK.getSound('ding').play();
} else if (gameState === 'completed') {
startLanguageSelection();
LK.getSound('ding').play();
}
};
// Continue button for language selection
game.down = function (x, y, obj) {
if (gameState === 'languageSelect' && selectedLanguage) {
startSinging();
}
};
// Main game loop
game.update = function () {
if (gameState === 'singing') {
singingTimer += 16; // Assuming 60 FPS
lyricTimer += 16;
// Update volume visualization
var volume = facekit.volume || 0;
volumeVisualizer.updateVolume(volume);
// Award points for singing
if (volume > minVolumeThreshold) {
if (volume > goodVolumeThreshold) {
currentScore += 3; // More points for louder singing
} else {
currentScore += 1;
}
LK.setScore(currentScore);
scoreText.setText('Score: ' + currentScore);
}
// Update lyrics
if (lyricTimer >= lyricDuration) {
lyricTimer = 0;
currentLyricIndex++;
if (currentLyricIndex < lyrics[selectedLanguage].length) {
updateLyrics();
} else {
// Song completed
completeSong();
}
}
// Check if song duration is complete
if (singingTimer >= songDuration) {
completeSong();
}
}
};
// Show initial instruction
instructionText.setText('Welcome to Karaoke Star!');
instructionText.visible = true;