首页  >  文章  >  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