Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ repos:
hooks:
- id: biome-check
name: run biome-check
description: Run Biome linter and formatter for JSON files
description: Run Biome linter and formatter for JSON and JavaScript files
additional_dependencies: ["@biomejs/biome"]

- repo: https://github.com/igorshubovych/markdownlint-cli
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.10/schema.json",
"files": {
"includes": ["**/*.json"]
"includes": ["**/*.json", "src/assets/js/**/*.js"]
},
"linter": {
"enabled": true,
Expand Down
22 changes: 11 additions & 11 deletions src/assets/js/games/code-breaker.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Theme-aware: reads the current dark/light mode at startup.
*/

// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
const CodeBreaker = (() => {
const GAME_ID = "code-breaker";
const TILE_SPEED_BASE = 180;
Expand Down Expand Up @@ -75,7 +76,7 @@ const CodeBreaker = (() => {
},
scene: {
create: function () {
_onSceneCreate(this, skills, devName, theme, W, H);
_onSceneCreate(this, skills, theme, W, H);
},
update: function () {
_onSceneUpdate(this);
Expand All @@ -91,7 +92,7 @@ const CodeBreaker = (() => {

// ─── Scene ───────────────────────────────────────────────────────────────

function _onSceneCreate(scene, skills, devName, theme, W, H) {
function _onSceneCreate(scene, skills, theme, W, H) {
// State stored on scene object
scene.cb_lives = LIVES;
scene.cb_score = 0;
Expand Down Expand Up @@ -138,8 +139,8 @@ const CodeBreaker = (() => {
scene.physics.add.overlap(
scene.cb_catcher,
scene.cb_tiles,
(catcher, tile) => {
_collectTile(scene, tile, theme, W, H);
(_catcher, tile) => {
_collectTile(scene, tile, W, H);
},
);

Expand All @@ -163,7 +164,7 @@ const CodeBreaker = (() => {

// Spawn first tile after a short delay
scene.time.delayedCall(500, () => {
_spawnTile(scene, theme, W);
_spawnTile(scene, W);
});
}

Expand All @@ -184,7 +185,7 @@ const CodeBreaker = (() => {
const now = scene.time.now;
if (now - scene.cb_lastSpawn > scene.cb_spawnDelay) {
scene.cb_lastSpawn = now;
_spawnTile(scene, getGameTheme(), scene.scale.width);
_spawnTile(scene, scene.scale.width);
}

// Check if any tile fell off the bottom.
Expand All @@ -203,7 +204,7 @@ const CodeBreaker = (() => {

// ─── Game logic ──────────────────────────────────────────────────────────

function _spawnTile(scene, theme, W) {
function _spawnTile(scene, W) {
if (!scene.cb_active) return;

const skill =
Expand Down Expand Up @@ -264,8 +265,7 @@ const CodeBreaker = (() => {
scene.cb_spawnDelay = Math.max(600, scene.cb_spawnDelay - 20);
}

function _collectTile(scene, tile, theme, W, H) {
const skill = tile.getData("skill");
function _collectTile(scene, tile, W, H) {
const rarity = tile.getData("rarity");
const color = tile.getData("color");

Expand All @@ -277,7 +277,7 @@ const CodeBreaker = (() => {
TILE_SPEED_BASE + scene.cb_score * TILE_SPEED_INC,
);

if (scene.cb_scoreText && scene.cb_scoreText.active) {
if (scene.cb_scoreText?.active) {
scene.cb_scoreText.setText("Score: " + scene.cb_score);
}

Expand Down Expand Up @@ -316,7 +316,7 @@ const CodeBreaker = (() => {

scene.cb_lives--;

if (scene.cb_livesText && scene.cb_livesText.active) {
if (scene.cb_livesText?.active) {
scene.cb_livesText.setText("❤️".repeat(Math.max(0, scene.cb_lives)));
}

Expand Down
7 changes: 7 additions & 0 deletions src/assets/js/games/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
*/

// CDN URL for the pinned Phaser version used site-wide
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
const PHASER_CDN_URL =
"https://cdnjs.cloudflare.com/ajax/libs/phaser/3.90.0/phaser.min.js";

// Rarity order and weights used by Dev Duel scoring
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
const RARITY_WEIGHTS = {
common: 1,
uncommon: 2,
Expand All @@ -19,6 +21,7 @@ const RARITY_WEIGHTS = {
};

// CSS variable colour names per rarity (matches style.css)
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
const RARITY_COLORS = {
common: "#94a3b8",
uncommon: "#10b981",
Expand All @@ -30,6 +33,7 @@ const RARITY_COLORS = {
};

// Fallback generic tech skills used when no profile skills are available
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
const GENERIC_SKILLS = [
"JavaScript",
"TypeScript",
Expand Down Expand Up @@ -57,6 +61,7 @@ const GENERIC_SKILLS = [
* Reads the current site theme from the document root class.
* Returns an object of useful colour strings for Phaser text/backgrounds.
*/
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
function getGameTheme() {
const isDark = document.documentElement.classList.contains("dark");
return {
Expand All @@ -73,6 +78,7 @@ function getGameTheme() {
* Deterministically assigns a rarity tier to a skill name string.
* Uses a simple hash so the same skill always gets the same rarity.
*/
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
function skillRarity(skillName) {
let hash = 0;
for (let i = 0; i < skillName.length; i++) {
Expand All @@ -99,6 +105,7 @@ function skillRarity(skillName) {
*
* @param {object} overrides Fields that replace defaults (e.g. width, scene).
*/
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
function buildGameConfig(overrides) {
return Object.assign(
{
Expand Down
35 changes: 9 additions & 26 deletions src/assets/js/games/dev-duel.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ const DevDuel = (() => {
.setOrigin(0.5, 0);

// Cards
_drawCard(scene, challenger, cPower, W * 0.22, H / 2 - 20, theme, false);
_drawCard(scene, opponent, oPower, W * 0.78, H / 2 - 20, theme, true);
_drawCard(scene, challenger, cPower, W * 0.22, H / 2 - 20, theme);
_drawCard(scene, opponent, oPower, W * 0.78, H / 2 - 20, theme);

// VS label
scene.add
Expand Down Expand Up @@ -127,11 +127,11 @@ const DevDuel = (() => {

// Animate the battle after a short delay
scene.time.delayedCall(800, () => {
_animateBattle(scene, challenger, opponent, cPower, oPower, W, H, theme);
_animateBattle(scene, challenger, opponent, cPower, oPower, W, H);
});
}

function _drawCard(scene, dev, power, cx, cy, theme, flipSide) {
function _drawCard(scene, dev, power, cx, cy, theme) {
const cardW = 160;
const cardH = 200;
const x = cx - cardW / 2;
Expand Down Expand Up @@ -215,7 +215,7 @@ const DevDuel = (() => {
w: barW,
duration: 800,
ease: "Power2",
onUpdate: (tween, target) => {
onUpdate: (_tween, target) => {
fillGfx.clear();
fillGfx.fillStyle(0x38bdf8, 1);
fillGfx.fillRoundedRect(x, y + 14, target.w, 10, 3);
Expand All @@ -231,24 +231,15 @@ const DevDuel = (() => {

// ─── Battle animation ─────────────────────────────────────────────────────

function _animateBattle(
scene,
challenger,
opponent,
cPower,
oPower,
W,
H,
theme,
) {
function _animateBattle(scene, challenger, opponent, cPower, oPower, W, H) {
// Flash attacks back and forth
let round = 0;
const maxRounds = 5;

const attackFlash = () => {
if (round >= maxRounds) {
scene.time.delayedCall(400, () => {
_showResult(scene, challenger, opponent, cPower, oPower, W, H, theme);
_showResult(scene, challenger, opponent, cPower, oPower, W, H);
});
return;
}
Expand Down Expand Up @@ -280,16 +271,7 @@ const DevDuel = (() => {

// ─── Result screen ────────────────────────────────────────────────────────

function _showResult(
scene,
challenger,
opponent,
cPower,
oPower,
W,
H,
theme,
) {
function _showResult(scene, challenger, opponent, cPower, oPower, W, H) {
const challengerWins = cPower >= oPower;
const winner = challengerWins ? challenger : opponent;

Expand Down Expand Up @@ -397,6 +379,7 @@ function getCardData(cardEl) {
*
* @param {HTMLElement} challengerCard The card element that was clicked.
*/
// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
function startDuelFromCard(challengerCard) {
const allCards = Array.from(
document.querySelectorAll(".user-card[data-name]"),
Expand Down
1 change: 1 addition & 0 deletions src/assets/js/games/game-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* - Persisting per-game high scores and achievement flags in localStorage
*/

// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
const GameManager = (() => {
/** Active Phaser.Game instances keyed by game id. */
const _instances = {};
Expand Down
26 changes: 17 additions & 9 deletions src/assets/js/games/space-invaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* GameManager and lazy-loaded alongside the other mini-games.
*/

// biome-ignore lint/correctness/noUnusedVariables: Used outside this classic script.
const SpaceInvaders = (() => {
const ALIEN_ROWS = ["👾", "👽", "🛸", "🐙", "👾"];
const GAME_ID = "space-invaders";
Expand Down Expand Up @@ -69,22 +70,29 @@ const SpaceInvaders = (() => {
_setupGame(this);
}

function _onUpdate() {
if (!this.si_player || !this.si_player.body) return;

if (this.si_cursors.left.isDown) {
this.si_player.body.setVelocityX(-400);
} else if (this.si_cursors.right.isDown) {
this.si_player.body.setVelocityX(400);
function _updatePlayerVelocity(scene) {
if (scene.si_cursors.left.isDown) {
scene.si_player.body.setVelocityX(-400);
} else if (scene.si_cursors.right.isDown) {
scene.si_player.body.setVelocityX(400);
} else {
this.si_player.body.setVelocityX(0);
scene.si_player.body.setVelocityX(0);
}
}

function _getBullets(scene) {
return scene.si_bullets?.getChildren?.() || [];
}

function _onUpdate() {
if (!this.si_player?.body) return;

_updatePlayerVelocity(this);
if (this.si_cursors.space.isDown) {
_fireBullet(this);
}

const bullets = this.si_bullets?.getChildren?.() || [];
const bullets = _getBullets(this);
bullets.forEach((bullet) => {
if (!bullet.active) return;
if (
Expand Down
Loading