User prompt
AmeÌliore le jeu en mettant le fond du jeu en turquoise, en ajoutant plusieurs notes (une suite de notes), pour le choix de la gamme et en ajoutant des effets sonores au jeu âȘđĄ Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Accorder les bots
Initial prompt
CreÌe un jeu nommeÌe "Accorder les bots", dans lequel le but est simple : des bots rouges qui chantent faux pparaissent aleÌatoirement a l'eÌcran, et le joueur doit les accorder en appuyant sur un boutton accorder sous chaque bot, et choisir la bonne gamme correspondant aux notes qui s'affichent pour que le bot devienne vert et dispaisse, en disant qu'il chante juste, si le joueur de trompe, le bot reste rouge et disparaiÌt, un message s'affiche disant que c'est pas la bonne gamme, il y a un systeÌme de niveaux, plus le joueur accorde de bots avec succeÌs, plus il monte en niveaux, le joueur niveau 1 doit accorder 5 bots pour atteindre le niveau 2, et a chaque fois ce nombre double pour passer au niveau suivant.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bot class: represents a singing bot to be tuned var Bot = Container.expand(function () { var self = Container.call(this); // Bot state: 'untuned', 'tuning', 'tuned', 'failed' self.state = 'untuned'; // Randomly pick a sequence of notes and a scale for this bot self.notes = Bot.randomNoteSequence(); self.correctScale = Bot.notesToScale(self.notes); // Timer for tuning (15s) self.tuneTimer = null; self.tuneTimeLeft = 15; self.tuneTimerText = null; // Create bot body (red box for untuned, green for tuned) self.botAsset = self.attachAsset('botBody', { anchorX: 0.5, anchorY: 0.5 }); self.botAsset.tint = 0xd83318; // red // Display the notes above the bot self.noteText = new Text2(self.notes.join(" "), { size: 90, fill: 0xFFFFFF }); self.noteText.anchor.set(0.5, 1); self.noteText.x = 0; self.noteText.y = -self.botAsset.height / 2 - 20; self.addChild(self.noteText); // "Accorder" button under the bot self.tuneBtn = self.attachAsset('tuneBtn', { anchorX: 0.5, anchorY: 0 }); self.tuneBtn.y = self.botAsset.height / 2 + 30; self.tuneBtn.x = 0; self.addChild(self.tuneBtn); // Button label self.tuneBtnLabel = new Text2("Accorder", { size: 60, fill: 0x222222 }); self.tuneBtnLabel.anchor.set(0.5, 0.5); self.tuneBtnLabel.x = self.tuneBtn.x; self.tuneBtnLabel.y = self.tuneBtn.y + self.tuneBtn.height / 2; self.addChild(self.tuneBtnLabel); // When tuning, show scale choices self.scaleBtns = []; self.scaleBtnLabels = []; // Event: press on "Accorder" button self.tuneBtn.down = function (x, y, obj) { if (self.state !== 'untuned') return; LK.getSound('tune_press').play(); self.showScaleChoices(); }; // Show scale choices under the bot self.showScaleChoices = function () { if (self.state !== 'untuned') return; self.state = 'tuning'; // Remove previous scale buttons if any for (var i = 0; i < self.scaleBtns.length; i++) { self.removeChild(self.scaleBtns[i]); self.removeChild(self.scaleBtnLabels[i]); } self.scaleBtns = []; self.scaleBtnLabels = []; // Get 3 scales: correct + 2 random wrong var scales = Bot.getScaleChoices(self.correctScale); for (var i = 0; i < scales.length; i++) { var btn = self.attachAsset('scaleBtn', { anchorX: 0.5, anchorY: 0 }); btn.x = 0 + (i - 1) * (btn.width + 40); btn.y = self.tuneBtn.y + self.tuneBtn.height + 30; self.addChild(btn); var label = new Text2(scales[i], { size: 55, fill: 0x222222 }); label.anchor.set(0.5, 0.5); label.x = btn.x; label.y = btn.y + btn.height / 2; self.addChild(label); // Closure for scale selection (function (scaleName, btnObj) { btn.down = function (x, y, obj) { self.handleScaleChoice(scaleName); }; })(scales[i], btn); self.scaleBtns.push(btn); self.scaleBtnLabels.push(label); } // Show and start 15s timer if (self.tuneTimerText) { self.removeChild(self.tuneTimerText); self.tuneTimerText = null; } self.tuneTimeLeft = 15; self.tuneTimerText = new Text2("15", { size: 70, fill: 0xFFD700 }); self.tuneTimerText.anchor.set(0.5, 0); self.tuneTimerText.x = 0; self.tuneTimerText.y = self.tuneBtn.y + self.tuneBtn.height + 140; self.addChild(self.tuneTimerText); if (self.tuneTimer) { LK.clearInterval(self.tuneTimer); self.tuneTimer = null; } self.tuneTimer = LK.setInterval(function () { if (self.state !== 'tuning') { LK.clearInterval(self.tuneTimer); self.tuneTimer = null; return; } self.tuneTimeLeft--; self.tuneTimerText.setText(self.tuneTimeLeft + ""); if (self.tuneTimeLeft <= 0) { LK.clearInterval(self.tuneTimer); self.tuneTimer = null; // Remove scale buttons for (var i = 0; i < self.scaleBtns.length; i++) { self.removeChild(self.scaleBtns[i]); self.removeChild(self.scaleBtnLabels[i]); } self.scaleBtns = []; self.scaleBtnLabels = []; self.state = 'failed'; self.botAsset.tint = 0xd83318; self.noteText.setText(self.notes.join(" ") + " â"); if (self.tuneTimerText) { self.removeChild(self.tuneTimerText); self.tuneTimerText = null; } // Animate and remove after a short delay tween(self, { alpha: 0 }, { duration: 600, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); onBotTuned(false); } }); } }, 1000); }; // Handle scale choice self.handleScaleChoice = function (chosenScale) { if (self.state !== 'tuning') return; // Stop timer and remove timer text if (self.tuneTimer) { LK.clearInterval(self.tuneTimer); self.tuneTimer = null; } if (self.tuneTimerText) { self.removeChild(self.tuneTimerText); self.tuneTimerText = null; } // Remove scale buttons for (var i = 0; i < self.scaleBtns.length; i++) { self.removeChild(self.scaleBtns[i]); self.removeChild(self.scaleBtnLabels[i]); } self.scaleBtns = []; self.scaleBtnLabels = []; if (chosenScale === self.correctScale) { LK.getSound('tune_success').play(); self.state = 'tuned'; self.botAsset.tint = 0x83de44; // green self.noteText.setText(self.notes.join(" ") + " â"); // Show "Le bot chante juste !" message in the center for 1s showSuccess("Le bot chante juste !"); // Animate and remove after a short delay tween(self, { alpha: 0 }, { duration: 600, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); onBotTuned(true); } }); } else { LK.getSound('tune_fail').play(); self.state = 'failed'; self.botAsset.tint = 0xd83318; // red self.noteText.setText(self.notes.join(" ") + " â"); // Animate and remove after a short delay tween(self, { alpha: 0 }, { duration: 600, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); onBotTuned(false); } }); } }; return self; }); /**** * Initialize Game ****/ // Static: pick a random note var game = new LK.Game({ backgroundColor: 0x000000 // black fallback }); /**** * Game Code ****/ // Add custom background image var backgroundImage = LK.getAsset('customBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(backgroundImage); // Play background music in a loop LK.playMusic('bgmusic', { loop: true }); // End of file; Bot.randomNoteSequence = function () { // Expanded notes: include all 12 chromatic notes var notes = ["C", "C#", "Db", "D", "D#", "Eb", "E", "F", "F#", "Gb", "G", "G#", "Ab", "A", "A#", "Bb", "B"]; var len = 2 + Math.floor(Math.random() * 3); // 2-4 notes var seq = []; for (var i = 0; i < len; i++) { var n = notes[Math.floor(Math.random() * notes.length)]; seq.push(n); } return seq; }; // Map a sequence of notes to a scale (use first note for simplicity, but support more scales) Bot.notesToScale = function (notes) { // Map note to scale name (major/minor, sharps/flats) var note = notes[0]; // Normalize note for mapping var map = { "C": "Do majeur", "C#": "Do# majeur", "Db": "RĂ©b majeur", "D": "RĂ© majeur", "D#": "RĂ©# majeur", "Eb": "Mib majeur", "E": "Mi majeur", "F": "Fa majeur", "F#": "Fa# majeur", "Gb": "Solb majeur", "G": "Sol majeur", "G#": "Sol# majeur", "Ab": "Lab majeur", "A": "La majeur", "A#": "La# majeur", "Bb": "Sib majeur", "B": "Si majeur" }; // Add some minor scales for more variety var minorMap = { "C": "Do mineur", "C#": "Do# mineur", "Db": "RĂ©b mineur", "D": "RĂ© mineur", "D#": "RĂ©# mineur", "Eb": "Mib mineur", "E": "Mi mineur", "F": "Fa mineur", "F#": "Fa# mineur", "Gb": "Solb mineur", "G": "Sol mineur", "G#": "Sol# mineur", "Ab": "Lab mineur", "A": "La mineur", "A#": "La# mineur", "Bb": "Sib mineur", "B": "Si mineur" }; // 50% chance to use minor scale var useMinor = Math.random() < 0.5; if (useMinor && minorMap[note]) return minorMap[note]; return map[note] || "Do majeur"; }; // Static: get 3 scale choices (1 correct, 2 random wrong) from expanded list Bot.getScaleChoices = function (correct) { var all = ["Do majeur", "Do# majeur", "RĂ©b majeur", "RĂ© majeur", "RĂ©# majeur", "Mib majeur", "Mi majeur", "Fa majeur", "Fa# majeur", "Solb majeur", "Sol majeur", "Sol# majeur", "Lab majeur", "La majeur", "La# majeur", "Sib majeur", "Si majeur", "Do mineur", "Do# mineur", "RĂ©b mineur", "RĂ© mineur", "RĂ©# mineur", "Mib mineur", "Mi mineur", "Fa mineur", "Fa# mineur", "Solb mineur", "Sol mineur", "Sol# mineur", "Lab mineur", "La mineur", "La# mineur", "Sib mineur", "Si mineur"]; var choices = [correct]; // Pick 2 random wrong scales var wrong = []; for (var i = 0; i < all.length; i++) { if (all[i] !== correct) wrong.push(all[i]); } for (var i = 0; i < 2; i++) { var idx = Math.floor(Math.random() * wrong.length); choices.push(wrong[idx]); wrong.splice(idx, 1); } // Shuffle for (var i = choices.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var tmp = choices[i]; choices[i] = choices[j]; choices[j] = tmp; } return choices; }; // Game state var bots = []; var level = 1; var botsToTune = 5; var botsTuned = 0; var botsFailed = 0; var maxBotsOnScreen = 3; var isSpawning = true; // Score/level display var scoreTxt = new Text2("Niveau 1\n0/5 bots accordĂ©s", { size: 90, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Error message var errorMsg = new Text2("", { size: 80, fill: 0xFF3333 }); errorMsg.anchor.set(0.5, 0.5); errorMsg.visible = false; LK.gui.center.addChild(errorMsg); // Success message var successMsg = new Text2("", { size: 80, fill: 0x44FF44 }); successMsg.anchor.set(0.5, 0.5); successMsg.visible = false; LK.gui.center.addChild(successMsg); // Show success message for 1s function showSuccess(msg) { successMsg.setText(msg); successMsg.visible = true; tween(successMsg, { alpha: 1 }, { duration: 0 }); LK.setTimeout(function () { tween(successMsg, { alpha: 0 }, { duration: 400, onFinish: function onFinish() { successMsg.visible = false; } }); }, 1000); } // Called when a bot is tuned or failed function onBotTuned(success) { if (success) { botsTuned++; } else { botsFailed++; showError("Mauvaise gamme !"); } updateScoreText(); // Remove from bots array for (var i = bots.length - 1; i >= 0; i--) { if (bots[i].state === 'tuned' || bots[i].state === 'failed') { bots.splice(i, 1); } } // Check level up if (botsTuned >= botsToTune) { nextLevel(); } } // Show error message for 1s function showError(msg) { errorMsg.setText(msg); errorMsg.visible = true; tween(errorMsg, { alpha: 1 }, { duration: 0 }); LK.setTimeout(function () { tween(errorMsg, { alpha: 0 }, { duration: 400, onFinish: function onFinish() { errorMsg.visible = false; } }); }, 1000); } // Update score/level text function updateScoreText() { scoreTxt.setText("Niveau " + level + "\n" + botsTuned + "/" + botsToTune + " bots accordĂ©s"); } // Level up function nextLevel() { level++; botsTuned = 0; botsFailed = 0; botsToTune = botsToTune * 2; updateScoreText(); // Flash green LK.effects.flashScreen(0x83de44, 600); } // Spawn a bot at a random position function spawnBot() { if (!isSpawning) return; if (bots.length >= maxBotsOnScreen) return; if (botsTuned >= botsToTune) return; var bot = new Bot(); // Place randomly, avoid top 100px and bottom 200px var margin = 120; var minY = 200; var maxY = 2732 - 350; var minX = margin; var maxX = 2048 - margin; bot.x = minX + Math.random() * (maxX - minX); bot.y = minY + Math.random() * (maxY - minY); bots.push(bot); game.addChild(bot); } // Main game update game.update = function () { // Spawn bots as needed if (isSpawning && bots.length < maxBotsOnScreen && botsTuned < botsToTune) { spawnBot(); } // Win condition: after last level, e.g. level 50 (arbitrary cap) if (level > 50) { LK.showYouWin(); isSpawning = false; } }; // Reset game state on game over game.onGameOver = function () { bots = []; level = 1; botsToTune = 5; botsTuned = 0; botsFailed = 0; isSpawning = true; updateScoreText(); errorMsg.visible = false; }; // (Optional) handle resizing, but LK does this automatically // No dragging or movement needed; all interaction is via buttons // End of file
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bot class: represents a singing bot to be tuned
var Bot = Container.expand(function () {
var self = Container.call(this);
// Bot state: 'untuned', 'tuning', 'tuned', 'failed'
self.state = 'untuned';
// Randomly pick a sequence of notes and a scale for this bot
self.notes = Bot.randomNoteSequence();
self.correctScale = Bot.notesToScale(self.notes);
// Timer for tuning (15s)
self.tuneTimer = null;
self.tuneTimeLeft = 15;
self.tuneTimerText = null;
// Create bot body (red box for untuned, green for tuned)
self.botAsset = self.attachAsset('botBody', {
anchorX: 0.5,
anchorY: 0.5
});
self.botAsset.tint = 0xd83318; // red
// Display the notes above the bot
self.noteText = new Text2(self.notes.join(" "), {
size: 90,
fill: 0xFFFFFF
});
self.noteText.anchor.set(0.5, 1);
self.noteText.x = 0;
self.noteText.y = -self.botAsset.height / 2 - 20;
self.addChild(self.noteText);
// "Accorder" button under the bot
self.tuneBtn = self.attachAsset('tuneBtn', {
anchorX: 0.5,
anchorY: 0
});
self.tuneBtn.y = self.botAsset.height / 2 + 30;
self.tuneBtn.x = 0;
self.addChild(self.tuneBtn);
// Button label
self.tuneBtnLabel = new Text2("Accorder", {
size: 60,
fill: 0x222222
});
self.tuneBtnLabel.anchor.set(0.5, 0.5);
self.tuneBtnLabel.x = self.tuneBtn.x;
self.tuneBtnLabel.y = self.tuneBtn.y + self.tuneBtn.height / 2;
self.addChild(self.tuneBtnLabel);
// When tuning, show scale choices
self.scaleBtns = [];
self.scaleBtnLabels = [];
// Event: press on "Accorder" button
self.tuneBtn.down = function (x, y, obj) {
if (self.state !== 'untuned') return;
LK.getSound('tune_press').play();
self.showScaleChoices();
};
// Show scale choices under the bot
self.showScaleChoices = function () {
if (self.state !== 'untuned') return;
self.state = 'tuning';
// Remove previous scale buttons if any
for (var i = 0; i < self.scaleBtns.length; i++) {
self.removeChild(self.scaleBtns[i]);
self.removeChild(self.scaleBtnLabels[i]);
}
self.scaleBtns = [];
self.scaleBtnLabels = [];
// Get 3 scales: correct + 2 random wrong
var scales = Bot.getScaleChoices(self.correctScale);
for (var i = 0; i < scales.length; i++) {
var btn = self.attachAsset('scaleBtn', {
anchorX: 0.5,
anchorY: 0
});
btn.x = 0 + (i - 1) * (btn.width + 40);
btn.y = self.tuneBtn.y + self.tuneBtn.height + 30;
self.addChild(btn);
var label = new Text2(scales[i], {
size: 55,
fill: 0x222222
});
label.anchor.set(0.5, 0.5);
label.x = btn.x;
label.y = btn.y + btn.height / 2;
self.addChild(label);
// Closure for scale selection
(function (scaleName, btnObj) {
btn.down = function (x, y, obj) {
self.handleScaleChoice(scaleName);
};
})(scales[i], btn);
self.scaleBtns.push(btn);
self.scaleBtnLabels.push(label);
}
// Show and start 15s timer
if (self.tuneTimerText) {
self.removeChild(self.tuneTimerText);
self.tuneTimerText = null;
}
self.tuneTimeLeft = 15;
self.tuneTimerText = new Text2("15", {
size: 70,
fill: 0xFFD700
});
self.tuneTimerText.anchor.set(0.5, 0);
self.tuneTimerText.x = 0;
self.tuneTimerText.y = self.tuneBtn.y + self.tuneBtn.height + 140;
self.addChild(self.tuneTimerText);
if (self.tuneTimer) {
LK.clearInterval(self.tuneTimer);
self.tuneTimer = null;
}
self.tuneTimer = LK.setInterval(function () {
if (self.state !== 'tuning') {
LK.clearInterval(self.tuneTimer);
self.tuneTimer = null;
return;
}
self.tuneTimeLeft--;
self.tuneTimerText.setText(self.tuneTimeLeft + "");
if (self.tuneTimeLeft <= 0) {
LK.clearInterval(self.tuneTimer);
self.tuneTimer = null;
// Remove scale buttons
for (var i = 0; i < self.scaleBtns.length; i++) {
self.removeChild(self.scaleBtns[i]);
self.removeChild(self.scaleBtnLabels[i]);
}
self.scaleBtns = [];
self.scaleBtnLabels = [];
self.state = 'failed';
self.botAsset.tint = 0xd83318;
self.noteText.setText(self.notes.join(" ") + " â");
if (self.tuneTimerText) {
self.removeChild(self.tuneTimerText);
self.tuneTimerText = null;
}
// Animate and remove after a short delay
tween(self, {
alpha: 0
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
onBotTuned(false);
}
});
}
}, 1000);
};
// Handle scale choice
self.handleScaleChoice = function (chosenScale) {
if (self.state !== 'tuning') return;
// Stop timer and remove timer text
if (self.tuneTimer) {
LK.clearInterval(self.tuneTimer);
self.tuneTimer = null;
}
if (self.tuneTimerText) {
self.removeChild(self.tuneTimerText);
self.tuneTimerText = null;
}
// Remove scale buttons
for (var i = 0; i < self.scaleBtns.length; i++) {
self.removeChild(self.scaleBtns[i]);
self.removeChild(self.scaleBtnLabels[i]);
}
self.scaleBtns = [];
self.scaleBtnLabels = [];
if (chosenScale === self.correctScale) {
LK.getSound('tune_success').play();
self.state = 'tuned';
self.botAsset.tint = 0x83de44; // green
self.noteText.setText(self.notes.join(" ") + " â");
// Show "Le bot chante juste !" message in the center for 1s
showSuccess("Le bot chante juste !");
// Animate and remove after a short delay
tween(self, {
alpha: 0
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
onBotTuned(true);
}
});
} else {
LK.getSound('tune_fail').play();
self.state = 'failed';
self.botAsset.tint = 0xd83318; // red
self.noteText.setText(self.notes.join(" ") + " â");
// Animate and remove after a short delay
tween(self, {
alpha: 0
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
onBotTuned(false);
}
});
}
};
return self;
});
/****
* Initialize Game
****/
// Static: pick a random note
var game = new LK.Game({
backgroundColor: 0x000000 // black fallback
});
/****
* Game Code
****/
// Add custom background image
var backgroundImage = LK.getAsset('customBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(backgroundImage);
// Play background music in a loop
LK.playMusic('bgmusic', {
loop: true
});
// End of file;
Bot.randomNoteSequence = function () {
// Expanded notes: include all 12 chromatic notes
var notes = ["C", "C#", "Db", "D", "D#", "Eb", "E", "F", "F#", "Gb", "G", "G#", "Ab", "A", "A#", "Bb", "B"];
var len = 2 + Math.floor(Math.random() * 3); // 2-4 notes
var seq = [];
for (var i = 0; i < len; i++) {
var n = notes[Math.floor(Math.random() * notes.length)];
seq.push(n);
}
return seq;
};
// Map a sequence of notes to a scale (use first note for simplicity, but support more scales)
Bot.notesToScale = function (notes) {
// Map note to scale name (major/minor, sharps/flats)
var note = notes[0];
// Normalize note for mapping
var map = {
"C": "Do majeur",
"C#": "Do# majeur",
"Db": "Réb majeur",
"D": "RĂ© majeur",
"D#": "RĂ©# majeur",
"Eb": "Mib majeur",
"E": "Mi majeur",
"F": "Fa majeur",
"F#": "Fa# majeur",
"Gb": "Solb majeur",
"G": "Sol majeur",
"G#": "Sol# majeur",
"Ab": "Lab majeur",
"A": "La majeur",
"A#": "La# majeur",
"Bb": "Sib majeur",
"B": "Si majeur"
};
// Add some minor scales for more variety
var minorMap = {
"C": "Do mineur",
"C#": "Do# mineur",
"Db": "Réb mineur",
"D": "RĂ© mineur",
"D#": "RĂ©# mineur",
"Eb": "Mib mineur",
"E": "Mi mineur",
"F": "Fa mineur",
"F#": "Fa# mineur",
"Gb": "Solb mineur",
"G": "Sol mineur",
"G#": "Sol# mineur",
"Ab": "Lab mineur",
"A": "La mineur",
"A#": "La# mineur",
"Bb": "Sib mineur",
"B": "Si mineur"
};
// 50% chance to use minor scale
var useMinor = Math.random() < 0.5;
if (useMinor && minorMap[note]) return minorMap[note];
return map[note] || "Do majeur";
};
// Static: get 3 scale choices (1 correct, 2 random wrong) from expanded list
Bot.getScaleChoices = function (correct) {
var all = ["Do majeur", "Do# majeur", "Réb majeur", "Ré majeur", "Ré# majeur", "Mib majeur", "Mi majeur", "Fa majeur", "Fa# majeur", "Solb majeur", "Sol majeur", "Sol# majeur", "Lab majeur", "La majeur", "La# majeur", "Sib majeur", "Si majeur", "Do mineur", "Do# mineur", "Réb mineur", "Ré mineur", "Ré# mineur", "Mib mineur", "Mi mineur", "Fa mineur", "Fa# mineur", "Solb mineur", "Sol mineur", "Sol# mineur", "Lab mineur", "La mineur", "La# mineur", "Sib mineur", "Si mineur"];
var choices = [correct];
// Pick 2 random wrong scales
var wrong = [];
for (var i = 0; i < all.length; i++) {
if (all[i] !== correct) wrong.push(all[i]);
}
for (var i = 0; i < 2; i++) {
var idx = Math.floor(Math.random() * wrong.length);
choices.push(wrong[idx]);
wrong.splice(idx, 1);
}
// Shuffle
for (var i = choices.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = choices[i];
choices[i] = choices[j];
choices[j] = tmp;
}
return choices;
};
// Game state
var bots = [];
var level = 1;
var botsToTune = 5;
var botsTuned = 0;
var botsFailed = 0;
var maxBotsOnScreen = 3;
var isSpawning = true;
// Score/level display
var scoreTxt = new Text2("Niveau 1\n0/5 bots accordés", {
size: 90,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Error message
var errorMsg = new Text2("", {
size: 80,
fill: 0xFF3333
});
errorMsg.anchor.set(0.5, 0.5);
errorMsg.visible = false;
LK.gui.center.addChild(errorMsg);
// Success message
var successMsg = new Text2("", {
size: 80,
fill: 0x44FF44
});
successMsg.anchor.set(0.5, 0.5);
successMsg.visible = false;
LK.gui.center.addChild(successMsg);
// Show success message for 1s
function showSuccess(msg) {
successMsg.setText(msg);
successMsg.visible = true;
tween(successMsg, {
alpha: 1
}, {
duration: 0
});
LK.setTimeout(function () {
tween(successMsg, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
successMsg.visible = false;
}
});
}, 1000);
}
// Called when a bot is tuned or failed
function onBotTuned(success) {
if (success) {
botsTuned++;
} else {
botsFailed++;
showError("Mauvaise gamme !");
}
updateScoreText();
// Remove from bots array
for (var i = bots.length - 1; i >= 0; i--) {
if (bots[i].state === 'tuned' || bots[i].state === 'failed') {
bots.splice(i, 1);
}
}
// Check level up
if (botsTuned >= botsToTune) {
nextLevel();
}
}
// Show error message for 1s
function showError(msg) {
errorMsg.setText(msg);
errorMsg.visible = true;
tween(errorMsg, {
alpha: 1
}, {
duration: 0
});
LK.setTimeout(function () {
tween(errorMsg, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
errorMsg.visible = false;
}
});
}, 1000);
}
// Update score/level text
function updateScoreText() {
scoreTxt.setText("Niveau " + level + "\n" + botsTuned + "/" + botsToTune + " bots accordés");
}
// Level up
function nextLevel() {
level++;
botsTuned = 0;
botsFailed = 0;
botsToTune = botsToTune * 2;
updateScoreText();
// Flash green
LK.effects.flashScreen(0x83de44, 600);
}
// Spawn a bot at a random position
function spawnBot() {
if (!isSpawning) return;
if (bots.length >= maxBotsOnScreen) return;
if (botsTuned >= botsToTune) return;
var bot = new Bot();
// Place randomly, avoid top 100px and bottom 200px
var margin = 120;
var minY = 200;
var maxY = 2732 - 350;
var minX = margin;
var maxX = 2048 - margin;
bot.x = minX + Math.random() * (maxX - minX);
bot.y = minY + Math.random() * (maxY - minY);
bots.push(bot);
game.addChild(bot);
}
// Main game update
game.update = function () {
// Spawn bots as needed
if (isSpawning && bots.length < maxBotsOnScreen && botsTuned < botsToTune) {
spawnBot();
}
// Win condition: after last level, e.g. level 50 (arbitrary cap)
if (level > 50) {
LK.showYouWin();
isSpawning = false;
}
};
// Reset game state on game over
game.onGameOver = function () {
bots = [];
level = 1;
botsToTune = 5;
botsTuned = 0;
botsFailed = 0;
isSpawning = true;
updateScoreText();
errorMsg.visible = false;
};
// (Optional) handle resizing, but LK does this automatically
// No dragging or movement needed; all interaction is via buttons
// End of file
Modern App Store icon, high definition, square with rounded corners, for a game titled "Accorder les bots" and with the description "Des bots rouges chantent faux aÌ lâeÌcran. Appuie sur "Accorder", choisis la bonne gamme selon les notes afficheÌes pour accorder chaque bot. Monte de niveau en accordant de plus en plus de bots.". No text on icon!
Fond d'eÌcran salle de programmation. In-Game asset. 2d. High contrast. No shadows