三国华容道离线html代码

最近感觉脑子有点不够用,手机真不能玩多了,玩多了降智hh。现在感觉不管是刷视频还是打游戏都影响状态,但是有时候又感觉很累想简单放松一下,同时又不想影响状态。

前不久也看了点最强大脑,说实话感觉和最早的几季有点不太像了,最早的几季主要考验记忆能力,最近这几季感觉很多都是玩类似智力测验这种更注重逻辑推理的游戏。有一季看到了何猷君21秒复原了数字华容道,之前我也只是听说过但没玩过,于是认真学习了一下,才了解到华容道原来还被称为智力游戏界“三大不可思议”(另外两个是独立钻石棋和魔方)。经过了解之后,终于学会了华容道这款游戏。现在又觉得自己玩还不够过瘾,还想直接把这款游戏用代码编写出来,于是前一篇文章写了一个网页版的数字华容道,这一篇则是编写了三国华容道,欢迎大家分享交流游戏经验和攻略。

以下是我所编写游戏的详细介绍:

基于HTML+CSS+JS实现离线版华容道游戏

华容道作为中国经典益智游戏,承载着几代人的童年回忆。今天给大家分享一款我开发的离线版华容道游戏,无需后端依赖,打开浏览器即可畅玩,支持多种经典布局、拖拽+按键双操作模式,还加入了主题切换、攻略提示等实用功能。下面详细介绍游戏特性和核心代码实现。

一、游戏核心功能亮点

这款华容道游戏在还原经典玩法的基础上,做了不少体验优化,核心功能包括:

  • 5种经典游戏模式:横刀立马、齐头并进、兵分三路、雨声淅沥、指挥若定,满足不同难度需求
  • 双操作方式:支持鼠标拖拽棋子+方向键/虚拟方向按钮控制,操作流畅
  • 可视化体验:木质纹理棋子+明暗主题切换,适配不同使用场景
  • 游戏数据统计:实时显示游戏时间和移动步数,胜负判定自动化
  • 实用辅助功能:棋子ID显示/隐藏、分步攻略提示,新手友好
  • 完全离线运行:纯前端实现,无需网络,打开HTML文件即可玩

二、核心技术架构

游戏采用纯前端技术栈开发,无任何框架依赖,结构清晰:

  • HTML:搭建游戏面板、控制区、提示弹窗等基础结构
  • CSS:实现响应式布局、棋子样式、主题切换、动画效果
  • JavaScript:处理游戏逻辑(棋子移动、碰撞检测、胜利判定等)、交互事件、数据管理

三、关键代码解析

1. 游戏核心数据结构

首先定义游戏状态和配置,统一管理棋盘、棋子、游戏进度等数据:

// 游戏状态和配置
const gameState = {
   
   
    board: [], // 棋盘网格数据
    pieces: [], // 棋子集合
    selectedPiece: null, // 当前选中棋子
    moves: 0, // 移动步数
    startTime: null, // 游戏开始时间
    timer: null, // 计时定时器
    isPlaying: false, // 游戏是否进行中
    showIds: true, // 是否显示棋子ID
    isDarkMode: false, // 是否暗色主题
    currentMode: 'hengdao', // 当前游戏模式
    // 拖动相关状态
    dragData: {
   
   
        isDragging: false,
        startX: 0,
        startY: 0,
        piece: null
    }
};

// 棋子配置(尺寸+名称映射)
const pieceConfig = [
    {
   
    id: 1, name: "曹操", width: 2, height: 2 }, // 2x2大棋子
    {
   
    id: 2, name: "关羽", width: 2, height: 1 }, // 2x1横向棋子
    {
   
    id: 3, name: "张飞", width: 1, height: 2 }, // 1x2纵向棋子
    {
   
    id: 4, name: "赵云", width: 1, height: 2 },
    {
   
    id: 5, name: "马超", width: 1, height: 2 },
    {
   
    id: 6, name: "黄忠", width: 1, height: 2 },
    {
   
    id: 7, name: "卒", width: 1, height: 1 }, // 1x1小棋子
    {
   
    id: 8, name: "卒", width: 1, height: 1 },
    {
   
    id: 9, name: "卒", width: 1, height: 1 },
    {
   
    id: 10, name: "卒", width: 1, height: 1 }
];

2. 棋盘与棋子渲染

通过网格布局创建棋盘,根据游戏模式初始化棋子位置:

// 创建棋盘(5行4列网格)
function createBoard() {
   
   
    boardGrid.innerHTML = '';
    for (let i = 0; i < 5; i++) {
   
   
        for (let j = 0; j < 4; j++) {
   
   
            const cell = document.createElement('div');
            cell.className = 'cell';
            cell.dataset.row = i;
            cell.dataset.col = j;
            boardGrid.appendChild(cell);
        }
    }
}

