/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Equality point class var EqualityPoint = Container.expand(function () { var self = Container.call(this); var eqGfx = self.attachAsset('equality', { anchorX: 0.5, anchorY: 0.5 }); self.width = eqGfx.width; self.height = eqGfx.height; return self; }); /**** * Discrimination Situations ****/ // Hero class var Hero = Container.expand(function () { var self = Container.call(this); var heroGfx = self.attachAsset('hero', { anchorX: 0.5, anchorY: 1 }); self.width = heroGfx.width; self.height = heroGfx.height; self.vx = 0; self.vy = 0; self.isOnGround = false; self.jumpPower = -60; self.moveSpeed = 22; self.gravity = 5; self.update = function () { // Apply gravity self.vy += self.gravity; self.x += self.vx; self.y += self.vy; }; return self; }); // Obstacle class var Obstacle = Container.expand(function () { var self = Container.call(this); var obsGfx = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 1 }); self.width = obsGfx.width; self.height = obsGfx.height; return self; }); // Platform class var Platform = Container.expand(function () { var self = Container.call(this); var platGfx = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.width = platGfx.width; self.height = platGfx.height; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf1f5f9 }); /**** * Game Code ****/ // Add custom background image to the game, covering the entire game area var backgroundImg = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: GAME_WIDTH, height: GAME_HEIGHT }); game.addChild(backgroundImg); /**** * Game Code /**** * Discrimination Situations ****/ // Discrimination popup background (box, white) // Equality point (ellipse, green) // Obstacle (ellipse, red) // Platform (box, gray) // Character: Woman of color (box, purple) // Game constants var discriminationSituations = [{ text: "Un collègue fait une remarque raciste au travail.", choices: ["Ignorer la remarque", "Rire avec lui", "Signaler à la RH", "Répondre calmement", "Quitter le travail", "Faire une remarque agressive"], correct: [2, 3] }, { text: "On refuse de vous servir dans un café.", choices: ["Demander poliment pourquoi", "Partir sans rien dire", "Faire un scandale", "Appeler la police", "Filmer la scène", "Accepter la situation"], correct: [0, 3, 4] }, { text: "Un enfant subit des moqueries à l’école à cause de sa couleur de peau.", choices: ["En parler à l’enseignant", "Ignorer la situation", "Encourager l’enfant à répondre", "Rire avec les autres", "Organiser une discussion sur la diversité", "Punir les moqueurs"], correct: [0, 2, 4] }, { text: "Une entreprise refuse votre candidature sans raison.", choices: ["Demander un retour", "Porter plainte pour discrimination", "Chercher un autre emploi", "Publier sur les réseaux sociaux", "Accepter sans rien faire", "Envoyer un message d’insulte"], correct: [0, 1, 3] }, { text: "Un chauffeur de bus ne s’arrête pas pour vous.", choices: ["Attendre le prochain bus", "Signaler à la compagnie", "Crier sur le chauffeur", "Filmer la scène", "Ignorer l’incident", "Demander de l’aide à d’autres passagers"], correct: [1, 3, 5] }, { text: "Un agent de sécurité vous suit dans un magasin sans raison.", choices: ["Lui demander calmement pourquoi", "Ignorer et continuer vos achats", "Faire un scandale", "Quitter le magasin", "Filmer la scène", "Appeler la direction"], correct: [0, 1, 5] }, { text: "Un professeur fait une remarque stéréotypée sur votre culture.", choices: ["Lui expliquer pourquoi c'est blessant", "Ignorer", "Rire avec la classe", "En parler à la direction", "Répondre agressivement", "Demander des excuses"], correct: [0, 3, 5] }, { text: "On vous refuse l'entrée d'une boîte de nuit.", choices: ["Demander la raison", "Accepter sans rien dire", "Filmer la scène", "Appeler la police", "Faire un scandale", "Chercher un autre lieu"], correct: [0, 2, 3] }, { text: "Un inconnu fait une remarque sur vos cheveux dans la rue.", choices: ["Répondre poliment", "Ignorer", "Faire une remarque sur son apparence", "Expliquer pourquoi ce n'est pas approprié", "Rire", "S'énerver"], correct: [0, 3] }, { text: "Un enfant est exclu d'un jeu à cause de sa couleur de peau.", choices: ["Intervenir et inclure l'enfant", "Ignorer", "En parler aux parents", "Rire avec les autres", "Organiser un jeu inclusif", "Punir les enfants"], correct: [0, 2, 4] }, { text: "Un propriétaire refuse de vous louer un appartement à cause de votre nom.", choices: ["Demander une explication", "Accepter sans rien dire", "Porter plainte pour discrimination", "Chercher un autre logement", "Publier sur les réseaux sociaux", "Faire une remarque agressive"], correct: [0, 2, 4] }, { text: "Un médecin minimise vos symptômes en raison de votre origine.", choices: ["Demander un second avis", "Accepter le diagnostic", "Changer de médecin", "Signaler à l'ordre des médecins", "Ignorer la situation", "Faire un scandale"], correct: [0, 2, 3] }, { text: "Un policier vous contrôle sans raison apparente.", choices: ["Demander poliment la raison", "Refuser de coopérer", "Filmer la scène", "S'énerver", "Rester calme et coopérer", "Faire un scandale"], correct: [0, 2, 4] }, { text: "Un camarade de classe refuse de travailler avec vous.", choices: ["Demander pourquoi", "Ignorer et travailler seul", "En parler à l’enseignant", "Faire une remarque agressive", "Chercher un autre camarade", "Rire de la situation"], correct: [0, 2, 4] }, { text: "Un commerçant vous surveille de façon insistante.", choices: ["Lui demander calmement pourquoi", "Ignorer", "Quitter le magasin", "Faire un scandale", "Filmer la scène", "Appeler la direction"], correct: [0, 1, 5] }, { text: "Un collègue fait des blagues sur votre accent.", choices: ["Lui expliquer que c'est blessant", "Rire avec lui", "Ignorer", "En parler à la RH", "Faire une remarque agressive", "Changer de sujet"], correct: [0, 3] }, { text: "On vous attribue systématiquement les tâches les moins valorisantes.", choices: ["Demander une répartition équitable", "Accepter sans rien dire", "En parler à la direction", "Faire un scandale", "Ignorer", "Chercher un autre poste"], correct: [0, 2] }, { text: "Un inconnu vous interpelle dans la rue avec un surnom stéréotypé.", choices: ["Répondre poliment", "Ignorer", "Expliquer pourquoi ce n'est pas approprié", "Faire une remarque sur son apparence", "S'énerver", "Rire"], correct: [0, 2] }, { text: "Un enseignant refuse de prononcer correctement votre prénom.", choices: ["Lui expliquer l'importance de votre prénom", "Ignorer", "Faire une remarque agressive", "En parler à la direction", "Changer de classe", "Rire avec la classe"], correct: [0, 3] }, { text: "Un voisin fait des remarques sur votre famille à cause de votre origine.", choices: ["Lui expliquer que c'est blessant", "Ignorer", "Faire un scandale", "En parler à la mairie", "Répondre calmement", "Changer de sujet"], correct: [0, 3, 4] }, // Nouvelles situations ajoutées { text: "Un recruteur vous demande si vous comptez porter le voile au travail.", choices: ["Répondre poliment à la question", "Refuser de répondre", "Signaler la question à la direction", "Ignorer la question", "Faire un scandale", "Changer de sujet"], correct: [0, 2] }, { text: "Un client refuse d’être servi par vous à cause de votre origine.", choices: ["Demander à un collègue d’intervenir", "Ignorer et continuer le service", "Signaler à la direction", "Faire un scandale", "Accepter la situation", "Répondre calmement"], correct: [0, 2, 5] }, { text: "Un inconnu vous demande d'où vous venez 'vraiment'.", choices: ["Répondre calmement", "Ignorer la question", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur attribue systématiquement de moins bonnes notes aux élèves issus de minorités.", choices: ["En parler à la direction", "Ignorer", "Organiser une réunion avec les parents", "Faire un scandale", "Demander une explication au professeur", "Changer d’établissement"], correct: [0, 2, 4] }, { text: "Un collègue vous appelle par un surnom basé sur votre origine.", choices: ["Lui expliquer que ce n'est pas approprié", "Ignorer", "Faire une remarque sur son nom", "En parler à la RH", "Rire avec lui", "Changer de sujet"], correct: [0, 3] }, { text: "Un propriétaire exige plus de garanties à cause de votre nom.", choices: ["Demander une explication", "Accepter sans rien dire", "Refuser la demande", "Porter plainte", "Chercher un autre logement", "Faire un scandale"], correct: [0, 2, 3] }, { text: "Un inconnu vous touche les cheveux sans demander.", choices: ["Expliquer que ce n'est pas approprié", "Ignorer", "S'énerver", "Faire une remarque sur son comportement", "Changer de sujet", "Rire"], correct: [0, 3] }, { text: "Un collègue vous demande de changer votre prénom pour un plus 'français'.", choices: ["Refuser poliment", "Accepter", "En parler à la RH", "Faire un scandale", "Ignorer", "Changer de sujet"], correct: [0, 2] }, { text: "Un enseignant fait des blagues sur votre accent devant la classe.", choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la direction", "Faire une blague sur lui", "Rire avec la classe", "Changer de classe"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous comprenez bien le français.", choices: ["Répondre poliment", "Ignorer", "Expliquer que la question est déplacée", "Faire une remarque sur son français", "S'énerver", "Changer de sujet"], correct: [0, 2] }, // Ajout de 40 situations supplémentaires { text: "Un collègue refuse de vous serrer la main à cause de votre origine.", choices: ["Demander poliment la raison", "Ignorer", "Faire une remarque", "En parler à la RH", "Rire", "Changer de sujet"], correct: [0, 3] }, { text: "Un professeur ne vous laisse pas participer à un projet de groupe.", choices: ["Demander pourquoi", "Ignorer", "En parler à la direction", "Faire un scandale", "Chercher un autre groupe", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous interpelle dans la rue avec un accent exagéré.", choices: ["Répondre calmement", "Ignorer", "Expliquer que c'est blessant", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant refuse votre paiement sans raison.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un collègue fait des remarques sur votre religion.", choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la RH", "Faire une remarque agressive", "Rire", "Changer de sujet"], correct: [0, 2] }, { text: "Un voisin refuse de vous adresser la parole.", choices: ["Essayer de dialoguer", "Ignorer", "Faire un scandale", "En parler à la mairie", "Changer de sujet", "Rire"], correct: [0, 3] }, { text: "Un inconnu vous demande si vous avez des papiers.", choices: ["Répondre calmement", "Ignorer", "Expliquer que la question est déplacée", "Faire une remarque", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur vous donne systématiquement la parole en dernier.", choices: ["Demander pourquoi", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous exclut des pauses café.", choices: ["Demander à participer", "Ignorer", "En parler à la RH", "Faire un scandale", "Changer de sujet", "Rire"], correct: [0, 2] }, { text: "Un commerçant vous parle de façon condescendante.", choices: ["Lui demander de parler normalement", "Ignorer", "Faire une remarque", "Signaler à la direction", "Changer de magasin", "Rire"], correct: [0, 3] }, { text: "Un inconnu vous prend en photo sans votre accord.", choices: ["Demander d'arrêter", "Ignorer", "Faire une remarque", "Appeler la police", "Changer de sujet", "Rire"], correct: [0, 3] }, { text: "Un professeur fait des généralisations sur votre culture.", choices: ["Lui expliquer pourquoi c'est blessant", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous mangez du porc.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant refuse de vous rendre la monnaie.", choices: ["Demander poliment", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous avez grandi en France.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur vous donne toujours les tâches les plus simples.", choices: ["Demander une répartition équitable", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue fait des remarques sur votre façon de vous habiller.", choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la RH", "Faire une remarque agressive", "Rire", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant vous demande de sortir sans raison.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous parlez arabe.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une remarque", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur vous ignore en classe.", choices: ["Demander poliment la parole", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous fêtez Noël.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant vous accuse de vol sans preuve.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Appeler la police", "Changer de magasin", "Rire"], correct: [0, 2, 3] }, { text: "Un inconnu vous demande si vous avez des enfants.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur fait des remarques sur votre prénom.", choices: ["Lui expliquer l'importance de votre prénom", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous êtes musulman(e).", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant refuse de vous servir un produit.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous avez la nationalité française.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une remarque", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur vous donne toujours la note la plus basse.", choices: ["Demander une explication", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous mangez halal.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant vous demande de quitter le magasin sans raison.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous avez des frères et sœurs.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur fait des remarques sur votre famille.", choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous êtes pratiquant(e).", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant vous refuse l'accès à une promotion.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous avez un travail.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur vous donne toujours les pires horaires.", choices: ["Demander une répartition équitable", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous avez déjà été en prison.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant vous demande de payer en avance sans raison.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous avez une voiture.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur fait des remarques sur votre accent.", choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous avez des enfants.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant vous demande de présenter une pièce d'identité sans raison.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }, { text: "Un inconnu vous demande si vous êtes marié(e).", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un professeur vous donne toujours les pires sujets d'examen.", choices: ["Demander une répartition équitable", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"], correct: [0, 2] }, { text: "Un collègue vous demande si vous avez déjà été contrôlé par la police.", choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"], correct: [0, 2] }, { text: "Un commerçant vous demande de sortir de la file d'attente sans raison.", choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"], correct: [0, 2] }]; var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var GROUND_Y = GAME_HEIGHT - 200; var PLATFORM_GAP_Y = 320; var PLATFORM_MIN_X = 300; var PLATFORM_MAX_X = GAME_WIDTH - 300; var HERO_START_X = 400; var HERO_START_Y = GROUND_Y - 200; var OBSTACLE_CHANCE = 0.5; var EQUALITY_CHANCE = 0.5; var MAX_LEVEL = 40; // Game state var platforms = []; var obstacles = []; var equalityPoints = []; var currentLevel = 1; var equalityScore = 0; var equalityNeeded = 2; var hero = null; var isPopupActive = false; var popupContainer = null; var dragStartX = null; var dragStartY = null; var dragHeroStartX = null; var dragHeroStartY = null; var lastTouchId = null; // GUI var levelTxt = new Text2('Niveau 1', { size: 90, fill: 0x1E293B }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); var equalityTxt = new Text2('Égalité: 0/2', { size: 90, fill: 0x22C55E }); equalityTxt.anchor.set(0.5, 0); LK.gui.top.addChild(equalityTxt); // Position GUI levelTxt.y = 40; equalityTxt.y = 140; // Helper: Update GUI function updateGUI() { levelTxt.setText('Niveau ' + currentLevel + ' / ' + MAX_LEVEL); equalityTxt.setText('Égalité: ' + equalityScore + ' / ' + equalityNeeded); } // Helper: Reset game state for new level or restart function resetGameState() { // Remove old elements for (var i = 0; i < platforms.length; i++) { platforms[i].destroy(); } for (var i = 0; i < obstacles.length; i++) { obstacles[i].destroy(); } for (var i = 0; i < equalityPoints.length; i++) { equalityPoints[i].destroy(); } platforms = []; obstacles = []; equalityPoints = []; equalityScore = 0; // Niveau 1 = 6, puis double à chaque fois equalityNeeded = 6 * Math.pow(2, currentLevel - 1); updateGUI(); // Reset hero if (hero) { hero.destroy(); } hero = new Hero(); hero.x = HERO_START_X; hero.y = HERO_START_Y; game.addChild(hero); // Play background music in loop at game start LK.playMusic('bgmusic', { loop: true }); // Generate platforms var y = GROUND_Y; var plat, obs, eq; for (var lvl = 0; lvl < 10; lvl++) { var px = PLATFORM_MIN_X + Math.floor(Math.random() * (PLATFORM_MAX_X - PLATFORM_MIN_X)); plat = new Platform(); plat.x = px; plat.y = y; platforms.push(plat); game.addChild(plat); // Place obstacle if (Math.random() < OBSTACLE_CHANCE) { obs = new Obstacle(); obs.x = px + 120 + Math.floor(Math.random() * 120); obs.y = y - 60; obstacles.push(obs); game.addChild(obs); } y -= PLATFORM_GAP_Y; } // Add ground platform var groundPlat = new Platform(); groundPlat.x = GAME_WIDTH / 2; groundPlat.y = GROUND_Y + 60; platforms.push(groundPlat); game.addChild(groundPlat); // Place one equality point on every platform except ground for (var pi = 0; pi < platforms.length - 1; pi++) { var plat = platforms[pi]; var eq = new EqualityPoint(); eq.x = plat.x; eq.y = plat.y - 80; equalityPoints.push(eq); game.addChild(eq); } } // Helper: Show discrimination popup function showDiscriminationPopup(situation, onChoice) { isPopupActive = true; popupContainer = new Container(); // Timer pour la popup if (typeof showDiscriminationPopup.popupTimeout !== "undefined" && showDiscriminationPopup.popupTimeout) { LK.clearTimeout(showDiscriminationPopup.popupTimeout); } showDiscriminationPopup.popupTimeout = null; // Background var bg = LK.getAsset('popupBg', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 }); popupContainer.addChild(bg); // Situation text var txt = new Text2(situation.text, { size: 70, fill: 0x1E293B }); txt.anchor.set(0.5, 0); txt.x = GAME_WIDTH / 2; txt.y = GAME_HEIGHT / 2 - 350; popupContainer.addChild(txt); // Choices var btns = []; var btnY = GAME_HEIGHT / 2 - 120; for (var i = 0; i < 6; i++) { var btn = new Container(); var btnBg = LK.getAsset('platform', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: btnY, width: 1200, height: 100, color: 0xf1f5f9 }); btn.addChild(btnBg); var btnTxt = new Text2(situation.choices[i], { size: 54, fill: 0x1E293B }); btnTxt.anchor.set(0.5, 0.5); btnTxt.x = GAME_WIDTH / 2; btnTxt.y = btnY; btn.addChild(btnTxt); // Touch/click event (function (idx) { btn.down = function (x, y, obj) { if (!isPopupActive) { return; } if (showDiscriminationPopup.popupTimeout) { LK.clearTimeout(showDiscriminationPopup.popupTimeout); showDiscriminationPopup.popupTimeout = null; } onChoice(idx); }; })(i); popupContainer.addChild(btn); btns.push(btn); btnY += 130; } game.addChild(popupContainer); // Affiche le temps restant sur la popup et retire la popup après 20 secondes // Ajout du texte du timer var popupTimerTxt = new Text2("20", { size: 60, fill: 0xEF4444 }); popupTimerTxt.anchor.set(0.5, 0.5); popupTimerTxt.x = GAME_WIDTH / 2; popupTimerTxt.y = GAME_HEIGHT / 2 + 400; popupContainer.addChild(popupTimerTxt); // Timer state var popupTimeLeft = 20; if (typeof showDiscriminationPopup.popupTimeout !== "undefined" && showDiscriminationPopup.popupTimeout) { LK.clearTimeout(showDiscriminationPopup.popupTimeout); } if (typeof showDiscriminationPopup.popupInterval !== "undefined" && showDiscriminationPopup.popupInterval) { LK.clearInterval(showDiscriminationPopup.popupInterval); } showDiscriminationPopup.popupTimeout = null; showDiscriminationPopup.popupInterval = null; // Interval pour décrémenter le timer chaque seconde showDiscriminationPopup.popupInterval = LK.setInterval(function () { if (!isPopupActive) { LK.clearInterval(showDiscriminationPopup.popupInterval); showDiscriminationPopup.popupInterval = null; return; } popupTimeLeft -= 1; if (popupTimeLeft < 0) { popupTimeLeft = 0; } popupTimerTxt.setText(popupTimeLeft.toString()); if (popupTimeLeft === 0) { // Temps écoulé, retire la popup if (isPopupActive) { hideDiscriminationPopup(); } LK.clearInterval(showDiscriminationPopup.popupInterval); showDiscriminationPopup.popupInterval = null; if (showDiscriminationPopup.popupTimeout) { LK.clearTimeout(showDiscriminationPopup.popupTimeout); showDiscriminationPopup.popupTimeout = null; } } }, 1000); // Timeout de sécurité pour 20 secondes (au cas où) showDiscriminationPopup.popupTimeout = LK.setTimeout(function () { if (isPopupActive) { hideDiscriminationPopup(); } showDiscriminationPopup.popupTimeout = null; if (showDiscriminationPopup.popupInterval) { LK.clearInterval(showDiscriminationPopup.popupInterval); showDiscriminationPopup.popupInterval = null; } }, 20000); } // Helper: Hide popup function hideDiscriminationPopup() { if (popupContainer) { popupContainer.destroy(); popupContainer = null; } isPopupActive = false; // Nettoyer le timer de la popup si présent if (typeof showDiscriminationPopup.popupTimeout !== "undefined" && showDiscriminationPopup.popupTimeout) { LK.clearTimeout(showDiscriminationPopup.popupTimeout); showDiscriminationPopup.popupTimeout = null; } // Nettoyer l'interval du timer de la popup si présent if (typeof showDiscriminationPopup.popupInterval !== "undefined" && showDiscriminationPopup.popupInterval) { LK.clearInterval(showDiscriminationPopup.popupInterval); showDiscriminationPopup.popupInterval = null; } } // Helper: Handle collision with obstacle function handleObstacleCollision() { // Pick a random situation var sitIdx = Math.floor(Math.random() * discriminationSituations.length); var situation = discriminationSituations[sitIdx]; showDiscriminationPopup(situation, function (choiceIdx) { // Check if correct if (situation.correct.indexOf(choiceIdx) !== -1) { // Good answer: progress, remove obstacle hideDiscriminationPopup(); // Remove the obstacle hero is colliding with for (var i = 0; i < obstacles.length; i++) { if (hero.intersects(obstacles[i])) { obstacles[i].destroy(); obstacles.splice(i, 1); break; } } } else { // Bad answer: game over hideDiscriminationPopup(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); // Après un Game Over, recommence au niveau 1 LK.on('gameOver', function () { currentLevel = 1; resetGameState(); }); } }); } // Helper: Handle collision with equality point // Now, equality points are only collectible after answering a situation correctly. // We'll use a flag to allow collection, and respawn new points if none remain. var canCollectEquality = false; var pendingEqualityIdx = null; function handleEqualityCollision(eqIdx) { // If not allowed to collect, trigger a situation popup if (!canCollectEquality) { // Pick a random situation var sitIdx = Math.floor(Math.random() * discriminationSituations.length); var situation = discriminationSituations[sitIdx]; showDiscriminationPopup(situation, function (choiceIdx) { if (situation.correct.indexOf(choiceIdx) !== -1) { // Good answer: allow collection hideDiscriminationPopup(); canCollectEquality = true; pendingEqualityIdx = eqIdx; } else { // Bad answer: game over hideDiscriminationPopup(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); LK.on('gameOver', function () { currentLevel = 1; resetGameState(); }); } }); return; } // If allowed, collect the point equalityScore += 1; updateGUI(); // Store the platform index before removing the equality point var platformIdx = -1; if (eqIdx >= 0 && eqIdx < platforms.length - 1) { // Try to find the closest platform (by position) var eq = equalityPoints[eqIdx]; for (var pi = 0; pi < platforms.length - 1; pi++) { if (Math.abs(platforms[pi].x - eq.x) < 2 && Math.abs(platforms[pi].y - (eq.y + 80)) < 2) { platformIdx = pi; break; } } } equalityPoints[eqIdx].destroy(); equalityPoints.splice(eqIdx, 1); canCollectEquality = false; pendingEqualityIdx = null; // Spawn a new equality point on the same platform (unless level up) if (platformIdx !== -1 && equalityScore < equalityNeeded) { var plat = platforms[platformIdx]; var newEq = new EqualityPoint(); newEq.x = plat.x; newEq.y = plat.y - 80; equalityPoints.push(newEq); game.addChild(newEq); } // Check for level up if (equalityScore >= equalityNeeded) { if (currentLevel >= MAX_LEVEL) { // Affiche le message de victoire final var winPopup = new Container(); var bg = LK.getAsset('popupBg', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 }); winPopup.addChild(bg); var winTxt = new Text2("Le monde est désormais égal pour tous!", { size: 80, fill: 0x22C55E }); winTxt.anchor.set(0.5, 0.5); winTxt.x = GAME_WIDTH / 2; winTxt.y = GAME_HEIGHT / 2; winPopup.addChild(winTxt); game.addChild(winPopup); LK.setTimeout(function () { winPopup.destroy(); LK.showYouWin(); // Reset du jeu pour recommencer au niveau 1 currentLevel = 1; resetGameState(); }, 2500); } else { currentLevel += 1; resetGameState(); } } else { // If no more equality points, respawn one on every platform (except ground) if (equalityPoints.length === 0 && platforms.length > 0) { // Exclude the ground platform (last one) for (var pi = 0; pi < platforms.length - 1; pi++) { var plat = platforms[pi]; var eq = new EqualityPoint(); eq.x = plat.x; eq.y = plat.y - 80; equalityPoints.push(eq); game.addChild(eq); } // Reset collection state so player must answer a new situation for the next point canCollectEquality = false; pendingEqualityIdx = null; } } } // Helper: Hero-platform collision function checkHeroPlatformCollision() { hero.isOnGround = false; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; // Simple AABB collision, only check if hero is falling if (hero.vy >= 0) { var hx = hero.x, hy = hero.y; var px = plat.x, py = plat.y; var hw = hero.width, hh = hero.height; var pw = plat.width, ph = plat.height; // Check if hero's feet are just above platform if (hx + hw / 2 > px - pw / 2 && hx - hw / 2 < px + pw / 2) { if (hy > py - ph / 2 && hy < py + ph / 2 && hy - hero.vy <= py - ph / 2) { // Land on platform hero.y = py - ph / 2; hero.vy = 0; hero.isOnGround = true; } } } } // Prevent falling below ground if (hero.y > GROUND_Y) { hero.y = GROUND_Y; hero.vy = 0; hero.isOnGround = true; } } // Helper: Clamp hero inside screen function clampHero() { if (hero.x < hero.width / 2) { hero.x = hero.width / 2; } if (hero.x > GAME_WIDTH - hero.width / 2) { hero.x = GAME_WIDTH - hero.width / 2; } if (hero.y < 0) { hero.y = 0; } if (hero.y > GROUND_Y) { hero.y = GROUND_Y; } } // Touch controls: tap anywhere to move hero there game.down = function (x, y, obj) { // Permettre le déplacement même si une popup est active hero.x = x; hero.y = y; hero.vx = 0; hero.vy = 0; hero.isOnGround = false; clampHero(); }; // Désactive le drag & jump, car le déplacement se fait par tap sur plateforme game.move = function (x, y, obj) {}; game.up = function (x, y, obj) {}; // Main update loop game.update = function () { if (isPopupActive) { return; } hero.update(); checkHeroPlatformCollision(); clampHero(); // Check collision with obstacles for (var i = 0; i < obstacles.length; i++) { if (hero.intersects(obstacles[i])) { handleObstacleCollision(); break; } } // Check collision with equality points for (var j = equalityPoints.length - 1; j >= 0; j--) { if (hero.intersects(equalityPoints[j])) { // If a correct answer was just given, allow collection if (canCollectEquality && pendingEqualityIdx === j) { handleEqualityCollision(j); break; } // Otherwise, only trigger popup if not already in process if (!canCollectEquality) { handleEqualityCollision(j); break; } } } }; // Start game resetGameState(); // Permet au joueur de recommencer le jeu après la victoire LK.on('youWin', function () { currentLevel = 1; resetGameState(); });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Equality point class
var EqualityPoint = Container.expand(function () {
var self = Container.call(this);
var eqGfx = self.attachAsset('equality', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = eqGfx.width;
self.height = eqGfx.height;
return self;
});
/****
* Discrimination Situations
****/
// Hero class
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGfx = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 1
});
self.width = heroGfx.width;
self.height = heroGfx.height;
self.vx = 0;
self.vy = 0;
self.isOnGround = false;
self.jumpPower = -60;
self.moveSpeed = 22;
self.gravity = 5;
self.update = function () {
// Apply gravity
self.vy += self.gravity;
self.x += self.vx;
self.y += self.vy;
};
return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obsGfx = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
self.width = obsGfx.width;
self.height = obsGfx.height;
return self;
});
// Platform class
var Platform = Container.expand(function () {
var self = Container.call(this);
var platGfx = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = platGfx.width;
self.height = platGfx.height;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf1f5f9
});
/****
* Game Code
****/
// Add custom background image to the game, covering the entire game area
var backgroundImg = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: GAME_WIDTH,
height: GAME_HEIGHT
});
game.addChild(backgroundImg);
/****
* Game Code
/****
* Discrimination Situations
****/
// Discrimination popup background (box, white)
// Equality point (ellipse, green)
// Obstacle (ellipse, red)
// Platform (box, gray)
// Character: Woman of color (box, purple)
// Game constants
var discriminationSituations = [{
text: "Un collègue fait une remarque raciste au travail.",
choices: ["Ignorer la remarque", "Rire avec lui", "Signaler à la RH", "Répondre calmement", "Quitter le travail", "Faire une remarque agressive"],
correct: [2, 3]
}, {
text: "On refuse de vous servir dans un café.",
choices: ["Demander poliment pourquoi", "Partir sans rien dire", "Faire un scandale", "Appeler la police", "Filmer la scène", "Accepter la situation"],
correct: [0, 3, 4]
}, {
text: "Un enfant subit des moqueries à l’école à cause de sa couleur de peau.",
choices: ["En parler à l’enseignant", "Ignorer la situation", "Encourager l’enfant à répondre", "Rire avec les autres", "Organiser une discussion sur la diversité", "Punir les moqueurs"],
correct: [0, 2, 4]
}, {
text: "Une entreprise refuse votre candidature sans raison.",
choices: ["Demander un retour", "Porter plainte pour discrimination", "Chercher un autre emploi", "Publier sur les réseaux sociaux", "Accepter sans rien faire", "Envoyer un message d’insulte"],
correct: [0, 1, 3]
}, {
text: "Un chauffeur de bus ne s’arrête pas pour vous.",
choices: ["Attendre le prochain bus", "Signaler à la compagnie", "Crier sur le chauffeur", "Filmer la scène", "Ignorer l’incident", "Demander de l’aide à d’autres passagers"],
correct: [1, 3, 5]
}, {
text: "Un agent de sécurité vous suit dans un magasin sans raison.",
choices: ["Lui demander calmement pourquoi", "Ignorer et continuer vos achats", "Faire un scandale", "Quitter le magasin", "Filmer la scène", "Appeler la direction"],
correct: [0, 1, 5]
}, {
text: "Un professeur fait une remarque stéréotypée sur votre culture.",
choices: ["Lui expliquer pourquoi c'est blessant", "Ignorer", "Rire avec la classe", "En parler à la direction", "Répondre agressivement", "Demander des excuses"],
correct: [0, 3, 5]
}, {
text: "On vous refuse l'entrée d'une boîte de nuit.",
choices: ["Demander la raison", "Accepter sans rien dire", "Filmer la scène", "Appeler la police", "Faire un scandale", "Chercher un autre lieu"],
correct: [0, 2, 3]
}, {
text: "Un inconnu fait une remarque sur vos cheveux dans la rue.",
choices: ["Répondre poliment", "Ignorer", "Faire une remarque sur son apparence", "Expliquer pourquoi ce n'est pas approprié", "Rire", "S'énerver"],
correct: [0, 3]
}, {
text: "Un enfant est exclu d'un jeu à cause de sa couleur de peau.",
choices: ["Intervenir et inclure l'enfant", "Ignorer", "En parler aux parents", "Rire avec les autres", "Organiser un jeu inclusif", "Punir les enfants"],
correct: [0, 2, 4]
}, {
text: "Un propriétaire refuse de vous louer un appartement à cause de votre nom.",
choices: ["Demander une explication", "Accepter sans rien dire", "Porter plainte pour discrimination", "Chercher un autre logement", "Publier sur les réseaux sociaux", "Faire une remarque agressive"],
correct: [0, 2, 4]
}, {
text: "Un médecin minimise vos symptômes en raison de votre origine.",
choices: ["Demander un second avis", "Accepter le diagnostic", "Changer de médecin", "Signaler à l'ordre des médecins", "Ignorer la situation", "Faire un scandale"],
correct: [0, 2, 3]
}, {
text: "Un policier vous contrôle sans raison apparente.",
choices: ["Demander poliment la raison", "Refuser de coopérer", "Filmer la scène", "S'énerver", "Rester calme et coopérer", "Faire un scandale"],
correct: [0, 2, 4]
}, {
text: "Un camarade de classe refuse de travailler avec vous.",
choices: ["Demander pourquoi", "Ignorer et travailler seul", "En parler à l’enseignant", "Faire une remarque agressive", "Chercher un autre camarade", "Rire de la situation"],
correct: [0, 2, 4]
}, {
text: "Un commerçant vous surveille de façon insistante.",
choices: ["Lui demander calmement pourquoi", "Ignorer", "Quitter le magasin", "Faire un scandale", "Filmer la scène", "Appeler la direction"],
correct: [0, 1, 5]
}, {
text: "Un collègue fait des blagues sur votre accent.",
choices: ["Lui expliquer que c'est blessant", "Rire avec lui", "Ignorer", "En parler à la RH", "Faire une remarque agressive", "Changer de sujet"],
correct: [0, 3]
}, {
text: "On vous attribue systématiquement les tâches les moins valorisantes.",
choices: ["Demander une répartition équitable", "Accepter sans rien dire", "En parler à la direction", "Faire un scandale", "Ignorer", "Chercher un autre poste"],
correct: [0, 2]
}, {
text: "Un inconnu vous interpelle dans la rue avec un surnom stéréotypé.",
choices: ["Répondre poliment", "Ignorer", "Expliquer pourquoi ce n'est pas approprié", "Faire une remarque sur son apparence", "S'énerver", "Rire"],
correct: [0, 2]
}, {
text: "Un enseignant refuse de prononcer correctement votre prénom.",
choices: ["Lui expliquer l'importance de votre prénom", "Ignorer", "Faire une remarque agressive", "En parler à la direction", "Changer de classe", "Rire avec la classe"],
correct: [0, 3]
}, {
text: "Un voisin fait des remarques sur votre famille à cause de votre origine.",
choices: ["Lui expliquer que c'est blessant", "Ignorer", "Faire un scandale", "En parler à la mairie", "Répondre calmement", "Changer de sujet"],
correct: [0, 3, 4]
},
// Nouvelles situations ajoutées
{
text: "Un recruteur vous demande si vous comptez porter le voile au travail.",
choices: ["Répondre poliment à la question", "Refuser de répondre", "Signaler la question à la direction", "Ignorer la question", "Faire un scandale", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un client refuse d’être servi par vous à cause de votre origine.",
choices: ["Demander à un collègue d’intervenir", "Ignorer et continuer le service", "Signaler à la direction", "Faire un scandale", "Accepter la situation", "Répondre calmement"],
correct: [0, 2, 5]
}, {
text: "Un inconnu vous demande d'où vous venez 'vraiment'.",
choices: ["Répondre calmement", "Ignorer la question", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur attribue systématiquement de moins bonnes notes aux élèves issus de minorités.",
choices: ["En parler à la direction", "Ignorer", "Organiser une réunion avec les parents", "Faire un scandale", "Demander une explication au professeur", "Changer d’établissement"],
correct: [0, 2, 4]
}, {
text: "Un collègue vous appelle par un surnom basé sur votre origine.",
choices: ["Lui expliquer que ce n'est pas approprié", "Ignorer", "Faire une remarque sur son nom", "En parler à la RH", "Rire avec lui", "Changer de sujet"],
correct: [0, 3]
}, {
text: "Un propriétaire exige plus de garanties à cause de votre nom.",
choices: ["Demander une explication", "Accepter sans rien dire", "Refuser la demande", "Porter plainte", "Chercher un autre logement", "Faire un scandale"],
correct: [0, 2, 3]
}, {
text: "Un inconnu vous touche les cheveux sans demander.",
choices: ["Expliquer que ce n'est pas approprié", "Ignorer", "S'énerver", "Faire une remarque sur son comportement", "Changer de sujet", "Rire"],
correct: [0, 3]
}, {
text: "Un collègue vous demande de changer votre prénom pour un plus 'français'.",
choices: ["Refuser poliment", "Accepter", "En parler à la RH", "Faire un scandale", "Ignorer", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un enseignant fait des blagues sur votre accent devant la classe.",
choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la direction", "Faire une blague sur lui", "Rire avec la classe", "Changer de classe"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous comprenez bien le français.",
choices: ["Répondre poliment", "Ignorer", "Expliquer que la question est déplacée", "Faire une remarque sur son français", "S'énerver", "Changer de sujet"],
correct: [0, 2]
},
// Ajout de 40 situations supplémentaires
{
text: "Un collègue refuse de vous serrer la main à cause de votre origine.",
choices: ["Demander poliment la raison", "Ignorer", "Faire une remarque", "En parler à la RH", "Rire", "Changer de sujet"],
correct: [0, 3]
}, {
text: "Un professeur ne vous laisse pas participer à un projet de groupe.",
choices: ["Demander pourquoi", "Ignorer", "En parler à la direction", "Faire un scandale", "Chercher un autre groupe", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous interpelle dans la rue avec un accent exagéré.",
choices: ["Répondre calmement", "Ignorer", "Expliquer que c'est blessant", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant refuse votre paiement sans raison.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue fait des remarques sur votre religion.",
choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la RH", "Faire une remarque agressive", "Rire", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un voisin refuse de vous adresser la parole.",
choices: ["Essayer de dialoguer", "Ignorer", "Faire un scandale", "En parler à la mairie", "Changer de sujet", "Rire"],
correct: [0, 3]
}, {
text: "Un inconnu vous demande si vous avez des papiers.",
choices: ["Répondre calmement", "Ignorer", "Expliquer que la question est déplacée", "Faire une remarque", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur vous donne systématiquement la parole en dernier.",
choices: ["Demander pourquoi", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous exclut des pauses café.",
choices: ["Demander à participer", "Ignorer", "En parler à la RH", "Faire un scandale", "Changer de sujet", "Rire"],
correct: [0, 2]
}, {
text: "Un commerçant vous parle de façon condescendante.",
choices: ["Lui demander de parler normalement", "Ignorer", "Faire une remarque", "Signaler à la direction", "Changer de magasin", "Rire"],
correct: [0, 3]
}, {
text: "Un inconnu vous prend en photo sans votre accord.",
choices: ["Demander d'arrêter", "Ignorer", "Faire une remarque", "Appeler la police", "Changer de sujet", "Rire"],
correct: [0, 3]
}, {
text: "Un professeur fait des généralisations sur votre culture.",
choices: ["Lui expliquer pourquoi c'est blessant", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous mangez du porc.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant refuse de vous rendre la monnaie.",
choices: ["Demander poliment", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous avez grandi en France.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur vous donne toujours les tâches les plus simples.",
choices: ["Demander une répartition équitable", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue fait des remarques sur votre façon de vous habiller.",
choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la RH", "Faire une remarque agressive", "Rire", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant vous demande de sortir sans raison.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous parlez arabe.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une remarque", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur vous ignore en classe.",
choices: ["Demander poliment la parole", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous fêtez Noël.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant vous accuse de vol sans preuve.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Appeler la police", "Changer de magasin", "Rire"],
correct: [0, 2, 3]
}, {
text: "Un inconnu vous demande si vous avez des enfants.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur fait des remarques sur votre prénom.",
choices: ["Lui expliquer l'importance de votre prénom", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous êtes musulman(e).",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant refuse de vous servir un produit.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous avez la nationalité française.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une remarque", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur vous donne toujours la note la plus basse.",
choices: ["Demander une explication", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous mangez halal.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant vous demande de quitter le magasin sans raison.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous avez des frères et sœurs.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur fait des remarques sur votre famille.",
choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous êtes pratiquant(e).",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant vous refuse l'accès à une promotion.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous avez un travail.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur vous donne toujours les pires horaires.",
choices: ["Demander une répartition équitable", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous avez déjà été en prison.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant vous demande de payer en avance sans raison.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous avez une voiture.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur fait des remarques sur votre accent.",
choices: ["Lui expliquer que c'est blessant", "Ignorer", "En parler à la direction", "Faire une remarque agressive", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous avez des enfants.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant vous demande de présenter une pièce d'identité sans raison.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}, {
text: "Un inconnu vous demande si vous êtes marié(e).",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un professeur vous donne toujours les pires sujets d'examen.",
choices: ["Demander une répartition équitable", "Ignorer", "En parler à la direction", "Faire un scandale", "Changer de classe", "Rire"],
correct: [0, 2]
}, {
text: "Un collègue vous demande si vous avez déjà été contrôlé par la police.",
choices: ["Répondre calmement", "Ignorer", "Expliquer pourquoi la question est déplacée", "Faire une blague", "S'énerver", "Changer de sujet"],
correct: [0, 2]
}, {
text: "Un commerçant vous demande de sortir de la file d'attente sans raison.",
choices: ["Demander une explication", "Ignorer", "Signaler à la direction", "Faire un scandale", "Changer de magasin", "Rire"],
correct: [0, 2]
}];
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var GROUND_Y = GAME_HEIGHT - 200;
var PLATFORM_GAP_Y = 320;
var PLATFORM_MIN_X = 300;
var PLATFORM_MAX_X = GAME_WIDTH - 300;
var HERO_START_X = 400;
var HERO_START_Y = GROUND_Y - 200;
var OBSTACLE_CHANCE = 0.5;
var EQUALITY_CHANCE = 0.5;
var MAX_LEVEL = 40;
// Game state
var platforms = [];
var obstacles = [];
var equalityPoints = [];
var currentLevel = 1;
var equalityScore = 0;
var equalityNeeded = 2;
var hero = null;
var isPopupActive = false;
var popupContainer = null;
var dragStartX = null;
var dragStartY = null;
var dragHeroStartX = null;
var dragHeroStartY = null;
var lastTouchId = null;
// GUI
var levelTxt = new Text2('Niveau 1', {
size: 90,
fill: 0x1E293B
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
var equalityTxt = new Text2('Égalité: 0/2', {
size: 90,
fill: 0x22C55E
});
equalityTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(equalityTxt);
// Position GUI
levelTxt.y = 40;
equalityTxt.y = 140;
// Helper: Update GUI
function updateGUI() {
levelTxt.setText('Niveau ' + currentLevel + ' / ' + MAX_LEVEL);
equalityTxt.setText('Égalité: ' + equalityScore + ' / ' + equalityNeeded);
}
// Helper: Reset game state for new level or restart
function resetGameState() {
// Remove old elements
for (var i = 0; i < platforms.length; i++) {
platforms[i].destroy();
}
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].destroy();
}
for (var i = 0; i < equalityPoints.length; i++) {
equalityPoints[i].destroy();
}
platforms = [];
obstacles = [];
equalityPoints = [];
equalityScore = 0;
// Niveau 1 = 6, puis double à chaque fois
equalityNeeded = 6 * Math.pow(2, currentLevel - 1);
updateGUI();
// Reset hero
if (hero) {
hero.destroy();
}
hero = new Hero();
hero.x = HERO_START_X;
hero.y = HERO_START_Y;
game.addChild(hero);
// Play background music in loop at game start
LK.playMusic('bgmusic', {
loop: true
});
// Generate platforms
var y = GROUND_Y;
var plat, obs, eq;
for (var lvl = 0; lvl < 10; lvl++) {
var px = PLATFORM_MIN_X + Math.floor(Math.random() * (PLATFORM_MAX_X - PLATFORM_MIN_X));
plat = new Platform();
plat.x = px;
plat.y = y;
platforms.push(plat);
game.addChild(plat);
// Place obstacle
if (Math.random() < OBSTACLE_CHANCE) {
obs = new Obstacle();
obs.x = px + 120 + Math.floor(Math.random() * 120);
obs.y = y - 60;
obstacles.push(obs);
game.addChild(obs);
}
y -= PLATFORM_GAP_Y;
}
// Add ground platform
var groundPlat = new Platform();
groundPlat.x = GAME_WIDTH / 2;
groundPlat.y = GROUND_Y + 60;
platforms.push(groundPlat);
game.addChild(groundPlat);
// Place one equality point on every platform except ground
for (var pi = 0; pi < platforms.length - 1; pi++) {
var plat = platforms[pi];
var eq = new EqualityPoint();
eq.x = plat.x;
eq.y = plat.y - 80;
equalityPoints.push(eq);
game.addChild(eq);
}
}
// Helper: Show discrimination popup
function showDiscriminationPopup(situation, onChoice) {
isPopupActive = true;
popupContainer = new Container();
// Timer pour la popup
if (typeof showDiscriminationPopup.popupTimeout !== "undefined" && showDiscriminationPopup.popupTimeout) {
LK.clearTimeout(showDiscriminationPopup.popupTimeout);
}
showDiscriminationPopup.popupTimeout = null;
// Background
var bg = LK.getAsset('popupBg', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2,
y: GAME_HEIGHT / 2
});
popupContainer.addChild(bg);
// Situation text
var txt = new Text2(situation.text, {
size: 70,
fill: 0x1E293B
});
txt.anchor.set(0.5, 0);
txt.x = GAME_WIDTH / 2;
txt.y = GAME_HEIGHT / 2 - 350;
popupContainer.addChild(txt);
// Choices
var btns = [];
var btnY = GAME_HEIGHT / 2 - 120;
for (var i = 0; i < 6; i++) {
var btn = new Container();
var btnBg = LK.getAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2,
y: btnY,
width: 1200,
height: 100,
color: 0xf1f5f9
});
btn.addChild(btnBg);
var btnTxt = new Text2(situation.choices[i], {
size: 54,
fill: 0x1E293B
});
btnTxt.anchor.set(0.5, 0.5);
btnTxt.x = GAME_WIDTH / 2;
btnTxt.y = btnY;
btn.addChild(btnTxt);
// Touch/click event
(function (idx) {
btn.down = function (x, y, obj) {
if (!isPopupActive) {
return;
}
if (showDiscriminationPopup.popupTimeout) {
LK.clearTimeout(showDiscriminationPopup.popupTimeout);
showDiscriminationPopup.popupTimeout = null;
}
onChoice(idx);
};
})(i);
popupContainer.addChild(btn);
btns.push(btn);
btnY += 130;
}
game.addChild(popupContainer);
// Affiche le temps restant sur la popup et retire la popup après 20 secondes
// Ajout du texte du timer
var popupTimerTxt = new Text2("20", {
size: 60,
fill: 0xEF4444
});
popupTimerTxt.anchor.set(0.5, 0.5);
popupTimerTxt.x = GAME_WIDTH / 2;
popupTimerTxt.y = GAME_HEIGHT / 2 + 400;
popupContainer.addChild(popupTimerTxt);
// Timer state
var popupTimeLeft = 20;
if (typeof showDiscriminationPopup.popupTimeout !== "undefined" && showDiscriminationPopup.popupTimeout) {
LK.clearTimeout(showDiscriminationPopup.popupTimeout);
}
if (typeof showDiscriminationPopup.popupInterval !== "undefined" && showDiscriminationPopup.popupInterval) {
LK.clearInterval(showDiscriminationPopup.popupInterval);
}
showDiscriminationPopup.popupTimeout = null;
showDiscriminationPopup.popupInterval = null;
// Interval pour décrémenter le timer chaque seconde
showDiscriminationPopup.popupInterval = LK.setInterval(function () {
if (!isPopupActive) {
LK.clearInterval(showDiscriminationPopup.popupInterval);
showDiscriminationPopup.popupInterval = null;
return;
}
popupTimeLeft -= 1;
if (popupTimeLeft < 0) {
popupTimeLeft = 0;
}
popupTimerTxt.setText(popupTimeLeft.toString());
if (popupTimeLeft === 0) {
// Temps écoulé, retire la popup
if (isPopupActive) {
hideDiscriminationPopup();
}
LK.clearInterval(showDiscriminationPopup.popupInterval);
showDiscriminationPopup.popupInterval = null;
if (showDiscriminationPopup.popupTimeout) {
LK.clearTimeout(showDiscriminationPopup.popupTimeout);
showDiscriminationPopup.popupTimeout = null;
}
}
}, 1000);
// Timeout de sécurité pour 20 secondes (au cas où)
showDiscriminationPopup.popupTimeout = LK.setTimeout(function () {
if (isPopupActive) {
hideDiscriminationPopup();
}
showDiscriminationPopup.popupTimeout = null;
if (showDiscriminationPopup.popupInterval) {
LK.clearInterval(showDiscriminationPopup.popupInterval);
showDiscriminationPopup.popupInterval = null;
}
}, 20000);
}
// Helper: Hide popup
function hideDiscriminationPopup() {
if (popupContainer) {
popupContainer.destroy();
popupContainer = null;
}
isPopupActive = false;
// Nettoyer le timer de la popup si présent
if (typeof showDiscriminationPopup.popupTimeout !== "undefined" && showDiscriminationPopup.popupTimeout) {
LK.clearTimeout(showDiscriminationPopup.popupTimeout);
showDiscriminationPopup.popupTimeout = null;
}
// Nettoyer l'interval du timer de la popup si présent
if (typeof showDiscriminationPopup.popupInterval !== "undefined" && showDiscriminationPopup.popupInterval) {
LK.clearInterval(showDiscriminationPopup.popupInterval);
showDiscriminationPopup.popupInterval = null;
}
}
// Helper: Handle collision with obstacle
function handleObstacleCollision() {
// Pick a random situation
var sitIdx = Math.floor(Math.random() * discriminationSituations.length);
var situation = discriminationSituations[sitIdx];
showDiscriminationPopup(situation, function (choiceIdx) {
// Check if correct
if (situation.correct.indexOf(choiceIdx) !== -1) {
// Good answer: progress, remove obstacle
hideDiscriminationPopup();
// Remove the obstacle hero is colliding with
for (var i = 0; i < obstacles.length; i++) {
if (hero.intersects(obstacles[i])) {
obstacles[i].destroy();
obstacles.splice(i, 1);
break;
}
}
} else {
// Bad answer: game over
hideDiscriminationPopup();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
// Après un Game Over, recommence au niveau 1
LK.on('gameOver', function () {
currentLevel = 1;
resetGameState();
});
}
});
}
// Helper: Handle collision with equality point
// Now, equality points are only collectible after answering a situation correctly.
// We'll use a flag to allow collection, and respawn new points if none remain.
var canCollectEquality = false;
var pendingEqualityIdx = null;
function handleEqualityCollision(eqIdx) {
// If not allowed to collect, trigger a situation popup
if (!canCollectEquality) {
// Pick a random situation
var sitIdx = Math.floor(Math.random() * discriminationSituations.length);
var situation = discriminationSituations[sitIdx];
showDiscriminationPopup(situation, function (choiceIdx) {
if (situation.correct.indexOf(choiceIdx) !== -1) {
// Good answer: allow collection
hideDiscriminationPopup();
canCollectEquality = true;
pendingEqualityIdx = eqIdx;
} else {
// Bad answer: game over
hideDiscriminationPopup();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
LK.on('gameOver', function () {
currentLevel = 1;
resetGameState();
});
}
});
return;
}
// If allowed, collect the point
equalityScore += 1;
updateGUI();
// Store the platform index before removing the equality point
var platformIdx = -1;
if (eqIdx >= 0 && eqIdx < platforms.length - 1) {
// Try to find the closest platform (by position)
var eq = equalityPoints[eqIdx];
for (var pi = 0; pi < platforms.length - 1; pi++) {
if (Math.abs(platforms[pi].x - eq.x) < 2 && Math.abs(platforms[pi].y - (eq.y + 80)) < 2) {
platformIdx = pi;
break;
}
}
}
equalityPoints[eqIdx].destroy();
equalityPoints.splice(eqIdx, 1);
canCollectEquality = false;
pendingEqualityIdx = null;
// Spawn a new equality point on the same platform (unless level up)
if (platformIdx !== -1 && equalityScore < equalityNeeded) {
var plat = platforms[platformIdx];
var newEq = new EqualityPoint();
newEq.x = plat.x;
newEq.y = plat.y - 80;
equalityPoints.push(newEq);
game.addChild(newEq);
}
// Check for level up
if (equalityScore >= equalityNeeded) {
if (currentLevel >= MAX_LEVEL) {
// Affiche le message de victoire final
var winPopup = new Container();
var bg = LK.getAsset('popupBg', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2,
y: GAME_HEIGHT / 2
});
winPopup.addChild(bg);
var winTxt = new Text2("Le monde est désormais égal pour tous!", {
size: 80,
fill: 0x22C55E
});
winTxt.anchor.set(0.5, 0.5);
winTxt.x = GAME_WIDTH / 2;
winTxt.y = GAME_HEIGHT / 2;
winPopup.addChild(winTxt);
game.addChild(winPopup);
LK.setTimeout(function () {
winPopup.destroy();
LK.showYouWin();
// Reset du jeu pour recommencer au niveau 1
currentLevel = 1;
resetGameState();
}, 2500);
} else {
currentLevel += 1;
resetGameState();
}
} else {
// If no more equality points, respawn one on every platform (except ground)
if (equalityPoints.length === 0 && platforms.length > 0) {
// Exclude the ground platform (last one)
for (var pi = 0; pi < platforms.length - 1; pi++) {
var plat = platforms[pi];
var eq = new EqualityPoint();
eq.x = plat.x;
eq.y = plat.y - 80;
equalityPoints.push(eq);
game.addChild(eq);
}
// Reset collection state so player must answer a new situation for the next point
canCollectEquality = false;
pendingEqualityIdx = null;
}
}
}
// Helper: Hero-platform collision
function checkHeroPlatformCollision() {
hero.isOnGround = false;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
// Simple AABB collision, only check if hero is falling
if (hero.vy >= 0) {
var hx = hero.x,
hy = hero.y;
var px = plat.x,
py = plat.y;
var hw = hero.width,
hh = hero.height;
var pw = plat.width,
ph = plat.height;
// Check if hero's feet are just above platform
if (hx + hw / 2 > px - pw / 2 && hx - hw / 2 < px + pw / 2) {
if (hy > py - ph / 2 && hy < py + ph / 2 && hy - hero.vy <= py - ph / 2) {
// Land on platform
hero.y = py - ph / 2;
hero.vy = 0;
hero.isOnGround = true;
}
}
}
}
// Prevent falling below ground
if (hero.y > GROUND_Y) {
hero.y = GROUND_Y;
hero.vy = 0;
hero.isOnGround = true;
}
}
// Helper: Clamp hero inside screen
function clampHero() {
if (hero.x < hero.width / 2) {
hero.x = hero.width / 2;
}
if (hero.x > GAME_WIDTH - hero.width / 2) {
hero.x = GAME_WIDTH - hero.width / 2;
}
if (hero.y < 0) {
hero.y = 0;
}
if (hero.y > GROUND_Y) {
hero.y = GROUND_Y;
}
}
// Touch controls: tap anywhere to move hero there
game.down = function (x, y, obj) {
// Permettre le déplacement même si une popup est active
hero.x = x;
hero.y = y;
hero.vx = 0;
hero.vy = 0;
hero.isOnGround = false;
clampHero();
};
// Désactive le drag & jump, car le déplacement se fait par tap sur plateforme
game.move = function (x, y, obj) {};
game.up = function (x, y, obj) {};
// Main update loop
game.update = function () {
if (isPopupActive) {
return;
}
hero.update();
checkHeroPlatformCollision();
clampHero();
// Check collision with obstacles
for (var i = 0; i < obstacles.length; i++) {
if (hero.intersects(obstacles[i])) {
handleObstacleCollision();
break;
}
}
// Check collision with equality points
for (var j = equalityPoints.length - 1; j >= 0; j--) {
if (hero.intersects(equalityPoints[j])) {
// If a correct answer was just given, allow collection
if (canCollectEquality && pendingEqualityIdx === j) {
handleEqualityCollision(j);
break;
}
// Otherwise, only trigger popup if not already in process
if (!canCollectEquality) {
handleEqualityCollision(j);
break;
}
}
}
};
// Start game
resetGameState();
// Permet au joueur de recommencer le jeu après la victoire
LK.on('youWin', function () {
currentLevel = 1;
resetGameState();
});
Femme de couleur. In-Game asset. 2d. High contrast. No shadows
Bus. In-Game asset. 2d. High contrast. No shadows
Étoile de l'égalité. In-Game asset. 2d. High contrast. No shadows
FOND ROSE. In-Game asset. 2d. High contrast. No shadows
Fond d'écran ville. In-Game asset. 2d. High contrast. No shadows