VUE+CanvasはシンプルなGobangゲームの全プロセスを実現します

VUE+CanvasはシンプルなGobangゲームの全プロセスを実現します

序文

レイアウトの点では、Gobang はランダムな動きを目的とするゲームよりも実装がはるかに簡単で、アイデアも明確です。Gobang は次のように分かれています。

(1)チェス盤を描く。

(2)クリックイベントをリッスンし、黒と白のチェスの駒を描きます。

(3)各移動後、5つの駒がつながっているかどうかを判定します。つながっている場合は勝ちです。

一番複雑なのは、ゴバンが勝ったかどうかをどうやって判断するかということでしょう。そこで、まずは簡単なところから、チェス盤を描いてみましょう。

1. チェス盤を描く

チェス盤は非常にシンプルです。交差する水平線と垂直線を持つ 15 x 15 のチェス盤を描きましょう。

チェッカーボードを描画する() {
      // チェス盤を描画します let _this = this;
      _this.ctx.beginPath();
      _this.ctx.fillStyle = "#fff";
      _this.ctx.rect(0, 0, 450, 450);
      _this.ctx.fill();
      (var i = 0; i < 15; i++) の場合 {
        _this.ctx.beginPath();
        _this.ctx.strokeStyle = "#D6D1D1";
        _this.ctx.moveTo(15 + i * 30, 15); // 30px間隔で垂直に15本の線を描きます。
        _this.ctx.lineTo(15 + i * 30, 435);
        _this.ctx.stroke();
        _this.ctx.moveTo(15, 15 + i * 30); // 30px間隔で水平方向に15本の線を描きます。
        _this.ctx.lineTo(435, 15 + i * 30);
        _this.ctx.stroke();
 
        _this.resultArr.push(新しい配列(15).fill(0));
      }
}

まず 450 × 450 の正方形をベースとして使用し、その周りに幅 15 の空白を残し、間隔 30 で線を描きます。 for ループでは、15 * 15 の 2 次元配列も初期化し、0 で埋めました。はい、これは動きを記録するために使用されます。

2. クリックイベントをリッスンして黒と白のチェスの駒を描画する

さて、DOM を取得したら、クリック イベントをリッスンしてチェスの駒を描画します。

コンテナを document.getElementById("gobang");

container.addEventListener("クリック", _this.handleClick);

ハンドルクリック(イベント) {
      x = event.offsetX - 70 とします。
      y = event.offsetY - 70 とします。
      (x < 15 || x > 435 || y < 15 || y > 435) の場合 {
        // 範囲外をクリックすると return;
      }
      this.drawChess(x, y);
      if(this.winGame){
        この.drawResult();
        戻る;
      }
      this.whiteTurn = !this.whiteTurn;
      テキストを描画します。
}

チェスの駒を描くコード:

チェスを描く(x, y) {
      _this = this とします。
      let xLine = Math.round((x - 15) / 30); // 垂直線の数 x let yLine = Math.round((y - 15) / 30); // 水平線の数 y if(_this.resultArr[xLine][yLine] !== 0){
        戻る;
      }
      grd = _this.ctx.createRadialGradient( とする
        x行 * 30 + 15、
        yライン * 30 + 15、
        4、
        x行 * 30 + 15、
        yライン * 30 + 15、
        10
      );
      grd.addColorStop(0, _this.whiteTurn ? "#fff" : "#4c4c4c");
      grd.addColorStop(1, _this.whiteTurn ? "#dadada" : "#000");
      _this.ctx.beginPath();
      _this.ctx.fillStyle = grd;
      _this.ctx.arc(
        x行 * 30 + 15、
        yライン * 30 + 15、
        10、
        0,
        2 * 数学.PI、
        間違い
      );
      _this.ctx.fill();
      _this.ctx.closePath();
 
      _this.setResultArr(xLine, yLine);
      _this.checkResult(xLine, yLine);
}

クリックした座標に最も近いチェス盤の交点を計算するのは簡単です。 もちろん、そこにすでに駒が置かれている場合は、戻る必要があります。次に、交差点に白または黒の駒を描き、ここでグラデーション塗りつぶしを使用してチェスの駒をよりリアルに見せます。次に、チェスの駒の状態を対応する 2 次元配列に記録します。

