oneshotlm
Compare all models on this prompt →

Brick breaker · qwen3-235b-a22b

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
Okay, I need to create a brick-breaker game using Phaser.min.js. The user specified that it should be a single-page app with all CSS and JS inline in index.html. Let me start by setting up the basic structure of the HTML file.

First, include the Phaser script with a script tag pointing to the local phaser.min.js. Then, create a script tag for the game code. I'll need to initialize the Phaser game, set up the scenes, and handle the game logic.

The game requires a paddle, a ball, bricks, and a score. Let's break it down step by step.

For the paddle: create a rectangle using Phaser's Graphics API. It should move with the arrow keys or mouse. I'll set up input listeners for keyboard left and right arrows. Also, maybe mouse movement to control the paddle by checking the pointer's x position.

The ball: another rectangle, maybe a circle. It needs to bounce off the walls and the paddle. Implement velocity for the ball, and check for collisions with the paddle and bricks.

Bricks: generate them in a grid pattern. Each brick is a colored rectangle. When the ball collides with a brick, destroy it and increase the score.

Score: display a text element that updates when bricks are destroyed. Also, check if all bricks are destroyed to end the game.

Collision detection: use Phaser's built-in physics or handle it manually. Since the user mentioned using procedural graphics, maybe use the Graphics API to draw shapes and handle collisions via bounds checking.

Let me outline the code structure. The game will have a single scene with preload, create, and update methods. In preload, maybe load any necessary assets, but since the user said no external assets, maybe not needed. In create, set up the paddle, ball, bricks, score text. In update, handle input, movement, collisions.

Wait, Phaser has a physics system. Maybe enable physics for the ball and paddle. The paddle can be static, and the ball dynamic. Bricks can be static as well. Use the physics.collide method to check collisions between the ball and paddle/bricks.

But since the bricks are destroyed when hit, need to create a group of bricks and set up collision callbacks.

Also, handle the ball going out of bounds (bottom of the screen) to end the game.

Now, writing the code. Start with the HTML structure:

<!DOCTYPE html>
<html>
<head>
    <title>Brick Breaker</title>
    <script src="phaser.min.js"></script>
    <script>
        // Phaser game code here
    </script>
</head>
<body>
</body>
</html>

In the script tag, define the game configuration. Set type to AUTO, set the width and height. Then create the scene.

In the scene's create function:

- Create the paddle: a rectangle, positioned at the bottom center. Enable physics for movement? Or just move it manually. Maybe create a sprite or a graphics object. Since using procedural graphics, create a rectangle with Graphics.

Wait, maybe use the Graphics API to draw the paddle. So:

let paddle = this.add.graphics();
paddle.fillStyle(0xffffff, 1);
paddle.fillRect(0, 0, paddleWidth, paddleHeight);
Then position it.

But for physics, maybe better to use a sprite with a generated texture. Alternatively, use a physics body for collision detection.

Alternatively, create a physics-enabled rectangle. Maybe use this.physics.add.sprite for the paddle and ball. For the paddle, set it as immovable if moving manually.

For the paddle movement, in the update function, check arrow keys or mouse position.

For the ball, set velocity and bounce off walls. Use physics to handle collisions.

Wait, perhaps using Phaser's physics system would simplify collision handling. Let me structure it with physics.

So, in the create function:

- Create the paddle as a physics body. Maybe a rectangle that's static or kinematic.

Wait, the paddle should move left and right, so it's dynamic. But to prevent it from being affected by gravity, set immovable.

Similarly, the ball is dynamic with velocity.

Bricks are static bodies.

So, code steps:

1. Initialize game with physics.

In the scene config, include physics: { enabled: true, gravity: { y: 0 } }, but maybe not needed if no gravity.

Wait, in the game config, set physics: { default: 'arcade', arcade: { gravity: { y: 0 }, debug: false } }

Then in the scene's create function:

this.physics.world.setBounds(0, 0, game.config.width, game.config.height);

