您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Play a Snake Battle game (Human vs AI) on drawaria.online
// ==UserScript== // @name Snake Battle: Human vs AI on Drawaria // @namespace http://tampermonkey.net/ // @version 1.0 // @description Play a Snake Battle game (Human vs AI) on drawaria.online // @author YouTubeDrawaria // @match https://drawaria.online/* // @grant none // @license MIT // @icon https://drawaria.online/avatar/cache/86e33830-86ea-11ec-8553-bff27824cf71.jpg // ==/UserScript== (function () { 'use strict'; // Create game container const gameContainer = document.createElement('div'); gameContainer.style.position = 'fixed'; gameContainer.style.top = '20px'; gameContainer.style.right = '20px'; gameContainer.style.zIndex = '10000'; gameContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; gameContainer.style.padding = '10px'; gameContainer.style.borderRadius = '10px'; gameContainer.style.boxShadow = '0 0 20px rgba(0, 255, 255, 0.5)'; // Add game title const title = document.createElement('h3'); title.textContent = 'Snake Battle 🐍'; title.style.color = '#00ffff'; title.style.textAlign = 'center'; title.style.margin = '0 0 10px 0'; gameContainer.appendChild(title); // Add score display const score = document.createElement('div'); score.id = 'score'; score.textContent = '🚀 PLAYER: 0 | 🤖 AI: 0'; score.style.color = '#ffffff'; score.style.fontSize = '16px'; score.style.marginBottom = '10px'; // Add canvas for the game const canvas = document.createElement('canvas'); canvas.id = 'gameBoard'; canvas.width = 400; canvas.height = 300; canvas.style.border = '2px solid #00ffff'; canvas.style.borderRadius = '10px'; canvas.style.backgroundColor = '#000000'; gameContainer.appendChild(canvas); // Add restart button const restartBtn = document.createElement('button'); restartBtn.textContent = '🔄 NEW BATTLE'; restartBtn.style.display = 'block'; restartBtn.style.margin = '10px auto 0'; restartBtn.style.padding = '8px 16px'; restartBtn.style.backgroundColor = '#00ffff'; restartBtn.style.color = '#000000'; restartBtn.style.border = 'none'; restartBtn.style.borderRadius = '20px'; restartBtn.style.cursor = 'pointer'; restartBtn.style.fontWeight = 'bold'; restartBtn.onclick = resetGame; gameContainer.appendChild(restartBtn); // Append game container to the body document.body.appendChild(gameContainer); // Game logic const ctx = canvas.getContext('2d'); const GRID_SIZE = 20; const CELL_SIZE = canvas.width / GRID_SIZE; let particles = []; let playerScore = 0; let aiScore = 0; let gameSpeed = 100; let gameLoop; let obstacles = []; let playerSnake = [{ x: 5, y: 5 }]; let aiSnake = [{ x: GRID_SIZE - 5, y: GRID_SIZE - 5 }]; let playerDirection = 'right'; let aiDirection = 'left'; let food = generateFood(); function generateObstacles() { const obstacles = []; for (let i = 2; i < GRID_SIZE - 2; i += 4) { for (let j = 2; j < GRID_SIZE - 2; j += 4) { if (Math.random() > 0.5) { obstacles.push({ x: i, y: j }); obstacles.push({ x: i + 1, y: j }); obstacles.push({ x: i, y: j + 1 }); } } } return obstacles; } function generateFood() { let position; do { position = { x: Math.floor(Math.random() * (GRID_SIZE - 4)) + 2, y: Math.floor(Math.random() * (GRID_SIZE - 4)) + 2 }; } while ([...playerSnake, ...aiSnake, ...obstacles].some(item => item.x === position.x && item.y === position.y)); return position; } function aiPathfinding() { const head = aiSnake[0]; const queue = [{ pos: head, path: [] }]; const visited = new Set(); while (queue.length > 0) { const current = queue.shift(); if (current.pos.x === food.x && current.pos.y === food.y) { return current.path[0] || aiDirection; } const directions = [ { dir: 'up', x: 0, y: -1 }, { dir: 'down', x: 0, y: 1 }, { dir: 'left', x: -1, y: 0 }, { dir: 'right', x: 1, y: 0 } ]; for (const d of directions) { const newPos = { x: current.pos.x + d.x, y: current.pos.y + d.y }; const posKey = `${newPos.x},${newPos.y}`; if (!visited.has(posKey) && newPos.x >= 0 && newPos.x < GRID_SIZE && newPos.y >= 0 && newPos.y < GRID_SIZE && !obstacles.some(o => o.x === newPos.x && o.y === newPos.y) && !aiSnake.some(s => s.x === newPos.x && s.y === newPos.y)) { visited.add(posKey); queue.push({ pos: newPos, path: [...current.path, d.dir] }); } } } return aiDirection; } function updateParticles() { particles = particles.filter(p => { p.x += p.velocity.x; p.y += p.velocity.y; p.life -= 0.02; return p.life > 0; }); } function draw() { ctx.fillStyle = '#000'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.strokeStyle = 'rgba(0, 255, 255, 0.05)'; for (let i = 0; i < GRID_SIZE; i++) { ctx.beginPath(); ctx.moveTo(i * CELL_SIZE, 0); ctx.lineTo(i * CELL_SIZE, canvas.height); ctx.stroke(); ctx.beginPath(); ctx.moveTo(0, i * CELL_SIZE); ctx.lineTo(canvas.width, i * CELL_SIZE); ctx.stroke(); } ctx.fillStyle = '#2a2a2a'; obstacles.forEach(obs => { ctx.beginPath(); ctx.roundRect(obs.x * CELL_SIZE, obs.y * CELL_SIZE, CELL_SIZE, CELL_SIZE, 5); ctx.fill(); }); ctx.fillStyle = '#ff006e'; ctx.shadowColor = '#ff006e'; ctx.shadowBlur = 20; ctx.beginPath(); ctx.arc( (food.x + 0.5) * CELL_SIZE, (food.y + 0.5) * CELL_SIZE, CELL_SIZE / 2 - 2, 0, Math.PI * 2 ); ctx.fill(); ctx.shadowBlur = 0; playerSnake.forEach((segment, index) => { const gradient = ctx.createLinearGradient( segment.x * CELL_SIZE, segment.y * CELL_SIZE, (segment.x + 1) * CELL_SIZE, (segment.y + 1) * CELL_SIZE ); gradient.addColorStop(0, '#00ff88'); gradient.addColorStop(1, '#00ff00'); ctx.fillStyle = gradient; ctx.beginPath(); ctx.roundRect( segment.x * CELL_SIZE + 2, segment.y * CELL_SIZE + 2, CELL_SIZE - 4, CELL_SIZE - 4, 8 ); ctx.fill(); }); aiSnake.forEach((segment, index) => { const gradient = ctx.createLinearGradient( segment.x * CELL_SIZE, segment.y * CELL_SIZE, (segment.x + 1) * CELL_SIZE, (segment.y + 1) * CELL_SIZE ); gradient.addColorStop(0, '#ff6600'); gradient.addColorStop(1, '#ff0000'); ctx.fillStyle = gradient; ctx.beginPath(); ctx.roundRect( segment.x * CELL_SIZE + 2, segment.y * CELL_SIZE + 2, CELL_SIZE - 4, CELL_SIZE - 4, 8 ); ctx.fill(); }); particles.forEach(p => { ctx.fillStyle = p.color; ctx.globalAlpha = p.life; ctx.beginPath(); ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); ctx.fill(); }); ctx.globalAlpha = 1; } function gameOver() { clearInterval(gameLoop); setTimeout(() => { alert(`GAME OVER\nPlayer: ${playerScore}\nAI: ${aiScore}`); resetGame(); }, 1000); } function resetGame() { playerSnake = [{ x: 5, y: 5 }]; aiSnake = [{ x: GRID_SIZE - 5, y: GRID_SIZE - 5 }]; playerDirection = 'right'; aiDirection = 'left'; playerScore = aiScore = 0; food = generateFood(); obstacles = generateObstacles(); particles = []; score.textContent = '🚀 PLAYER: 0 | 🤖 AI: 0'; if (gameLoop) clearInterval(gameLoop); gameLoop = setInterval(update, gameSpeed); } document.addEventListener('keydown', (e) => { switch (e.key) { case 'ArrowUp': if (playerDirection !== 'down') playerDirection = 'up'; break; case 'ArrowDown': if (playerDirection !== 'up') playerDirection = 'down'; break; case 'ArrowLeft': if (playerDirection !== 'right') playerDirection = 'left'; break; case 'ArrowRight': if (playerDirection !== 'left') playerDirection = 'right'; break; } }); function update() { aiDirection = aiPathfinding(); const playerHead = { ...playerSnake[0] }; const aiHead = { ...aiSnake[0] }; switch (playerDirection) { case 'up': playerHead.y--; break; case 'down': playerHead.y++; break; case 'left': playerHead.x--; break; case 'right': playerHead.x++; break; } switch (aiDirection) { case 'up': aiHead.y--; break; case 'down': aiHead.y++; break; case 'left': aiHead.x--; break; case 'right': aiHead.x++; break; } const playerCollision = checkCollision(playerHead, playerSnake); const aiCollision = checkCollision(aiHead, aiSnake); if (playerCollision || aiCollision) { gameOver(); return; } playerSnake.unshift(playerHead); aiSnake.unshift(aiHead); if (playerHead.x === food.x && playerHead.y === food.y) { playerScore++; food = generateFood(); } else { playerSnake.pop(); } if (aiHead.x === food.x && aiHead.y === food.y) { aiScore++; food = generateFood(); } else { aiSnake.pop(); } score.textContent = `🚀 PLAYER: ${playerScore} | 🤖 AI: ${aiScore}`; updateParticles(); draw(); } function checkCollision(head, snake) { return head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE || obstacles.some(o => o.x === head.x && o.y === head.y) || snake.slice(1).some(s => s.x === head.x && s.y === head.y) || (snake === playerSnake ? aiSnake : playerSnake).some(s => s.x === head.x && s.y === head.y); } resetGame(); })();