Hamburger breakoutOne-line
GLM 5.3
by Z.aiReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 19.9 s
- Cost
- $0.011
- Output tokens
- 3,568
- Spent thinking
- 34 tokens
- Speed
- 184.5 tok/s
- Console errors
- 0
- First token after
- 546 ms
- First visible text after
- 2.1 s
- Prompt tokens
- 357
- Code size
- 9.9 KB
- Finish reason
- stop
- Served by
- CoreWeave
- Model id
z-ai/glm-5.3- Reasoning sent
{"effort":"low"}- Max output
- 943,718 tokens
- Generated
- Nov 12, 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 · 282 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HeartBreaker — Burger Breakout</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; overflow: hidden; }
body {
background: radial-gradient(ellipse at 50% 0%, #2b1a3d 0%, #14092b 60%, #0a0518 100%);
font-family: Georgia, 'Times New Roman', serif;
display: flex; align-items: center; justify-content: center;
color: #ffd9ec;
}
#wrap { position: relative; width: 100%; max-width: 900px; }
canvas { display: block; width: 100%; height: auto; border-radius: 12px; }
#overlay {
position: absolute; inset: 0; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 14px;
background: rgba(10,5,24,.55); backdrop-filter: blur(2px);
border-radius: 12px; text-align: center; padding: 20px;
transition: opacity .4s; cursor: pointer;
}
#overlay.hidden { opacity: 0; pointer-events: none; }
#overlay h1 { font-size: clamp(28px, 6vw, 54px); letter-spacing: 2px;
text-shadow: 0 0 18px #ff5fa8, 0 2px 0 #7a1f4d; color: #fff; font-style: italic; }
#overlay p { font-size: clamp(15px, 2.5vw, 20px); color: #ffd9ec; }
#hud { position: absolute; top: 10px; left: 14px; right: 14px;
display: flex; justify-content: space-between; font-size: 17px;
pointer-events: none; text-shadow: 0 1px 3px #000; letter-spacing: 1px; }
.blink { animation: bl 1.2s infinite; }
@keyframes bl { 50% { opacity: .35; } }
</style>
</head>
<body>
<div id="wrap">
<canvas id="cv" width="900" height="620"></canvas>
<div id="hud"><span>SCORE <b id="score">0</b></span><span>HEARTS 💗 <b id="lives">3</b></span></div>
<div id="overlay">
<h1>💗 HeartBreaker 🍔</h1>
<p>Break bricks with your burger paddle —<br>every brick bursts into little hearts!</p>
<p class="blink" id="cta">Click or press a key to start</p>
<p style="font-size:14px;opacity:.7">← → or mouse to move the burger</p>
</div>
</div>
<script>
const cv = document.getElementById('cv'), ctx = cv.getContext('2d');
const W = cv.width, H = cv.height;
const overlay = document.getElementById('overlay');
const scoreEl = document.getElementById('score'), livesEl = document.getElementById('lives');
let score = 0, lives = 3, playing = false, demo = true;
let paddleX = W/2, paddleW = 130, paddleH = 42, paddleY = H - 60;
let targetX = W/2;
let ball = { x: W/2, y: H-120, r: 9, vx: 3.2, vy: -4.4, stuck: false };
let bricks = [], hearts = [], floats = [];
const COLS = 10, ROWS = 5, BW = 74, BH = 26, GAP = 8, TOP = 70;
const COLORS = ['#ff5c8a','#ff8f5c','#ffd15c','#7ee08a','#6cc5ff'];
function buildBricks(){
bricks = [];
const totalW = COLS*BW + (COLS-1)*GAP;
const ox = (W - totalW)/2;
for (let r=0;r<ROWS;r++) for (let c=0;c<COLS;c++)
bricks.push({x: ox + c*(BW+GAP), y: TOP + r*(BH+GAP), w: BW, h: BH, col: COLORS[r], alive: true});
}
buildBricks();
function burst(x, y, col){
for (let i=0;i<26;i++){
const a = Math.random()*Math.PI*2, s = 1+Math.random()*4.5;
hearts.push({x, y, vx: Math.cos(a)*s, vy: Math.sin(a)*s - 1.5,
size: 4+Math.random()*8, rot: Math.random()*6.28, vr:(Math.random()-.5)*.3,
life: 1, hue: Math.random()<.5 ? col : '#ff5c9e'});
}
floats.push({x, y, txt: '+10', life: 1});
}
function drawHeart(x, y, s, rot, col, alpha){
ctx.save(); ctx.translate(x,y); ctx.rotate(rot); ctx.scale(s/10, s/10);
ctx.globalAlpha = alpha;
ctx.fillStyle = col;
ctx.beginPath();
ctx.moveTo(0, 4);
ctx.bezierCurveTo(-10, -6, -5, -14, 0, -8);
ctx.bezierCurveTo(5, -14, 10, -6, 0, 4);
ctx.fill(); ctx.restore();
}
function drawBurger(cx){
const x = cx - paddleW/2, y = paddleY;
ctx.save();
// bun top
ctx.fillStyle = '#e8a34e';
ctx.beginPath();
ctx.moveTo(x, y+16);
ctx.quadraticCurveTo(x+paddleW/2, y-22, x+paddleW, y+16);
ctx.closePath(); ctx.fill();
ctx.fillStyle = 'rgba(255,255,255,.25)';
for (let i=0;i<6;i++){
ctx.beginPath();
ctx.arc(x+18+i*(paddleW-36)/5, y+4+ (i%2)*3, 2.4, 0, 7); ctx.fill();
}
// lettuce
ctx.fillStyle = '#6fbf4a';
ctx.beginPath();
ctx.moveTo(x, y+18);
for (let i=0;i<9;i++) ctx.quadraticCurveTo(x+ (i+.5)*paddleW/9, y+ (i%2? 26:14), x+(i+1)*paddleW/9, y+18);
ctx.lineTo(x+paddleW, y+22); ctx.lineTo(x, y+22); ctx.fill();
// tomato
ctx.fillStyle = '#d8433f';
ctx.fillRect(x+4, y+24, paddleW-8, 5);
// patty
ctx.fillStyle = '#6b3d1f';
ctx.beginPath();
ctx.roundRect(x-3, y+29, paddleW+6, 10, 5); ctx.fill();
// bun bottom
ctx.fillStyle = '#e8a34e';
ctx.beginPath();
ctx.roundRect(x, y+38, paddleW, 12, 6); ctx.fill();
ctx.restore();
}
function resetBall(dir){
ball.x = paddleX; ball.y = paddleY - 24;
const ang = (-Math.PI/2) + (Math.random()-.5)*.7;
const sp = 6;
ball.vx = Math.cos(ang)*sp*(dir||1); ball.vy = Math.sin(ang)*sp;
}
function reflectOffPaddle(){
const hit = (ball.x - paddleX) / (paddleW/2);
const sp = Math.min(9, Math.hypot(ball.vx, ball.vy)*1.03);
const ang = -Math.PI/2 + hit*1.0;
ball.vx = Math.cos(ang)*sp; ball.vy = Math.sin(ang)*sp;
}
function aiMove(){
// simple demo AI
const px = ball.vx > 0 && ball.y < H*0.6 ? ball.x + 60 : ball.x;
targetX = Math.max(paddleW/2, Math.min(W-paddleW/2, px + Math.sin(t*2)*10));
}
let t = 0;
function update(){
t += 0.016;
if (demo) aiMove();
paddleX += (targetX - paddleX) * 0.25;
paddleX = Math.max(paddleW/2, Math.min(W-paddleW/2, paddleX));
if (!ball.stuck){
ball.x += ball.vx; ball.y += ball.vy;
if (ball.x < ball.r){ ball.x = ball.r; ball.vx *= -1; }
if (ball.x > W-ball.r){ ball.x = W-ball.r; ball.vx *= -1; }
if (ball.y < ball.r){ ball.y = ball.r; ball.vy *= -1; }
// paddle collision — ball vs burger
if (ball.vy > 0 && ball.y + ball.r > paddleY && ball.y - ball.r < paddleY + paddleH &&
ball.x > paddleX - paddleW/2 - ball.r && ball.x < paddleX + paddleW/2 + ball.r){
ball.y = paddleY - ball.r;
reflectOffPaddle();
for (let i=0;i<5;i++) hearts.push({x: ball.x, y: paddleY, vx:(Math.random()-.5)*3, vy: -Math.random()*3,
size: 5+Math.random()*5, rot: Math.random()*6, vr: .1, life: 1, hue: '#ffd15c'});
}
// bricks
for (const b of bricks){
if (!b.alive) continue;
if (ball.x + ball.r > b.x && ball.x - ball.r < b.x + b.w &&
ball.y + ball.r > b.y && ball.y - ball.r < b.y + b.h){
b.alive = false;
score += 10; scoreEl.textContent = score;
burst(b.x + b.w/2, b.y + b.h/2, b.col);
// bounce: pick axis by penetration
const oxl = ball.x + ball.r - b.x, oxr = b.x + b.w - (ball.x - ball.r);
const oyt = ball.y + ball.r - b.y, oyb = b.y + b.h - (ball.y - ball.r);
const m = Math.min(oxl, oxr, oyt, oyb);
if (m === oxl || m === oxr) ball.vx *= -1; else ball.vy *= -1;
break;
}
}
if (bricks.every(b=>!b.alive)){
buildBricks(); score += 100; scoreEl.textContent = score;
for (let i=0;i<60;i++) burst(Math.random()*W, TOP+Math.random()*200, '#fff');
resetBall(1);
}
if (ball.y > H + 30){
lives--; livesEl.textContent = Math.max(0,lives);
if (lives <= 0){ lives = 3; score = 0; scoreEl.textContent = 0; livesEl.textContent = 3; }
if (!demo){ ball.stuck = true; }
resetBall(Math.random()<.5?1:-1);
}
} else {
ball.x = paddleX; ball.y = paddleY - 24;
}
// hearts
for (const h of hearts){
h.x += h.vx; h.y += h.vy; h.vy += .12; h.rot += h.vr; h.life -= .012;
}
hearts = hearts.filter(h => h.life > 0 && h.y < H + 40);
for (const f of floats){ f.y -= 1; f.life -= .02; }
floats = floats.filter(f => f.life > 0);
}
function render(){
// background
const g = ctx.createLinearGradient(0,0,0,H);
g.addColorStop(0,'#241238'); g.addColorStop(1,'#120825');
ctx.fillStyle = g; ctx.fillRect(0,0,W,H);
// faint hearts bg
ctx.globalAlpha = .06;
for (let i=0;i<8;i++) drawHeart(100+i*100, 150 + Math.sin(i*2)*60, 40, .3, '#ff5c9e', 1);
ctx.globalAlpha = 1;
for (const b of bricks){
if (!b.alive) continue;
ctx.fillStyle = b.col;
ctx.beginPath(); ctx.roundRect(b.x, b.y, b.w, b.h, 6); ctx.fill();
ctx.fillStyle = 'rgba(255,255,255,.3)';
ctx.beginPath(); ctx.roundRect(b.x+4, b.y+4, b.w-8, 6, 3); ctx.fill();
ctx.strokeStyle = 'rgba(0,0,0,.3)'; ctx.strokeRect(b.x+.5, b.y+.5, b.w-1, b.h-1);
}
for (const h of hearts) drawHeart(h.x, h.y, h.size, h.rot, h.hue, Math.max(0,h.life));
ctx.font = 'bold 20px Georgia'; ctx.textAlign = 'center';
for (const f of floats){
ctx.globalAlpha = f.life; ctx.fillStyle = '#fff';
ctx.fillText(f.txt, f.x, f.y); ctx.globalAlpha = 1;
}
drawBurger(paddleX);
// ball — a little heart!
drawHeart(ball.x, ball.y + 6, 18, 0, '#ff3d7f', 1);
drawHeart(ball.x, ball.y + 5, 11, 0, '#ff8fb8', 1);
if (ball.stuck){
ctx.fillStyle = '#ffd9ec'; ctx.font = '16px Georgia';
ctx.fillText('Click to launch the heart!', W/2, H-110);
}
}
function loop(){ update(); render(); requestAnimationFrame(loop); }
loop();
function start(){
if (playing) return;
playing = true; demo = false;
overlay.classList.add('hidden');
lives = 3; score = 0;
scoreEl.textContent = 0; livesEl.textContent = 3;
buildBricks(); resetBall(1);
}
overlay.addEventListener('click', start);
window.addEventListener('keydown', e => {
if (!playing){ start(); return; }
if (e.key === 'ArrowLeft') targetX = paddleX - 90;
if (e.key === 'ArrowRight') targetX = paddleX + 90;
if (e.key === ' ' && ball.stuck){ ball.stuck = false; resetBall(1); }
});
cv.addEventListener('mousemove', e => {
const r = cv.getBoundingClientRect();
targetX = (e.clientX - r.left) * (W / r.width);
});
overlay.addEventListener('mousemove', e => {
if (demo){
const r = cv.getBoundingClientRect();
// keep AI in demo
}
});
cv.addEventListener('click', () => { if (playing && ball.stuck) ball.stuck = false; });
// gentle idle drift so demo looks alive
setInterval(()=>{ if (demo && !ball.stuck) {} }, 1000);
</script>
</body>
</html>Reasoning trace (34 tokens)
Make a canvas breakout game: paddle = hamburger (drawn with arcs), bricks explode into heart particles. Self-playing demo mode, click/key to start.