Változók — az adatok tárolása
A program memóriája. Változók nélkül nem tudjuk tárolni a pontszámot, az életek számát, a béka pozícióját — semmit. Ez az alapja mindennek.
1Mi az a változó?
A változó egy névvel ellátott fiók a gép memóriájában, amibe adatot teszünk, és amit bármikor előveszünk vagy kicserélünk. Minden játékadat változóban él.
let — változó, aminek az értéke változhat (pl. életek száma csökken)
const — konstans, aminek az értéke nem változhat (pl. pálya szélessége)
var — régi, kerüld — a modern kódban nem használjuk
3 példa a játékainkból
A játéksebesség, ami a gombokkal változtatható:
// let — mert a játékos megváltoztatja let DT = 0.6; // 0.3 = Gyerek, 0.6 = Lassú // 1.0 = Normal, 1.5 = Gyors // const — a szint soha nem megy 50 fölé const MAX_LEVEL = 50;
A béka pozíciója és az élet számláló:
// let — a béka mozog, pozíció változik let frogCol = 5.5; let lives = 3; // const — a pályaméret soha nem változik const COLS = 12; const CELL = W / COLS; // 45px
Az energia és a teknős pozíciója:
// let — energia fogyhat, töltődhet let energy = 100; let score = 0; // const — a pálya hossza fix const LEVEL_DIST = 600;
2Adattípusok
Egy változóban nem csak szám lehet. A JavaScript 6 alapvető típust ismer:
| Típus | Példa | Mire jó | Játékban |
|---|---|---|---|
| number | 42 3.14 -5 | Számolás, pozíció, pont | Élet, energia, koordináta |
| string | "Zoli" 'Béka' | Szöveg tárolása | Játékos neve, felirat |
| boolean | true false | Igen/nem döntések | Ugrás? Páncél? Él? |
| array | [1, 2, 3] | Lista tárolása | Ellenségek, tojások, tornyok |
| object | {x:10, y:20} | Összetett adat | Béka, teknős, kastély |
| null / undefined | null | Nincs érték / nem létezik | Toronyhelyen nincs torony |
let pont = 1500; // number let nev = "Zoli"; // string let ugrik = false; // boolean let ellenség = ["goblin", "ork"]; // array let beka = { x: 5, y: 0 }; // object let torony = null; // null (még nincs torony) // typeof megmutatja a típust console.log(typeof pont); // "number" console.log(typeof nev); // "string" console.log(typeof ugrik); // "boolean"
Nyomd meg F12-t a böngészőben → Console fül → ide írhatsz JS kódot és azonnal látod az eredményt. Pl. írd be: typeof 42 és nyomj Entert!
Nyisd meg a böngésző konzolját (F12 → Console) és próbáld ki:
- Hozz létre egy
let lives = 3változót, majd írd ki konzolra - Változtasd meg:
lives = lives - 1— mi lett az értéke? - Próbáld meg felülírni egy const-ot — mit ír a konzol hibaüzenetnek?
- Hozz létre egy objektumot a saját teknős karakteredhez: x, y, lives, energy tulajdonságokkal
🧠 Melyik deklaráció helyes, ha az értéke többször változik?
Feltételek — a program dönt
Az if-else nélkül nincs játék. Minden ütközés, minden élet-elvesztés, minden győzelem feltételes logikán alapszik.
1Az if-else szerkezet
// Alap szerkezet if (feltétel) { // ha IGAZ, ezt csinálja } else if (másik feltétel) { // ha az első hamis de ez igaz } else { // ha egyik sem igaz }
3 példa a játékainkból
Kastély HP vizsgálata — vége van-e a játéknak?
if (G.castle.hp <= 0) { G.phase = 'gameover'; return; } // Kastély HP szín a sáv alapján if (pct > 0.6) { color = '#3a8a3a'; // zöld } else if (pct > 0.3) { color = '#9a8a20'; // sárga } else { color = '#8a2020'; // piros }
A béka meghal — mi típusú halál?
if (ZONE.road.includes(f.row)) { // úton van → autó ütötte-e? dieFrog('squish'); } if (ZONE.river.includes(f.row)) { // vízen van → van-e alatta rönk? if (!onLog) { dieFrog('splash'); } }
Energia szint hatása a felszín szerint:
if (surface === 'mud') { energy -= 0.22; // sárban gyorsan fogy } else if (surface === 'road') { energy += 0.07; // úton töltődik } else { energy -= 0.05; // egyébként lassan fogy } if (energy <= 0) { loseLife(player); }
Összehasonlító operátorok
| Operátor | Jelentés | Példa | Eredmény |
|---|---|---|---|
=== | Egyenlő (típus is!) | 3 === 3 | true |
!== | Nem egyenlő | 3 !== 5 | true |
> | Nagyobb | hp > 0 | true ha él |
<= | Kisebb vagy egyenlő | lives <= 0 | true ha meghalt |
&& | ÉS — mindkettő igaz | alive && hasEnergy | játszhat |
|| | VAGY — legalább egy | won || timesUp | vége van |
! | NEM — megfordítja | !jumping | nem ugrik |
== 3 csak az értéket nézi: "3" == 3 → true (rossz!)
=== 3 típust is néz: "3" === 3 → false (helyes!)
Írj feltételeket a konzolban vagy egy HTML fájlban:
- Hozz létre
let lives = 3változót, majd if-fel vizsgáld: ha 0, írd ki "Game Over" - Írj if-else if-else láncot: 3 élet = "Teljes élet", 1-2 = "Vigyázz!", 0 = "Vége"
- Hozz létre
let isJumping = falseéslet onRock = true— if-el vizsgáld: ha nem ugrik ÉS kövön van → "Meghalt!"
🧠 Mi lesz az eredmény? if ("3" === 3)
Ciklusok — ismétlés
Minden ellenséget, minden tojást, minden tornyot végig kell nézni minden egyes képkockában. Ciklusok nélkül ez lehetetlen lenne.
1A három fő ciklus
// 1. for ciklus — ha tudjuk hányszor fut for (let i = 0; i < 5; i++) { console.log("Hullám: " + i); } // 0, 1, 2, 3, 4 // 2. while ciklus — amíg feltétel igaz let lives = 3; while (lives > 0) { console.log("Él még: " + lives); lives--; } // 3. forEach — tömbök bejárásához const enemies = ["goblin", "ork", "troll"]; enemies.forEach(enemy => { console.log("Ellenség: " + enemy); });
3 példa a játékainkból
Minden torony megkeresi a legközelebbi ellenséget:
// forEach: minden toronyra lefut G.towers.forEach(tower => { let best = null; let bestDist = ts.range; // beágyazott forEach: ellenségek G.enemies.forEach(enemy => { const d = dist(tower, enemy); if (d < bestDist) { bestDist = d; best = enemy; } }); });
Az összes objektum mozgatása minden képkockában:
// Minden tárgy (tojás, kő, sirály) // ütközésvizsgálata a békaval G.objects.forEach(obj => { if (obj.done) return; // skip const dist = Math.hypot( frog.x - obj.x, frogY - obj.y ); if (dist < obj.r + 13) { collect(obj); } });
A pálya felszín-szegmenseinek kirajzolása:
// for ciklus — pontosan 5 szegmens for (let i = 0; i < segs.length; i++) { const surf = SURFACES[segs[i]]; const topY = -((i+1) * segH) + scrollY; const botY = -(i * segH) + scrollY; ctx.fillStyle = surf.col; ctx.fillRect(TL, topY, TW, botY-topY); }
for — ha pontosan tudod hányszor kell futni (pl. 5 szegmens, 50 pálya)
while — ha feltételtől függ mikor áll meg (pl. amíg van ellenség)
forEach — ha egy tömbön kell végigmenni (ez a leggyakoribb a játékokban!)
Írj ciklusokat a konzolban:
- for ciklussal írd ki a számokat 1-től 10-ig
- Hozz létre egy tömböt 5 ellenség nevével, forEach-csel írd ki mindegyiket
- while ciklussal szimulálj egy játékot: kezdj 3 élettel, minden körben vonj le 1-et, írd ki mikor ér el 0-t
- Keresd meg a Castle Siege-ben azt a sort ahol
G.enemies.forEachszerepel (Ctrl+F)
🧠 Melyik ciklus a leggyakoribb a játékainkban tömbök bejárásához?
Függvények — újrafelhasználható kód
Ha valamit többször csinálunk, azt egy függvénybe tesszük. A Castle Siege-ben 40+ függvény van — mindegyik egy jól körülhatárolt feladatot végez.
1Függvény alapok
// Egyszerű függvény — nincs paraméter, nincs visszatérési érték function startGame() { lives = 3; score = 0; phase = 'play'; } // Paraméteres függvény function addScore(amount) { score += amount; // amount = amit kaptunk paraméternek } addScore(10); // meghívás 10-zel addScore(50); // meghívás 50-nel // Visszatérési értékkel function dist(ax, ay, bx, by) { return Math.hypot(bx-ax, by-ay); } const d = dist(0, 0, 3, 4); // d = 5
3 példa a játékainkból
A addFloat() — lebegő szöveg megjelenítése:
// Paraméter: hol, mit, milyen színnel function addFloat(x, y, txt, col) { G.floats.push({ x, y, txt, col, life: 95, vy: -0.65 }); } // Meghívás — mindenhol ugyanígy: addFloat(enemy.x, enemy.y, '+10g', '#FFD700'); addFloat(p.x, p.y-25, '-1 ❤️', '#f44');
A dieFrog() — a halál kezelése típus szerint:
function dieFrog(type) { // Ha már halott — ne futtasson le kétszer if (G.frog.dead) return; G.frog.dead = true; G.frog.deathType = type; // 'squish' vagy 'splash' G.lives--; G.phase = 'dead'; G.phTimer = 80; updateUI(); } // Kétféle hívás — más paraméterrel: dieFrog('squish'); // autó elütötte dieFrog('splash'); // vízbe esett
A getSurface() — visszaadja az aktuális felszínt:
// Visszatérési értékkel rendelkező függvény function getSurface(dist, level) { const lv = LEVELS[level - 1]; const segH = LEVEL_DIST / lv.segs.length; const idx = Math.min( Math.floor(dist / segH), lv.segs.length - 1 ); return lv.segs[idx]; // pl. 'mud' } // Felhasználás: const surf = getSurface(250, 2); // surf === 'mud' → lassít és fogy az energia
A modern JS-ben a függvényeket nyíl szintaxissal is írhatjuk. Ugyanazt csinálja, csak rövidebb:
// Hagyományos forma function dist(ax, ay, bx, by) { return Math.hypot(bx-ax, by-ay); } // Arrow function — ugyanaz, rövidebben const dist = (ax, ay, bx, by) => Math.hypot(bx-ax, by-ay); // A Castle Siege-ben így látod a forEach-ben: G.enemies.forEach(e => { // e = egy ellenség const d = dist(tower.x, tower.y, e.x, e.y); });
Írj saját függvényeket:
- Írj egy
loseLife()függvényt ami csökkenti a lives-t és kiírja ha vége van - Írj egy
addScore(amount)függvényt ami hozzáad pontot és kiírja az újat - Írj egy
dist(x1,y1,x2,y2)függvényt ami visszaadja két pont távolságát (Math.hypot) - Keresd meg a Froggy Rush-ban a
function drawFrogsort — hány paramétere van?
🧠 Mi a különbség a paraméter és az argumentum között?
Tömbök — listák kezelése
A játékban egyszerre 20 ellenség, 30 tojás, 6 torony él. Mind tömbben van tárolva — és minden képkockában végigmegyünk rajtuk.
1Tömb alapok
// Tömb létrehozása let enemies = []; // üres tömb let levels = [1, 2, 3]; // számokkal let names = ["Goblin", "Ork", "Troll"]; // Indexelés — 0-tól kezdődik! names[0] // "Goblin" names[2] // "Troll" names.length // 3 // Hozzáadás — push() enemies.push({ x: 100, y: 200, hp: 50 }); // Eltávolítás — splice() enemies.splice(0, 1); // 0. indexű elem törlése
A legfontosabb tömb-műveletek
| Metódus | Mit csinál | Játékban mire |
|---|---|---|
push(elem) | Végére ad egy elemet | Új ellenség, új lövedék spawning |
filter(fn) | Csak az igaz elemek maradnak | Halott ellenségek törlése |
forEach(fn) | Minden elemre lefuttat egy függvényt | Minden ellenség mozgatása |
find(fn) | Az első megfelelő elemet adja vissza | Legközelebbi ellenség keresése |
map(fn) | Minden elemet átalakít | Koordináták átszámítása |
some(fn) | Igaz ha legalább egy megfelel | Van-e még élő ellenség? |
every(fn) | Igaz ha mind megfelel | Minden home pad tele van-e? |
3 példa a játékainkból
Halott lövedékek törlése filterrel:
// filter: csak az életben lévők maradnak G.hProj = G.hProj.filter(p => { p.x += p.vx * DT; p.y += p.vy * DT; p.life -= DT; // ha life <= 0 vagy kimegy → töröljük return p.life > 0 && p.x > 0 && p.x < W; });
Ellenőrzés: minden home pad tele van-e?
// every: akkor igaz, ha MINDEGYIK tele if (G.homes.every(h => h.filled)) { G.phase = 'levelup'; G.score += 500 * G.level; }
Top 10 lista rendezése és leszűkítése:
let topList = [ { name: "Zoli", score: 1500 }, { name: "Jen", score: 2200 }, { name: "Tom", score: 800 }, ]; // Rendezés pont szerint — csökkenő topList.sort((a, b) => b.score - a.score); // Csak az első 10 maradjon topList = topList.slice(0, 10); // Kiírás: "1. Jen: 2200 pont" topList.forEach((t, i) => { console.log(`${i+1}. ${t.name}: ${t.score}`); });
Tömbök a konzolban:
- Hozz létre egy üres
enemiestömböt, push-csal adj hozzá 3 objektumot (name, hp tulajdonságokkal) - forEach-csel írd ki minden ellenség nevét és HP-ját
- filter-rel töröld azokat akiknek HP-ja 0 alá ment (hp <= 0)
- find-dal keresd meg az első ellenséget akinek hp < 50
- sort-tal rendezd HP szerint csökkenő sorrendbe
🧠 Mit csinál a filter() metódus?
Objektumok — összetett adatok
Egy teknős nem csak egy szám — van x pozíciója, y pozíciója, energia szintje, neve, sebessége. Mindez egyetlen objektumban él együtt.
1Objektum alapok
// Objektum létrehozása — kapcsos zárójelek const beka = { col: 5.5, // vízszintes pozíció row: 0, // sor (pályán) lives: 3, // életek dead: false, // él-e riding: null // melyik rönkön áll }; // Olvasás — pont operátorral console.log(beka.lives); // 3 console.log(beka.dead); // false // Írás — ugyanígy beka.lives = 2; beka.dead = true;
3 példa a játékainkból
A G — az egész játékállapot egy objektumban:
let G; // a teljes játékállapot function initLevel() { G = { hero: { x: 155, y: 300, hp: 100 }, castle: { hp: 200, maxHp: 200 }, enemies: [], // tömb az objektumban! towers: [], gold: 0, wave: 0, phase: 'play' }; } // Elérés: G.castle.hp, G.hero.x, stb.
A makeTurtle() — objektumot gyártó függvény:
function makeTurtle(x, isAI) { return { x, // rövidítés: x: x vx: 0, lives: 3, energy: 100, jumping: false, inShell: false, isAI, // rövidítés: isAI: isAI eggs: 0 }; } // Két teknős, ugyanazzal a szerkezettel: const player = makeTurtle(W/2-22, false); const ai = makeTurtle(W/2+22, true);
Beágyazott objektumok — játékos profil:
const profil = { name: "Zoli", score: 4500, hero: { // beágyazott objektum spd: 2, dmg: 3, level: 15 }, games: ["castle", "froggy"] // tömb benne }; // Elérés láncolással: profil.hero.spd // 2 profil.games[0] // "castle"
Objektumok tervezése:
- Hozz létre egy
playerobjektumot: name, lives, energy, x, y, score tulajdonságokkal - Adj hozzá egy beágyazott
heroobjektumot: speed, damage, level mezőkkel - Írj egy
makeEnemy(type)függvényt ami visszaad egy ellenség-objektumot (hp, speed, gold, name alapján a type-tól függően) - Hívd meg 3-szor különböző type-okkal és tedd egy tömbbe
🧠 Hogyan érjük el egy beágyazott objektum tulajdonságát?
Események — billentyűzet
A játékos nyomja a nyilat → a béka ugrik. Ez eseménykezelés. Nélküle a játék csak néz vissza, de nem reagál semmire.
1Az addEventListener
// Eseményfigyelő hozzáadása document.addEventListener('keydown', (e) => { console.log(e.key); // kiírja melyik gombot nyomták }); // Gomb felengedésekor document.addEventListener('keyup', (e) => { console.log("Felengedve: " + e.key); });
3 példa a játékainkból
K objektum — tárolja melyik gomb van lenyomva:
const K = {}; // lenyomott gombok document.addEventListener('keydown', e => { K[e.key.toLowerCase()] = true; if (e.key === 'e') doInteract(); }); document.addEventListener('keyup', e => { K[e.key.toLowerCase()] = false; }); // A game loopban folyamatosan ellenőrzi: if (K['a'] || K['arrowleft']) hero.vx -= speed;
Béka mozgatása nyíl billentyűkkel:
document.addEventListener('keydown', e => { const k = e.key; if (k === 'ArrowUp' || k === 'w') { dpad(0, 1); // fel } else if (k === 'ArrowLeft' || k === 'a') { dpad(-1, 0); // bal } // Space / Enter: újrakezdés if (k === ' ' || k === 'Enter') { e.preventDefault(); startGame(); } });
Ugrás és páncél billentyűk kezelése:
document.addEventListener('keydown', e => { if (e.key === 'ArrowUp') { K.up = true; // ugrás e.preventDefault();// oldal ne görgessen } if (e.key === 'ArrowDown') { K.down = true; // páncél } }); document.addEventListener('keyup', e => { if (e.key === 'ArrowUp') K.up = false; if (e.key === 'ArrowDown') K.down = false; });
Billentyűzet kezelés saját HTML fájlban:
- Hozz létre egy HTML fájlt canvas-szal, és addEventListener-rel figyeld a keydown eseményt
- Nyomj különböző gombokat és írd ki a konzolra az
e.keyértékét — mit kapsz ArrowLeft-re? - Hozz létre egy K = {} objektumot, és valósítsd meg a keydown/keyup párost
- Rajzolj egy kis négyzetet canvas-ra, és mozgasd nyilakkal a K objektum alapján
🧠 Mi az e.key értéke ha a bal nyilat nyomják?
Egér és érintés kezelése
A Castle Siege-ben a torony-építési pontokra kattintunk, a Galactic Conquest-ben hex mezőkre. Mobilon érintéssel irányítunk. Mindkettő eseménykezelés.
1Egér kattintás canvason
// A canvas nem mindig 1:1 méretű a képernyőn // getBoundingClientRect() adja az igazi pozícióját canvas.addEventListener('click', e => { const rect = canvas.getBoundingClientRect(); // Kattintás pozíciója a canvason belül: const mx = (e.clientX - rect.left) * (W / rect.width); const my = (e.clientY - rect.top) * (H / rect.height); console.log(`Kattintva: ${mx}, ${my}`); });
3 példa a játékainkból
Galactic Conquest — hex mező kattintás:
CV.addEventListener('click', e => { const rect = CV.getBoundingClientRect(); const mx = (e.clientX - rect.left) * (W/rect.width); const my = (e.clientY - rect.top) * (H/rect.height); // Legközelebbi hex keresése let best = null, bestD = HEX_SIZE * 1.1; G.hexes.forEach(h => { const {x,y} = hexCenter(h.col, h.row); const d = Math.hypot(mx-x, my-y); if (d < bestD) { bestD = d; best = h; } }); if (best) selectHex(best.col, best.row); });
Swipe érintéskezelés a canvason:
let touchStart = null; CV.addEventListener('touchstart', e => { touchStart = { x: e.touches[0].clientX, y: e.touches[0].clientY }; }, { passive: false }); CV.addEventListener('touchend', e => { const dx = e.changedTouches[0].clientX - touchStart.x; const dy = e.changedTouches[0].clientY - touchStart.y; if (Math.abs(dx) > Math.abs(dy)) dpad(dx > 0 ? 1 : -1, 0); // vízszintes else dpad(0, dy < 0 ? 1 : -1); // függőleges });
D-pad gombok — érintős irányítás:
<!-- HTML: érintős gomb --> <div class="dp" ontouchstart="K.left=true" ontouchend="K.left=false">⬅️</div> // JS: a K objektum alapján mozog a teknős if (K.left) turtle.vx -= accel; if (K.right) turtle.vx += accel;
Kattintás és érintés kezelése:
- Adj canvas-click eseményt a saját HTML fájlodhoz — írd ki a kattintás koordinátáit
- Rajzolj egy kört a canvasra ahol kattintottál
- Adj hozzá 4 HTML gombot (⬆️⬅️🐢➡️) ontouchstart/ontouchend attribútumokkal
- Tesztelj mobilon vagy Chrome DevTools mobilos nézetében (F12 → telefon ikon)
🧠 Miért kell getBoundingClientRect() a canvas kattintásnál?
Math és véletlenszerűség
Minden tojás véletlenszerű helyen jelenik meg. Az ellenség sinusos mozgást végez. A lövés parabolát ír le. Mind a Math objektummal valósul meg.
1A Math objektum legfontosabb metódusai
| Metódus | Mit ad vissza | Játékban mire |
|---|---|---|
Math.random() | 0 és 1 közötti véletlen szám | Tojás pozíció, ellenség delay |
Math.floor(x) | Lefelé kerekít (egész) | Véletlenszám egészre |
Math.ceil(x) | Felfelé kerekít | Minimális érték biztosítása |
Math.round(x) | Legközelebbi egészre kerekít | HP kijelzés egészben |
Math.min(a, b) | A kisebb érték | Energia max 100-ra korlátozva |
Math.max(a, b) | A nagyobb érték | HP 0 alá ne menjen |
Math.abs(x) | Abszolút érték (előjel nélkül) | Távolság vizsgálat |
Math.hypot(dx, dy) | Euklideszi távolság | Ütközésdetektálás |
Math.sin(x) | Szinusz (-1 és 1 között) | Hullámzás, ugrásív, légzés |
Math.PI | π = 3.14159... | Körök, szögek |
3 példa a játékainkból
Véletlenszerű ellenség pozíció spawnolásnál:
// Véletlenszerű y pozíció a pálya magasságán belül const y = UIH + et.r + Math.random() * (GH - et.r * 2); // Energia töltési animáció — Math.min biztosítja // hogy nem megy 100 fölé p.energy = Math.min(100, p.energy + 40); // HP 0 alá ne menjen: G.castle.hp = Math.max(0, G.castle.hp - dmg);
Béka ugrás íve — Math.sin()-nel:
// jumpT 0-tól 22-ig megy // Math.sin() 0→1→0 parabolát ír le p.jumpH = Math.sin(p.jumpT / 22 * Math.PI) * 38; // jumpH: 0 → 38px (csúcs) → 0 vissza // Ha időkeret lejárt — leszállt if (p.jumpT >= 22) { p.jumping = false; p.jumpH = 0; }
Léptető animáció és rönk hullámzás:
// frame folyamatosan nő (0, 1, 2, 3...) // sin(frame * 0.2) → -1 és 1 között oszcillál // Ez adja a lépegető animációt const walk = Math.sin(frame * 0.2) * 2; // A teknős lábai ellentétesen lépnek: ctx.ellipse(-10, 12 + walk, 7, 4, ...); ctx.ellipse( 10, 12 - walk, 7, 4, ...);
0 és N között: Math.floor(Math.random() * N)
MIN és MAX között: MIN + Math.floor(Math.random() * (MAX - MIN))
Pl. 1-6 (kocka): 1 + Math.floor(Math.random() * 6)
Math műveletek a konzolban:
- Generálj véletlenszerű számot 1 és 100 között — futtasd 5-ször
- Írj egy
clamp(val, min, max)függvényt ami Math.min és Math.max segítségével korlátoz - Írd ki a Math.sin() értékét frame=0-tól frame=62-ig (egy teljes kör) — milyen mintát látsz?
- Számítsd ki a távolságot a (0,0) és (100, 150) pontok között Math.hypot-tal
🧠 Hogyan generálunk véletlenszerű egész számot 1 és 6 között (kockadobás)?
🏆 Projektzáró — Mini kvíz játék
Az összes JavaScript alap összefoglalása egy kis önálló projektben. Változók, feltételek, ciklusok, függvények, objektumok, események — mind egyszerre.
1A projekt feladata
Készíts egy böngészős kvíz játékot tisztán HTML + JavaScript alapokon (Canvas nélkül — DOM-mal). A játék legyen képes:
✓ Legalább 5 kérdés (tömbben tárolva, objektumokként)
✓ 4 válaszlehetőség minden kérdésnél
✓ Helyes válasz kiemelése zölddel, helytelen pirossal
✓ Pontszám számolása és megjelenítése
✓ "Következő kérdés" gomb
✓ Végeredmény képernyő pontszámmal
// A kérdések tömbben, objektumokként const questions = [ { q: "Melyik kulcsszóval hozunk létre változó értéket?", options: ["var", "let", "const", "int"], answer: 2 // const (index) }, { q: "Mit csinál a filter() metódus?", options: ["Rendez", "Szűr", "Összeadja", "Keres"], answer: 1 }, // ... még 3 kérdés ... ]; // Játékállapot let currentQ = 0; let score = 0; // Kérdés megjelenítése function showQuestion() { const q = questions[currentQ]; document.getElementById('question').textContent = q.q; q.options.forEach((opt, i) => { document.getElementById('opt' + i).textContent = opt; }); } // Válasz ellenőrzés function checkAnswer(selectedIndex) { const correct = questions[currentQ].answer; if (selectedIndex === correct) { score++; // zöld kiemelés... } currentQ++; if (currentQ >= questions.length) { showResult(); } else { showQuestion(); } }
A kész projektnek ezeket kell tartalmaznia:
- let és const helyesen használva (score = let, questions = const)
- A kérdések objektumokban vannak tárolva, tömbben
- forEach-csel jelennek meg a válaszlehetőségek
- if-else-sel dőlt el helyes-e a válasz
- Függvények: showQuestion(), checkAnswer(), showResult()
- Eseménykezelők: a válasz-gombokra kattintás
- Math.round()-dal jelenik meg a végeredmény százalékban
- CSS-sel stílusos megjelenés (legalább sötét háttér + színes gombok)
⭐ Keverje meg a kérdések sorrendjét (Math.random() alapú shuffle)
⭐⭐ Időkorlát kérdésenként (setTimeout, visszaszámláló)
⭐⭐⭐ localStorage-ban menti a legjobb eredményt és visszatölti