Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Buff Man: The Full Saga</title> <style> body { background-color: #1a1a1a; color: white; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; min-height: 100vh; margin: 0; font-family: 'Courier New', Courier, monospace; overflow: hidden; user-select: none; touch-action: manipulation; } h1 { margin: 10px 0; font-size: 18px; color: #aaa; text-transform: uppercase; } /* HUD */ #hud { display: flex; justify-content: space-between; width: 440px; padding: 8px; background: #000; border: 2px solid #444; border-bottom: none; box-sizing: border-box; font-weight: bold; visibility: hidden; } .lives { color: #ff3333; letter-spacing: 2px; } .key-slot { color: #555; } .key-active { color: #ffd700; text-shadow: 0 0 10px #ffd700; } .gum-active { color: #d000ff; animation: pulse 0.5s infinite alternate; } @keyframes pulse { from { opacity: 1; } to { opacity: 0.5; } } /* GAME AREA */ .game-container { position: relative; width: 440px; height: 440px; } canvas { background-color: #000; border: 4px solid #444; box-shadow: 0 0 20px rgba(0,0,0,0.8); image-rendering: pixelated; display: block; } /* OVERLAYS */ #start-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.9); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 20; border: 4px solid #444; box-sizing: border-box; } #start-btn { padding: 15px 30px; font-size: 24px; font-family: 'Courier New', Courier, monospace; font-weight: bold; background: #ff3333; color: white; border: none; border-radius: 5px; cursor: pointer; text-transform: uppercase; box-shadow: 0 0 10px red; display: none; } #start-btn:hover { background: #ff6666; transform: scale(1.05); } #loading-txt { font-size: 18px; color: #888; animation: blink 1s infinite; } @keyframes blink { 50% { opacity: 0.5; } } #msg { position: absolute; top: 180px; width: 100%; text-align: center; font-size: 24px; font-weight: bold; color: white; text-shadow: 2px 2px 0 #000; pointer-events: none; opacity: 0; transition: opacity 0.3s; z-index: 10; } /* CONTROLS */ .controls { margin-top: 15px; display: grid; grid-template-columns: repeat(3, 60px); grid-template-rows: repeat(2, 60px); gap: 5px; justify-items: center; } .btn { width: 60px; height: 60px; background: #333; border: 2px solid #555; border-radius: 10px; color: white; font-size: 24px; display: flex; justify-content: center; align-items: center; cursor: pointer; } .btn:active { background: #555; transform: scale(0.95); } .btn-up { grid-column: 2; grid-row: 1; } .btn-left { grid-column: 1; grid-row: 2; } .btn-down { grid-column: 2; grid-row: 2; } .btn-right { grid-column: 3; grid-row: 2; } </style> </head> <body> <h1>Buff Man Saga</h1> <div id="hud"> <div class="stat"><span id="lives-txt" class="lives">❤️❤️❤️</span></div> <div class="stat"><span id="key-icon" class="key-slot">🗝️ NEED KEY</span></div> <div class="stat"><span id="gum-txt" style="display:none">IMMORTAL: <span id="timer-val">0</span>s</span></div> </div> <div class="game-container"> <div id="msg">LOCKED!</div> <div id="start-screen"> <h2 style="font-size: 30px; margin-bottom: 10px; color:white;">BUFF MAN</h2> <p style="color:#aaa; margin-bottom: 30px; font-size: 14px;">The Romance & The Twist</p> <div id="loading-txt">LOADING...</div> <button id="start-btn" onclick="startGame()">START GAME</button> </div> <canvas id="gameCanvas" width="440" height="440"></canvas> </div> <div class="controls"> <div class="btn btn-up" onclick="move(0, -1)">▲</div> <div class="btn btn-left" onclick="move(-1, 0)">◀</div> <div class="btn btn-down" onclick="move(0, 1)">▼</div> <div class="btn btn-right" onclick="move(1, 0)">▶</div> </div> <script> const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const ui = { lives: document.getElementById('lives-txt'), key: document.getElementById('key-icon'), gum: document.getElementById('gum-txt'), timer: document.getElementById('timer-val'), msg: document.getElementById('msg'), hud: document.getElementById('hud'), startScreen: document.getElementById('start-screen'), startBtn: document.getElementById('start-btn'), loadTxt: document.getElementById('loading-txt') }; const TILE = 40; const GRID_W = 11; const GRID_H = 11; const SPEED_NORMAL = 0.2; const SPEED_BOOST = 0.4; /** ASSETS **/ const svgHero = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 450" width="${TILE}" height="${TILE}"><path d="M 80 150 C 50 150 50 50 150 50 C 250 50 250 150 220 180 C 200 230 100 230 80 150 Z" stroke="white" stroke-width="20" fill="none"/><path d="M 110 215 L 100 290 Q 150 300 200 290 L 190 215" stroke="white" stroke-width="20" fill="none"/><path d="M 110 220 C 60 220 90 220 40 220 L 40 180" stroke="white" stroke-width="20" fill="none"/><path d="M 190 220 C 240 220 210 220 260 220 L 260 200" stroke="white" stroke-width="20" fill="none"/><path d="M 110 290 L 80 380" stroke="white" stroke-width="20" fill="none"/><path d="M 190 290 L 220 380" stroke="white" stroke-width="20" fill="none"/></svg>`; // Small Baby (Hero scaled down) const svgBaby = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 450" width="${TILE}" height="${TILE}"><g transform="scale(0.8, 0.8) translate(50, 50)"><path d="M 150 50 C 100 50 100 150 150 150 C 200 150 200 50 150 50 Z" stroke="white" stroke-width="25" fill="none"/><line x1="150" y1="150" x2="150" y2="250" stroke="white" stroke-width="25"/><line x1="150" y1="250" x2="100" y2="350" stroke="white" stroke-width="25"/><line x1="150" y1="250" x2="200" y2="350" stroke="white" stroke-width="25"/><line x1="80" y1="200" x2="220" y2="200" stroke="white" stroke-width="25"/></g></svg>`; const svgPrincess = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 450" width="${TILE}" height="${TILE}"><path d="M 150 140 L 50 380 L 250 380 Z" fill="#ff69b4" stroke="white" stroke-width="10"/><circle cx="150" cy="90" r="50" fill="white"/><path d="M 100 50 L 125 20 L 150 50 L 175 20 L 200 50" stroke="gold" stroke-width="10" fill="none"/><path d="M 135 100 L 135 130" stroke="#00ffff" stroke-width="8"/><path d="M 165 100 L 165 130" stroke="#00ffff" stroke-width="8"/></svg>`; const svgBhanu = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 450" width="${TILE}" height="${TILE}"><circle cx="150" cy="150" r="60" stroke="white" stroke-width="15" fill="none"/><line x1="150" y1="210" x2="150" y2="350" stroke="white" stroke-width="15"/><line x1="150" y1="350" x2="100" y2="440" stroke="white" stroke-width="15"/><line x1="150" y1="350" x2="200" y2="440" stroke="white" stroke-width="15"/><line x1="150" y1="250" x2="80" y2="220" stroke="white" stroke-width="15"/><line x1="150" y1="250" x2="220" y2="220" stroke="white" stroke-width="15"/><text x="150" y="80" font-family="monospace" font-size="60" fill="yellow" text-anchor="middle">BHANU</text></svg>`; const svgTerrorist = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 450" width="${TILE}" height="${TILE}"><circle cx="150" cy="100" r="60" fill="#333" stroke="red" stroke-width="8"/><rect x="110" y="80" width="80" height="20" fill="white"/><line x1="150" y1="160" x2="150" y2="300" stroke="white" stroke-width="20"/><line x1="150" y1="200" x2="260" y2="200" stroke="white" stroke-width="15"/><rect x="250" y="170" width="50" height="40" fill="#555"/><path d="M 150 300 L 100 400" stroke="white" stroke-width="20"/><path d="M 150 300 L 200 400" stroke="white" stroke-width="20"/></svg>`; const svgKey = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M 30 50 L 80 50 M 70 50 L 70 70 M 80 50 L 80 70" stroke="gold" stroke-width="10" stroke-linecap="round"/><circle cx="30" cy="50" r="15" stroke="gold" stroke-width="10" fill="none"/></svg>`; const svgFruit = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="55" r="30" fill="#bd00ff"/><path d="M 50 25 L 50 10" stroke="green" stroke-width="6"/></svg>`; const imgs = {}; function load(name, svg) { const i = new Image(); i.src = 'data:image/svg+xml;base64,' + btoa(svg); imgs[name] = i; } load('hero', svgHero); load('baby', svgBaby); load('princess', svgPrincess); load('bhanu', svgBhanu); load('terrorist', svgTerrorist); load('key', svgKey); load('fruit', svgFruit); /** GAME VARS **/ let level = 1; let lives = 3; let hasKey = false; let gumTimer = 0; let state = 'MENU'; let map = []; let items = []; let ghosts = []; const p = { x: 1, y: 1, vx: 1, vy: 1, tx: 1, ty: 1, moving: false, face: 1 }; const maps = { 1: [ [1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,0,0,1,0,0,0,1], [1,0,1,1,1,0,1,0,1,0,1], [1,0,1,0,0,0,0,0,1,0,1], [1,0,1,0,1,1,1,0,1,0,1], [1,0,0,0,0,0,0,0,0,0,1], [1,1,1,0,1,1,1,0,1,1,1], [1,0,0,0,0,0,1,0,0,0,1], [1,0,1,1,1,0,2,2,2,0,1], [1,0,0,0,0,0,2,0,2,0,1], [1,1,1,1,1,1,1,1,1,1,1] ], 2: [ [1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,1,0,0,0,0,0,1], [1,0,1,0,1,0,1,1,1,0,1], [1,0,1,0,0,0,0,0,1,0,1], [1,0,1,1,1,1,1,0,1,0,1], [1,0,0,0,0,0,0,0,0,0,1], [1,0,1,1,1,0,1,1,1,0,1], [1,0,0,0,0,0,0,0,0,0,1], [1,0,1,1,0,1,0,1,1,0,1], [1,0,0,0,0,1,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1,1] ] }; function showMsg(text, color="white") { ui.msg.innerText = text; ui.msg.style.color = color; ui.msg.style.opacity = 1; setTimeout(() => { ui.msg.style.opacity = 0; }, 2000); } function startGame() { ui.startScreen.style.display = 'none'; ui.hud.style.visibility = 'visible'; initLevel(1); } function updateHUD() { let h = ""; for(let i=0; i<lives; i++) h += "❤️"; ui.lives.innerText = h; if(hasKey) { ui.key.innerText = "🗝️ KEY FOUND"; ui.key.className = "key-slot key-active"; } else { ui.key.innerText = "🗝️ NEED KEY"; ui.key.className = "key-slot"; } if(gumTimer > 0) { ui.gum.style.display = 'inline'; ui.gum.className = "gum-active"; ui.timer.innerText = Math.ceil(gumTimer); } else { ui.gum.style.display = 'none'; } } function initLevel(lvl) { level = lvl; state = 'PLAY'; hasKey = false; p.x = 1; p.y = 1; p.vx = 1; p.vy = 1; p.tx = 1; p.ty = 1; p.moving = false; map = JSON.parse(JSON.stringify(maps[lvl])); items = []; ghosts = []; if(lvl === 1) { showMsg("LEVEL 1: SAVE PRINCESS"); items.push({x: 9, y: 1, type: 'key'}); items.push({x: 5, y: 5, type: 'fruit'}); items.push({x: 7, y: 9, type: 'princess'}); ghosts.push({x: 5, y: 3, type: 'ghost', speed: 0.04, dir: {x:0, y:1}, offX:0, offY:0}); ghosts.push({x: 8, y: 6, type: 'ghost', speed: 0.04, dir: {x:-1, y:0}, offX:0, offY:0}); } else if(lvl === 2) { showMsg("LEVEL 2: SAVE BHANU"); items.push({x: 1, y: 8, type: 'key'}); items.push({x: 9, y: 9, type: 'bhanu'}); ghosts.push({x: 8, y: 2, type: 'terrorist', speed: 0.07, dir: {x:0, y:1}, offX:0, offY:0}); ghosts.push({x: 5, y: 5, type: 'ghost', speed: 0.04, dir: {x:1, y:0}, offX:0, offY:0}); } updateHUD(); } function move(dx, dy) { if(state !== 'PLAY') return; if(!p.moving) { const nx = p.x + dx; const ny = p.y + dy; if(dx !== 0) p.face = dx; if(map[ny][nx] !== 1) { p.tx = nx; p.ty = ny; p.moving = true; } } } window.addEventListener('keydown', e => { if(state === 'OVER' && e.key === 'Enter') location.reload(); if(e.key === 'ArrowUp') move(0, -1); if(e.key === 'ArrowDown') move(0, 1); if(e.key === 'ArrowLeft') move(-1, 0); if(e.key === 'ArrowRight') move(1, 0); }); function gameLoop(dt) { if(state === 'PLAY') { if(gumTimer > 0) { gumTimer -= dt; updateHUD(); } if(p.moving) { const speed = (gumTimer > 0) ? SPEED_BOOST : SPEED_NORMAL; const dx = p.tx - p.vx; const dy = p.ty - p.vy; if(Math.abs(dx) < speed && Math.abs(dy) < speed) { p.vx = p.tx; p.vy = p.ty; p.x = p.tx; p.y = p.ty; p.moving = false; checkCollisions(); } else { p.vx += Math.sign(dx) * speed; p.vy += Math.sign(dy) * speed; } } ghosts.forEach(g => { if(g.offX === 0 && g.offY === 0) { const dirs = [{x:0, y:-1}, {x:0, y:1}, {x:-1, y:0}, {x:1, y:0}]; let valid = []; dirs.forEach(d => { if(d.x === -g.dir.x && d.y === -g.dir.y) return; if(map[g.y + d.y][g.x + d.x] !== 1) valid.push(d); }); if(valid.length > 0) { if(g.type === 'terrorist' && Math.random() > 0.2) { valid.sort((a,b) => (Math.abs((g.x+a.x)-p.x)+Math.abs((g.y+a.y)-p.y)) - (Math.abs((g.x+b.x)-p.x)+Math.abs((g.y+b.y)-p.y))); g.dir = valid[0]; } else g.dir = valid[Math.floor(Math.random() * valid.length)]; } else g.dir = {x: -g.dir.x, y: -g.dir.y}; } g.offX += g.dir.x * g.speed; g.offY += g.dir.y * g.speed; if(Math.abs(g.offX) >= 1 || Math.abs(g.offY) >= 1) { g.x += g.dir.x; g.y += g.dir.y; g.offX = 0; g.offY = 0; } if(Math.sqrt((p.vx-(g.x+g.offX))**2+(p.vy-(g.y+g.offY))**2) < 0.6) { if(gumTimer <= 0) die(); } }); } } function checkCollisions() { const idx = items.findIndex(i => i.x === p.x && i.y === p.y); if(idx !== -1) { const item = items[idx]; if(item.type === 'fruit') { gumTimer = 300; items.splice(idx, 1); showMsg("IMMORTAL!", "#d000ff"); } else if(item.type === 'key') { hasKey = true; items.splice(idx, 1); showMsg("GOT KEY!", "gold"); updateHUD(); } else if(item.type === 'princess') { if(hasKey) { showMsg("SAVED HER!"); setTimeout(() => initLevel(2), 1500); } else showMsg("LOCKED!", "red"); } else if(item.type === 'bhanu') { if(hasKey) { state = 'END'; playEnding(); } else showMsg("LOCKED!", "red"); } } } function die() { lives--; updateHUD(); showMsg("HIT! RESPAWNING...", "red"); p.x = 1; p.y = 1; p.vx = 1; p.vy = 1; p.tx = 1; p.ty = 1; p.moving = false; if(lives <= 0) state = 'OVER'; } function draw() { ctx.fillStyle = "#111"; ctx.fillRect(0, 0, canvas.width, canvas.height); if(state === 'MENU') return; for(let y=0; y<GRID_H; y++) { for(let x=0; x<GRID_W; x++) { const t = map[y][x]; const px = x*TILE; const py = y*TILE; if(t === 1) { ctx.fillStyle = "#333"; ctx.fillRect(px, py, TILE, TILE); ctx.strokeStyle = "#444"; ctx.strokeRect(px, py, TILE, TILE); } } } items.forEach(i => { const px = i.x*TILE; const py = i.y*TILE; if(i.type === 'fruit') ctx.drawImage(imgs.fruit, px, py, TILE, TILE); if(i.type === 'key') ctx.drawImage(imgs.key, px, py, TILE, TILE); if(i.type === 'princess') ctx.drawImage(imgs.princess, px, py, TILE, TILE); if(i.type === 'bhanu') ctx.drawImage(imgs.bhanu, px, py, TILE, TILE); }); ctx.save(); ctx.translate(p.vx*TILE + TILE/2, p.vy*TILE + TILE/2); if(p.face === -1) ctx.scale(-1, 1); ctx.drawImage(imgs.hero, -TILE/2, -TILE/2, TILE, TILE); if(gumTimer > 0) { ctx.beginPath(); ctx.arc(0, 0, TILE/1.5, 0, Math.PI*2); ctx.strokeStyle = "#d000ff"; ctx.lineWidth = 3; ctx.stroke(); } ctx.restore(); if(level === 1) { for(let y=0; y<GRID_H; y++) { for(let x=0; x<GRID_W; x++) { if(map[y][x] === 2) { const px = x*TILE; const py = y*TILE; ctx.strokeStyle = "#aaa"; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(px+10, py); ctx.lineTo(px+10, py+TILE); ctx.moveTo(px+20, py); ctx.lineTo(px+20, py+TILE); ctx.moveTo(px+30, py); ctx.lineTo(px+30, py+TILE); ctx.stroke(); } } } } ghosts.forEach(g => { const px = (g.x + g.offX)*TILE; const py = (g.y + g.offY)*TILE; if(g.type === 'terrorist') ctx.drawImage(imgs.terrorist, px, py, TILE, TILE); else { ctx.fillStyle = "red"; ctx.beginPath(); ctx.arc(px+TILE/2, py+TILE/2, TILE/2-4, Math.PI, 0); ctx.fill(); ctx.fillStyle = "white"; ctx.beginPath(); ctx.arc(px+14, py+16, 4, 0, Math.PI*2); ctx.arc(px+26, py+16, 4, 0, Math.PI*2); ctx.fill(); } }); if(state === 'OVER') { ctx.fillStyle = "rgba(0,0,0,0.8)"; ctx.fillRect(0,0, canvas.width, canvas.height); ctx.fillStyle = "red"; ctx.font = "40px monospace"; ctx.textAlign = "center"; ctx.fillText("GAME OVER", 220, 200); ctx.fillStyle = "white"; ctx.font = "20px monospace"; ctx.fillText("Press Enter to Retry", 220, 240); } } function playEnding() { let f = 0; const cx = 220; const cy = 220; function anim() { if(state !== 'END') return; // Clear ctx.fillStyle = "black"; ctx.fillRect(0,0, 440, 440); f++; if(f < 100) { // PART 1: The Encounter ctx.fillStyle = "white"; ctx.font = "16px monospace"; ctx.textAlign = "center"; ctx.fillText("Bhanu: Daddy! You found the key!", cx, 150); ctx.drawImage(imgs.hero, cx-60, cy, 60, 60); ctx.drawImage(imgs.bhanu, cx, cy, 60, 60); } else if (f < 150) { // PART 2: The Red Flash (Kill) ctx.fillStyle = "red"; ctx.font = "20px monospace"; ctx.textAlign = "center"; ctx.fillText("...", cx, 150); ctx.save(); ctx.translate(cx-60, cy); ctx.globalCompositeOperation = "source-over"; ctx.drawImage(imgs.hero, 0, 0, 60, 60); ctx.globalCompositeOperation = "source-atop"; ctx.fillStyle = "red"; ctx.fillRect(0,0,60,60); ctx.restore(); ctx.drawImage(imgs.bhanu, cx, cy, 60, 60); } else if (f < 200) { // PART 3: The Slash ctx.fillStyle = "#300"; ctx.fillRect(0,0,440,440); ctx.drawImage(imgs.hero, cx-30, cy, 60, 60); ctx.strokeStyle = "white"; ctx.lineWidth = 5; ctx.beginPath(); ctx.moveTo(cx-20, cy+60); ctx.lineTo(cx+80, cy); ctx.stroke(); } else if (f < 300) { // PART 4: Transition Text ctx.fillStyle = "black"; ctx.fillRect(0,0,440,440); ctx.fillStyle = "white"; ctx.font = "20px monospace"; ctx.textAlign = "center"; ctx.fillText("YEARS LATER...", cx, cy); } else { // PART 5: THE HAPPY ENDING DANCE ctx.fillStyle = "#ffb6c1"; // Pink background ctx.fillRect(0,0,440,440); const bounce = Math.sin(f * 0.1) * 10; // Parents ctx.drawImage(imgs.hero, cx-60, cy - 20 + bounce, 60, 60); ctx.drawImage(imgs.princess, cx, cy - 20 + bounce, 60, 60); // 5 Children for(let i=0; i<5; i++) { const childBounce = Math.sin((f + i*20) * 0.2) * 8; ctx.drawImage(imgs.baby, 60 + (i*70), cy + 60 + childBounce, 40, 40); } // Floating Hearts for(let i=0; i<5; i++) { const hY = (cy - (f*2 + i*50) % 440); if(hY > 0) { ctx.fillStyle = "red"; ctx.font = "30px sans-serif"; ctx.fillText("❤️", 80 + i*60, hY); } } ctx.fillStyle = "#d000ff"; ctx.font = "24px monospace"; ctx.textAlign = "center"; ctx.fillText("HAPPILY EVER AFTER", cx, 100); ctx.font = "14px monospace"; ctx.fillStyle = "#888"; ctx.fillText("(Don't ask about Bhanu)", cx, 130); requestAnimationFrame(anim); return; } requestAnimationFrame(anim); } anim(); } let lastTime = 0; function loop(timestamp) { const dt = (timestamp - lastTime) / 1000; lastTime = timestamp; gameLoop(dt); if(state !== 'END') draw(); requestAnimationFrame(loop); } Promise.all(Object.values(imgs).map(i => new Promise(r => i.onload = r))).then(() => { ui.loadTxt.style.display = 'none'; ui.startBtn.style.display = 'block'; requestAnimationFrame(loop); }); </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

1

Requests

1

Domains

25KB

Transfer Size

25KB

Content Size

118.0ms

Dom Content Loaded

196.0ms

First Paint

119.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...