• 首页
  • 说说
  • 友人
  • 留言
  • 赞赏
  • 建站史
  • 搜索
  • 夜间模式
    ©2025  Feng的小屋 Theme by OneBlog
    搜索
    标签
    # HTML # CSS # JS # 代码 # 分享 # 美化 # 感悟 # 小游戏 # 摄影 # 摄影知识
    🧑‍💻 代码

    趣味web在线小游戏-五子棋

    2025.07.23 / 56 阅读 / 0 评论 / 11902 字
    🧑‍💻 代码

    趣味web在线小游戏-五子棋

    阅读 56 评论 0 发表于2025.07.23
    AI摘要

    摘要:这篇文章介绍了一个趣味web在线小游戏——五子棋,使用HTML、CSS和JavaScript实现。文章详细阐述了游戏开发过程,包括HTML构建页面结构、CSS负责样式美化、JavaScript实现游戏核心逻辑。该项目不仅适合初学者学习Web开发,还可作为扩展和优化基础,增加AI对手、在线对战等功能。

    探索 HTML、CSS 和 JavaScript 实现的五子棋游戏

    用 HTML、CSS 和 JavaScript 实现各种有趣的小游戏是一种既实用又有趣的学习方式。今天,我们就来深入探索一个用这三种技术打造的五子棋小游戏

    点击即可转跳至在线预览~

    整体项目概述

    这个五子棋游戏是一个网页版应用,用户可以在浏览器中直接打开并进行对战。项目的整体结构清晰,由 HTML 构建页面结构,CSS 负责样式美化,JavaScript 实现游戏的核心逻辑。通过三者的协同工作,为玩家提供了一个流畅、有趣的游戏体验。

    HTML:搭建游戏的骨架

    HTML 文件为游戏搭建了基本的框架,包含了游戏的标题、控制按钮、棋盘区域、游戏信息展示和结果显示等部分。

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>五子棋游戏</title>
      <script src="https://cdn.tailwindcss.com"></script>
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css" rel="stylesheet">
      <!-- 其他元信息和脚本引入 -->
    </head>
    <body>
      <div class="max-w-5xl w-full bg-white rounded-2xl shadow-xl overflow-hidden">
        <!-- 游戏标题 -->
        <header class="bg-primary text-white p-4 text-center">
          <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold tracking-wide">五子棋</h1>
          <p class="text-amber-100 mt-1">落子连五获胜</p>
        </header>
    
        <!-- 游戏区域 -->
        <main class="p-6 md:p-8">
          <!-- 游戏控制区 -->
          <div class="flex flex-col lg:flex-row justify-between items-center mb-6 gap-4">
            <!-- 玩家信息和计时器 -->
            <div class="flex flex-col sm:flex-row items-center gap-3 w-full lg:w-auto">
              <div class="flex items-center gap-3">
                <div id="current-player" class="w-6 h-6 rounded-full piece-black piece-shadow"></div>
                <span class="text-lg font-medium">当前玩家: <span id="player-text" class="text-black font-bold">黑棋</span></span>
              </div>
              <div class="flex items-center gap-3 mt-2 sm:mt-0">
                <span class="text-lg font-medium">游戏时间: <span id="timer" class="text-primary font-bold">00:00</span></span>
              </div>
            </div>
            <!-- 控制按钮 -->
            <div class="flex gap-3 w-full lg:w-auto justify-center lg:justify-end">
              <button id="restart-btn" class="bg-primary hover:bg-primary/90 text-white px-4 py-2 rounded-lg transition-all flex items-center gap-2">
                <i class="fa fa-refresh"></i>
                <span>重新开始</span>
              </button>
              <button id="undo-btn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg transition-all flex items-center gap-2">
                <i class="fa fa-undo"></i>
                <span>悔棋</span>
              </button>
              <button id="hint-btn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition-all flex items-center gap-2">
                <i class="fa fa-lightbulb-o"></i>
                <span>提示</span>
              </button>
            </div>
          </div>
    
          <!-- 游戏主区域 -->
          <div class="flex flex-col lg:flex-row gap-6">
            <!-- 棋盘容器 -->
            <div class="relative mx-auto aspect-square max-w-md w-full bg-board rounded-lg board-shadow overflow-hidden grid-pattern" style="background-size: calc(100% / 14) calc(100% / 14);">
              <div id="board" class="absolute inset-0 cursor-pointer"></div>
              <!-- 棋盘标记点 -->
              <div class="absolute w-2 h-2 bg-dark rounded-full" style="top: calc(3/14 * 100%); left: calc(3/14 * 100%);"></div>
              <!-- 其他标记点 -->
            </div>
            <!-- 游戏信息和历史 -->
            <div class="w-full lg:w-80">
              <!-- 游戏统计 -->
              <div class="bg-gray-50 rounded-xl p-4 mb-4">
                <h3 class="text-lg font-semibold mb-3 text-gray-800">游戏统计</h3>
                <div class="grid grid-cols-2 gap-2">
                  <div class="bg-white p-3 rounded-lg shadow-sm">
                    <div class="text-sm text-gray-500">黑棋胜场</div>
                    <div id="black-wins" class="text-xl font-bold text-black">0</div>
                  </div>
                  <!-- 其他统计信息 -->
                </div>
              </div>
              <!-- 走棋历史 -->
              <div class="bg-gray-50 rounded-xl p-4 h-64 overflow-hidden">
                <div class="flex justify-between items-center mb-3">
                  <h3 class="text-lg font-semibold text-gray-800">走棋历史</h3>
                  <button id="clear-history-btn" class="text-xs text-gray-500 hover:text-primary">
                    <i class="fa fa-trash-o"></i> 清空
                  </button>
                </div>
                <div id="move-history" class="overflow-y-auto h-48 text-sm space-y-1">
                  <div class="text-gray-500 italic text-center">游戏尚未开始</div>
                </div>
              </div>
            </div>
          </div>
    
          <!-- 游戏结果 -->
          <div id="result" class="hidden mt-6 text-center p-4 rounded-lg bg-green-100 border border-green-300">
            <h2 id="result-text" class="text-xl font-bold text-green-800"></h2>
            <div class="mt-2 text-sm text-gray-600">
              用时: <span id="game-time">00:00</span> | 步数: <span id="move-count">0</span>
            </div>
            <button id="new-game-btn" class="mt-3 bg-primary hover:bg-primary/90 text-white px-6 py-2 rounded-lg transition-all">
              开始新游戏
            </button>
          </div>
        </main>
    
        <!-- 页脚 -->
        <footer class="bg-gray-100 text-gray-600 p-4 text-center text-sm">
          <p>© 2025 五子棋游戏 | 简约而不简单</p>
        </footer>
      </div>
      <script>
        // JavaScript 代码
      </script>
    </body>
    </html>

    从这段代码中可以看出,HTML 页面使用了 Tailwind CSS 框架来快速实现样式布局,同时引入了 Font Awesome 图标库来增强视觉效果。页面结构层次分明,将游戏的各个部分清晰地展示出来,方便用户操作和查看信息。

    CSS:美化游戏的外观

    CSS 部分主要负责游戏界面的样式设计,通过自定义样式和 Tailwind CSS 的扩展,为游戏增添了丰富的视觉效果。

    @layer utilities {
      .board-shadow {
        box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
      }
      .piece-shadow {
        box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
      }
      .piece-white {
        background: radial-gradient(circle at 35% 35%, #ffffff, #e0e0e0);
      }
      .piece-black {
        background: radial-gradient(circle at 35% 35%, #505050, #000000);
      }
      .grid-pattern {
        background-image: linear-gradient(#8B4513 1px, transparent 1px),
                          linear-gradient(90deg, #8B4513 1px, transparent 1px);
      }
      .animate-fadeIn {
        animation: fadeIn 0.5s ease-in-out;
      }
      .hover-indicator {
        position: absolute;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background-color: rgba(255, 215, 0, 0.7);
        opacity: 0;
        transition: opacity 0.2s ease;
      }
      .game-history-item {
        padding: 0.5rem;
        border-radius: 0.375rem;
        transition: background-color 0.2s;
      }
      .game-history-item:hover {
        background-color: rgba(0, 0, 0, 0.05);
      }
    }
    
    @keyframes fadeIn {
      from { opacity: 0; transform: translateY(10px); }
      to { opacity: 1; transform: translateY(0); }
    }

    这里定义了棋盘的阴影效果、棋子的渐变背景、网格图案以及动画效果等。例如,piece-white 和 piece-black 类分别为白棋和黑棋设置了不同的径向渐变背景,使其看起来更加立体。而 animate-fadeIn 动画则为游戏结果的显示添加了淡入效果,提升了用户体验。

    JavaScript:实现游戏的核心逻辑

    JavaScript 是这个五子棋游戏的核心,它负责处理游戏的各种交互和逻辑判断。

    游戏状态管理

    // 游戏常量
    const BOARD_SIZE = 15;
    const CELL_SIZE = 100 / (BOARD_SIZE - 1); // 百分比单位
    const WINNING_LENGTH = 5;
    
    // 游戏状态
    let currentPlayer = 'black';
    let gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
    let gameActive = true;
    let moveHistory = [];
    let gameStartTime = null;
    let gameTimer = null;
    let hintTimeout = null;
    let hintPosition = null;
    
    // 游戏统计
    let stats = {
      blackWins: 0,
      whiteWins: 0,
      totalGames: 0,
      totalTime: 0
    };

    这里定义了游戏的常量和状态变量,包括棋盘大小、获胜条件、当前玩家、游戏棋盘状态、走棋历史等。同时,还使用 stats 对象来记录游戏的统计信息,如黑棋和白棋的胜场数、总对局数和总游戏时间。

    初始化棋盘

    function initializeBoard() {
      boardElement.innerHTML = '';
      
      // 创建交叉点
      for (let row = 0; row < BOARD_SIZE; row++) {
        for (let col = 0; col < BOARD_SIZE; col++) {
          const intersection = document.createElement('div');
          intersection.className = 'absolute w-8 h-8 rounded-full flex items-center justify-center transition-all duration-200 hover:bg-black/5 -translate-x-1/2 -translate-y-1/2';
          intersection.style.left = `${col * CELL_SIZE}%`;
          intersection.style.top = `${row * CELL_SIZE}%`;
          intersection.dataset.row = row;
          intersection.dataset.col = col;
        
          // 添加鼠标悬停指示器
          const hoverIndicator = document.createElement('div');
          hoverIndicator.className = 'hover-indicator';
          intersection.appendChild(hoverIndicator);
        
          // 添加点击事件
          intersection.addEventListener('click', () => handleIntersectionClick(row, col));
        
          // 添加鼠标进入事件
          intersection.addEventListener('mouseenter', () => {
            if (gameActive && gameBoard[row][col] === null) {
              hoverIndicator.style.opacity = '1';
            }
          });
        
          // 添加鼠标离开事件
          intersection.addEventListener('mouseleave', () => {
            hoverIndicator.style.opacity = '0';
          });
        
          boardElement.appendChild(intersection);
        }
      }
    }

    initializeBoard 函数用于创建棋盘的交叉点,并为每个交叉点添加鼠标悬停指示器和点击事件。当鼠标悬停在空闲的交叉点上时,指示器会显示出来,提示玩家可以落子。

    处理落子事件

    function handleIntersectionClick(row, col) {
      // 检查是否可以落子
      if (gameBoard[row][col] !== null || !gameActive) {
        return;
      }
      
      // 清除提示
      clearHint();
      
      // 记录历史
      moveHistory.push({row, col, player: currentPlayer});
      
      // 更新走棋历史显示
      addToMoveHistory(row, col, currentPlayer);
      
      // 落子
      placePiece(row, col, currentPlayer);
      
      // 检查是否获胜
      if (checkWin(row, col, currentPlayer)) {
        gameActive = false;
        stopTimer();
      
        // 更新统计
        if (currentPlayer === 'black') {
          stats.blackWins++;
        } else {
          stats.whiteWins++;
        }
        stats.totalGames++;
        stats.totalTime += getElapsedTime();
        saveStats();
        updateStatsDisplay();
      
        showResult(`${currentPlayer === 'black' ? '黑棋' : '白棋'}获胜!`);
        return;
      }
      
      // 检查是否平局
      if (checkDraw()) {
        gameActive = false;
        stopTimer();
        showResult('平局!');
        return;
      }
      
      // 切换玩家
      currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
      updatePlayerIndicator();
    }

    handleIntersectionClick 函数处理玩家点击交叉点的事件。它会先检查该位置是否可以落子,然后记录走棋历史,放置棋子,并检查是否获胜或平局。如果游戏结束,会更新统计信息并显示结果;否则,切换玩家继续游戏。

    检查获胜和平局

    function checkWin(row, col, player) {
      const directions = [
        [0, 1],  // 水平
        [1, 0],  // 垂直
        [1, 1],  // 对角线
        [1, -1]  // 反对角线
      ];
      
      for (const [dx, dy] of directions) {
        let count = 1;  // 当前位置已经有一个棋子
      
        // 正向检查
        for (let i = 1; i < WINNING_LENGTH; i++) {
          const newRow = row + i * dx;
          const newCol = col + i * dy;
        
          if (
            newRow >= 0 && newRow < BOARD_SIZE &&
            newCol >= 0 && newCol < BOARD_SIZE &&
            gameBoard[newRow][newCol] === player
          ) {
            count++;
          } else {
            break;
          }
        }
      
        // 反向检查
        for (let i = 1; i < WINNING_LENGTH; i++) {
          const newRow = row - i * dx;
          const newCol = col - i * dy;
        
          if (
            newRow >= 0 && newRow < BOARD_SIZE &&
            newCol >= 0 && newCol < BOARD_SIZE &&
            gameBoard[newRow][newCol] === player
          ) {
            count++;
          } else {
            break;
          }
        }
      
        // 检查是否连成五子
        if (count >= WINNING_LENGTH) {
          // 高亮显示获胜的棋子
          highlightWinningPieces(row, col, dx, dy, count);
          return true;
        }
      }
      
      return false;
    }
    
    function checkDraw() {
      for (let row = 0; row < BOARD_SIZE; row++) {
        for (let col = 0; col < BOARD_SIZE; col++) {
          if (gameBoard[row][col] === null) {
            return false;  // 还有空位,不是平局
          }
        }
      }
      return true;  // 棋盘已满,平局
    }

    checkWin 函数通过检查四个方向(水平、垂直、对角线和反对角线)上是否有连续五个相同颜色的棋子来判断是否获胜。如果获胜,会调用 highlightWinningPieces 函数高亮显示获胜的棋子。checkDraw 函数则遍历整个棋盘,检查是否还有空位,如果没有则判定为平局。

    总结

    通过这个五子棋游戏项目,我们可以看到 HTML、CSS 和 JavaScript 是如何协同工作来创建一个完整的 Web 应用的。HTML 提供了页面的结构,CSS 美化了界面,而 JavaScript 实现了游戏的核心逻辑和交互功能。这个项目不仅适合初学者学习 Web 开发的基础知识,还可以作为一个基础,进一步扩展和优化,例如添加 AI 对手、在线对战等功能。

    本文著作权归作者 [ Feng ] 享有,未经作者书面授权,禁止转载,封面图片来源于 [ 互联网 ] ,本文仅供个人学习、研究和欣赏使用。如有异议,请联系博主及时处理。
    取消回复

    发表留言
    回复

    首页说说友人留言赞赏建站史
    Copyright©2025  All Rights Reserved.  Load:0.015 s
    Theme by OneBlog V3.6.3
    夜间模式

    开源不易,请尊重作者版权,保留基本的版权信息。