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
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 ); } }
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 papanclass 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; } }
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/lajurf/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 itubentuk), 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; } }
Keping.baris/Kepingan. col). Anda perlu mendarab ini dengan PIXEL_SIZE dan menambah pemisahan dengan kotak.
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!