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.
transcript · 4 messages
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.
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./tmp/ws/index.html (5317 bytes)Successfully wrote 5317 bytes to /tmp/ws/index.html
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
EVALUATION
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.