PCOL-ASSIST

为该在线台球游戏增加双人手动计分器,移动端虚拟按键

当前为 2025-07-20 提交的版本,查看 最新版本

// ==UserScript==
// @name         PCOL-ASSIST
// @author       葉月Hikaru
// @match        http://www.heyzxz.me/pcol/*
// @version 7.3
// @namespace https://gf.qytechs.cn/users/your-id
// @description 为该在线台球游戏增加双人手动计分器,移动端虚拟按键
// ==/UserScript==
(function() {
    'use strict';
    const keysConfig = [
        { key: '+', text: '-', top: 30, left: 40 },
        { key: 'w', text: 'W', top: 30, left: 50 },
        { key: '-', text: '+', top: 30, left: 60 },
        { key: 'space', text: 'SPACE', top: 30, left: 70 },
        { key: 'x', text: 'X', top: 30, left: 80 },
        { key: 'c', text: 'C', top: 30, left: 90 },
        { key: 'p', text: 'P', top: 120, left: 90 },
        { key: 'a', text: 'A', top: 120, left: 30 },
        { key: 's', text: 'S', top: 120, left: 50 },
        { key: 'd', text: 'D', top: 120, left: 70 }
    ];
    const originalButtons = [];
    let areButtonsVisible = true;
    let isScoreboardVisible = true;
    let scores = { player1: 0, player2: 0 };
    let buttonCooldowns = {};
    let minusCooldowns = {};
    let longPressTimer = null;
    const LONG_PRESS_DELAY = 500;
    const scoreColors = {
        1: 'rgba(255, 0, 0, 0.6)',
        2: 'rgba(255, 255, 0, 0.6)',
        3: 'rgba(0, 255, 0, 0.6)',
        4: 'rgba(139, 69, 19, 0.6)',
        5: 'rgba(0, 0, 255, 0.6)',
        6: 'rgba(255, 192, 203, 0.6)',
        7: 'rgba(0, 0, 0, 0.6)'
    };
    function createVirtualKey(keyConfig) {
        const btn = document.createElement('button');
        btn.id = `pcol-assist-${keyConfig.key}-btn`;
        btn.textContent = keyConfig.text;
        btn.style.cssText = `
            position: fixed;
            top: ${keyConfig.top}px;
            left: ${keyConfig.left}%;
            transform: ${keyConfig.left === 50 ? 'translateX(-50%)' : 'translateX(0)'};
            width: 60px;
            height: 60px;
            font-size: ${keyConfig.text === 'SPACE' ? '16px' : '28px'};
            background-color: rgba(255, 165, 0, 0.9);
            color: white;
            border: 2px solid white;
            border-radius: 50%;
            cursor: pointer;
            z-index: 9999;
        `;
        function triggerEvent(type, keyInfo = {}) {
            if (keyConfig.key === '+' || keyConfig.key === '-') {
                const wheelEvent = new WheelEvent('wheel', {
                    deltaY: keyConfig.key === '+' ? -300 : 300,
                    bubbles: true,
                    cancelable: true
                });
                document.querySelector('canvas')?.dispatchEvent(wheelEvent) || document.dispatchEvent(wheelEvent);
            } else {
                const eventKey = keyInfo.key || (keyConfig.key === 'space' ? ' ' : keyConfig.key);
                const eventCode = keyInfo.code || (keyConfig.key === 'space' ? 'Space' : `Key${keyConfig.key.toUpperCase()}`);
                const eventKeyCode = keyInfo.keyCode || (keyConfig.key === 'w' ? 87 : keyConfig.key === 'a' ? 65 : keyConfig.key === 's' ? 83 : 
                        keyConfig.key === 'd' ? 68 : keyConfig.key === 'x' ? 88 : keyConfig.key === 'c' ? 67 : keyConfig.key === 'p' ? 80 : 32);
                const event = new KeyboardEvent(type, {
                    key: eventKey === ' ' ? 'Spacebar' : eventKey,
                    code: eventCode,
                    keyCode: eventKeyCode,
                    bubbles: true,
                    cancelable: true
                });
                document.querySelector('canvas')?.dispatchEvent(event) || document.dispatchEvent(event);
            }
        }
        ['touchstart', 'mousedown'].forEach(e => btn.addEventListener(e, e => {
            e.preventDefault();
            triggerEvent('keydown');
        }));
        ['touchend', 'mouseup'].forEach(e => btn.addEventListener(e, e => {
            e.preventDefault();
            triggerEvent('keyup');
        }));
        document.body.appendChild(btn);
        originalButtons.push(btn);
    }
    function createVisibilityToggle() {
        const toggle = document.createElement('button');
        toggle.id = 'pcol-assist-visibility-toggle';
        toggle.textContent = '按钮: 显示';
        toggle.style.cssText = `
            position: fixed;
            top: 60px;
            left: 20px;
            width: 100px;
            height: 40px;
            font-size: 16px;
            background-color: rgba(0, 128, 0, 0.9);
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 9999;
        `;
        toggle.addEventListener('click', () => {
            areButtonsVisible = !areButtonsVisible;
            originalButtons.forEach(btn => {
                btn.style.display = areButtonsVisible ? 'block' : 'none';
            });
            if (areButtonsVisible) {
                toggle.textContent = '按钮: 显示';
                toggle.style.backgroundColor = 'rgba(0, 128, 0, 0.9)';
            } else {
                toggle.textContent = '按钮: 隐藏';
                toggle.style.backgroundColor = 'rgba(128, 128, 128, 0.9)';
            }
        });
        document.body.appendChild(toggle);
    }
    function createScoreboardToggle() {
        const toggle = document.createElement('button');
        toggle.id = 'pcol-assist-scoreboard-toggle';
        toggle.textContent = '记分板: 显示';
        toggle.style.cssText = `
            position: fixed;
            top: 60px;
            left: 140px;
            width: 100px;
            height: 40px;
            font-size: 16px;
            background-color: rgba(0, 128, 0, 0.9);
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 9999;
        `;
        toggle.addEventListener('click', () => {
            isScoreboardVisible = !isScoreboardVisible;
            const scoreboard = document.getElementById('pcol-assist-scoreboard');
            scoreboard.style.display = isScoreboardVisible ? 'flex' : 'none';
            if (isScoreboardVisible) {
                toggle.textContent = '记分板: 显示';
                toggle.style.backgroundColor = 'rgba(0, 128, 0, 0.9)';
            } else {
                toggle.textContent = '记分板: 隐藏';
                toggle.style.backgroundColor = 'rgba(128, 128, 128, 0.9)';
            }
        });
        document.body.appendChild(toggle);
    }
    // 新增全屏控制按钮(适配Safari)
    function createFullscreenToggle() {
        const toggle = document.createElement('button');
        toggle.id = 'pcol-assist-fullscreen-toggle';
        toggle.textContent = '全屏';
        toggle.style.cssText = `
            position: fixed;
            top: 60px;
            left: 260px;
            width: 80px;
            height: 40px;
            font-size: 16px;
            background-color: rgba(70, 130, 180, 0.9);
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 9999;
        `;
        // 全屏切换逻辑(优先适配Safari的webkit前缀方法)
        toggle.addEventListener('click', () => {
            const docEl = document.documentElement;
            // 判断当前是否全屏(Safari使用webkitIsFullScreen)
            const isFullscreen = document.webkitIsFullScreen || document.fullscreenElement;
            
            if (!isFullscreen) {
                // 进入全屏(Safari需要webkitRequestFullscreen)
                if (docEl.webkitRequestFullscreen) {
                    docEl.webkitRequestFullscreen();
                } else if (docEl.requestFullscreen) {
                    docEl.requestFullscreen();
                }
                toggle.textContent = '退出全屏';
            } else {
                // 退出全屏(Safari使用webkitExitFullscreen)
                if (document.webkitExitFullscreen) {
                    document.webkitExitFullscreen();
                } else if (document.exitFullscreen) {
                    document.exitFullscreen();
                }
                toggle.textContent = '全屏';
            }
        });
        document.body.appendChild(toggle);
    }
    function createScoreboard() {
        const scoreboard = document.createElement('div');
        scoreboard.id = 'pcol-assist-scoreboard';
        scoreboard.style.cssText = `
            position: fixed;
            top: 100px;
            left: 10px;
            display: flex;
            gap: 20px;
            z-index: 9998;
        `;
        function createPlayerScore(playerId, name) {
            const container = document.createElement('div');
            container.style.cssText = `
                display: flex;
                flex-direction: column;
                align-items: center;
                background-color: rgba(0, 0, 0, 0.7);
                padding: 10px;
                border-radius: 8px;
            `;
            const nameEl = document.createElement('div');
            nameEl.textContent = name;
            nameEl.style.cssText = `
                color: white;
                font-size: 20px;
                font-weight: bold;
                margin-bottom: 5px;
            `;
            const scoreEl = document.createElement('div');
            scoreEl.id = `pcol-score-${playerId}`;
            scoreEl.textContent = '0';
            scoreEl.style.cssText = `
                color: white;
                font-size: 36px;
                width: 80px;
                text-align: center;
                margin-bottom: 10px;
                border: 2px solid white;
                border-radius: 4px;
                padding: 5px 0;
            `;
            const buttonsContainer = document.createElement('div');
            buttonsContainer.style.cssText = `
                display: grid;
                grid-template-columns: repeat(2, 1fr);
                gap: 5px;
            `;
            for (let i = 1; i <= 7; i++) {
                const btn = document.createElement('button');
                btn.id = `pcol-add-${playerId}-${i}`;
                btn.textContent = `+${i}`;
                btn.style.cssText = `
                    width: 40px;
                    height: 40px;
                    font-size: 18px;
                    background-color: ${scoreColors[i]};
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                `;
                btn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    const btnId = btn.id;
                    if (buttonCooldowns[btnId]) return;
                    scores[playerId] += i;
                    scoreEl.textContent = scores[playerId];
                    buttonCooldowns[btnId] = true;
                    btn.style.backgroundColor = scoreColors[i].replace('0.6', '0.3');
                    setTimeout(() => {
                        buttonCooldowns[btnId] = false;
                        btn.style.backgroundColor = scoreColors[i];
                    }, 1000);
                });
                buttonsContainer.appendChild(btn);
            }
            const minusBtn = document.createElement('button');
            minusBtn.id = `pcol-minus-${playerId}-1`;
            minusBtn.textContent = '-1';
            minusBtn.style.cssText = `
                width: 40px;
                height: 40px;
                font-size: 18px;
                background-color: rgba(178, 34, 34, 0.6);
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
            `;
            minusBtn.addEventListener('mousedown', (e) => {
                e.stopPropagation();
                longPressTimer = setTimeout(() => {
                    scores[playerId] = 0;
                    scoreEl.textContent = '0';
                }, LONG_PRESS_DELAY);
            });
            minusBtn.addEventListener('mouseup', (e) => {
                e.stopPropagation();
                if (longPressTimer) {
                    clearTimeout(longPressTimer);
                    longPressTimer = null;
                    const btnId = minusBtn.id;
                    if (minusCooldowns[btnId]) return;
                    if (scores[playerId] > 0) {
                        scores[playerId] -= 1;
                        scoreEl.textContent = scores[playerId];
                        minusCooldowns[btnId] = true;
                        minusBtn.style.backgroundColor = 'rgba(139, 0, 0, 0.3)';
                        setTimeout(() => {
                            minusCooldowns[btnId] = false;
                            minusBtn.style.backgroundColor = 'rgba(178, 34, 34, 0.6)';
                        }, 200);
                    }
                }
            });
            minusBtn.addEventListener('touchstart', (e) => {
                e.stopPropagation();
                longPressTimer = setTimeout(() => {
                    scores[playerId] = 0;
                    scoreEl.textContent = '0';
                }, LONG_PRESS_DELAY);
            });
            minusBtn.addEventListener('touchend', (e) => {
                e.stopPropagation();
                if (longPressTimer) {
                    clearTimeout(longPressTimer);
                    longPressTimer = null;
                    const btnId = minusBtn.id;
                    if (minusCooldowns[btnId]) return;
                    if (scores[playerId] > 0) {
                        scores[playerId] -= 1;
                        scoreEl.textContent = scores[playerId];
                        minusCooldowns[btnId] = true;
                        minusBtn.style.backgroundColor = 'rgba(139, 0, 0, 0.3)';
                        setTimeout(() => {
                            minusCooldowns[btnId] = false;
                            minusBtn.style.backgroundColor = 'rgba(178, 34, 34, 0.6)';
                        }, 200);
                    }
                }
            });
            minusBtn.addEventListener('mouseleave', () => {
                if (longPressTimer) {
                    clearTimeout(longPressTimer);
                    longPressTimer = null;
                }
            });
            buttonsContainer.appendChild(minusBtn);
            container.appendChild(nameEl);
            container.appendChild(scoreEl);
            container.appendChild(buttonsContainer);
            return container;
        }
        scoreboard.appendChild(createPlayerScore('player1', '玩家1'));
        scoreboard.appendChild(createPlayerScore('player2', '玩家2'));
        document.body.appendChild(scoreboard);
    }
    setTimeout(() => {
        keysConfig.forEach(createVirtualKey);
        createVisibilityToggle();
        createScoreboardToggle();
        createFullscreenToggle(); // 添加全屏控制按钮
        createScoreboard();
        console.log('【PCOL-ASSIST】虚拟按键、显示切换、记分及全屏功能已激活');
    }, 500);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址