双人贪吃蛇 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).

    Two-Player Snake Game
    Player 1 Score: 0
    Player 2 Score: 0
    复制代码
      <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>
相关推荐
子兮曰3 小时前
把 649 种文件格式塞进一个网页里:一个「文件不出浏览器」的预览器
前端·javascript·后端
java资料站6 小时前
十一、Spring AI Alibaba · 高级 · 多智能体(Multi-agent)
人工智能·spring·microsoft
2601_955662466 小时前
情感解说视频如何提升感染力?配音细节很关键
人工智能·音视频·语音识别·视频
苏醒的人生6 小时前
电商品牌物料AI生图工具推荐:让品牌调性一套到底
人工智能
lank_M6 小时前
截图OCR预处理在普通屏上翻车,Retina截图却没事
图像处理·人工智能·计算机视觉·ocr
Aloudata6 小时前
LookML 语义模型 vs 企业级独立语义层:BI 建模语言能否承担企业语义底座?
数据库·人工智能·数据分析·数据资产·dataagent
启观川6 小时前
数据结构与算法 -第 3 章 常用算法-动态规划
数据结构·笔记·python·算法
码爸6 小时前
排序算法介绍
python·算法·排序算法
paopaokaka_luck6 小时前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis