双人贪吃蛇 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>
相关推荐
说私域26 分钟前
基于开源AI智能名片链动2+1模式S2B2C商城小程序的超级文化符号构建路径研究
人工智能·小程序·开源
永洪科技28 分钟前
永洪科技荣获商业智能品牌影响力奖,全力打造”AI+决策”引擎
大数据·人工智能·科技·数据分析·数据可视化·bi
shangyingying_138 分钟前
关于小波降噪、小波增强、小波去雾的原理区分
人工智能·深度学习·计算机视觉
凌肖战1 小时前
力扣网C语言编程题:在数组中查找目标值位置之二分查找法
c语言·算法·leetcode
weixin_478689762 小时前
十大排序算法汇总
java·算法·排序算法
书玮嘎2 小时前
【WIP】【VLA&VLM——InternVL系列】
人工智能·深度学习
猫头虎2 小时前
猫头虎 AI工具分享:一个网页抓取、结构化数据提取、网页爬取、浏览器自动化操作工具:Hyperbrowser MCP
运维·人工智能·gpt·开源·自动化·文心一言·ai编程
要努力啊啊啊2 小时前
YOLOv2 正负样本分配机制详解
人工智能·深度学习·yolo·计算机视觉·目标跟踪