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

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

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

ゲームの特徴:

1. 難易度は4段階あります
2. 難易度を自分で設定できる

1. HTML関連コード

<!DOCTYPE html>
<html lang="ja">
 
<ヘッド>
 <メタ文字セット="UTF-8">
 <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
 <title>マインスイーパ</title>
 <script src="js/mine.js"></script>
 <link rel="スタイルシート" href="./css/mine.css" >
</head>
<!-- 
需要分析:
 1. ゲームエリア:
  9*9 エリア 2. マスを開いてマークすることができます。左クリックして開くと、周囲のマスにある地雷の数を示す数字が表示されます。右クリックしてマークします 3. 地雷はランダムに配置されます 4. 地雷を踏むとゲームが終了し、すべての地雷が表示されます 5. 大きな空のマスを開くためのチェーン 6. 残りの地雷の数とタイマー 7. ゲームの勝利条件。地雷以外のすべてのマスが開くと、ゲームに勝ちます。マスに含まれる情報:
  座標xy
  それは地雷ですか? 周囲の地雷の数 = 9
  2次元配列には周囲の地雷の数が格納されます -->
 
<本文>
 <div class="レベル">
 <button type="button" name="button" class="choice-level">カスタム</button>
 <button type="button" name="button" class="choice-level">初級</button>
 <button type="button" name="button" class="choice-level">中級</button>
 <button type="button" name="button" class="choice-level">詳細</​​button>
 <button type="button" name="button" class="choice-level">悪魔レベル</button>
 <button type="button" name="button" class="restart">再起動</button>
 </div>
 <div class="gameBox"></div>
 <div class="info">
 <p>残りの地雷の数:
  <span class="残留物"></span>
 </p>
 <p>
  時間:
  <span class="tick"></span>S
 </p>
 
 </div>
</本文>
 
 
</html>

2. CSSスタイル

*{
 マージン: 0;
 パディング: 0;
}
.ゲームボックス{
 上マージン: 30px;
}
体{
 フォントサイズ: 0;
}
ul{
 リストスタイル: なし;
 テキスト配置: 中央;
 オーバーフロー: 非表示;
}
.col{
 表示: インラインブロック;
 幅: 22px;
 高さ: 22px;
 行の高さ: 22px;
 背景色: rgba(32, 226, 255, 0.4);
 境界線: 1px実線rgb(129, 129, 129);
 フォントサイズ: 16px;
 マージン: 1.5px;
 垂直方向の位置合わせ: 上;
 位置: 相対的;
}
.col:hover{
 背景色: #0af;
}
.col span{
 カーソル: デフォルト;
}
。隠れる{
 表示: なし;
}
。ブーム{
 背景: url("../img/boom.svg") 繰り返しなし 2.5px 2px;
 背景サイズ: 18px 18px;
}
.nu​​m-1{
 色: rgb(8, 153, 235);
}
.nu​​m-2{
 色: rgb(255, 45, 178);
}
.nu​​m-3{
 カラー:#16a085;
}
.nu​​m-4{
 色: #8e44ad;
}
.nu​​m-5{
 色: rgb(255, 167, 45);
}
.nu​​m-6{
 色: rgb(8, 126, 176);
}
.nu​​m-7{
 色: #e67e22;
}
.nu​​m-8{
 色: #c0392b;
}
.img-フラグ{
 幅: 18px;
 高さ: 18px;
 位置: 絶対;
 上: 3px;
 左: 3px;
}
。レベル{
 上マージン: 30px;
 フォントサイズ: 20px;
 テキスト配置: 中央;
}
.レベルボタン{
 パディング: 5px 8px;
 背景色: rgb(67, 183, 189);
 境界線: なし;
 アウトライン: なし;
 境界線の半径: 3px;
 カーソル: ポインタ;
 色: #fff;
}
.level ボタン:hover{
 背景色: rgb(23, 132, 138);
}
。情報{
 上マージン: 30px;
 フォントサイズ: 16px;
 テキスト配置: 中央;
}
.info p{
 表示: インラインブロック;
 幅: 130ピクセル;
 マージン: 0 自動;
}
.info p span{
 色: rgb(67, 183, 189);
}

3.jsコード

