群调飞行棋游戏

星期二, 3月 17, 2026 | 20分钟阅读 | 更新于 星期二, 3月 17, 2026

DOM_ZS

游戏

每主配置:一个棋子(代表“奴隶”)
核心玩法: 主人投骰子对弈!主人轮流掷骰子,移动自己的奴隶棋子。落地后立即执行该格的
调教要求**(主人对奴隶下达并监督)。
胜利条件: 第一个让奴隶棋子到达或超过终点的主人获胜,其奴隶“毕业”!其他主人继续玩到全部完成(可多人同时冲刺,超刺激)。

规则亮点(确保趣味性强 + 穿插前进后退):

  • 纯非性:所有任务只有服从、服务、姿势、轻纪律、宠物扮演、口头赞美、身体小挑战,无任何性行为
  • 安全第一:全程SSC(安全、理智、同意),随时喊“红灯”停止,强度可自行调节。
  • 趣味设计:任务幽默、互动、带仪式感,像在玩“真人版奴隶养成游戏”。
  • 前进/后退穿插:部分格子奖励“主人开心,奴隶加飞”,部分格子惩罚“训练失败,奴隶倒退”,增加策略与笑点。

详细调教要求(落地即执行,完成后看括号里的移动效果):

  1. 奴跪下为自己的主人进行足部崇拜(舔脚、吸脚趾),持续骰子点数×10秒。
  2. 奴为对方奴戴上项圈并牵行一圈。
  3. 奴自扇屁股(轻拍或重拍),点数×2下,同时抵消对方一次物理攻击。
  4. 奴用舌头为自己的主人清洁鞋子或脚底,持续骰子点数×5秒。
  5. 奴给对方奴戴眼罩,亲吻对方脖子10秒。
  6. 奴摆出M字腿姿势暴露给两位主人观看,维持骰子点数×5秒。
  7. 奴为自己的主人提供跪式口交服务(模拟),持续骰子点数×5秒。
  8. 奴临时“反客为主”,命令对方奴跪下叫“主人”点子数声。
  9. 奴自绑双手(用丝带或手铐),抵消对方一次前进。
  10. 奴用蜡烛滴蜡在自己大腿(安全位置),滴数=骰子点数×2。
  11. 奴为对方奴进行轻度鞭打(软鞭或手掌),次数对应骰子点数。
  12. 奴临时支配对方奴舔自己脚,持续骰子点数×15秒。
  13. 奴摆出宠物姿势(四肢着地、汪汪叫),持续骰子点数X2并额外移动1格。
  14. 奴狗叫并摇臀,次数=骰子点数×2。
  15. 奴强制对方奴舔自己的脚趾,持续骰子点数×10秒。
  16. 奴表演缓慢脱衣舞给所有人看,完成后可让对方主人少掷一次骰。
  17. 奴自夹乳头(用夹子或手指),夹住骰子点数×10秒。
  18. 奴为自己的主人提供骑乘式服务,持续骰子点数×10秒。
  19. 奴把对方奴绑成龟甲缚姿势展示,维持骰子点数×20秒。
  20. 奴跪下高潮边缘控制(自摸但不能高潮)。
  21. 奴为两位主人同时口侍手指(模拟口交),每人点数秒。
  22. 奴让对方奴骑在自己背上绕圈走1圈。
  23. 奴自打耳光(轻度),次数=骰子点数×3,同时获得一次额外掷骰机会。
  24. 奴跪下为自己的主人献上“宠物式”摩擦大腿,维持骰子点数×10秒。
  25. 奴表演“乞求高潮”姿势(双手举高、跪地恳求),持续骰子点数×5秒。
  26. 奴摆出后入式姿势让主人轻拍,拍数=骰子点数×5。
  27. 奴临时支配对方奴为自己做口交姿势展示,持续骰子点数×15秒。
  28. 奴表演“乞求高潮”姿势(双手举高、跪地恳求),持续骰子点数×5秒。
  29. 奴为自己的主人献上深喉服务(模拟),持续骰子点数X5秒。
  30. 奴命令对方奴爬到自己胯下亲吻,持续骰子点数×20秒。
  31. 奴跪下为自己的主人献上“宠物式”摩擦大腿,持续骰子点数×10秒。
  32. 奴表演“乞求高潮”姿势(双手举高、跪地恳求),持续骰子点数×5秒。
  33. 奴让对方奴为自己做足部按摩,持续骰子点数×20秒。
  34. 奴把对方奴按倒轻度骑乘,持续骰子点数×10秒。
  35. 奴自扇私密部位(轻拍),次数=骰子点数×4,同时对方少掷一次骰。
  36. 奴命令对方奴学狗叫并舔自己手指。
  37. 奴摆出完全暴露的“展示姿势”给所有人评分,点数越高维持越久;若获好评,可让本队额外前进骰子点数格。
  38. 奴表演“乞求高潮”姿势(双手举高、跪地恳求),持续骰子点数×5秒。

