Phase 2 ยท JavaScript
HU EN
Phase 2 ยท Lesson 1

Variables โ€” storing data

The program's memory. Without variables we can't store the score, the number of lives, the frog's position โ€” nothing at all. This is the foundation of everything.

โฑ 60 min
๐Ÿ“ JavaScript
๐ŸŽฏ let ยท const ยท types

1What is a variable?

A variable is a named slot in the machine's memory that we put data into and can retrieve or replace at any time. Every piece of game data lives in a variable.

The three keywords

let โ€” a variable whose value can change (e.g. lives count going down)
const โ€” a constant whose value cannot change (e.g. level width)
var โ€” old style, avoid โ€” not used in modern code

3 examples from our games

๐Ÿฐ Castle Siege

The game speed, which the buttons can change:

castle_siege.html
// let โ€” because the player changes it
let DT = 0.6;
// 0.3 = Child, 0.6 = Slow
// 1.0 = Normal, 1.5 = Fast

// const โ€” the level never exceeds 50
const MAX_LEVEL = 50;
๐Ÿธ Froggy Rush

The frog's position and life counter:

froggy_rush.html
// let โ€” the frog moves, position changes
let frogCol = 5.5;
let lives   = 3;

// const โ€” grid size never changes
const COLS = 12;
const CELL = W / COLS; // 45px
๐Ÿข Turtle Race

Energy and the turtle's position:

turtle_race.html
// let โ€” energy can drain and recharge
let energy = 100;
let score  = 0;

// const โ€” level length is fixed
const LEVEL_DIST = 600;

2Data types

A variable can hold more than just numbers. JavaScript has 6 basic types:

TypeExampleUsed forIn the game
number42 3.14 -5Counting, position, scoreLives, energy, coordinates
string"Alex" 'Frog'Storing textPlayer name, labels
booleantrue falseYes/no decisionsJumping? Shield? Alive?
array[1, 2, 3]Storing a listEnemies, eggs, towers
object{x:10, y:20}Complex dataFrog, turtle, castle
null / undefinednullNo value / doesn't existNo tower on a tower slot
types.js โ€” all 6 typesJavaScript
let score   = 1500;          // number
let name    = "Alex";         // string
let jumping = false;          // boolean
let enemies = ["goblin", "orc"]; // array
let frog    = { x: 5, y: 0 }; // object
let tower   = null;           // null (no tower yet)

// typeof shows the type
console.log(typeof score);   // "number"
console.log(typeof name);    // "string"
console.log(typeof jumping); // "boolean"
Tip โ€” F12 console

Press F12 in the browser โ†’ Console tab โ†’ type JS code and see the result instantly. Try: typeof 42 then press Enter!

โœ๏ธ Lesson 1 Task

Open the browser console (F12 โ†’ Console) and try these:

  • Create a let lives = 3 variable, then print it to the console
  • Change it: lives = lives - 1 โ€” what's its value now?
  • Try to overwrite a const โ€” what error message does the console show?
  • Create an object for your own turtle character with x, y, lives, energy properties

๐Ÿง  Which declaration is correct when the value changes multiple times?

