Code edit (1 edits merged)
Please save this source code
User prompt
Karaoke Star
Initial prompt
Toca singing (2015). Hold the mic 🎤 up neatly and then you try. Sing the sun has go his hat on and sing along with ginger 🐱, press the French button or the Spanish button to make ginger 🐱 sing in 2 different ways.
/**** * 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;