2. Fázis · JavaScript
2. Fázis · 1. Lecke

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.

⏱ 60 perc
📁 JavaScript
🎯 let · const · típusok

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.

A három kulcsszó

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

🏰 Castle Siege

A játéksebesség, ami a gombokkal változtatható:

castle_siege.html
// 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;
🐸 Froggy Rush

A béka pozíciója és az élet számláló:

froggy_rush.html
// 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
🐢 Teknős Verseny

Az energia és a teknős pozíciója:

turtle_race.html
// 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ípusPéldaMire jóJátékban
number42 3.14 -5Számolás, pozíció, pontÉlet, energia, koordináta
string"Zoli" 'Béka'Szöveg tárolásaJátékos neve, felirat
booleantrue falseIgen/nem döntésekUgrás? Páncél? Él?
array[1, 2, 3]Lista tárolásaEllenségek, tojások, tornyok
object{x:10, y:20}Összetett adatBéka, teknős, kastély
null / undefinednullNincs érték / nem létezikToronyhelyen nincs torony
tipusok.js — mind a 6 típusJavaScript
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"
Tipp — F12 konzol

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!

✏️ 1. Lecke feladata

Nyisd meg a böngésző konzolját (F12 → Console) és próbáld ki:

  • Hozz létre egy let lives = 3 vá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?

const lives = 3;
let lives = 3;
var lives = 3;  (működik, de kerülendő)
int lives = 3;  (ez C/Java szintaxis, JS-ben nem létezik)
2. Fázis · 2. Lecke

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.

⏱ 60 perc
🎯 if · else · switch
🎮 Ütközésdetektálás

1Az if-else szerkezet

feltetel_alap.jsJavaScript
// 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

🏰 Castle Siege

Kastély HP vizsgálata — vége van-e a játéknak?

castle_siege.html
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
}
🐸 Froggy Rush

A béka meghal — mi típusú halál?

froggy_rush.html
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');
  }
}
🐢 Teknős Verseny

Energia szint hatása a felszín szerint:

turtle_race.html
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átorJelentésPéldaEredmény
===Egyenlő (típus is!)3 === 3true
!==Nem egyenlő3 !== 5true
>Nagyobbhp > 0true ha él
<=Kisebb vagy egyenlőlives <= 0true ha meghalt
&&ÉS — mindkettő igazalive && hasEnergyjátszhat
||VAGY — legalább egywon || timesUpvége van
!NEM — megfordítja!jumpingnem ugrik
== vs === — mindig a háromjelet használd!

== 3 csak az értéket nézi: "3" == 3 → true (rossz!)
=== 3 típust is néz: "3" === 3 → false (helyes!)

✏️ 2. Lecke feladata

Írj feltételeket a konzolban vagy egy HTML fájlban:

  • Hozz létre let lives = 3 vá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 és let onRock = true — if-el vizsgáld: ha nem ugrik ÉS kövön van → "Meghalt!"

🧠 Mi lesz az eredmény? if ("3" === 3)

true — mert mindkettő 3
false — mert a string "3" nem egyenlő a number 3-mal típusban
Hibát dob
undefined
2. Fázis · 3. Lecke

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.

⏱ 60 perc
🎯 for · while · forEach
🎮 Tömeges ütközésdetektálás

1A három fő ciklus

ciklusok.js — a három alaptípusJavaScript
// 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

🏰 Castle Siege

Minden torony megkeresi a legközelebbi ellenséget:

castle_siege.html
// 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;
    }
  });
});
🐸 Froggy Rush

Az összes objektum mozgatása minden képkockában:

froggy_rush.html
// 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);
  }
});
🐢 Teknős Verseny

A pálya felszín-szegmenseinek kirajzolása:

turtle_race.html
// 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);
}
Melyik ciklust mikor?

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!)

✏️ 3. Lecke feladata

Í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.forEach szerepel (Ctrl+F)

🧠 Melyik ciklus a leggyakoribb a játékainkban tömbök bejárásához?

while
for
forEach
do...while
2. Fázis · 4. Lecke

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.

⏱ 75 perc
🎯 function · paraméter · return
🎮 drawTurtle · dieFrog · buildTower

1Függvény alapok

fuggvenyek.js — az alapszerkezetJavaScript
// 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

🏰 Castle Siege

A addFloat() — lebegő szöveg megjelenítése:

castle_siege.html
// 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');
🐸 Froggy Rush

A dieFrog() — a halál kezelése típus szerint:

froggy_rush.html
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
🐢 Teknős Verseny

A getSurface() — visszaadja az aktuális felszínt:

turtle_race.html
// 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
Arrow function — rövid forma

A modern JS-ben a függvényeket nyíl szintaxissal is írhatjuk. Ugyanazt csinálja, csak rövidebb:

arrow_function.jsJavaScript
// 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);
});
✏️ 4. Lecke feladata

Í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 drawFrog sort — hány paramétere van?

🧠 Mi a különbség a paraméter és az argumentum között?

Semmilyen — ugyanazt jelenti
A paraméter a függvény definíciójában van (pl. amount), az argumentum a hívásnál átadott érték (pl. 10)
A paraméter mindig szám, az argumentum bármi lehet
Csak a return-ös függvényeknek van argumentuma
2. Fázis · 5. Lecke

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.

⏱ 75 perc
🎯 push · filter · map · find
🎮 Ellenségek · Tojások · Tornyok

1Tömb alapok

