Hamburger breakoutOne-line
Gemma 4 31B
by Googlereasoning defaultClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 26.0 s
- Cost
- $0.0012
- Output tokens
- 3,332
- Spent thinking
- 0 tokens
- Speed
- 129.7 tok/s
- Console errors
- 0
- First token after
- 334 ms
- First visible text after
- 334 ms
- Prompt tokens
- 381
- Code size
- 10.0 KB
- Finish reason
- stop
- Served by
- CoreWeave
- Model id
google/gemma-4-31b-it- Reasoning sent
model default- Max output
- 16,384 tokens
- Generated
- Nov 13, 2026
What it was asked
The prompt
“i want a breakout game where the paddle is a hamburger and every brick you break explodes into tons of little hearts”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task. Output rules: - Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block. - Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task. - Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw. - The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. - Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction. - Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session. - Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing. - The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message. - The code must run with zero errors in the console of the latest Chrome.
Code run-1.html · 344 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Burger Breakout: Love Edition</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #ff9a9e;
background-image: linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#game-container {
position: relative;
box-shadow: 0 20px 50px rgba(0,0,0,0.3);
border-radius: 15px;
overflow: hidden;
background: #222;
}
canvas {
display: block;
cursor: none;
}
#ui-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
pointer-events: none;
color: white;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
text-align: center;
}
#start-msg {
background: rgba(0, 0, 0, 0.6);
padding: 20px 40px;
border-radius: 50px;
font-size: 24px;
border: 3px solid white;
animation: pulse 1.5s infinite;
pointer-events: auto;
cursor: pointer;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.stats {
position: absolute;
top: 10px;
left: 20px;
font-size: 20px;
font-weight: bold;
text-align: left;
}
</style>
</head>
<body>
<div id="game-container">
<canvas id="gameCanvas"></canvas>
<div id="ui-overlay">
<div class="stats" id="stats">Score: 0</div>
<div id="start-msg">🍔 CLICK TO START 🍔<br><small>Move mouse or use keys</small></div>
</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const startMsg = document.getElementById('start-msg');
const statsEl = document.getElementById('stats');
// Settings
canvas.width = 600;
canvas.height = 700;
const PADDLE_WIDTH = 100;
const PADDLE_HEIGHT = 40;
const BALL_RADIUS = 8;
const BRICK_ROWS = 6;
const BRICK_COLS = 8;
const BRICK_PADDING = 10;
const BRICK_OFFSET_TOP = 60;
const BRICK_OFFSET_LEFT = 35;
const BRICK_WIDTH = (canvas.width - (BRICK_OFFSET_LEFT * 2) - (BRICK_PADDING * (BRICK_COLS - 1))) / BRICK_COLS;
const BRICK_HEIGHT = 25;
let score = 0;
let gameRunning = false;
let autoPlay = true;
const paddle = {
x: (canvas.width - PADDLE_WIDTH) / 2,
y: canvas.height - PADDLE_HEIGHT - 20,
width: PADDLE_WIDTH,
height: PADDLE_HEIGHT,
color: '#f39c12'
};
const ball = {
x: canvas.width / 2,
y: canvas.height - 60,
dx: 4,
dy: -4,
radius: BALL_RADIUS
};
const bricks = [];
const particles = [];
function initBricks() {
const colors = ['#FF5252', '#FF4081', '#E040FB', '#7C4DFF', '#536DFE', '#448AFF'];
for (let c = 0; c < BRICK_COLS; c++) {
bricks[c] = [];
for (let r = 0; r < BRICK_ROWS; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1, color: colors[r] };
}
}
}
function drawBurger(x, y, w, h) {
// Bottom bun
ctx.fillStyle = '#e3b04b';
ctx.beginPath();
ctx.roundRect(x, y + h*0.6, w, h*0.4, [0, 0, 10, 10]);
ctx.fill();
// Patty
ctx.fillStyle = '#633a1a';
ctx.beginPath();
ctx.roundRect(x - 2, y + h*0.4, w + 4, h*0.3, 5);
ctx.fill();
// Lettuce
ctx.fillStyle = '#7cfc00';
ctx.beginPath();
ctx.roundRect(x, y + h*0.3, w, h*0.15, 5);
ctx.fill();
// Top bun
ctx.fillStyle = '#f5c76b';
ctx.beginPath();
ctx.roundRect(x, y, w, h*0.4, [15, 15, 0, 0]);
ctx.fill();
// Sesame seeds
ctx.fillStyle = 'white';
for(let i=0; i<10; i++) {
ctx.fillRect(x + Math.random()*w, y + Math.random()*h*0.3, 2, 2);
}
}
function drawHeart(x, y, size, color) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.bezierCurveTo(x, y - size, x - size, y - size, x - size, y);
ctx.bezierCurveTo(x - size, y + size, x, y + size*1.5, x, y + size*2);
ctx.bezierCurveTo(x, y + size*1.5, x + size, y + size, x + size, y);
ctx.bezierCurveTo(x + size, y - size, x, y - size, x, y);
ctx.fill();
}
function spawnHearts(x, y, color) {
for (let i = 0; i < 12; i++) {
particles.push({
x: x,
y: y,
dx: (Math.random() - 0.5) * 8,
dy: (Math.random() - 0.5) * 8,
life: 1.0,
size: Math.random() * 4 + 2,
color: color
});
}
}
function updateParticles() {
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.x += p.dx;
p.y += p.dy;
p.dy += 0.1; // gravity
p.life -= 0.02;
if (p.life <= 0) particles.splice(i, 1);
}
}
function drawParticles() {
particles.forEach(p => {
ctx.globalAlpha = p.life;
drawHeart(p.x, p.y, p.size, p.color);
});
ctx.globalAlpha = 1.0;
}
function collisionDetection() {
for (let c = 0; c < BRICK_COLS; c++) {
for (let r = 0; r < BRICK_ROWS; r++) {
const b = bricks[c][r];
if (b.status === 1) {
if (ball.x > b.x && ball.x < b.x + BRICK_WIDTH && ball.y > b.y && ball.y < b.y + BRICK_HEIGHT) {
ball.dy = -ball.dy;
b.status = 0;
score += 10;
statsEl.innerText = `Score: ${score}`;
spawnHearts(b.x + BRICK_WIDTH/2, b.y + BRICK_HEIGHT/2, b.color);
}
}
}
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Bricks
for (let c = 0; c < BRICK_COLS; c++) {
for (let r = 0; r < BRICK_ROWS; r++) {
if (bricks[c][r].status === 1) {
const bx = c * (BRICK_WIDTH + BRICK_PADDING) + BRICK_OFFSET_LEFT;
const by = r * (BRICK_HEIGHT + BRICK_PADDING) + BRICK_OFFSET_TOP;
bricks[c][r].x = bx;
bricks[c][r].y = by;
ctx.fillStyle = bricks[c][r].color;
ctx.beginPath();
ctx.roundRect(bx, by, BRICK_WIDTH, BRICK_HEIGHT, 5);
ctx.fill();
// Highlight
ctx.fillStyle = 'rgba(255,255,255,0.3)';
ctx.fillRect(bx, by, BRICK_WIDTH, 3);
}
}
}
drawBurger(paddle.x, paddle.y, paddle.width, paddle.height);
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fillStyle = "#fff";
ctx.fill();
ctx.closePath();
drawParticles();
}
function move() {
if (!gameRunning && !autoPlay) return;
if (autoPlay) {
// Simple AI: move paddle to match ball X
const targetX = ball.x - paddle.width / 2;
paddle.x += (targetX - paddle.x) * 0.15;
}
// Boundary constraints
if (paddle.x < 0) paddle.x = 0;
if (paddle.x + paddle.width > canvas.width) paddle.x = canvas.width - paddle.width;
ball.x += ball.dx;
ball.y += ball.dy;
// Wall bounce
if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) ball.dx = -ball.dx;
if (ball.y - ball.radius < 0) ball.dy = -ball.dy;
// Paddle bounce
if (ball.y + ball.radius > paddle.y &&
ball.x > paddle.x &&
ball.x < paddle.x + paddle.width) {
ball.dy = -Math.abs(ball.dy);
// Add some English based on where it hits the burger
const hitPos = (ball.x - (paddle.x + paddle.width/2)) / (paddle.width/2);
ball.dx = hitPos * 5;
}
// Death / Reset
if (ball.y > canvas.height) {
ball.x = canvas.width / 2;
ball.y = canvas.height - 60;
ball.dx = 4;
ball.dy = -4;
score = 0;
statsEl.innerText = `Score: ${score}`;
initBricks();
}
collisionDetection();
updateParticles();
}
function gameLoop() {
move();
draw();
requestAnimationFrame(gameLoop);
}
// Interaction
window.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const root = document.documentElement;
const mouseX = e.clientX - rect.left - root.scrollLeft;
paddle.x = mouseX - paddle.width / 2;
if (gameRunning) autoPlay = false;
});
startMsg.addEventListener('click', () => {
startMsg.style.display = 'none';
gameRunning = true;
autoPlay = false;
});
// Init and Start
initBricks();
gameLoop();
// Every few seconds, if user hasn't clicked, toggle autoPlay for demo a bit
// but the request asks for self-playing demo mode initially.
// So we start with autoPlay = true and gameRunning = true but show the message.
gameRunning = true;
</script>
</body>
</html>