このシリーズの新しい記事では、ボードと現在画面上に落ちている駒を表示する方法を見ていきます。これを行うには、ブラウザで描画する必要があります。そのためのオプションは、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 ); } }
ガード (
_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; } }
つまり、最初のループは
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; } }
Piece.row/Piece. 列)。これに PIXEL_SIZE を掛けて、ボックスによる分離を追加する必要があります。
今、私たちが目にしているものは、まったく…当たり障りのないものです。ボードは空で、ゲームループがないので、駒も落ちません。このトピックについては次回の記事で説明し、上の画像のようなものを確認できるようにします。
以上がJavaScript IV を使用したテトリスの作成: キャンバスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。