diff --git a/src/config.js b/src/config.js index 5265679..ae013d8 100644 --- a/src/config.js +++ b/src/config.js @@ -15,6 +15,8 @@ export const BALL_SPEED_TIME_STEP = 0.002; export const BALL_INITIAL_ANGLE = 0; export const BALL_SPLIT_ANGLE = 20; +export const HEADER_HEIGHT = 30; + export const BRICK_WIDTH = 40; export const BRICK_HEIGHT = 10; diff --git a/src/entities/brick/layBricks/layBricks.js b/src/entities/brick/layBricks/layBricks.js index 1a26e50..46d0765 100644 --- a/src/entities/brick/layBricks/layBricks.js +++ b/src/entities/brick/layBricks/layBricks.js @@ -5,9 +5,10 @@ import { Brick } from '../brick'; * @param {number[][]} levelMap карта уровня в формате массива * @param {number} brickWidth ширина кирпича, неотрицателное число * @param {number} brickHeight длина кирпича, неотрицателное число + * @param {number} marginTop отступ сверху, неотрицательное число * @returns {Brick[]} массив кирпичей */ -export function layBricks(levelMap, brickWidth, brickHeight) { +export function layBricks(levelMap, brickWidth, brickHeight, marginTop = 0) { try { if (!(Array.isArray(levelMap) && levelMap.every(Array.isArray))) { throw new Error('Значение карты уровня должно являться вложенным масивом чисел глубины 2'); @@ -21,12 +22,16 @@ export function layBricks(levelMap, brickWidth, brickHeight) { throw new Error('Значения ширины и высоты кирпича должны являться положительными целыми числами'); } + if (typeof marginTop !== 'number' || marginTop < 0) { + throw new Error('Значение отступа сверху должно быть неотрицательным числом'); + } + const bricks = []; for (let i = 0; i < levelMap.length; i++) { for (let j = 0; j < levelMap[i].length; j++) { if (levelMap[i][j] !== 0) { - bricks.push(new Brick(j * brickWidth, i * brickHeight, brickWidth, brickHeight, levelMap[i][j])); + bricks.push(new Brick(j * brickWidth, marginTop + i * brickHeight, brickWidth, brickHeight, levelMap[i][j])); } } } diff --git a/src/entities/brick/layBricks/layBricks.test.js b/src/entities/brick/layBricks/layBricks.test.js index 70fe366..754bc42 100644 --- a/src/entities/brick/layBricks/layBricks.test.js +++ b/src/entities/brick/layBricks/layBricks.test.js @@ -24,6 +24,16 @@ describe('layBricks', () => { expect(layBricks(levelMap, 1, 1)).toBeNull(); }); + it('Возвращает корректное значение в случае некоректного отступа', () => { + const levelMap = [ + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + ]; + + expect(layBricks(levelMap, 1, 1, -1)).toBeNull(); + }); + it('Возвращает массив корректных размеров', () => { const levelMap = [ [1, 1, 1, 1, 1], diff --git a/src/game.js b/src/game.js index 3f52fc9..1bf0d44 100644 --- a/src/game.js +++ b/src/game.js @@ -8,6 +8,7 @@ import { BRICK_WIDTH, CONTAINER_HEIGHT, CONTAINER_WIDTH, + HEADER_HEIGHT, PADDLE_HEIGHT, PADDLE_WIDTH, PERK_BALL_SPEED_DECREASE, @@ -33,7 +34,7 @@ export class Game { this.paddle = new Paddle(0, CONTAINER_HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT); this.balls = [new Ball(0, 0, BALL_RADIUS, BALL_SPEED, BALL_INITIAL_ANGLE)]; - this.bricks = layBricks(this.levels[this.currentLevel], BRICK_WIDTH, BRICK_HEIGHT); + this.bricks = layBricks(this.levels[this.currentLevel], BRICK_WIDTH, BRICK_HEIGHT, HEADER_HEIGHT); this.perks = []; this._placeBallOnPaddle(); @@ -112,7 +113,7 @@ export class Game { _proceedToNextLevel() { this.ball.increaseSpeed(BALL_SPEED_LEVEL_STEP); this._placeBallOnPaddle(); - this.bricks = layBricks(this.levels[this.currentLevel], BRICK_WIDTH, BRICK_HEIGHT); + this.bricks = layBricks(this.levels[this.currentLevel], BRICK_WIDTH, BRICK_HEIGHT, HEADER_HEIGHT); } /** diff --git a/src/view.js b/src/view.js index e7e2f51..6647d04 100644 --- a/src/view.js +++ b/src/view.js @@ -1,4 +1,4 @@ -import { Container, Graphics } from 'pixi.js'; +import { Container, Graphics, Text } from 'pixi.js'; import { Ball } from './entities/ball/ball'; import { Brick } from './entities/brick/brick'; import { Paddle } from './entities/paddle/paddle'; @@ -67,6 +67,11 @@ function createPerkView(perk) { */ export function createGameView(game, container) { try { + const header = new Text({ style: { fill: '#ffffff', fontSize: 16 } }); + header.x = 8; + header.y = 8; + container.addChild(header); + const balls = new Map(); for (const ball of game.balls) { const ballView = createBallView(ball); @@ -86,6 +91,7 @@ export function createGameView(game, container) { const perks = new Map(); return { + header, balls, paddle, bricks, @@ -155,6 +161,8 @@ export function syncronizeViewsWithGame(views, game) { throw new Error('Аргумент game должен быть экземпляром класса Game'); } + views.header.text = `Уровень: ${game.currentLevel + 1} Количество жизней: ${game.livesAmount}`; + for (const ball of game.balls) { const ballView = views.balls.get(ball); ballView.x = ball.x;