setResultArr(m, n) {
      _this = this とします。
      _this.resultArr[m][n] = _this.whiteTurn ? 1 : 2; // 白は1、黒は2
 
}

3. 五番勝負の勝敗結果を確認する

勝ち負けの結果はどうやって決まるのでしょうか?肉眼では、現在の動きを 0,0 原点とする座標系を確立し、0°、180°、45°、135° の 4 つの線上に 5 つの連続した駒があるかどうかを判断するだけです。直接走査してカウントするよりも、4 行のデータを取り出して、1 文字または 2 文字が 5 つ連続しているかどうかを判断する方がよい方法です。

配置の配列座標が[m, n]であるとします。

(1)水平線の結果配列文字列:this.resultArr[m].join('');

(2)縦線の結果配列文字列:

for(i = 0; i<15; i++){
        水平方向の行をプッシュします(_this.resultArr[i][n]);

}

(3)135°(左上から右下):jの範囲は0から15なので、this.resultArr[m - j][n - j]を取って一時配列の先頭にシフト解除し、this.resultArr[m + j][n + j]を取って一時配列の末尾に置いて結果を形成する。

(4)45°(左下から右上):jの範囲は0から15なので、this.resultArr[m + j][n - j]を取って一時配列の先頭にシフト解除し、this.resultArr[m - j][n + j]を取って一時配列の末尾に置いて結果を形成します。

もちろん、配列が範囲外であるかどうかを判断する必要があります。

結果文字列を取得した後、「22222」や「11111」のような文字列があるかどうかを確認します。ある場合は勝利を意味します。

checkResult(m,n){ // 連結されたピースが 5 つあるかどうかを確認します。let _this = this;
      checkStr = _this.whiteTurn ? CheckStrWhite : CheckStrBlack とします。
      // 4行の1次元配列[m,n]を取り出します。let lineVertical = _this.resultArr[m].join('');
      (lineVertical.indexOf(checkStr) > -1) の場合 {
        _this.winGame = true;
        戻る;
      }
      lineHorizo​​ntal = [] とします。
      for(i = 0; i<15; i++){
        水平方向の行をプッシュします(_this.resultArr[i][n]);
      }
      水平線 = 水平線.join('');
      (lineHorizo​​ntal.indexOf(checkStr) > -1) の場合 {
        _this.winGame = true;
        戻る;
      }
      135行目を[]とします。
      (j = 0; j < 15; j++){
        if(m - j >= 0 && n - j >= 0){ // 左上隅 line135.unshift(_this.resultArr[m - j][n -j]);
        }
        if(j > 0 && m + j < 15 && n + j < 15){ // 右下隅 line135.push(_this.resultArr[m + j][n + j]);
        }
      }
      行135 = 行135.join('');
      if(line135.indexOf(checkStr) > -1){
        _this.winGame = true;
        戻る;
      }
      45行目を[]とします。
      (j = 0; j < 15; j++){
        if(m + j < 15 && n - j >= 0){ // 右上隅 line45.unshift(_this.resultArr[m + j][n -j]);
        }
        if(j > 0 && m - j >=0 && n + j < 15){ // 左下隅 line45.push(_this.resultArr[m - j][n + j]);
        }
      }
      行45 = 行45.join('');
      if(line45.indexOf(checkStr) > -1){
        _this.winGame = true;
        戻る;
      }
}

最後に、どちらが勝つかを示します。

これで、シンプルな白黒チェスゲームが完成です~~~~~

いつものように、ソースコードは次のとおりです。

<テンプレート>
  <div class="gobang">
    <canvas id="gobang" width="800" height="600"></canvas>
  </div>
</テンプレート>
 
