吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1984|回复: 44
收起左侧

[其他原创] 围住小猫改进版游戏,橘猫、虎斑、狸花猫,根据小猫性格改良的一款小游戏,附赠...

[复制链接]
Summer000 发表于 2026-6-22 11:42
[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>围住小猫-By Mr yang</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: "Microsoft YaHei", "PingFang SC", -apple-system, sans-serif;
            min-height: 100vh;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
            display: flex;
            flex-direction: column;
            align-items: center;
            overflow-x: hidden;
        }
        
        /* 页面容器 */
        .page {
            display: none;
            width: 100%;
            max-width: 100%;
            padding: 20px;
            animation: fadeIn 0.3s ease;
        }
        
        .page.active {
            display: block;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        /* ========== 选择页面 ========== */
        .select-title {
            font-size: 36px;
            color: white;
            text-shadow: 3px 3px 6px rgba(0,0,0,0.3);
            margin: 30px 0 20px;
            text-align: center;
            font-weight: bold;
        }
        
        .select-subtitle {
            color: rgba(255,255,255,0.9);
            font-size: 16px;
            text-align: center;
            margin-bottom: 30px;
        }
        
        /* 猫咪卡片 */
        .cat-cards {
            display: flex;
            flex-direction: column;
            gap: 20px;
            width: 100%;
            max-width: 400px;
            margin: 0 auto;
        }
        
        .cat-card {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            padding: 20px;
            display: flex;
            align-items: center;
            gap: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 10px 30px rgba(0,0,0,0.15);
            border: 3px solid transparent;
        }
        
        .cat-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 15px 40px rgba(0,0,0,0.25);
        }
        
        .cat-card:active {
            transform: scale(0.98);
        }
        
        .cat-card-img {
            width: 80px;
            height: 80px;
            border-radius: 50%;
            object-fit: cover;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            flex-shrink: 0;
        }
        
        .cat-card-info {
            flex: 1;
        }
        
        .cat-card-name {
            font-size: 22px;
            font-weight: bold;
            color: #333;
            margin-bottom: 5px;
        }
        
        .cat-card-difficulty {
            display: inline-block;
            font-size: 13px;
            padding: 4px 12px;
            border-radius: 12px;
            color: white;
            margin-bottom: 8px;
        }
        
        .diff-low { background: linear-gradient(135deg, #52c41a, #73d13d); }
        .diff-medium { background: linear-gradient(135deg, #faad14, #ffc53d); }
        .diff-high { background: linear-gradient(135deg, #ff4d4f, #ff7875); }
        
        .cat-card-desc {
            font-size: 14px;
            color: #666;
        }
        
        /* ========== 游戏页面 ========== */
        .game-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            width: 100%;
            max-width: 500px;
            margin-bottom: 15px;
            padding: 0 5px;
        }
        
        .back-btn {
            background: rgba(255,255,255,0.2);
            border: none;
            color: white;
            padding: 10px 15px;
            border-radius: 20px;
            font-size: 14px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 5px;
            transition: 0.3s;
        }
        
        .back-btn:hover {
            background: rgba(255,255,255,0.3);
        }
        
        .current-cat-badge {
            background: rgba(255,255,255,0.9);
            padding: 8px 16px;
            border-radius: 20px;
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 14px;
            color: #333;
            font-weight: bold;
        }
        
        .current-cat-badge img {
            width: 24px;
            height: 24px;
            border-radius: 50%;
            object-fit: cover;
        }
        
        .game-container {
            background: rgba(255, 255, 255, 0.98);
            border-radius: 20px;
            padding: 20px;
            box-shadow: 0 15px 60px rgba(0,0,0,0.2);
            width: 100%;
            max-width: 500px;
        }
        
        .game-status-bar {
            display: flex;
            justify-content: space-around;
            margin-bottom: 15px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 12px;
        }
        
        .status-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 3px;
        }
        
        .status-item .label {
            font-size: 11px;
            color: #999;
        }
        
        .status-item .value {
            font-size: 15px;
            font-weight: bold;
            color: #333;
        }
        
        .status-text {
            text-align: center;
            font-size: 16px;
            color: #667eea;
            font-weight: bold;
            margin-bottom: 10px;
            min-height: 24px;
        }
        
        .status-text.win { color: #52c41a; }
        .status-text.lose { color: #ff4d4f; }
        
        .restart-hint {
            text-align: center;
            font-size: 13px;
            color: #999;
            margin-bottom: 10px;
            opacity: 0;
            transition: 0.3s;
        }
        
        .restart-hint.show { opacity: 1; }
        
        /* Canvas容器 */
        .canvas-wrapper {
            display: flex;
            justify-content: center;
            padding: 10px;
            background: linear-gradient(135deg, #667eea22, #764ba222);
            border-radius: 15px;
            overflow-x: auto;
            -webkit-overflow-scrolling: touch;
        }
        
        canvas {
            display: block;
            cursor: pointer;
            max-width: 100%;
            height: auto;
            -webkit-tap-highlight-color: transparent;
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            user-select: none;
            outline: none;
        }
        
        /* 难度说明 */
        .difficulty-card {
            margin-top: 15px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 12px;
        }
        
        .difficulty-card h3 {
            font-size: 14px;
            color: #333;
            margin-bottom: 10px;
            text-align: center;
        }
        
        .difficulty-list {
            display: flex;
            flex-direction: column;
            gap: 6px;
        }
        
        .difficulty-item {
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 12px;
            color: #555;
        }
        
        .difficulty-item .emoji {
            font-size: 16px;
        }
        
        /* 重新开始按钮 */
        .restart-btn {
            width: 100%;
            margin-top: 15px;
            padding: 14px;
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            border: none;
            border-radius: 25px;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
        }
        
        .restart-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
        }
        
        .restart-btn:active {
            transform: scale(0.98);
        }
        
        /* ========== 响应式适配 ========== */
        [url=home.php?mod=space&uid=945662]@media[/url] (max-width: 480px) {
            .select-title {
                font-size: 28px;
                margin: 20px 0 15px;
            }
            
            .select-subtitle {
                font-size: 14px;
                margin-bottom: 20px;
            }
            
            .cat-cards {
                padding: 0 10px;
            }
            
            .cat-card {
                padding: 15px;
                gap: 15px;
            }
            
            .cat-card-img {
                width: 65px;
                height: 65px;
            }
            
            .cat-card-name {
                font-size: 18px;
            }
            
            .cat-card-desc {
                font-size: 13px;
            }
            
            .game-container {
                padding: 15px;
                border-radius: 15px;
            }
            
            .game-status-bar {
                padding: 8px;
            }
            
            .status-item .label {
                font-size: 10px;
            }
            
            .status-item .value {
                font-size: 13px;
            }
            
            .difficulty-card {
                padding: 12px;
            }
            
            .difficulty-item {
                font-size: 11px;
            }
        }
        
        /* 横屏适配 */
        @media (max-height: 500px) and (orientation: landscape) {
            .select-title {
                font-size: 24px;
                margin: 10px 0;
            }
            
            .select-subtitle {
                display: none;
            }
            
            .cat-cards {
                flex-direction: row;
                max-width: 100%;
                overflow-x: auto;
                gap: 15px;
                padding: 0 10px;
            }
            
            .cat-card {
                flex-direction: column;
                min-width: 140px;
                padding: 15px;
                text-align: center;
            }
            
            .cat-card-info {
                display: flex;
                flex-direction: column;
                align-items: center;
            }
        }
    </style>
</head>
<body>
    <!-- ========== 选择猫咪页面 ========== -->
    <div id="selectPage" class="page active">
        <h1 class="select-title">围住小猫</h1>
        <p class="select-subtitle">摸鱼摸鱼&#128031;&#65039;,打发时间....</p>
        
        <div class="cat-cards">
            <div class="cat-card" onclick="startGame('orange')">
                <img class="cat-card-img" src="https://coze-coding-project.tos.coze.site/coze_storage_7633745811309953058/image/generate_image_fef41237-3294-4d26-961f-da549e688db7.jpeg?sign=1808906758-1f5b482dea-0-b5fb3a750ad553b048f383d5032514900fa9ff36037ca2705e1bedc1eb87270a" alt="橘猫">
                <div class="cat-card-info">
                    <div class="cat-card-name">橘猫</div>
                    <span class="cat-card-difficulty diff-low">佛系</span>
                    <div class="cat-card-desc">走一步,慢悠悠的~</div>
                </div>
            </div>
            
            <div class="cat-card" onclick="startGame('tabby')">
                <img class="cat-card-img" src="https://coze-coding-project.tos.coze.site/coze_storage_7633745811309953058/image/generate_image_8fb2213f-8103-42db-ba18-5bacd5706749.jpeg?sign=1808906764-896eafba5d-0-8860c0eeb05efbbac4f103af0705d2a00434a32ba05358426e074f93627c6e7c" alt="虎斑猫">
                <div class="cat-card-info">
                    <div class="cat-card-name">虎斑猫</div>
                    <span class="cat-card-difficulty diff-medium">敏捷</span>
                    <div class="cat-card-desc">走一步,速度更快~</div>
                </div>
            </div>
            
            <div class="cat-card" onclick="startGame('lihua')">
                <img class="cat-card-img" src="https://coze-coding-project.tos.coze.site/coze_storage_7633745811309953058/image/generate_image_2f4ca293-4b47-4254-9506-62759412fdcc.jpeg?sign=1808906761-46b3d7c170-0-ec10d13ced249bf5ff258ba5e164669c538f5a0c33d84f9fe18f0302e7e14b6a" alt="狸花猫">
                <div class="cat-card-info">
                    <div class="cat-card-name">狸花猫</div>
                    <span class="cat-card-difficulty diff-high">狡猾</span>
                    <div class="cat-card-desc">走两步,心眼超多~</div>
                </div>
            </div>
        </div>
    </div>
  
    <!-- ========== 游戏页面 ========== -->
    <div id="gamePage" class="page">
        <div class="game-header">
            <button class="back-btn" onclick="goBack()">
                <span>&lt;</span> 返回
            </button>
            <div class="current-cat-badge" id="currentCatBadge">
                <img id="badgeCatImg" src="" alt="">
                <span id="badgeCatName">橘猫</span>
            </div>
        </div>
        
        <div class="game-container">
            <div class="game-status-bar">
                <div class="status-item">
                    <span class="label">放置次数</span>
                    <span class="value" id="moveCount">0</span>
                </div>
                <div class="status-item">
                    <span class="label">限制</span>
                    <span class="value">≤13步</span>
                </div>
                <div class="status-item">
                    <span class="label">难度</span>
                    <span class="value" id="difficultyText">佛系</span>
                </div>
                <div class="status-item">
                    <span class="label">猫咪位置</span>
                    <span class="value" id="catPosition">(5,5)</span>
                </div>
            </div>
            
            <div id="status" class="status-text">点击蓝色圆点开始围堵</div>
            <div id="restartHint" class="restart-hint">点击重新开始</div>
            
            <div class="canvas-wrapper">
                <canvas id="catCanvas"></canvas>
            </div>
            
            <div class="difficulty-card">
                <h3>游戏说明</h3>
                <div class="difficulty-list">
                    <div class="difficulty-item">
                        <span class="emoji">&#128049;</span>
                        <span>点击蓝色圆点放置障碍物</span>
                    </div>
                    <div class="difficulty-item">
                        <span class="emoji">&#127919;</span>
                        <span>围住猫咪 + ≤13步 = 胜利</span>
                    </div>
                    <div class="difficulty-item">
                        <span class="emoji" id="hintEmoji">&#128049;</span>
                        <span id="hintText">橘猫每次走一步</span>
                    </div>
                    <div class="difficulty-item" id="lihuaHint" style="display:none;">
                        <span class="emoji">&#9888;&#65039;</span>
                        <span>围堵太紧时狸花猫会愤怒跳两步!</span>
                    </div>
                </div>
            </div>
            
            <button class="restart-btn" onclick="restartGame()">重新开始</button>
        </div>
    </div>
  
    <script>
        const canvas = document.getElementById('catCanvas');
        const ctx = canvas.getContext('2d');
        const statusText = document.getElementById('status');
        const restartHint = document.getElementById('restartHint');
        const moveCountDisplay = document.getElementById('moveCount');
        const catPositionDisplay = document.getElementById('catPosition');
        const difficultyText = document.getElementById('difficultyText');
        const hintText = document.getElementById('hintText');
        const hintEmoji = document.getElementById('hintEmoji');
        const badgeCatImg = document.getElementById('badgeCatImg');
        const badgeCatName = document.getElementById('badgeCatName');
  
        // 游戏配置
        const ROWS = 11, COLS = 11, RADIUS = 16, GAP = 6;
        
        // 响应式调整画布大小
        function resizeCanvas() {
            const screenWidth = window.innerWidth;
            let canvasWidth, canvasHeight;
            
            if (screenWidth <= 480) {
                // 手机端:缩小圆点和间距
                canvas.width = COLS * (RADIUS * 2 + GAP) + RADIUS + 10;
                canvas.height = ROWS * (RADIUS * 2 + 4) + 10;
            } else {
                // 桌面端
                canvas.width = COLS * (RADIUS * 2 + GAP) + RADIUS + 15;
                canvas.height = ROWS * (RADIUS * 2 + 4) + 15;
            }
        }
        
        // 猫咪配置
        const catConfigs = {
            orange: {
                name: '橘猫',
                difficulty: '佛系',
                steps: 1,
                speed: 200,
                furColor: '#FF8C00',
                bellyColor: '#FFB347',
                eyeColor: '#000',
                emoji: '&#128049;'
            },
            tabby: {
                name: '虎斑猫',
                difficulty: '敏捷',
                steps: 1,
                speed: 120,
                furColor: '#708090',
                bellyColor: '#C0C0C0',
                eyeColor: '#2F4F4F',
                emoji: '&#128047;'
            },
            lihua: {
                name: '狸花猫',
                difficulty: '狡猾',
                steps: 1,  // 默认走一步
                speed: 150,
                furColor: '#8B4513',
                bellyColor: '#DEB887',
                eyeColor: '#006400',
                emoji: '&#129418;',
                angrySteps: 2  // 被激怒时走两步
            }
        };
        
        // 猫咪图片
        const catImages = {};
        const catImageUrls = {
            orange: 'https://coze-coding-project.tos.coze.site/coze_storage_7633745811309953058/image/generate_image_fef41237-3294-4d26-961f-da549e688db7.jpeg?sign=1808906758-1f5b482dea-0-b5fb3a750ad553b048f383d5032514900fa9ff36037ca2705e1bedc1eb87270a',
            tabby: 'https://coze-coding-project.tos.coze.site/coze_storage_7633745811309953058/image/generate_image_8fb2213f-8103-42db-ba18-5bacd5706749.jpeg?sign=1808906764-896eafba5d-0-8860c0eeb05efbbac4f103af0705d2a00434a32ba05358426e074f93627c6e7c',
            lihua: 'https://coze-coding-project.tos.coze.site/coze_storage_7633745811309953058/image/generate_image_2f4ca293-4b47-4254-9506-62759412fdcc.jpeg?sign=1808906761-46b3d7c170-0-ec10d13ced249bf5ff258ba5e164669c538f5a0c33d84f9fe18f0302e7e14b6a'
        };
        
        // 游戏状态
        let currentCatType = 'orange';
        let moveCount = 0;
        let map = [], catPos = { r: 5, c: 5 }, catDrawPos = { x: 0, y: 0 }, catDir = 1;
        let isOver = false, isAnimating = false;
        let aniId = null;
        
        // 预加载猫咪图片
        function preloadCatImages() {
            return new Promise((resolve) => {
                let loaded = 0;
                const total = Object.keys(catImageUrls).length;
                
                Object.keys(catImageUrls).forEach(type => {
                    const img = new Image();
                    img.crossOrigin = 'anonymous';
                    img.onload = () => {
                        catImages[type] = img;
                        loaded++;
                        if (loaded >= total) resolve();
                    };
                    img.onerror = () => {
                        loaded++;
                        if (loaded >= total) resolve();
                    };
                    img.src = catImageUrls[type];
                });
            });
        }
        
        // 页面切换
        function showPage(pageId) {
            document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
            document.getElementById(pageId).classList.add('active');
        }
        
        // 开始游戏
        function startGame(type) {
            currentCatType = type;
            const config = catConfigs[type];
            
            // 更新顶部徽章
            badgeCatImg.src = catImageUrls[type];
            badgeCatName.textContent = config.name;
            difficultyText.textContent = config.difficulty;
            hintEmoji.textContent = config.emoji;
            hintText.textContent = `${config.name}每次走${config.steps}步`;
            
            // 狸花猫特殊提示
            const lihuaHint = document.getElementById('lihuaHint');
            if (type === 'lihua') {
                lihuaHint.style.display = 'flex';
            } else {
                lihuaHint.style.display = 'none';
            }
            
            // 初始化游戏
            resizeCanvas();
            initMap();
            
            // 切换到游戏页面
            showPage('gamePage');
        }
        
        // 返回选择页面
        function goBack() {
            if (aniId) cancelAnimationFrame(aniId);
            showPage('selectPage');
        }
        
        // 重新开始游戏
        function restartGame() {
            initMap();
        }
        
        function initMap() {
            if (aniId) cancelAnimationFrame(aniId);
            isOver = false; isAnimating = false;
            moveCount = 0;
            moveCountDisplay.textContent = '0';
            
            const config = catConfigs[currentCatType];
            statusText.innerText = `选择${config.name},点击蓝点围住它!`;
            statusText.className = "status-text";
            restartHint.className = "restart-hint";
            
            map = Array.from({ length: ROWS }, () => Array(COLS).fill(0));
            let minObs = currentCatType === 'lihua' ? 10 : currentCatType === 'tabby' ? 11 : 12;
            let maxObs = currentCatType === 'lihua' ? 14 : currentCatType === 'tabby' ? 15 : 18;
            let count = minObs + Math.floor(Math.random() * (maxObs - minObs + 1));
            
            while (count > 0) {
                let r = Math.floor(Math.random() * ROWS), c = Math.floor(Math.random() * COLS);
                if (map[r][c] === 0 && !(r === 5 && c === 5)) { 
                    map[r][c] = 1; 
                    count--; 
                }
            }
            catPos = { r: 5, c: 5 };
            catDrawPos = getXY(catPos.r, catPos.c);
            catPositionDisplay.textContent = `(5,5)`;
            startLoop();
        }
  
        function getXY(r, c) {
            const x = RADIUS + 6 + c * (RADIUS * 2 + GAP) + (r % 2 === 1 ? RADIUS : 0);
            const y = RADIUS + 6 + r * (RADIUS * 2 + 4);
            return { x, y };
        }
  
        // 绘制猫咪
        function drawCat(x, y, dir, isRunning) {
            if (isNaN(x) || isNaN(y)) return;
            ctx.save();
            
            const config = catConfigs[currentCatType];
            const t = Date.now();
            let bobY = isRunning ? Math.sin(t / 35) * 3 : Math.sin(t / 400) * 0.8;
  
            ctx.translate(x, y + bobY);
            ctx.scale(dir, 1);
  
            const furColor = config.furColor;
            const bellyColor = config.bellyColor;
            
            // 身体
            ctx.fillStyle = furColor;
            ctx.beginPath();
            ctx.roundRect(-12, -6, 24, 14, 6);
            ctx.fill();
            
            // 肚子
            ctx.fillStyle = bellyColor;
            ctx.beginPath();
            ctx.ellipse(0, 2, 8, 4, 0, 0, Math.PI*2);
            ctx.fill();
            
            // 条纹
            if (currentCatType === 'tabby' || currentCatType === 'lihua') {
                ctx.strokeStyle = currentCatType === 'tabby' ? '#2F2F2F' : '#3D2314';
                ctx.lineWidth = 1.5;
                ctx.beginPath();
                ctx.moveTo(-6, -5); ctx.lineTo(-6, 4);
                ctx.moveTo(0, -5); ctx.lineTo(0, 4);
                ctx.moveTo(6, -5); ctx.lineTo(6, 4);
                ctx.stroke();
            }
  
            // 头
            ctx.fillStyle = furColor;
            ctx.beginPath();
            ctx.arc(10, -5, 9, 0, Math.PI * 2);
            ctx.fill();
  
            // 耳朵
            ctx.beginPath(); ctx.moveTo(7, -12); ctx.lineTo(13, -12); ctx.lineTo(10, -20); ctx.fill();
            ctx.beginPath(); ctx.moveTo(12, -10); ctx.lineTo(18, -8); ctx.lineTo(16, -16); ctx.fill();
            
            // 耳内
            ctx.fillStyle = '#FFB6C1';
            ctx.beginPath(); ctx.moveTo(8, -12); ctx.lineTo(11, -12); ctx.lineTo(9.5, -17); ctx.fill();
            ctx.beginPath(); ctx.moveTo(13, -10); ctx.lineTo(16, -9); ctx.lineTo(15, -14); ctx.fill();
  
            // 眼睛
            ctx.fillStyle = "#FFF";
            ctx.beginPath(); ctx.arc(13, -6, 2, 0, Math.PI*2); ctx.fill();
            ctx.fillStyle = config.eyeColor;
            ctx.beginPath(); ctx.arc(14, -6, 1, 0, Math.PI*2); ctx.fill();
  
            // 鼻子
            ctx.fillStyle = '#FFB6C1';
            ctx.beginPath();
            ctx.moveTo(17, -3);
            ctx.lineTo(15, -1);
            ctx.lineTo(19, -1);
            ctx.closePath();
            ctx.fill();
  
            // 腮红
            ctx.fillStyle = 'rgba(255, 182, 193, 0.4)';
            ctx.beginPath(); ctx.ellipse(19, -1, 2.5, 1.5, 0, 0, Math.PI*2); ctx.fill();
            ctx.beginPath(); ctx.ellipse(7, -1, 2.5, 1.5, 0, 0, Math.PI*2); ctx.fill();
  
            // 腿
            ctx.fillStyle = furColor;
            ctx.beginPath(); ctx.roundRect(7, 5, 4, 8, 2); ctx.fill();
            ctx.beginPath(); ctx.roundRect(-10, 5, 4, 8, 2); ctx.fill();
  
            // 尾巴
            ctx.lineWidth = 3; ctx.strokeStyle = furColor; ctx.lineCap = "round";
            ctx.beginPath(); ctx.moveTo(-12, -2); ctx.quadraticCurveTo(-20, -6, -18, -14); ctx.stroke();
  
            ctx.restore();
        }
  
        function startLoop() {
            const loop = () => {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                for (let r = 0; r < ROWS; r++) {
                    for (let c = 0; c < COLS; c++) {
                        const { x, y } = getXY(r, c);
                        ctx.beginPath(); ctx.arc(x, y, RADIUS, 0, Math.PI * 2);
                        ctx.fillStyle = map[r][c] === 1 ? "#34495e" : "#b3d9ff"; ctx.fill();
                    }
                }
                const catBase = getXY(catPos.r, catPos.c);
                if (!isAnimating || (isAnimating && !isOver)) {
                    ctx.beginPath(); ctx.arc(catBase.x, catBase.y, RADIUS, 0, Math.PI*2);
                    ctx.fillStyle = "#b3d9ff"; ctx.fill();
                }
                drawCat(catDrawPos.x, catDrawPos.y, catDir, isAnimating && !isOver);
                aniId = requestAnimationFrame(loop);
            };
            loop();
        }
  
        function getAdj(r, c) {
            let n = [[r, c-1], [r, c+1]];
            if (r % 2 === 0) n.push([r-1, c-1], [r-1, c], [r+1, c-1], [r+1, c]);
            else n.push([r-1, c], [r-1, c+1], [r+1, c], [r+1, c+1]);
            return n.filter(p => p[0]>=0 && p[0]<ROWS && p[1]>=0 && p[1]<COLS);
        }
  
        function findSimplePath(startR, startC) {
            let queue = [{ r: startR, c: startC, path: [] }], visited = new Set([`${startR},${startC}`]);
            while (queue.length > 0) {
                let curr = queue.shift();
                if (curr.r === 0 || curr.r === ROWS - 1 || curr.c === 0 || curr.c === COLS - 1) return curr.path;
                for (let [nr, nc] of getAdj(curr.r, curr.c)) {
                    if (map[nr][nc] === 0 && !visited.has(`${nr},${nc}`)) {
                        visited.add(`${nr},${nc}`);
                        queue.push({ r: nr, c: nc, path: curr.path.concat({ r: nr, c: nc }) });
                    }
                }
            }
            return null;
        }
  
        function catMove() {
            if (isOver || isAnimating) return;
            
            const config = catConfigs[currentCatType];
            let path = findSimplePath(catPos.r, catPos.c);
            
            if (!path || path.length === 0) {
                // 猫被困住了,检查放置次数
                if (moveCount <= 13) {
                    isOver = true; 
                    const winMessages = [
                        `${config.name}已经无路可走,你赢了!`,
                        `太棒了!${config.name}被困住了!`,
                        `成功围住${config.name}!`
                    ];
                    statusText.innerText = winMessages[Math.floor(Math.random() * winMessages.length)];
                    statusText.className = "status-text win"; 
                } else {
                    isOver = true;
                    statusText.innerText = `超过13步限制,${config.name}成功坚守!`;
                    statusText.className = "status-text lose";
                }
                restartHint.className = "restart-hint show";
                return;
            }
            
            isAnimating = true;
            
            // 狸花猫特殊机制:当周围逃跑路线 ≤3 时被激怒跳两步
            let stepsToMove = 1;
            if (currentCatType === 'lihua' && config.angrySteps) {
                const escapeRoutes = countEscapeRoutes(catPos.r, catPos.c);
                if (escapeRoutes <= 3) {
                    stepsToMove = 2;
                    statusText.innerText = `狸花猫被激怒了!跳两步逃跑!`;
                }
            }
            
            // 执行移动
            const actualSteps = Math.min(stepsToMove, path.length);
            animateCatMove(path.slice(0, actualSteps), () => {
                isAnimating = false;
            });
        }
        
        // 计算某位置的可逃跑方向数量
        function countEscapeRoutes(r, c) {
            let count = 0;
            const adj = getAdj(r, c);
            for (let [nr, nc] of adj) {
                if (map[nr][nc] === 0) {
                    count++;
                }
            }
            return count;
        }
        
        function animateCatMove(pathSegments, onComplete) {
            if (pathSegments.length === 0) {
                onComplete();
                return;
            }
            
            const config = catConfigs[currentCatType];
            const segment = pathSegments[0];
            const startXY = { ...catDrawPos };
            const endXY = getXY(segment.r, segment.c);
            catDir = endXY.x < startXY.x ? -1 : 1;
            catPos = { r: segment.r, c: segment.c };
            catPositionDisplay.textContent = `(${segment.r},${segment.c})`;
            
            let startTime = null;
            const duration = config.speed;
            
            const aniStep = (time) => {
                if (!startTime) startTime = time;
                const p = Math.min((time - startTime) / duration, 1);
                catDrawPos.x = startXY.x + (endXY.x - startXY.x) * p;
                catDrawPos.y = startXY.y + (endXY.y - startXY.y) * p;
                
                if (p < 1) {
                    requestAnimationFrame(aniStep);
                } else {
                    if (pathSegments.length > 1) {
                        animateCatMove(pathSegments.slice(1), onComplete);
                    } else {
                        if (catPos.r === 0 || catPos.r === ROWS-1 || catPos.c === 0 || catPos.c === COLS-1) {
                            // 猫逃跑了,检查放置次数
                            if (moveCount <= 13) {
                                isOver = true;
                                const loseMessages = [
                                    `哎呀,${config.name}逃跑了!`,
                                    `${config.name}跑掉了,下次再战!`,
                                    `被${config.name}溜走了~`
                                ];
                                statusText.innerText = loseMessages[Math.floor(Math.random() * loseMessages.length)];
                                statusText.className = "status-text lose";
                            } else {
                                isOver = true;
                                statusText.innerText = `超过13步限制,${config.name}成功逃脱!`;
                                statusText.className = "status-text lose";
                            }
                            restartHint.className = "restart-hint show";
                        } else {
                            onComplete();
                        }
                    }
                }
            };
            requestAnimationFrame(aniStep);
        }
  
        canvas.addEventListener('click', (e) => {
            if (isOver) { initMap(); return; }
            if (isAnimating) return;
            
            const rect = canvas.getBoundingClientRect();
            const scaleX = canvas.width / rect.width;
            const scaleY = canvas.height / rect.height;
            const mX = (e.clientX - rect.left) * scaleX;
            const mY = (e.clientY - rect.top) * scaleY;
            
            for (let r = 0; r < ROWS; r++) {
                for (let c = 0; c < COLS; c++) {
                    const { x, y } = getXY(r, c);
                    if (Math.hypot(mX - x, mY - y) < RADIUS + 8) {
                        if (map[r][c] === 0 && !(r === catPos.r && c === catPos.c)) {
                            const config = catConfigs[currentCatType];
                            moveCount++;
                            moveCountDisplay.textContent = moveCount;
                            
                            // 检查是否超过13步限制
                            if (moveCount > 13) {
                                isOver = true;
                                statusText.innerText = `超过13步限制,${config.name}成功坚守!`;
                                statusText.className = "status-text lose";
                                restartHint.className = "restart-hint show";
                                return;
                            }
                            
                            statusText.innerText = `放置障碍物,${config.name}要动了!`;
                            map[r][c] = 1; 
                            catMove();
                            return;
                        }
                    }
                }
            }
        });
        
        // 监听窗口大小变化
        window.addEventListener('resize', () => {
            if (document.getElementById('gamePage').classList.contains('active')) {
                resizeCanvas();
            }
        });
        
        // 初始化
        preloadCatImages();
    </script>
</body>
</html>

围住小猫-改进版

围住小猫-改进版

免费评分

参与人数 11吾爱币 +16 热心值 +9 收起 理由
jw52pj + 1 + 1 谢谢@Thanks!
freckle + 1 + 1 谢谢@Thanks!
lfm333 + 1 + 1 谢谢@Thanks!
user23456 + 1 + 1 热心回复!
shengruqing + 1 我很赞同!
sxp3468 + 1 + 1 谢谢@Thanks!
yyxu44 + 1 用心讨论,共获提升!
lsb2pojie + 1 + 1 热心回复!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
qjlfl + 1 + 1 我很赞同!
zxcvbnm12 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

嘿嘿嘿001 发表于 2026-6-22 14:54
好玩了 有趣
jxsdxxf 发表于 2026-6-22 19:12
本帖最后由 jxsdxxf 于 2026-6-22 19:20 编辑

最好不要限制步数,可以把初始的黑点弄少点。另外前二只猫好像没有什么区别(就是动得慢一点而已),可以都弄一个不同的随机出的技能,比如  吃掉前进方向上的一个黑点 或者 冰冻目前算出的道路上的一个点(玩家下一次堵就不能堵这里),玩家也可以有几个主动放的技能(每场只能放一次)如:沉睡 (让小猫下回步不动,相当于玩家连下二步),混乱(小猫脱离原本的最短方向,随机向其它三个可走的方向走),诱惑(选一个方向让猫必走) 等

当然技能可以是开局就有,也可以是走到某些格子触发得到(玩家并不知道在哪里),或者是每走一格有20%概率得到之类的,玩家和猫都可以通过这种方式得到技能。
8201792 发表于 2026-6-22 12:45
zxcvbnm12 发表于 2026-6-22 13:20
进去后界面咋跑到最左边了
 楼主| Summer000 发表于 2026-6-22 13:22
zxcvbnm12 发表于 2026-6-22 13:20
进去后界面咋跑到最左边了

因为我适配的是手机端的,电脑端没做适配,手机上玩体验感更爽。
bybyby11 发表于 2026-6-22 13:53
选择猫后 进去后界面咋跑到最左边了
 楼主| Summer000 发表于 2026-6-22 13:58
bybyby11 发表于 2026-6-22 13:53
选择猫后 进去后界面咋跑到最左边了

适配的是手机端
开创者 发表于 2026-6-22 14:16
越玩越花了是
jjm1997 发表于 2026-6-22 14:35
可爱的小猫在哪里,我要围住它。
goodbone 发表于 2026-6-22 14:41

越来越好玩了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-6-24 09:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表