window.onload = 関数() {
 var 行 = 4;
 var 列 = 4;
 var 数値 = 1;
 // 地雷を踏んだ後は勝てないと判断する var gg = false;
 // マップを生成する function mineMap(r, c, num) {
 //定義行 var map = [];
 //行数を指定して2次元配列を生成する for (var i = 0; i < r; i++) {
  map[i] = 新しい配列()
 }
 // 代入 for (var i = 0; i < map.length; i++) {
  (var j = 0; j < c; j++) の場合 {
  // //周囲の地雷の数 map[i][j] = 0;
  }
 }
 var plus = 関数(配列、x、y) {
  (x >= 0 && x < r && y >= 0 && y < c) の場合 {
  配列[x][y] !== 9の場合{
   配列[x][y]++
  }
  }
 }
 (var i = 0; i < num; i++) の場合 {
  var x = Math.floor(Math.random() * r)
  var y = Math.floor(Math.random() * c)
  マップ[x][y]が9の場合
  マップ[x][y] = 9
   //6 上下 + 1
  (var j = -1; j < 2; j++) の場合 {
   //3 プラス (map, x - 1, y + j)
   //次の3つは(map, x + 1, y + j)を加算します
  }
  //左右に2つずつ+1
  プラス(マップ、x、y - 1)
  プラス(マップ、x、y + 1)
  } それ以外 {
  //num++ を再ランダム化
  }
 }
 マップを返します。
 }
 //まず x 軸の量を ul に書き込み、次に y 軸の属性を li に書き込みます。
 関数 writeHtml(map) {
 // ボックスを取得します var gameBox = document.querySelector(".gameBox");
 //生成されたulとliを格納するための空の文字列を宣言します
 var グリッドHTML = "";
 (var i = 0; i < map.length; i++) の場合 {
  gridHTML += '<ul class = "row" data-x="' + i + '">';
  //liを生成する
  (var j = 0; j < map[0].length; j++) {
  var m = マップ[i][j]
  (m == 0)の場合{
   m = "";
  }
  グリッドHTML += "<li class='col' data-y=" + j + ">" +
   "<span class='hide num-" + m + "'>" + m + "</span>" +
   "<img src='img/flag.svg' class='img-flag hide'>" +
   「</li>」
  }
  グリッドHTML += '</ul>'
  ゲームボックスの内側のHTMLをグリッドHTMLにする。
 }
 }
 
 //グリッドにイベントをバインドし、デジタルマイン関数を右クリック show() {
 // 行 ul を取得
 var 行 = document.querySelectorAll(".row");
 // すべてのulをトラバースする
 (var i = 0; i < 行数.長さ; i++) {
  var 要素 = 行[i];
  // クリックイベントを追加 element.onclick = function(event) {
   //現在クリックされている要素 var el = event.target;
   // liであるかどうかを判定する
   el.nodeName != "LI") の場合 {
   戻る;
   }
   //todo は開かれてマークされているかどうかを決定します if (el.style.background == "white" || !el.children[1].classList.contains("hide")) {
   戻る;
   }
   // spanタグのコンテンツを取得します。var mineNum = el.children[0].innerHTML;
   if (mineNum !== "9" && el.style.background !== "white") {
   // 空白チェーンがオープン if (mineNum == "") {
    var x = parseInt(el.parentNode.dataset.x);
    var y = parseInt(el.dataset.y);
    showNoMine(x, y);
   }
   // li 背景が白に変わり、span は el.style.background = "white" と表示されます。
   el.children[0].style.display = "インライン";
   // 開いている地雷の数を決定します clearMineNum++;
   // 勝利関数 judgeVictory()
 
   } そうでない場合 (mineNum == "9") {
   // 勝利タイマーをクリアします clearInterval(stopTime);
   // li はクラス名を追加します el.classList.add("boom");
   警告("あなたは本当に最低な人だ!")
   gg = 真;
   // すべての地雷を表示し、すべてのliを取得する
   var all = document.querySelectorAll(".col");
   // すべての地雷を配置します var ff = [];
   var allnum = 0;
   // すべてのliをトラバース
   (var i = 0; i < all.length; i++) の場合 {
    (すべての[i].children[0].innerHTML == "9"の場合){
    // Leiは配列に値を割り当てます ff[allnum] = all[i];
    すべてnum++;
    }
   }
   // 地雷を一つずつ開くためのタイマーを設定します。allnum = 0;
   var stop = setInterval(function() {
    ff[allnum].classList.add("ブーム")
    すべてnum++;
    // 終了条件を決定する if (allnum == ff.length) {
    // タイマーをクリアします clearInterval(stop);
    }
   }, 30)
 
   }
  }
  // 右クリックして地雷をマークします element.oncontextmenu = function(event) {
  // 右クリックメニューイベントを防止します。preventDefault();
  // 現在クリックされているノードを取得します。var el = event.target;
  // (el.parentNode.nodeName == "LI") かどうかを判定します。
   el = el.parentNode;
  }
  if (el.nodeName != "LI") {
   戻る;
  }
  // 画像を取得
  var classList = el.children[1].classList;
  // 残りの鉱山番号 var residual = document.querySelector(".residue");
  var mineNum = parseInt(residue.innerHTML);
  // フラグがなく、クリックされていない場合は、フラグを挿入できます if (classList.contains("hide") && el.style.background != "white") {
   // 非表示を削除します classList.remove("hide");
   // 地雷番号を取得します mineNum--;
  } そうでない場合 (el.style.background != "white") {
   classList.add("非表示");
   // 地雷の数を決定する if (mineNum < num) {
   鉱山番号++;
   }
  }
  // 残りの地雷番号 residual.innerHTML = mineNum;
  }
 }
 }
 
 関数 judgeVictory() {
 //ゲーム勝利 if (clearMineNum === (row * col - num)) {
  // 小さなアニメーションを作成しますvar all = document.querySelectorAll(".col");
  var allNum = 0;
  var stop = setInterval(function() {
  var r = Math.floor(Math.random() * 256)
  var g = Math.floor(Math.random() * 256)
  var b = Math.floor(Math.random() * 256)
  all[allNum].style.background = "rgba(" + r + "," + g + "," + b + ",0.6)";
  //フラグとスパンの両方を非表示にする all[allNum].children[0].style.display = "none"
  all[allNum].children[1].style.display = "なし"
  すべて数++
  (allNum === all.length)の場合{
   クリア間隔(停止)
   もし (!gg) {
   アラート("頑張って、今夜はチキンを食べましょう")
   init(行、列、数値)
   }
  }
  }, 20)
 }
 }
 //スペースを自動的に開く function showNoMine(x, y) {
 (var i = -1; i <= 1; i++) の場合 {
  (x + i >= 0 && x + i < 行) の場合 {
  // 現在の行を取得します var rowElement = document.querySelectorAll(".row")[x + i];
  (var j = -1; j <= 1; j++) の場合 {
   (y + j >= 0 && y + j < 列)の場合{
   //現在のセルを取得します var el = rowElement.children[y + j]
    // グリッドを自動的に開くには、開いていない必要があります if (el.style.background != "white") {
    el.style.background = "白"
    el.children[0].style.display = "インライン"
    // 正方形の数 + 1 を開く
    クリアMineNum++
    //ゲームに勝ったかどうかを判定する judgeVictory(clearMineNum)
 
    if (el.children[0].innerText === "") {
    表示NoMine(x + i, y + j)
    }
   }
   }
  }
  }
  // (x + i >= 0 && x + i < 行) の場合 {
  // // 現在の行を取得します // var rowElement = document.querySelectorAll(".row")[x + i];
  // (var j = -1; j <= 1; j++ && y + j < col) の場合 {
  // // 現在のセルを取得します // var el = rowElement.children[y + j];
  // if (el.style.background !== "white") {
  // el.style.background = "白";
  // el.children[0].style.display = "インライン";
  // // 開いているグリッドの数が1増加します
  // clearMineNum++;
  // // ゲームに勝ったかどうかを判定します// judgeVictory(clearMineNum);
  // // 周囲のグリッドが空かどうかを判定する// if (el.children[0].innerHTML === "") {
  // showNoMine(x + i, y + j)
  // }
  // }
  // }
  // }
 }
 
 }
 //初期化メソッド var stopTime;
 
 関数 init(行, 列, 数値) {
 //データ初期化 clearMineNum = 0
 gg = 偽;
 // 元のマップをクリアして新しいマップを生成します var box = document.querySelector(".gameBox")
 ボックス内の要素
 var map = mineMap(行、列、数値);
 //新しいマップを作成します writeHtml(map);
 見せる()
  //地雷の数をHTMLに書き込む var residual = document.querySelector(".residue")
 残余.innerHTML = 数値
  // タイミングを取得します var tick = document.querySelector(".tick");
 var i = 0;
 // 初期化 tick.innerHTML = i;
 // タイミングをクリアする clearInterval(stopTime);
 // タイマー stopTime = setInterval(function() {
  tick.innerHTML = ++i
 }, 1000)
 }
 // リセット var restart = document.querySelector(".restart");
 restart.onclick = 関数(イベント) {
  //バブリングを停止する event.stopPropagation()
  init(行、列、数値)
 }
 // カスタム var level = document.querySelector(".level")
 level.onclick = 関数(イベント) {
 var el = イベント.ターゲット;
 スイッチ (el.innerHTML) {
  ケース「プライマリ」:
  行 = 9;
  列 = 9;
  数値 = 10;
  init(行、列、数値)
  壊す;
  ケース「中間」:
  行 = 16;
  列 = 16;
  数値 = 40;
  init(行、列、数値)
  壊す;
  ケース「詳細」:
  行 = 16;
  列 = 30;
  数値 = 479;
  init(行、列、数値)
  壊す;
  ケース「悪魔レベル」:
  行 = 40;
  列 = 50;
  数値 = 300;
  init(行、列、数値)
  壊す;
  ケース「カスタム」:
  row = prompt("列数を入力してください!");
  col = prompt("行数を入力してください!");
  num = prompt("必要な地雷の数を入力してください。(慎重に選択してください)");
  init(行、列、数値);
  壊す;
  デフォルト:
  行 = 9;
  列 = 9;
  数値 = 10;
  init(行、列、数値)
  壊す;
 }
 }
 init(行、列、数値)
}

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • JavaScript ベースのシンプルなマインスイーパ ゲームの実装
  • js+ca​​nvas はシンプルなマインスイーパゲームを実装します
  • JavaScript を使用したマインスイーパ ゲームのコード例の実装
  • マインスイーパーゲームを実装するためのHTML+JavaScript
  • 古典的なゲーム「マインスイーパ」の JavaScript 版の完全な例 [デモ ソース コードのダウンロード付き]
  • JS で作成したマインスイーパ ゲームを共有します
  • 純粋なJavaScriptを使用して古典的なマインスイーパゲームを実装する
  • JavaScript で Windows の定番マインスイーパ ゲームを実現
  • JavaScript マインスイーパ ゲーム
  • jsは古典的なマインスイーパゲームを実装します

