User prompt
Ajoute la fonctionnalité qui permet au joueur de caresser ses dauphins (3 Dauphicoins par caresse et une caresse par dauphin toutes les minutes seulement) avec un bouton violet a texte blanc "caresser" sous chaque dauphin du joueur Par la même occasion, fait en sorte que la progression du joueur et de ses dauphins (Nombre de Dauphicoins, dauphibouffe, cerceaux achetés et posséder par les dauphins, niveaux des dauphins , noms des Dauphins) Soient sauvegardes ! Mais que le joueur puisse reset toute sa progression en appuyant sur le bouton rouge a texte noir "reset" quelque part dans L'ui ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Corrigé les problèmes de façon durable!!! ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var dauphicoins = storage.get('dauphicoins') || 50;' Line Number: 311 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Corrigé les erreurs et problèmes
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var dauphicoins = storage.get('dauphicoins') || 50;' Line Number: 311 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Corrigé les problemes
User prompt
Ajoute la fonctionnalité qui permet au joueur de caresser ses dauphins (3 Dauphicoins par caresse et une caresse par dauphins toutes les 2 minutes) avec un bouton violet a texte blanc "caresser" sous chaque dauphin du joueur Par la même occasion, fait en sorte que la progression du joueur et de ses dauphins (Nombre de Dauphicoins, dauphibouffe, cerceaux achetés et posséder par les dauphins, niveaux des dauphins , noms des Dauphins) Soient sauvegardes de manière persistante dans le local! Mais que le joueur puisse reset toute sa progression en appuyant sur le bouton rouge a texte noir "reset" quelque part dans L'ui , corrigé les problèmes ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Ajoute la fonctionnalité qui permet au joueur de caresser ses dauphins (3 Dauphicoins par caresse et une caresse par dauphins toutes les 2 minutes) avec un bouton violet a texte blanc "caresser" sous chaque dauphin du joueur Par la même occasion, fait en sorte que la progression du joueur et de ses dauphins (Nombre de Dauphicoins, dauphibouffe, cerceaux achetés et posséder par les dauphins, niveaux des dauphins , noms des Dauphins) Soient sauvegardes de manière persistante dans le local! Mais que le joueur puisse reset toute sa progression en appuyant sur le bouton rouge a texte noir "reset" quelque part dans L'ui ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Pour le keyboard qui permet au joueur de changer le nom d'un de ses dauphins, fait en sorte que chaque lettre ou chiffre soit affiché soit forme de texte noir sur sa touche correspondante (fait aussi en sorte que les touche ne se chevauchent pas et qu'on voit le texte du chiffre ou de la lettre correspondante sur la touche)
User prompt
Fait en sorte que lorsque le joueur a acheté un cerceau a un de ses dauphins, le cerveau s'affiche en petit de la même façon comme il est dans les assets a côté du dauphin qui le possède Quand le dauphin possède plusieurs cerceaux, les cerceaux sont les uns a côté des autres en petit a côté du dauphin
User prompt
Please fix the bug: 'Uncaught TypeError: selectedDolphinForNaming.children[0].setText is not a function' in or related to this line: 'selectedDolphinForNaming.children[0].setText(currentInputText);' Line Number: 738
User prompt
Please fix the bug: 'Uncaught TypeError: selectedDolphinForNaming.children[2].setText is not a function' in or related to this line: 'selectedDolphinForNaming.children[2].setText(currentInputText);' Line Number: 738
User prompt
affiche chaque lettre et chiffre du keyboard de façon lisible sur sa touche correspondante (toutes les lettres et chiffres)
User prompt
Affiche chaque lettre ou chiffr du keyboard correspondant a sa touche au centre de sa touche , et ajoute le boutton effacer au keyboard, qui permet au joueur de supprimer des lettres et chiffres (utile pour récrire un autre nom) pour toutes les lettres et chiffres, le boutton pour effacer le nom doit être disponible dans L'ui du keyboard, et effacer le nom actuel du dauphin quand le joueur appuie dessus pour qu'il puisse en saisir un nom tout neuf
User prompt
Affiche chaque lettre ou chiffr du keyboard correspondant a sa touche au centre de sa touche , et ajoute le boutton effacer au keyboard, qui permet au joueur de supprimer des lettres et chiffres (utile pour récrire un autre nom) pour toutes les lettres et chiffres, et ajoute les cerceaux de la boutique aux assets etc...
User prompt
Affiche chaque lettre ou chiffr du keyboard correspondant a sa touche au centre de sa touche , et ajoute le boutton effacer au keyboard, qui permet au joueur de supprimer des lettres et chiffres (utile pour récrire un autre nom)
User prompt
Améliore la visibilité des articles dans la boutique, et la visibilité des lettres sur le keyboard de choix de nom pour les dauphins (ajoute aussi au keyboard un boutton pour supprimer des lettres) , affiche chaque lettre du keyboard sur le bouton correspondant
User prompt
Améliore la visibilité des articles dans la boutique, et la visibilité des lettres sur le keyboard de choix de nom pour les dauphins (ajoute aussi au keyboard un boutton pour supprimer des lettres)
User prompt
Ajoute les différents types de cerceaux et mets les en vente a la boutique avec leurs prix respectifs : - cerceaux cute (prix : 25 Dauphicoins) - cerceau tricolore (prix : 34 Dauphicoins) - cerceau enflammé (prix : 45 Dauphicoins) - cerceau de l'océan (prix : 50 dauphins) - cerceau doré (le cerveau déjà existant dans le jeu) Lorsque le joueur achète un cerceau, et possède plusieurs dauphins, Le jeu lui demande à quel dauphin il veut offrir le cerceau avec un petit écran ou le joueur dois appuyer sur le nom de son dauphin correspondant (D'ailleurs implante aussi une fonctionnalité qui permet au joueur de personnalisalise et modifier le nom de son dauphin, Le joueur peut renommer un dauphin en appuyant sur un boutton noir a texte blanc "Nommer un dauphin", dans L'ui du jeu, un écran s'affiche avec sa liste de dauphins, et le joueur doit appuyer sur le nom actuel de son dauphin pour le renommer, Puis un écran keyboard apparaît avec toutes les lettres de les chiffres requis pour donner un nom s'ouvre, le joueur peut alors écrire le nouveau nom de son dauphin et le valider pour renommer son dauphin
User prompt
Les pièces doivent être des Dauphicoins Et la bouffe doit être de la dauphibouffe
User prompt
Le jeu doit être en français
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var localPos = shopModal.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 363
Code edit (1 edits merged)
Please save this source code
User prompt
Dauphinya - Dolphin Care Adventure
Initial prompt
Je souhaite créer un jeu mobile 2D complet et immersif appelé "Dauphinya", un jeu d'élevage de dauphins mignon, relaxant et apaisant. L'objectif est de fournir une expérience ludique où les joueurs peuvent créer un lien unique avec leurs dauphins personnalisés, les faire progresser et enrichir leur monde sous-marin. 1. Concept Général et Ambiance * Titre du Jeu : Dauphinya * Genre : Simulation d'élevage / Gestion de créatures, jeu mobile relaxant. * Plateforme : Mobile (iOS/Android). * Style Visuel : 2D cartoon, très adorable, avec des couleurs vives et un univers sous-marin féerique et enchanteur. L'interface utilisateur (UI) doit être intuitive et esthétique, en accord avec le thème. * Objectif du Joueur : Acquérir, élever et chérir une collection de dauphins uniques, les faire monter de niveau, personnaliser leur environnement et progresser en tant qu'éleveur de dauphins. 2. Éléments Visuels (Assets 2D) * Scènes : * Aquarium Principal : Fond marin dynamique avec coraux colorés, algues flottantes, rochers doux, et effets de lumière sous-marine (bulles, rayons solaires filtrant). L'arrière-plan peut évoluer visuellement en fonction du niveau du joueur (plus d'éléments décoratifs débloqués, etc.). * Écran de Boutique : Interface claire pour l'achat de dauphins et d'objets. * Écran de Quiz : Interface pour les questions et réponses. * Sprites des Dauphins : * Modèles de base de dauphin mignon en 2D, avec différentes poses : nage lente, nage rapide, repos, saut hors de l'eau. * Expressions / États : Heureux (cœurs flottants, étincelles), Affamé (bulle de pensée avec un poisson), Neutre, Triste (si négligé). * Animations clés : Caresse (réaction au toucher), Manger (animation de consommation de nourriture), Saut (animation ludique). * Variations : Possibilité future de différentes espèces ou couleurs/patterns de dauphins. * Objets d'Interaction et Décoration (Sprites 2D) : * Nourriture : Sprite de "Dauphibouffe" (petits poissons stylisés ou granulés). * Cerceaux : Sprites de cerceaux uniques (ex: "Cute", "Tricolore", "Enflammé", "de l'Océan"). Ces cerceaux s'affichent par-dessus le dauphin. * Éléments d'Interface (UI - Sprites 2D) : * Icônes des Monnaies : "Dauphicoin" (pièce dorée avec un dauphin), "Dauphibouffe" (sachet/poisson). * Affichage des Monnaies : Compteurs numériques clairs en haut de l'écran. * Barres de Progression : * Barre de Bonheur par dauphin (au-dessus du dauphin). * Barre de Niveau pour chaque dauphin (au-dessus du dauphin, sous la barre de bonheur). * Barre de Niveau du Joueur (en haut de l'écran ou dans un panneau dédié). * Boutons Principaux : "Nourrir", "Caresse", "Boutique", "Quiz". Design agréable au toucher. * Pop-ups et Notifications : Messages pour gains, montées de niveau, rappels, etc. 3. Systèmes et Logiques de Jeu 3.1. Gestion des Dauphins * Acquisition de Dauphins : * Le joueur commence avec un dauphin initial. * La boutique permet d'acheter de nouveaux dauphins en utilisant des Dauphicoins. Chaque dauphin a un coût différent. * Lors de l'achat, le joueur peut nommer son nouveau dauphin (champ de texte). * Bonheur des Dauphins : * Chaque dauphin possède une barre de bonheur (échelle de 0 à 100). * Le bonheur diminue lentement avec le temps (nécessite des soins réguliers). * Actions pour augmenter le bonheur : * Caresse : En cliquant sur le dauphin. Augmente le bonheur de X points (ex: +10). Limite : Peut être effectuée une fois toutes les 2 minutes par dauphin. Rapport des Dauphicoins (ex: +5 Dauphicoins). Animation de caresse et affichage de cœurs. * Nourrir : Utilise 1 unité de Dauphibouffe. Augmente le bonheur de Y points (ex: +20). Animation de repas. Nécessite que le dauphin ne soit pas au bonheur maximum. * Cadeaux (Cerceaux) : L'équipement d'un cerceau sur un dauphin augmente son bonheur de manière significative et/ou passivement. * Niveau des Dauphins : * Chaque dauphin possède un niveau (ex: Niveau 1, 2, 3...). * Le dauphin monte de niveau lorsque sa barre de bonheur atteint 100%. La barre se réinitialise. * Chaque montée de niveau : * Augmente les points de bonheur maximum du dauphin (si la barre va au-delà de 100). * Peut débloquer de nouvelles animations ou capacités spécifiques au dauphin (à définir ultérieurement). * Contribue à l'expérience du joueur (voir ci-dessous). * Peut donner une petite récompense de Dauphibouffe (ex: +1). 3.2. Monnaies du Jeu * Dauphicoins (Monnaie Principale) : * Obtention : Principalement via les caresses de dauphins. Potentiellement via des quêtes ou succès. * Utilisation : Achat de nouveaux dauphins, achat de cerceaux, achat de Dauphibouffe (si nécessaire). * Dauphibouffe (Ressource) : * Obtention : En répondant correctement aux Quiz Marins. Potentiellement en récompense de montées de niveau de dauphin ou quêtes. * Utilisation : Nourrir les dauphins. 3.3. Système de Quiz Marins * Accès : Via un bouton dédié sur l'écran principal. * Mécanisme : Le joueur répond à des questions à choix multiples sur le thème de l'océan, des dauphins et de la vie marine. * Récompense : Chaque bonne réponse (ou série de bonnes réponses) rapporte de la Dauphibouffe. * Database : Une base de données de questions/réponses variées. 3.4. Boutique * Contenu : * Nouveaux Dauphins : Liste des dauphins disponibles à l'achat, avec leur coût en Dauphicoins. * Cerceaux : Liste des cerceaux uniques à acheter. Chaque cerceau a un coût en Dauphicoins et une description. * Exemples : "Cerceau Cute", "Cerceau Tricolore", "Cerceau Enflammé" (avec un petit effet visuel de flammes 2D), "Cerceau de l'Océan" (avec un effet d'eau scintillante). * Interaction : Le joueur sélectionne un article, confirme l'achat. Pour les cerceaux, une fois achetés, ils sont disponibles dans l'inventaire du joueur pour être équipés sur un dauphin spécifique. 3.5. Progression du Joueur * Niveau du Joueur : Le joueur a un niveau global qui augmente au fur et à mesure qu'il prend soin de ses dauphins. * Expérience du Joueur : Chaque fois qu'un dauphin monte de niveau, le joueur gagne de l'expérience (XP). * Montée de Niveau du Joueur : Atteindre un certain seuil d'XP débloque un nouveau niveau de joueur. * Récompenses du Niveau Joueur : * Déblocage de nouvelles espèces de dauphins dans la boutique. * Déblocage de nouveaux types de cerceaux ou décorations pour l'aquarium. * Récompenses ponctuelles de Dauphicoins ou Dauphibouffe. 4. Expérience Utilisateur et Qualité de Vie * Interface Intuitive : Tous les éléments UI doivent être clairs, réactifs et faciles à comprendre pour un public mobile. * Musique et Sons : * Musique d'ambiance : Relaxante, féerique et apaisante pour l'aquarium. * Sons SFX : Sons de dauphins (clics, sifflements joyeux), sons de caresse, sons de bulles, sons de pièces (Dauphicoins), sons de notification, sons de succès pour les montées de niveau. * Notifications : Rappels amicaux si un dauphin est affamé ou si une caresse est de nouveau disponible. * Nommage : Le joueur doit pouvoir nommer facilement ses dauphins. 5. Demande Initiale à Upit AI Game Maker En me basant sur cette description, je souhaite que vous commenciez par générer les éléments de base suivants : * Une scène d'aquarium 2D avec un arrière-plan marin générique. * Un sprite de dauphin de base avec une animation de nage simple. * Un système pour instancier ce dauphin dans la scène. * Les éléments UI de base : affichage des Dauphicoins et de la Dauphibouffe, et une barre de bonheur pour le dauphin. * La logique d'interaction "Caresse" : un clic sur le dauphin augmente sa barre de bonheur et donne des Dauphicoins, avec le timer de 2 minutes. Afficher un message ou un effet visuel pour indiquer que la caresse est "en cooldown". * La logique d'interaction "Nourrir" : un clic sur un bouton "Nourrir" utilise de la Dauphibouffe et augmente le bonheur du dauphin. * Un mécanisme pour nommer le dauphin lors de son "apparition". Je prévois ensuite de fournir des requêtes plus spécifiques pour les assets détaillés (types de cerceaux, autres dauphins, éléments de quiz) et pour affiner les logiques de progression, la boutique et les effets visuels.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Coral = Container.expand(function (type, x, y) { var self = Container.call(this); var coralTypes = ['coral1', 'coral2', 'coral3']; var coralAsset = coralTypes[type % 3]; var coral = self.attachAsset(coralAsset, { anchorX: 0.5, anchorY: 1 }); self.x = x || 0; self.y = y || 0; self.update = function () { // Gentle swaying animation coral.rotation = Math.sin(Date.now() * 0.0008) * 0.1; }; return self; }); var Dolphin = Container.expand(function (name, x, y) { var self = Container.call(this); // Dolphin properties self.dolphinName = name || 'Flipper'; self.happiness = Math.floor(Math.random() * 50) + 25; self.level = 1; self.lastPetTime = 0; self.petCooldown = 60000; // 1 minute self.maxHappiness = 100; self.ownedHoops = []; // Track owned hoops self.hoopIcons = []; // Visual representations of owned hoops // Expression/emotion system self.currentExpression = 'neutral'; self.lastFeedTime = 0; self.expressionElements = []; self.lastExpressionUpdate = 0; // Graphics var dolphinBody = self.attachAsset('dolphin', { anchorX: 0.5, anchorY: 0.5 }); // Happiness bar background var happinessBarBg = self.attachAsset('happinessBarBg', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -80 }); // Happiness bar var happinessBar = self.attachAsset('happinessBar', { anchorX: 0, anchorY: 0.5, x: -80, y: -80 }); // Cooldown bar background var cooldownBarBg = self.attachAsset('cooldownBarBg', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -55 }); // Cooldown bar var cooldownBar = self.attachAsset('cooldownBar', { anchorX: 0, anchorY: 0.5, x: -80, y: -55 }); // Name text var nameText = new Text2(self.dolphinName, { size: 36, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.x = 0; nameText.y = -120; self.addChild(nameText); // Store reference for external access self.nameText = nameText; // Pet button var petButton = self.attachAsset('petButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 80 }); var petButtonText = new Text2('Caresser', { size: 28, fill: 0xFFFFFF }); petButtonText.anchor.set(0.5, 0.5); petButtonText.x = 0; petButtonText.y = 80; self.addChild(petButtonText); // Feed button var feedButton = self.attachAsset('petButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 140 }); feedButton.tint = 0xE91E63; // Pink color var feedButtonText = new Text2('Nourrir', { size: 28, fill: 0xFFFFFF }); feedButtonText.anchor.set(0.5, 0.5); feedButtonText.x = 0; feedButtonText.y = 140; self.addChild(feedButtonText); // Level text var levelText = new Text2('Niv.' + self.level, { size: 28, fill: 0xFFEB3B }); levelText.anchor.set(0.5, 0.5); levelText.x = 0; levelText.y = -100; self.addChild(levelText); // Store reference for external access self.levelText = levelText; self.updateHappinessBar = function () { var percentage = self.happiness / self.maxHappiness; happinessBar.scaleX = percentage; if (self.happiness >= self.maxHappiness) { self.levelUp(); } }; self.updateCooldownBar = function () { var now = Date.now(); var timeSinceLastPet = now - self.lastPetTime; var cooldownRemaining = Math.max(0, self.petCooldown - timeSinceLastPet); var percentage = cooldownRemaining / self.petCooldown; cooldownBar.scaleX = percentage; cooldownBar.visible = percentage > 0; cooldownBarBg.visible = percentage > 0; }; self.clearExpressionElements = function () { for (var i = 0; i < self.expressionElements.length; i++) { self.expressionElements[i].destroy(); } self.expressionElements = []; }; self.updateExpression = function () { var now = Date.now(); // Clear old expression elements self.clearExpressionElements(); // Determine current expression based on state var timeSinceLastPet = now - self.lastPetTime; var timeSinceLastFeed = now - self.lastFeedTime; if (self.happiness >= 80) { self.currentExpression = 'happy'; } else if (timeSinceLastFeed > 300000 || self.happiness < 30) { // 5 minutes since last feed or low happiness self.currentExpression = 'hungry'; } else if (self.happiness < 50 && timeSinceLastPet > 180000) { // Low happiness and 3 minutes since pet self.currentExpression = 'sad'; } else { self.currentExpression = 'neutral'; } // Create expression elements based on current state if (self.currentExpression === 'happy') { // Create floating hearts for (var i = 0; i < 3; i++) { var heart = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 60 - 30, y: -40 - Math.random() * 20 }); self.expressionElements.push(heart); // Animate hearts floating up tween(heart, { y: heart.y - 50, alpha: 0 }, { duration: 2000, easing: tween.easeOut }); } // Create sparkles for (var i = 0; i < 4; i++) { var sparkle = self.attachAsset('sparkle', { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 80 - 40, y: Math.random() * 40 - 20 }); self.expressionElements.push(sparkle); // Animate sparkles twinkling tween(sparkle, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 1500, easing: tween.easeInOut }); } } else if (self.currentExpression === 'hungry') { // Create thought bubble with fish var thoughtBubble = self.attachAsset('thoughtBubble', { anchorX: 0.5, anchorY: 0.5, x: 60, y: -60, alpha: 0.8 }); self.expressionElements.push(thoughtBubble); var fish = self.attachAsset('fish', { anchorX: 0.5, anchorY: 0.5, x: 60, y: -60 }); self.expressionElements.push(fish); // Animate thought bubble pulsing tween(thoughtBubble, { scaleX: 1.1, scaleY: 1.1 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(thoughtBubble, { scaleX: 1, scaleY: 1 }, { duration: 1000, easing: tween.easeInOut }); } }); } else if (self.currentExpression === 'sad') { // Tint dolphin slightly blue for sadness tween(dolphinBody, { tint: 0x8bb6d6 }, { duration: 500 }); } else { // Neutral - ensure normal tint tween(dolphinBody, { tint: 0x4fa8d8 }, { duration: 500 }); } self.lastExpressionUpdate = now; }; self.addHoopIcon = function (hoopType) { // Add hoop type to owned hoops self.ownedHoops.push(hoopType); // Create small hoop icon var hoopAssetNames = ['hoop', 'hoopCute', 'hoopTricolore', 'hoopEnflamme', 'hoopOcean']; var hoopIcon = self.attachAsset(hoopAssetNames[hoopType] || 'hoop', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); // Position icon next to dolphin var iconIndex = self.hoopIcons.length; hoopIcon.x = 120 + iconIndex * 40; hoopIcon.y = 0; self.hoopIcons.push(hoopIcon); // Save hoop progression immediately updateUI(); }; self.canPet = function () { var now = Date.now(); return now - self.lastPetTime >= self.petCooldown; }; self.pet = function () { if (!self.canPet()) return false; self.lastPetTime = Date.now(); self.happiness = Math.min(self.happiness + 10, self.maxHappiness); dauphicoins += 3; dauphibouffe += 5; // Player gains 5 dauphibouffe per pet // Pet animation tween(dolphinBody, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(dolphinBody, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); LK.getSound('pet').play(); LK.getSound('coin').play(); self.updateHappinessBar(); // Trigger happy expression immediately self.updateExpression(); updateUI(); return true; }; self.feed = function () { if (dauphibouffe <= 0) return false; dauphibouffe--; self.lastFeedTime = Date.now(); self.happiness = Math.min(self.happiness + 20, self.maxHappiness); // Feed animation tween(dolphinBody, { tint: 0x8bc34a }, { duration: 300 }); tween(dolphinBody, { tint: 0x4fa8d8 }, { duration: 300 }); self.updateHappinessBar(); // Update expression after feeding self.updateExpression(); updateUI(); return true; }; self.levelUp = function () { self.level++; self.happiness = 0; self.maxHappiness += 10; trainerXP += 10; // Level up animation LK.effects.flashObject(self, 0xffeb3b, 1000); LK.getSound('levelup').play(); self.levelText.setText('Niv.' + self.level); self.updateHappinessBar(); updateUI(); // Check trainer level up var newTrainerLevel = Math.floor(trainerXP / 50) + 1; if (newTrainerLevel > trainerLevel) { trainerLevel = newTrainerLevel; updateUI(); } }; self.down = function (x, y, obj) { var localPos; if (obj && obj.parent && obj.parent.toGlobal) { localPos = self.toLocal(obj.parent.toGlobal(obj.position)); } else { localPos = { x: x, y: y }; } // Check if pet button was clicked if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 50 && localPos.y <= 110) { if (self.canPet()) { self.pet(); } } else if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 110 && localPos.y <= 170) { // Check if feed button was clicked if (dauphibouffe > 0) { self.feed(); } } else { // Original dolphin body click behavior if (self.canPet()) { self.pet(); } else { // Show feed option if has food if (dauphibouffe > 0) { self.feed(); } } } }; self.update = function () { self.updateCooldownBar(); // Gentle floating animation dolphinBody.y = Math.sin(Date.now() * 0.001) * 10; // Update expressions every 3 seconds var now = Date.now(); if (now - self.lastExpressionUpdate > 3000) { self.updateExpression(); } }; // Position dolphin self.x = x || 0; self.y = y || 0; // Initialize bars self.updateHappinessBar(); self.updateCooldownBar(); return self; }); var Hoop = Container.expand(function (x, y) { var self = Container.call(this); var hoop = self.attachAsset('hoop', { anchorX: 0.5, anchorY: 0.5 }); // Make hoop hollow by reducing alpha in center hoop.alpha = 0.3; self.hoopType = 0; // Default to golden hoop self.attachedDolphin = null; self.x = x || 0; self.y = y || 0; self.update = function () { // Gentle rotation hoop.rotation += 0.01; // Apply color based on hoop type if (hoopTypes && hoopTypes[self.hoopType]) { hoop.tint = hoopTypes[self.hoopType].color; } // Follow attached dolphin if any if (self.attachedDolphin) { self.x = self.attachedDolphin.x; self.y = self.attachedDolphin.y - 50; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0066cc }); /**** * Game Code ****/ // Add custom ocean background var oceanBg = game.attachAsset('oceanBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); // Game variables var dolphins = []; var corals = []; var hoops = []; var dauphicoins = storage.dauphicoins !== undefined ? storage.dauphicoins : 50; var dauphibouffe = storage.dauphibouffe !== undefined ? storage.dauphibouffe : 3; var trainerLevel = storage.trainerLevel !== undefined ? storage.trainerLevel : 1; var trainerXP = storage.trainerXP !== undefined ? storage.trainerXP : 0; var totalDolphinsRaised = storage.totalDolphinsRaised !== undefined ? storage.totalDolphinsRaised : 0; // Database of 80 unique dolphin names var dolphinNames = ['Luna', 'Neptune', 'Océan', 'Azur', 'Coral', 'Marina', 'Aqua', 'Bleu', 'Splash', 'Bubble', 'Wave', 'Tide', 'Storm', 'Misty', 'Pearl', 'Crystal', 'Echo', 'Sonic', 'Melody', 'Harmony', 'Rhythm', 'Jazz', 'Blues', 'Tempo', 'Atlas', 'Zeus', 'Triton', 'Poseidon', 'Apollo', 'Orion', 'Cosmos', 'Nova', 'Star', 'Comet', 'Galaxy', 'Meteor', 'Stellar', 'Solar', 'Lunar', 'Cosmic', 'Aquarius', 'Pisces', 'Delphinus', 'Cetus', 'Orca', 'Narval', 'Beluga', 'Marlin', 'Spirit', 'Dream', 'Hope', 'Joy', 'Grace', 'Faith', 'Love', 'Peace', 'Thunder', 'Lightning', 'Rain', 'Frost', 'Snow', 'Ice', 'Wind', 'Breeze', 'Coral', 'Reef', 'Lagoon', 'Bay', 'Cove', 'Shore', 'Beach', 'Dune', 'Captain', 'Admiral', 'Sailor', 'Navigator', 'Explorer', 'Voyager', 'Pioneer', 'Ranger']; // Track used names to avoid duplicates - load from storage var usedNames = storage.usedNames || []; // Hoop types with their properties var hoopTypes = [{ name: 'Cerceau Doré', price: 50, color: 0xFFD700 }, { name: 'Cerceau Cute', price: 25, color: 0xFF69B4 }, { name: 'Cerceau Tricolore', price: 34, color: 0x0000FF }, { name: 'Cerceau Enflammé', price: 45, color: 0xFF4500 }, { name: 'Cerceau de l\'Océan', price: 50, color: 0x00CED1 }]; // UI elements var coinText, foodText, trainerText, totalDolphinsRaisedText; var shopModal = null; var quizModal = null; var hoopSelectionModal = null; var dolphinSelectionModal = null; var namingModal = null; var keyboardModal = null; var selectedHoopType = null; var selectedDolphinForNaming = null; var currentInputText = ''; // Quiz questions var quizQuestions = [{ question: "Qu'utilisent les dauphins pour l'écholocation ?", answers: ["Ondes sonores", "Ondes lumineuses", "Champs magnétiques", "Champs électriques"], correct: 0 }, { question: "Combien de temps les dauphins peuvent-ils retenir leur respiration ?", answers: ["5 minutes", "15 minutes", "30 minutes", "1 heure"], correct: 1 }, { question: "Comment appelle-t-on un groupe de dauphins ?", answers: ["Banc", "Pod", "Troupeau", "Meute"], correct: 1 }, { question: "Comment les dauphins dorment-ils ?", answers: ["Complètement inconscients", "Une moitié du cerveau à la fois", "Ne dorment jamais", "Seulement la nuit"], correct: 1 }, { question: "Quelle est la plus grande espèce de dauphin ?", answers: ["Grand dauphin", "Orque", "Dauphin à long bec", "Dauphin sombre"], correct: 1 }, { question: "À quelle profondeur les dauphins peuvent-ils plonger ?", answers: ["50 mètres", "200 mètres", "500 mètres", "1000 mètres"], correct: 2 }, { question: "Combien de dents a un grand dauphin adulte ?", answers: ["20-30", "40-50", "80-100", "120-140"], correct: 2 }, { question: "Quelle est la vitesse maximale d'un dauphin ?", answers: ["15 km/h", "35 km/h", "55 km/h", "75 km/h"], correct: 2 }, { question: "Où vivent les dauphins roses ?", answers: ["Océan Pacifique", "Mer Méditerranée", "Fleuve Amazone", "Océan Arctique"], correct: 2 }, { question: "Quel est le nom scientifique du grand dauphin ?", answers: ["Delphinus delphis", "Tursiops truncatus", "Orcinus orca", "Stenella longirostris"], correct: 1 }, { question: "Combien pèse un dauphin adulte en moyenne ?", answers: ["50-100 kg", "150-300 kg", "400-500 kg", "600-800 kg"], correct: 1 }, { question: "Quelle est la durée de gestation d'un dauphin ?", answers: ["6 mois", "9 mois", "12 mois", "18 mois"], correct: 2 }, { question: "À quel âge les dauphins atteignent-ils la maturité sexuelle ?", answers: ["2-3 ans", "5-7 ans", "10-12 ans", "15-20 ans"], correct: 1 }, { question: "Comment les dauphins communiquent-ils principalement ?", answers: ["Gestes", "Couleurs", "Sons et sifflements", "Odeurs"], correct: 2 }, { question: "Quelle est la température corporelle d'un dauphin ?", answers: ["32°C", "37°C", "42°C", "45°C"], correct: 1 }, { question: "Combien de chambres a le cœur d'un dauphin ?", answers: ["2", "3", "4", "5"], correct: 2 }, { question: "Quel pourcentage du cerveau utilisent les dauphins ?", answers: ["10%", "50%", "80%", "100%"], correct: 3 }, { question: "Comment s'appelle le bébé dauphin ?", answers: ["Poulain", "Veau", "Petit", "Chiot"], correct: 1 }, { question: "Quelle distance peuvent parcourir les dauphins en une journée ?", answers: ["10 km", "50 km", "100 km", "200 km"], correct: 2 }, { question: "Dans quels océans trouve-t-on des dauphins ?", answers: ["Seulement Atlantique", "Seulement Pacifique", "Tous les océans", "Seulement Indien"], correct: 2 }, { question: "Combien de vertèbres cervicales ont les dauphins ?", answers: ["5", "7", "9", "12"], correct: 1 }, { question: "Quelle est la principale menace pour les dauphins ?", answers: ["Requins", "Pollution", "Maladies", "Froid"], correct: 1 }, { question: "Comment les dauphins régulent-ils leur température ?", answers: ["Poils", "Graisse", "Glandes sudoripares", "Respiration"], correct: 1 }, { question: "Quel est le plus petit dauphin au monde ?", answers: ["Dauphin de Maui", "Dauphin commun", "Marsouin du Pacifique", "Dauphin de Risso"], correct: 0 }, { question: "Combien d'estomacs ont les dauphins ?", answers: ["1", "2", "3", "4"], correct: 2 }, { question: "À quelle fréquence respirent les dauphins ?", answers: ["En continu", "Toutes les 30 secondes", "Toutes les 8-10 minutes", "Une fois par heure"], correct: 2 }, { question: "Comment les dauphins voient-ils sous l'eau ?", answers: ["Mal", "En noir et blanc", "Très bien", "Seulement de près"], correct: 2 }, { question: "Quelle est la structure sociale des dauphins ?", answers: ["Solitaires", "En couples", "En groupes", "En familles"], correct: 2 }, { question: "Comment s'appelle l'évent des dauphins ?", answers: ["Narine", "Spiracle", "Blowhole", "Trou respiratoire"], correct: 2 }, { question: "Quelle est la portée de l'écholocation des dauphins ?", answers: ["10 mètres", "50 mètres", "100 mètres", "500 mètres"], correct: 2 }, { question: "Les dauphins sont-ils des mammifères ?", answers: ["Non, ce sont des poissons", "Oui", "Parfois", "Seulement les grands"], correct: 1 }, { question: "Quel sens est le plus développé chez les dauphins ?", answers: ["Vue", "Ouïe", "Odorat", "Toucher"], correct: 1 }, { question: "Combien de sons différents un dauphin peut-il produire ?", answers: ["10", "50", "200", "Plus de 1000"], correct: 3 }, { question: "Comment les dauphins reconnaissent-ils leurs proches ?", answers: ["Par l'odeur", "Par la vue", "Par leur signature sifflée", "Par le toucher"], correct: 2 }, { question: "Quelle est la couleur typique d'un grand dauphin ?", answers: ["Blanc", "Gris", "Bleu", "Noir"], correct: 1 }, { question: "À quelle profondeur vivent principalement les dauphins ?", answers: ["Surface seulement", "0-200 mètres", "200-500 mètres", "Plus de 1000 mètres"], correct: 1 }, { question: "Comment naissent les bébés dauphins ?", answers: ["Tête première", "Queue première", "Sur le côté", "Dans un œuf"], correct: 1 }, { question: "Combien de temps un bébé dauphin reste-t-il avec sa mère ?", answers: ["6 mois", "1-2 ans", "3-6 ans", "10 ans"], correct: 2 }, { question: "Quel est le prédateur principal des dauphins ?", answers: ["Baleine", "Requin", "Pieuvre", "Raie"], correct: 1 }, { question: "Comment les dauphins chassent-ils en groupe ?", answers: ["Individuellement", "En cercle", "En ligne", "Au hasard"], correct: 1 }, { question: "Quelle est la nourriture préférée des dauphins ?", answers: ["Algues", "Plancton", "Poissons", "Crustacés"], correct: 2 }, { question: "Les dauphins peuvent-ils sauter hors de l'eau ?", answers: ["Non, jamais", "Rarement", "Souvent", "Seulement en captivité"], correct: 2 }, { question: "Combien de nageoires a un dauphin ?", answers: ["2", "3", "4", "5"], correct: 3 }, { question: "Quelle est la fonction de la nageoire dorsale ?", answers: ["Nager plus vite", "Stabilité", "Communication", "Respiration"], correct: 1 }, { question: "Comment s'appelle la queue d'un dauphin ?", answers: ["Palme", "Nageoire caudale", "Gouvernail", "Aileron"], correct: 1 }, { question: "Les dauphins migrent-ils ?", answers: ["Non, jamais", "Oui, tous", "Certaines espèces", "Seulement les jeunes"], correct: 2 }, { question: "Quelle distance peut couvrir l'écholocation d'un dauphin ?", answers: ["1 mètre", "10 mètres", "100 mètres", "1 kilomètre"], correct: 2 }, { question: "Comment les dauphins expriment-ils la joie ?", answers: ["En chantant", "En sautant", "En nageant vite", "En se touchant"], correct: 1 }, { question: "Quel âge peut atteindre un dauphin en liberté ?", answers: ["10-15 ans", "20-25 ans", "30-45 ans", "50-60 ans"], correct: 2 }, { question: "Comment les dauphins nettoient-ils leur peau ?", answers: ["Avec du sable", "En se frottant", "Avec des algues", "Avec l'aide d'autres poissons"], correct: 3 }, { question: "Quelle partie du corps utilisent les dauphins pour l'écholocation ?", answers: ["Les yeux", "Le melon", "La queue", "Les nageoires"], correct: 1 }, { question: "Les dauphins peuvent-ils reconnaître leur reflet ?", answers: ["Non", "Oui", "Parfois", "Seulement les adultes"], correct: 1 }, { question: "Comment s'appelle le groupe de dauphins qui chasse ensemble ?", answers: ["Banc", "Pod", "Alliance", "Meute"], correct: 2 }, { question: "Quelle est la particularité des dauphins roses d'Amazonie ?", answers: ["Ils volent", "Ils vivent en eau douce", "Ils sont très petits", "Ils ne nagent pas"], correct: 1 }, { question: "Comment les dauphins apprennent-ils à chasser ?", answers: ["Instinct seulement", "En observant leur mère", "En essayant seuls", "Ils savent déjà"], correct: 1 }, { question: "Quelle est la forme du crâne des dauphins ?", answers: ["Rond", "Pointu", "Allongé", "Plat"], correct: 2 }, { question: "Les dauphins ont-ils des cordes vocales ?", answers: ["Oui", "Non", "Seulement les mâles", "Seulement les femelles"], correct: 1 }, { question: "Comment les dauphins se dirigent-ils dans l'obscurité ?", answers: ["Au hasard", "Avec l'écholocation", "En suivant les courants", "Grâce aux étoiles"], correct: 1 }, { question: "Quel est le rôle du père chez les dauphins ?", answers: ["Protéger le bébé", "Chasser pour la famille", "Enseigner la nage", "Aucun rôle particulier"], correct: 3 }, { question: "Comment les dauphins montrent-ils leur affection ?", answers: ["En se touchant", "En chantant", "En nageant ensemble", "Toutes ces réponses"], correct: 3 }, { question: "Quelle est la principale différence entre dauphins et marsouins ?", answers: ["La taille", "La forme du bec", "La couleur", "L'habitat"], correct: 1 }]; function getRandomDolphinName() { // If all names are used, reset the used names array if (usedNames.length >= dolphinNames.length) { usedNames = []; } var availableNames = []; for (var i = 0; i < dolphinNames.length; i++) { var name = dolphinNames[i]; var nameUsed = false; for (var j = 0; j < usedNames.length; j++) { if (usedNames[j] === name) { nameUsed = true; break; } } if (!nameUsed) { availableNames.push(name); } } // Pick random name from available names var randomIndex = Math.floor(Math.random() * availableNames.length); var selectedName = availableNames[randomIndex]; // Mark this name as used usedNames.push(selectedName); return selectedName; } function updateUI() { if (coinText) coinText.setText('Dauphicoins: ' + dauphicoins); if (foodText) foodText.setText('Dauphibouffe: ' + dauphibouffe); if (trainerText) trainerText.setText('Dresseur Niv.' + trainerLevel + ' (' + trainerXP + ' XP)'); if (totalDolphinsRaisedText) totalDolphinsRaisedText.setText('Dauphins élevés: ' + totalDolphinsRaised); // Save to storage with error handling try { storage.dauphicoins = dauphicoins; storage.dauphibouffe = dauphibouffe; storage.trainerLevel = trainerLevel; storage.trainerXP = trainerXP; storage.totalDolphinsRaised = totalDolphinsRaised; // Save complete dolphin progression data including names, levels, and owned hoops var dolphinData = []; for (var i = 0; i < dolphins.length; i++) { var dolphin = dolphins[i]; if (dolphin && dolphin.dolphinName) { dolphinData.push({ name: dolphin.dolphinName, happiness: dolphin.happiness, level: dolphin.level, maxHappiness: dolphin.maxHappiness, lastPetTime: dolphin.lastPetTime, lastFeedTime: dolphin.lastFeedTime || 0, ownedHoops: dolphin.ownedHoops || [], x: dolphin.x, y: dolphin.y, petCooldown: dolphin.petCooldown }); } } storage.dolphinData = dolphinData; // Save complete game progression storage.dolphinCount = dolphins.length; storage.usedNames = usedNames; } catch (e) { console.log('Storage error:', e); } } function createShopModal() { if (shopModal) return; shopModal = new Container(); var modalBg = shopModal.attachAsset('modalBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); var panel = shopModal.attachAsset('panel', { anchorX: 0.5, anchorY: 0.5 }); var titleText = new Text2('Boutique des Dauphins', { size: 70, fill: 0x000000 }); titleText.anchor.set(0.5, 0.5); titleText.x = 0; titleText.y = -320; shopModal.addChild(titleText); // New dolphin button var newDolphinBtn = shopModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -180, scaleX: 1.5, scaleY: 1.3 }); var dolphinBtnText = new Text2('Nouveau Dauphin (100 Dauphicoins)', { size: 36, fill: 0x000000 }); dolphinBtnText.anchor.set(0.5, 0.5); dolphinBtnText.x = 0; dolphinBtnText.y = -180; shopModal.addChild(dolphinBtnText); // Hoop buttons for each type for (var h = 0; h < hoopTypes.length; h++) { var hoopBtn = shopModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: (h % 3 - 1) * 300, y: -60 + Math.floor(h / 3) * 140, scaleX: 1.4, scaleY: 1.2 }); var hoopBtnText = new Text2(hoopTypes[h].name + ' (' + hoopTypes[h].price + ' Dauphicoins)', { size: 32, fill: 0x000000 }); hoopBtnText.anchor.set(0.5, 0.5); hoopBtnText.x = (h % 3 - 1) * 300; hoopBtnText.y = -60 + Math.floor(h / 3) * 140; shopModal.addChild(hoopBtnText); } // Close button var closeBtn = shopModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 250, scaleX: 1.2, scaleY: 1.0 }); var closeBtnText = new Text2('Fermer', { size: 42, fill: 0x000000 }); closeBtnText.anchor.set(0.5, 0.5); closeBtnText.x = 0; closeBtnText.y = 250; shopModal.addChild(closeBtnText); shopModal.x = 1024; shopModal.y = 1366; shopModal.down = function (x, y, obj) { var localPos; if (obj.parent && obj.parent.toGlobal) { localPos = shopModal.toLocal(obj.parent.toGlobal(obj.position)); } else { localPos = { x: x, y: y }; } // Check new dolphin button if (localPos.x >= -150 && localPos.x <= 150 && localPos.y >= -220 && localPos.y <= -140) { if (dauphicoins >= 100) { dauphicoins -= 100; // Create unique random name for new dolphin var randomName = getRandomDolphinName(); var newDolphin = new Dolphin(randomName, 400 + dolphins.length % 3 * 300, 800 + Math.floor(dolphins.length / 3) * 300); dolphins.push(newDolphin); game.addChild(newDolphin); // Increment total dolphins raised counter totalDolphinsRaised++; updateUI(); LK.getSound('coin').play(); } } // Check hoop buttons for (var h = 0; h < hoopTypes.length; h++) { var btnX = (h % 3 - 1) * 300; var btnY = -60 + Math.floor(h / 3) * 140; if (localPos.x >= btnX - 140 && localPos.x <= btnX + 140 && localPos.y >= btnY - 50 && localPos.y <= btnY + 50) { if (dauphicoins >= hoopTypes[h].price) { selectedHoopType = h; game.removeChild(shopModal); shopModal = null; createHoopSelectionModal(); } break; } } // Check close button if (localPos.x >= -120 && localPos.x <= 120 && localPos.y >= 210 && localPos.y <= 290) { game.removeChild(shopModal); shopModal = null; } }; game.addChild(shopModal); } function createHoopSelectionModal() { if (hoopSelectionModal || dolphins.length === 0) return; hoopSelectionModal = new Container(); var modalBg = hoopSelectionModal.attachAsset('modalBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); var panel = hoopSelectionModal.attachAsset('panel', { anchorX: 0.5, anchorY: 0.5 }); var titleText = new Text2('Choisir un Dauphin pour le Cerceau', { size: 50, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 0; titleText.y = -300; hoopSelectionModal.addChild(titleText); // Dolphin selection buttons for (var d = 0; d < dolphins.length; d++) { var dolphinBtn = hoopSelectionModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -200 + d * 80 }); var dolphinBtnText = new Text2(dolphins[d].dolphinName, { size: 36, fill: 0xFFFFFF }); dolphinBtnText.anchor.set(0.5, 0.5); dolphinBtnText.x = 0; dolphinBtnText.y = -200 + d * 80; hoopSelectionModal.addChild(dolphinBtnText); } // Cancel button var cancelBtn = hoopSelectionModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 200, scaleX: 0.8, scaleY: 0.8 }); var cancelBtnText = new Text2('Annuler', { size: 36, fill: 0xFFFFFF }); cancelBtnText.anchor.set(0.5, 0.5); cancelBtnText.x = 0; cancelBtnText.y = 200; hoopSelectionModal.addChild(cancelBtnText); hoopSelectionModal.x = 1024; hoopSelectionModal.y = 1366; hoopSelectionModal.down = function (x, y, obj) { var localPos; if (obj.parent && obj.parent.toGlobal) { localPos = hoopSelectionModal.toLocal(obj.parent.toGlobal(obj.position)); } else { localPos = { x: x, y: y }; } // Check dolphin buttons for (var d = 0; d < dolphins.length; d++) { var buttonY = -200 + d * 80; if (localPos.x >= -100 && localPos.x <= 100 && localPos.y >= buttonY - 30 && localPos.y <= buttonY + 30) { // Purchase hoop for selected dolphin dauphicoins -= hoopTypes[selectedHoopType].price; dolphins[d].addHoopIcon(selectedHoopType); // Save updated hoop data immediately updateUI(); LK.getSound('coin').play(); game.removeChild(hoopSelectionModal); hoopSelectionModal = null; break; } } // Check cancel button if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 170 && localPos.y <= 230) { game.removeChild(hoopSelectionModal); hoopSelectionModal = null; } }; game.addChild(hoopSelectionModal); } function createDolphinNamingModal() { if (namingModal || dolphins.length === 0) return; namingModal = new Container(); var modalBg = namingModal.attachAsset('modalBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); var panel = namingModal.attachAsset('panel', { anchorX: 0.5, anchorY: 0.5 }); var titleText = new Text2('Choisir un Dauphin à Renommer', { size: 50, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 0; titleText.y = -300; namingModal.addChild(titleText); // Dolphin selection buttons for (var d = 0; d < dolphins.length; d++) { var dolphinBtn = namingModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -200 + d * 80 }); var dolphinBtnText = new Text2(dolphins[d].dolphinName, { size: 36, fill: 0xFFFFFF }); dolphinBtnText.anchor.set(0.5, 0.5); dolphinBtnText.x = 0; dolphinBtnText.y = -200 + d * 80; namingModal.addChild(dolphinBtnText); } // Cancel button var cancelBtn = namingModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 200, scaleX: 0.8, scaleY: 0.8 }); var cancelBtnText = new Text2('Annuler', { size: 36, fill: 0xFFFFFF }); cancelBtnText.anchor.set(0.5, 0.5); cancelBtnText.x = 0; cancelBtnText.y = 200; namingModal.addChild(cancelBtnText); namingModal.x = 1024; namingModal.y = 1366; namingModal.down = function (x, y, obj) { var localPos; if (obj.parent && obj.parent.toGlobal) { localPos = namingModal.toLocal(obj.parent.toGlobal(obj.position)); } else { localPos = { x: x, y: y }; } // Check dolphin buttons for (var d = 0; d < dolphins.length; d++) { var buttonY = -200 + d * 80; if (localPos.x >= -100 && localPos.x <= 100 && localPos.y >= buttonY - 30 && localPos.y <= buttonY + 30) { selectedDolphinForNaming = dolphins[d]; currentInputText = dolphins[d].dolphinName; game.removeChild(namingModal); namingModal = null; createKeyboardModal(); break; } } // Check cancel button if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 170 && localPos.y <= 230) { game.removeChild(namingModal); namingModal = null; } }; game.addChild(namingModal); } function createKeyboardModal() { if (keyboardModal) return; keyboardModal = new Container(); var modalBg = keyboardModal.attachAsset('modalBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.95 }); var panel = keyboardModal.attachAsset('panel', { anchorX: 0.5, anchorY: 0.5 }); var titleText = new Text2('Nouveau Nom', { size: 60, fill: 0x000000 }); titleText.anchor.set(0.5, 0.5); titleText.x = 0; titleText.y = -350; keyboardModal.addChild(titleText); // Input display var inputText = new Text2(currentInputText, { size: 50, fill: 0x1976D2 }); inputText.anchor.set(0.5, 0.5); inputText.x = 0; inputText.y = -280; keyboardModal.addChild(inputText); // Keyboard layout with better spacing var keyboard = [['A', 'B', 'C', 'D', 'E', 'F', 'G'], ['H', 'I', 'J', 'K', 'L', 'M', 'N'], ['O', 'P', 'Q', 'R', 'S', 'T', 'U'], ['V', 'W', 'X', 'Y', 'Z', '1', '2'], ['3', '4', '5', '6', '7', '8', '9'], ['0', 'ESPACE', 'EFFACER', 'TOUT EFFACER', 'VALIDER']]; for (var row = 0; row < keyboard.length; row++) { for (var col = 0; col < keyboard[row].length; col++) { var key = keyboard[row][col]; // Better spacing calculation to prevent overlap var keySpacing = key.length > 1 ? 120 : 90; var startOffset = row === 5 ? -200 : (keyboard[row].length - 1) * keySpacing * -0.5; var keyBtn = keyboardModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: startOffset + col * keySpacing, y: -150 + row * 70, scaleX: key.length > 1 ? 1.6 : 1.2, scaleY: 1.2 }); // Set button background color based on key type if (key === 'EFFACER') { keyBtn.tint = 0xFF6644; } else if (key === 'TOUT EFFACER') { keyBtn.tint = 0xFF4444; } else if (key === 'VALIDER') { keyBtn.tint = 0x44AA44; } else if (key === 'ESPACE') { keyBtn.tint = 0x4488CC; } else { keyBtn.tint = 0xFFFFFF; } // Create text with better visibility var keyText = new Text2(key, { size: key.length > 1 ? 20 : 28, fill: 0x000000 }); keyText.anchor.set(0.5, 0.5); keyText.x = startOffset + col * keySpacing; keyText.y = -150 + row * 70; keyboardModal.addChild(keyText); } } keyboardModal.x = 1024; keyboardModal.y = 1366; keyboardModal.down = function (x, y, obj) { var localPos; if (obj.parent && obj.parent.toGlobal) { localPos = keyboardModal.toLocal(obj.parent.toGlobal(obj.position)); } else { localPos = { x: x, y: y }; } // Check keyboard buttons with updated spacing for (var row = 0; row < keyboard.length; row++) { for (var col = 0; col < keyboard[row].length; col++) { var key = keyboard[row][col]; // Updated position calculation to match button creation var keySpacing = key.length > 1 ? 120 : 90; var startOffset = row === 5 ? -200 : (keyboard[row].length - 1) * keySpacing * -0.5; var keyX = startOffset + col * keySpacing; var keyY = -150 + row * 70; var keyWidth = key.length > 1 ? 96 : 54; // Based on scale factors var keyHeight = 36; // Based on scale factors if (localPos.x >= keyX - keyWidth && localPos.x <= keyX + keyWidth && localPos.y >= keyY - keyHeight && localPos.y <= keyY + keyHeight) { if (key === 'ESPACE') { if (currentInputText.length < 15) { currentInputText += ' '; } } else if (key === 'EFFACER') { if (currentInputText.length > 0) { currentInputText = currentInputText.slice(0, -1); } } else if (key === 'TOUT EFFACER') { currentInputText = ''; } else if (key === 'VALIDER') { if (currentInputText.length > 0 && selectedDolphinForNaming) { // Permanently set the custom name chosen by player selectedDolphinForNaming.dolphinName = currentInputText; // Update dolphin name display to show custom name selectedDolphinForNaming.nameText.setText(currentInputText); // Immediately force save the custom name to ensure it persists between sessions try { var dolphinData = []; for (var i = 0; i < dolphins.length; i++) { var dolphin = dolphins[i]; if (dolphin && dolphin.dolphinName) { dolphinData.push({ name: dolphin.dolphinName, happiness: dolphin.happiness, level: dolphin.level, maxHappiness: dolphin.maxHappiness, lastPetTime: dolphin.lastPetTime, ownedHoops: dolphin.ownedHoops || [], x: dolphin.x, y: dolphin.y }); } } storage.dolphinData = dolphinData; // Force save immediately to ensure persistence storage.dolphinCount = dolphins.length; } catch (e) { console.log('Storage error saving dolphin name:', e); } // Also update UI to save other game data updateUI(); } game.removeChild(keyboardModal); keyboardModal = null; selectedDolphinForNaming = null; currentInputText = ''; return; } else if (currentInputText.length < 15) { currentInputText += key; } inputText.setText(currentInputText); return; } } } }; game.addChild(keyboardModal); } function createQuizModal() { if (quizModal) return; var currentQuestion = quizQuestions[Math.floor(Math.random() * quizQuestions.length)]; quizModal = new Container(); var modalBg = quizModal.attachAsset('modalBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); var panel = quizModal.attachAsset('panel', { anchorX: 0.5, anchorY: 0.5 }); var titleText = new Text2('Quiz Marin', { size: 60, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 0; titleText.y = -350; quizModal.addChild(titleText); var questionText = new Text2(currentQuestion.question, { size: 44, fill: 0xFFFFFF }); questionText.anchor.set(0.5, 0.5); questionText.x = 0; questionText.y = -250; quizModal.addChild(questionText); // Answer buttons for (var i = 0; i < currentQuestion.answers.length; i++) { var answerBtn = quizModal.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -100 + i * 80 }); var answerText = new Text2(currentQuestion.answers[i], { size: 36, fill: 0xFFFFFF }); answerText.anchor.set(0.5, 0.5); answerText.x = 0; answerText.y = -100 + i * 80; quizModal.addChild(answerText); } quizModal.x = 1024; quizModal.y = 1366; quizModal.down = function (x, y, obj) { var localPos; if (obj.parent && obj.parent.toGlobal) { localPos = quizModal.toLocal(obj.parent.toGlobal(obj.position)); } else { localPos = { x: x, y: y }; } // Check answer buttons for (var i = 0; i < currentQuestion.answers.length; i++) { var buttonY = -100 + i * 80; if (localPos.x >= -100 && localPos.x <= 100 && localPos.y >= buttonY - 30 && localPos.y <= buttonY + 30) { if (i === currentQuestion.correct) { var quizReward = Math.floor(Math.random() * 21) + 10; // Random between 10-30 dauphibouffe += quizReward; LK.getSound('correct').play(); LK.effects.flashScreen(0x4caf50, 500); } else { LK.effects.flashScreen(0xf44336, 500); } updateUI(); game.removeChild(quizModal); quizModal = null; break; } } }; game.addChild(quizModal); } // Create background corals for (var i = 0; i < 8; i++) { var coral = new Coral(i, 200 + i * 250, 2700 - Math.random() * 200); corals.push(coral); game.addChild(coral); } // Load saved dolphins from storage - they persist between game sessions if (storage.dolphinData && storage.dolphinData.length > 0) { // Restore each saved dolphin with all their properties for (var i = 0; i < storage.dolphinData.length; i++) { var data = storage.dolphinData[i]; if (data && data.name) { // Create dolphin with the exact saved custom name - this is permanent var savedDolphin = new Dolphin(data.name, data.x || 1024, data.y || 1200); savedDolphin.happiness = data.happiness || 50; savedDolphin.level = data.level || 1; savedDolphin.maxHappiness = data.maxHappiness || 100; savedDolphin.lastPetTime = data.lastPetTime || 0; savedDolphin.petCooldown = data.petCooldown || 60000; savedDolphin.ownedHoops = data.ownedHoops || []; savedDolphin.lastFeedTime = data.lastFeedTime || 0; // Ensure the custom name is permanently retained - no generic names savedDolphin.dolphinName = data.name; // Display the custom name permanently savedDolphin.nameText.setText(data.name); // Update level display to match saved level using stored reference if (savedDolphin.levelText) { savedDolphin.levelText.setText('Niv.' + savedDolphin.level); } // Update happiness bars to reflect saved state savedDolphin.updateHappinessBar(); // Initialize expression system savedDolphin.updateExpression(); // Restore hoop icons without triggering additional saves for (var h = 0; h < savedDolphin.ownedHoops.length; h++) { // Create small hoop icon var hoopAssetNames = ['hoop', 'hoopCute', 'hoopTricolore', 'hoopEnflamme', 'hoopOcean']; var hoopIcon = savedDolphin.attachAsset(hoopAssetNames[savedDolphin.ownedHoops[h]] || 'hoop', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); // Position icon next to dolphin hoopIcon.x = 120 + h * 40; hoopIcon.y = 0; savedDolphin.hoopIcons.push(hoopIcon); } dolphins.push(savedDolphin); game.addChild(savedDolphin); // Ensure saved names are marked as used to prevent duplicates if (usedNames.indexOf(data.name) === -1) { usedNames.push(data.name); } } } } else { // Create starting dolphin with random name that can be changed var randomStartName = getRandomDolphinName(); var firstDolphin = new Dolphin(randomStartName, 1024, 1200); // Initialize expression system for new dolphin firstDolphin.updateExpression(); dolphins.push(firstDolphin); game.addChild(firstDolphin); // Increment total dolphins raised counter for first dolphin totalDolphinsRaised++; } // Create UI coinText = new Text2('Dauphicoins: ' + dauphicoins, { size: 48, fill: 0xFFEB3B }); coinText.anchor.set(0, 0); coinText.x = 120; coinText.y = 50; LK.gui.topLeft.addChild(coinText); foodText = new Text2('Dauphibouffe: ' + dauphibouffe, { size: 48, fill: 0x8BC34A }); foodText.anchor.set(0, 0); foodText.x = 120; foodText.y = 120; LK.gui.topLeft.addChild(foodText); trainerText = new Text2('Dresseur Niv.' + trainerLevel + ' (' + trainerXP + ' XP)', { size: 48, fill: 0xFFFFFF }); trainerText.anchor.set(0.5, 0); trainerText.x = 0; trainerText.y = 50; LK.gui.top.addChild(trainerText); totalDolphinsRaisedText = new Text2('Dauphins élevés: ' + totalDolphinsRaised, { size: 40, fill: 0x00E676 }); totalDolphinsRaisedText.anchor.set(0.5, 0); totalDolphinsRaisedText.x = 0; totalDolphinsRaisedText.y = 110; LK.gui.top.addChild(totalDolphinsRaisedText); // Shop button var shopBtn = LK.gui.bottomLeft.attachAsset('shopButton', { anchorX: 0, anchorY: 1, x: 50, y: -50 }); var shopBtnText = new Text2('Boutique', { size: 36, fill: 0xFFFFFF }); shopBtnText.anchor.set(0, 1); shopBtnText.x = 50; shopBtnText.y = -50; LK.gui.bottomLeft.addChild(shopBtnText); // Quiz button var quizBtn = LK.gui.bottomRight.attachAsset('quizButton', { anchorX: 1, anchorY: 1, x: -50, y: -50 }); var quizBtnText = new Text2('Quiz', { size: 36, fill: 0xFFFFFF }); quizBtnText.anchor.set(1, 1); quizBtnText.x = -50; quizBtnText.y = -50; LK.gui.bottomRight.addChild(quizBtnText); // Naming button var namingBtn = LK.gui.bottomRight.attachAsset('button', { anchorX: 1, anchorY: 1, x: -50, y: -130, scaleX: 1.2, scaleY: 0.8 }); var namingBtnText = new Text2('Nommer un dauphin', { size: 28, fill: 0xFFFFFF }); namingBtnText.anchor.set(1, 1); namingBtnText.x = -50; namingBtnText.y = -130; LK.gui.bottomRight.addChild(namingBtnText); // Button event handlers LK.gui.bottomLeft.down = function (x, y, obj) { createShopModal(); }; LK.gui.bottomRight.down = function (x, y, obj) { // Check if naming button was clicked if (y >= -160 && y <= -100) { createDolphinNamingModal(); } else if (y >= -80 && y <= -20) { createQuizModal(); } }; // Play background music LK.playMusic('underwater'); // Initialize UI updateUI(); // Game update loop game.update = function () { // Update all dolphins for (var i = 0; i < dolphins.length; i++) { dolphins[i].update(); } // Update corals for (var i = 0; i < corals.length; i++) { corals[i].update(); } // Update hoops for (var i = 0; i < hoops.length; i++) { hoops[i].update(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Coral = Container.expand(function (type, x, y) {
var self = Container.call(this);
var coralTypes = ['coral1', 'coral2', 'coral3'];
var coralAsset = coralTypes[type % 3];
var coral = self.attachAsset(coralAsset, {
anchorX: 0.5,
anchorY: 1
});
self.x = x || 0;
self.y = y || 0;
self.update = function () {
// Gentle swaying animation
coral.rotation = Math.sin(Date.now() * 0.0008) * 0.1;
};
return self;
});
var Dolphin = Container.expand(function (name, x, y) {
var self = Container.call(this);
// Dolphin properties
self.dolphinName = name || 'Flipper';
self.happiness = Math.floor(Math.random() * 50) + 25;
self.level = 1;
self.lastPetTime = 0;
self.petCooldown = 60000; // 1 minute
self.maxHappiness = 100;
self.ownedHoops = []; // Track owned hoops
self.hoopIcons = []; // Visual representations of owned hoops
// Expression/emotion system
self.currentExpression = 'neutral';
self.lastFeedTime = 0;
self.expressionElements = [];
self.lastExpressionUpdate = 0;
// Graphics
var dolphinBody = self.attachAsset('dolphin', {
anchorX: 0.5,
anchorY: 0.5
});
// Happiness bar background
var happinessBarBg = self.attachAsset('happinessBarBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -80
});
// Happiness bar
var happinessBar = self.attachAsset('happinessBar', {
anchorX: 0,
anchorY: 0.5,
x: -80,
y: -80
});
// Cooldown bar background
var cooldownBarBg = self.attachAsset('cooldownBarBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -55
});
// Cooldown bar
var cooldownBar = self.attachAsset('cooldownBar', {
anchorX: 0,
anchorY: 0.5,
x: -80,
y: -55
});
// Name text
var nameText = new Text2(self.dolphinName, {
size: 36,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.x = 0;
nameText.y = -120;
self.addChild(nameText);
// Store reference for external access
self.nameText = nameText;
// Pet button
var petButton = self.attachAsset('petButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 80
});
var petButtonText = new Text2('Caresser', {
size: 28,
fill: 0xFFFFFF
});
petButtonText.anchor.set(0.5, 0.5);
petButtonText.x = 0;
petButtonText.y = 80;
self.addChild(petButtonText);
// Feed button
var feedButton = self.attachAsset('petButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 140
});
feedButton.tint = 0xE91E63; // Pink color
var feedButtonText = new Text2('Nourrir', {
size: 28,
fill: 0xFFFFFF
});
feedButtonText.anchor.set(0.5, 0.5);
feedButtonText.x = 0;
feedButtonText.y = 140;
self.addChild(feedButtonText);
// Level text
var levelText = new Text2('Niv.' + self.level, {
size: 28,
fill: 0xFFEB3B
});
levelText.anchor.set(0.5, 0.5);
levelText.x = 0;
levelText.y = -100;
self.addChild(levelText);
// Store reference for external access
self.levelText = levelText;
self.updateHappinessBar = function () {
var percentage = self.happiness / self.maxHappiness;
happinessBar.scaleX = percentage;
if (self.happiness >= self.maxHappiness) {
self.levelUp();
}
};
self.updateCooldownBar = function () {
var now = Date.now();
var timeSinceLastPet = now - self.lastPetTime;
var cooldownRemaining = Math.max(0, self.petCooldown - timeSinceLastPet);
var percentage = cooldownRemaining / self.petCooldown;
cooldownBar.scaleX = percentage;
cooldownBar.visible = percentage > 0;
cooldownBarBg.visible = percentage > 0;
};
self.clearExpressionElements = function () {
for (var i = 0; i < self.expressionElements.length; i++) {
self.expressionElements[i].destroy();
}
self.expressionElements = [];
};
self.updateExpression = function () {
var now = Date.now();
// Clear old expression elements
self.clearExpressionElements();
// Determine current expression based on state
var timeSinceLastPet = now - self.lastPetTime;
var timeSinceLastFeed = now - self.lastFeedTime;
if (self.happiness >= 80) {
self.currentExpression = 'happy';
} else if (timeSinceLastFeed > 300000 || self.happiness < 30) {
// 5 minutes since last feed or low happiness
self.currentExpression = 'hungry';
} else if (self.happiness < 50 && timeSinceLastPet > 180000) {
// Low happiness and 3 minutes since pet
self.currentExpression = 'sad';
} else {
self.currentExpression = 'neutral';
}
// Create expression elements based on current state
if (self.currentExpression === 'happy') {
// Create floating hearts
for (var i = 0; i < 3; i++) {
var heart = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 60 - 30,
y: -40 - Math.random() * 20
});
self.expressionElements.push(heart);
// Animate hearts floating up
tween(heart, {
y: heart.y - 50,
alpha: 0
}, {
duration: 2000,
easing: tween.easeOut
});
}
// Create sparkles
for (var i = 0; i < 4; i++) {
var sparkle = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 80 - 40,
y: Math.random() * 40 - 20
});
self.expressionElements.push(sparkle);
// Animate sparkles twinkling
tween(sparkle, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 1500,
easing: tween.easeInOut
});
}
} else if (self.currentExpression === 'hungry') {
// Create thought bubble with fish
var thoughtBubble = self.attachAsset('thoughtBubble', {
anchorX: 0.5,
anchorY: 0.5,
x: 60,
y: -60,
alpha: 0.8
});
self.expressionElements.push(thoughtBubble);
var fish = self.attachAsset('fish', {
anchorX: 0.5,
anchorY: 0.5,
x: 60,
y: -60
});
self.expressionElements.push(fish);
// Animate thought bubble pulsing
tween(thoughtBubble, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(thoughtBubble, {
scaleX: 1,
scaleY: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
} else if (self.currentExpression === 'sad') {
// Tint dolphin slightly blue for sadness
tween(dolphinBody, {
tint: 0x8bb6d6
}, {
duration: 500
});
} else {
// Neutral - ensure normal tint
tween(dolphinBody, {
tint: 0x4fa8d8
}, {
duration: 500
});
}
self.lastExpressionUpdate = now;
};
self.addHoopIcon = function (hoopType) {
// Add hoop type to owned hoops
self.ownedHoops.push(hoopType);
// Create small hoop icon
var hoopAssetNames = ['hoop', 'hoopCute', 'hoopTricolore', 'hoopEnflamme', 'hoopOcean'];
var hoopIcon = self.attachAsset(hoopAssetNames[hoopType] || 'hoop', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
// Position icon next to dolphin
var iconIndex = self.hoopIcons.length;
hoopIcon.x = 120 + iconIndex * 40;
hoopIcon.y = 0;
self.hoopIcons.push(hoopIcon);
// Save hoop progression immediately
updateUI();
};
self.canPet = function () {
var now = Date.now();
return now - self.lastPetTime >= self.petCooldown;
};
self.pet = function () {
if (!self.canPet()) return false;
self.lastPetTime = Date.now();
self.happiness = Math.min(self.happiness + 10, self.maxHappiness);
dauphicoins += 3;
dauphibouffe += 5; // Player gains 5 dauphibouffe per pet
// Pet animation
tween(dolphinBody, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
tween(dolphinBody, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
LK.getSound('pet').play();
LK.getSound('coin').play();
self.updateHappinessBar();
// Trigger happy expression immediately
self.updateExpression();
updateUI();
return true;
};
self.feed = function () {
if (dauphibouffe <= 0) return false;
dauphibouffe--;
self.lastFeedTime = Date.now();
self.happiness = Math.min(self.happiness + 20, self.maxHappiness);
// Feed animation
tween(dolphinBody, {
tint: 0x8bc34a
}, {
duration: 300
});
tween(dolphinBody, {
tint: 0x4fa8d8
}, {
duration: 300
});
self.updateHappinessBar();
// Update expression after feeding
self.updateExpression();
updateUI();
return true;
};
self.levelUp = function () {
self.level++;
self.happiness = 0;
self.maxHappiness += 10;
trainerXP += 10;
// Level up animation
LK.effects.flashObject(self, 0xffeb3b, 1000);
LK.getSound('levelup').play();
self.levelText.setText('Niv.' + self.level);
self.updateHappinessBar();
updateUI();
// Check trainer level up
var newTrainerLevel = Math.floor(trainerXP / 50) + 1;
if (newTrainerLevel > trainerLevel) {
trainerLevel = newTrainerLevel;
updateUI();
}
};
self.down = function (x, y, obj) {
var localPos;
if (obj && obj.parent && obj.parent.toGlobal) {
localPos = self.toLocal(obj.parent.toGlobal(obj.position));
} else {
localPos = {
x: x,
y: y
};
}
// Check if pet button was clicked
if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 50 && localPos.y <= 110) {
if (self.canPet()) {
self.pet();
}
} else if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 110 && localPos.y <= 170) {
// Check if feed button was clicked
if (dauphibouffe > 0) {
self.feed();
}
} else {
// Original dolphin body click behavior
if (self.canPet()) {
self.pet();
} else {
// Show feed option if has food
if (dauphibouffe > 0) {
self.feed();
}
}
}
};
self.update = function () {
self.updateCooldownBar();
// Gentle floating animation
dolphinBody.y = Math.sin(Date.now() * 0.001) * 10;
// Update expressions every 3 seconds
var now = Date.now();
if (now - self.lastExpressionUpdate > 3000) {
self.updateExpression();
}
};
// Position dolphin
self.x = x || 0;
self.y = y || 0;
// Initialize bars
self.updateHappinessBar();
self.updateCooldownBar();
return self;
});
var Hoop = Container.expand(function (x, y) {
var self = Container.call(this);
var hoop = self.attachAsset('hoop', {
anchorX: 0.5,
anchorY: 0.5
});
// Make hoop hollow by reducing alpha in center
hoop.alpha = 0.3;
self.hoopType = 0; // Default to golden hoop
self.attachedDolphin = null;
self.x = x || 0;
self.y = y || 0;
self.update = function () {
// Gentle rotation
hoop.rotation += 0.01;
// Apply color based on hoop type
if (hoopTypes && hoopTypes[self.hoopType]) {
hoop.tint = hoopTypes[self.hoopType].color;
}
// Follow attached dolphin if any
if (self.attachedDolphin) {
self.x = self.attachedDolphin.x;
self.y = self.attachedDolphin.y - 50;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0066cc
});
/****
* Game Code
****/
// Add custom ocean background
var oceanBg = game.attachAsset('oceanBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Game variables
var dolphins = [];
var corals = [];
var hoops = [];
var dauphicoins = storage.dauphicoins !== undefined ? storage.dauphicoins : 50;
var dauphibouffe = storage.dauphibouffe !== undefined ? storage.dauphibouffe : 3;
var trainerLevel = storage.trainerLevel !== undefined ? storage.trainerLevel : 1;
var trainerXP = storage.trainerXP !== undefined ? storage.trainerXP : 0;
var totalDolphinsRaised = storage.totalDolphinsRaised !== undefined ? storage.totalDolphinsRaised : 0;
// Database of 80 unique dolphin names
var dolphinNames = ['Luna', 'Neptune', 'Océan', 'Azur', 'Coral', 'Marina', 'Aqua', 'Bleu', 'Splash', 'Bubble', 'Wave', 'Tide', 'Storm', 'Misty', 'Pearl', 'Crystal', 'Echo', 'Sonic', 'Melody', 'Harmony', 'Rhythm', 'Jazz', 'Blues', 'Tempo', 'Atlas', 'Zeus', 'Triton', 'Poseidon', 'Apollo', 'Orion', 'Cosmos', 'Nova', 'Star', 'Comet', 'Galaxy', 'Meteor', 'Stellar', 'Solar', 'Lunar', 'Cosmic', 'Aquarius', 'Pisces', 'Delphinus', 'Cetus', 'Orca', 'Narval', 'Beluga', 'Marlin', 'Spirit', 'Dream', 'Hope', 'Joy', 'Grace', 'Faith', 'Love', 'Peace', 'Thunder', 'Lightning', 'Rain', 'Frost', 'Snow', 'Ice', 'Wind', 'Breeze', 'Coral', 'Reef', 'Lagoon', 'Bay', 'Cove', 'Shore', 'Beach', 'Dune', 'Captain', 'Admiral', 'Sailor', 'Navigator', 'Explorer', 'Voyager', 'Pioneer', 'Ranger'];
// Track used names to avoid duplicates - load from storage
var usedNames = storage.usedNames || [];
// Hoop types with their properties
var hoopTypes = [{
name: 'Cerceau Doré',
price: 50,
color: 0xFFD700
}, {
name: 'Cerceau Cute',
price: 25,
color: 0xFF69B4
}, {
name: 'Cerceau Tricolore',
price: 34,
color: 0x0000FF
}, {
name: 'Cerceau Enflammé',
price: 45,
color: 0xFF4500
}, {
name: 'Cerceau de l\'Océan',
price: 50,
color: 0x00CED1
}];
// UI elements
var coinText, foodText, trainerText, totalDolphinsRaisedText;
var shopModal = null;
var quizModal = null;
var hoopSelectionModal = null;
var dolphinSelectionModal = null;
var namingModal = null;
var keyboardModal = null;
var selectedHoopType = null;
var selectedDolphinForNaming = null;
var currentInputText = '';
// Quiz questions
var quizQuestions = [{
question: "Qu'utilisent les dauphins pour l'écholocation ?",
answers: ["Ondes sonores", "Ondes lumineuses", "Champs magnétiques", "Champs électriques"],
correct: 0
}, {
question: "Combien de temps les dauphins peuvent-ils retenir leur respiration ?",
answers: ["5 minutes", "15 minutes", "30 minutes", "1 heure"],
correct: 1
}, {
question: "Comment appelle-t-on un groupe de dauphins ?",
answers: ["Banc", "Pod", "Troupeau", "Meute"],
correct: 1
}, {
question: "Comment les dauphins dorment-ils ?",
answers: ["Complètement inconscients", "Une moitié du cerveau à la fois", "Ne dorment jamais", "Seulement la nuit"],
correct: 1
}, {
question: "Quelle est la plus grande espèce de dauphin ?",
answers: ["Grand dauphin", "Orque", "Dauphin à long bec", "Dauphin sombre"],
correct: 1
}, {
question: "À quelle profondeur les dauphins peuvent-ils plonger ?",
answers: ["50 mètres", "200 mètres", "500 mètres", "1000 mètres"],
correct: 2
}, {
question: "Combien de dents a un grand dauphin adulte ?",
answers: ["20-30", "40-50", "80-100", "120-140"],
correct: 2
}, {
question: "Quelle est la vitesse maximale d'un dauphin ?",
answers: ["15 km/h", "35 km/h", "55 km/h", "75 km/h"],
correct: 2
}, {
question: "Où vivent les dauphins roses ?",
answers: ["Océan Pacifique", "Mer Méditerranée", "Fleuve Amazone", "Océan Arctique"],
correct: 2
}, {
question: "Quel est le nom scientifique du grand dauphin ?",
answers: ["Delphinus delphis", "Tursiops truncatus", "Orcinus orca", "Stenella longirostris"],
correct: 1
}, {
question: "Combien pèse un dauphin adulte en moyenne ?",
answers: ["50-100 kg", "150-300 kg", "400-500 kg", "600-800 kg"],
correct: 1
}, {
question: "Quelle est la durée de gestation d'un dauphin ?",
answers: ["6 mois", "9 mois", "12 mois", "18 mois"],
correct: 2
}, {
question: "À quel âge les dauphins atteignent-ils la maturité sexuelle ?",
answers: ["2-3 ans", "5-7 ans", "10-12 ans", "15-20 ans"],
correct: 1
}, {
question: "Comment les dauphins communiquent-ils principalement ?",
answers: ["Gestes", "Couleurs", "Sons et sifflements", "Odeurs"],
correct: 2
}, {
question: "Quelle est la température corporelle d'un dauphin ?",
answers: ["32°C", "37°C", "42°C", "45°C"],
correct: 1
}, {
question: "Combien de chambres a le cœur d'un dauphin ?",
answers: ["2", "3", "4", "5"],
correct: 2
}, {
question: "Quel pourcentage du cerveau utilisent les dauphins ?",
answers: ["10%", "50%", "80%", "100%"],
correct: 3
}, {
question: "Comment s'appelle le bébé dauphin ?",
answers: ["Poulain", "Veau", "Petit", "Chiot"],
correct: 1
}, {
question: "Quelle distance peuvent parcourir les dauphins en une journée ?",
answers: ["10 km", "50 km", "100 km", "200 km"],
correct: 2
}, {
question: "Dans quels océans trouve-t-on des dauphins ?",
answers: ["Seulement Atlantique", "Seulement Pacifique", "Tous les océans", "Seulement Indien"],
correct: 2
}, {
question: "Combien de vertèbres cervicales ont les dauphins ?",
answers: ["5", "7", "9", "12"],
correct: 1
}, {
question: "Quelle est la principale menace pour les dauphins ?",
answers: ["Requins", "Pollution", "Maladies", "Froid"],
correct: 1
}, {
question: "Comment les dauphins régulent-ils leur température ?",
answers: ["Poils", "Graisse", "Glandes sudoripares", "Respiration"],
correct: 1
}, {
question: "Quel est le plus petit dauphin au monde ?",
answers: ["Dauphin de Maui", "Dauphin commun", "Marsouin du Pacifique", "Dauphin de Risso"],
correct: 0
}, {
question: "Combien d'estomacs ont les dauphins ?",
answers: ["1", "2", "3", "4"],
correct: 2
}, {
question: "À quelle fréquence respirent les dauphins ?",
answers: ["En continu", "Toutes les 30 secondes", "Toutes les 8-10 minutes", "Une fois par heure"],
correct: 2
}, {
question: "Comment les dauphins voient-ils sous l'eau ?",
answers: ["Mal", "En noir et blanc", "Très bien", "Seulement de près"],
correct: 2
}, {
question: "Quelle est la structure sociale des dauphins ?",
answers: ["Solitaires", "En couples", "En groupes", "En familles"],
correct: 2
}, {
question: "Comment s'appelle l'évent des dauphins ?",
answers: ["Narine", "Spiracle", "Blowhole", "Trou respiratoire"],
correct: 2
}, {
question: "Quelle est la portée de l'écholocation des dauphins ?",
answers: ["10 mètres", "50 mètres", "100 mètres", "500 mètres"],
correct: 2
}, {
question: "Les dauphins sont-ils des mammifères ?",
answers: ["Non, ce sont des poissons", "Oui", "Parfois", "Seulement les grands"],
correct: 1
}, {
question: "Quel sens est le plus développé chez les dauphins ?",
answers: ["Vue", "Ouïe", "Odorat", "Toucher"],
correct: 1
}, {
question: "Combien de sons différents un dauphin peut-il produire ?",
answers: ["10", "50", "200", "Plus de 1000"],
correct: 3
}, {
question: "Comment les dauphins reconnaissent-ils leurs proches ?",
answers: ["Par l'odeur", "Par la vue", "Par leur signature sifflée", "Par le toucher"],
correct: 2
}, {
question: "Quelle est la couleur typique d'un grand dauphin ?",
answers: ["Blanc", "Gris", "Bleu", "Noir"],
correct: 1
}, {
question: "À quelle profondeur vivent principalement les dauphins ?",
answers: ["Surface seulement", "0-200 mètres", "200-500 mètres", "Plus de 1000 mètres"],
correct: 1
}, {
question: "Comment naissent les bébés dauphins ?",
answers: ["Tête première", "Queue première", "Sur le côté", "Dans un œuf"],
correct: 1
}, {
question: "Combien de temps un bébé dauphin reste-t-il avec sa mère ?",
answers: ["6 mois", "1-2 ans", "3-6 ans", "10 ans"],
correct: 2
}, {
question: "Quel est le prédateur principal des dauphins ?",
answers: ["Baleine", "Requin", "Pieuvre", "Raie"],
correct: 1
}, {
question: "Comment les dauphins chassent-ils en groupe ?",
answers: ["Individuellement", "En cercle", "En ligne", "Au hasard"],
correct: 1
}, {
question: "Quelle est la nourriture préférée des dauphins ?",
answers: ["Algues", "Plancton", "Poissons", "Crustacés"],
correct: 2
}, {
question: "Les dauphins peuvent-ils sauter hors de l'eau ?",
answers: ["Non, jamais", "Rarement", "Souvent", "Seulement en captivité"],
correct: 2
}, {
question: "Combien de nageoires a un dauphin ?",
answers: ["2", "3", "4", "5"],
correct: 3
}, {
question: "Quelle est la fonction de la nageoire dorsale ?",
answers: ["Nager plus vite", "Stabilité", "Communication", "Respiration"],
correct: 1
}, {
question: "Comment s'appelle la queue d'un dauphin ?",
answers: ["Palme", "Nageoire caudale", "Gouvernail", "Aileron"],
correct: 1
}, {
question: "Les dauphins migrent-ils ?",
answers: ["Non, jamais", "Oui, tous", "Certaines espèces", "Seulement les jeunes"],
correct: 2
}, {
question: "Quelle distance peut couvrir l'écholocation d'un dauphin ?",
answers: ["1 mètre", "10 mètres", "100 mètres", "1 kilomètre"],
correct: 2
}, {
question: "Comment les dauphins expriment-ils la joie ?",
answers: ["En chantant", "En sautant", "En nageant vite", "En se touchant"],
correct: 1
}, {
question: "Quel âge peut atteindre un dauphin en liberté ?",
answers: ["10-15 ans", "20-25 ans", "30-45 ans", "50-60 ans"],
correct: 2
}, {
question: "Comment les dauphins nettoient-ils leur peau ?",
answers: ["Avec du sable", "En se frottant", "Avec des algues", "Avec l'aide d'autres poissons"],
correct: 3
}, {
question: "Quelle partie du corps utilisent les dauphins pour l'écholocation ?",
answers: ["Les yeux", "Le melon", "La queue", "Les nageoires"],
correct: 1
}, {
question: "Les dauphins peuvent-ils reconnaître leur reflet ?",
answers: ["Non", "Oui", "Parfois", "Seulement les adultes"],
correct: 1
}, {
question: "Comment s'appelle le groupe de dauphins qui chasse ensemble ?",
answers: ["Banc", "Pod", "Alliance", "Meute"],
correct: 2
}, {
question: "Quelle est la particularité des dauphins roses d'Amazonie ?",
answers: ["Ils volent", "Ils vivent en eau douce", "Ils sont très petits", "Ils ne nagent pas"],
correct: 1
}, {
question: "Comment les dauphins apprennent-ils à chasser ?",
answers: ["Instinct seulement", "En observant leur mère", "En essayant seuls", "Ils savent déjà"],
correct: 1
}, {
question: "Quelle est la forme du crâne des dauphins ?",
answers: ["Rond", "Pointu", "Allongé", "Plat"],
correct: 2
}, {
question: "Les dauphins ont-ils des cordes vocales ?",
answers: ["Oui", "Non", "Seulement les mâles", "Seulement les femelles"],
correct: 1
}, {
question: "Comment les dauphins se dirigent-ils dans l'obscurité ?",
answers: ["Au hasard", "Avec l'écholocation", "En suivant les courants", "Grâce aux étoiles"],
correct: 1
}, {
question: "Quel est le rôle du père chez les dauphins ?",
answers: ["Protéger le bébé", "Chasser pour la famille", "Enseigner la nage", "Aucun rôle particulier"],
correct: 3
}, {
question: "Comment les dauphins montrent-ils leur affection ?",
answers: ["En se touchant", "En chantant", "En nageant ensemble", "Toutes ces réponses"],
correct: 3
}, {
question: "Quelle est la principale différence entre dauphins et marsouins ?",
answers: ["La taille", "La forme du bec", "La couleur", "L'habitat"],
correct: 1
}];
function getRandomDolphinName() {
// If all names are used, reset the used names array
if (usedNames.length >= dolphinNames.length) {
usedNames = [];
}
var availableNames = [];
for (var i = 0; i < dolphinNames.length; i++) {
var name = dolphinNames[i];
var nameUsed = false;
for (var j = 0; j < usedNames.length; j++) {
if (usedNames[j] === name) {
nameUsed = true;
break;
}
}
if (!nameUsed) {
availableNames.push(name);
}
}
// Pick random name from available names
var randomIndex = Math.floor(Math.random() * availableNames.length);
var selectedName = availableNames[randomIndex];
// Mark this name as used
usedNames.push(selectedName);
return selectedName;
}
function updateUI() {
if (coinText) coinText.setText('Dauphicoins: ' + dauphicoins);
if (foodText) foodText.setText('Dauphibouffe: ' + dauphibouffe);
if (trainerText) trainerText.setText('Dresseur Niv.' + trainerLevel + ' (' + trainerXP + ' XP)');
if (totalDolphinsRaisedText) totalDolphinsRaisedText.setText('Dauphins élevés: ' + totalDolphinsRaised);
// Save to storage with error handling
try {
storage.dauphicoins = dauphicoins;
storage.dauphibouffe = dauphibouffe;
storage.trainerLevel = trainerLevel;
storage.trainerXP = trainerXP;
storage.totalDolphinsRaised = totalDolphinsRaised;
// Save complete dolphin progression data including names, levels, and owned hoops
var dolphinData = [];
for (var i = 0; i < dolphins.length; i++) {
var dolphin = dolphins[i];
if (dolphin && dolphin.dolphinName) {
dolphinData.push({
name: dolphin.dolphinName,
happiness: dolphin.happiness,
level: dolphin.level,
maxHappiness: dolphin.maxHappiness,
lastPetTime: dolphin.lastPetTime,
lastFeedTime: dolphin.lastFeedTime || 0,
ownedHoops: dolphin.ownedHoops || [],
x: dolphin.x,
y: dolphin.y,
petCooldown: dolphin.petCooldown
});
}
}
storage.dolphinData = dolphinData;
// Save complete game progression
storage.dolphinCount = dolphins.length;
storage.usedNames = usedNames;
} catch (e) {
console.log('Storage error:', e);
}
}
function createShopModal() {
if (shopModal) return;
shopModal = new Container();
var modalBg = shopModal.attachAsset('modalBg', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
var panel = shopModal.attachAsset('panel', {
anchorX: 0.5,
anchorY: 0.5
});
var titleText = new Text2('Boutique des Dauphins', {
size: 70,
fill: 0x000000
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -320;
shopModal.addChild(titleText);
// New dolphin button
var newDolphinBtn = shopModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -180,
scaleX: 1.5,
scaleY: 1.3
});
var dolphinBtnText = new Text2('Nouveau Dauphin (100 Dauphicoins)', {
size: 36,
fill: 0x000000
});
dolphinBtnText.anchor.set(0.5, 0.5);
dolphinBtnText.x = 0;
dolphinBtnText.y = -180;
shopModal.addChild(dolphinBtnText);
// Hoop buttons for each type
for (var h = 0; h < hoopTypes.length; h++) {
var hoopBtn = shopModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: (h % 3 - 1) * 300,
y: -60 + Math.floor(h / 3) * 140,
scaleX: 1.4,
scaleY: 1.2
});
var hoopBtnText = new Text2(hoopTypes[h].name + ' (' + hoopTypes[h].price + ' Dauphicoins)', {
size: 32,
fill: 0x000000
});
hoopBtnText.anchor.set(0.5, 0.5);
hoopBtnText.x = (h % 3 - 1) * 300;
hoopBtnText.y = -60 + Math.floor(h / 3) * 140;
shopModal.addChild(hoopBtnText);
}
// Close button
var closeBtn = shopModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 250,
scaleX: 1.2,
scaleY: 1.0
});
var closeBtnText = new Text2('Fermer', {
size: 42,
fill: 0x000000
});
closeBtnText.anchor.set(0.5, 0.5);
closeBtnText.x = 0;
closeBtnText.y = 250;
shopModal.addChild(closeBtnText);
shopModal.x = 1024;
shopModal.y = 1366;
shopModal.down = function (x, y, obj) {
var localPos;
if (obj.parent && obj.parent.toGlobal) {
localPos = shopModal.toLocal(obj.parent.toGlobal(obj.position));
} else {
localPos = {
x: x,
y: y
};
}
// Check new dolphin button
if (localPos.x >= -150 && localPos.x <= 150 && localPos.y >= -220 && localPos.y <= -140) {
if (dauphicoins >= 100) {
dauphicoins -= 100;
// Create unique random name for new dolphin
var randomName = getRandomDolphinName();
var newDolphin = new Dolphin(randomName, 400 + dolphins.length % 3 * 300, 800 + Math.floor(dolphins.length / 3) * 300);
dolphins.push(newDolphin);
game.addChild(newDolphin);
// Increment total dolphins raised counter
totalDolphinsRaised++;
updateUI();
LK.getSound('coin').play();
}
}
// Check hoop buttons
for (var h = 0; h < hoopTypes.length; h++) {
var btnX = (h % 3 - 1) * 300;
var btnY = -60 + Math.floor(h / 3) * 140;
if (localPos.x >= btnX - 140 && localPos.x <= btnX + 140 && localPos.y >= btnY - 50 && localPos.y <= btnY + 50) {
if (dauphicoins >= hoopTypes[h].price) {
selectedHoopType = h;
game.removeChild(shopModal);
shopModal = null;
createHoopSelectionModal();
}
break;
}
}
// Check close button
if (localPos.x >= -120 && localPos.x <= 120 && localPos.y >= 210 && localPos.y <= 290) {
game.removeChild(shopModal);
shopModal = null;
}
};
game.addChild(shopModal);
}
function createHoopSelectionModal() {
if (hoopSelectionModal || dolphins.length === 0) return;
hoopSelectionModal = new Container();
var modalBg = hoopSelectionModal.attachAsset('modalBg', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
var panel = hoopSelectionModal.attachAsset('panel', {
anchorX: 0.5,
anchorY: 0.5
});
var titleText = new Text2('Choisir un Dauphin pour le Cerceau', {
size: 50,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -300;
hoopSelectionModal.addChild(titleText);
// Dolphin selection buttons
for (var d = 0; d < dolphins.length; d++) {
var dolphinBtn = hoopSelectionModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -200 + d * 80
});
var dolphinBtnText = new Text2(dolphins[d].dolphinName, {
size: 36,
fill: 0xFFFFFF
});
dolphinBtnText.anchor.set(0.5, 0.5);
dolphinBtnText.x = 0;
dolphinBtnText.y = -200 + d * 80;
hoopSelectionModal.addChild(dolphinBtnText);
}
// Cancel button
var cancelBtn = hoopSelectionModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 200,
scaleX: 0.8,
scaleY: 0.8
});
var cancelBtnText = new Text2('Annuler', {
size: 36,
fill: 0xFFFFFF
});
cancelBtnText.anchor.set(0.5, 0.5);
cancelBtnText.x = 0;
cancelBtnText.y = 200;
hoopSelectionModal.addChild(cancelBtnText);
hoopSelectionModal.x = 1024;
hoopSelectionModal.y = 1366;
hoopSelectionModal.down = function (x, y, obj) {
var localPos;
if (obj.parent && obj.parent.toGlobal) {
localPos = hoopSelectionModal.toLocal(obj.parent.toGlobal(obj.position));
} else {
localPos = {
x: x,
y: y
};
}
// Check dolphin buttons
for (var d = 0; d < dolphins.length; d++) {
var buttonY = -200 + d * 80;
if (localPos.x >= -100 && localPos.x <= 100 && localPos.y >= buttonY - 30 && localPos.y <= buttonY + 30) {
// Purchase hoop for selected dolphin
dauphicoins -= hoopTypes[selectedHoopType].price;
dolphins[d].addHoopIcon(selectedHoopType);
// Save updated hoop data immediately
updateUI();
LK.getSound('coin').play();
game.removeChild(hoopSelectionModal);
hoopSelectionModal = null;
break;
}
}
// Check cancel button
if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 170 && localPos.y <= 230) {
game.removeChild(hoopSelectionModal);
hoopSelectionModal = null;
}
};
game.addChild(hoopSelectionModal);
}
function createDolphinNamingModal() {
if (namingModal || dolphins.length === 0) return;
namingModal = new Container();
var modalBg = namingModal.attachAsset('modalBg', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
var panel = namingModal.attachAsset('panel', {
anchorX: 0.5,
anchorY: 0.5
});
var titleText = new Text2('Choisir un Dauphin à Renommer', {
size: 50,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -300;
namingModal.addChild(titleText);
// Dolphin selection buttons
for (var d = 0; d < dolphins.length; d++) {
var dolphinBtn = namingModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -200 + d * 80
});
var dolphinBtnText = new Text2(dolphins[d].dolphinName, {
size: 36,
fill: 0xFFFFFF
});
dolphinBtnText.anchor.set(0.5, 0.5);
dolphinBtnText.x = 0;
dolphinBtnText.y = -200 + d * 80;
namingModal.addChild(dolphinBtnText);
}
// Cancel button
var cancelBtn = namingModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 200,
scaleX: 0.8,
scaleY: 0.8
});
var cancelBtnText = new Text2('Annuler', {
size: 36,
fill: 0xFFFFFF
});
cancelBtnText.anchor.set(0.5, 0.5);
cancelBtnText.x = 0;
cancelBtnText.y = 200;
namingModal.addChild(cancelBtnText);
namingModal.x = 1024;
namingModal.y = 1366;
namingModal.down = function (x, y, obj) {
var localPos;
if (obj.parent && obj.parent.toGlobal) {
localPos = namingModal.toLocal(obj.parent.toGlobal(obj.position));
} else {
localPos = {
x: x,
y: y
};
}
// Check dolphin buttons
for (var d = 0; d < dolphins.length; d++) {
var buttonY = -200 + d * 80;
if (localPos.x >= -100 && localPos.x <= 100 && localPos.y >= buttonY - 30 && localPos.y <= buttonY + 30) {
selectedDolphinForNaming = dolphins[d];
currentInputText = dolphins[d].dolphinName;
game.removeChild(namingModal);
namingModal = null;
createKeyboardModal();
break;
}
}
// Check cancel button
if (localPos.x >= -80 && localPos.x <= 80 && localPos.y >= 170 && localPos.y <= 230) {
game.removeChild(namingModal);
namingModal = null;
}
};
game.addChild(namingModal);
}
function createKeyboardModal() {
if (keyboardModal) return;
keyboardModal = new Container();
var modalBg = keyboardModal.attachAsset('modalBg', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.95
});
var panel = keyboardModal.attachAsset('panel', {
anchorX: 0.5,
anchorY: 0.5
});
var titleText = new Text2('Nouveau Nom', {
size: 60,
fill: 0x000000
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -350;
keyboardModal.addChild(titleText);
// Input display
var inputText = new Text2(currentInputText, {
size: 50,
fill: 0x1976D2
});
inputText.anchor.set(0.5, 0.5);
inputText.x = 0;
inputText.y = -280;
keyboardModal.addChild(inputText);
// Keyboard layout with better spacing
var keyboard = [['A', 'B', 'C', 'D', 'E', 'F', 'G'], ['H', 'I', 'J', 'K', 'L', 'M', 'N'], ['O', 'P', 'Q', 'R', 'S', 'T', 'U'], ['V', 'W', 'X', 'Y', 'Z', '1', '2'], ['3', '4', '5', '6', '7', '8', '9'], ['0', 'ESPACE', 'EFFACER', 'TOUT EFFACER', 'VALIDER']];
for (var row = 0; row < keyboard.length; row++) {
for (var col = 0; col < keyboard[row].length; col++) {
var key = keyboard[row][col];
// Better spacing calculation to prevent overlap
var keySpacing = key.length > 1 ? 120 : 90;
var startOffset = row === 5 ? -200 : (keyboard[row].length - 1) * keySpacing * -0.5;
var keyBtn = keyboardModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: startOffset + col * keySpacing,
y: -150 + row * 70,
scaleX: key.length > 1 ? 1.6 : 1.2,
scaleY: 1.2
});
// Set button background color based on key type
if (key === 'EFFACER') {
keyBtn.tint = 0xFF6644;
} else if (key === 'TOUT EFFACER') {
keyBtn.tint = 0xFF4444;
} else if (key === 'VALIDER') {
keyBtn.tint = 0x44AA44;
} else if (key === 'ESPACE') {
keyBtn.tint = 0x4488CC;
} else {
keyBtn.tint = 0xFFFFFF;
}
// Create text with better visibility
var keyText = new Text2(key, {
size: key.length > 1 ? 20 : 28,
fill: 0x000000
});
keyText.anchor.set(0.5, 0.5);
keyText.x = startOffset + col * keySpacing;
keyText.y = -150 + row * 70;
keyboardModal.addChild(keyText);
}
}
keyboardModal.x = 1024;
keyboardModal.y = 1366;
keyboardModal.down = function (x, y, obj) {
var localPos;
if (obj.parent && obj.parent.toGlobal) {
localPos = keyboardModal.toLocal(obj.parent.toGlobal(obj.position));
} else {
localPos = {
x: x,
y: y
};
}
// Check keyboard buttons with updated spacing
for (var row = 0; row < keyboard.length; row++) {
for (var col = 0; col < keyboard[row].length; col++) {
var key = keyboard[row][col];
// Updated position calculation to match button creation
var keySpacing = key.length > 1 ? 120 : 90;
var startOffset = row === 5 ? -200 : (keyboard[row].length - 1) * keySpacing * -0.5;
var keyX = startOffset + col * keySpacing;
var keyY = -150 + row * 70;
var keyWidth = key.length > 1 ? 96 : 54; // Based on scale factors
var keyHeight = 36; // Based on scale factors
if (localPos.x >= keyX - keyWidth && localPos.x <= keyX + keyWidth && localPos.y >= keyY - keyHeight && localPos.y <= keyY + keyHeight) {
if (key === 'ESPACE') {
if (currentInputText.length < 15) {
currentInputText += ' ';
}
} else if (key === 'EFFACER') {
if (currentInputText.length > 0) {
currentInputText = currentInputText.slice(0, -1);
}
} else if (key === 'TOUT EFFACER') {
currentInputText = '';
} else if (key === 'VALIDER') {
if (currentInputText.length > 0 && selectedDolphinForNaming) {
// Permanently set the custom name chosen by player
selectedDolphinForNaming.dolphinName = currentInputText;
// Update dolphin name display to show custom name
selectedDolphinForNaming.nameText.setText(currentInputText);
// Immediately force save the custom name to ensure it persists between sessions
try {
var dolphinData = [];
for (var i = 0; i < dolphins.length; i++) {
var dolphin = dolphins[i];
if (dolphin && dolphin.dolphinName) {
dolphinData.push({
name: dolphin.dolphinName,
happiness: dolphin.happiness,
level: dolphin.level,
maxHappiness: dolphin.maxHappiness,
lastPetTime: dolphin.lastPetTime,
ownedHoops: dolphin.ownedHoops || [],
x: dolphin.x,
y: dolphin.y
});
}
}
storage.dolphinData = dolphinData;
// Force save immediately to ensure persistence
storage.dolphinCount = dolphins.length;
} catch (e) {
console.log('Storage error saving dolphin name:', e);
}
// Also update UI to save other game data
updateUI();
}
game.removeChild(keyboardModal);
keyboardModal = null;
selectedDolphinForNaming = null;
currentInputText = '';
return;
} else if (currentInputText.length < 15) {
currentInputText += key;
}
inputText.setText(currentInputText);
return;
}
}
}
};
game.addChild(keyboardModal);
}
function createQuizModal() {
if (quizModal) return;
var currentQuestion = quizQuestions[Math.floor(Math.random() * quizQuestions.length)];
quizModal = new Container();
var modalBg = quizModal.attachAsset('modalBg', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
var panel = quizModal.attachAsset('panel', {
anchorX: 0.5,
anchorY: 0.5
});
var titleText = new Text2('Quiz Marin', {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -350;
quizModal.addChild(titleText);
var questionText = new Text2(currentQuestion.question, {
size: 44,
fill: 0xFFFFFF
});
questionText.anchor.set(0.5, 0.5);
questionText.x = 0;
questionText.y = -250;
quizModal.addChild(questionText);
// Answer buttons
for (var i = 0; i < currentQuestion.answers.length; i++) {
var answerBtn = quizModal.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -100 + i * 80
});
var answerText = new Text2(currentQuestion.answers[i], {
size: 36,
fill: 0xFFFFFF
});
answerText.anchor.set(0.5, 0.5);
answerText.x = 0;
answerText.y = -100 + i * 80;
quizModal.addChild(answerText);
}
quizModal.x = 1024;
quizModal.y = 1366;
quizModal.down = function (x, y, obj) {
var localPos;
if (obj.parent && obj.parent.toGlobal) {
localPos = quizModal.toLocal(obj.parent.toGlobal(obj.position));
} else {
localPos = {
x: x,
y: y
};
}
// Check answer buttons
for (var i = 0; i < currentQuestion.answers.length; i++) {
var buttonY = -100 + i * 80;
if (localPos.x >= -100 && localPos.x <= 100 && localPos.y >= buttonY - 30 && localPos.y <= buttonY + 30) {
if (i === currentQuestion.correct) {
var quizReward = Math.floor(Math.random() * 21) + 10; // Random between 10-30
dauphibouffe += quizReward;
LK.getSound('correct').play();
LK.effects.flashScreen(0x4caf50, 500);
} else {
LK.effects.flashScreen(0xf44336, 500);
}
updateUI();
game.removeChild(quizModal);
quizModal = null;
break;
}
}
};
game.addChild(quizModal);
}
// Create background corals
for (var i = 0; i < 8; i++) {
var coral = new Coral(i, 200 + i * 250, 2700 - Math.random() * 200);
corals.push(coral);
game.addChild(coral);
}
// Load saved dolphins from storage - they persist between game sessions
if (storage.dolphinData && storage.dolphinData.length > 0) {
// Restore each saved dolphin with all their properties
for (var i = 0; i < storage.dolphinData.length; i++) {
var data = storage.dolphinData[i];
if (data && data.name) {
// Create dolphin with the exact saved custom name - this is permanent
var savedDolphin = new Dolphin(data.name, data.x || 1024, data.y || 1200);
savedDolphin.happiness = data.happiness || 50;
savedDolphin.level = data.level || 1;
savedDolphin.maxHappiness = data.maxHappiness || 100;
savedDolphin.lastPetTime = data.lastPetTime || 0;
savedDolphin.petCooldown = data.petCooldown || 60000;
savedDolphin.ownedHoops = data.ownedHoops || [];
savedDolphin.lastFeedTime = data.lastFeedTime || 0;
// Ensure the custom name is permanently retained - no generic names
savedDolphin.dolphinName = data.name;
// Display the custom name permanently
savedDolphin.nameText.setText(data.name);
// Update level display to match saved level using stored reference
if (savedDolphin.levelText) {
savedDolphin.levelText.setText('Niv.' + savedDolphin.level);
}
// Update happiness bars to reflect saved state
savedDolphin.updateHappinessBar();
// Initialize expression system
savedDolphin.updateExpression();
// Restore hoop icons without triggering additional saves
for (var h = 0; h < savedDolphin.ownedHoops.length; h++) {
// Create small hoop icon
var hoopAssetNames = ['hoop', 'hoopCute', 'hoopTricolore', 'hoopEnflamme', 'hoopOcean'];
var hoopIcon = savedDolphin.attachAsset(hoopAssetNames[savedDolphin.ownedHoops[h]] || 'hoop', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
// Position icon next to dolphin
hoopIcon.x = 120 + h * 40;
hoopIcon.y = 0;
savedDolphin.hoopIcons.push(hoopIcon);
}
dolphins.push(savedDolphin);
game.addChild(savedDolphin);
// Ensure saved names are marked as used to prevent duplicates
if (usedNames.indexOf(data.name) === -1) {
usedNames.push(data.name);
}
}
}
} else {
// Create starting dolphin with random name that can be changed
var randomStartName = getRandomDolphinName();
var firstDolphin = new Dolphin(randomStartName, 1024, 1200);
// Initialize expression system for new dolphin
firstDolphin.updateExpression();
dolphins.push(firstDolphin);
game.addChild(firstDolphin);
// Increment total dolphins raised counter for first dolphin
totalDolphinsRaised++;
}
// Create UI
coinText = new Text2('Dauphicoins: ' + dauphicoins, {
size: 48,
fill: 0xFFEB3B
});
coinText.anchor.set(0, 0);
coinText.x = 120;
coinText.y = 50;
LK.gui.topLeft.addChild(coinText);
foodText = new Text2('Dauphibouffe: ' + dauphibouffe, {
size: 48,
fill: 0x8BC34A
});
foodText.anchor.set(0, 0);
foodText.x = 120;
foodText.y = 120;
LK.gui.topLeft.addChild(foodText);
trainerText = new Text2('Dresseur Niv.' + trainerLevel + ' (' + trainerXP + ' XP)', {
size: 48,
fill: 0xFFFFFF
});
trainerText.anchor.set(0.5, 0);
trainerText.x = 0;
trainerText.y = 50;
LK.gui.top.addChild(trainerText);
totalDolphinsRaisedText = new Text2('Dauphins élevés: ' + totalDolphinsRaised, {
size: 40,
fill: 0x00E676
});
totalDolphinsRaisedText.anchor.set(0.5, 0);
totalDolphinsRaisedText.x = 0;
totalDolphinsRaisedText.y = 110;
LK.gui.top.addChild(totalDolphinsRaisedText);
// Shop button
var shopBtn = LK.gui.bottomLeft.attachAsset('shopButton', {
anchorX: 0,
anchorY: 1,
x: 50,
y: -50
});
var shopBtnText = new Text2('Boutique', {
size: 36,
fill: 0xFFFFFF
});
shopBtnText.anchor.set(0, 1);
shopBtnText.x = 50;
shopBtnText.y = -50;
LK.gui.bottomLeft.addChild(shopBtnText);
// Quiz button
var quizBtn = LK.gui.bottomRight.attachAsset('quizButton', {
anchorX: 1,
anchorY: 1,
x: -50,
y: -50
});
var quizBtnText = new Text2('Quiz', {
size: 36,
fill: 0xFFFFFF
});
quizBtnText.anchor.set(1, 1);
quizBtnText.x = -50;
quizBtnText.y = -50;
LK.gui.bottomRight.addChild(quizBtnText);
// Naming button
var namingBtn = LK.gui.bottomRight.attachAsset('button', {
anchorX: 1,
anchorY: 1,
x: -50,
y: -130,
scaleX: 1.2,
scaleY: 0.8
});
var namingBtnText = new Text2('Nommer un dauphin', {
size: 28,
fill: 0xFFFFFF
});
namingBtnText.anchor.set(1, 1);
namingBtnText.x = -50;
namingBtnText.y = -130;
LK.gui.bottomRight.addChild(namingBtnText);
// Button event handlers
LK.gui.bottomLeft.down = function (x, y, obj) {
createShopModal();
};
LK.gui.bottomRight.down = function (x, y, obj) {
// Check if naming button was clicked
if (y >= -160 && y <= -100) {
createDolphinNamingModal();
} else if (y >= -80 && y <= -20) {
createQuizModal();
}
};
// Play background music
LK.playMusic('underwater');
// Initialize UI
updateUI();
// Game update loop
game.update = function () {
// Update all dolphins
for (var i = 0; i < dolphins.length; i++) {
dolphins[i].update();
}
// Update corals
for (var i = 0; i < corals.length; i++) {
corals[i].update();
}
// Update hoops
for (var i = 0; i < hoops.length; i++) {
hoops[i].update();
}
};
Bouton bleu. In-Game asset. 2d. High contrast. No shadows
Coral. In-Game asset. 2d. High contrast. No shadows
Coral bleu. In-Game asset. 2d. High contrast. No shadows
Coral rouge. In-Game asset. 2d. High contrast. No shadows
nourriture pour dauphins. In-Game asset. 2d. High contrast. No shadows
Cerceau dorée. In-Game asset. 2d. High contrast. No shadows
Fond d'écran océan mignon. In-Game asset. 2d. High contrast. No shadows
Dauphin. In-Game asset. 2d. High contrast. No shadows
Cerceau de couleur rose mignon. In-Game asset. 2d. High contrast. No shadows
Cerceau enflammé. In-Game asset. 2d. High contrast. No shadows
Cerceau tricolore. In-Game asset. 2d. High contrast. No shadows
Cerceau de l'océan. In-Game asset. 2d. High contrast. No shadows
Poisson. In-Game asset. 2d. High contrast. No shadows
Coeur. In-Game asset. 2d. High contrast. No shadows
éclat. In-Game asset. 2d. High contrast. No shadows
Fond d'écran océan mignon. In-Game asset. 2d. High contrast. No shadows