В этой новой части серии мы увидим, как отображать доску и фигуру, которая в данный момент отображается на экране. Для этого нам нужно будет нарисовать его в браузере, и мы можем сделать это с помощью HTML-элемента Canvas.
class Canvas { static SEPARATION = 2; #_painting = false; #_element = null; #_board = null; #_piece = null; constructor(element, board) { element.width = 5 ( board.cols * Board.PIXEL_SIZE ); element.height = 5 ( board.rows * Board.PIXEL_SIZE ); this._board = board; this._element = element; } // más cosas... }
Этот класс Canvas представляет одноименный элемент HTML, который передается в качестве параметра в конструктор. Поскольку вы собираетесь рисовать доску, она также передается как параметр, чтобы получить доступ к точкам для рисования.
Первое, что он делает, это изменяет размер элемента Canvas для размещения доски в соответствии с размерами, которые сама доска сообщает через свои свойства cols и rows. Доска также сообщает нам, сколько пикселей составляет точку каждого фрагмента или каждой ячейки доски, через PIXEL_SIZE.
Давайте прекратим обходные пути. Нам нужно покрасить доску и фигуру, которая в этот момент опускается, верно? Что ж, приступим к делу.
class Canvas { // más cosas... paint() { if ( this._painting ) { return; } const ctx = this.element.getContext( "2d" ); const SEP = Canvas.SEPARATION; this._painting = true; this.clear(); this.paintBoard( ctx, SEP ); this.paintPiece( ctx, SEP ); this._painting = false; } clear() { const ctx = this.element.getContext( "2d" ); ctx.clearRect( 0, 0, this.element.width, this.element.height ); } }
Сначала мы берем контекст для 2D, который позволит нам рисовать на холсте. Ради интереса, есть еще контекст для 3D, основанный на WebGL.
У нас есть некоторые защитные меры (_painting), которые не позволяют нескольким потокам одновременно (в разных точках) выполнить метод в определенный момент времени. Это могло произойти, если метод выполнялся дольше, чем время между перерисовками. Хотя что ж, в таком случае у нас было бы много других проблем...
Следующий шаг — удалить то, что было на экране при предыдущей перерисовке (кадр). Мы делаем это с помощью метода clear(), который использует clearRect() для удаления изображения на холсте.
А потом мы красим доску, а затем фигуру, которая в этот момент падает. Ну, вот и все. Але, доставка завершена.
Я сказал нет. Давайте посмотрим, как раскрашены доска и фигура. Первым делом покрасим доску. SEP — это расстояние, которое мы оставим между фигурами и полем доски. Это поле — первое, что мы рисуем в параграфе кода под названием Нарисовать рамку. Это простой прямоугольник, который можно нарисовать с помощью strokeRect(), который принимает четыре параметра: положение верхней левой вершины, а затем ее ширину и высоту.
class Canvas { // más cosas... paintBoard(ctx, SEP) { // Draw frame ctx.strokeWidth = 1; ctx.strokeStyle = this.board.color; ctx.strokeRect( 1, 1, this.element.width - 1, this.element.height -1 ); // Draw board for(let numRow = 0; numRowДалее идет вложенный цикл (строки и столбцы), поэтому мы посмотрим, в каких ячейках на доске есть содержимое (целое число 1, а не целое число 0), а затем нарисуем небольшой квадрат со стороной PIXEL_SIZE.
Таким образом, первый цикл проходит по строкам до тех пор, пока Board.rows. Затем мы получаем полную строку с помощью метода getRow(), чтобы пройти ее с помощью внутреннего цикла, пока Board.cols.
Итак, дана ячейка в строке/столбце f/c, Board.getCell(f, c), и принимая во внимание, что в JavaScript есть конструктор для Boolean, который принимает целое число, любое значение которого, кроме 0, означает true, мы рисуем квадрат со стороной PIXEL_SIZE. Итак, чтобы знать, где рисовать строку f, нам нужно умножить ее на PIXEL_SIZE и добавить расстояние между полем доски и первой ячейкой. Поскольку они квадратные, то столбец c мы найдем таким же образом: SEP (c * PIXEL_SIZE).
Раскрашивание произведения
Мы делаем что-то подобное с деталями. Имея форму (shape), которая представляет собой не что иное, как матрицу, у нас снова будет два цикла: внешний для строк и внутренний для столбцов.
class Canvas { // más cosas... paintPiece(ctx, SEP) { const SHAPE = this.piece.shape; for(let numRow = 0; numRowОпять же, если мы найдем 1, мы нарисуем квадрат со стороной PIXEL_SIZE. Позиция закрашивания каждого квадрата, составляющего фигуру, определяется положением строки/столбца самой фигуры (Piece.row/Piece. капуста). Вам нужно умножить это значение на PIXEL_SIZE и добавить разделение с помощью рамки.
Прямо сейчас то, что мы сможем увидеть, довольно... пресно. Доска пуста, игрового цикла у нас нет, поэтому фишки даже не падают. Мы обсудим эту тему в следующем выпуске, чтобы увидеть нечто похожее на изображение выше.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3