您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Advanced drawing animation library for multiplayer drawing games
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/546216/1643825/Drawaria%20Animation%20Library.js
// ==UserScript== // @name Drawaria Animation Library // @namespace drawaria-animations // @version 1.0 // @description Advanced drawing animation library for multiplayer drawing games // @author DrawArtist // @license MIT // ==/UserScript== (function() { 'use strict'; // Core drawing animation functions const DRAWING_FUNCTIONS = { // Utility functions for drawing _delay: function(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }, _getRandomColor: function(saturation = 70, lightness = 50) { const hue = Math.floor(Math.random() * 360); return `hsl(${hue}, ${saturation}%, ${lightness}%)`; }, _sendDrawCmd: function(startPoint, endPoint, color, thickness) { try { if (!window.getGameSocket || !window.getGameSocket()) { console.warn('Game socket not available'); return false; } const socket = window.getGameSocket(); if (socket.readyState !== WebSocket.OPEN) { console.warn('WebSocket not open'); return false; } // Simulate drawing command - adjust based on actual game API const drawData = { type: 'draw', from: startPoint, to: endPoint, color: color, thickness: thickness }; socket.send(JSON.stringify(drawData)); return true; } catch (error) { console.error('Error sending draw command:', error); return false; } }, _drawPixel: async function(x, y, size, color, delay = 0) { const result = this._sendDrawCmd([x, y], [x + size, y + size], color, Math.max(1, size * 1000)); if (delay > 0) await this._delay(delay); return result; }, notify: function(type, message) { console.log(`[${type.toUpperCase()}] ${message}`); // You can extend this to show actual notifications }, // Initialize drawing state _drawingActive: false, _globalFrameCount: 0, _pixelFont: { 'V': [['###', '###', ' # ', ' # ', ' # ']], 'S': [['###', '# ', '###', ' #', '###']], 'M': [['# #', '###', '# #', '# #', '# #']], // Add more characters as needed }, _charHeight: 5, // Main animation functions async pixelArtCharacters() { if (!window.getGameSocket || !window.getGameSocket() || window.getGameSocket().readyState !== WebSocket.OPEN) { this.notify("error", "Not connected to game. Please be in a room."); return; } this._drawingActive = true; this.notify("info", "Starting Enhanced Pixel Art Characters..."); const Q_TOP_LEFT = { xMin: 0.0, yMin: 0.0, xMax: 0.5, yMax: 0.5 }; const Q_TOP_RIGHT = { xMin: 0.5, yMin: 0.0, xMax: 1.0, yMax: 0.5 }; const Q_BOTTOM_LEFT = { xMin: 0.0, yMin: 0.5, xMax: 0.5, yMax: 1.0 }; const Q_BOTTOM_RIGHT = { xMin: 0.5, yMin: 0.5, xMax: 1.0, yMax: 1.0 }; const marioSprite = { name: "MARIO", nameColor: "#FF0000", width: 12, data: ["____RRRRR___", "___RRRRRRR__", "___NNNYNY___", "__NSSYSYYN__", "__NSSYSYYYNN", "__NYYYYYYYYN", "____BBBB____", "__RBBBRBBR__", "_RBBRRRBBRR_", "RBBBBBRBBBB_", "BBBBBBRBBBBB", "BBBB__BBBB__", "NNN____NNN__", "_NN____NN___"], colors: { R: "#E60000", N: "#7A3D03", Y: "#FBD000", S: "#FFCC99", B: "#0040FF" }, quadrant: Q_TOP_LEFT, textOffsetY: -0.08 }; const characters = [marioSprite]; const pixelDrawDelay = 3; try { for (const char of characters) { if (!this._drawingActive) break; const charHeightPx = char.data.length; const charWidthPx = char.width; const quadW = char.quadrant.xMax - char.quadrant.xMin; const quadH = char.quadrant.yMax - char.quadrant.yMin; const scaleFactor = 0.65; const pixelSizeX = (quadW * scaleFactor) / charWidthPx; const pixelSizeY = (quadH * scaleFactor) / charHeightPx; const finalPixelSize = Math.min(pixelSizeX, pixelSizeY); const totalSpriteW = charWidthPx * finalPixelSize; const totalSpriteH = charHeightPx * finalPixelSize; const startX = char.quadrant.xMin + (quadW - totalSpriteW) / 2; const startY = char.quadrant.yMin + (quadH - totalSpriteH) / 2; for (let y = 0; y < charHeightPx; y++) { if (!this._drawingActive) break; for (let x = 0; x < charWidthPx; x++) { if (!this._drawingActive) break; const colorChar = char.data[y][x]; if (colorChar !== "_" && char.colors[colorChar]) { const dX = startX + x * finalPixelSize; const dY = startY + y * finalPixelSize; if (!await this._drawPixel(dX, dY, finalPixelSize, char.colors[colorChar], pixelDrawDelay)) { this._drawingActive = false; break; } } } } if (!this._drawingActive) break; await this._delay(200); } this._drawingActive = false; this.notify("success", "Enhanced Pixel Art Characters finished."); } catch (error) { this._drawingActive = false; this.notify("error", "Animation failed: " + error.message); } }, async colorFestival() { if (!window.getGameSocket || !window.getGameSocket() || window.getGameSocket().readyState !== WebSocket.OPEN) { this.notify("error", "Not connected to game. Please be in a room."); return; } this._drawingActive = true; this.notify("info", "Starting Color Festival..."); try { const numShapes = 120; const frameDelay = 60; const shapeDelay = 10; for (let i = 0; i < numShapes && this._drawingActive; i++) { let x = Math.random() * 0.8 + 0.1; let y = Math.random() * 0.8 + 0.1; let size = Math.random() * 0.08 + 0.03; let color = this._getRandomColor(90, 55); let thickness = Math.floor(Math.random() * 10) + 4; let shapeType = Math.floor(Math.random() * 4); let success = true; if (shapeType === 0) { // Rectangle success = this._sendDrawCmd([x - size/2, y - size/2], [x + size/2, y - size/2], color, thickness) && this._sendDrawCmd([x + size/2, y - size/2], [x + size/2, y + size/2], color, thickness) && this._sendDrawCmd([x + size/2, y + size/2], [x - size/2, y + size/2], color, thickness) && this._sendDrawCmd([x - size/2, y + size/2], [x - size/2, y - size/2], color, thickness); } else if (shapeType === 1) { // Triangle success = this._sendDrawCmd([x, y - size/2], [x + size/2, y + size/2], color, thickness) && this._sendDrawCmd([x + size/2, y + size/2], [x - size/2, y + size/2], color, thickness) && this._sendDrawCmd([x - size/2, y + size/2], [x, y - size/2], color, thickness); } else if (shapeType === 2) { // Star pattern for (let k = 0; k < 8 && success && this._drawingActive; k++) { const angle = (k / 8) * 2 * Math.PI; success = this._sendDrawCmd([x, y], [x + size * Math.cos(angle), y + size * Math.sin(angle)], color, thickness); if (shapeDelay > 0 && success) await this._delay(shapeDelay); } } else { // Spiral let lastX = x, lastY = y; for (let k = 0; k <= 20 && success && this._drawingActive; k++) { const angle = (k / 20) * 4 * Math.PI; const radius = (k / 20) * size; const currentX = x + radius * Math.cos(angle); const currentY = y + radius * Math.sin(angle); if (k > 0) success = this._sendDrawCmd([lastX, lastY], [currentX, currentY], color, thickness); lastX = currentX; lastY = currentY; if (shapeDelay > 0 && success) await this._delay(shapeDelay); } } if (!success || !this._drawingActive) break; if (frameDelay > 0) await this._delay(frameDelay); } this._drawingActive = false; this.notify("success", "Color Festival finished."); } catch (error) { this._drawingActive = false; this.notify("error", "Animation failed: " + error.message); } }, async fireworks() { if (!window.getGameSocket || !window.getGameSocket() || window.getGameSocket().readyState !== WebSocket.OPEN) { this.notify("error", "Not connected to game. Please be in a room."); return; } this._drawingActive = true; this.notify("info", "Starting Fireworks..."); try { const numFireworks = 8; const fireworkDelay = 600; for (let i = 0; i < numFireworks && this._drawingActive; i++) { // Launch trail let startX = Math.random() * 0.6 + 0.2; let startY = 0.95; let peakX = startX + (Math.random() - 0.5) * 0.3; let peakY = Math.random() * 0.4 + 0.05; let launchColor = this._getRandomColor(100, 70); // Draw launch trail for (let step = 0; step < 25 && this._drawingActive; step++) { let progress = step / 25; let nextProgress = (step + 1) / 25; let currentX = startX + (peakX - startX) * progress; let currentY = startY + (peakY - startY) * progress; let nextX = startX + (peakX - startX) * nextProgress; let nextY = startY + (peakY - startY) * nextProgress; if (!this._sendDrawCmd([currentX, currentY], [nextX, nextY], launchColor, 6)) { this._drawingActive = false; break; } await this._delay(4); } if (!this._drawingActive) break; // Explosion const explosionHue = Math.random() * 360; const particleCount = 40 + Math.floor(Math.random() * 40); for (let j = 0; j < particleCount && this._drawingActive; j++) { const angle = Math.random() * 2 * Math.PI; const distance = Math.random() * 0.20 + 0.05; const endX = peakX + distance * Math.cos(angle); const endY = peakY + distance * Math.sin(angle); const particleHue = (explosionHue + (Math.random() - 0.5) * 60 + 360) % 360; if (!this._sendDrawCmd([peakX, peakY], [endX, endY], `hsl(${particleHue},100%,60%)`, 4)) { this._drawingActive = false; break; } await this._delay(8); } if (!this._drawingActive) break; if (fireworkDelay > 0) await this._delay(fireworkDelay); } this._drawingActive = false; this.notify("success", "Fireworks finished."); } catch (error) { this._drawingActive = false; this.notify("error", "Animation failed: " + error.message); } }, stopDrawing() { this._drawingActive = false; this.notify("info", "Drawing stopped by user."); } }; // Utility functions for the library window.DRAWARIA_ANIMATIONS = { // Get all available animation functions getAnimations: function() { try { return Object.keys(DRAWING_FUNCTIONS).filter(key => typeof DRAWING_FUNCTIONS[key] === 'function' && !key.startsWith('_') && key !== 'notify' && key !== 'stopDrawing' ); } catch (error) { console.error('Error getting animations:', error); return []; } }, // Execute a specific animation runAnimation: function(animationName) { try { if (typeof DRAWING_FUNCTIONS[animationName] === 'function') { return DRAWING_FUNCTIONS[animationName].call(DRAWING_FUNCTIONS); } else { console.error('Animation not found:', animationName); return Promise.reject('Animation not found'); } } catch (error) { console.error('Error running animation:', error); return Promise.reject(error); } }, // Get a random animation getRandomAnimation: function() { try { const animations = this.getAnimations(); if (animations.length === 0) return null; return animations[Math.floor(Math.random() * animations.length)]; } catch (error) { console.error('Error getting random animation:', error); return null; } }, // Stop current animation stop: function() { try { DRAWING_FUNCTIONS.stopDrawing(); } catch (error) { console.error('Error stopping animation:', error); } }, // Check if drawing is active isDrawing: function() { return DRAWING_FUNCTIONS._drawingActive; }, // Direct access to drawing functions animations: DRAWING_FUNCTIONS }; // Make drawing functions available globally window.DRAWING_FUNCTIONS = DRAWING_FUNCTIONS; console.log('🎨 Drawaria Animation Library loaded with', Object.keys(DRAWING_FUNCTIONS).filter(k => typeof DRAWING_FUNCTIONS[k] === 'function').length, 'functions'); console.log('Available animations:', window.DRAWARIA_ANIMATIONS.getAnimations()); })();