<スクリプト>
定数CheckStrWhite = "11111";
定数CheckStrBlack = "22222";
エクスポートデフォルト{
  名前: 「ゴバン」
  データ() {
    戻る {
      ctx: null、
      勝利ゲーム: 偽、
      whiteTurn: false, // 白ターン; true - 黒ターンresultArr: [] // チェスの駒の位置を記録する配列};
  },
  マウント() {
    _this = this とします。
    コンテナを document.getElementById("gobang");
 
    container.addEventListener("クリック", _this.handleClick);
 
    _this.ctx = コンテナ.getContext("2d");
    _this.ctx.translate(70,70);
    _this.drawCheckerboard();
  },
  計算:{
    チェステキスト(){
      this.whiteTurn ? 'ホワイトチェス' : 'ブラックチェス' を返します。
    }
  },
  メソッド: {
    チェッカーボードを描画する() {
      // チェス盤を描画します let _this = this;
      _this.ctx.beginPath();
      _this.ctx.fillStyle = "#fff";
      _this.ctx.rect(0, 0, 450, 450);
      _this.ctx.fill();
      (var i = 0; i < 15; i++) の場合 {
        _this.ctx.beginPath();
        _this.ctx.strokeStyle = "#D6D1D1";
        _this.ctx.moveTo(15 + i * 30, 15); // 30px間隔で垂直に15本の線を描きます。
        _this.ctx.lineTo(15 + i * 30, 435);
        _this.ctx.stroke();
        _this.ctx.moveTo(15, 15 + i * 30); // 30 ピクセル間隔で水平に 15 本の線を描きます。チェス盤は 14*14 です。
        _this.ctx.lineTo(435, 15 + i * 30);
        _this.ctx.stroke();
 
        _this.resultArr.push(新しい配列(15).fill(0));
      }
      _this.drawText();
    },
    チェスを描く(x, y) {
      _this = this とします。
      let xLine = Math.round((x - 15) / 30); // 垂直線の数 x let yLine = Math.round((y - 15) / 30); // 水平線の数 y if(_this.resultArr[xLine][yLine] !== 0){
        戻る;
      }
      grd = _this.ctx.createRadialGradient( とする
        x行 * 30 + 15、
        yライン * 30 + 15、
        4、
        x行 * 30 + 15、
        yライン * 30 + 15、
        10
      );
      grd.addColorStop(0, _this.whiteTurn ? "#fff" : "#4c4c4c");
      grd.addColorStop(1, _this.whiteTurn ? "#dadada" : "#000");
      _this.ctx.beginPath();
      _this.ctx.fillStyle = grd;
      _this.ctx.arc(
        x行 * 30 + 15、
        yライン * 30 + 15、
        10、
        0,
        2 * 数学.PI、
        間違い
      );
      _this.ctx.fill();
      _this.ctx.closePath();
 
      _this.setResultArr(xLine, yLine);
      _this.checkResult(xLine, yLine);
    },
    setResultArr(m, n) {
      _this = this とします。
      _this.resultArr[m][n] = _this.whiteTurn ? 1 : 2; // 白は1、黒は2
 
    },
    
    checkResult(m,n){ // 連結されたピースが 5 つあるかどうかを確認します。let _this = this;
      checkStr = _this.whiteTurn ? CheckStrWhite : CheckStrBlack とします。
      // 4行の1次元配列[m,n]を取り出します。let lineVertical = _this.resultArr[m].join('');
      (lineVertical.indexOf(checkStr) > -1) の場合 {
        _this.winGame = true;
        戻る;
      }
      lineHorizo​​ntal = [] とします。
      for(i = 0; i<15; i++){
        水平方向の行をプッシュします(_this.resultArr[i][n]);
      }
      水平線 = 水平線.join('');
      (lineHorizo​​ntal.indexOf(checkStr) > -1) の場合 {
        _this.winGame = true;
        戻る;
      }
      135行目を[]とします。
      (j = 0; j < 15; j++){
        if(m - j >= 0 && n - j >= 0){ // 左上隅 line135.unshift(_this.resultArr[m - j][n -j]);
        }
        if(j > 0 && m + j < 15 && n + j < 15){ // 右下隅 line135.push(_this.resultArr[m + j][n + j]);
        }
      }
      行135 = 行135.join('');
      if(line135.indexOf(checkStr) > -1){
        _this.winGame = true;
        戻る;
      }
      45行目を[]とします。
      (j = 0; j < 15; j++){
        if(m + j < 15 && n - j >= 0){ // 右上隅 line45.unshift(_this.resultArr[m + j][n -j]);
        }
        if(j > 0 && m - j >=0 && n + j < 15){ // 左下隅 line45.push(_this.resultArr[m - j][n + j]);
        }
      }
      行45 = 行45.join('');
      if(line45.indexOf(checkStr) > -1){
        _this.winGame = true;
        戻る;
      }
    },
    テキストを描画する(){
      _this = this とします。
      _this.ctx.clearRect(435 + 60, 0, 100, 70);
      _this.ctx.fillStyle = "#fff";
      _this.ctx.font="20px Arial";
      _this.ctx.fillText('このラウンド:' + _this.chessText, 435 + 70, 35);
    },
    描画結果(){
      _this = this とします。
      _this.ctx.fillStyle = "#ff2424";
      _this.ctx.font="20px Arial";
      _this.ctx.fillText(_this.chessText+'勝ちました!', 435 + 70, 70);
    },
    ハンドルクリック(イベント) {
      x = event.offsetX - 70 とします。
      y = event.offsetY - 70 とします。
      (x < 15 || x > 435 || y < 15 || y > 435) の場合 {
        // 範囲外をクリックすると return;
      }
      this.drawChess(x, y);
      if(this.winGame){
        この.drawResult();
        戻る;
      }
      this.whiteTurn = !this.whiteTurn;
      テキストを描画します。
    }
  }
};
</スクリプト>
 
