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, maximum-scale=1.0, user-scalable=no"> <title>Mobile Surfer</title> <style> body { margin: 0; overflow: hidden; background-color: #333; font-family: Arial, sans-serif; touch-action: none; /* Prevents zooming/scrolling on tap */ } canvas { display: block; margin: 0 auto; background: #444; } #ui { position: absolute; top: 20px; left: 0; width: 100%; text-align: center; color: white; font-size: 24px; pointer-events: none; text-shadow: 2px 2px 2px #000; } #gameOver { display: none; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0, 0, 0, 0.8); padding: 20px; border-radius: 10px; text-align: center; color: white; } button { background: #00ff88; border: none; padding: 15px 30px; font-size: 20px; border-radius: 5px; margin-top: 10px; cursor: pointer; } </style> </head> <body> <div id="ui">Score: <span id="scoreVal">0</span></div> <canvas id="gameCanvas"></canvas> <div id="gameOver"> <h1>πŸ’₯ CRASH!</h1> <p>Final Score: <span id="finalScore">0</span></p> <button onclick="resetGame()">Try Again</button> </div> <script> const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const scoreEl = document.getElementById('scoreVal'); const finalScoreEl = document.getElementById('finalScore'); const gameOverScreen = document.getElementById('gameOver'); // Game State let gameRunning = true; let score = 0; let speed = 5; let laneWidth; // Player let player = { lane: 1, // 0: Left, 1: Middle, 2: Right y: 0, width: 50, height: 50, color: '#00ff88' }; // Obstacles let obstacles = []; let frameCount = 0; // Resize canvas to full mobile screen function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; laneWidth = canvas.width / 3; player.y = canvas.height - 150; player.width = laneWidth * 0.5; } window.addEventListener('resize', resize); resize(); // Controls (Touch) window.addEventListener('touchstart', (e) => { if (!gameRunning) return; const touchX = e.touches[0].clientX; const screenMiddle = canvas.width / 2; if (touchX < screenMiddle) { // Tap Left if (player.lane > 0) player.lane--; } else { // Tap Right if (player.lane < 2) player.lane++; } }); // Game Loop function update() { if (!gameRunning) return; // Spawn Obstacles frameCount++; if (frameCount % 60 === 0) { // Approx every 1 second let obsLane = Math.floor(Math.random() * 3); obstacles.push({ lane: obsLane, y: -100, width: laneWidth * 0.5, height: 50 }); // Increase speed slightly if (score % 5 === 0) speed += 0.2; } // Move Obstacles for (let i = obstacles.length - 1; i >= 0; i--) { let obs = obstacles[i]; obs.y += speed; // Collision Detection // Player Y is fixed, Obs Y moves down // Simple box collision let playerX = (player.lane * laneWidth) + (laneWidth / 2) - (player.width / 2); let obsX = (obs.lane * laneWidth) + (laneWidth / 2) - (obs.width / 2); if ( player.lane === obs.lane && obs.y + obs.height > player.y && obs.y < player.y + player.height ) { endGame(); } // Remove if off screen if (obs.y > canvas.height) { obstacles.splice(i, 1); score++; scoreEl.innerText = score; } } draw(); requestAnimationFrame(update); } function draw() { // Clear Screen ctx.fillStyle = '#444'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw Lanes ctx.strokeStyle = '#666'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(laneWidth, 0); ctx.lineTo(laneWidth, canvas.height); ctx.moveTo(laneWidth * 2, 0); ctx.lineTo(laneWidth * 2, canvas.height); ctx.stroke(); // Draw Player let pX = (player.lane * laneWidth) + (laneWidth / 2) - (player.width / 2); ctx.fillStyle = player.color; // Draw a simple surfboard shape (ellipse-ish) or rectangle ctx.fillRect(pX, player.y, player.width, player.height); // Draw Player Eyes (Cute factor) ctx.fillStyle = 'black'; ctx.fillRect(pX + 10, player.y + 10, 5, 5); ctx.fillRect(pX + player.width - 15, player.y + 10, 5, 5); // Draw Obstacles ctx.fillStyle = '#ff4444'; obstacles.forEach(obs => { let oX = (obs.lane * laneWidth) + (laneWidth / 2) - (obs.width / 2); ctx.fillRect(oX, obs.y, obs.width, obs.height); // Warning stripes ctx.fillStyle = 'yellow'; ctx.fillRect(oX + 5, obs.y + 10, obs.width - 10, 10); ctx.fillStyle = '#ff4444'; }); } function endGame() { gameRunning = false; finalScoreEl.innerText = score; gameOverScreen.style.display = 'block'; } function resetGame() { obstacles = []; score = 0; speed = 5; player.lane = 1; scoreEl.innerText = '0'; gameOverScreen.style.display = 'none'; gameRunning = true; frameCount = 0; update(); } // Start update(); </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

1

Requests

1

Domains

7KB

Transfer Size

7KB

Content Size

150.0ms

Dom Content Loaded

192.0ms

First Paint

150.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...