const lives = 3;
let lives = 3;
var lives = 3;  (works, but avoid)
int lives = 3;  (C/Java syntax โ€” doesn't exist in JS)
Phase 2 ยท Lesson 2

Conditions โ€” the program decides

Without if-else there is no game. Every collision, every life loss, every victory is built on conditional logic.

โฑ 60 min
๐ŸŽฏ if ยท else ยท switch
๐ŸŽฎ Collision detection

1The if-else structure

conditions_basic.jsJavaScript
// Basic structure
if (condition) {
  // runs if TRUE
} else if (anotherCondition) {
  // runs if first is false but this is true
} else {
  // runs if none of the above were true
}

3 examples from our games

๐Ÿฐ Castle Siege

Checking castle HP โ€” is the game over?

castle_siege.html
if (G.castle.hp <= 0) {
  G.phase = 'gameover';
  return;
}

// HP bar colour based on percentage
if (pct > 0.6) {
  color = '#3a8a3a'; // green
} else if (pct > 0.3) {
  color = '#9a8a20'; // yellow
} else {
  color = '#8a2020'; // red
}
๐Ÿธ Froggy Rush

The frog dies โ€” what type of death?

froggy_rush.html
if (ZONE.road.includes(f.row)) {
  // on road โ†’ was it hit by a car?
  dieFrog('squish');
}

if (ZONE.river.includes(f.row)) {
  // on water โ†’ is there a log below?
  if (!onLog) {
    dieFrog('splash');
  }
}
๐Ÿข Turtle Race

Energy drain based on surface type:

turtle_race.html
if (surface === 'mud') {
  energy -= 0.22; // drains fast in mud
} else if (surface === 'road') {
  energy += 0.07; // recharges on road
} else {
  energy -= 0.05; // slow drain otherwise
}

if (energy <= 0) {
  loseLife(player);
}

Comparison operators

OperatorMeaningExampleResult
===Equal (type too!)3 === 3true
!==Not equal3 !== 5true
>Greater thanhp > 0true if alive
<=Less than or equallives <= 0true if dead
&&AND โ€” both must be truealive && hasEnergycan play
||OR โ€” at least one truewon || timesUpgame over
!NOT โ€” inverts!jumpingnot jumping
== vs === โ€” always use triple equals!

== 3 only checks value: "3" == 3 โ†’ true (wrong!)
=== 3 also checks type: "3" === 3 โ†’ false (correct!)

โœ๏ธ Lesson 2 Task

Write conditions in the console or an HTML file:

  • Create let lives = 3, then use if to check: if 0, print "Game Over"
  • Write an if-else if-else chain: 3 lives = "Full health", 1โ€“2 = "Watch out!", 0 = "Game Over"
  • Create let isJumping = false and let onRock = true โ€” use if to check: if not jumping AND on a rock โ†’ "Died!"

๐Ÿง  What is the result of if ("3" === 3)?

true โ€” because both are 3
false โ€” because the string "3" and the number 3 are different types
Throws an error
undefined
Phase 2 ยท Lesson 3

Loops โ€” repetition

Every enemy, every egg, every tower must be checked every single frame. Without loops this would be impossible.

โฑ 60 min
๐ŸŽฏ for ยท while ยท forEach
๐ŸŽฎ Mass collision detection

1The three main loops

loops.js โ€” the three basic typesJavaScript
// 1. for loop โ€” when we know how many times to run
for (let i = 0; i < 5; i++) {
  console.log("Wave: " + i);
} // 0, 1, 2, 3, 4

// 2. while loop โ€” while a condition is true
let lives = 3;
while (lives > 0) {
  console.log("Still alive: " + lives);
  lives--;
}

// 3. forEach โ€” for iterating arrays
const enemies = ["goblin", "orc", "troll"];
enemies.forEach(enemy => {
  console.log("Enemy: " + enemy);
});

3 examples from our games

๐Ÿฐ Castle Siege

Every tower finds the closest enemy:

castle_siege.html
// forEach: runs for every tower
G.towers.forEach(tower => {
  let best = null;
  let bestDist = ts.range;

  // nested forEach: check enemies
  G.enemies.forEach(enemy => {
    const d = dist(tower, enemy);
    if (d < bestDist) {
      bestDist = d;
      best = enemy;
    }
  });
});
๐Ÿธ Froggy Rush

Moving all objects every frame:

froggy_rush.html
// Check collision of all objects
// (eggs, rocks, seagulls) with the frog
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);
  }
});
๐Ÿข Turtle Race

Drawing surface segments of the track:

turtle_race.html
// for loop โ€” exactly 5 segments
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);
}
Which loop when?

for โ€” when you know exactly how many times to run (e.g. 5 segments, 50 levels)
while โ€” when it depends on a condition when to stop (e.g. while there are enemies)
forEach โ€” when you need to iterate an array (the most common in games!)

โœ๏ธ Lesson 3 Task