tomb_alapok.jsJavaScript
// 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ódusMit csinálJá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 maradnakHalott ellenségek törlése
forEach(fn)Minden elemre lefuttat egy függvénytMinden ellenség mozgatása
find(fn)Az első megfelelő elemet adja visszaLegközelebbi ellenség keresése
map(fn)Minden elemet átalakítKoordináták átszámítása
some(fn)Igaz ha legalább egy megfelelVan-e még élő ellenség?
every(fn)Igaz ha mind megfelelMinden home pad tele van-e?

3 példa a játékainkból

🏰 Castle Siege

Halott lövedékek törlése filterrel:

castle_siege.html
// 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;
});
🐸 Froggy Rush

Ellenőrzés: minden home pad tele van-e?

froggy_rush.html
// every: akkor igaz, ha MINDEGYIK tele
if (G.homes.every(h => h.filled)) {
  G.phase = 'levelup';
  G.score += 500 * G.level;
}
💡 Kitalált példa

Top 10 lista rendezése és leszűkítése:

toplista.js
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}`);
});
✏️ 5. Lecke feladata

Tömbök a konzolban:

  • Hozz létre egy üres enemies tö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?

Megkeresi az első megfelelő elemet
Módosítja az eredeti tömb elemeit
Új tömböt ad vissza, csak azokkal az elemekkel amelyekre a feltétel igaz
Rendezi a tömböt
2. Fázis · 6. Lecke

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.

⏱ 75 perc
🎯 Objektumok · Tulajdonságok · Beágyazás
🎮 G állapot · makeTurtle

1Objektum alapok

objektumok.jsJavaScript
// 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

🏰 Castle Siege

A G — az egész játékállapot egy objektumban:

castle_siege.html
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.
🐢 Teknős Verseny

A makeTurtle() — objektumot gyártó függvény:

turtle_race.html
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);
💡 Kitalált példa

Beágyazott objektumok — játékos profil:

profil.js
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"
✏️ 6. Lecke feladata

Objektumok tervezése:

  • Hozz létre egy player objektumot: name, lives, energy, x, y, score tulajdonságokkal
  • Adj hozzá egy beágyazott hero objektumot: 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?

player[hero][speed]
player.hero.speed
player->hero->speed
player::hero::speed
2. Fázis · 7. Lecke

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.

⏱ 60 perc
🎯 addEventListener · keydown · keyup
🎮 WASD és nyilak irányítás

1Az addEventListener

billentyuk.js — az alap szerkezetJavaScript
// 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

🏰 Castle Siege

K objektum — tárolja melyik gomb van lenyomva:

castle_siege.html
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;
🐸 Froggy Rush

Béka mozgatása nyíl billentyűkkel:

froggy_rush.html
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();
  }
});
🐢 Teknős Verseny

Ugrás és páncél billentyűk kezelése:

turtle_race.html
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;
});
✏️ 7. Lecke feladata

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?

"left"
"LeftArrow"
"ArrowLeft"
37
2. Fázis · 8. Lecke

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.

⏱ 60 perc
🎯 click · touchstart · getBoundingClientRect
🎮 Canvas kattintás · D-pad

1Egér kattintás canvason

eger_canvas.js — koordináta számításJavaScript
// 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

🏰 Castle Siege

Galactic Conquest — hex mező kattintás:

galactic_conquest.html
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);
});
🐸 Froggy Rush

Swipe érintéskezelés a canvason:

froggy_rush.html
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
});
🐢 Teknős Verseny

D-pad gombok — érintős irányítás:

turtle_race.html (HTML + JS)
<!-- 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;
✏️ 8. Lecke feladata

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?

Mert a canvas nem érzékeli a kattintást alapból
Mert a canvas nem mindig a (0,0) koordinátán kezdődik az oldalon — a rect adja meg a valódi pozícióját
Mert mobilon másképp működik az érintés
Csak IE11-ben szükséges
2. Fázis · 9. Lecke

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.

⏱ 60 perc
🎯 Math.random · Math.floor · Math.sin
🎮 Spawn · Animáció · Parabolaív

1A Math objektum legfontosabb metódusai

MetódusMit ad visszaJátékban mire
Math.random()0 és 1 közötti véletlen számTojás pozíció, ellenség delay
Math.floor(x)Lefelé kerekít (egész)Véletlenszám egészre
Math.ceil(x)Felfelé kerekítMinimális érték biztosítása
Math.round(x)Legközelebbi egészre kerekítHP kijelzés egészben
Math.min(a, b)A kisebb értékEnergia max 100-ra korlátozva
Math.max(a, b)A nagyobb értékHP 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

🏰 Castle Siege

Véletlenszerű ellenség pozíció spawnolásnál:

castle_siege.html
// 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);
🐸 Froggy Rush

Béka ugrás íve — Math.sin()-nel:

froggy_rush.html
// 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;
}
🐢 Teknős Verseny

Léptető animáció és rönk hullámzás:

turtle_race.html
// 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, ...);
A véletlenszám receptje

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)

✏️ 9. Lecke feladata

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)?

Math.random() * 6
Math.floor(Math.random() * 6)
1 + Math.floor(Math.random() * 6)
Math.random(1, 6)
2. Fázis · 10. Lecke

🏆 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.

⏱ 2–3 óra
🎯 Önálló fejlesztés
📁 Egyetlen HTML fájl

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:

Minimális követelmények

✓ 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

kviz.html — javasolt adatszerkezetJavaScript
// 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();
  }
}
✏️ Projekt Checklist

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)
Bónusz kihívások

⭐ 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