diff --git a/src/entities/ball/clone/clone.js b/src/entities/ball/clone/clone.js new file mode 100644 index 0000000..058afd8 --- /dev/null +++ b/src/entities/ball/clone/clone.js @@ -0,0 +1,36 @@ +import { toRadians } from '../../../lib/toRadians/toRadians'; +import { Ball } from '../ball'; + +/** + * Создает копию мяча в той же точке с направлением, повернутым на заданный угол + * @param {Ball} ball исходный мяч + * @param {number} angle угол поворота направления в градусах + * @returns {Ball | null} новый мяч с повернутой скоростью + */ +export function clone(ball, angle) { + try { + if (!(ball instanceof Ball)) { + throw new Error('Аргумент ball должен быть экземпляром класса мяча'); + } + + if (typeof angle !== 'number') { + throw new Error('Угол поворота должен являться числом'); + } + + const clonedBall = new Ball(ball.x, ball.y, ball.radius, ball.speed); + const angleInRadians = toRadians(angle); + const cos = Math.cos(angleInRadians); + const sin = Math.sin(angleInRadians); + + clonedBall.status = ball.status; + clonedBall.horizontalSpeed = ball.horizontalSpeed * cos - ball.verticalSpeed * sin; + clonedBall.verticalSpeed = ball.horizontalSpeed * sin + ball.verticalSpeed * cos; + clonedBall.defaultHorizontalSpeed = clonedBall.horizontalSpeed; + clonedBall.defaultVerticalSpeed = clonedBall.verticalSpeed; + + return clonedBall; + } catch (err) { + console.error(err); + return null; + } +} diff --git a/src/entities/ball/clone/clone.test.js b/src/entities/ball/clone/clone.test.js new file mode 100644 index 0000000..61451f4 --- /dev/null +++ b/src/entities/ball/clone/clone.test.js @@ -0,0 +1,26 @@ +import { Ball } from '../ball'; +import { clone } from './clone'; + +describe('clone', () => { + it('Возвращает корректное значение при неверных типах аргументов', () => { + expect(clone(null, 20)).toBeNull(); + expect(clone(new Ball(0, 0, 10, 3), '20')).toBeNull(); + }); + + it('Клонирует мяч и задает корректное значение скоростей по осям X и Y', () => { + const ball = new Ball(100, 200, 10, 90); + ball.status = 'moving'; + ball.horizontalSpeed = 3; + ball.verticalSpeed = 4; + + const clonedBall = clone(ball, 90); + + expect(clonedBall).toBeInstanceOf(Ball); + expect(clonedBall).not.toEqual(ball); + expect(clonedBall.x).toBe(100); + expect(clonedBall.y).toBe(200); + expect(clonedBall.status).toBe('moving'); + expect(clonedBall.horizontalSpeed).toBeCloseTo(-4); + expect(clonedBall.verticalSpeed).toBeCloseTo(3); + }); +});