oneshotlm
Compare all models on this prompt →

Brick breaker · seed-2.0-lite

Using the pre-provided phaser.min.js (global Phaser), build a playable brick-breaker game with a paddle (arrow keys or mouse), a bouncing ball, and a wall of breakable bricks with a score. Use ONLY procedurally generated graphics via the Phaser Graphics API or generated textures — no external image or audio assets whatsoever.

⛨ sandboxed Open in new tab ↗
transcript · 4 messages
user

Using the pre-provided phaser.min.js (global Phaser), build a playable brick-breaker game with a paddle (arrow keys or mouse), a bouncing ball, and a wall of breakable bricks with a score. Use ONLY procedurally generated graphics via the Phaser Graphics API or generated textures — no external image or audio assets whatsoever.

assistant
thinking
Got it, let's tackle this. I need to create a brick breaker game in Phaser, all in one index.html file, using only procedural graphics, no external assets. First, I'll start by setting up the basic HTML structure that includes phaser.min.js, then the Phaser game config.

First, the game will need a scene. Let's outline the key components:
1.  Paddle that can move with arrow keys or mouse.
2.  A ball that bounces off walls, paddle, and bricks.
3.  A grid of breakable bricks, each with different colors maybe.
4.  Score tracking.
5.  Game over and win conditions.

First, the HTML file structure: start with <!DOCTYPE html>, then the script tag for phaser.min.js, then a script tag for the game code. The Phaser config will set the width and height, say 800x600, use Arcade physics, which is perfect for this kind of game.

In the scene's create() function:
- Set up the paddle: create a rectangle using Phaser's Graphics, make it a static? No, dynamic, so it can move. Wait, Arcade physics, so add a sprite, but since we use procedural graphics, generate a texture for the paddle. Or use a graphics object to draw it, but better to generate a texture so we can add it as a physics sprite. Oh right, Phaser can generate textures dynamically. So first, generate a paddle texture: create a graphics object, draw a rectangle, generate a texture from it, then destroy the graphics. Same for the ball and bricks.

Wait, alternatively, in Phaser 3, you can use this.add.graphics() to draw shapes, but to use them with physics, you need to make them a game object with physics. The easiest way is to generate a texture for each shape first. Let's do that in the preload() function? Wait no, preload is for loading assets, but we can generate textures in create() or preload. Wait, let's generate textures for paddle, ball, brick.

Wait paddle: 100px wide, 20px tall, blue color. Ball: 10px diameter, yellow. Bricks: 80px wide, 20px tall, different colors like red, green, orange.

Then, create the paddle at the bottom center of the screen, set its physics body to be immovable? No, we need to move it, so set its collide world bounds so it can't go off screen. The ball starts on top of the paddle, waits for a click or space to launch, so initial velocity is zero, then when user clicks, set velocity to, say, 300, -300 to make it go up and right.

Bricks: create a grid at the top, like 8 columns, 4 rows, spaced out. Each brick is a physics sprite, immovable, so when the ball hits them, they get destroyed. Add collision between ball and bricks, when they collide, destroy the brick and increase the score.

Score: add a text object at the top left that updates the score whenever a brick is destroyed.

Input: handle arrow keys: left and right arrows to move the paddle. Also mouse movement: track the mouse x position, set the paddle x to the mouse x, so it follows the mouse, that way both input methods work.

Collision handling: when the ball hits the paddle, reverse the y velocity, and maybe adjust the x velocity based on where it hit the paddle to make it feel more dynamic. When the ball goes below the screen (y > game height), it's game over, show game over text. When all bricks are destroyed, show you win text.

Let's structure the code step by step. First, the HTML file:

