← back to Games Agentabrams
Retire old particle-text (Particle Word); keep improved Starling only
0bbf2b0b2feacaccf02d0424480101b6b71db79c · 2026-07-25 00:40:31 -0700 · Steve
Files touched
M games-data.jsM games.jsonD games/particle-text/ParticleWord.aaD games/particle-text/index.html
Diff
commit 0bbf2b0b2feacaccf02d0424480101b6b71db79c
Author: Steve <steve@designerwallcoverings.com>
Date: Sat Jul 25 00:40:31 2026 -0700
Retire old particle-text (Particle Word); keep improved Starling only
---
games-data.js | 8 --
games.json | 8 --
games/particle-text/ParticleWord.aa | 143 ------------------------------------
games/particle-text/index.html | 143 ------------------------------------
4 files changed, 302 deletions(-)
diff --git a/games-data.js b/games-data.js
index fa59dbe..1415bee 100644
--- a/games-data.js
+++ b/games-data.js
@@ -82,14 +82,6 @@ window.__GAMES_DATA__ = {
"path": "games/rope-physics/",
"added": "2026-07-24"
},
- {
- "id": "particle-text",
- "file": "ParticleWord.aa",
- "title": "Particle Word",
- "desc": "Type a word and watch it assemble from a swarm of particles that scatter and reform. An interactive typography toy, not a scored game. Model Arena winner (Qwen3-14B). Pure Canvas 2D, zero dependencies.",
- "path": "games/particle-text/",
- "added": "2026-07-24"
- },
{
"id": "particle-text-starling",
"file": "Starling.aa",
diff --git a/games.json b/games.json
index b16dcbc..90d3dba 100644
--- a/games.json
+++ b/games.json
@@ -80,14 +80,6 @@
"path": "games/rope-physics/",
"added": "2026-07-24"
},
- {
- "id": "particle-text",
- "file": "ParticleWord.aa",
- "title": "Particle Word",
- "desc": "Type a word and watch it assemble from a swarm of particles that scatter and reform. An interactive typography toy, not a scored game. Model Arena winner (Qwen3-14B). Pure Canvas 2D, zero dependencies.",
- "path": "games/particle-text/",
- "added": "2026-07-24"
- },
{
"id": "particle-text-starling",
"file": "Starling.aa",
diff --git a/games/particle-text/ParticleWord.aa b/games/particle-text/ParticleWord.aa
deleted file mode 100644
index 36408d4..0000000
--- a/games/particle-text/ParticleWord.aa
+++ /dev/null
@@ -1,143 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <title>Particle Word</title>
- <style>
- html, body {
- margin: 0;
- padding: 0;
- overflow: hidden;
- background: #000;
- height: 100%;
- width: 100%;
- font-family: 'Arial', sans-serif;
- }
- #word {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- color: #fff;
- font-size: 48px;
- pointer-events: none;
- text-transform: uppercase;
- text-align: center;
- }
- #controls {
- position: absolute;
- top: 20px;
- left: 50%;
- transform: translateX(-50%);
- color: #fff;
- font-size: 18px;
- }
- </style>
-</head>
-<body>
- <div id="word">TYPE HERE</div>
- <div id="controls">Type a word to see particles form it</div>
- <canvas id="canvas"></canvas>
- <script>
- const canvas = document.getElementById('canvas');
- const ctx = canvas.getContext('2d');
- let width, height;
- let particles = [];
- let targetWord = 'TYPE HERE';
- let isHovering = false;
-
- function resize() {
- width = canvas.width = window.innerWidth;
- height = canvas.height = window.innerHeight;
- }
- window.addEventListener('resize', resize);
- resize();
-
- function createParticles(word, count = 2000) {
- particles = [];
- const chars = word.split('');
- const totalChars = chars.length;
- for (let i = 0; i < count; i++) {
- const charIndex = Math.floor(i / (count / totalChars));
- const char = chars[charIndex % totalChars];
- const angle = (Math.random() * Math.PI * 2);
- const radius = Math.random() * 150 + 100;
- const x = width / 2 + Math.cos(angle) * radius;
- const y = height / 2 + Math.sin(angle) * radius;
- const size = Math.random() * 2 + 1;
- const speed = Math.random() * 0.5 + 0.2;
- particles.push({
- x,
- y,
- targetX: width / 2 + (char.charCodeAt(0) - 65) * 30,
- targetY: height / 2 + (Math.floor(i / totalChars)) * 30,
- size,
- speed,
- vx: (Math.random() - 0.5) * 2,
- vy: (Math.random() - 0.5) * 2,
- char: char
- });
- }
- }
-
- function updateParticles() {
- for (let p of particles) {
- const dx = p.targetX - p.x;
- const dy = p.targetY - p.y;
- const dist = Math.sqrt(dx * dx + dy * dy);
- if (dist < 2) {
- p.x = p.targetX;
- p.y = p.targetY;
- } else {
- const angle = Math.atan2(dy, dx);
- p.x += Math.cos(angle) * p.speed;
- p.y += Math.sin(angle) * p.speed;
- }
- if (isHovering) {
- const nx = (Math.random() - 0.5) * 10;
- const ny = (Math.random() - 0.5) * 10;
- p.x += nx;
- p.y += ny;
- }
- }
- }
-
- function drawParticles() {
- ctx.clearRect(0, 0, width, height);
- ctx.fillStyle = '#00ffcc';
- for (let p of particles) {
- ctx.beginPath();
- ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
- ctx.fill();
- }
- }
-
- function animate() {
- updateParticles();
- drawParticles();
- requestAnimationFrame(animate);
- }
-
- function resetParticles() {
- createParticles(targetWord);
- }
-
- window.addEventListener('mousemove', () => {
- isHovering = true;
- setTimeout(() => {
- isHovering = false;
- }, 500);
- });
-
- window.addEventListener('keydown', (e) => {
- if (e.key.length === 1 && e.key.match(/[a-zA-Z]/)) {
- targetWord = e.key.toUpperCase();
- resetParticles();
- }
- });
-
- createParticles(targetWord);
- animate();
- </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/games/particle-text/index.html b/games/particle-text/index.html
deleted file mode 100644
index 36408d4..0000000
--- a/games/particle-text/index.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <title>Particle Word</title>
- <style>
- html, body {
- margin: 0;
- padding: 0;
- overflow: hidden;
- background: #000;
- height: 100%;
- width: 100%;
- font-family: 'Arial', sans-serif;
- }
- #word {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- color: #fff;
- font-size: 48px;
- pointer-events: none;
- text-transform: uppercase;
- text-align: center;
- }
- #controls {
- position: absolute;
- top: 20px;
- left: 50%;
- transform: translateX(-50%);
- color: #fff;
- font-size: 18px;
- }
- </style>
-</head>
-<body>
- <div id="word">TYPE HERE</div>
- <div id="controls">Type a word to see particles form it</div>
- <canvas id="canvas"></canvas>
- <script>
- const canvas = document.getElementById('canvas');
- const ctx = canvas.getContext('2d');
- let width, height;
- let particles = [];
- let targetWord = 'TYPE HERE';
- let isHovering = false;
-
- function resize() {
- width = canvas.width = window.innerWidth;
- height = canvas.height = window.innerHeight;
- }
- window.addEventListener('resize', resize);
- resize();
-
- function createParticles(word, count = 2000) {
- particles = [];
- const chars = word.split('');
- const totalChars = chars.length;
- for (let i = 0; i < count; i++) {
- const charIndex = Math.floor(i / (count / totalChars));
- const char = chars[charIndex % totalChars];
- const angle = (Math.random() * Math.PI * 2);
- const radius = Math.random() * 150 + 100;
- const x = width / 2 + Math.cos(angle) * radius;
- const y = height / 2 + Math.sin(angle) * radius;
- const size = Math.random() * 2 + 1;
- const speed = Math.random() * 0.5 + 0.2;
- particles.push({
- x,
- y,
- targetX: width / 2 + (char.charCodeAt(0) - 65) * 30,
- targetY: height / 2 + (Math.floor(i / totalChars)) * 30,
- size,
- speed,
- vx: (Math.random() - 0.5) * 2,
- vy: (Math.random() - 0.5) * 2,
- char: char
- });
- }
- }
-
- function updateParticles() {
- for (let p of particles) {
- const dx = p.targetX - p.x;
- const dy = p.targetY - p.y;
- const dist = Math.sqrt(dx * dx + dy * dy);
- if (dist < 2) {
- p.x = p.targetX;
- p.y = p.targetY;
- } else {
- const angle = Math.atan2(dy, dx);
- p.x += Math.cos(angle) * p.speed;
- p.y += Math.sin(angle) * p.speed;
- }
- if (isHovering) {
- const nx = (Math.random() - 0.5) * 10;
- const ny = (Math.random() - 0.5) * 10;
- p.x += nx;
- p.y += ny;
- }
- }
- }
-
- function drawParticles() {
- ctx.clearRect(0, 0, width, height);
- ctx.fillStyle = '#00ffcc';
- for (let p of particles) {
- ctx.beginPath();
- ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
- ctx.fill();
- }
- }
-
- function animate() {
- updateParticles();
- drawParticles();
- requestAnimationFrame(animate);
- }
-
- function resetParticles() {
- createParticles(targetWord);
- }
-
- window.addEventListener('mousemove', () => {
- isHovering = true;
- setTimeout(() => {
- isHovering = false;
- }, 500);
- });
-
- window.addEventListener('keydown', (e) => {
- if (e.key.length === 1 && e.key.match(/[a-zA-Z]/)) {
- targetWord = e.key.toUpperCase();
- resetParticles();
- }
- });
-
- createParticles(targetWord);
- animate();
- </script>
-</body>
-</html>
\ No newline at end of file
← db80d5d auto-save: 2026-07-25T00:32:03 (39 files) — games.json index
·
back to Games Agentabrams
·
deploy: add rsync --delete so retired games are purged from 5c7f274 →