A creation from the community
Clap Cat Court
Made by ArkheOS
A playable Snake × Pong mashup with an original black cat judge. Miss a ball and the cat claps; your next serve splits into two. Catch cleanly to quiet the judge and earn a bonus. Remix of Merge Lab by ArkheOS.
Make your version
Play this widget, then change its rules, look, or purpose with Widget Canvas in ChatGPT.
Copy the selected request. In ChatGPT, choose “Try in chat,” replace the example prompt, and paste it.
You are exploring the published defaults. Changes here stay in this browser and do not change the creator’s work.
Follow the remix chain
- Merge Lab
Made by ArkheOS - Clap Cat Court
Made by ArkheOS
View published code
HTML
<main id="lab"><header><div><span class="eyebrow">SNAKE × PONG / FELINE COURT</span><h1>Clap Cat Court</h1></div><button id="sound" aria-pressed="false">Sound off</button></header><div class="stats"><div>SCORE <strong id="score">0</strong></div><div>BEST <strong id="best">0</strong></div><div>LIVES <strong id="lives">● ● ●</strong></div></div><div class="label"><span><i class="mint"></i>01 SNAKE</span><small>orb = +10 + segment + ball</small></div><div class="scene"><canvas id="snake" width="360" height="220" aria-label="Snake chamber. Hold the turn buttons to steer."></canvas><div id="intro"><b>The judge is watching.</b><span>Hold a turn button to begin ↙</span></div></div><div class="turns"><button id="left" aria-label="Turn snake left">↶ <span>TURN LEFT</span></button><button id="right" aria-label="Turn snake right"><span>TURN RIGHT</span> ↷</button></div><div class="connector"><span>GROW</span><b>↓ ORB TRANSFER ↓</b><span>DEFLECT</span></div><section class="court" aria-label="Black cat judge"><div class="judge"><svg id="cat" viewBox="0 0 180 116" role="img" aria-label="Original black cat judge with visible clapping paws"><path d="M41 109 Q35 83 50 73 L48 24 L69 40 Q90 32 111 40 L134 24 L129 73 Q145 90 139 109Z" fill="#080d15" stroke="#667284" stroke-width="2"/><path d="M53 33L65 44L54 48M128 33L116 44L127 48" fill="#a57a8b"/><path d="M57 57Q66 50 77 57M103 57Q114 50 123 57" fill="none" stroke="#d9f596" stroke-width="5" stroke-linecap="round"/><path d="M67 52L68 61M113 52L112 61" stroke="#0a1320" stroke-width="3"/><path d="M85 68L95 68L90 73Z" fill="#d9a7b6"/><path d="M90 73v5m0-1q-7 7-12 0m12 0q7 7 12 0M61 70L39 65m22 11L37 77m82-7 22-5m-22 11 24 1" fill="none" stroke="#99a7b4" stroke-width="1.5"/><path d="M71 91L90 82L109 91L104 110H76Z" fill="#2d3a4e"/><path d="M90 84v25" stroke="#d8bc85" stroke-width="3"/><g id="pawL"><path d="M60 110Q45 104 57 88Q67 75 78 88L86 99Q85 113 60 110Z" fill="#171f2b" stroke="#91a0ae" stroke-width="2"/><path d="M60 89l5 5m2-9 5 6m3-5 4 6" stroke="#c3a0b0" stroke-width="2"/></g><g id="pawR"><path d="M120 110Q135 104 123 88Q113 75 102 88L94 99Q95 113 120 110Z" fill="#171f2b" stroke="#91a0ae" stroke-width="2"/><path d="M120 89l-5 5m-2-9-5 6m-3-5-4 6" stroke="#c3a0b0" stroke-width="2"/></g><path d="M16 113h148" stroke="#bb8f73" stroke-width="5" stroke-linecap="round"/></svg><div><span class="eyebrow">JUDGE INK / ORIGINAL ART</span><b id="verdict" aria-live="polite">Waiting for your serve.</b><span id="split">SPLITS 0 · NEXT: SINGLE</span></div></div><div class="rule">CAT CLAPS → NEXT BALL SPLITS</div><p>Miss: −1 life + two-ball next serve.<br>Clean catch: cat freezes +5 quiet bonus.</p></section><div class="label"><span><i class="gold"></i>02 PONG</span><small>catch +25 / quiet bonus +5</small></div><canvas id="pong" width="360" height="160" tabindex="0" aria-label="Pong chamber. Drag to move the paddle."></canvas><div id="strip" role="slider" tabindex="0" aria-label="Paddle position" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50"><span>← DRAG PADDLE →</span><b id="thumb"></b></div><footer><span class="mark">ARKHEOS</span><span id="status" role="status">Steer → collect → catch</span><button id="restart">Restart ↻</button></footer><p class="keys">Keys: A/D turn · ←/→ paddle · Space pause</p><a class="credit" href="https://widgets.arkheos.ai/community/widgets/28cb917a-fb20-4341-a081-7d87dfc072d8" target="_blank" rel="noopener">Remix of Merge Lab · by ArkheOS</a></main>
CSS
*{box-sizing:border-box}body{margin:0;color:#e9f3f1;font-family:ui-sans-serif,system-ui,sans-serif;background:#0c141b}#lab{width:100%;max-width:460px;margin:auto;padding:16px;background:radial-gradient(ellipse at 10% 0%,#233b40,#111d27 60%);border:1px solid #36505c;border-radius:20px;overflow:hidden}header{display:flex;justify-content:space-between;align-items:center;gap:8px}.eyebrow{font-size:9px;letter-spacing:1.7px;color:#92aeb6}h1{font-size:29px;letter-spacing:-1px;margin:3px 0 13px}.dot{color:#bbf578;font-size:23px;margin-left:10px}button{font:inherit;cursor:pointer;touch-action:none;color:inherit;background:#213540;border:1px solid #42606c;border-radius:10px;min-height:44px}button:focus-visible,#strip:focus-visible{outline:2px solid #d7ff91;outline-offset:2px}#sound{font-size:10px;padding:0 10px;margin-top:-8px;white-space:nowrap}.stats{display:flex;border:1px solid #354d57;border-radius:10px;padding:10px 12px;justify-content:space-between;background:#0c1820;margin-bottom:16px}.stats div{font-size:9px;letter-spacing:1px;color:#93abb4}.stats strong{display:block;font-size:21px;letter-spacing:0;color:#f1f7ec;line-height:1.3}#lives{font-size:16px;color:#ffb98d;padding-top:4px}.label{display:flex;justify-content:space-between;align-items:center;margin:8px 0;font-size:10px;font-weight:800;letter-spacing:1px}.label small{font-size:9px;color:#9fb2bb;letter-spacing:0;font-weight:500}i{display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:6px}.mint{background:#b9f480}.gold{background:#ffbd7b}canvas{display:block;width:100%;background:#0c171f;border:1px solid #314b58;border-radius:12px}#snake{aspect-ratio:360/220}.scene{position:relative}#intro{position:absolute;left:12px;right:12px;top:12px;display:flex;flex-direction:column;gap:4px;font-size:12px;pointer-events:none}#intro span{color:#b9f480;font-size:10px}.turns{display:flex;gap:10px;margin-top:9px}.turns button{flex:1;font-size:27px;color:#c6f795;min-height:52px;display:flex;align-items:center;justify-content:center;gap:10px;background:#203d36}.turns span{font-size:10px;font-weight:800;letter-spacing:.5px}.turns button:active,.turns button.held{background:#355d43}.connector{display:flex;justify-content:space-between;padding:11px 10px 4px;font-size:8px;letter-spacing:1px;color:#6a8c9a}.connector b{color:#aac3cb;font-weight:500}#pong{aspect-ratio:360/160;touch-action:none}#strip{position:relative;height:44px;background:#293b46;border:1px solid #4f6270;border-radius:10px;margin-top:8px;touch-action:none;cursor:ew-resize;overflow:hidden;text-align:center;user-select:none}#strip span{font-size:9px;letter-spacing:2px;line-height:42px;color:#b6c7ce}#thumb{position:absolute;left:50%;bottom:4px;width:28px;height:3px;border-radius:3px;background:#ffbf83;transform:translateX(-50%)}footer{display:flex;align-items:center;justify-content:space-between;gap:7px;margin-top:12px}.mark{font-size:10px;font-weight:1000;letter-spacing:1px;border:1px solid #8097a0;padding:4px 5px;color:#b2c6cc}#status{font-size:9px;color:#b9c9cb;max-width:130px}#restart{font-size:10px;padding:0 10px;min-height:44px}.keys{font-size:9px;color:#728e9c;text-align:center;margin:7px 0 0}@media(max-width:340px){#lab{padding:12px;border-radius:14px}.label small{font-size:8px}h1{font-size:27px}.stats{padding:9px}#status{max-width:95px;font-size:8px}.turns{gap:8px}.turns span{font-size:9px}.mark{font-size:8px}}h1{font-size:25px;line-height:1.15;letter-spacing:-.7px}header>div{min-width:0}#lab{background:radial-gradient(ellipse at 10% 0%,#353547,#131e2b 60%)}.court{margin-top:8px;background:#202435;border:1px solid #586174;border-radius:12px;padding:8px 10px}.judge{display:flex;align-items:center;gap:9px}.judge svg{width:115px;height:82px;flex:0 0 115px;overflow:visible}.judge>div{display:flex;flex-direction:column;gap:6px;min-width:0}.judge .eyebrow{font-size:8px;letter-spacing:.6px}.judge b{font-size:12px;line-height:1.25;color:#eee7da}#split{font:700 10px ui-monospace,monospace;color:#ffcf95}.rule{font-size:12px;font-weight:900;letter-spacing:.2px;color:#ffe1b0;text-align:center;border-top:1px solid #4d4b60;padding-top:8px;margin-top:5px}.court p{font-size:10px;line-height:1.5;color:#bdc7d3;text-align:center;margin:5px 0 0}.credit{display:block;color:#9caeba;text-align:center;font-size:10px;margin-top:9px;text-decoration:underline;min-height:24px}#cat.clapping{filter:drop-shadow(0 0 4px #ffbd7b66)}#cat.frozen{filter:drop-shadow(0 0 3px #c5e6ff55)}@media(max-width:340px){h1{font-size:22px}.judge svg{width:100px;flex-basis:100px}.rule{font-size:11px}.judge b{font-size:11px}}@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}#cat{filter:none!important}}JavaScript
(()=>{
'use strict';
const $=id=>document.getElementById(id),a=$('snake').getContext('2d'),b=$('pong').getContext('2d'),bridge=typeof WidgetCanvas!=='undefined'?WidgetCanvas:null;
let score=0,best=0,sound=false,running=false,over=false,life=3,angle=0,head,body,orb,balls=[],paddle=180,turn=0,keys={},last=0,acc=0,cool=0,flash=0,clock=0,audio;
let pendingSplit=false,splitCount=0,catMood='watch',clapUntil=0;const reduced=window.matchMedia('(prefers-reduced-motion: reduce)');
const clamp=(x,l,h)=>Math.max(l,Math.min(h,x));
function save(){if(bridge)try{Promise.resolve(bridge.setState({id:'clap-cat-court-v1',score,best,sound,splitCount,pendingSplit})).catch(()=>{});}catch(e){}}
function restore(q){if(q&&q.id==='clap-cat-court-v1'){score=Number.isFinite(q.score)?clamp(Math.floor(q.score),0,1e8):0;best=Number.isFinite(q.best)?Math.max(score,clamp(Math.floor(q.best),0,1e8)):score;sound=!!q.sound;splitCount=Number.isInteger(q.splitCount)?clamp(q.splitCount,0,1e6):0;pendingSplit=!!q.pendingSplit;hud();}}
function hud(){$('split').textContent='SPLITS '+splitCount+' · NEXT: '+(pendingSplit?'DOUBLE':'SINGLE');$('score').textContent=score;$('best').textContent=best;$('lives').textContent=Array.from({length:3},(_,i)=>i<life?'●':'○').join(' ');$('sound').textContent=sound?'Sound on':'Sound off';$('sound').setAttribute('aria-pressed',String(sound));}
function tone(f){if(!sound)return;try{audio=audio||new (window.AudioContext||window.webkitAudioContext)();audio.resume();const o=audio.createOscillator(),g=audio.createGain();o.type='sine';o.frequency.value=f;g.gain.setValueAtTime(.06,audio.currentTime);g.gain.exponentialRampToValueAtTime(.001,audio.currentTime+.13);o.connect(g);g.connect(audio.destination);o.start();o.stop(audio.currentTime+.14);}catch(e){}}
function clapSound(){if(!sound)return;try{audio=audio||new (window.AudioContext||window.webkitAudioContext)();audio.resume();for(let k=0;k<2;k++){const buffer=audio.createBuffer(1,Math.floor(audio.sampleRate*.065),audio.sampleRate),data=buffer.getChannelData(0);for(let i=0;i<data.length;i++)data[i]=(Math.random()*2-1)*Math.exp(-i/(audio.sampleRate*.012));const src=audio.createBufferSource(),filter=audio.createBiquadFilter(),gain=audio.createGain();src.buffer=buffer;filter.type='bandpass';filter.frequency.value=1450;filter.Q.value=.65;gain.gain.value=.3;src.connect(filter);filter.connect(gain);gain.connect(audio.destination);src.start(audio.currentTime+k*.14);}}catch(e){}}
function applaud(){pendingSplit=true;catMood='clap';clapUntil=clock+.9;$('verdict').textContent='Clap clap. Next serve: DOUBLE!';clapSound();hud();save();}
function launchOrb(){const velocity=83+Math.min(score*.08,35),x=orb.x,vx=(x-180)*.36;if(pendingSplit){pendingSplit=false;splitCount++;balls.push({x:x-6,y:20,vx:vx-23,vy:velocity,split:true},{x:x+6,y:20,vx:vx+23,vy:velocity,split:true});$('status').textContent='+10 · TWO BALLS launched!';$('verdict').textContent='Split verdict served. Catch both!';}else{balls.push({x,y:20,vx,vy:velocity});$('status').textContent='+10 · segment + ball!';}hud();save();}
function add(n){score+=n;best=Math.max(best,score);hud();save();}
function resetSnake(){head={x:85,y:125};angle=0;body=Array.from({length:5},(_,i)=>({x:85-i*9,y:125}));orb={x:145,y:125};}
function restart(){score=0;life=3;pendingSplit=false;splitCount=0;catMood='watch';clapUntil=0;acc=0;$('verdict').textContent='Waiting for your serve.';over=false;running=false;balls=[];paddle=180;turn=0;keys={};cool=0;resetSnake();$('intro').style.display='flex';$('intro').innerHTML='<b>The judge is watching.</b><span>Hold a turn button to begin ↙</span>';$('status').textContent='Steer → collect → catch';hud();save();draw();}
function begin(){if(over)return;if(!running){running=true;$('intro').style.display='none';$('status').textContent='Collect green. Catch gold.';last=0;}}
function miss(message,ballMiss=false){if(over)return;life--;flash=reduced.matches?0:.5;if(ballMiss)applaud();else tone(130);hud();save();$('status').textContent=message;if(life<=0){over=true;running=false;$('intro').style.display='flex';$('intro').innerHTML='<b>Experiment complete · '+score+' points</b><span>Tap Restart for another run</span>';}}
function step(dt){clock+=dt;flash=Math.max(0,flash-dt);if(!running||over)return;cool=Math.max(0,cool-dt);angle+=((keys.d?1:0)-(keys.a?1:0)||turn)*2.8*dt;head.x+=Math.cos(angle)*68*dt;head.y+=Math.sin(angle)*68*dt;
// Lab walls wrap; the snake's body remains a hazard.
if(head.x<8)head.x=352;if(head.x>352)head.x=8;if(head.y<58)head.y=212;if(head.y>212)head.y=58;
acc+=dt;if(acc>=.075){acc-=.075;body.unshift({...head});body.pop();}
if(cool===0&&body.slice(12).some(p=>Math.hypot(head.x-p.x,head.y-p.y)<8)){miss('Snake collision · −1 life');resetSnake();cool=1.4;}
if(Math.hypot(head.x-orb.x,head.y-orb.y)<13){add(10);body.push({...body[body.length-1]});launchOrb();tone(660);let tries=0;do{orb={x:26+Math.random()*308,y:76+Math.random()*118};}while(++tries<30&&body.some(p=>Math.hypot(p.x-orb.x,p.y-orb.y)<26));}
paddle=clamp(paddle+((keys.ArrowRight?1:0)-(keys.ArrowLeft?1:0))*235*dt,37,323);
for(let i=balls.length-1;i>=0;i--){let p=balls[i],old=p.y;p.x+=p.vx*dt;p.y+=p.vy*dt;if(p.x<6){p.x=6;p.vx=Math.abs(p.vx);}if(p.x>354){p.x=354;p.vx=-Math.abs(p.vx);}if(p.vy>0&&old+5<=135&&p.y+5>=135&&Math.abs(p.x-paddle)<=39){p.y=130;p.vy=-Math.abs(p.vy)*1.25;p.vx=(p.x-paddle)*2;catMood='frozen';clapUntil=0;add(30);$('verdict').textContent='Frozen. Quiet bonus +5.';$('status').textContent='+25 catch +5 quiet bonus';}if(p.y< -8){balls.splice(i,1);}else if(p.y>167){balls.splice(i,1);miss('Ball missed · next serve splits!',true);if(over)break;}}
$('thumb').style.left=(paddle/360*100)+'%';$('strip').setAttribute('aria-valuenow',String(Math.round(paddle/360*100)));
}
function drawCat(){const clapping=catMood==='clap'&&clock<clapUntil;const squeeze=clapping?(reduced.matches?10:7+7*Math.sin(clock*25)):0;$('pawL').setAttribute('transform','translate('+squeeze+' '+(clapping?-5:0)+')');$('pawR').setAttribute('transform','translate('+(-squeeze)+' '+(clapping?-5:0)+')');$('cat').setAttribute('class',clapping?'clapping':catMood==='frozen'?'frozen':'');}
function circle(c,x,y,r,col){c.fillStyle=col;c.beginPath();c.arc(x,y,r,0,7);c.fill();}
function rr(c,x,y,w,h,r,col){c.fillStyle=col;c.beginPath();c.roundRect(x,y,w,h,r);c.fill();}
function grid(c,h){c.clearRect(0,0,360,h);c.strokeStyle='#1c303a';c.lineWidth=1;for(let x=18;x<360;x+=24)for(let y=18;y<h;y+=24){c.beginPath();c.moveTo(x-2,y);c.lineTo(x+2,y);c.moveTo(x,y-2);c.lineTo(x,y+2);c.stroke();}}
function draw(){drawCat();grid(a,220);a.font='9px monospace';a.fillStyle='#607f8c';a.fillText('↔ WRAP WALLS / AVOID YOUR TAIL',12,20);
a.strokeStyle='#b9f480';a.lineWidth=1.5;a.beginPath();a.arc(orb.x,orb.y,13+(reduced.matches?0:Math.sin(clock*4)*2),0,7);a.stroke();circle(a,orb.x,orb.y,7,'#bef587');a.fillStyle='#102a22';a.fillRect(orb.x-3,orb.y-1,6,2);a.fillRect(orb.x-1,orb.y-3,2,6);
body.slice().reverse().forEach((p,i)=>circle(a,p.x,p.y,6,'hsl(143, '+(30+i/body.length*30)+'%, '+(25+i/body.length*30)+'%)'));
a.save();a.translate(head.x,head.y);a.rotate(angle);rr(a,-9,-8,18,16,6,cool>0?'#f4ca90':'#d1ff9a');circle(a,3,-4,1.6,'#163528');circle(a,3,4,1.6,'#163528');a.restore();
grid(b,160);b.font='9px monospace';b.fillStyle='#8a7965';b.fillText('ORB IN →',12,18);b.setLineDash([4,5]);b.strokeStyle='#553b32';b.beginPath();b.moveTo(0,154);b.lineTo(360,154);b.stroke();b.setLineDash([]);
if(!balls.length){b.fillStyle='#678591';b.textAlign='center';b.font='11px system-ui';b.fillText('Collect an orb above to launch a ball',180,69);b.textAlign='left';}
balls.forEach(p=>{b.strokeStyle='#d99e6650';b.lineWidth=3;b.beginPath();b.moveTo(p.x,p.y);b.lineTo(p.x-p.vx*.1,p.y-p.vy*.1);b.stroke();circle(b,p.x,p.y,5,p.split?'#d9b5ff':'#ffd39a');});
rr(b,paddle-34,135,68,9,4,'#ffb879');rr(b,paddle-27,136,54,2,1,'#ffe6bb');if(flash>0&&!reduced.matches){a.fillStyle=b.fillStyle='rgba(255,111,100,'+flash*.28+')';a.fillRect(0,0,360,220);b.fillRect(0,0,360,160);}
}
for(const [id,dir] of [['left',-1],['right',1]]){const el=$(id);el.addEventListener('pointerdown',e=>{e.preventDefault();el.setPointerCapture(e.pointerId);turn=dir;el.classList.add('held');begin();tone(320);});for(const event of ['pointerup','pointercancel','lostpointercapture'])el.addEventListener(event,()=>{if(turn===dir)turn=0;el.classList.remove('held');});}
for(const id of ['pong','strip']){const el=$(id);let active=null;function move(e){const r=el.getBoundingClientRect();paddle=clamp((e.clientX-r.left)/r.width*360,37,323);draw();}el.addEventListener('pointerdown',e=>{if(e.pointerType==='touch'&&e.clientX<48)return;e.preventDefault();active=e.pointerId;el.setPointerCapture(active);move(e);});el.addEventListener('pointermove',e=>{if(active===e.pointerId)move(e);});for(const ev of ['pointerup','pointercancel','lostpointercapture'])el.addEventListener(ev,()=>active=null);}
document.addEventListener('keydown',e=>{if(['a','d','ArrowLeft','ArrowRight',' '].includes(e.key)){e.preventDefault();if(e.key===' '&&!e.repeat){running=!running&&!over;$('status').textContent=running?'Collect green. Catch gold.':'Paused · Space resumes';}else if(e.key!==' '){keys[e.key]=true;begin();}}});document.addEventListener('keyup',e=>delete keys[e.key]);
$('restart').onclick=restart;$('sound').onclick=()=>{sound=!sound;tone(520);hud();save();};
window.addEventListener('blur',()=>{keys={};turn=0;running=false;$('status').textContent=over?'Experiment complete':'Paused · turn to resume';save();});
document.addEventListener('visibilitychange',()=>{last=0;if(document.hidden){running=false;turn=0;keys={};save();}});
resetSnake();if(bridge)try{restore(bridge.getState());bridge.setControlsPosition('top-right');bridge.setResetEnabled(false);bridge.setSharingEnabled(false);}catch(e){}
window.addEventListener('widgetcanvas:restore',e=>restore(e.detail));hud();draw();
function loop(t){let dt=last?Math.min((t-last)/1000,.04):0;last=t;let n=Math.ceil(dt/(1/120));for(let i=0;i<n;i++)step(dt/n);draw();requestAnimationFrame(loop);}requestAnimationFrame(loop);
})();