首頁  >  文章  >  web前端  >  使用 JavaScript IV 建立俄羅斯方塊:canvas

使用 JavaScript IV 建立俄羅斯方塊:canvas

PHPz
PHPz原創
2024-07-16 20:45:22381瀏覽

介紹

在系列的新一期中,我們將了解如何在螢幕上顯示棋盤和目前正在下降的棋子。為此,我們必須在瀏覽器中繪製它,而我們必須執行此操作的選項是 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 並添加與框的分隔。

El juego Insertrix en su estado actual

現在,我們所看到的非常…平淡。棋盤是空的,我們沒有遊戲循環,所以棋子甚至不會落下。我們將在下一部分中討論該主題,以便我們可以開始看到與上圖類似的內容。

以上是使用 JavaScript IV 建立俄羅斯方塊:canvas的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn