From 0f057c1add8e5467625f36264256dfc76eb9e0ab Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Sun, 19 Jul 2026 11:24:37 +0300 Subject: [PATCH] =?UTF-8?q?feat(ball):=20=D0=A4=D0=BB=D0=B0=D0=B3=20isOut?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=B5=20status,=20=D0=B8=D0=B7=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=BE=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BC=D1=8F=D1=87=D0=B0=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B5=20=D0=B8=D0=B3=D1=80=D1=8B?= =?UTF-8?q?,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=83=D1=81=D0=BA=D0=B0=20=D0=BC=D1=8F=D1=87=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D0=BA=D0=BB=D0=B8=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/ball/ball.js | 19 ++++++++++++++----- src/game.js | 27 +++++++++++++++++++++------ src/lib/tick/tick.js | 2 +- src/main.js | 4 ++++ 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/entities/ball/ball.js b/src/entities/ball/ball.js index f2c96c0..55b9582 100644 --- a/src/entities/ball/ball.js +++ b/src/entities/ball/ball.js @@ -16,7 +16,7 @@ export class Ball { this.radius = radius; this.verticalSpeed = verticalSpeed; this.horizontalSpeed = horizontalSpeed; - this.isOut = false; + this.status = 'idle'; this.defaultX = x; this.defaultY = y; @@ -36,11 +36,20 @@ export class Ball { /** * Возвращает значения к дефолтным */ - reset() { - this.x = this.defaultX; - this.y = this.defaultY; + reset(x = this.defaultX, y = this.defaultY) { + this.x = x; + this.y = y; this.verticalSpeed = this.defaultVerticalSpeed; this.horizontalSpeed = this.defaultHorizontalSpeed; - this.isOut = false; + this.status = 'idle'; + } + + /** + * Запускает мяч с ракетки - переводит из ожидания в игру + */ + launch() { + if (this.status === 'idle') { + this.status = 'moving'; + } } } diff --git a/src/game.js b/src/game.js index d73919f..1f9bb4b 100644 --- a/src/game.js +++ b/src/game.js @@ -29,15 +29,17 @@ export class Game { this.currentLevel = 0; this.maxLevel = levels.length - 1; + this.paddle = new Paddle(0, CONTAINER_HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT); this.ball = new Ball( - CONTAINER_WIDTH / 2 - BALL_RADIUS / 2, - CONTAINER_HEIGHT / 2 - BALL_RADIUS / 2, + 0, + 0, BALL_RADIUS, BALL_SPEED * Math.cos(toRadians(BALL_INITIAL_ANGLE)), -1 * BALL_SPEED * Math.sin(toRadians(BALL_INITIAL_ANGLE)), ); - this.paddle = new Paddle(0, CONTAINER_HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT); this.bricks = layBricks(this.levels[this.currentLevel], BRICK_WIDTH, BRICK_HEIGHT); + + this._placeBallOnPaddle(); } /** @@ -49,15 +51,21 @@ export class Game { return; } + // Пока мяч не запущен - держим его на ракетке и не считаем физику + if (this.ball.status === 'idle') { + this._placeBallOnPaddle(); + return; + } + tick(this, CONTAINER_WIDTH, CONTAINER_HEIGHT, deltaTime); - if (this.ball.isOut) { + if (this.ball.status === 'out') { this.livesAmount -= 1; if (this.livesAmount === 0) { this.status = 'over'; } else { - this.ball.reset(); + this._placeBallOnPaddle(); } return; @@ -88,7 +96,14 @@ export class Game { * Запускает переход на новый уровень, возвращает мяч в дефоотное положение и отрисовывает кирпичи по карте уровня. */ _proceedToNextLevel() { - this.ball.reset(); + this._placeBallOnPaddle(); this.bricks = layBricks(this.levels[this.currentLevel], BRICK_WIDTH, BRICK_HEIGHT); } + + /** + * Ставит мяч по центру ракетки + */ + _placeBallOnPaddle() { + this.ball.reset(this.paddle.x + this.paddle.width / 2, this.paddle.y - this.ball.radius); + } } diff --git a/src/lib/tick/tick.js b/src/lib/tick/tick.js index 21cd7d2..8394cf6 100644 --- a/src/lib/tick/tick.js +++ b/src/lib/tick/tick.js @@ -61,7 +61,7 @@ export function tick(game, containerWidth, containerHeight, deltaTime) { // Проверяем выход за границу стены снизу if (ball.y >= bottomBoundary) { - game.ball.isOut = true; + game.ball.status = 'out'; return; } diff --git a/src/main.js b/src/main.js index e19c5b8..36313b2 100644 --- a/src/main.js +++ b/src/main.js @@ -49,6 +49,10 @@ import { createGameView, rebuildBrickViews, syncronizeViewsWithGame } from './vi game.paddle.moveTo(localPosition.x, 0, CONTAINER_WIDTH); }); + container.on('pointerdown', () => { + game.ball.launch(); + }); + app.ticker.add((time) => { game.update(time.deltaTime);