<!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します -->
<スタイル スコープ lang="scss">
.ゴバン {
  #ゴバン {
    背景: #2a4546;
  }
}
</スタイル>

要約する

VUE+Canvas を使って簡単な Gobang ゲームを実装する方法についての記事はこれで終わりです。VUE+Canvas Gobang ゲームに関するその他の関連コンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue が Gobang ゲームを実装
  • Vue が Gobang ゲームを実装

<<:  Linux で PHP curl 拡張機能をインストールする方法の詳細な説明

>>:  MySQL における主キーが 0 であることと主キーの自己選択制約の関係についての詳しい説明 (詳細)

推薦する

mysql8.0.14.zip のインストール中にデータ フォルダを自動的に作成できませんでした。サービスを開始できません。

今日システムを再インストールした後、コンピューターに mysql を再インストールし、ZIP ファイ...

Vue+WebSocket ページでの長時間接続のリアルタイム更新

最近、Vue プロジェクトではデータをリアルタイムで更新する必要があります。折れ線グラフは 1 秒ご...

5分でDockerを使ってRedisのクラスターモードとセンチネルモードを構築する方法を教えます

目次1. 準備Redisイメージを取得する2. Redis Sentinel マスタースレーブモード...

Vue のクロスドメイン問題の処理と解決策の概要

ネットワークリクエストを送信すると、次の保存情報が表示されます。おめでとうございます。ドメインを越え...

Ubuntu 18でターミナルを美しいコマンドラインプロンプトに変更する方法

VMware と Ubuntu を再インストールしましたが、コマンドラインプロンプトが単調すぎて美し...

MySQL エラー「すべての派生テーブルには独自のエイリアスが必要です」の解決方法

MySQL は、マルチテーブルクエリを実行するときにエラーを報告します。 [SQL] SELECT ...

Dockerを使用してOracle_11gをインストールする方法

DockerでOracle_11gをインストールする1. oracle_11gイメージを取得する d...

UbuntuへのDocker CEのインストール

この記事は、Ubuntu 17.10 での Docker CE のインストールを記録するために使用さ...

CentOS 8 VMware 仮想マシンがインターネットにアクセスするための静的 IP ネットワーク カードの設定の詳細な説明

最初のステップ: VMwareで、「編集」-「仮想ネットワークエディタ」をクリックします。下図に示す...

HTMLを圧縮しない理由はいくつかある

理由は簡単です。 HTML ドキュメントでは、複数の空白文字は 1 つの空白文字と同等です。つまり、...

SeataがMySQL 8バージョンを使用できない問題を解決する方法

考えられる理由: Seata が MySQL 8 をサポートしない主な理由は、接続ドライバーがバージ...

MacOS に MySQL 8.0 をインストールして MySQL にログインする方法

公式チュートリアルに従って、インストール パッケージをダウンロードし、[インストール] をクリックし...

JS のあらゆる場所で絶対等価演算子の使用をやめる

目次概要1. NULL値のテスト2. ユーザー入力を読み取る導入事実の根源はどこにあるのでしょうか?...

nginxでの共有メモリの使用に関する詳細な説明

nginx プロセス モデルでは、トラフィック統計、トラフィック制御、データ共有などのタスクを完了す...

Vueはechartを使用してラベルと色をカスタマイズします

この記事では、参考までに、echartを使用してタグと色をカスタマイズするVueの具体的なコードを紹...