<<:  シェルスクリプトはNginxのaccess.logのPVを定期的にカウントし、APIに送信してデータベースに保存します。

>>:  64 ビット CentOs7 ソース コードのインストール mysql-5.6.35 プロセス共有

推薦する

反応ルーティングでパラメータを渡すいくつかの方法についての簡単な説明

最初のパラメータ渡し方法は、動的ルーティングパラメータ渡しです。リンクのパス属性を設定することで、ル...

MySQLでクエリキャッシュを実行する方法と失敗を解決する方法

関数を使用する前にパラメータのプロパティを理解して、関数の使い方をより深く理解する必要があることは誰...

Vue プロジェクトのパッケージ化、マージ、圧縮により、Web ページの応答速度を最適化します。

目次序文1. リクエスト内容が大きすぎる解決: CDN の紹介リクエストリソースを圧縮する1. HT...

Vue ミックスインの使い方の詳しい説明

目次Vue ミックスインの使用ミックスインでのデータアクセスミックスイン/index.jsホーム.v...

Linux のバックグラウンドで & と nohup を使用する方法

ターミナルやコンソールで作業しているときは、メールを読むなど、もっと重要な作業があるかもしれないので...

正の整数かどうかを判断するMYSQLカスタム関数の例コード

関数を記述できます。主に正規表現を使用して判断を行います。入力文字が空の場合は、「-」を使用して置き...

