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; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,343 @@
-/****
+/**** 
+* 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: 0x000000
-});
\ No newline at end of file
+	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;
\ No newline at end of file