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 であることと主キーの自己選択制約の関係についての詳しい説明 (詳細)

推薦する

CSS スタイルの競合を解決するいくつかの方法 (要約)

1. セレクターを調整するコンビネータを使用すると、セレクターの説明をより正確に記述できます (C...

Dockerイメージのサイズを縮小する6つの方法

2017 年に Vulhub に取り組み始めてから、私は厄介な問題に悩まされてきました。Docker...

Docker+Selenium Grid に基づく技術アプリケーションをテストするためのサンプル コード

Selenium Grid の紹介Selenium Grid のいくつかの新しい機能は、今後リリース...

Linux インストール Redis 実装プロセスとエラー解決

今日、redis をインストールしたところ、今までになかったいくつかのエラーが発生しました。ここで記...

ウェブサイトのコンテンツの100~1%はナビゲーションである

ウェブサイトでは、コンテンツの(100-1)%がナビゲーションです1. ジェシー・ジェームズ・ギャレ...

Flash での HTML と CSS の適用

Flash での HTML と CSS の適用:同僚の Den が Flash で HTML と C...

HTML の類似タグと属性の違いの詳細な説明

【1】<i></i>タグと<em></em>タグ同じ...

JSプロトタイプとプロトタイプチェーンについての簡単な説明

目次1. プロトタイプ2. プロトタイプポインタ: __proto__要約する1. プロトタイプJa...

Centos7でmysql6の初期化インストールパスワードをインストールする方法

1. まずデータベースサーバーを停止しますサービスmysqld停止2.vim /etc/my.cnf...

JavaScript 関数呼び出し、適用、バインド メソッドのケース スタディ

要約する1. 類似点どちらも、ターゲット関数が実行されると内部の this ポインターを変更できます...

docker createコマンドの使用方法

docker create コマンドは、イメージに基づいてコンテナを作成できます。このコマンドの効果...

ネイティブ js でカスタム難易度のマインスイーパ ゲームを実装する

この記事の例では、マインスイーパゲームを実装するためのjsの具体的なコードを参考までに共有しています...

MySQL の複合インデックスはどのように機能しますか?

目次背景複合インデックスを理解する左端一致原則フィールド順序の影響複合インデックスは単一のインデック...

nginxとIISで使用できるSSL証明書を作成する

目次SSL証明書の作成1. 秘密鍵を生成する2. 証明書要求ファイルを生成する3. CRT証明書ファ...

MySQL の垂直テーブルを水平テーブルに変換する方法と最適化のチュートリアル

1. 縦型テーブルと横型テーブル垂直テーブル: テーブル内のフィールドとフィールド値はキーと値の形式...