Write loops in the console:

  • Use a for loop to print numbers 1 to 10
  • Create an array of 5 enemy names, use forEach to print each one
  • Use a while loop to simulate a game: start with 3 lives, subtract 1 each round, print when it reaches 0
  • Find the line in Castle Siege where G.enemies.forEach appears (Ctrl+F)

๐Ÿง  Which loop is most common in our games for iterating arrays?

while
for
forEach
do...while
Phase 2 ยท Lesson 4

Functions โ€” reusable code

If we do something more than once, we put it in a function. Castle Siege has 40+ functions โ€” each one performs one well-defined task.

โฑ 75 min
๐ŸŽฏ function ยท parameter ยท return
๐ŸŽฎ drawTurtle ยท dieFrog ยท buildTower

1Function basics

functions.js โ€” the basic structureJavaScript
// Simple function โ€” no parameter, no return value
function startGame() {
  lives = 3;
  score = 0;
  phase = 'play';
}

// Function with a parameter
function addScore(amount) {
  score += amount;       // amount = what we received as parameter
}
addScore(10);           // called with 10
addScore(50);           // called with 50

// With a return value
function dist(ax, ay, bx, by) {
  return Math.hypot(bx-ax, by-ay);
}
const d = dist(0, 0, 3, 4); // d = 5

3 examples from our games

๐Ÿฐ Castle Siege

addFloat() โ€” displaying floating text:

castle_siege.html
// Parameters: where, what, what colour
function addFloat(x, y, txt, col) {
  G.floats.push({
    x, y, txt, col,
    life: 95,
    vy: -0.65
  });
}

// Calling โ€” same way everywhere:
addFloat(enemy.x, enemy.y, '+10g', '#FFD700');
addFloat(p.x, p.y-25, '-1 โค๏ธ', '#f44');
๐Ÿธ Froggy Rush

dieFrog() โ€” handling death by type:

froggy_rush.html
function dieFrog(type) {
  // Already dead โ€” don't run twice
  if (G.frog.dead) return;

  G.frog.dead = true;
  G.frog.deathType = type; // 'squish' or 'splash'
  G.lives--;
  G.phase = 'dead';
  G.phTimer = 80;
  updateUI();
}

// Two calls โ€” different parameters:
dieFrog('squish'); // hit by a car
dieFrog('splash'); // fell in water
๐Ÿข Turtle Race

getSurface() โ€” returns the current surface:

turtle_race.html
// Function with a return value
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]; // e.g. 'mud'
}

// Usage:
const surf = getSurface(250, 2);
// surf === 'mud' โ†’ slows down, drains energy
Arrow function โ€” short form

In modern JS we can also write functions using arrow syntax. Same result, just shorter:

arrow_function.jsJavaScript
// Traditional form
function dist(ax, ay, bx, by) {
  return Math.hypot(bx-ax, by-ay);
}

// Arrow function โ€” same thing, shorter
const dist = (ax, ay, bx, by) => Math.hypot(bx-ax, by-ay);

// You'll see this inside forEach in Castle Siege:
G.enemies.forEach(e => {       // e = one enemy
  const d = dist(tower.x, tower.y, e.x, e.y);
});
โœ๏ธ Lesson 4 Task

Write your own functions:

  • Write a loseLife() function that reduces lives and prints "Game Over" when it hits zero
  • Write an addScore(amount) function that adds points and prints the new total
  • Write a dist(x1,y1,x2,y2) function that returns the distance between two points (Math.hypot)
  • Find the function drawFrog line in Froggy Rush โ€” how many parameters does it have?

๐Ÿง  What's the difference between a parameter and an argument?

Nothing โ€” they mean the same thing
A parameter is in the function definition (e.g. amount); an argument is the value passed when calling it (e.g. 10)
Parameters are always numbers; arguments can be anything
Only functions with return values have arguments
Phase 2 ยท Lesson 5

Arrays โ€” managing lists

A game can have 20 enemies, 30 eggs and 6 towers active at once. They all live in arrays โ€” and every frame we iterate through all of them.

