const gameArea = document.querySelector('.game-area'); const dotCountDisplay = document.getElementById('dotCount'); const message = document.querySelector('.message'); let dots = []; let lastMouseX = 0; let lastMouseY = 0; let lastMouseTime = 0; let mouseVelocityX = 0; let mouseVelocityY = 0; class Dot { constructor(x, y) { this.element = document.createElement('div'); this.element.className = 'dot'; this.x = x; this.y = y; this.velocityX = (Math.random() - 0.5) * 200; this.velocityY = (Math.random() - 0.5) * 200; this.lastDuplication = Date.now(); this.acceleration = 0; gameArea.appendChild(this.element); this.updatePosition(); } updatePosition() { this.element.style.left = `${this.x}px`; this.element.style.top = `${this.y}px`; } move() { this.velocityX += (Math.random() - 0.5) * 20; this.velocityY += (Math.random() - 0.5) * 20; this.x += this.velocityX * 0.016; this.y += this.velocityY * 0.016; if (this.x < 0) { this.x = window.innerWidth; } else if (this.x > window.innerWidth) { this.x = 0; } if (this.y < 0) { this.y = window.innerHeight; } else if (this.y > window.innerHeight) { this.y = 0; } this.velocityX *= 0.98; this.velocityY *= 0.98; const currentSpeed = Math.sqrt(this.velocityX * this.velocityX + this.velocityY * this.velocityY); if (currentSpeed < 100) { const angle = Math.atan2(this.velocityY, this.velocityX); this.velocityX = Math.cos(angle) * 100; this.velocityY = Math.sin(angle) * 100; } if (currentSpeed > 400) { const angle = Math.atan2(this.velocityY, this.velocityX); this.velocityX = Math.cos(angle) * 400; this.velocityY = Math.sin(angle) * 400; } this.updatePosition(); const now = Date.now(); if (now - this.lastDuplication > 3000 && Math.random() < 0.002) { this.duplicate(); this.lastDuplication = now; } } duplicate() { if (dots.length < 8) { const newDot = new Dot(this.x, this.y); newDot.velocityX = this.velocityX * 1.2; newDot.velocityY = this.velocityY * 1.2; dots.push(newDot); updateDotCount(); } } avoidMouse(mouseX, mouseY, mouseVelX, mouseVelY) { const dx = this.x - mouseX; const dy = this.y - mouseY; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < 300) { const speed = 300; const mouseSpeed = Math.sqrt(mouseVelX * mouseVelX + mouseVelY * mouseVelY); const dotToMouseAngle = Math.atan2(dy, dx); const mouseMovementAngle = Math.atan2(mouseVelY, mouseVelX); const angleDiff = Math.abs(dotToMouseAngle - mouseMovementAngle); const distanceFactor = Math.min(1, (300 - distance) / 300); if (angleDiff < Math.PI / 2) { const targetSpeed = speed + mouseSpeed * 800 * distanceFactor; const currentSpeed = Math.sqrt(this.velocityX * this.velocityX + this.velocityY * this.velocityY); const acceleration = Math.min(0.2, (targetSpeed - currentSpeed) / 1000); this.velocityX = this.velocityX * (1 - acceleration) + Math.cos(dotToMouseAngle) * targetSpeed * acceleration; this.velocityY = this.velocityY * (1 - acceleration) + Math.sin(dotToMouseAngle) * targetSpeed * acceleration; } } } } function updateDotCount() { dotCountDisplay.textContent = dots.length; } function initializeGame() { const firstDot = new Dot( Math.random() * window.innerWidth, Math.random() * window.innerHeight ); dots.push(firstDot); updateDotCount(); } function moveDot(event) { const currentTime = Date.now(); const timeDiff = currentTime - lastMouseTime; if (lastMouseTime !== 0) { mouseVelocityX = (event.clientX - lastMouseX) / timeDiff; mouseVelocityY = (event.clientY - lastMouseY) / timeDiff; } lastMouseX = event.clientX; lastMouseY = event.clientY; lastMouseTime = currentTime; dots.forEach(dot => dot.avoidMouse(event.clientX, event.clientY, mouseVelocityX, mouseVelocityY)); } function updateDots() { dots.forEach(dot => dot.move()); requestAnimationFrame(updateDots); } gameArea.addEventListener('mousemove', moveDot); initializeGame(); updateDots(); window.addEventListener('resize', () => { dots.forEach(dot => { dot.x = Math.min(dot.x, window.innerWidth); dot.y = Math.min(dot.y, window.innerHeight); dot.updatePosition(); }); });