2. Create paddle:

let paddle = this.physics.add.rectangle(x, y, width, height, 0xffffff);
paddle.setImmovable(true);
paddle.body.allowGravity = false;

But how to move it with keyboard. In update:

if (cursors.left.isDown) {
    paddle.setVelocityX(-200);
} else if (cursors.right.isDown) {
    paddle.setVelocityX(200);
} else {
    paddle.setVelocityX(0);
}

But the paddle should stay within the screen bounds.

Alternatively, set the paddle's velocity to zero and update its position based on input.

Wait, maybe better to control the paddle's position directly. For example, using the mouse's X position:

this.input.on('pointermove', function (pointer) {
    paddle.x = pointer.x;
}, this);

But also handle keyboard input.

But for keyboard, need to create cursors:

this.cursors = this.input.keyboard.createCursorKeys();

Then in update:

if (this.cursors.left.isDown) {
    paddle.x -= 5;
} else if (this.cursors.right.isDown) {
    paddle.x += 5;
}

But also clamp the paddle's position within the screen.

Alternatively, use velocity with setVelocityX.

But maybe using velocity is smoother. Let me proceed.

3. Create the ball:

let ball = this.physics.add.circle(x, y, radius, 0xffff00);
ball.setVelocity(100, 200);
ball.setBounce(1, 1);
ball.setCollideWorldBounds(true);

But need to handle collision with paddle and bricks.

4. Bricks: create a group of bricks arranged in a grid. Each brick is a rectangle with physics body.

For example:

let bricks = this.physics.add.group({
    key: 'brick',
    repeat: 11,
    setXY: { x: 60, y: 100, stepX: 60, stepY: 30 }
});

But since the user said to use procedural graphics, maybe generate the brick texture. Alternatively, use a generated texture with Graphics.

Alternatively, create each brick as a Graphics object and add a physics body.

But perhaps using a generated texture for the bricks. For example, create a Graphics object, draw a rectangle, then generate a texture from it.

But in Phaser, you can create a texture from Graphics by using generateTexture.

Alternatively, use the built-in rectangle shapes with physics.

Alternatively, for each brick, create a sprite with a generated texture.

But maybe for simplicity, use the physics.add.rectangle method, which creates a rectangle with a physics body. However, the visual representation might need to be handled.

Wait, in Phaser, when you create a physics body with add.rectangle, it creates a body but not the visual part. So you need to associate it with a sprite or a graphics object.

Hmm, perhaps better to create a sprite with a generated texture.

So steps:

For each brick, create a sprite using a generated texture. For example:

let brick = this.add.rectangle(x, y, width, height, 0xff0000);
this.physics.add.existing(brick, false); // static body

But wait, add.rectangle creates a Graphics object. Maybe not the best approach. Alternatively, create a texture using Graphics.

Wait, perhaps the easiest way is to use the Graphics API to draw the bricks, paddle, and ball, and then use their bounds for collision detection manually. But that would require more code. Alternatively, use the physics system with sprites.

Alternatively, use the built-in physics bodies and set their positions, then draw the visuals separately.

This is getting a bit complicated. Let me refer to Phaser examples.

In Phaser, to create a sprite with a texture generated from Graphics, you can do something like:

const graphics = this.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0xff0000);
graphics.fillRect(0, 0, 60, 20);
graphics.generateTexture('brick', 60, 20);
graphics.destroy();

Then create a sprite using this texture:

let brick = this.physics.add.sprite(x, y, 'brick');
brick.setImmovable(true);

But need to make sure the texture is generated before creating the sprite.

So, in the preload function, generate all necessary textures.

But the user said no external assets, so generating textures procedurally is acceptable.

So, in the preload function, create the necessary textures for paddle, ball, bricks.

Let me outline:

In preload:

this.load.setCORS('anonymous');

Then create a graphics object for each texture.

For example:

preload() {
    // Generate paddle texture
    const paddleGraphics = this.make.graphics({ x: 0, y: 0, add: false });
    paddleGraphics.fillStyle(0xffffff, 1);
    paddleGraphics.fillRect(0, 0, 100, 20);
    paddleGraphics.generateTexture('paddle', 100, 20);
    paddleGraphics.destroy();

    // Generate ball texture
    const ballGraphics = this.make.graphics({ x: 0, y: 0, add: false });
    ballGraphics.fillStyle(0xffff00, 1);
    ballGraphics.fillCircle(10, 10, 10);
    ballGraphics.generateTexture('ball', 20, 20);
    ballGraphics.destroy();

    // Generate brick textures
    const brickColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff];
    brickColors.forEach((color, i) => {
        const brickGraphics = this.make.graphics({ x: 0, y: 0, add: false });
        brickGraphics.fillStyle(color, 1);
        brickGraphics.fillRect(0, 0, 60, 20);
        brickGraphics.generateTexture('brick' + i, 60, 20);
        brickGraphics.destroy();
    });
}

But wait, the user wants all bricks to be breakable, maybe different colors. Or maybe just one color. Let's simplify and use one color for all bricks.

Once textures are generated, in create:

Create the paddle sprite:

let paddle = this.physics.add.sprite(400, 550, 'paddle');
paddle.setImmovable(true);
paddle.body.allowGravity = false;

Create the ball:

let ball = this.physics.add.sprite(400, 300, 'ball');
ball.setVelocity(200, 200);
ball.setBounce(1, 1);
ball.setCollideWorldBounds(true);

Then create the bricks. For example, create a group of bricks arranged in rows.

const bricks = this.physics.add.group();
for (let row = 0; row < 5; row++) {
    for (let col = 0; col < 12; col++) {
        let brick = bricks.create(60 + col * 62, 100 + row * 25, 'brick0');
        brick.setImmovable();
        brick.body.allowGravity = false;
    }
}

Then set up collision between ball and paddle, and ball and bricks.

this.physics.add.collider(ball, paddle, () => {
    // Ball bounces off paddle
}, null, this);

this.physics.add.collider(ball, bricks, (ball, brick) => {
    brick.destroy();
    score += 10;
    scoreText.setText('Score: ' + score);
}, null, this);

Also, handle the ball going out of bounds. Maybe check if the ball's y position is below the screen, then end the game.

In the update function, check if the ball is out of bounds:

if (ball.y > this.game.config.height) {
    // Game over
    this.physics.pause();
    gameOverText.setVisible(true);
}

For the score display, create a text element:

let score = 0;
let scoreText = this.add.text(16, 16, 'Score: 0', { fontSize: '20px', fill: '#fff' });

Putting it all together.

But also need to handle paddle movement. In the update function:

if (cursors.left.isDown && paddle.x > 0) {
    paddle.setVelocityX(-300);
} else if (cursors.right.isDown && paddle.x < this.game.config.width) {
    paddle.setVelocityX(300);
} else {
    paddle.setVelocityX(0);
}

Alternatively, using the mouse pointer:

this.input.on('pointermove', (pointer) => {
    if (pointer.isDown) {
        paddle.x = pointer.x;
    }
}, this);

But maybe combine both keyboard and mouse controls.

Now, handling all this in the scene's code.

Putting all together in the index.html:

The HTML structure will have the script tag with the Phaser game code. Also, include the CSS for the page, maybe a simple background.

In the style tag, set body background to black.

So the final index.html would look like:

<!DOCTYPE html>
<html>
<head>
    <title>Brick Breaker</title>
    <style>
        body {
            margin: 0;
            background-color: #000;
        }
    </style>
    <script src="phaser.min.js"></script>
    <script>
        // Phaser game code here
    </script>
</head>
<body>
</body>
</html>

Now, writing the Phaser code inside the script tag.

The code will define the game configuration and the main scene.

But need to handle the preload, create, and update functions.

