feat: implement Phase 4 Molecule-Molecule Reactions and expand Story Mode to 8 levels
This commit is contained in:
parent
3765333a66
commit
508bdc1fba
22
PLAN.md
22
PLAN.md
@ -28,18 +28,30 @@ Dieses Dokument dokumentiert die erfolgreich abgeschlossenen Entwicklungsphasen
|
||||
3. *Level 3: Der Mülleimerbrand* (Ziel: $CO_2$ Kohlendioxid)
|
||||
4. *Level 4: Dünger für die Ernte* (Ziel: $NH_3$ Ammoniak)
|
||||
5. *Level 5: Die Verdauungshilfe* (Ziel: $HCl$ Salzsäure)
|
||||
6. *Level 6: Die weiße Rauchbombe* (Ziel: $NH_4Cl$ Ammoniumchlorid aus $NH_3$ und $HCl$)
|
||||
7. *Level 7: Das saure Umweltproblem* (Ziel: $H_2SO_3$ Schweflige Säure aus $SO_2$ und $H_2O$)
|
||||
8. *Level 8: Die Säure-Base-Schlacht* (Ziel: Neutralisation von $HCl$ und $NaOH$ zu $NaCl$ und $H_2O$)
|
||||
- **Professor Atomus NPCs:** Ein stilisierter Avatar des Professors führt den Spieler mit Dialogen durch die Quests, gibt Hinweise und gratuliert zum Erfolg.
|
||||
- **Level-Beschränkungen (Constraints):** Jedes Level schaltet nur diejenigen Elemente frei, die chemisch sinnvoll sind. Andere Elemente sind gesperrt, um den Lernpfad zu kanalisieren.
|
||||
- **Erfolgs-Zertifikat:** Nach Abschluss des fünften Levels wird das Spiel offiziell mit einem Meistertitel gekrönt.
|
||||
- **Erfolgs-Zertifikat:** Nach Abschluss des achten Levels wird das Spiel offiziell mit einem Meistertitel gekrönt.
|
||||
|
||||
### Phase 4: Molekül-Reaktionen (Säure-Base-Interaktionen)
|
||||
- **Mehrstufige Reaktionen:** Ermöglichen von Kollisionen zwischen Atomen und Molekülen sowie Molekülen mit Molekülen.
|
||||
- **7 komplexe Reaktionen:**
|
||||
- Säure-Base-Neutralisation ($HCl$ + $NaOH$ $\rightarrow$ $NaCl$ + $H_2O$)
|
||||
- Methangas-Verbrennung ($CH_4$ + 2 $O_2$ $\rightarrow$ $CO_2$ + 2 $H_2O$)
|
||||
- Ammoniumchlorid-Synthese ($NH_3$ + $HCl$ $\rightarrow$ $NH_4Cl$)
|
||||
- Saure-Regen-Bildung ($SO_2$ + $H_2O$ $\rightarrow$ $H_2SO_3$)
|
||||
- Kohlensäure-Bildung ($CO_2$ + $H_2O$ $\rightarrow$ $H_2CO_3$)
|
||||
- Säureangriff auf Metalle ($Fe$ + 2 $HCl$ $\rightarrow$ $FeCl_2$ + $H_2$)
|
||||
- Chlorknallgas-Reaktion ($H_2$ + $Cl_2$ $\rightarrow$ 2 $HCl$)
|
||||
- **Neue Moleküle:** Ammoniumchlorid ($NH_4Cl$), Schweflige Säure ($H_2SO_3$), Kohlensäure ($H_2CO_3$) und Eisenchlorid ($FeCl_2$) im Lexikon integriert (jetzt 22 Moleküle insgesamt).
|
||||
- **Visuelle Reaktivitäts-Overlays:** Spezielle Orange exotherme Explosionseffekte und Reaktionsgleichungen-Anzeigen im Entdeckungs-Modal (z.B. `HCl + NaOH → NaCl + H₂O` mit tiefgestellten Zahlen).
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Zukünftige Roadmap (Für die mobile App)
|
||||
|
||||
### Phase 4: Molekül-Reaktionen (Säure-Base-Interaktionen)
|
||||
- **Mehrstufige Reaktionen:** Ermöglichen von Kollisionen zwischen Atomen und Molekülen sowie Molekülen mit Molekülen.
|
||||
- **Beispiel:** Salzsäure ($HCl$) + Natronlauge ($NaOH$) $\rightarrow$ Kochsalz ($NaCl$) + Wasser ($H_2O$) (Klassische Neutralisation!).
|
||||
|
||||
### Phase 5: Multimedia & Grafik-Erweiterung
|
||||
- **Bilder & Animationen:** Ersatz der einfachen Kreise durch kunstvolle Texturen oder Element-Avatare.
|
||||
- **Soundeffekte (SFX):** Integrieren von Audio-Signalen bei Reaktionen ("Zisch!", "Plopp!", "Puff!").
|
||||
|
||||
212
app.js
212
app.js
@ -212,6 +212,87 @@ const recipes = [
|
||||
result: 'C₂H₄ (Ethen)',
|
||||
color: '#ffeaa7',
|
||||
desc: 'Ethen (Ethylen) ist ein gasförmiges Pflanzenhormon, das Früchte reifen lässt. Industriell ist es der absolut wichtigste Baustein zur Herstellung des Kunststoffs Polyethylen (PE).'
|
||||
},
|
||||
{
|
||||
id: 'nh4cl',
|
||||
ingredients: ['Cl', 'H', 'H', 'H', 'H', 'N'],
|
||||
result: 'NH₄Cl (Ammoniumchlorid)',
|
||||
color: '#ffffff',
|
||||
desc: 'Ammoniumchlorid (Salmiak) ist ein weißes, feinkristallines Salz. Es schmeckt extrem salzig-sauer und wird traditionell in Nordeuropa für die Herstellung von echtem, starkem Salzlakritz verwendet!'
|
||||
},
|
||||
{
|
||||
id: 'h2so3',
|
||||
ingredients: ['H', 'H', 'O', 'O', 'O', 'S'],
|
||||
result: 'H₂SO₃ (Schweflige Säure)',
|
||||
color: '#e74c3c',
|
||||
desc: 'Schweflige Säure entsteht, wenn Schwefeldioxid mit Wasser reagiert. Sie ist eine unbeständige, säuerliche Flüssigkeit, die stark reduzierend wirkt und zum Bleichen oder Konservieren genutzt wird.'
|
||||
},
|
||||
{
|
||||
id: 'h2co3',
|
||||
ingredients: ['C', 'H', 'H', 'O', 'O', 'O'],
|
||||
result: 'H₂CO₃ (Kohlensäure)',
|
||||
color: '#1abc9c',
|
||||
desc: 'Kohlensäure entsteht, wenn sich CO₂ in Wasser löst. Sie ist eine schwache Säure, die für das erfrischende Prickeln in Getränken sorgt. Im Körper ist sie wichtig für den Säure-Basen-Haushalt.'
|
||||
},
|
||||
{
|
||||
id: 'fecl2',
|
||||
ingredients: ['Cl', 'Cl', 'Fe'],
|
||||
result: 'FeCl₂ (Eisenchlorid)',
|
||||
color: '#2ecc71',
|
||||
desc: 'Eisen(II)-chlorid ist ein blassgrünes Salz. Seine sauren Lösungen werden in der Industrie zur Abwasserreinigung (als Fällungsmittel) und zum präzisen Ätzen von Leiterplatten eingesetzt.'
|
||||
}
|
||||
];
|
||||
|
||||
// Fortgeschrittene Molekül-Reaktionen Datenbank (Phase 4: Säure-Base & komplexe Reaktionen)
|
||||
const advancedRecipes = [
|
||||
{
|
||||
id: 'neutralisation',
|
||||
ingredients: ['hcl', 'naoh'], // Salzsäure + Natronlauge
|
||||
results: ['nacl', 'h2o'], // ergibt Kochsalz + Wasser
|
||||
name: 'Säure-Base-Neutralisation',
|
||||
desc: 'Eine der klassischsten Reaktionen der Chemie! Die stark saure Salzsäure (HCl) und die aggressive, basische Natronlauge (NaOH) neutralisieren sich gegenseitig vollständig zu harmlosem Kochsalz (NaCl) und reinem Wasser (H₂O). Die Lösung erwärmt sich dabei durch die freiwerdende Neutralisationswärme stark!'
|
||||
},
|
||||
{
|
||||
id: 'methan_verbrennung',
|
||||
ingredients: ['ch4', 'o2', 'o2'], // Methan + 2x Sauerstoff
|
||||
results: ['co2', 'h2o', 'h2o'], // ergibt Kohlendioxid + 2x Wasser
|
||||
name: 'Methangas-Verbrennung',
|
||||
desc: 'Methan (CH₄), der Hauptbestandteil von gasförmigem Erdgas, reagiert intensiv mit Sauerstoff (O₂). Bei dieser stark exothermen Verbrennungsreaktion entstehen Kohlendioxid (CO₂) und Wasserdampf (H₂O). Dies ist die treibende Kraft hinter vielen häuslichen Gasheizungen!'
|
||||
},
|
||||
{
|
||||
id: 'salmiak_rauch',
|
||||
ingredients: ['nh3', 'hcl'], // Ammoniak + Salzsäure (Chlorwasserstoff)
|
||||
results: ['nh4cl'], // ergibt Ammoniumchlorid
|
||||
name: 'Ammoniumchlorid-Synthese (Salmiak-Rauch)',
|
||||
desc: 'Wenn das stechend riechende Ammoniakgas (NH₃) und Chlorwasserstoffgas (HCl) direkt aufeinandertreffen, findet eine Gasphasenreaktion statt. Es bildet sich sofort ein dichter weißer Rauch aus feinsten Ammoniumchlorid-Salzkristallen (NH₄Cl), auch bekannt als Salmiak!'
|
||||
},
|
||||
{
|
||||
id: 'saurer_regen',
|
||||
ingredients: ['so2', 'h2o'], // Schwefeldioxid + Wasser
|
||||
results: ['h2so3'], // ergibt Schweflige Säure
|
||||
name: 'Saure-Regen-Bildung',
|
||||
desc: 'Schwefeldioxid (SO₂) entsteht bei der Verbrennung fossiler Brennstoffe. Wenn dieses Gas in der Atmosphäre mit Regenwasser (H₂O) reagiert, bildet sich Schweflige Säure (H₂SO₃). Dies führt zum berüchtigten "sauren Regen", der Böden, Wälder und historische Bauten schädigt.'
|
||||
},
|
||||
{
|
||||
id: 'kohlensaeure_bildung',
|
||||
ingredients: ['co2', 'h2o'], // Kohlendioxid + Wasser
|
||||
results: ['h2co3'], // ergibt Kohlensäure
|
||||
name: 'Kohlensäure-Bildung',
|
||||
desc: 'Kohlendioxid (CO₂) löst sich zu einem kleinen Prozentsatz physikalisch-chemisch in Wasser (H₂O) und bildet Kohlensäure (H₂CO₃). Sie sorgt für das spritzige Prickeln in Mineralwasser und sprudelnden Erfrischungsgetränken!'
|
||||
},
|
||||
{
|
||||
id: 'eisen_saeure',
|
||||
ingredients: ['Fe', 'hcl', 'hcl'], // Eisen + 2x Salzsäure
|
||||
results: ['fecl2', 'h2'], // ergibt Eisenchlorid + Wasserstoff
|
||||
name: 'Säureangriff auf Metalle',
|
||||
desc: 'Unedle Metalle wie Eisen (Fe) werden von Säuren wie der Salzsäure (HCl) angegriffen. Dabei oxidiert das Eisen zu löslichem Eisenchlorid (FeCl₂), während der Wasserstoff der Säure als hochentzündliches Wasserstoff-Gas (H₂) entweicht. Es sprudelt!'
|
||||
},
|
||||
{
|
||||
id: 'chlorknallgas',
|
||||
ingredients: ['h2', 'cl2'], // Wasserstoff-Molekül + Chlor-Molekül
|
||||
results: ['hcl', 'hcl'], // ergibt 2x Salzsäure-Gas
|
||||
name: 'Chlorknallgas-Reaktion',
|
||||
desc: 'Wenn reines Wasserstoff-Gas (H₂) und Chlor-Gas (Cl₂) gemischt werden, genügt ein kurzer Lichtblitz oder Funke, um eine extrem heftige, explosive Kettenreaktion auszulösen. Dabei entsteht gasförmiger Chlorwasserstoff (HCl), der in Wasser gelöst Salzsäure bildet!'
|
||||
}
|
||||
];
|
||||
|
||||
@ -259,7 +340,34 @@ const levels = [
|
||||
goalFormula: "hcl",
|
||||
allowedAtoms: ['H', 'Cl'],
|
||||
intro: "Unser Labor-Maskottchen (ein kleiner gefräßiger Drache) hat Bauchschmerzen, weil er zu viel gefressen hat. Wir müssen seine Verdauung ankurbeln! Synthetisiere Salzsäure (HCl) aus einem Wasserstoff-Atom (H) und einem Chlor-Atom (Cl), um seinen Magensaft zu verstärken!",
|
||||
successText: "Perfekt! Dem kleinen Drachen geht es schon viel besser. Salzsäure ist extrem sauer und zersetzt selbst zähes Fleisch im Handumdrehen. Du hast den Story-Modus abgeschlossen! Du bist jetzt ein zertifizierter Labor-Meister!",
|
||||
successText: "Perfekt! Dem kleinen Drachen geht es schon viel besser. Salzsäure ist extrem sauer und zersetzt selbst zähes Fleisch im Handumdrehen. Nun bist du bereit für fortgeschrittenere Synthesen!",
|
||||
reward: "Schaltet Level 6 frei"
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "Die weiße Rauchbombe",
|
||||
goalFormula: "salmiak_rauch",
|
||||
allowedAtoms: ['N', 'H', 'Cl'],
|
||||
intro: "Hervorragend, Alchemist! Jetzt wird es spektakulär: Wir bereiten einen Show-Effekt für den Tag der offenen Tür vor. Wir wollen dichten, weißen Nebel erzeugen! Synthetisiere zuerst Ammoniak (NH₃) aus 1x N und 3x H, und Salzsäure (HCl) aus 1x H und 1x Cl. Ziehe dann beide Moleküle zusammen, um feinstes Ammoniumchlorid-Salz (NH₄Cl) als Nebel entstehen zu lassen!",
|
||||
successText: "Sensationell! Ein dichter weißer Rauch steigt auf. Du hast soeben deine erste zweistufige Synthese gemeistert! Aus Stickstoff, Wasserstoff und Chlor hast du zuerst Gase erzeugt und diese dann zu feinem Ammoniumchlorid-Salz neutralisiert.",
|
||||
reward: "Schaltet Level 7 frei"
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: "Das saure Umweltproblem",
|
||||
goalFormula: "saurer_regen",
|
||||
allowedAtoms: ['S', 'O', 'H'],
|
||||
intro: "Sehr gut! Ein Naturschutzverein bittet uns um Hilfe: Sie vermuten sauren Regen als Ursache für ein Waldsterben. Kannst du im Labor demonstrieren, wie dieser gebildet wird? Synthetisiere Schwefeldioxid (SO₂) aus 1x S und 2x O, sowie Wasser (H₂O) aus 2x H und 1x O. Ziehe dann beide Moleküle zusammen, um Schweflige Säure (H₂SO₃) zu erzeugen!",
|
||||
successText: "Perfekt demonstriert! Schwefeldioxid (SO₂) verbindet sich mit dem Regenwasser (H₂O) zu Schwefliger Säure (H₂SO₃). Dank deiner Veranschaulichung versteht das Team das Problem nun genau und kann gezielte Filteranlagen fordern!",
|
||||
reward: "Schaltet Level 8 frei"
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
title: "Die Säure-Base-Schlacht",
|
||||
goalFormula: "neutralisation",
|
||||
allowedAtoms: ['H', 'Cl', 'Na', 'O'],
|
||||
intro: "Willkommen zum großen Meisterstück der Alchemie! Ein wahrer Meister muss aggressive Säuren und Basen bändigen. Wir haben ätzende Salzsäure (HCl) und hochreaktive Natronlauge (NaOH). Neutralisiere sie! Synthetisiere zuerst HCl und NaOH, und bringe sie dann zusammen, um harmloses Kochsalz (NaCl) und reines Wasser (H₂O) zu erhalten!",
|
||||
successText: "Unglaublich! Du hast es geschafft! Die heftige Reaktion hat Energie freigesetzt, aber am Ende blieben nur Speisesalz und klares Wasser übrig. Du hast die Kunst der Neutralisation gemeistert und bist nun ein anerkannter Großmeister der molekularen Alchemie!",
|
||||
reward: "Story-Modus abgeschlossen! 🎉"
|
||||
}
|
||||
];
|
||||
@ -427,7 +535,78 @@ function checkForReactions() {
|
||||
}
|
||||
|
||||
if (cluster.length > 1) {
|
||||
// Ignoriere Cluster, die bereits Moleküle enthalten (nur Atome fusionieren in diesem Prototyp)
|
||||
// Reaktions-Keys extrahieren (Atome => Großbuchstaben-Symbol, Moleküle => Kleinbuchstaben-Rezept-ID)
|
||||
const reactantKeys = [];
|
||||
cluster.forEach(el => {
|
||||
if (el.classList.contains('atom')) {
|
||||
reactantKeys.push(el.dataset.symbol);
|
||||
} else if (el.classList.contains('molecule')) {
|
||||
reactantKeys.push(el.dataset.recipeId);
|
||||
}
|
||||
});
|
||||
reactantKeys.sort();
|
||||
|
||||
// ZUERST: Fortgeschrittene Molekül-Reaktionen prüfen
|
||||
let advancedReactionFound = false;
|
||||
for (const advRecipe of advancedRecipes) {
|
||||
const advIngredients = [...advRecipe.ingredients].sort();
|
||||
|
||||
if (JSON.stringify(reactantKeys) === JSON.stringify(advIngredients)) {
|
||||
// FORTGESCHRITTENE REAKTION ERFOLGREICH!
|
||||
advancedReactionFound = true;
|
||||
const midX = parseFloat(draggingElement.style.left) + draggingElement.offsetWidth / 2;
|
||||
const midY = parseFloat(draggingElement.style.top) + draggingElement.offsetHeight / 2;
|
||||
|
||||
// Lösche alle reactant-Elemente im Cluster vom Tisch
|
||||
cluster.forEach(el => {
|
||||
if (workspace.contains(el)) {
|
||||
workspace.removeChild(el);
|
||||
}
|
||||
elementsOnDesk = elementsOnDesk.filter(e => e !== el);
|
||||
});
|
||||
|
||||
// Dicke, bunte Explosion erzeugen
|
||||
triggerExplosion(midX, midY, '#ff9f43');
|
||||
|
||||
// Erzeuge alle Produkt-Moleküle des fortgeschrittenen Rezepts
|
||||
advRecipe.results.forEach((prodId, index) => {
|
||||
const prodRecipe = recipes.find(r => r.id === prodId);
|
||||
if (prodRecipe) {
|
||||
// Platziere Produkte nebeneinander im Fusionszentrum
|
||||
const offsetMultiplier = index - (advRecipe.results.length - 1) / 2;
|
||||
const molX = midX - 60 + (offsetMultiplier * 80);
|
||||
const molY = midY - 20;
|
||||
createMolecule(prodRecipe, molX, molY);
|
||||
|
||||
// Entdeckung registrieren
|
||||
const isNew = !discoveredMolecules.has(prodRecipe.id);
|
||||
if (isNew) {
|
||||
discoveredMolecules.add(prodRecipe.id);
|
||||
localStorage.setItem('chem_lab_discoveries', JSON.stringify([...discoveredMolecules]));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
renderDiscoveryBook();
|
||||
|
||||
// Story-Modus Ziel prüfen (für fortgeschrittene Reaktionen)
|
||||
if (gameMode === 'story') {
|
||||
const currentLevel = levels[currentLevelIndex];
|
||||
if (advRecipe.id === currentLevel.goalFormula) {
|
||||
handleLevelSuccess(currentLevel, advRecipe);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Info-Modal für die gesamte Reaktion anzeigen!
|
||||
showAdvancedReactionModal(advRecipe);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (advancedReactionFound) return;
|
||||
|
||||
// DANACH: Normale Atom-Fusion (Cluster darf KEINE Moleküle enthalten!)
|
||||
const hasMolecule = cluster.some(el => el.classList.contains('molecule'));
|
||||
if (hasMolecule) return;
|
||||
|
||||
@ -466,7 +645,7 @@ function checkForReactions() {
|
||||
renderDiscoveryBook();
|
||||
}
|
||||
|
||||
// Story-Modus Ziel prüfen
|
||||
// Story-Modus Ziel prüfen (für atomare Fusionen)
|
||||
if (gameMode === 'story') {
|
||||
const currentLevel = levels[currentLevelIndex];
|
||||
if (recipe.id === currentLevel.goalFormula) {
|
||||
@ -489,6 +668,7 @@ function createMolecule(recipe, x, y) {
|
||||
el.classList.add('molecule');
|
||||
el.innerText = recipe.result.split(' ')[0]; // Zeigt z.B. H₂O an
|
||||
el.dataset.symbol = recipe.result;
|
||||
el.dataset.recipeId = recipe.id;
|
||||
el.style.backgroundColor = recipe.color;
|
||||
|
||||
// Grenzen im Workspace einhalten
|
||||
@ -564,6 +744,28 @@ function showModal(recipe, isNew = true) {
|
||||
infoModal.classList.remove('hidden');
|
||||
}
|
||||
|
||||
function showAdvancedReactionModal(advRecipe) {
|
||||
modalTitle.innerText = "Chemische Reaktivität! 💥";
|
||||
document.querySelector('#info-modal .modal-emoji').innerText = "💥";
|
||||
|
||||
// Formel mit Tiefstellung formatieren (Sowohl Atome wie Fe als auch Moleküle wie h2o)
|
||||
const formatFormula = (id) => {
|
||||
const formulaText = id.toUpperCase();
|
||||
return formulaText.replace(/\d/g, m => '<sub>' + m + '</sub>');
|
||||
};
|
||||
|
||||
const reactantsText = advRecipe.ingredients.map(formatFormula).join(' + ');
|
||||
const productsText = advRecipe.results.map(formatFormula).join(' + ');
|
||||
|
||||
modalFormula.innerHTML = `${reactantsText} → ${productsText}`;
|
||||
modalFormula.style.backgroundColor = '#ff9f43'; // Schöne orange exotherme Reaktionsfarbe
|
||||
|
||||
modalName.innerText = advRecipe.name;
|
||||
modalDesc.innerText = advRecipe.desc;
|
||||
|
||||
infoModal.classList.remove('hidden');
|
||||
}
|
||||
|
||||
function renderDiscoveryBook() {
|
||||
discoveryBook.innerHTML = '';
|
||||
let count = 0;
|
||||
@ -851,8 +1053,8 @@ function renderLevelDots() {
|
||||
container.appendChild(dot);
|
||||
});
|
||||
|
||||
const completedCount = completedLevels.length;
|
||||
document.getElementById('story-overall-progress').innerText = `${completedLevels.includes(5) ? 5 : Math.max(1, completedLevels.length + 1)}/5`;
|
||||
const totalLevels = levels.length;
|
||||
document.getElementById('story-overall-progress').innerText = `${completedLevels.includes(totalLevels) ? totalLevels : Math.min(totalLevels, completedLevels.length + 1)}/${totalLevels}`;
|
||||
}
|
||||
|
||||
function renderStorySpawnButtons() {
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
<div id="story-level-selector">
|
||||
<div class="level-selector-header">
|
||||
<h3>Kapitel-Auswahl</h3>
|
||||
<span id="story-overall-progress">1/5</span>
|
||||
<span id="story-overall-progress">1/8</span>
|
||||
</div>
|
||||
<div class="level-dots-grid">
|
||||
<!-- Level-Auswahlknöpfe [1] [2] etc. -->
|
||||
|
||||
Loading…
Reference in New Issue
Block a user