Files
arkanoid/src/game.js
T

104 lines
3.0 KiB
JavaScript

import {
BALL_INITIAL_ANGLE,
BALL_RADIUS,
BALL_SPEED,
BRICK_HEIGHT,
BRICK_WIDTH,
CONTAINER_HEIGHT,
CONTAINER_WIDTH,
PADDLE_HEIGHT,
PADDLE_WIDTH,
} from './config';
import { Ball } from './entities/ball/ball';
import { layBricks } from './entities/brick/layBricks/layBricks';
import { Paddle } from './entities/paddle/paddle';
import { tick } from './lib/tick/tick';
import { toRadians } from './lib/toRadians/toRadians';
/**
* Класс игры c информацией о всех игровых сущностях
*/
export class Game {
/**
* @param {number[][][]} levels список уровней, каждый элемент которого - карта расположения блоков
*/
constructor(levels) {
this.livesAmount = 3;
this.status = 'in_process';
this.levels = levels;
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(0, 0, BALL_RADIUS, BALL_SPEED, BALL_INITIAL_ANGLE);
this.bricks = layBricks(this.levels[this.currentLevel], BRICK_WIDTH, BRICK_HEIGHT);
this._placeBallOnPaddle();
}
/**
* Изменяет значения сущностей в зависимости от времени
* @param {*} deltaTime изменение времени из Ticker
*/
update(deltaTime) {
if (this.status !== 'in_process') {
return;
}
// Пока мяч не запущен - держим его на ракетке и не считаем физику
if (this.ball.status === 'idle') {
this._placeBallOnPaddle();
return;
}
tick(this, CONTAINER_WIDTH, CONTAINER_HEIGHT, deltaTime);
if (this.ball.status === 'out') {
this.livesAmount -= 1;
if (this.livesAmount === 0) {
this.status = 'over';
} else {
this._placeBallOnPaddle();
}
return;
}
const isLevelComplete = this._checkLevelCompletion();
if (isLevelComplete) {
this.currentLevel += 1;
if (this.currentLevel <= this.maxLevel) {
this._proceedToNextLevel();
} else {
this.status = 'completed';
}
}
}
/**
* Проверяет завершен ли текущий уровень
* @returns {boolean}
*/
_checkLevelCompletion() {
return this.bricks.every((brick) => brick.type === 3 || !brick.alive);
}
/**
* Запускает переход на новый уровень, возвращает мяч в дефоотное положение и отрисовывает кирпичи по карте уровня.
*/
_proceedToNextLevel() {
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);
}
}