Weltkueche Fundament: geschaffte Gerichte persistent (localStorage, Schueler-Reload) + Backend-Submit pro Gericht (Lehrer-Historie: score/correctClicks/wrongClicks/completed) + Fehler-Zaehler
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -618,7 +618,7 @@ const BADGES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
/* ====================== STATE ====================== */
|
/* ====================== STATE ====================== */
|
||||||
let state={name:"",score:0,badges:[],completed:[],totalCorrect:0,cleanIngredients:0};
|
let state={name:"",score:0,badges:[],completed:[],totalCorrect:0,totalWrong:0,cleanIngredients:0,startedAt:0};
|
||||||
let map,markerLayer,current;
|
let map,markerLayer,current;
|
||||||
const store={get(k,d){try{const v=localStorage.getItem(k);return v?JSON.parse(v):d;}catch(e){return d;}},set(k,v){try{localStorage.setItem(k,JSON.stringify(v));}catch(e){}}};
|
const store={get(k,d){try{const v=localStorage.getItem(k);return v?JSON.parse(v):d;}catch(e){return d;}},set(k,v){try{localStorage.setItem(k,JSON.stringify(v));}catch(e){}}};
|
||||||
|
|
||||||
@@ -639,6 +639,7 @@ async function startGame(){
|
|||||||
try { await loadWeltkuecheData(); }
|
try { await loadWeltkuecheData(); }
|
||||||
catch (e) { alert('Daten konnten nicht geladen werden: ' + e.message); return; }
|
catch (e) { alert('Daten konnten nicht geladen werden: ' + e.message); return; }
|
||||||
}
|
}
|
||||||
|
wkLoadProgress(); // bereits geschaffte Gerichte (dieser Browser) wiederherstellen
|
||||||
// Name aus Plattform-Session — kein Eingabefeld mehr
|
// Name aus Plattform-Session — kein Eingabefeld mehr
|
||||||
state.name = (window.WK_STUDENT_NAME && window.WK_STUDENT_NAME !== 'Gast') ? window.WK_STUDENT_NAME : 'Forscher:in';
|
state.name = (window.WK_STUDENT_NAME && window.WK_STUDENT_NAME !== 'Gast') ? window.WK_STUDENT_NAME : 'Forscher:in';
|
||||||
document.getElementById('statName').textContent = state.name;
|
document.getElementById('statName').textContent = state.name;
|
||||||
@@ -792,6 +793,8 @@ window.GGS_LIVE_STATE = function() {
|
|||||||
ingCurrent: (current && current.dish && current.idx<current.dish.ings.length) ? current.dish.ings[current.idx] : null,
|
ingCurrent: (current && current.dish && current.idx<current.dish.ings.length) ? current.dish.ings[current.idx] : null,
|
||||||
mistakesInDish: current ? (current.mistakesInDish||0) : 0,
|
mistakesInDish: current ? (current.mistakesInDish||0) : 0,
|
||||||
score: state.score || 0,
|
score: state.score || 0,
|
||||||
|
correctClicks: state.totalCorrect || 0,
|
||||||
|
wrongClicks: state.totalWrong || 0,
|
||||||
completed: completedDish,
|
completed: completedDish,
|
||||||
completedTotal: totalDish,
|
completedTotal: totalDish,
|
||||||
badgesEarned: (state.badges||[]).length,
|
badgesEarned: (state.badges||[]).length,
|
||||||
@@ -800,6 +803,44 @@ window.GGS_LIVE_STATE = function() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ===== Persistenz (Schüler-Reload) + Backend-Submit (Lehrer-Historie/Kennzahlen) ===== */
|
||||||
|
const WK_PKEY = 'wk_progress_' + (window.WK_SESSION_ID || 'local');
|
||||||
|
function wkSaveProgress(){
|
||||||
|
try { store.set(WK_PKEY, { completed: state.completed, score: state.score, badges: state.badges }); } catch(_){}
|
||||||
|
}
|
||||||
|
function wkLoadProgress(){
|
||||||
|
const p = store.get(WK_PKEY, null);
|
||||||
|
if (p && Array.isArray(p.completed)) {
|
||||||
|
state.completed = p.completed;
|
||||||
|
state.score = p.score || 0;
|
||||||
|
state.badges = Array.isArray(p.badges) ? p.badges : [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function wkSubmitProgress(dish, perfect){
|
||||||
|
if (!window.WK_SESSION_ID) return; // Free-Mode → nichts senden
|
||||||
|
const api = (window.WK_API_BASE || '/geograsim/App/php/api') + '/progress';
|
||||||
|
const mis = current ? (current.mistakesInDish||0) : 0;
|
||||||
|
// grobe Sterne aus der Fehlerquote des Gerichts (für Benchmark/Übersicht)
|
||||||
|
const dishStars = perfect ? 5 : mis <= 1 ? 4 : mis <= 3 ? 3 : mis <= 6 ? 2 : 1;
|
||||||
|
try {
|
||||||
|
fetch(api, {
|
||||||
|
method:'POST', headers:{'Content-Type':'application/json'}, credentials:'same-origin',
|
||||||
|
body: JSON.stringify({
|
||||||
|
action:'complete', simId:'weltkueche', stars: dishStars,
|
||||||
|
durationMs: Math.max(0, Date.now() - ((current && current.startTs) || Date.now())),
|
||||||
|
data: {
|
||||||
|
event:'dish_complete',
|
||||||
|
dishId: dish.id, dishName: dish.name, dishOrigin: dish.origin || null,
|
||||||
|
completed: state.completed.length, total: DISHES.length,
|
||||||
|
score: state.score, dishScore: (current && current.dishScore) || 0,
|
||||||
|
correctClicks: state.totalCorrect || 0, wrongClicks: state.totalWrong || 0,
|
||||||
|
mistakesInDish: mis, perfect: !!perfect
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(()=>{});
|
||||||
|
} catch(_){}
|
||||||
|
}
|
||||||
|
|
||||||
/* ====================== DISH GRID ====================== */
|
/* ====================== DISH GRID ====================== */
|
||||||
let _activeFilter = 'all';
|
let _activeFilter = 'all';
|
||||||
function renderDishes(){
|
function renderDishes(){
|
||||||
@@ -839,7 +880,7 @@ window.setDishFilter = setDishFilter;
|
|||||||
/* ====================== GAME ====================== */
|
/* ====================== GAME ====================== */
|
||||||
function openDish(id){
|
function openDish(id){
|
||||||
const dish=DISHES.find(d=>d.id===id);
|
const dish=DISHES.find(d=>d.id===id);
|
||||||
current={dish,idx:0,solved:[],dishScore:0,mistakesInDish:0,found:[],wrongHere:0,wrongStreak:0};
|
current={dish,idx:0,solved:[],dishScore:0,mistakesInDish:0,found:[],wrongHere:0,wrongStreak:0,startTs:Date.now()};
|
||||||
// Aufgabe-Cache reset pro Gericht — neue Korrekt-Auswahl + neue Distraktoren
|
// Aufgabe-Cache reset pro Gericht — neue Korrekt-Auswahl + neue Distraktoren
|
||||||
_taskCache = {};
|
_taskCache = {};
|
||||||
showRecipeScreen(dish);
|
showRecipeScreen(dish);
|
||||||
@@ -1243,7 +1284,7 @@ function guess(key){
|
|||||||
updateHUD(); renderIngList();
|
updateHUD(); renderIngList();
|
||||||
} else {
|
} else {
|
||||||
b.classList.add('wrong'); b.disabled=true;
|
b.classList.add('wrong'); b.disabled=true;
|
||||||
current.wrongStreak++; current.wrongHere++; current.mistakesInDish++;
|
current.wrongStreak++; current.wrongHere++; current.mistakesInDish++; state.totalWrong++;
|
||||||
showWrong(key, cls, ingKey);
|
showWrong(key, cls, ingKey);
|
||||||
setTimeout(()=>playSfx('ingredient-wrong'), 120);
|
setTimeout(()=>playSfx('ingredient-wrong'), 120);
|
||||||
}
|
}
|
||||||
@@ -1569,6 +1610,8 @@ function finishDish(){
|
|||||||
if(!state.completed.includes(d.id)) state.completed.push(d.id);
|
if(!state.completed.includes(d.id)) state.completed.push(d.id);
|
||||||
playSfx('dish-complete');
|
playSfx('dish-complete');
|
||||||
const perfect=current.mistakesInDish===0;
|
const perfect=current.mistakesInDish===0;
|
||||||
|
wkSaveProgress(); // Schüler-Reload merkt sich geschaffte Gerichte
|
||||||
|
wkSubmitProgress(d, perfect); // Lehrer-Historie + Kennzahlen ans Backend
|
||||||
const newly=[];
|
const newly=[];
|
||||||
if(perfect) newly.push(...awardLive(['perfect']));
|
if(perfect) newly.push(...awardLive(['perfect']));
|
||||||
newly.push(...awardLive(['dish']));
|
newly.push(...awardLive(['dish']));
|
||||||
|
|||||||
Reference in New Issue
Block a user