Previsão de Trajetória da Bola - Haxball Overlay

Desenha uma linha com a previsão da trajetória da bola com múltiplos reflexos usando um canvas overlay.

目前為 2025-04-14 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Previsão de Trajetória da Bola - Haxball Overlay
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Desenha uma linha com a previsão da trajetória da bola com múltiplos reflexos usando um canvas overlay.
// @author       SeuNome
// @match        https://www.haxball.com/play?c=gw93UukucpQ&p=1*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Cria um canvas overlay e adiciona ao body
    let overlayCanvas = document.createElement("canvas");
    overlayCanvas.style.position = "absolute";
    overlayCanvas.style.top = "0";
    overlayCanvas.style.left = "0";
    overlayCanvas.style.width = "100%";
    overlayCanvas.style.height = "100%";
    overlayCanvas.style.zIndex = "9999";
    overlayCanvas.style.pointerEvents = "none"; // Para que o overlay não capture cliques
    document.body.appendChild(overlayCanvas);

    // Ajusta o tamanho do canvas para a janela inteira
    function resizeCanvas() {
        overlayCanvas.width = window.innerWidth;
        overlayCanvas.height = window.innerHeight;
    }
    resizeCanvas();
    window.addEventListener("resize", resizeCanvas);

    const ctx = overlayCanvas.getContext("2d");

    // Função que simula a trajetória da bola com múltiplos reflexos
    // ballPos: posição inicial (em pixels)
    // ballSpeed: velocidade (em pixels/segundo)
    // arenaWidth, arenaHeight: dimensões da arena (em pixels)
    // simulationTime: tempo total para simulação (em segundos)
    // timeStep: intervalo de simulação (em segundos)
    function simulateTrajectory(ballPos, ballSpeed, arenaWidth, arenaHeight, simulationTime, timeStep) {
        let positions = [];
        // Copia dos valores iniciais
        let pos = { x: ballPos.x, y: ballPos.y };
        let vel = { x: ballSpeed.x, y: ballSpeed.y };

        // Define os limites da arena (supondo que (0,0) seja o canto superior esquerdo)
        const maxX = arenaWidth;
        const maxY = arenaHeight;
        const minX = 0;
        const minY = 0;

        // Simula enquanto o tempo acumulado for menor que simulationTime
        for (let t = 0; t < simulationTime; t += timeStep) {
            // Atualiza posição
            pos.x += vel.x * timeStep;
            pos.y += vel.y * timeStep;

            // Verifica colisão com paredes verticais (esquerda e direita)
            if (pos.x <= minX) {
                pos.x = minX;
                vel.x = -vel.x;
            } else if (pos.x >= maxX) {
                pos.x = maxX;
                vel.x = -vel.x;
            }

            // Verifica colisão com paredes horizontais (topo e fundo)
            if (pos.y <= minY) {
                pos.y = minY;
                vel.y = -vel.y;
            } else if (pos.y >= maxY) {
                pos.y = maxY;
                vel.y = -vel.y;
            }

            // Armazena a posição calculada
            positions.push({ x: pos.x, y: pos.y });
        }
        return positions;
    }

    // Função para desenhar a trajetória sobre o canvas
    function drawTrajectory(ctx, positions) {
        if (positions.length === 0) return;
        ctx.strokeStyle = "yellow";
        ctx.lineWidth = 3;
        ctx.beginPath();
        ctx.moveTo(positions[0].x, positions[0].y);
        for (let i = 1; i < positions.length; i++) {
            ctx.lineTo(positions[i].x, positions[i].y);
        }
        ctx.stroke();
    }

    // Função principal para atualizar o overlay e desenhar a previsão
    function updateOverlay() {
        // Limpa o canvas do overlay
        ctx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);

        // Simulação: aqui usamos valores exemplo para posição e velocidade da bola
        // Para integrar com dados reais, substitua esses valores pelos obtidos do jogo
        // Exemplo: bola começa no centro do canvas com velocidade arbitrária
        const ballPos = { x: overlayCanvas.width / 2, y: overlayCanvas.height / 2 };
        const ballSpeed = { x: 200, y: 150 }; // pixels/segundo (ajuste conforme necessário)

        // Parâmetros da simulação
        const simulationTime = 3; // simula 3 segundos
        const timeStep = 0.02; // intervalo de 20ms

        // Usando todo o overlay como "arena"
        const arenaWidth = overlayCanvas.width;
        const arenaHeight = overlayCanvas.height;

        // Calcula as posições simuladas
        const positions = simulateTrajectory(ballPos, ballSpeed, arenaWidth, arenaHeight, simulationTime, timeStep);

        // Desenha a trajetória prevista
        drawTrajectory(ctx, positions);

        requestAnimationFrame(updateOverlay);
    }

    // Inicia a atualização do overlay
    updateOverlay();

})();