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

推薦する

vue3 学習ノートにおける axios の使用の変更の概要

目次1. axioの基本的な使い方2. クロスドメインの問題を解決するには? 3. パッケージ4. ...

Vue はアップロードした画像に透かしを追加できるようになりました (アップグレード版)

vueプロジェクトでは、アップロードした画像に透かしを追加して参照できるようにするアップグレード版...

mysql-8.0.11-winx64.zip の詳細なインストール チュートリアル

zip インストール パッケージをダウンロードします。 MySQL8.0 For Windows z...

デザインにおいて無視できないインタラクティブデザインにおける製品状態の分析

製品デザインのプロセスにおいて、デザイナーは常に写真を非常に美しくすることを好みます。仮想ページのコ...

MySQLの大規模テーブル最適化ソリューションについての簡単な説明

背景Alibaba Cloud RDS for MySQL(MySQL バージョン 5.7)データベ...

CSS フォーム検証機能の実装コード

レンダリング原理フォーム要素には、正規表現(携帯電話番号、メールアドレス、IDカードなど)をカスタマ...

詳細なハードウェア情報を取得するための Linux のいくつかのコマンドの詳細な説明

Linux システム、特にサーバー システムでは、デバイスのハードウェア情報を表示する必要がよくあり...

MAC で Mysql5.7.10 のルートパスワードを変更する方法

まず、MySQLをskip-grant-tablesモードで起動します: mysqld --skip...

NavicatがMySQL8.0.11に接続するとエラー2059が発生する

間違いNavicat Premium を使用して MySQL に接続すると、次のエラーが発生します。...

インスタンス化されたオブジェクトパラメータによるMySQLクエリ例の説明

この記事では、オブジェクト パラメータをインスタンス化して MySQL でデータをクエリする方法を紹...

要素のフォームコンポーネントに関する注意事項

要素フォームとコード表示詳細はエレメントフォーム公式サイトをご覧ください構造と機能の分析紹介とソース...

Ubuntu 20.04 オペレーティング システムの VMware インストール チュートリアル図

メモ: とにかく体験してみましょう。記録: NO.209この例の環境:仮想マシン: vmwareオペ...

MySQL 5.7.15 バージョンのインストールと設定方法のグラフィックチュートリアル

この記事では、MySQLバージョン5.7のインストール方法と使用方法、およびデータベースデータの保存...

Vue-Routerのルート設定の詳しい説明

目次導入ルート内のオブジェクト属性パス: 文字列コンポーネント: コンポーネント | () =>...

MySQLループは数千万のデータを挿入する

1. テストテーブルを作成する テーブル `mysql_genarate` を作成します ( `id...