要素フォーム検証で検証プロンプトをクリアする方法

目次問題のシナリオ:解決: 1. フィールドを個別にチェックする2. フォームフィールドの下のフィー...

CSS フロートプロパティ図 フロートプロパティの詳細

CSS の float プロパティを正しく使用することは、カバーすべき内容が多く、ブラウザの互換性の...

Docker プライマリ ネットワーク ポート マッピング構成

ポートマッピングDocker コンテナを起動する前にポート マッピングを行わないと、コンテナ外部のネ...

js キャンバスは検証コードを実装し、検証コード機能を取得します

この記事の例では、検証コードを作成して取得するためのjsキャンバスの具体的なコードを共有しています。...

新しいウィンドウで開くジャンプメニュー、window.open の使い方の紹介

コードをコピーコードは次のとおりです。 <前> <div> <sele...

Nginx は高可用性クラスタ構築を実装します (Keepalived+Haproxy+Nginx)

1. コンポーネントと実装機能Keepalived: Haproxy サービスの高可用性を実現し、...

Dockerを使用してSpringBootプロジェクトをデプロイする方法

Docker テクノロジの開発により、マイクロサービスの実装にさらに便利な環境が提供されます。Doc...

Vueでキャッシュされたページを管理する方法

目次問題1: 破壊1. 破壊する方法2. いつ破壊するか2.1 解決策1: route.queryを...

Zabbix 監視ソリューション - 最新の公式バージョン 4.4 [推奨]

ザビックス2019/10/12 チェンシン参照するhttps://www.zabbix.com/do...