这个设计完全围绕“多主多奴调教”展开,每一格都是主人对奴隶的真实小训练,同时主人之间用骰子对弈竞争,趣味性爆棚!

源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>趣乐飞行棋</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            background: linear-gradient(145deg, #1e2b3c 0%, #0f1a24 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Segoe UI', Roboto, system-ui, -apple-system, sans-serif;
            padding: 20px;
            overflow-x: hidden;
            position: relative;
        }

        .game-container {
            max-width: 1300px;
            width: 100%;
            background: rgba(255, 255, 255, 0.08);
            backdrop-filter: blur(4px);
            border-radius: 60px 60px 40px 40px;
            padding: 30px 30px 40px;
            box-shadow: 0 30px 40px -15px rgba(0,0,0,0.6), inset 0 1px 3px rgba(255,255,255,0.1);
            border: 1px solid rgba(255,255,255,0.06);
            transition: filter 0.2s ease;
            position: relative;
            z-index: 1;
        }

        /* 掷骰动画遮罩 */
        .dice-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            backdrop-filter: blur(5px);
            z-index: 999;
            display: flex;
            justify-content: center;
            align-items: center;
            visibility: hidden;
            opacity: 0;
            transition: opacity 0.3s ease, visibility 0s 0.3s;
        }
        .dice-overlay.show {
            visibility: visible;
            opacity: 1;
            transition: opacity 0.3s ease, visibility 0s 0s;
        }
        .big-dice {
            width: 200px;
            height: 200px;
            background: white;
            border-radius: 50px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 140px;
            font-weight: 800;
            box-shadow: 0 20px 0 #b57c1a, 0 40px 40px black, 0 0 0 8px #ffd966, 0 0 0 12px #ffb703;
            animation: dicePop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards, diceSpin 0.6s ease-in-out;
            transform-origin: center;
            color: #2d1f00;
            background: linear-gradient(145deg, #fff8e0, #ffe39c);
            border: 4px solid #ffb703;
            text-shadow: 8px 8px 0 rgba(0,0,0,0.2);
        }

        @keyframes dicePop {
            0% { transform: scale(0.2) rotate(-20deg); opacity: 0; }
            50% { transform: scale(1.1) rotate(5deg); opacity: 1; }
            100% { transform: scale(1) rotate(0deg); opacity: 1; }
        }
        @keyframes diceSpin {
            0% { transform: rotateX(0deg) rotateY(0deg); }
            25% { transform: rotateX(180deg) rotateY(90deg); }
            50% { transform: rotateX(360deg) rotateY(180deg); }
            75% { transform: rotateX(540deg) rotateY(270deg); }
            100% { transform: rotateX(720deg) rotateY(360deg); }
        }

        /* 胜利动画遮罩 */
        .victory-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.7);
            backdrop-filter: blur(8px);
            z-index: 2000;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            visibility: hidden;
            opacity: 0;
            transition: opacity 0.5s ease, visibility 0s 0.5s;
            pointer-events: none;
        }
        .victory-overlay.show {
            visibility: visible;
            opacity: 1;
            transition: opacity 0.5s ease, visibility 0s 0s;
            pointer-events: all;
        }
        .victory-content {
            text-align: center;
            animation: victoryPop 1s ease-out;
        }
        .victory-emoji {
            font-size: 120px;
            filter: drop-shadow(0 0 30px gold);
            margin-bottom: 20px;
            animation: victoryFloat 2s infinite;
        }
        .victory-text {
            font-size: 80px;
            font-weight: 900;
            color: #ffd966;
            text-shadow: 0 0 20px #ffb703, 0 0 40px #ff8c00, 4px 4px 0 #b57c1a;
            letter-spacing: 8px;
            margin-bottom: 30px;
            animation: victoryGlow 1.5s infinite;
        }
        .victory-sub {
            font-size: 40px;
            color: white;
            text-shadow: 0 0 15px cyan;
        }
        .restart-btn {
            background: #f5c542;
            border: none;
            font-size: 32px;
            padding: 20px 60px;
            border-radius: 80px;
            font-weight: 800;
            color: #1d2c3a;
            box-shadow: 0 10px 0 #b57c1a, 0 5px 30px gold;
            cursor: pointer;
            margin-top: 50px;
            transition: 0.1s linear;
            border: 3px solid white;
        }
        .restart-btn:active {
            transform: translateY(6px);
            box-shadow: 0 4px 0 #b57c1a, 0 8px 30px orange;
        }
        @keyframes victoryPop {
            0% { transform: scale(0.2); opacity: 0; }
            80% { transform: scale(1.1); }
            100% { transform: scale(1); opacity: 1; }
        }
        @keyframes victoryFloat {
            0% { transform: translateY(0px); }
            50% { transform: translateY(-20px); }
            100% { transform: translateY(0px); }
        }
        @keyframes victoryGlow {
            0% { text-shadow: 0 0 20px #ffd966, 0 0 40px #ffb703, 4px 4px 0 #b57c1a; }
            50% { text-shadow: 0 0 40px #ffd966, 0 0 80px #ffb703, 4px 4px 0 #b57c1a; }
            100% { text-shadow: 0 0 20px #ffd966, 0 0 40px #ffb703, 4px 4px 0 #b57c1a; }
        }

        /* 彩带画布 */
        #confetti-canvas {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 1999;
        }

        /* 棋盘轨道 */
        .board-rail {
            background: #2d3f4e;
            padding: 25px 30px;
            border-radius: 180px 180px 60px 60px;
            box-shadow: inset 0 -5px 0 #1c2935, inset 0 5px 10px #3f5568, 0 15px 20px #0b1219;
            border-bottom: 3px solid #ffd966;
            transition: filter 0.2s;
        }

        .grid-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 12px;
            padding: 0 15px;
        }

        .player-tag {
            display: flex;
            align-items: center;
            gap: 12px;
            background: #253544;
            padding: 10px 30px 10px 20px;
            border-radius: 50px;
            box-shadow: inset 0 1px 4px #101b24, 0 6px 0 #0e1a22;
            border-bottom: 2px solid #ffe484;
        }

        .red-die, .blue-die {
            width: 48px;
            height: 48px;
            background: white;
            border-radius: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 28px;
            font-weight: 800;
            box-shadow: 0 5px 0 #a0a0a0, 0 8px 10px black;
            transition: 0.1s ease;
        }
        .red-die { background: #ff7675; color: #440000; border: 2px solid #ffd0a4; }
        .blue-die { background: #74b9ff; color: #003f6f; border: 2px solid #b3e0ff; }
        .turn-indicator {
            font-size: 18px;
            font-weight: 600;
            background: #2f4253;
            color: #ffd966;
            padding: 10px 30px;
            border-radius: 40px;
            letter-spacing: 1px;
            box-shadow: inset 0 -2px 0 #1a2933;
        }

        /* 格子轨道 */
        .track {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            margin: 15px 0 5px;
        }

        .cell {
            width: calc(100% / 13 - 6px);
            min-width: 70px;
            height: 90px;
            background: #edf2f7;
            margin: 3px;
            border-radius: 20px 12px 12px 12px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            box-shadow: 0 8px 0 #8b9aab, 0 12px 15px -5px #04131f;
            transition: all 0.15s;
            color: #1a2b36;
            font-weight: 600;
            position: relative;
            cursor: help;
            border: 2px solid #f7e05e;
            padding: 5px 2px;
            text-align: center;
        }

        .cell:hover {
            transform: translateY(-4px);
            box-shadow: 0 12px 0 #7b8a9b, 0 18px 20px -5px #020b12;
            background: #fff7cf;
            border-color: #ffb347;
        }

        .cell-number {
            font-size: 13px;
            background: #2b404e;
            color: white;
            width: 28px;
            line-height: 22px;
            border-radius: 30px;
            margin-top: -20px;
            margin-bottom: 4px;
            font-weight: 700;
            box-shadow: inset 0 -2px 0 #15262e;
        }

        .cell-icon {
            font-size: 22px;
            line-height: 1;
            filter: drop-shadow(0 3px 2px rgba(0,0,0,0.3));
            display: flex;
            align-items: center;
            gap: 4px;
        }

        .cell-desc {
            font-size: 9px;
            font-weight: 500;
            background: #ffffffc4;
            padding: 3px 5px;
            border-radius: 30px;
            color: #0b1a24;
            max-width: 95%;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            margin-top: 3px;
            box-shadow: inset 0 1px 3px #cddae4;
        }

        /* 格子内小图片 */
        .cell-img {
            max-width: 20px;
            max-height: 20px;
            border-radius: 4px;
            margin-left: 2px;
            vertical-align: middle;
        }

        /* 棋子标记 */
        .piece {
            font-size: 26px;
            line-height: 1;
            position: absolute;
            bottom: -10px;
            right: -6px;
            text-shadow: 0 4px 3px black;
            filter: drop-shadow(0 0 4px gold);
        }

        .red-piece {
            color: #e63946;
            left: 2px;
            bottom: -6px;
        }
        .blue-piece {
            color: #1e6f9f;
            right: 2px;
            bottom: -6px;
        }

        /* 控制区域 */
        .control-panel {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 35px;
            background: #1c2b37d9;
            border-radius: 90px;
            padding: 18px 30px;
            border: 1px solid #ffe270;
            box-shadow: 0 15px 20px #060d13;
        }

        .dice-area {
            display: flex;
            gap: 30px;
            align-items: center;
        }

        .dice-box {
            background: #2f404e;
            border-radius: 30px;
            padding: 10px 25px;
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .roll-btn {
            background: #f5c542;
            border: none;
            font-size: 32px;
            padding: 12px 35px;
            border-radius: 80px;
            font-weight: 800;
            color: #1d2c3a;
            box-shadow: 0 10px 0 #b57c1a, 0 5px 20px black;
            transition: 0.05s linear;
            cursor: pointer;
            letter-spacing: 2px;
            position: relative;
            overflow: hidden;
        }
        .roll-btn:active {
            transform: translateY(6px);
            box-shadow: 0 4px 0 #b57c1a, 0 8px 15px black;
        }
        .roll-btn.disabled {
            opacity: 0.5;
            pointer-events: none;
            filter: grayscale(0.6);
        }
        .roll-btn::after {
            content: '';
            position: absolute;
            top: -50%;
            left: -60%;
            width: 200%;
            height: 200%;
            background: rgba(255,255,255,0.3);
            transform: rotate(30deg);
            transition: left 0.3s;
        }
        .roll-btn:active::after {
            left: 100%;
        }

        .action-log {
            background: #0f1f2b;
            border-radius: 60px;
            padding: 15px 30px;
            color: #ffdb8e;
            font-size: 18px;
            font-weight: 600;
            max-width: 450px;
            border-left: 6px solid #ffbe3f;
            box-shadow: inset 0 2px 8px black;
        }

        .tooltip-custom {
            position: fixed;
            background: #1e2f3d;
            color: #faeac2;
            padding: 14px 20px;
            border-radius: 30px 30px 30px 8px;
            font-size: 15px;
            font-weight: 500;
            max-width: 350px;
            box-shadow: 0 15px 20px #020a10, 0 0 0 2px #fdc62e;
            backdrop-filter: blur(6px);
            border: 1px solid #ffcf7a;
            pointer-events: none;
            z-index: 1000;
            line-height: 1.5;
            transition: opacity 0.2s;
            opacity: 0;
        }

        .tooltip-img {
            max-width: 100%;
            max-height: 100px;
            border-radius: 12px;
            margin-top: 8px;
            border: 2px solid #ffd966;
            display: block;
        }

        .footer-note {
            text-align: center;
            color: #b7cdde;
            margin-top: 20px;
            font-size: 14px;
        }

        .flash-effect {
            animation: flash 0.4s 2;
        }
        @keyframes flash {
            0% { background-color: rgba(255,215,0,0.1); }
            50% { background-color: rgba(255,215,0,0.4); }
            100% { background-color: rgba(255,215,0,0.1); }
        }
    </style>
</head>
<body>
    <!-- 巨型骰子弹窗 -->
    <div id="diceOverlay" class="dice-overlay">
        <div id="bigDice" class="big-dice">⚀</div>
    </div>

    <!-- 胜利动画遮罩 -->
    <div id="victoryOverlay" class="victory-overlay">
        <div class="victory-content">
            <div id="victoryEmoji" class="victory-emoji">🏆</div>
            <div id="victoryText" class="victory-text">红方胜利</div>
            <div class="victory-sub">🎉 恭喜到达终点 🎉</div>
            <button class="restart-btn" id="restartBtn">再 玩 一 局</button>
        </div>
    </div>

    <!-- 彩带画布 -->
    <canvas id="confetti-canvas"></canvas>

    <div class="game-container" id="gameContainer">
        <!-- 棋盘头 显示红蓝状态 -->
        <div class="grid-header">
            <div class="player-tag">
                <span class="red-die" id="redDice">⚀</span>
                <span style="color:#ffb9b9; font-weight:600;">红方</span>
            </div>
            <div class="turn-indicator" id="turnIndicator">🔴 红方回合</div>
            <div class="player-tag">
                <span style="color:#b3deff; font-weight:600;">蓝方</span>
                <span class="blue-die" id="blueDice">⚀</span>
            </div>
        </div>

        <!-- 棋盘格 52格 动态绘制 -->
        <div class="board-rail" id="boardTrack"></div>

        <!-- 控制栏 -->
        <div class="control-panel">
            <div class="dice-area">
                <div class="dice-box">
                    <span style="color:white; font-size:20px;">🎲 本轮</span>
                    <span id="diceResult" style="font-size:48px; font-weight:800; color:#ffe189;">0</span>
                </div>
                <button class="roll-btn" id="rollBtn">掷 骰</button>
            </div>
            <div class="action-log" id="actionMessage">
                点击掷骰开始 🎲
            </div>
        </div>
        <div class="footer-note">✨ 率先抵达终点者获胜 ✨</div>
    </div>

    <!-- 自定义悬浮tooltip -->
    <div id="cellTooltip" class="tooltip-custom"></div>

    <script>
        (function() {
            // ---------- 游戏配置 ----------
            const TOTAL_CELLS = 61;
            const WINNING_CELL = TOTAL_CELLS - 1; 

            // 52个格子详情(索引0~51)包含图片示例
            const cellDetails = [
                { emoji: '🏁', desc: '起点 · 全体集合', game: '起点', img: 'https://picsum.photos/50/50?random=1' },
                { emoji:'🐶', desc: '学狗叫', game:'奴狗叫并摇臀,次数=骰子点数×2'},
				{ emoji:'💃',desc:  '即兴舞蹈', game:'奴表演缓慢脱衣舞给所有人看,完成后可让对方主人少掷一次骰'},
				{ emoji:'🙇‍♀️',desc:  '奴自夹乳头',game: '奴自夹乳头(用夹子或手指),夹住骰子点数×10秒'},
				{ emoji:'🐎', desc: '奴为主人提供骑乘服务', game:'奴为自己的主人提供骑乘式服务,持续骰子点数×10秒'},
				{ emoji:'👨‍👨‍👧', desc: '口侍手指',game: '奴为两位主人同时口侍手指(模拟口交),每人点数秒'},
				{ emoji:'3️⃣', desc: '前进3步',game: '运气真好!直接前进3步', move: 3},
				{ emoji:'🍌',desc:  '深喉服务,前进2步', game:'奴为自己的主人献上深喉服务(模拟),持续骰子点数X5秒', move: 2},
				{ emoji:'🔙',desc:  '后退4步',game: '不小心退后3步', move: -3},
				{ emoji:'🕺', desc: '蹲立',game: '奴表演蹲立,维持骰子点数×5秒', img: 'https://picsum.photos/50/50?random=54'},
				{ emoji:'🐎', desc: '让对方奴骑', game:'奴让对方奴骑在自己背上绕圈走1圈'},
				{ emoji:'🙇‍♀️',desc:  '对方奴侍奉', game:'奴命令对方奴爬到自己胯下亲吻,持续骰子点数×20秒'},
				{ emoji:'🐧',desc:  '企鹅走路',game: '像企鹅一样走(后退1步)', move: -1},
				{ emoji:'🍪', desc: '零食奖励',game:'前进1步 (奖励零食)', move: 1},
				{ emoji:'🦀', desc: '螃蟹步',game: '横着走(后退3步)', move: -3},
				{ emoji:'👣',desc:  '足部崇拜', game:'奴跪下为自己的主人进行足部崇拜(舔脚、吸脚趾),持续骰子点数×10秒'},
				{ emoji:'🐕‍🚶', desc: '项圈牵行', game:'奴为对方奴戴上项圈并牵行一圈'},
				{ emoji:'🙇‍♀️', desc: '前进4步', game:'冲刺3步', move: 3},
				{ emoji:'🙋‍♀️',desc:  '自扇屁股',game: '奴自扇屁股(轻拍或重拍),点数×2下,同时抵消对方一次物理攻击'},
				{ emoji:'👣', desc: '清洁脚底',game: '奴用舌头为自己的主人清洁鞋子或脚底,持续骰子点数×5秒'},
				{ emoji:'💏',desc:  '亲吻同类', game:'奴给对方奴戴眼罩,亲吻对方脖子10秒'},
				{ emoji:'🕺', desc: 'M字展示',game: '奴摆出M字腿姿势暴露给主人观看,维持骰子点数×5秒', img: 'https://picsum.photos/50/50?random=54'},
				{ emoji:'🔙',desc:  '后退3步', game:'哎哟,退3步', move: -3},
				{ emoji:'🍌',desc:  '跪侍主人', game:'奴为自己的主人提供跪式口交服务(模拟),持续骰子点数×5秒'},
				{ emoji:'🎁', desc: '惊喜礼物',game: '前进2步', move: 2},
				{ emoji:'🕯️',desc:  '滴蜡', game:'奴用蜡烛滴蜡在自己大腿(安全位置),滴数=骰子点数×2'},
				{ emoji:'🙋‍♀️',desc:  '鞭打同类',game: '奴为对方奴进行轻度鞭打(软鞭或手掌),次数对应骰子点数'},
				{ emoji:'🐕‍🦺',desc:  '宠物姿势', game:'奴摆出宠物姿势(四肢着地、汪汪叫),持续骰子点数X2并额外移动1格', move: 1},
				{ emoji:'🦶',desc:  '同类舔脚', game:'奴临时支配对方奴舔自己脚,持续骰子点数×15秒'},
				{ emoji:'🕺', desc: '检查',game: '奴表演检查体位,维持骰子点数×5秒', img: 'hhttps://picsum.photos/50/50?random=54'},
				{ emoji:'🐌',desc:  '慢吞吞', game:'后退1步', move: -1},
				{ emoji:'🐎', desc: '主人骑行',game: '奴为自己的主人提供骑乘式服务,持续骰子点数×10秒'},
				{ emoji:'🤟', desc: '边缘', game:'奴跪下高潮边缘控制(自摸但不能高潮),获得前进4步', move: 4},
				{ emoji:'👑',desc:  '国王游戏', game:'命令任意一个奴学狗叫点数声'},
				{ emoji:'💔',desc:  '奴一败涂地',game: '后退3步', move: -3},
				{ emoji:'🚀',desc:  '火箭', game:'前进4步', move: 4},
				{ emoji:'👨‍👩‍👧',desc:  '支配', game:'奴临时支配对方奴为自己做口交姿势展示,姿势数=骰子点数'},
				{ emoji:'🕺', desc: '侯责的奴',game: '奴摆出侯责姿势,维持骰子点数×5秒,根据效果主人给予责罚和奖励零食', img: 'https://picsum.photos/50/50?random=54'},
				{ emoji:'💏',desc:  '亲吻同类', game:'奴给对方奴戴眼罩,亲吻对方脖子10秒'},
				{ emoji:'🐕‍', desc: '狗狗撒尿', game:'狗狗生动形象表演抬腿撒尿', img: 'https://picsum.photos/50/50?random=54'},
				{ emoji:'🐢',desc:  '乌龟', game:'后退2步', move: -2},
				{ emoji:'👨‍👨‍👧',desc:  '口手侍手指',game: '奴为两位主人同时口手侍手指(模拟口交),每人点数秒'},
				{ emoji:'🤹',desc:  '对方奴侍奉',game: '奴命令对方奴爬到自己胯下亲吻,持续骰子点数×20秒'},
				{ emoji:'🔙',desc:  '奴的错',game: '严重失误后退4步', move: -4},
				{ emoji:'🎯',desc:  '靶心', game:'前进2步', move: 2},
				{ emoji:'🍕',desc:  '奖励零食',game: '前进1步', move: 1},
				{ emoji:'🥤',desc:  '宠物行动',game: '奴跪下为自己的主人献上“宠物式”摩擦大腿,持续骰子点数×10秒。'},
				{ emoji:'🐉', desc: '舞龙', game:'前进3步', move: 3},
				{ emoji:'🙎',desc:  '支配同类', game:'奴让对方奴为自己做足部按摩,持续骰子点数×20秒'},
				{ emoji:'🌋', desc: '火山喷发', game:'后退4步', move: -4},
				{ emoji:'🏆',desc:  '奴是主的骄傲', game:'前进4步', move: 4},
				{ emoji:'🕺', desc: '一切都是奴的错',game: '奴摆出面壁鞭刑姿势,主人鞭打×2下,根据效果主人赏赐零食安抚', img: 'https://picsum.photos/50/50?random=54'},
				{ emoji:'🐎',desc:  '骑狗', game:'奴把对方奴按倒轻度骑乘,持续骰子点数×10秒'},
				{ emoji:'🙋‍♀️', desc: '奴的自责',game: '奴自扇私密部位(轻拍),次数=骰子点数×4'},
				{ emoji:'🔙', desc: '后退1步', game:'小退一步',move: -1},
				{ emoji:'🐕',desc:  '遛狗', game:'前进2步', move: 2},
				{ emoji:'🙋‍♀️',desc:  '鞭打同类',game: '奴为对方奴进行轻度鞭打(软鞭或手掌),次数对应骰子点数'},
				{ emoji:'👆',desc:  '舔指', game:'奴命令对方奴学狗叫并舔自己手指'},
				{ emoji:'🙇‍♀️',desc:  '奴的乞求',game: '奴表演“乞求高潮”姿势(双手举高、跪地恳求),持续骰子点数×5秒', img: 'https://picsum.photos/50/50?random=54'},
				{ emoji:'🎢',desc:  '过山车', game:'前进1步', move: 1},
				{ emoji:'🏁', desc: '终点冲刺', game:'恭喜到达终点!'} ,
            ];

            // 保证刚好52格
            while (cellDetails.length < TOTAL_CELLS) {
                cellDetails.push({ emoji: '🎲', desc: '随机表演', game: '自由发挥一个才艺', img: 'https://picsum.photos/50/50?random=54' });
            }
            // 截断前52个
            const finalCells = cellDetails.slice(0, TOTAL_CELLS);

            // ---------- 游戏状态 ----------
            let redPos = 0;
            let bluePos = 0;
            let currentTurn = 'red';
            let diceValue = 0;
            let gameActive = true;
            let isRolling = false;
            let winner = null; // 'red' 或 'blue'

            // DOM元素
            const boardEl = document.getElementById('boardTrack');
            const redDiceEl = document.getElementById('redDice');
            const blueDiceEl = document.getElementById('blueDice');
            const diceResultSpan = document.getElementById('diceResult');
            const turnIndicator = document.getElementById('turnIndicator');
            const actionMsg = document.getElementById('actionMessage');
            const rollBtn = document.getElementById('rollBtn');
            const tooltip = document.getElementById('cellTooltip');
            const diceOverlay = document.getElementById('diceOverlay');
            const bigDice = document.getElementById('bigDice');
            const gameContainer = document.getElementById('gameContainer');
            const victoryOverlay = document.getElementById('victoryOverlay');
            const victoryEmoji = document.getElementById('victoryEmoji');
            const victoryText = document.getElementById('victoryText');
            const restartBtn = document.getElementById('restartBtn');

            // 彩带
            const canvas = document.getElementById('confetti-canvas');
            const ctx = canvas.getContext('2d');
            let width, height;
            let particles = [];
            let animationId = null;

            function resizeCanvas() {
                width = window.innerWidth;
                height = window.innerHeight;
                canvas.width = width;
                canvas.height = height;
            }
            window.addEventListener('resize', resizeCanvas);
            resizeCanvas();

            class Particle {
                constructor() {
                    this.x = Math.random() * width;
                    this.y = Math.random() * height - height;
                    this.size = Math.random() * 8 + 4;
                    this.speedY = Math.random() * 5 + 3;
                    this.speedX = Math.random() * 2 - 1;
                    this.color = `hsl(${Math.random() * 360}, 80%, 60%)`;
                }
                update() {
                    this.y += this.speedY;
                    this.x += this.speedX;
                    if (this.y > height) {
                        this.y = -this.size;
                        this.x = Math.random() * width;
                    }
                }
                draw() {
                    ctx.fillStyle = this.color;
                    ctx.fillRect(this.x, this.y, this.size, this.size * 0.4);
                }
            }

            function startConfetti() {
                particles = [];
                for (let i = 0; i < 150; i++) {
                    particles.push(new Particle());
                }
                if (animationId) cancelAnimationFrame(animationId);
                function animate() {
                    ctx.clearRect(0, 0, width, height);
                    particles.forEach(p => {
                        p.update();
                        p.draw();
                    });
                    animationId = requestAnimationFrame(animate);
                }
                animate();
            }

            function stopConfetti() {
                if (animationId) {
                    cancelAnimationFrame(animationId);
                    animationId = null;
                }
                ctx.clearRect(0, 0, width, height);
            }

            // 检查胜利
            function checkVictory() {
                if (!gameActive) return false;
                if (redPos === WINNING_CELL) {
                    winner = 'red';
                    gameActive = false;
                    showVictory('red');
                    return true;
                } else if (bluePos === WINNING_CELL) {
                    winner = 'blue';
                    gameActive = false;
                    showVictory('blue');
                    return true;
                }
                return false;
            }

            function showVictory(player) {
                victoryEmoji.textContent = player === 'red' ? '🔴' : '🔵';
                victoryText.textContent = player === 'red' ? '红方胜利' : '蓝方胜利';
                victoryOverlay.classList.add('show');
                startConfetti();
                rollBtn.classList.add('disabled');
            }

            function hideVictory() {
                victoryOverlay.classList.remove('show');
                stopConfetti();
            }

            // 绘制棋盘
            function renderBoard() {
                let html = '<div class="track">';
                finalCells.forEach((cell, idx) => {
                    let pieces = '';
                    if (redPos === idx) pieces += '<span class="piece red-piece" style="left:2px;">🔴</span>';
                    if (bluePos === idx) pieces += '<span class="piece blue-piece" style="right:2px;">🔵</span>';
                    if (redPos === idx && bluePos === idx) {
                        pieces = '<span class="piece red-piece" style="left:2px;">🔴</span><span class="piece blue-piece" style="right:2px;">🔵</span>';
                    }

                    const imgHtml = cell.img ? `<img src="${cell.img}" class="cell-img" alt="img">` : '';

                    html += `<div class="cell" data-index="${idx}" data-emoji="${cell.emoji}" data-desc="${cell.desc}" data-game="${cell.game}" data-move="${cell.move ?? ''}" data-img="${cell.img || ''}">
                        <span class="cell-number">${idx+1}</span>
                        <span class="cell-icon">${cell.emoji}${imgHtml}</span>
                        <span class="cell-desc">${cell.desc}</span>
                        ${pieces}
                    </div>`;
                });
                html += '</div>';
                boardEl.innerHTML = html;

                document.querySelectorAll('.cell').forEach(cell => {
                    cell.addEventListener('mouseenter', showTooltip);
                    cell.addEventListener('mouseleave', hideTooltip);
                });
            }

            function showTooltip(e) {
                const cell = e.currentTarget;
                const idx = cell.dataset.index;
                const data = finalCells[idx];
                const moveText = data.move ? (data.move > 0 ? ` 🚩前进 ${data.move} 步` : ` 🔙后退 ${Math.abs(data.move)} 步`) : ' · 表演格';
                const imgHtml = data.img ? `<img src="${data.img}" class="tooltip-img" alt="格子图片">` : '';
                tooltip.style.opacity = '1';
                tooltip.style.left = (e.pageX + 20) + 'px';
                tooltip.style.top = (e.pageY - 40) + 'px';
                tooltip.innerHTML = `<strong style="color:#ffd966">${data.emoji} 格子 ${+idx+1} · ${data.desc}</strong><br>${data.game} ${moveText}${imgHtml}`;
            }

            function hideTooltip() {
                tooltip.style.opacity = '0';
            }

            function updateUI() {
                const diceMap = ['⚀', '⚁', '⚂', '⚃', '⚄', '⚅'];
                redDiceEl.textContent = diceMap[Math.floor(Math.random() * 6)];
                blueDiceEl.textContent = diceMap[Math.floor(Math.random() * 6)];
                turnIndicator.innerHTML = !gameActive ? '⏸️ 游戏结束' : (currentTurn === 'red' ? '🔴 红方回合 · 掷骰吧' : '🔵 蓝方回合 · 掷骰吧');
                redDiceEl.style.border = currentTurn === 'red' && gameActive ? '4px solid #ffb703' : '2px solid #afafaf';
                blueDiceEl.style.border = currentTurn === 'blue' && gameActive ? '4px solid #ffb703' : '2px solid #afafaf';
            }

            function applyCellEffect(player) {
                const pos = player === 'red' ? redPos : bluePos;
                const cell = finalCells[pos];
                let moveDelta = cell.move || 0;
                if (moveDelta !== 0) {
                    if (moveDelta > 5) moveDelta = 5;
                    if (moveDelta < -5) moveDelta = -5;
                    actionMsg.innerText += ` · 触发了${moveDelta>0?'前进':'后退'} ${Math.abs(moveDelta)} 步`;
                    if (player === 'red') {
                        let newPos = redPos + moveDelta;
                        newPos = Math.min(TOTAL_CELLS-1, Math.max(0, newPos));
                        redPos = newPos;
                    } else {
                        let newPos = bluePos + moveDelta;
                        newPos = Math.min(TOTAL_CELLS-1, Math.max(0, newPos));
                        bluePos = newPos;
                    }
                } else {
                    actionMsg.innerText += ` · 任务:${cell.desc}`;
                }
                renderBoard();
            }

            async function animateDice(finalValue) {
                return new Promise((resolve) => {
                    diceOverlay.classList.add('show');
                    const diceFaces = ['⚀', '⚁', '⚂', '⚃', '⚄', '⚅'];
                    let spinCount = 0;
                    const spinInterval = setInterval(() => {
                        const randomFace = diceFaces[Math.floor(Math.random() * 6)];
                        bigDice.textContent = randomFace;
                        spinCount++;
                        if (spinCount > 8) {
                            clearInterval(spinInterval);
                            bigDice.textContent = diceFaces[finalValue - 1];
                            bigDice.style.animation = 'none';
                            bigDice.offsetHeight;
                            bigDice.style.animation = 'dicePop 0.3s ease, diceSpin 0.5s ease';
                            setTimeout(() => {
                                diceOverlay.classList.remove('show');
                                resolve();
                            }, 600);
                        }
                    }, 80);
                });
            }

            async function handleRoll() {
                if (!gameActive || isRolling) return;

                isRolling = true;
                rollBtn.classList.add('disabled');

                const dice = Math.floor(Math.random() * 6) + 1;
                diceValue = dice;
                diceResultSpan.textContent = dice;

                await animateDice(dice);

                const player = currentTurn;
                const playerName = player === 'red' ? '红方' : '蓝方';
                actionMsg.innerText = `${playerName} 掷出 ${dice} 点 · `;

                if (player === 'red') {
                    let newPos = redPos + dice;
                    if (newPos >= TOTAL_CELLS) newPos = TOTAL_CELLS - 1;
                    redPos = newPos;
                } else {
                    let newPos = bluePos + dice;
                    if (newPos >= TOTAL_CELLS) newPos = TOTAL_CELLS - 1;
                    bluePos = newPos;
                }
                actionMsg.innerText += `移动到格子 ${player === 'red'? redPos+1 : bluePos+1}`;

                renderBoard();
                applyCellEffect(player);

                // 检查胜利
                if (checkVictory()) {
                    renderBoard();
                    updateUI();
                    isRolling = false;
                    return;
                }

                currentTurn = currentTurn === 'red' ? 'blue' : 'red';
                updateUI();
                renderBoard();

                gameContainer.classList.add('flash-effect');
                setTimeout(() => gameContainer.classList.remove('flash-effect'), 500);

                isRolling = false;
                rollBtn.classList.remove('disabled');
            }

            function restartGame() {
                redPos = 0;
                bluePos = 0;
                currentTurn = 'red';
                gameActive = true;
                winner = null;
                diceResultSpan.textContent = '0';
                actionMsg.innerText = '新的一局!红方先掷骰';
                hideVictory();
                renderBoard();
                updateUI();
                rollBtn.classList.remove('disabled');
            }

            // 事件绑定
            rollBtn.addEventListener('click', handleRoll);
            restartBtn.addEventListener('click', restartGame);

            document.addEventListener('mousemove', (e) => {
                if (tooltip.style.opacity === '1') {
                    tooltip.style.left = (e.pageX + 20) + 'px';
                    tooltip.style.top = (e.pageY - 40) + 'px';
                }
            });

            // 启动
            restartGame();
        })();
    </script>
</body>
</html>

© 2024 - 2026 我的梦境博客

🌱 Powered by Hugo with theme Dream.

关于我

👋 你好,我是DOM_zs!

这是我的个人博客。

📧 联系我:zhangsong192@proton.me

社交链接

© 2024 - 2026 我的梦境博客

🌱 Powered by Hugo with theme Dream.