โฑ 75 min
๐ŸŽฏ push ยท filter ยท map ยท find
๐ŸŽฎ Enemies ยท Eggs ยท Towers

1Array basics

array_basics.jsJavaScript
// Creating arrays
let enemies = [];          // empty array
let levels  = [1, 2, 3];  // with numbers
let names   = ["Goblin", "Orc", "Troll"];

// Indexing โ€” starts at 0!
names[0] // "Goblin"
names[2] // "Troll"
names.length // 3

// Adding โ€” push()
enemies.push({ x: 100, y: 200, hp: 50 });

// Removing โ€” splice()
enemies.splice(0, 1); // removes element at index 0

The most important array methods

MethodWhat it doesUsed in game for
push(elem)Adds to the endSpawning a new enemy or projectile
filter(fn)Keeps only elements where fn returns trueRemoving dead enemies
forEach(fn)Runs a function on each elementMoving every enemy
find(fn)Returns the first matching elementFinding the closest enemy
map(fn)Transforms every elementConverting coordinates
some(fn)True if at least one matchesIs there still a living enemy?
every(fn)True if all matchAre all home pads filled?

3 examples from our games

๐Ÿฐ Castle Siege

Removing dead projectiles with filter:

castle_siege.html
// filter: only the living ones remain
G.hProj = G.hProj.filter(p => {
  p.x += p.vx * DT;
  p.y += p.vy * DT;
  p.life -= DT;
  // if life <= 0 or off screen โ†’ remove
  return p.life > 0 && p.x > 0 && p.x < W;
});
๐Ÿธ Froggy Rush

Checking if all home pads are filled:

froggy_rush.html
// every: true only if ALL are filled
if (G.homes.every(h => h.filled)) {
  G.phase = 'levelup';
  G.score += 500 * G.level;
}
๐Ÿ’ก Custom example

Sorting and trimming a Top 10 list:

leaderboard.js
let topList = [
  { name: "Alex", score: 1500 },
  { name: "Sam",  score: 2200 },
  { name: "Tom",  score: 800  },
];

// Sort by score โ€” descending
topList.sort((a, b) => b.score - a.score);

// Keep only the top 10
topList = topList.slice(0, 10);

// Print: "1. Sam: 2200 pts"
topList.forEach((t, i) => {
  console.log(`${i+1}. ${t.name}: ${t.score}`);
});
โœ๏ธ Lesson 5 Task

Arrays in the console:

  • Create an empty enemies array, use push to add 3 objects (with name, hp properties)
  • Use forEach to print every enemy's name and HP
  • Use filter to remove those whose HP dropped to 0 or below (hp <= 0)
  • Use find to locate the first enemy with hp < 50
  • Use sort to arrange them by HP in descending order

๐Ÿง  What does the filter() method do?

Finds the first matching element
Modifies the elements of the original array
Returns a new array containing only the elements for which the condition is true
Sorts the array
Phase 2 ยท Lesson 6

Objects โ€” complex data

A turtle is not just one number โ€” it has an x position, y position, energy level, name, speed. All of this lives together in a single object.

โฑ 75 min
๐ŸŽฏ Objects ยท Properties ยท Nesting
๐ŸŽฎ G state ยท makeTurtle

1Object basics

objects.jsJavaScript
// Creating an object โ€” curly braces
const frog = {
  col:    5.5,         // horizontal position
  row:    0,           // row (on grid)
  lives:  3,           // lives
  dead:   false,       // is it alive?
  riding: null         // which log it's standing on
};

// Reading โ€” dot operator
console.log(frog.lives);  // 3
console.log(frog.dead);   // false

// Writing โ€” same way
frog.lives = 2;
frog.dead  = true;

3 examples from our games

๐Ÿฐ Castle Siege

G โ€” the entire game state in one object:

castle_siege.html
let G; // the entire game state

function initLevel() {
  G = {
    hero:    { x: 155, y: 300, hp: 100 },
    castle:  { hp: 200, maxHp: 200 },
    enemies: [],   // array inside object!
    towers:  [],
    gold:    0,
    wave:    0,
    phase:   'play'
  };
}
// Access: G.castle.hp, G.hero.x, etc.
๐Ÿข Turtle Race

