Individual Porfolio


Basketball Game


Basketball Evasion — CS111 Code Review

I built a basketball evasion game where you dodge LeBron James on a court. Below I break down every CS111 concept using real code from the game.


Control Structures

Iteration — for, forEach, while loops

The court’s wood plank lines use a for loop:

for (let x = 0; x < W; x += W/28) {
    ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, H); ctx.stroke();
}

The bench legs use forEach to draw 3 positions without repeating code:

[.1, .5, .82].forEach(fx => 
    ctx.fillRect(o.x + o.w*fx, o.y + o.h*.4, o.w*.1, o.h*.55)
);

Conditionals — if/else

Only move if the path isn’t blocked:

if (!blocked(p.x + dx, p.y, PR)) p.x += dx;
if (!blocked(p.x, p.y + dy, PR)) p.y += dy;

LeBron tries direct path first, then slides along walls:

if (!blocked(l.x+mx, l.y+my, LR)) { l.x += mx; l.y += my; }
else {
    if (!blocked(l.x+mx, l.y, LR)) l.x += mx;
    if (!blocked(l.x, l.y+my, LR)) l.y += my;
}

Nested Conditions — multi-level conditionals

Catch check with nested high score update:

if (dist < PR + LR + 2) {
    over = true;
    if (elapsed > best) best = elapsed;
}

Speed warning with nested opacity calculation:

if (spd > 2.8) {
    const alpha = Math.min((spd - 2.8) * 0.5, 0.9);
    ctx.fillStyle = `rgba(230,50,50,${alpha})` ;
    ctx.fillText('⚡ LeBron is heating up!', W/2, 54);
}

Data Types

Numbers — position, velocity, score tracking

const PR = 12;    // player radius
const LR = 15;    // LeBron radius
let elapsed = 0;  // time survived
let best = 0;     // best time
let tick = 0;     // frame counter
let dx = 0, dy = 0;  // velocity

Strings — character names, game states, template literals

ctx.fillText('11', 0, -28);   // player jersey number string
ctx.fillText('23', 0, -28);   // LeBron jersey number string
ctx.fillText(`⏱ ${elapsed.toFixed(1)}s`, W/2, 24);  // template literal
keys[e.key.toLowerCase()] = true;  // string key name

Booleans — flags like isOver, isPaused

let over = false;           // boolean — is game over?
if (over) return;           // gate all logic
if (elapsed > best) best = elapsed;
if (e.key.toLowerCase() === 'r' && over) reset();  // && AND

Arrays — game object collections, level data

const OBS = [
    { x: W*.25, y: H*.25, w: W*.12, h: H*.08 },
    { x: W*.55, y: H*.55, w: W*.12, h: H*.08 },
    // boundary walls...
];
[.1, .5, .82].forEach(fx => ctx.fillRect(...));
['arrowup','arrowdown','arrowleft','arrowright'].includes(e.key.toLowerCase())

Objects (JSON) — configuration objects, sprite data

let p = { x: W*.08, y: H*.5, dir: 1 };   // player object
let l = { x: W*.90, y: H*.5, dir: -1 };  // LeBron object
let keys = {};  // keyboard state map
{ x: W*.25, y: H*.25, w: W*.12, h: H*.08 }  // obstacle config object

Operators

Mathematical — physics calculations

const dist = Math.sqrt(ddx*ddx + ddy*ddy);  // distance formula
const nx = ddx / dist;   // normalize direction
const mx = nx * spd;     // scale by speed
if (dx && dy) { dx *= 0.707; dy *= 0.707; }  // diagonal fix
const spd = Math.min(1.5 + elapsed * 0.04, 4);  // speed over time
const bounce = Math.sin(tick * 0.22) * 5;  // sine wave bounce

String Operations — template literals, concatenation

ctx.fillText(`⏱ ${elapsed.toFixed(1)}s`, W/2, 24);
ctx.fillText(`Best: ${best.toFixed(1)}s`, W/2+145, 24);
ctx.fillText(`Survived  ${elapsed.toFixed(1)}s`, W/2, by+105);
keys[e.key.toLowerCase()] = true;  // .toLowerCase() string method

Boolean Expressions — &&, ||, !

if (keys['w'] || keys['arrowup']) dy = -3.5;   // OR
if (keys['a'] || keys['arrowleft']) dx = -3.5;  // OR
if (!blocked(p.x+dx, p.y, PR)) p.x += dx;       // NOT
if (e.key.toLowerCase() === 'r' && over) reset(); // AND
if (dx && dy) { dx *= .707; dy *= .707; }         // AND

Play the Game

%%html

Click court to focus · WASD / Arrow Keys to move · R to restart

Reflection

Building this game was the best way to actually understand these CS111 concepts because I had to use all of them together at once. The for loop draws the court, the Array holds the obstacles, the Object tracks player state, Boolean flags control game flow, and the math operators power the physics and AI. Seeing how they all connect in a real project made it way easier to understand than just reading about them separately.