"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Criando um Tetris com JavaScript IV: canvas

Criando um Tetris com JavaScript IV: canvas

Publicado em 01/08/2024
Navegar:776

Introdução

Nesta nova edição da série, veremos como exibir o tabuleiro e a peça que está caindo na tela. Para isso teremos que desenhá-lo no navegador, e a opção que temos para fazer isso é o elemento 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...
}

Esta classe Canvas representa o elemento HTML de mesmo nome, que é passado como parâmetro no construtor. Como você vai desenhar o tabuleiro, ele também é passado como parâmetro, para acessar os pontos a serem desenhados.

A primeira coisa que ele faz é dimensionar o elemento Canvas para acomodar o quadro, de acordo com as dimensões que o próprio quadro informa através de suas propriedades cols e rows. O tabuleiro também nos informa quantos pixels compõem um ponto de cada peça ou de cada célula do tabuleiro, através de PIXEL_SIZE.

Redesenhando o jogo

Vamos parar com os desvios. Temos que pintar o tabuleiro e a peça que está descendo naquele momento, certo? Bem, vamos lá.

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 );
    }
}

Primeiro pegamos o contexto para 2D, o que nos permitirá desenhar na tela. A título de curiosidade, existe também um contexto para 3D, que é baseado em WebGL.

Temos algumas proteções (_painting), que impedem que diversas threads executem o método ao mesmo tempo (em pontos diferentes), em um determinado momento. Isso poderia acontecer se o método fosse executado por mais tempo do que o tempo entre os redesenhos. Embora bem, nesse caso teríamos muitos outros problemas...

O próximo passo é deletar o que estava na tela no redesenho anterior (quadro). Fazemos isso com o método clear(), que usa clearRect() para excluir a imagem na tela.

E aí a gente pinta o quadro, e depois a peça que desce naquele momento. Bem, seria isso. Ale, entrega concluída.

Eu disse não. Vamos ver como o tabuleiro e a peça são pintados. A primeira coisa é pintar o quadro. SEP é a separação que deixaremos entre as peças e o quadrado do tabuleiro. Esta caixa é a primeira coisa que desenhamos no parágrafo de código intitulado Draw frame. É um retângulo simples que pode ser desenhado com strokeRect(), que aceita quatro parâmetros com a posição do vértice superior esquerdo, e depois sua largura e altura.

Pintando o quadro

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 



Em seguida vem um loop aninhado (linhas e colunas), então veremos quais das células do quadro têm conteúdo (um número inteiro 1, versus um número inteiro 0) e, em seguida, desenharemos um pequeno quadrado com lado PIXEL_SIZE.

Assim, o primeiro loop percorre as linhas até Board.rows. Obtemos então a linha completa com o método getRow(), para percorrê-la com o loop interno, até Board.cols.

Então, dada uma célula na linha/coluna f/c, Board.getCell(f, c), e levando em consideração que JavaScript possui um construtor para Boolean que aceita um inteiro que com qualquer valor exceto 0, significa true, pintamos um quadrado com lado PIXEL_SIZE. Então, para saber onde pintar a linha f, temos que multiplicar por PIXEL_SIZE e somar a separação entre a caixa do tabuleiro e a primeira célula. Como são quadradas, encontraremos a coluna c da mesma forma: SEP (c * PIXEL_SIZE).

Pintando a peça

Fazemos algo parecido com as peças. Por termos uma forma (shape), que nada mais é do que uma matriz, teremos novamente dois loops, o externo para linhas e o interno para colunas.

class Canvas {
    // más cosas...

    paintPiece(ctx, SEP)
    {
        const SHAPE = this.piece.shape;

        for(let numRow = 0; numRow 



Novamente, se encontrarmos 1, pintaremos um quadrado com lado PIXEL_SIZE. A posição para pintar cada quadrado que compõe a peça é dada pela posição da linha/coluna da própria peça (Peça.linha/Peça. repolho). Você tem que multiplicar isso por PIXEL_SIZE e adicionar a separação com a caixa.

El juego Insertrix en su estado actual

No momento, o que poderemos ver é bastante... insípido. O tabuleiro está vazio e não temos loop de jogo, então as peças nem caem. Discutiremos esse assunto na próxima edição, para que possamos começar a ver algo semelhante à imagem acima.

Declaração de lançamento Este artigo é reproduzido em: https://dev.to/baltasarq/creard-un-tetris-javascript-iv-anvas-7k?
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3