let snakeTimer = null; let pongTimer = null; let snakeState = null; let pongState = null; let tttBoard = Array(9).fill(""); function stopRetroGames() { if (snakeTimer) clearInterval(snakeTimer); if (pongTimer) clearInterval(pongTimer); snakeTimer = null; pongTimer = null; snakeState = null; pongState = null; } function startRetroGame(game) { stopRetroGames(); openApp(); const area = $("gameArea"); area.replaceChildren(); if (game === "snake") { $("gameTitle").textContent = "🐍 Snake"; area.innerHTML = `
Use the arrow keys to move. Don't hit the walls or yourself!
Score: 0
`; const canvas = $("snakeCanvas"); const ctx = canvas.getContext("2d"); snakeState = { snake: [{x:8,y:7},{x:7,y:7},{x:6,y:7}], dir: {x:1,y:0}, next: {x:1,y:0}, food: {x:13,y:8}, score: 0, over: false }; function drawSnake() { if (!snakeState) return; const s = snakeState; ctx.fillStyle = "#101810"; ctx.fillRect(0,0,400,300); ctx.fillStyle = "#ff4040"; ctx.fillRect(s.food.x*20,s.food.y*20,18,18); s.snake.forEach((p,i) => { ctx.fillStyle = i === 0 ? "#8aff70" : "#39b82c"; ctx.fillRect(p.x*20,p.y*20,18,18); }); $("snakeScore").textContent = "Score: " + s.score + (s.over ? " — Game over! Restart to play again." : ""); } function tickSnake() { const s = snakeState; if (!s || s.over) return; s.dir = s.next; const head = { x: s.snake[0].x+s.dir.x, y: s.snake[0].y+s.dir.y }; const eating = head.x === s.food.x && head.y === s.food.y; const body = eating ? s.snake : s.snake.slice(0,-1); if (head.x<0 || head.x>=20 || head.y<0 || head.y>=15 || body.some(p=>p.x===head.x && p.y===head.y)) { s.over = true; drawSnake(); return; } s.snake.unshift(head); if (eating) { s.score += 10; do { s.food = { x: Math.floor(Math.random()*20), y: Math.floor(Math.random()*15) }; } while (s.snake.some(p=>p.x===s.food.x && p.y===s.food.y)); } else { s.snake.pop(); } drawSnake(); } window.onkeydown = function(e) { if (!snakeState || snakeState.over) return; const dirs = { ArrowUp:{x:0,y:-1}, ArrowDown:{x:0,y:1}, ArrowLeft:{x:-1,y:0}, ArrowRight:{x:1,y:0} }; const d = dirs[e.key]; if (!d) return; e.preventDefault(); const current = snakeState.dir; if (d.x === -current.x && d.y === -current.y) return; snakeState.next = d; }; drawSnake(); snakeTimer = setInterval(tickSnake,130); } if (game === "ttt") { $("gameTitle").textContent = "⭕ Tic-Tac-Toe"; tttBoard = Array(9).fill(""); drawTicTacToe(); } if (game === "pong") { $("gameTitle").textContent = "🏓 Pong"; area.innerHTML = `Move your mouse over the game or use ↑ and ↓ to control your paddle.
You 0 — 0 CPU
`; const canvas = $("pongCanvas"); const ctx = canvas.getContext("2d"); pongState = { y:120, ballX:240, ballY:150, vx:3, vy:2, player:0, cpu:0, up:false, down:false, over:false }; canvas.addEventListener("mousemove",e=>{ if (!pongState) return; const rect = canvas.getBoundingClientRect(); pongState.y = (e.clientY-rect.top)*canvas.height/rect.height-35; pongState.y = Math.max(0,Math.min(230,pongState.y)); }); window.onkeydown = e => { if (!pongState) return; if (e.key==="ArrowUp") { pongState.up=true; e.preventDefault(); } if (e.key==="ArrowDown") { pongState.down=true; e.preventDefault(); } }; window.onkeyup = e => { if (!pongState) return; if (e.key==="ArrowUp") pongState.up=false; if (e.key==="ArrowDown") pongState.down=false; }; function tickPong() { const p = pongState; if (!p) return; if (p.up) p.y-=5; if (p.down) p.y+=5; p.y=Math.max(0,Math.min(230,p.y)); p.ballX+=p.vx; p.ballY+=p.vy; if (p.ballY<5 || p.ballY>295) p.vy=-p.vy; const cpuY = p.ballY-35; const paddleY = Math.max(0,Math.min(230,cpuY)); if (p.ballX>445 && p.ballY>paddleY && p.ballYYour turn: X
`; const grid = $("tttGrid"); tttBoard.forEach((value,i)=>{ const b=document.createElement("button"); b.textContent=value || " "; b.style.height="70px"; b.style.fontSize="28px"; b.disabled=!!value || !!tttWinner(); b.onclick=()=>{ if(tttBoard[i] || tttWinner())return; tttBoard[i]="X"; if(!tttWinner() && tttBoard.some(v=>!v)){ const available=tttBoard.map((v,j)=>v?null:j).filter(v=>v!==null); const move=available[Math.floor(Math.random()*available.length)]; tttBoard[move]="O"; } drawTicTacToe(); }; grid.appendChild(b); }); const winner=tttWinner(); $("tttStatus").textContent=winner ? (winner==="Draw"?"It's a draw!":winner+" wins!") : "You are X. The computer is O."; } function tttWinner() { const lines=[ [0,1,2],[3,4,5],[6,7,8], [0,3,6],[1,4,7],[2,5,8], [0,4,8],[2,4,6] ]; for(const line of lines){ const [a,b,c]=line; if(tttBoard[a] && tttBoard[a]===tttBoard[b] && tttBoard[a]===tttBoard[c]){ return tttBoard[a]; } } return tttBoard.every(Boolean)?"Draw":null; }