Симулятор Запуска Ракеты
+Введите начальную скорость ракеты в метрах в секунду (м/с).
Чтобы преодолеть притяжение Земли, нужна скорость не менее 11 200 м/с.
diff --git a/assets/js/simulator.js b/assets/js/simulator.js new file mode 100644 index 0000000..ea67180 --- /dev/null +++ b/assets/js/simulator.js @@ -0,0 +1,142 @@ +document.addEventListener('DOMContentLoaded', () => { + const canvas = document.getElementById('simulationCanvas'); + if (!canvas) return; + + const ctx = canvas.getContext('2d'); + const launchButton = document.getElementById('launchButton'); + const velocityInput = document.getElementById('velocity'); + const resultMessage = document.getElementById('result-message'); + + // --- Параметры симуляции --- + const GRAVITY = 9.8; // Ускорение свободного падения (м/с^2) + const ESCAPE_VELOCITY = 11200; // Вторая космическая скорость (м/с) + const PIXELS_PER_METER = 0.005; // Масштаб: сколько пикселей в одном метре + const TIME_STEP = 2.0; // Шаг времени для симуляции (влияет на скорость анимации) + + let rocket = {}; + let animationFrameId; + let initialVelocity = 0; + + function initializeRocket() { + return { + x: canvas.width / 2, + y: canvas.height - 45, // Позиция на холсте (пиксели) + width: 10, + height: 25, + // Физические свойства + y_meters: 0, // Высота в метрах + velocityY_meters_per_sec: 0, // Скорость в м/с + }; + } + + function drawEarth() { + ctx.fillStyle = '#2c5c23'; + ctx.beginPath(); + ctx.arc(canvas.width / 2, canvas.height + canvas.height - 50, canvas.height, 0, Math.PI, true); + ctx.fill(); + } + + function drawRocket() { + ctx.fillStyle = '#d0d0d0'; + ctx.beginPath(); + ctx.moveTo(rocket.x, rocket.y - rocket.height / 2); + ctx.lineTo(rocket.x - rocket.width / 2, rocket.y + rocket.height / 2); + ctx.lineTo(rocket.x + rocket.width / 2, rocket.y + rocket.height / 2); + ctx.closePath(); + ctx.fill(); + } + + function resetSimulation() { + if (animationFrameId) { + cancelAnimationFrame(animationFrameId); + animationFrameId = null; + } + initialVelocity = 0; + rocket = initializeRocket(); + resultMessage.innerHTML = ' '; + resultMessage.className = 'alert alert-secondary'; + clearCanvas(); + drawEarth(); + drawRocket(); + } + + function clearCanvas() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + } + + function animate() { + // 1. Обновляем физику (пошаговая симуляция) + // Уменьшаем скорость под действием гравитации + rocket.velocityY_meters_per_sec -= GRAVITY * TIME_STEP; + // Обновляем высоту на основе новой скорости + rocket.y_meters += rocket.velocityY_meters_per_sec * TIME_STEP; + + // 2. Обновляем позицию для отрисовки + const groundY = canvas.height - 45; + rocket.y = groundY - (rocket.y_meters * PIXELS_PER_METER); + + // 3. Отрисовываем сцену + clearCanvas(); + drawEarth(); + drawRocket(); + + // 4. Проверяем условия завершения + const hasEscaped = initialVelocity >= ESCAPE_VELOCITY && rocket.y < -rocket.height; + const hasCrashed = rocket.y_meters <= 0 && initialVelocity < ESCAPE_VELOCITY; + + if (hasEscaped) { + cancelAnimationFrame(animationFrameId); + animationFrameId = null; + return; + } + + if (hasCrashed) { + // Фиксируем ракету на земле + rocket.y_meters = 0; + rocket.y = groundY; + clearCanvas(); + drawEarth(); + drawRocket(); + + resultMessage.innerHTML = "Неудача. Ракета упала обратно на Землю."; + resultMessage.className = 'alert alert-danger'; + + cancelAnimationFrame(animationFrameId); + animationFrameId = null; + return; + } + + // Продолжаем анимацию + animationFrameId = requestAnimationFrame(animate); + } + + launchButton.addEventListener('click', () => { + const velocityValue = parseFloat(velocityInput.value); + + if (isNaN(velocityValue) || velocityValue < 0) { + resultMessage.innerHTML = 'Пожалуйста, введите положительное число.'; + resultMessage.className = 'alert alert-warning'; + return; + } + + resetSimulation(); + + initialVelocity = velocityValue; + rocket.velocityY_meters_per_sec = initialVelocity; + + if (initialVelocity >= ESCAPE_VELOCITY) { + resultMessage.innerHTML = "Успешный запуск! Ракета улетит в космос."; + resultMessage.className = 'alert alert-success'; + } else { + resultMessage.innerHTML = "Запуск... Ракета должна упасть."; + resultMessage.className = 'alert alert-info'; + } + + if (!animationFrameId) { + animationFrameId = requestAnimationFrame(animate); + } + }); + + // Начальная отрисовка + resetSimulation(); +}); \ No newline at end of file diff --git a/index.php b/index.php index 5c9a593..02cc23f 100644 --- a/index.php +++ b/index.php @@ -56,6 +56,7 @@
Введите начальную скорость ракеты в метрах в секунду (м/с).
Чтобы преодолеть притяжение Земли, нужна скорость не менее 11 200 м/с.