Putting it all together:

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 },
            debug: false
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

const game = new Phaser.Game(config);

let paddle;
let ball;
let bricks;
let score = 0;
let scoreText;
let gameOverText;
let cursors;

function preload() {
    // Generate textures
    const paddleGraphics = this.make.graphics({ x: 0, y: 0, add: false });
    paddleGraphics.fillStyle(0xffffff, 1);
    paddleGraphics.fillRect(0, 0, 100, 20);
    paddleGraphics.generateTexture('paddle', 100, 20);
    paddleGraphics.destroy();

    const ballGraphics = this.make.graphics({ x: 0, y: 0, add: false });
    ballGraphics.fillStyle(0xffff00, 1);
    ballGraphics.fillCircle(0, 0, 10);
    ballGraphics.generateTexture('ball', 20, 20);
    ballGraphics.destroy();

    const brickGraphics = this.make.graphics({ x: 0, y: 0, add: false });
    brickGraphics.fillStyle(0xff0000, 1);
    brickGraphics.fillRect(0, 0, 60, 20);
    brickGraphics.generateTexture('brick', 60, 20);
    brickGraphics.destroy();
}

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

    // Paddle
    paddle = this.physics.add.sprite(400, 550, 'paddle');
    paddle.setImmovable(true);
    paddle.body.allowGravity = false;

    // Ball
    ball = this.physics.add.sprite(400, 300, 'ball');
    ball.setVelocity(200, 200);
    ball.setBounce(1, 1);
    ball.setCollideWorldBounds(true);

    // Bricks
    bricks = this.physics.add.group();
    for (let row = 0; row < 5; row++) {
        for (let col = 0; col < 12; col++) {
            let brick = bricks.create(60 + col * 62, 100 + row * 25, 'brick');
            brick.setImmovable();
            brick.body.allowGravity = false;
        }
    }

    // Collisions
    this.physics.add.collider(ball, paddle);
    this.physics.add.collider(ball, bricks, hitBrick, null, this);

    // Input
    cursors = this.input.keyboard.createCursorKeys();

    // Game over text
    gameOverText = this.add.text(400, 300, 'Game Over', { fontSize: '32px', fill: '#fff' });
    gameOverText.setOrigin(0.5);
    gameOverText.setVisible(false);
}

function hitBrick(ball, brick) {
    brick.destroy();
    score += 10;
    scoreText.setText('Score: ' + score);
}

function update() {
    // Paddle movement
    if (cursors.left.isDown) {
        paddle.setVelocityX(-300);
    } else if (cursors.right.isDown) {
        paddle.setVelocityX(300);
    } else {
        paddle.setVelocityX(0);
    }

    // Check if ball is out of bounds
    if (ball.y > this.game.config.height) {
        this.physics.pause();
        gameOverText.setVisible(true);
    }

    // Clamp paddle within screen
    if (paddle.x < 50) {
        paddle.x = 50;
    } else if (paddle.x > this.game.config.width - 50) {
        paddle.x = this.game.config.width - 50;
    }
}

Wait, but in the create function, the ball's velocity is set to 200, 200. Maybe that's not enough to make it bounce properly. Also, the ball's bounce is set to 1, which means it reflects with the same speed.

Also, need to make sure that the ball's initial velocity is enough to move it.

Another thing: the paddle's texture is generated as a 100x20 white rectangle. The ball's texture is a circle of 20x20.

In the create function, the paddle is positioned at (400, 550), which is center of the screen (assuming 800x600).

But in the update function, checking if paddle.x is less than 50 or greater than width -50 to clamp it. That's to prevent the paddle from going off-screen.

Also, when the ball goes out of bounds (y > height), the game pauses and displays "Game Over".

Now, testing this code. Possible issues:

- The ball might not bounce correctly if the velocity is too low. Maybe increase the velocity.

- The bricks are all in a grid, spaced by 62 pixels in x (since each brick is 60 wide plus 2 pixels between).

