>  기사  >  웹 프론트엔드  >  JavaScript IV로 테트리스 만들기: 캔버스

JavaScript IV로 테트리스 만들기: 캔버스

PHPz
PHPz원래의
2024-07-16 20:45:22380검색

소개

이번 시리즈에서는 보드와 현재 화면에 내려가고 있는 작품을 어떻게 표시하는지 살펴보겠습니다. 이렇게 하려면 브라우저에서 그려야 하며, 그렇게 해야 하는 옵션은 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...
}

캔버스 클래스는 생성자에서 매개변수로 전달되는 동일한 이름의 HTML 요소를 나타냅니다. 보드를 그릴 예정이므로 그릴 포인트에 접근하기 위해 매개변수로도 전달됩니다.

가장 먼저 하는 일은 보드 자체가 행을 통해 보고하는 크기에 따라 보드를 수용할 수 있도록 캔버스 요소의 크기를 조정하는 것입니다. . 보드는 또한 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)가 있습니다. 다시 그리기 사이의 시간보다 오랫동안 메서드가 실행된 경우 이런 일이 발생할 수 있습니다. 뭐, 그렇게 되면 다른 문제도 많이 생기겠지만...

다음 단계는 이전 다시 그리기에서 화면에 있던 내용(

프레임)을 삭제하는 것입니다. clearRect()를 사용하여 캔버스의 이미지를 삭제하는 clear() 메서드를 사용하여 이 작업을 수행합니다.

그런 다음 보드를 칠한 다음 그 순간에 내려오는 조각을 칠합니다. 글쎄, 그게 다야. 에일 배송완료.

안돼. 보드와 조각이 어떻게 칠해지는지 봅시다. 가장 먼저 할 일은 보드를 그리는 것입니다. SEP는 조각과 보드 사각형 사이에 남겨두는 분리입니다. 이 상자는

Draw Frame이라는 코드 단락에서 가장 먼저 그리는 것입니다. 스트로크Rect()를 사용하여 그릴 수 있는 간단한 직사각형입니다. 이 직사각형은 왼쪽 상단 꼭지점의 위치와 너비, 높이를 포함하는 4개의 매개변수를 받습니다.

보드 페인팅

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.까지 행을 통과합니다. 그런 다음 Board.cols.까지 내부 루프를 통해 순회하기 위해 getRow() 메서드를 사용하여 전체 행을 얻습니다.

행/열의 셀

f/c, Board.getCell(f, c) 및 JavaScript에는 0을 제외한 모든 값이 true를 의미하는 정수를 허용하는 Boolean에 대한 생성자가 있다는 점을 고려하여 변이 PIXEL_SIZE인 정사각형을 그립니다. 따라서 f 행을 어디에 칠해야 할지 알려면 PIXEL_SIZE를 곱하고 보드 상자와 첫 번째 셀 사이에 간격을 추가해야 합니다. 정사각형이므로 SEP + (c * PIXEL_SIZE)와 같은 방식으로 c 열을 찾습니다.

작품을 그림

우리는 조각으로도 비슷한 일을 합니다. 행렬에 지나지 않는 모양(

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인 정사각형을 칠합니다. 조각을 구성하는 각 사각형을 칠하는 위치는 행/열 조각 자체의 위치(

Piece.row/Piece. 열 ). 여기에 PIXEL_SIZE를 곱하고 상자로 구분을 추가해야 합니다.

El juego Insertrix en su estado actual현재 우리가 볼 수 있는 것은 꽤... 평범합니다. 보드는 비어 있고 게임 루프도 없으므로 조각이 내려가지도 않습니다. 위의 이미지와 유사한 내용을 볼 수 있도록 다음 회에서 해당 주제에 대해 논의하겠습니다.

위 내용은 JavaScript IV로 테트리스 만들기: 캔버스의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:Days of Code 3주차다음 기사:Days of Code 3주차