makeTurtle() โ€” a function that creates objects:

turtle_race.html
function makeTurtle(x, isAI) {
  return {
    x,            // shorthand: x: x
    vx:     0,
    lives:  3,
    energy: 100,
    jumping: false,
    inShell: false,
    isAI,         // shorthand: isAI: isAI
    eggs:   0
  };
}

// Two turtles with the same structure:
const player = makeTurtle(W/2-22, false);
const ai     = makeTurtle(W/2+22, true);
๐Ÿ’ก Custom example

Nested objects โ€” player profile:

profile.js
const profile = {
  name:  "Alex",
  score: 4500,
  hero: {                  // nested object
    spd:   2,
    dmg:   3,
    level: 15
  },
  games: ["castle", "froggy"] // array inside
};

// Chained access:
profile.hero.spd   // 2
profile.games[0]  // "castle"
โœ๏ธ Lesson 6 Task

Designing objects:

  • Create a player object with name, lives, energy, x, y, score properties
  • Add a nested hero object with speed, damage, level fields
  • Write a makeEnemy(type) function that returns an enemy object (hp, speed, gold, name based on type)
  • Call it 3 times with different types and put the results in an array

๐Ÿง  How do we access a property of a nested object?

player[hero][speed]
player.hero.speed
player->hero->speed
player::hero::speed
Phase 2 ยท Lesson 7

Events โ€” keyboard

Player presses the arrow โ†’ the frog jumps. This is event handling. Without it the game just stares back โ€” it doesn't react to anything.

โฑ 60 min
๐ŸŽฏ addEventListener ยท keydown ยท keyup
๐ŸŽฎ WASD and arrow controls

1The addEventListener

keyboard.js โ€” the basic structureJavaScript
// Adding an event listener
document.addEventListener('keydown', (e) => {
  console.log(e.key); // prints which key was pressed
});

// When a key is released
document.addEventListener('keyup', (e) => {
  console.log("Released: " + e.key);
});

3 examples from our games

๐Ÿฐ Castle Siege

K object โ€” tracks which keys are held:

castle_siege.html
const K = {}; // held keys

document.addEventListener('keydown', e => {
  K[e.key.toLowerCase()] = true;
  if (e.key === 'e') doInteract();
});
document.addEventListener('keyup', e => {
  K[e.key.toLowerCase()] = false;
});

// Checked continuously in the game loop:
if (K['a'] || K['arrowleft']) hero.vx -= speed;
๐Ÿธ Froggy Rush

Moving the frog with arrow keys:

froggy_rush.html
document.addEventListener('keydown', e => {
  const k = e.key;
  if (k === 'ArrowUp'   || k === 'w') {
    dpad(0, 1);  // up
  } else if (k === 'ArrowLeft' || k === 'a') {
    dpad(-1, 0); // left
  }
  // Space / Enter: restart
  if (k === ' ' || k === 'Enter') {
    e.preventDefault();
    startGame();
  }
});
๐Ÿข Turtle Race

Jump and shield key handling:

turtle_race.html
document.addEventListener('keydown', e => {
  if (e.key === 'ArrowUp') {
    K.up = true;      // jump
    e.preventDefault();// prevent page scroll
  } if (e.key === 'ArrowDown') {
    K.down = true;    // shell
  }
});
document.addEventListener('keyup', e => {
  if (e.key === 'ArrowUp')   K.up   = false;
  if (e.key === 'ArrowDown') K.down = false;
});
โœ๏ธ Lesson 7 Task

Keyboard handling in your own HTML file:

  • Create an HTML file with a canvas, and listen for keydown with addEventListener
  • Press different keys and print the e.key value โ€” what do you get for ArrowLeft?
  • Create a K = {} object and implement the keydown/keyup pair
  • Draw a small square on the canvas and move it with arrow keys based on the K object

๐Ÿง  What is the e.key value when the left arrow is pressed?

"left"
"LeftArrow"
"ArrowLeft"
37
Phase 2 ยท Lesson 8