// 创建棋子并定位
function createPiece(config, row, col) {
   
   
    const piece = document.createElement('div');
    piece.className = `piece piece-${
     
     config.width}x${
     
     config.height}`;
    piece.dataset.id = config.id;
    piece.dataset.row = row;
    piece.dataset.col = col;
    
    // 添加棋子名称和ID显示
    const nameElement = document.createElement('div');
    nameElement.className = 'character-name';
    nameElement.textContent = config.name;
    piece.appendChild(nameElement);
    
    if (gameState.showIds) {
   
   
        const idElement = document.createElement('div');
        idElement.className = 'character-id';
        idElement.textContent = config.id;
        piece.appendChild(idElement);
    }
    
    // 绑定拖动和点击事件
    piece.addEventListener('click', selectPiece);
    piece.addEventListener('mousedown', startDrag);
    
    // 计算棋子位置(基于单元格大小和间隙)
    updatePiecePosition(piece, row, col);
    
    document.getElementById('gameBoard').appendChild(piece);
    gameState.pieces.push({
   
   
        element: piece,
        id: config.id,
        name: config.name,
        row: row,
        col: col,
        width: config.width,
        height: config.height
    });
}

3. 核心交互逻辑

(1)拖拽移动实现

支持鼠标拖拽棋子移动,通过事件监听实现拖拽状态管理:

// 开始拖动
function startDrag(e) {
   
   
    if (!gameState.isPlaying) return;
    const pieceElement = e.currentTarget;
    const piece = gameState.pieces.find(p => p.element === pieceElement);
    
    if (piece) {
   
   
        gameState.dragData.isDragging = true;
        gameState.dragData.startX = e.clientX;
        gameState.dragData.startY = e.clientY;
        gameState.dragData.piece = piece;
        
        // 绑定全局拖动和结束事件
        document.addEventListener('mousemove', handleDrag);
        document.addEventListener('mouseup', endDrag);
        e.preventDefault();
    }
}

// 处理拖动逻辑
function handleDrag(e) {
   
   
    if (!gameState.dragData.isDragging) return;
    
    const dx = e.clientX - gameState.dragData.startX;
    const dy = e.clientY - gameState.dragData.startY;
    const threshold = 20; // 拖动阈值,避免误操作
    
    // 判断拖动方向
    if (Math.abs(dx) > threshold || Math.abs(dy) > threshold) {
   
   
        let direction = Math.abs(dx) > Math.abs(dy) 
            ? (dx > 0 ? 'right' : 'left') 
            : (dy > 0 ? 'down' : 'up');
        
        // 计算新位置并检查是否可移动
        const piece = gameState.dragData.piece;
        let newRow = piece.row, newCol = piece.col;
        switch(direction) {
   
   
            case 'up': newRow--; break;
            case 'down': newRow++; break;
            case 'left': newCol--; break;
            case 'right': newCol++; break;
        }
        
        if (canMove(piece, newRow, newCol)) {
   
   
            endDrag();
            movePiece(piece, newRow, newCol);
            gameState.moves++;
            updateDisplay();
            checkWinCondition();
        }
    }
}
(2)移动合法性校验

确保棋子不会超出棋盘边界,也不会与其他棋子重叠:

function canMove(piece, newRow, newCol) {
   
   
    // 边界校验(棋盘5行4列)
    if (newRow < 0 || newCol < 0) return false;
    if (newRow + piece.height - 1 >= 5) return false;
    if (newCol + piece.width - 1 >= 4) return false;

    // 清除原位置数据(临时)
    for (let r = piece.row; r < piece.row + piece.height; r++) {
   
   
        for (let c = piece.col; c < piece.col + piece.width; c++) {
   
   
            gameState.board[r][c] = 0;
        }
    }

    // 检查新位置是否被占用
    let canMove = true;
    for (let r = newRow; r < newRow + piece.height; r++) {
   
   
        for (let c = newCol; c < newCol + piece.width; c++) {
   
   
            if (gameState.board[r][c] !== 0) {
   
   
                canMove = false;
                break;
            }
        }
        if (!canMove) break;
    }

    // 恢复原位置数据
    for (let r = piece.row; r < piece.row + piece.height; r++) {
   
   
        for (let c = piece.col; c < piece.col + piece.width; c++) {
   
   
            gameState.board[r][c] = piece.id;
        }
    }

    return canMove;
}
(3)胜利条件判断

