Fausto900/gyroball-tilt-roll
0
1document.addEventListener('DOMContentLoaded', () => {2 const ball = document.getElementById('ball');3 const target = document.getElementById('target');4 const gameContainer = document.getElementById('game-container');5 const scoreDisplay = document.getElementById('score');6 const startBtn = document.getElementById('start-btn');7 8 let score = 0;9 let gameActive = false;10 let ballX = 0;11 let ballY = 0;12 let targetX = 0;13 let targetY = 0;14 let containerWidth = 0;15 let containerHeight = 0;16 17 // Initialize game18 function initGame() {19 containerWidth = gameContainer.offsetWidth;20 containerHeight = gameContainer.offsetHeight;21 22 // Center the ball initially23 ballX = containerWidth / 2 - ball.offsetWidth / 2;24 ballY = containerHeight / 2 - ball.offsetHeight / 2;25 updateBallPosition();26 27 // Place target randomly28 placeTarget();29 30 gameActive = true;31 score = 0;32 scoreDisplay.textContent = score;33 startBtn.innerHTML = '<i data-feather="refresh-cw" class="mr-2"></i> Restart Game';34 feather.replace();35 }36 37 // Update ball position38 function updateBallPosition() {39 ball.style.left = `${ballX}px`;40 ball.style.top = `${ballY}px`;41 }42 43 // Place target at random position44 function placeTarget() {45 targetX = Math.random() * (containerWidth - target.offsetWidth);46 targetY = Math.random() * (containerHeight - target.offsetHeight);47 48 target.style.left = `${targetX}px`;49 target.style.top = `${targetY}px`;50 }51 52 // Check collision between ball and target53 function checkCollision() {54 const ballRect = ball.getBoundingClientRect();55 const targetRect = target.getBoundingClientRect();56 57 return !(58 ballRect.right < targetRect.left || 59 ballRect.left > targetRect.right || 60 ballRect.bottom < targetRect.top || 61 ballRect.top > targetRect.bottom62 );63 }64 65 // Handle device orientation66 function handleOrientation(event) {67 if (!gameActive) return;68 69 // Get tilt values (beta for front/back, gamma for left/right)70 const beta = event.beta; // -180 to 18071 const gamma = event.gamma; // -90 to 9072 73 // Adjust ball position based on tilt74 // We'll use gamma for left/right movement and beta for front/back75 const sensitivity = 2;76 77 // Left/Right movement78 ballX += gamma * sensitivity;79 // Front/Back movement (inverted because beta is opposite)80 ballY -= (beta || 0) * sensitivity;81 82 // Boundary checks83 ballX = Math.max(0, Math.min(containerWidth - ball.offsetWidth, ballX));84 ballY = Math.max(0, Math.min(containerHeight - ball.offsetHeight, ballY));85 86 updateBallPosition();87 88 // Check for collision89 if (checkCollision()) {90 score++;91 scoreDisplay.textContent = score;92 placeTarget();93 94 // Add celebration effect95 ball.classList.add('animate-ping');96 setTimeout(() => ball.classList.remove('animate-ping'), 300);97 }98 }99 100 // Start button click handler101 startBtn.addEventListener('click', () => {102 initGame();103 104 // Request permission for iOS 13+ devices105 if (typeof DeviceOrientationEvent !== 'undefined' && typeof DeviceOrientationEvent.requestPermission === 'function') {106 DeviceOrientationEvent.requestPermission()107 .then(response => {108 if (response === 'granted') {109 window.addEventListener('deviceorientation', handleOrientation);110 } else {111 alert('Game requires device orientation access to work properly.');112 }113 })114 .catch(console.error);115 } else {116 window.addEventListener('deviceorientation', handleOrientation);117 }118 });119 120 // Fallback for devices without gyroscope121 if (!window.DeviceOrientationEvent) {122 startBtn.textContent = 'Device Not Supported';123 startBtn.classList.add('bg-red-500', 'cursor-not-allowed');124 startBtn.disabled = true;125 126 const infoText = document.createElement('p');127 infoText.className = 'text-red-400 text-sm mt-2';128 infoText.textContent = 'Your device doesn\'t support gyroscope features.';129 startBtn.parentNode.appendChild(infoText);130 }131});