Mouse and touch handling

In Castle Siege we click on tower placement spots; in Galactic Conquest we click on hex cells. On mobile we steer by touch. Both are event handling.

โฑ 60 min
๐ŸŽฏ click ยท touchstart ยท getBoundingClientRect
๐ŸŽฎ Canvas click ยท D-pad

1Mouse click on a canvas

mouse_canvas.js โ€” coordinate calculationJavaScript
// The canvas isn't always 1:1 on screen
// getBoundingClientRect() gives its real position
canvas.addEventListener('click', e => {
  const rect = canvas.getBoundingClientRect();

  // Click position inside the canvas:
  const mx = (e.clientX - rect.left) * (W / rect.width);
  const my = (e.clientY - rect.top)  * (H / rect.height);

  console.log(`Clicked: ${mx}, ${my}`);
});

3 examples from our games

๐Ÿฐ Castle Siege

Galactic Conquest โ€” hex cell click:

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

  // Find the closest hex
  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 touch handling on the canvas:

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); // horizontal
  else
    dpad(0, dy < 0 ? 1 : -1); // vertical
});
๐Ÿข Turtle Race

D-pad buttons โ€” touch controls:

turtle_race.html (HTML + JS)
<!-- HTML: touch button -->
<div class="dp"
  ontouchstart="K.left=true"
  ontouchend="K.left=false">โฌ…๏ธ</div>

// JS: the turtle moves based on K object
if (K.left)  turtle.vx -= accel;
if (K.right) turtle.vx += accel;
โœ๏ธ Lesson 8 Task

Click and touch handling:

  • Add a canvas click event to your HTML file โ€” print the click coordinates
  • Draw a circle on the canvas wherever you clicked
  • Add 4 HTML buttons (โฌ†๏ธโฌ…๏ธ๐Ÿขโžก๏ธ) with ontouchstart/ontouchend attributes
  • Test on mobile or in Chrome DevTools mobile view (F12 โ†’ phone icon)

๐Ÿง  Why do we need getBoundingClientRect() for canvas clicks?

Because the canvas doesn't detect clicks by default
Because the canvas doesn't always start at (0,0) on the page โ€” rect gives us its actual position
Because touch works differently on mobile
Only necessary in IE11
Phase 2 ยท Lesson 9

Math and randomness

Every egg appears in a random location. The enemy performs a sinusoidal motion. The shot follows a parabola. All of this is done with the Math object.

โฑ 60 min
๐ŸŽฏ Math.random ยท Math.floor ยท Math.sin
๐ŸŽฎ Spawn ยท Animation ยท Parabola arc

1The most important Math methods

MethodReturnsUsed in game for
Math.random()Random number between 0 and 1Egg position, enemy delay
Math.floor(x)Rounds down (integer)Random number to integer
Math.ceil(x)Rounds upEnsuring a minimum value
Math.round(x)Rounds to nearest integerDisplaying HP as whole number
Math.min(a, b)The smaller valueCapping energy at 100
Math.max(a, b)The larger valuePreventing HP from going below 0
Math.abs(x)Absolute value (no sign)Distance checks
Math.hypot(dx, dy)Euclidean distanceCollision detection
Math.sin(x)Sine (between -1 and 1)Wave motion, jump arc, breathing
Math.PIฯ€ = 3.14159...Circles, angles

3 examples from our games

๐Ÿฐ Castle Siege

Random enemy position on spawn:

castle_siege.html
// Random y position within the level height
const y = UIH + et.r + Math.random() * (GH - et.r * 2);

// Energy recharge โ€” Math.min ensures
// it doesn't exceed 100
p.energy = Math.min(100, p.energy + 40);

// HP can't go below 0:
G.castle.hp = Math.max(0, G.castle.hp - dmg);
๐Ÿธ Froggy Rush

Frog jump arc โ€” using Math.sin():

froggy_rush.html
// jumpT goes from 0 to 22
// Math.sin() traces a 0โ†’1โ†’0 parabola
p.jumpH = Math.sin(p.jumpT / 22 * Math.PI) * 38;
// jumpH: 0 โ†’ 38px (peak) โ†’ 0 back down

