feat(processReflection): Добавлена функция для изменеия горизонтальной и вертикальной скорости мяча в зависимости от места попадания в ракетку
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { Ball } from '../../entities/ball/ball';
|
||||
import { Paddle } from '../../entities/paddle/paddle';
|
||||
import { toRadians } from '../toRadians/toRadians';
|
||||
|
||||
/**
|
||||
* Проверяет произошло ли столкновение ракетки и мяча
|
||||
* @param {Paddle} paddle
|
||||
* @param {Ball} ball
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function didCollide(paddle, ball) {
|
||||
return (
|
||||
ball.verticalSpeed > 0 &&
|
||||
ball.y + ball.radius >= paddle.y &&
|
||||
ball.x >= paddle.x &&
|
||||
ball.x <= paddle.x + paddle.width
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Изменяет направление полета мяча в зависимости от места попадания в ракетку
|
||||
* @param {Paddle} paddle экземпляр класса ракетка
|
||||
* @param {Ball} ball экземпляр класса мяч
|
||||
* @param {number} paddleSectorAmount количество секторов ракетки, положительное целое число
|
||||
* @param {number} minAngle минимальный угол отскока мяча (от 0 до 180)
|
||||
* @param {number} maxAngle максимальный угол отскока мяча (от 0 до 180)
|
||||
* @param {number} ballSpeed константа скорости мяча, положительное число
|
||||
*/
|
||||
export function processReflection(paddle, ball, paddleSectorAmount, minAngle, maxAngle, ballSpeed) {
|
||||
try {
|
||||
if (!(paddle instanceof Paddle)) {
|
||||
throw new Error('Аргумерт paddle должен являться экземпляром класса Paddle');
|
||||
}
|
||||
|
||||
if (!(ball instanceof Ball)) {
|
||||
throw new Error('Аргумерт ball должен являться экземпляром класса Ball');
|
||||
}
|
||||
|
||||
if (typeof paddleSectorAmount !== 'number' || paddleSectorAmount <= 0 || paddleSectorAmount % 1 !== 0) {
|
||||
throw new Error('Аргумент paddleSectorAmount должен являться положительным целым числом');
|
||||
}
|
||||
|
||||
if (typeof minAngle !== 'number' || minAngle < 0 || minAngle > 180) {
|
||||
throw new Error('Аргумент minAngle должен являться числом в промежутке от 0 до 180');
|
||||
}
|
||||
|
||||
if (typeof maxAngle !== 'number' || maxAngle < 0 || maxAngle > 180) {
|
||||
throw new Error('Аргумент maxAngle должен являться числом в промежутке от 0 до 180');
|
||||
}
|
||||
|
||||
if (minAngle >= maxAngle) {
|
||||
throw new Error('Значение аргумента maxAngle должено быть строго больше значения аргумента minAngle');
|
||||
}
|
||||
|
||||
if (typeof ballSpeed !== 'number' || ballSpeed <= 0) {
|
||||
throw new Error('Значение аргумента ballSpeed должно быть положительным целым числом');
|
||||
}
|
||||
|
||||
if (!didCollide(paddle, ball)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const step = paddle.width / paddleSectorAmount;
|
||||
const sectorIndex = Math.floor((ball.x - paddle.x) / step);
|
||||
const normalizedSectorIndex = Math.min(Math.max(sectorIndex, 0), paddleSectorAmount - 1);
|
||||
|
||||
const angleStep = (maxAngle - minAngle) / (paddleSectorAmount - 1);
|
||||
const angleInRadians = toRadians(maxAngle - angleStep * normalizedSectorIndex);
|
||||
ball.horizontalSpeed = ballSpeed * Math.cos(angleInRadians);
|
||||
ball.verticalSpeed = -1 * ballSpeed * Math.sin(angleInRadians);
|
||||
ball.y = paddle.y - ball.radius;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user