当曹操(2x2棋子)移动到棋盘底部中间位置时,判定游戏胜利:

function checkWinCondition() {
   
   
    const caoCao = gameState.pieces.find(p => p.id === 1); // 曹操ID为1
    if (!caoCao) return;
    
    // 胜利条件:曹操底部到达第4行,且占据中间两列
    if (caoCao.row + caoCao.height - 1 === 4 && 
        caoCao.col === 1 && caoCao.col + caoCao.width - 1 === 2) {
   
   
        
        gameState.isPlaying = false;
        clearInterval(gameState.timer);
        alert(`恭喜你成功逃脱!\n用时: ${
     
     timeDisplay.textContent.split(': ')[1]}\n移动步数: ${
     
     gameState.moves}`);
    }
}

4. 主题切换与响应式设计

通过CSS变量实现明暗主题切换,适配移动端和桌面端:

/* 亮色主题变量 */
:root {
   
   
    --huarong-border-color: #666;
    --huarong-item-bg: #f5f5f5;
    --huarong-item-text: #333;
    /* 更多变量... */
}

/* 暗色主题变量 */
.dark {
   
   
    --huarong-border-color: #bbb;
    --huarong-item-bg: #f5f5f5;
    --huarong-item-text: white;
    /* 更多变量... */
}

/* 响应式布局 */
@media (max-width: 768px) {
   
   
    .game-container {
   
   
        flex-direction: column;
        align-items: center;
    }
    
    .controls {
   
   
        width: 100%;
        max-width: 320px;
    }
}

四、游戏使用说明

  1. 打开HTML文件即可启动游戏,无需安装任何插件
  2. 选择游戏模式(默认横刀立马),点击"开始游戏"按钮开始
  3. 操作方式:
    • 鼠标拖拽:选中棋子后拖动到目标位置
    • 按键控制:选中棋子后,使用方向键或虚拟方向按钮移动
  4. 辅助功能:
    • 查看攻略:点击"查看攻略"获取当前模式的最佳移动步骤
    • 显示/隐藏ID:点击对应按钮切换棋子ID显示状态
    • 主题切换:右上角按钮可切换明暗主题
  5. 胜利目标:移动曹操棋子到达棋盘底部中间的出口位置

五、扩展与优化建议

如果想进一步完善这款游戏,可以考虑以下方向:

  1. 增加难度分级:根据移动步数和时间设置星级评分
  2. 自定义布局:支持用户手动摆放棋子,创建自定义关卡
  3. 历史记录:保存玩家的最佳成绩(最短时间、最少步数)
  4. 音效反馈:添加棋子移动、胜利等音效,提升沉浸感
  5. 分享功能:支持将游戏成绩分享到社交平台

游戏界面

游戏界面
在这里插入图片描述
模式选择界面:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

游戏成功界面:在这里插入图片描述

总的代码(可保存为html文件,直接使用浏览器打开运行)

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>华容道 - 离线版</title>
    <style>
        :root {
     
     
            --huarong-border-color: #666;
            --huarong-arrow-color: #666;
            --huarong-overlay-bg: rgba(255,255,255,0.9);
            --huarong-overlay-text: #333;
            --huarong-text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
            --huarong-button-shadow: 0 4px 8px rgba(0,0,0,0.1);
            --huarong-item-bg: #f5f5f5;
            --huarong-item-text: #333;
            --huarong-item-text-shadow: 1px 1px 2px rgba(255,255,255,0.5);
            --huarong-id-bg: rgba(255,255,255,0.9);
            --huarong-id-text: #333;
            --huarong-time-text: #333;
            --huarong-time-text-shadow: 1px 1px 2px rgba(255,255,255,0.5);
            --huarong-info-panel-bg: rgba(255,255,255,0.9);
            --huarong-info-panel-text: #333;
            --huarong-success-overlay-bg: rgba(255,255,255,0.9);
            --huarong-success-desc-text: #333;
            --huarong-disclaimer-text: #666;
            --huarong-fill-border: #999;
            --huarong-item-hover-shadow: rgba(0,0,0,0.3);
            --huarong-item-disabled-shadow: rgba(100,100,100,0.3);
            --huarong-slider-hover-shadow: rgba(0,0,0,0.4);
            --huarong-slider-disabled-shadow: rgba(100,100,100,0.3);
            --huarong-hint-color: #4CAF50;
        }

        .dark {
     
     
            --huarong-border-color: #bbb;
            --huarong-arrow-color: #bbb;
            --huarong-overlay-bg: rgba(0,0,0,0.8);
            --huarong-overlay-text: white;
            --huarong-text-shadow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BetterInsight

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值