Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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) {
Comment thread
jbampton marked this conversation as resolved.
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