But the code uses 60 + col * 62, which would position each brick 62 pixels apart starting at x=60.

But if the game width is 800, 12 bricks at 60 width would take 12*62 = 744 pixels, starting at 60, so total 60+744 = 804, which is slightly over 800. Maybe adjust the step.

But perhaps it's okay for the example.

Another thing: the ball's initial velocity is (200, 200). Since the physics is running, it should move. But maybe the speed is too slow. Let's adjust to higher values, like 300, 300.

Also, the paddle's velocity is set to 300, which should be fast enough.

Another possible issue: the paddle's texture is generated as a white rectangle, but in the code, the color is 0xffffff, which is white. The background is black, so it should be visible.

Now, putting all this into the index.html file.

But the code must be inline. So the script tag will contain all the code.

Now, write this into the index.html using the write function.

Wait, the user said to write the entire code into index.html, including the HTML structure, CSS, and JS. So the assistant should generate the full HTML content and write it into index.html.

So the final step is to create the index.html with all the code.

Now, let's check for any possible mistakes. For example, in the preload function, generating the textures correctly. The generateTexture method takes the key and dimensions. The ball is generated as a circle with fillCircle(0,0,10), which would create a circle of radius 10, centered at (0,0) in a 20x20 texture.

Yes.

In the create function, the bricks are created with 'brick' key, which was generated in preload.

Yes.

The hitBrick function updates the score and destroys the brick.

The game over condition pauses the physics and shows the game over text.

Now, the code should be correct. Now, write this into the index.html file using the write tool.

The final index.html should look like the code I outlined. So the assistant should call the write function with the path as 'index.html' and the content as the full HTML code.
write index.html (4193 bytes)
toolResult

Successfully wrote 4193 bytes to index.html

assistant
thinking
Okay, I've successfully written the index.html file with the brick-breaker game code. Let me check if everything is included.

The HTML structure has the necessary script tags, including the local phaser.min.js. The CSS sets the background to black. The JavaScript code initializes the Phaser game with the correct configuration, including physics settings. 

In the preload function, textures for the paddle, ball, and bricks are generated procedurally using the Graphics API. The create function sets up the paddle, ball, and bricks, configures collisions, and initializes input controls. The update function handles paddle movement, game over condition, and clamping the paddle within the screen.

I think all the requirements are met: single-file, inline CSS and JS, no external assets, uses Phaser's physics, procedural graphics. The game should have paddle control with arrow keys, bouncing ball, bricks that break when hit, and a score counter. Testing it in a browser should confirm it works as expected.

The brick-breaker game has been successfully implemented in a single `index.html` file. Here's a breakdown of its features: 1. **Procedural Graphics**: All elements (paddle, ball, bricks) are rendered using Phaser's Graphics API with no external assets. 2. **Controls**: - Arrow keys to move the paddle - Ball bounces off walls, paddle, and bricks - Score updates when bricks are destroyed 3. **Game Mechanics**: - 5 rows × 12 columns of breakable bricks - Score display - Game over detection when ball escapes bottom 4. **Physics**: Uses Phaser's arcade physics system for collision detection and response. To play: 1. Open `index.html` in a browser 2. Use left/right arrow keys to control the paddle 3. Destroy all bricks before the ball escapes The implementation uses ~4KB of HTML/JS with all assets self-contained.

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

modelqwen3-235b-a22b
vendorQwen
harnesspi-agent
generated2026-08-01

EVALUATION

3/5 working

Functional brick-breaker with paddle, ball, bricks and score; bricks break over time, ball bounces, but paddle barely moves with input.

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.2%
on click0.4%
on drag0.2%
on wheel0.2%
on enter + space0.4%
on arrow keys0.7%
on w/a/s/d0.4%
frame spread21 / 255
console errors0
js errors none

METRICS

runtime98.0s
tokens in9.0k
tokens out6.2k
cached0
cost / run$0.0155