This component no longer exists. It was in sv11-twango’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-09 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Pong 01
sv11-twango/pong-01RemovedBlock
A retro Pong game rendered on the Matrix display: keyboard paddle control, AI opponent, Web Audio sound effects, and a local (localStorage) win counter. No backend.
Install it
npx shadcn@latest add http://sv11.ui.twango.dev/r/pong-01.jsonSource
1<script lang="ts" module>2 export type PongGameProps = { class?: string };3</script>45<script lang="ts">6 import { onMount, onDestroy } from "svelte";7 import { cn } from "$UTILS$.js";8 import { Button } from "$UI$/button/index.js";9 import { Card, CardContent } from "$UI$/card/index.js";10 import { Matrix, digits, type Frame } from "$UI$/matrix/index.js";11 import { PongEngine, COLS, ROWS, PADDLE_HEIGHT, type PongState } from "./game-engine.js";12 import { renderWord } from "./bitmaps.js";13 import { PongSounds } from "./sound.js";14 import { getWins, recordWin } from "./score-store.js";1516 let { class: className }: PongGameProps = $props();1718 const sounds = new PongSounds();19 const engine = new PongEngine((sound) => sounds.play(sound));2021 let gameState = $state<PongState>("title");22 let playerScore = $state(0);23 let aiScore = $state(0);24 let wins = $state(0);25 let frame = $state<Frame>(renderWord("PONG"));2627 let playerInput = 0;28 let raf = 0;29 let lastTime = 0;30 let winRecorded = false;31 let container: HTMLDivElement | null = null;3233 const hint = $derived(34 {35 title: "Press Space or tap Start · ↑ ↓ to move",36 countdown: "Get ready…",37 playing: "↑ ↓ to move · P to pause",38 paused: "Paused · P to resume",39 gameOver:40 engine.winner === "player" ? "You win! Space to play again" : "CPU wins · Space to retry",41 }[gameState]42 );4344 function buildFrame(): Frame {45 if (engine.state === "title") return renderWord("PONG");46 if (engine.state === "gameOver") return renderWord(engine.winner === "player" ? "WIN" : "LOSE");4748 const f: Frame = Array.from({ length: ROWS }, () => Array(COLS).fill(0));49 const set = (r: number, c: number, v: number) => {50 const rr = Math.round(r);51 const cc = Math.round(c);52 if (rr >= 0 && rr < ROWS && cc >= 0 && cc < COLS) f[rr][cc] = v;53 };5455 const midCol = Math.floor(COLS / 2);56 for (let r = 0; r < ROWS; r += 2) f[r][midCol] = 0.2;5758 const py = Math.round(engine.player.y);59 const ay = Math.round(engine.ai.y);60 for (let i = 0; i < PADDLE_HEIGHT; i++) {61 set(py + i, 0, 1);62 set(ay + i, COLS - 1, 1);63 }6465 engine.ball.trail.forEach((p, i) => set(p.y, p.x, Math.max(0.15, 0.5 - i * 0.12)));66 set(engine.ball.y, engine.ball.x, 1);67 return f;68 }6970 function sync() {71 gameState = engine.state;72 playerScore = engine.playerScore;73 aiScore = engine.aiScore;74 if (engine.state === "gameOver" && engine.winner === "player" && !winRecorded) {75 winRecorded = true;76 wins = recordWin();77 }78// … truncated
What it pulls in
Other registry items