Start with <!DOCTYPE html>
<html>
<head>
    <title>Brick Breaker</title>
    <style>
        body { margin: 0; display: flex; justify-content: center; align-items: center; background: #000; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="phaser.min.js"></script>
    <script>
        // Phaser game code here
        const config = {
            type: Phaser.AUTO,
            width: 800,
            height: 600,
            physics: {
                default: 'arcade',
                arcade: {
                    gravity: { y: 0 }, // No gravity, since it's a breakout game
                    debug: false
                }
            },
            scene: {
                preload: preload,
                create: create,
                update: update
            }
        };

        let paddle;
        let ball;
        let cursors;
        let score = 0;
        let scoreText;
        let gameOver = false;
        let bricks;
        let ballStarted = false;

        function preload() {
            // Generate all textures procedurally here
            // Paddle texture
            let paddleGraphics = this.add.graphics();
            paddleGraphics.fillStyle(0x2196F3, 1);
            paddleGraphics.fillRect(0, 0, 100, 20);
            paddleGraphics.generateTexture('paddle', 100, 20);
            paddleGraphics.destroy();

            // Ball texture
            let ballGraphics = this.add.graphics();
            ballGraphics.fillStyle(0xFFEB3B, 1);
            ballGraphics.fillCircle(10, 10, 10);
            ballGraphics.generateTexture('ball', 20, 20);
            ballGraphics.destroy();

            // Brick textures (different colors)
            const brickColors = [0xF44336, 0xE91E63, 0x9C27B0, 0x673AB7, 0x3F51B5, 0x2196F3, 0x00BCD4, 0x009688];
            brickColors.forEach((color, index) => {
                let brickGraphics = this.add.graphics();
                brickGraphics.fillStyle(color, 1);
                brickGraphics.fillRect(0, 0, 80, 20);
                // Add a border to bricks
                brickGraphics.lineStyle(2, 0x000000, 1);
                brickGraphics.strokeRect(0, 0, 80, 20);
                brickGraphics.generateTexture(`brick${index}`, 80, 20);
                brickGraphics.destroy();
            });
        }

        function create() {
            // Create score text
            scoreText = this.add.text(16, 16, 'Score: 0', { fontSize: '32px', fill: '#fff' });

            // Create paddle
            paddle = this.physics.add.sprite(400, 550, 'paddle');
            paddle.setCollideWorldBounds(true);
            paddle.body.immovable = true;

            // Create ball
            ball = this.physics.add.sprite(400, 520, 'ball');
            ball.setCollideWorldBounds(true);
            ball.setBounce(1, 1); // Bounce off all surfaces
            ball.body.velocity.set(0, 0); // Start stationary

            // Create bricks group
            bricks = this.physics.add.group({ immovable: true });
            const brickColors = [0xF44336, 0xE91E63, 0x9C27B0, 0x673AB7, 0x3F51B5, 0x2196F3, 0x00BCD4, 0x009688];
            // Create grid of bricks: 10 columns, 4 rows
            for (let y = 0; y < 4; y++) {
                for (let x = 0; x < 9; x++) {
                    const brick = bricks.create(80 + x * 88, 60 + y * 30, `brick${x % brickColors.length}`);
                    brick.body.immovable = true;
                }
            }

            // Add collisions
            this.physics.add.collider(ball, paddle, hitPaddle, null, this);
            this.physics.add.collider(ball, bricks, hitBrick, null, this);

            // Cursor keys for keyboard input
            cursors = this.input.keyboard.createCursorKeys();
            // Mouse input
            this.input.on('pointermove', (pointer) => {
                if (!gameOver) {
                    paddle.x = pointer.x;
                    // If ball hasn't started, keep it on paddle
                    if (!ballStarted) {
                        ball.x = paddle.x;
                    }
                }
            });
            // Click to launch ball
            this.input.on('pointerdown', () => {
                if (!ballStarted && !gameOver) {
                    ballStarted = true;
                    ball.setVelocity(300, -300);
                }
            });
            // Also space to launch
            this.input.keyboard.on('keydown_SPACE', () => {
                if (!ballStarted && !gameOver) {
                    ballStarted = true;
                    ball.setVelocity(300, -300);
                }
            });
        }

        function update() {
            if (gameOver) return;

            // Handle keyboard input
            if (cursors.left.isDown) {
                paddle.x -= 7;
                if (!ballStarted) {
                    ball.x = paddle.x;
                }
            } else if (cursors.right.isDown) {
                paddle.x += 7;
                if (!ballStarted) {
                    ball.x = paddle.x;
                }
            }

            // Check if ball fell off screen (game over)
            if (ball.y > 590) {
                gameOver = true;
                ball.setVelocity(0, 0);
                this.add.text(400, 300, 'GAME OVER', { fontSize: '64px', fill: '#ff0000' }).setOrigin(0.5);
            }

            // Check if all bricks are destroyed (win)
            if (bricks.countActive() === 0) {
                gameOver = true;
                ball.setVelocity(0, 0);
                this.add.text(400, 300, 'YOU WIN!', { fontSize: '64px', fill: '#00ff00' }).setOrigin(0.5);
            }
        }

        function hitPaddle(ball, paddle) {
            // Adjust x velocity based on where the ball hit the paddle to add angle
            let diff = ball.x - paddle.x;
            ball.setVelocityX(10 * diff);
        }

        function hitBrick(ball, brick) {
            // Destroy the brick
            brick.destroy();
            // Increase score
            score += 10;
            scoreText.setText(`Score: ${score}`);
        }

        // Initialize the game
        new Phaser.Game(config);
    </script>
</body>
</html>

Wait, let's check if all requirements are met:
- All in one index.html file, phaser.min.js is loaded correctly.
- Procedural graphics: all textures are generated using Phaser Graphics API, no external assets.
- Paddle moves with arrow keys or mouse: yes, pointermove tracks mouse, arrow keys work.
- Ball bounces: yes, setBounce(1,1), collides with world bounds.
- Breakable bricks: yes, group of bricks, when ball hits, they get destroyed.
- Score tracking: yes, score text updates.
- Game over and win conditions: yes, if ball falls off, game over, if all bricks gone, you win.
- No external assets, all generated locally. That should work. Let's write this to index.html.
write /tmp/ws/index.html (5317 bytes)
toolResult

Successfully wrote 5317 bytes to /tmp/ws/index.html

assistant
thinking
The game is fully created in index.html. Let's confirm all requirements are met:
1.  All code in one self-contained file, uses local phaser.min.js
2.  All graphics generated procedurally with Phaser's Graphics API, no external assets
3.  Paddle supports both arrow key (left/right) and mouse movement
4.  Bouncing ball with proper physics, launches on click or space
5.  Breakable brick grid with varied colors
6.  Score tracking, game over and win conditions
7.  No network requests, all assets generated locally.

The implementation is complete and ready to play.

The brick-breaker game is complete and saved to `/tmp/ws/index.html`. The game includes: - Dual input support: use left/right arrow keys or move your mouse to control the paddle - Procedurally generated graphics (all textures created via Phaser's Graphics API, no external assets) - Bouncing ball physics, with angle adjustment based on where it hits the paddle - 36 breakable, multicolored bricks arranged in a grid - Score tracking - Win condition (destroy all bricks) and game over condition (ball drops below the paddle) - Launch the ball with your mouse click or spacebar Open the file in a web browser to play!

TAKE IT TO CODE

A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.

RUN

modelseed-2.0-lite
vendorByteDance · Seed
harnesspi-agent
generated2026-08-01

EVALUATION

4/5 working

Working brick-breaker with paddle, ball physics, colorful brick grid, and increasing score across interactions.

Vision grade · anthropic/claude-sonnet-5

MEASUREMENTS

Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.

idle motion0.0%
on click0.4%
on drag1.1%
on wheel1.1%
on enter + space0.4%
on arrow keys0.5%
on w/a/s/d0.7%
frame spread21.7 / 255
console errors0
js errors none

METRICS

runtime55.1s
tokens in8.0k
tokens out4.6k
cached2.7k
cost / run$0.0105