双人贪吃蛇 HTML5 版

  • Player 1 uses W, A, S, D keys to control their snake (blue).

  • Player 2 uses U, H, J, K keys to control their snake (red).

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Two-Player Snake Game</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f0f0f0; font-family: Arial, sans-serif; } #gameCanvas { border: 2px solid #333; } #scoreBoard { position: absolute; top: 10px; left: 10px; font-size: 18px; } </style> </head> <body>
    Player 1 Score: 0
    Player 2 Score: 0
    <canvas id="gameCanvas" width="800" height="800"></canvas>
    复制代码
      <script>
          const canvas = document.getElementById('gameCanvas');
          const ctx = canvas.getContext('2d');
          const gridSize = 20;
          const tileCount = canvas.width / gridSize;
    
          let snake1 = [
              {x: 10, y: 10},
              {x: 9, y: 10},
              {x: 8, y: 10}
          ];
          let snake2 = [
              {x: 30, y: 30},
              {x: 31, y: 30},
              {x: 32, y: 30}
          ];
    
          let dx1 = 1;
          let dy1 = 0;
          let dx2 = -1;
          let dy2 = 0;
    
          let food = getRandomFood();
          let score1 = 0;
          let score2 = 0;
    
          function getRandomFood() {
              return {
                  x: Math.floor(Math.random() * tileCount),
                  y: Math.floor(Math.random() * tileCount)
              };
          }
    
          function drawGame() {
              clearCanvas();
              moveSnake(snake1, dx1, dy1);
              moveSnake(snake2, dx2, dy2);
              checkCollision();
              drawFood();
              drawSnake(snake1, '#00f');
              drawSnake(snake2, '#f00');
              updateScore();
          }
    
          function clearCanvas() {
              ctx.fillStyle = 'white';
              ctx.fillRect(0, 0, canvas.width, canvas.height);
          }
    
          function moveSnake(snake, dx, dy) {
              const head = {x: snake[0].x + dx, y: snake[0].y + dy};
              snake.unshift(head);
    
              if (head.x === food.x && head.y === food.y) {
                  food = getRandomFood();
                  if (snake === snake1) score1++;
                  else score2++;
              } else {
                  snake.pop();
              }
          }
    
          function checkCollision() {
              const head1 = snake1[0];
              const head2 = snake2[0];
    
              // Check wall collision
              if (head1.x < 0 || head1.x >= tileCount || head1.y < 0 || head1.y >= tileCount) gameOver();
              if (head2.x < 0 || head2.x >= tileCount || head2.y < 0 || head2.y >= tileCount) gameOver();
    
              // Check self-collision
              for (let i = 1; i < snake1.length; i++) {
                  if (head1.x === snake1[i].x && head1.y === snake1[i].y) gameOver();
              }
              for (let i = 1; i < snake2.length; i++) {
                  if (head2.x === snake2[i].x && head2.y === snake2[i].y) gameOver();
              }
    
              // Check collision between snakes
              for (let part of snake2) {
                  if (head1.x === part.x && head1.y === part.y) gameOver();
              }
              for (let part of snake1) {
                  if (head2.x === part.x && head2.y === part.y) gameOver();
              }
          }
    
          function drawFood() {
              ctx.fillStyle = 'green';
              ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
          }
    
          function drawSnake(snake, color) {
              ctx.fillStyle = color;
              for (let part of snake) {
                  ctx.fillRect(part.x * gridSize, part.y * gridSize, gridSize, gridSize);
              }
          }
    
          function updateScore() {
              document.getElementById('score1').textContent = score1;
              document.getElementById('score2').textContent = score2;
          }
    
          function gameOver() {
              alert('Game Over! Scores: Player 1 - ' + score1 + ', Player 2 - ' + score2);
              resetGame();
          }
    
          function resetGame() {
              snake1 = [{x: 10, y: 10}, {x: 9, y: 10}, {x: 8, y: 10}];
              snake2 = [{x: 30, y: 30}, {x: 31, y: 30}, {x: 32, y: 30}];
              dx1 = 1;
              dy1 = 0;
              dx2 = -1;
              dy2 = 0;
              food = getRandomFood();
              score1 = 0;
              score2 = 0;
          }
    
          document.addEventListener('keydown', (e) => {
              switch(e.key) {
                  case 'w': if (dy1 === 0) { dx1 = 0; dy1 = -1; } break;
                  case 's': if (dy1 === 0) { dx1 = 0; dy1 = 1; } break;
                  case 'a': if (dx1 === 0) { dx1 = -1; dy1 = 0; } break;
                  case 'd': if (dx1 === 0) { dx1 = 1; dy1 = 0; } break;
                  case 'u': if (dy2 === 0) { dx2 = 0; dy2 = -1; } break;
                  case 'j': if (dy2 === 0) { dx2 = 0; dy2 = 1; } break;
                  case 'h': if (dx2 === 0) { dx2 = -1; dy2 = 0; } break;
                  case 'k': if (dx2 === 0) { dx2 = 1; dy2 = 0; } break;
              }
          });
    
          setInterval(drawGame, 150);
      </script>
    </body> </html>
相关推荐
飞哥数智坊13 分钟前
我帮你读《一人公司(OPC)发展研究》
人工智能
董董灿是个攻城狮1 小时前
AI视觉连载8:传统 CV 之边缘检测
算法
冬奇Lab4 小时前
OpenClaw 源码精读(3):Agent 执行引擎——AI 如何「思考」并与真实世界交互?
人工智能·aigc
炫饭第一名5 小时前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
没事勤琢磨6 小时前
如何让 OpenClaw 控制使用浏览器:让 AI 像真人一样操控你的浏览器
人工智能
用户5191495848456 小时前
CrushFTP 认证绕过漏洞利用工具 (CVE-2024-4040)
人工智能·aigc
牛马摆渡人5286 小时前
OpenClaw实战--Day1: 本地化
人工智能
前端小豆6 小时前
玩转 OpenClaw:打造你的私有 AI 助手网关
人工智能
BugShare6 小时前
写一个你自己的Agent Skills
人工智能·程序员
机器之心6 小时前
英伟达护城河被AI攻破,字节清华CUDA Agent,让人人能搓CUDA内核
人工智能·openai