Hamburger breakoutOne-line
Dots3-Note Preview (free)
by Dots StudioReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 37.4 s
- Cost
- $0
- Output tokens
- 3,676
- Spent thinking
- 0 tokens
- Speed
- 100.1 tok/s
- Console errors
- 0
- First token after
- 709 ms
- First visible text after
- 709 ms
- Prompt tokens
- 359
- Code size
- 11.5 KB
- Finish reason
- stop
- Served by
- AtlasCloud
- Model id
dots-studio/dots-3-note-preview:free- Reasoning sent
{"effort":"none"}- Max output
- 32,000 tokens
- Generated
- Nov 9, 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 · 411 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hamburger Breakout – Hearts Explosion</title>
<style>
* { margin:0; padding:0; box-sizing:border-box; }
html,body { height:100%; background:#1a1a2e; color:#fff; font-family:'Arial Black',Arial,sans-serif; overflow:hidden; }
#wrap { position:relative; width:100vw; height:100vh; display:flex; align-items:center; justify-content:center; }
canvas { display:block; background:#16213e; border-radius:12px; box-shadow:0 0 40px rgba(255,105,180,.4); cursor:none; }
#overlay { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; background:rgba(0,0,0,.55); backdrop-filter:blur(4px); z-index:10; }
#overlay h1 { font-size:clamp(28px,6vw,64px); color:#ff6b9d; text-shadow:0 0 15px #ff6b9d; margin-bottom:10px; }
#overlay p { font-size:clamp(16px,3vw,24px); margin-bottom:30px; color:#ffd166; }
#overlay button { padding:14px 36px; font-size:clamp(16px,3vw,22px); background:#ff6b9d; border:none; border-radius:50px; color:#fff; cursor:pointer; box-shadow:0 0 20px #ff6b9d; transition:transform .2s; }
#overlay button:hover { transform:scale(1.05); }
.hidden { display:none !important; }
</style>
</head>
<body>
<div id="wrap">
<canvas id="game"></canvas>
<div id="overlay">
<h1>🍔 HAMBURGER BREAKOUT 🍔</h1>
<p>Break bricks, collect hearts, survive the sizzle!</p>
<button id="startBtn">Click or Press a Key to Start</button>
</div>
</div>
<script>
(() => {
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const overlay = document.getElementById('overlay');
const startBtn = document.getElementById('startBtn');
let W, H;
function resize() {
const maxW = Math.min(1280, window.innerWidth - 40);
const maxH = Math.min(800, window.innerHeight - 40);
W = maxW; H = maxH;
canvas.width = W; canvas.height = H;
}
window.addEventListener('resize', resize);
resize();
// ---------- GAME STATE ----------
let bricks = [];
let hearts = [];
let particles = [];
let paddle, ball;
let score = 0;
let lives = 3;
let level = 1;
let running = false;
let autoPlay = true;
let lastTime = 0;
// ---------- CLASSES ----------
class Paddle {
constructor() {
this.w = Math.max(100, W * 0.18);
this.h = 24;
this.x = W / 2 - this.w / 2;
this.y = H - 60;
this.speed = 10;
}
draw() {
// bun
ctx.fillStyle = '#d2691e';
ctx.beginPath();
ctx.ellipse(this.x + this.w/2, this.y + 8, this.w/2, 10, 0, 0, Math.PI*2);
ctx.fill();
// patty
ctx.fillStyle = '#5d4037';
ctx.fillRect(this.x + 4, this.y + 10, this.w - 8, 8);
// lettuce
ctx.fillStyle = '#4caf50';
ctx.fillRect(this.x + 6, this.y + 6, this.w - 12, 4);
// tomato
ctx.fillStyle = '#f44336';
ctx.beginPath();
ctx.arc(this.x + this.w/2, this.y + 14, 8, 0, Math.PI*2);
ctx.fill();
// bottom bun
ctx.fillStyle = '#deb887';
ctx.fillRect(this.x, this.y + 18, this.w, 6);
}
update(mx) {
// mouse or touch
this.x = mx - this.w/2;
if (this.x < 0) this.x = 0;
if (this.x + this.w > W) this.x = W - this.w;
}
}
class Ball {
constructor() {
this.reset();
}
reset() {
this.r = 8;
this.x = paddle ? paddle.x + paddle.w/2 : W/2;
this.y = paddle ? paddle.y - this.r - 2 : H - 100;
this.vx = (Math.random() < 0.5 ? -1 : 1) * 4;
this.vy = -6;
}
draw() {
ctx.fillStyle = '#fff';
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
ctx.fill();
ctx.strokeStyle = '#ffd166';
ctx.lineWidth = 2;
ctx.stroke();
}
update() {
this.x += this.vx;
this.y += this.vy;
// walls
if (this.x - this.r < 0 || this.x + this.r > W) this.vx *= -1;
if (this.y - this.r < 0) this.vy *= -1;
// paddle
if (this.y + this.r > paddle.y &&
this.x > paddle.x && this.x < paddle.x + paddle.w &&
this.vy > 0) {
const hit = (this.x - (paddle.x + paddle.w/2)) / (paddle.w/2);
this.vx = hit * 7;
this.vy = -Math.abs(this.vy) - 1;
// tiny speed ramp
if (Math.abs(this.vx) < 1) this.vx = 1.5 * Math.sign(this.vx);
}
// bottom = lose life
if (this.y - this.r > H) {
lives--;
if (lives <= 0) gameOver();
else ball.reset();
}
}
}
class Brick {
constructor(x, y, w, h, color) {
this.x = x; this.y = y; this.w = w; this.h = h;
this.color = color;
this.hits = 1; // 1-hit bricks
}
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
ctx.strokeStyle = 'rgba(0,0,0,.3)';
ctx.strokeRect(this.x, this.y, this.w, this.h);
}
hit() {
this.hits--;
if (this.hits <= 0) {
explode(this.x + this.w/2, this.y + this.h/2);
score += 10;
return true;
}
return false;
}
}
class Heart {
constructor(x, y) {
this.x = x; this.y = y;
this.vx = (Math.random() - 0.5) * 4;
this.vy = Math.random() * -3 - 1;
this.life = 120; // frames
this.size = 14;
}
draw() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.fillStyle = '#ff6b9d';
ctx.beginPath();
ctx.moveTo(0, this.size/2);
ctx.bezierCurveTo(this.size/2, -this.size/2, this.size, 0, 0, this.size);
ctx.bezierCurveTo(-this.size, 0, -this.size/2, -this.size/2, 0, this.size/2);
ctx.fill();
ctx.restore();
}
update() {
this.x += this.vx;
this.y += this.vy;
this.vy += 0.15; // gravity
this.life--;
// collect by paddle
if (this.y + this.size/2 > paddle.y &&
this.x > paddle.x && this.x < paddle.x + paddle.w) {
lives = Math.min(5, lives + 1);
score += 50;
return false;
}
return this.life > 0 && this.y < H + 50;
}
}
class Particle {
constructor(x, y, color) {
this.x = x; this.y = y;
this.vx = (Math.random() - 0.5) * 8;
this.vy = (Math.random() - 0.5) * 8;
this.color = color;
this.life = 40;
this.size = Math.random() * 3 + 1;
}
draw() {
ctx.globalAlpha = this.life / 40;
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size);
ctx.globalAlpha = 1;
}
update() {
this.x += this.vx;
this.y += this.vy;
this.vy += 0.2;
this.life--;
return this.life > 0;
}
}
// ---------- FUNCTIONS ----------
function makeBricks() {
bricks = [];
const rows = 5;
const cols = Math.floor(W / 70);
const bw = (W - 40) / cols;
const bh = 24;
const colors = ['#ff6b9d', '#ffd166', '#06d6a0', '#118ab2', '#ef476f'];
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
bricks.push(new Brick(
20 + c * bw,
60 + r * bh + 20,
bw - 4,
bh - 4,
colors[r % colors.length]
));
}
}
}
function explode(x, y) {
// hearts
for (let i = 0; i < 12; i++) {
hearts.push(new Heart(x, y));
}
// spark particles
const colors = ['#ff6b9d', '#ffd166', '#fff'];
for (let i = 0; i < 20; i++) {
particles.push(new Particle(x, y, colors[Math.floor(Math.random()*colors.length)]));
}
}
function gameOver() {
running = false;
overlay.querySelector('h1').textContent = 'GAME OVER 🍔';
overlay.querySelector('p').textContent = `Score: ${score} | Level: ${level}`;
startBtn.textContent = 'Play Again';
overlay.classList.remove('hidden');
}
function nextLevel() {
level++;
score += 100 * level;
makeBricks();
ball.reset();
}
// ---------- INPUT ----------
let mouseX = W/2;
canvas.addEventListener('mousemove', e => {
const rect = canvas.getBoundingClientRect();
mouseX = (e.clientX - rect.left) * (W / rect.width);
});
canvas.addEventListener('touchmove', e => {
e.preventDefault();
const rect = canvas.getBoundingClientRect();
const touch = e.touches[0];
mouseX = (touch.clientX - rect.left) * (W / rect.width);
}, { passive: false });
document.addEventListener('keydown', e => {
if (e.key === ' ' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
if (!running) startGame();
}
// manual arrow control fallback
if (running && !autoPlay) {
if (e.key === 'ArrowLeft') mouseX = Math.max(mouseX - 20, paddle.w/2);
if (e.key === 'ArrowRight') mouseX = Math.min(mouseX + 20, W - paddle.w/2);
}
});
startBtn.addEventListener('click', startGame);
function startGame() {
score = 0; lives = 3; level = 1;
paddle = new Paddle();
ball = new Ball();
makeBricks();
hearts = []; particles = [];
running = true;
overlay.classList.add('hidden');
requestAnimationFrame(gameLoop);
}
// ---------- AUTO PLAY (demo mode) ----------
function autoAIDemo() {
if (!running) return;
// simple AI: move paddle toward ball
const target = ball.x;
const paddleCenter = paddle.x + paddle.w/2;
const diff = target - paddleCenter;
if (Math.abs(diff) > 2) {
mouseX += Math.sign(diff) * Math.min(Math.abs(diff), 8);
}
}
// ---------- MAIN LOOP ----------
function gameLoop(ts) {
if (!running) return;
const dt = ts - lastTime;
lastTime = ts;
// auto-play
if (autoPlay) autoAIDemo();
paddle.update(mouseX);
ball.update();
// bricks
for (let i = bricks.length - 1; i >= 0; i--) {
const b = bricks[i];
if (ball.y - ball.r < b.y + b.h &&
ball.y + ball.r > b.y &&
ball.x + ball.r > b.x &&
ball.x - ball.r < b.x + b.w) {
// collision
const hit = b.hit();
if (hit) bricks.splice(i, 1);
// bounce
const prevVx = ball.vx;
ball.vy *= -1;
// add slight horizontal based on where it hit
const hitPos = (ball.x - (b.x + b.w/2)) / (b.w/2);
ball.vx = hitPos * 5 + prevVx * 0.3;
}
}
// hearts
for (let i = hearts.length - 1; i >= 0; i--) {
if (!hearts[i].update()) hearts.splice(i, 1);
}
// particles
for (let i = particles.length - 1; i >= 0; i--) {
if (!particles[i].update()) particles.splice(i, 1);
}
// level complete
if (bricks.length === 0) {
nextLevel();
}
draw();
requestAnimationFrame(gameLoop);
}
function draw() {
// background gradient
const grad = ctx.createLinearGradient(0, 0, 0, H);
grad.addColorStop(0, '#16213e');
grad.addColorStop(1, '#0f3460');
ctx.fillStyle = grad;
ctx.fillRect(0, 0, W, H);
// grid lines
ctx.strokeStyle = 'rgba(255,255,255,0.05)';
ctx.lineWidth = 1;
for (let x = 0; x < W; x += 40) {
ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, H); ctx.stroke();
}
for (let y = 0; y < H; y += 40) {
ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(W, y); ctx.stroke();
}
// draw game objects
bricks.forEach(b => b.draw());
hearts.forEach(h => h.draw());
particles.forEach(p => p.draw());
paddle.draw();
ball.draw();
// HUD
ctx.fillStyle = '#fff';
ctx.font = 'bold 18px Arial';
ctx.textAlign = 'left';
ctx.fillText(`Score: ${score}`, 16, 30);
ctx.fillText(`Lives: ${'❤️'.repeat(lives)}`, 16, 55);
ctx.fillText(`Level: ${level}`, W - 120, 30);
ctx.textAlign = 'right';
}
// ---------- INIT ----------
// show overlay until user clicks
overlay.classList.remove('hidden');
})();
</script>
</body>
</html>