UNPKG

claude-arcade

Version:

Add classic arcade games to your Claude Code workflow with Ctrl+G

158 lines (157 loc) 5.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BreakoutGame = void 0; class BreakoutGame { constructor() { this.ball = { x: 25, y: 10, vx: 1, vy: 1 }; this.paddle = { x: 21 }; this.blocks = []; this.score = 0; this.playing = false; this.WIDTH = 50; this.HEIGHT = 20; this.PADDLE_WIDTH = 7; } isPlaying() { return this.playing; } getScore() { return this.score; } initBlocks() { this.blocks = []; const colors = ['red', 'yellow', 'green', 'magenta']; for (let row = 0; row < 4; row++) { for (let col = 0; col < 10; col++) { this.blocks.push({ x: col * 5, y: row, active: true, color: colors[row] }); } } } reset() { this.ball = { x: 25, y: 10, vx: 1, vy: 1 }; this.paddle = { x: 21 }; this.score = 0; this.initBlocks(); } start() { this.playing = true; this.reset(); } stop() { this.playing = false; } update() { this.ball.x += this.ball.vx; this.ball.y += this.ball.vy; // Wall bounce if (this.ball.x <= 0 || this.ball.x >= this.WIDTH - 1) { this.ball.vx *= -1; this.ball.x = Math.max(0, Math.min(this.WIDTH - 1, this.ball.x)); } if (this.ball.y <= 0) { this.ball.vy *= -1; this.ball.y = 0; } // Paddle hit const ballX = Math.round(this.ball.x); const ballY = Math.round(this.ball.y); if (ballY >= this.HEIGHT - 2 && ballX >= this.paddle.x && ballX < this.paddle.x + this.PADDLE_WIDTH && this.ball.vy > 0) { this.ball.vy *= -1; const hitPos = (this.ball.x - this.paddle.x) / this.PADDLE_WIDTH; if (hitPos < 0.3) this.ball.vx = -1; else if (hitPos > 0.7) this.ball.vx = 1; } // Block hit for (const block of this.blocks) { if (!block.active) continue; if (ballX >= block.x && ballX < block.x + 5 && ballY === block.y) { block.active = false; this.ball.vy *= -1; this.score += 10; break; } } // Win/Lose if (this.blocks.every(b => !b.active)) { this.playing = false; return { won: true }; } if (this.ball.y >= this.HEIGHT) { this.playing = false; return { lost: true }; } return {}; } movePaddleLeft() { this.paddle.x = Math.max(0, this.paddle.x - 5); } movePaddleRight() { this.paddle.x = Math.min(this.WIDTH - this.PADDLE_WIDTH, this.paddle.x + 5); } draw() { const YELLOW = '\x1b[33m', CYAN = '\x1b[36m', RED = '\x1b[31m'; const GREEN = '\x1b[32m', MAGENTA = '\x1b[35m', RESET = '\x1b[0m'; const WHITE = '\x1b[37m'; const colors = { red: RED, yellow: YELLOW, green: GREEN, magenta: MAGENTA }; let output = '\x1b[2J\x1b[1;1H' + YELLOW + `Score: ${this.score}` + RESET; const ballX = Math.round(this.ball.x); const ballY = Math.round(this.ball.y); const paddleY = this.HEIGHT - 2; // Top border output += `\x1b[2;1H` + WHITE + '┌' + '─'.repeat(this.WIDTH) + '┐' + RESET; for (let y = 0; y < this.HEIGHT; y++) { output += `\x1b[${y + 3};1H` + WHITE + '│' + RESET; for (let x = 0; x < this.WIDTH; x++) { const block = this.blocks.find(b => b.active && y === b.y && x >= b.x && x < b.x + 5); const isBall = ballX === x && ballY === y; const isPaddle = y === paddleY && x >= this.paddle.x && x < this.paddle.x + this.PADDLE_WIDTH; if (block) { output += colors[block.color] + '█' + RESET; } else if (isBall) { output += YELLOW + '●' + RESET; } else if (isPaddle) { output += CYAN + '═' + RESET; } else { output += ' '; } } output += WHITE + '│' + RESET; } // Bottom border output += `\x1b[${this.HEIGHT + 3};1H` + WHITE + '└' + '─'.repeat(this.WIDTH) + '┘' + RESET; output += `\x1b[${this.HEIGHT + 5};1H` + GREEN + 'Press Q to exit back to Claude | ←→ or A/D to move | P to restart' + RESET; return output; } drawGameOver(won) { const GREEN = '\x1b[32m', RED = '\x1b[31m', YELLOW = '\x1b[33m', RESET = '\x1b[0m'; let output = '\x1b[2J\x1b[10;1H'; if (won) { output += GREEN + '🎉 YOU WIN! 🎉\n\n' + RESET; } else { output += RED + '💀 GAME OVER! 💀\n\n' + RESET; } output += YELLOW + `Final Score: ${this.score}\n\n` + RESET; output += GREEN + 'Press P to play again | Press Q to exit back to Claude\n' + RESET; return output; } drawWelcome() { const CYAN = '\x1b[36m', GREEN = '\x1b[32m', YELLOW = '\x1b[33m', RESET = '\x1b[0m'; return '\x1b[2J\x1b[10;1H' + CYAN + 'BREAKOUT GAME\n\n' + RESET + GREEN + 'Press P to start!\n' + YELLOW + 'Press Q to exit back to Claude\n' + RESET; } } exports.BreakoutGame = BreakoutGame;