Rumah  >  Artikel  >  hujung hadapan web  >  Mencipta Tetris dengan JavaScript IV: kanvas

Mencipta Tetris dengan JavaScript IV: kanvas

PHPz
PHPzasal
2024-07-16 20:45:22381semak imbas

pengenalan

Dalam ansuran baharu siri ini, kita akan melihat cara memaparkan papan dan bahagian yang sedang turun pada skrin. Untuk melakukan ini, kita perlu melukisnya dalam penyemak imbas, dan pilihan yang perlu kita lakukan ialah elemen Kanvas HTML.

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...
}

Kelas ini Kanvas mewakili elemen HTML dengan nama yang sama, yang diluluskan sebagai parameter dalam pembina. Memandangkan anda akan melukis papan, ia juga diluluskan sebagai parameter, untuk mengakses mata untuk dilukis.

Perkara pertama yang dilakukan ialah saiz elemen Kanvas agar dapat memuatkan papan, mengikut dimensi yang dilaporkan oleh papan itu sendiri melalui baris cols dan nya . Papan juga memberitahu kami berapa banyak piksel membuat satu titik bagi setiap bahagian atau setiap sel papan, melalui PIXEL_SIZE.

Melukis semula permainan

Mari kita hentikan lencongan. Kita perlu melukis papan dan kepingan yang sedang menurun pada masa itu, bukan? Baiklah kita mula berniaga.


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 );
    }
}
Mula-mula kami mengambil konteks untuk 2D, yang akan membolehkan kami melukis di atas kanvas. Kerana ingin tahu, terdapat juga konteks untuk 3D, yang berdasarkan WebGL.

Kami mempunyai pengawal (

_painting), yang menghalang beberapa utas daripada melaksanakan kaedah pada masa yang sama (pada titik berbeza), pada masa tertentu. Ini boleh berlaku jika kaedah itu dilaksanakan lebih lama daripada masa antara lukisan semula. Walaupun begitu, dalam kes itu kita akan menghadapi banyak masalah lain...

Langkah seterusnya ialah memadam apa yang terdapat pada skrin dalam lukisan semula sebelumnya (

bingkai). Kami melakukan ini dengan kaedah clear(), yang menggunakan clearRect() untuk memadamkan imej pada kanvas.

Dan kemudian kami melukis papan, dan kemudian kepingan yang turun pada masa itu. Baiklah, itu sahaja. Ale, penghantaran selesai.

Tidak. Mari lihat bagaimana papan dan kepingan itu dicat. Perkara pertama ialah mengecat papan. SEP ialah pemisahan yang akan kita tinggalkan antara kepingan dan segi empat sama papan. Kotak ini ialah perkara pertama yang kita lukis dalam perenggan kod bertajuk

Bingkai Lukis. Ia ialah segi empat tepat mudah yang boleh dilukis dengan strokeRect(), yang menerima empat parameter dengan kedudukan bucu kiri atas, dan kemudian lebar dan tingginya.

Mengecat papan

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 < this.board.rows; ++numRow)
        {
            const row = this.board.getRow( numRow );

            for(let numCol = 0; numCol < row.length; ++numCol) {
                if ( Boolean( row[ numCol ] ) ) {
                    ctx.strokeWidth = 1;
                    ctx.strokeStyle = this.board.color;
                    ctx.fillStyle = this.board.color;
                    ctx.fillRect(
                        SEP + ( Board.PIXEL_SIZE * numCol ),
                        SEP + ( Board.PIXEL_SIZE * numRow ),
                        Board.PIXEL_SIZE,
                        Board.PIXEL_SIZE );
                }
            }            
        }

        return;
    }
}
Seterusnya muncul gelung bersarang (baris dan lajur), jadi kita akan melihat sel mana yang terdapat pada papan yang mempunyai kandungan (integer 1, berbanding integer 0), dan kemudian lukis petak kecil dengan PIXEL_SIZE sisi.

Jadi, gelung pertama melalui baris sehingga

Papan.baris. Kami kemudiannya memperoleh baris lengkap dengan kaedah getRow(), untuk melintasinya dengan gelung dalam, sehingga Papan.cols.

Jadi, diberi sel dalam baris/lajur

f/c, Papan.getCell(f, c), dan mengambil kira bahawa JavaScript mempunyai pembina untuk Boolean yang menerima integer dengan sebarang nilai kecuali 0, bermakna benar, kami melukis segi empat sama dengan PIXEL_SIZE sisi. Jadi, untuk mengetahui di mana hendak melukis baris f, kita perlu mendarab dengan PIXEL_SIZE dan menambah pemisahan antara kotak papan dan sel pertama. Oleh kerana ia adalah segi empat sama, kita akan mencari lajur c dengan cara yang sama: SEP + (c * PIXEL_SIZE).

Melukis kepingan itu

Kami melakukan sesuatu yang serupa dengan kepingan. Dengan mempunyai bentuk (

bentuk), yang tidak lebih daripada matriks, kita akan mempunyai dua gelung sekali lagi, yang luar untuk baris dan yang dalam untuk lajur.

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

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

        for(let numRow = 0; numRow < SHAPE.length; ++numRow) {
            const ROW = SHAPE[ numRow ];
            for(let numCol = 0; numCol < ROW.length; ++numCol) {
                if ( Boolean( ROW[ numCol ] ) ) {
                    ctx.strokeWidth = 1;
                    ctx.strokeStyle = this.piece.color;
                    ctx.fillStyle = this.piece.color;
                    ctx.fillRect(
                        SEP
                        + ( this.piece.col * Board.PIXEL_SIZE )
                        + ( numCol * Board.PIXEL_SIZE ),
                        SEP + 
                        + ( this.piece.row * Board.PIXEL_SIZE )
                        + ( numRow * Board.PIXEL_SIZE ),
                        Board.PIXEL_SIZE,
                        Board.PIXEL_SIZE );
                }
            }
        }

        return;
    }
}
Sekali lagi, jika kita menemui 1, kita akan melukis segi empat sama dengan sisi PIXEL_SIZE. Kedudukan untuk mengecat setiap segi empat sama yang membentuk kepingan diberikan oleh kedudukan bahagian baris/lajur (

Keping.baris/Kepingan. col). Anda perlu mendarab ini dengan PIXEL_SIZE dan menambah pemisahan dengan kotak.

El juego Insertrix en su estado actual

Sekarang ni, apa yang kita nampak agak...hambar. Papan itu kosong, dan kami tidak mempunyai gelung permainan, jadi kepingan itu tidak jatuh. Kami akan membincangkan topik itu dalam ansuran seterusnya, supaya kita boleh mula melihat sesuatu yang serupa dengan imej di atas.

Atas ialah kandungan terperinci Mencipta Tetris dengan JavaScript IV: kanvas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Hari Kod Minggu 3Artikel seterusnya:Hari Kod Minggu 3