// If timer is up โ€” landed
if (p.jumpT >= 22) {
  p.jumping = false;
  p.jumpH   = 0;
}
๐Ÿข Turtle Race

Walking animation and log bobbing:

turtle_race.html
// frame increments continuously (0, 1, 2, 3...)
// sin(frame * 0.2) โ†’ oscillates between -1 and 1
// This produces the walking animation
const walk = Math.sin(frame * 0.2) * 2;

// The turtle's legs step in opposite phase:
ctx.ellipse(-10, 12 + walk, 7, 4, ...);
ctx.ellipse( 10, 12 - walk, 7, 4, ...);
The random number recipe

Between 0 and N: Math.floor(Math.random() * N)
Between MIN and MAX: MIN + Math.floor(Math.random() * (MAX - MIN))
e.g. 1โ€“6 (dice): 1 + Math.floor(Math.random() * 6)

โœ๏ธ Lesson 9 Task

Math operations in the console:

  • Generate a random number between 1 and 100 โ€” run it 5 times
  • Write a clamp(val, min, max) function that limits using Math.min and Math.max
  • Print the Math.sin() value from frame=0 to frame=62 (one full circle) โ€” what pattern do you see?
  • Calculate the distance between (0,0) and (100, 150) using Math.hypot

๐Ÿง  How do we generate a random integer between 1 and 6 (dice roll)?

Math.random() * 6
Math.floor(Math.random() * 6)
1 + Math.floor(Math.random() * 6)
Math.random(1, 6)
Phase 2 ยท Lesson 10

๐Ÿ† Phase Project โ€” Mini Quiz Game

A summary of all JavaScript basics in one small independent project. Variables, conditions, loops, functions, objects, events โ€” all at once.

โฑ 2โ€“3 hours
๐ŸŽฏ Independent work
๐Ÿ“ Single HTML file

1The project task

Build a browser quiz game using pure HTML + JavaScript (no Canvas โ€” using the DOM). The game must be able to:

Minimum requirements

โœ“ At least 5 questions (stored in an array as objects)
โœ“ 4 answer options for each question
โœ“ Correct answer highlighted in green, wrong ones in red
โœ“ Score counting and display
โœ“ "Next question" button
โœ“ Final results screen with score

quiz.html โ€” suggested data structureJavaScript
// Questions in an array, as objects
const questions = [
  {
    q:       "Which keyword creates a variable that cannot change?",
    options: ["var", "let", "const", "int"],
    answer:  2  // const (index)
  },
  {
    q:       "What does the filter() method do?",
    options: ["Sorts", "Filters", "Sums", "Searches"],
    answer:  1
  },
  // ... 3 more questions ...
];

// Game state
let currentQ = 0;
let score    = 0;

// Show a question
function showQuestion() {
  const q = questions[currentQ];
  document.getElementById('question').textContent = q.q;
  q.options.forEach((opt, i) => {
    document.getElementById('opt' + i).textContent = opt;
  });
}

// Check an answer
function checkAnswer(selectedIndex) {
  const correct = questions[currentQ].answer;
  if (selectedIndex === correct) {
    score++;
    // green highlight...
  }
  currentQ++;
  if (currentQ >= questions.length) {
    showResult();
  } else {
    showQuestion();
  }
}
โœ๏ธ Project Checklist

The finished project must include:

  • let and const used correctly (score = let, questions = const)
  • Questions stored as objects inside an array
  • Answer options displayed using forEach
  • if-else used to determine correct/wrong answers
  • Functions: showQuestion(), checkAnswer(), showResult()
  • Event listeners: clicking on answer buttons
  • Math.round() used to display final score as a percentage
  • CSS for a stylish appearance (at least dark background + coloured buttons)
Bonus challenges

โญ Shuffle question order (Math.random() based shuffle)
โญโญ Time limit per question (setTimeout, countdown)
โญโญโญ Save the best result in localStorage and reload it