ホームページ > 記事 > ウェブフロントエンド > JavaScript IV を使用したテトリスの作成: キャンバス
このシリーズの新しい記事では、ボードと現在画面上に落ちている駒を表示する方法を見ていきます。これを行うには、ブラウザで描画する必要があります。そのためのオプションは、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 は、駒とボードの正方形の間に残す分離です。このボックスは、
フレームを描画というタイトルのコード段落で最初に描画するものです。 これは ストローク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.rows まで行を処理します。次に、getRow() メソッドで完全な行を取得し、Board.cols. まで内部ループで走査します。
行/列のセルが指定された場合、f/c、Board.getCell(f, c)、およびJavaScript には、0 以外の値が true を意味する整数を受け入れる Boolean のコンストラクターがあることを考慮して、辺が PIXEL_SIZE の正方形をペイントします。したがって、行 f をどこにペイントするかを知るには、PIXEL_SIZE を乗算し、ボード ボックスと最初のセルの間の間隔を追加する必要があります。これらは正方形であるため、同じ方法で列 c を見つけます: SEP + (c * PIXEL_SIZE).
作品をペイントするshape) を使用すると、再び 2 つのループが作成されます。外側のループは行用で、内側のループは列用です。
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 を掛けて、ボックスによる分離を追加する必要があります。
今、私たちが目にしているものは、まったく…当たり障りのないものです。ボードは空で、ゲームループがないので、駒も落ちません。このトピックについては次回の記事で説明し、上の画像のようなものを確認できるようにします。
以上がJavaScript IV を使用したテトリスの作成: キャンバスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。