在系列的新一期中,我們將了解如何在螢幕上顯示棋盤和目前正在下降的棋子。為此,我們必須在瀏覽器中繪製它,而我們必須執行此操作的選項是 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元素,它作為建構子中的參數傳遞。由於您要繪製棋盤,因此它也作為參數傳遞,以便訪問要繪製的點。
它所做的第一件事是根據板本身通過其cols 和 行報告的尺寸,調整Canvas 元素的大小,以便能夠容納板。棋盤也透過 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 上下文,這將允許我們在畫布上繪圖。出於好奇,還有一個基於 WebGL 的 3D 上下文。
我們有守衛(
_painting),它可以防止多個執行緒在給定時間同時(在不同點)執行該方法。如果該方法的執行時間長於重繪之間的時間,則可能會發生這種情況。雖然好吧,那樣的話我們還會遇到很多其他問題...
下一步是刪除先前重繪中螢幕上的內容(幀)。我們使用 clear() 方法來執行此操作,該方法使用 clearRect() 刪除畫布上的圖像。
然後我們畫木板,然後畫那一刻掉下來的那塊。嗯,就這樣了。麥酒,配送完畢。不。讓我們看看棋盤和棋子是如何繪製的。首先是給木板上漆。 SEP 是我們在棋子和棋盤方塊之間留下的間隔。這個框是我們在標題為
繪製框架的程式碼段中繪製的第一個東西。 它是一個簡單的矩形,可以使用 tripleRect() 繪製,它接受四個參數,其中包括左上角頂點的位置,然後是其寬度和高度。
畫板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; } }接下來是一個巢狀循環(行和列),因此我們將查看板上的哪些單元格有內容(整數 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 < 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; } }同樣,如果我們找到 1,我們將繪製一個邊長為 PIXEL_SIZE 的正方形。繪製構成該塊的每個方塊的位置由行/列塊的位置給出(
塊.行/塊.上校)。您必須將其乘以 PIXEL_SIZE 並添加與框的分隔。
現在,我們所看到的非常…平淡。棋盤是空的,我們沒有遊戲循環,所以棋子甚至不會落下。我們將在下一部分中討論該主題,以便我們可以開始看到與上圖類似的內容。
以上是使用 JavaScript IV 建立俄羅斯方塊:canvas的詳細內容。更多資訊請關注PHP中文網其他相關文章!