| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Slither Game</title> |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> |
| <style> |
| body { |
| margin: 0; |
| overflow: hidden; |
| background: #000; |
| } |
| canvas { |
| display: block; |
| } |
| </style> |
| </head> |
| <body> |
| <canvas id="gameCanvas"></canvas> |
| |
| <script> |
| const canvas = document.getElementById('gameCanvas'); |
| const ctx = canvas.getContext('2d'); |
| |
| canvas.width = window.innerWidth; |
| canvas.height = window.innerHeight; |
| |
| |
| const player = { |
| x: canvas.width / 2, |
| y: canvas.height / 2, |
| size: 10, |
| speed: 3, |
| trail: [], |
| maxTrail: 100, |
| color: '#00FF00' |
| }; |
| |
| const food = { |
| x: Math.random() * canvas.width, |
| y: Math.random() * canvas.height, |
| size: 5, |
| color: '#FF0000' |
| }; |
| |
| let direction = { x: 0, y: 0 }; |
| |
| |
| window.addEventListener('mousemove', (e) => { |
| const angle = Math.atan2(e.clientY - player.y, e.clientX - player.x); |
| direction.x = Math.cos(angle) * player.speed; |
| direction.y = Math.sin(angle) * player.speed; |
| }); |
| |
| |
| window.addEventListener('touchmove', (e) => { |
| e.preventDefault(); |
| const touch = e.touches[0]; |
| const angle = Math.atan2(touch.clientY - player.y, touch.clientX - player.x); |
| direction.x = Math.cos(angle) * player.speed; |
| direction.y = Math.sin(angle) * player.speed; |
| }); |
| |
| function gameLoop() { |
| |
| ctx.fillStyle = '#000'; |
| ctx.fillRect(0, 0, canvas.width, canvas.height); |
| |
| |
| player.x += direction.x; |
| player.y += direction.y; |
| |
| |
| if (player.x < 0) player.x = canvas.width; |
| if (player.x > canvas.width) player.x = 0; |
| if (player.y < 0) player.y = canvas.height; |
| if (player.y > canvas.height) player.y = 0; |
| |
| |
| player.trail.push({ x: player.x, y: player.y }); |
| if (player.trail.length > player.maxTrail) { |
| player.trail.shift(); |
| } |
| |
| |
| for (let i = 0; i < player.trail.length; i++) { |
| const segment = player.trail[i]; |
| const size = player.size * (i / player.trail.length); |
| ctx.fillStyle = player.color; |
| ctx.beginPath(); |
| ctx.arc(segment.x, segment.y, size, 0, Math.PI * 2); |
| ctx.fill(); |
| } |
| |
| |
| ctx.fillStyle = player.color; |
| ctx.beginPath(); |
| ctx.arc(player.x, player.y, player.size, 0, Math.PI * 2); |
| ctx.fill(); |
| |
| |
| ctx.fillStyle = food.color; |
| ctx.beginPath(); |
| ctx.arc(food.x, food.y, food.size, 0, Math.PI * 2); |
| ctx.fill(); |
| |
| |
| const dist = Math.sqrt( |
| Math.pow(player.x - food.x, 2) + |
| Math.pow(player.y - food.y, 2) |
| ); |
| |
| if (dist < player.size + food.size) { |
| |
| player.maxTrail += 50; |
| |
| |
| food.x = Math.random() * canvas.width; |
| food.y = Math.random() * canvas.height; |
| } |
| |
| requestAnimationFrame(gameLoop); |
| } |
| |
| gameLoop(); |
| |
| |
| window.addEventListener('resize', () => { |
| canvas.width = window.innerWidth; |
| canvas.height = window.innerHeight; |
| }); |
| </script> |
| </body> |
| </html> |