CSSHTMLJavaScript

【ゲーム開発】マインスイーパーを作成してみよう。さらに機能を追加し、ゲーム性を向上させよう。

2024.12.28 土
94 view
【ゲーム開発】マインスイーパーを作成してみよう。さらに機能を追加し、ゲーム性を向上させよう。

前回の記事はこちら

前回はマインスイーパーの基本的な動作部分を作成した。

基本的な機能自体は出来たが、とても楽しめるものではないだろう。

より楽しめるようにするために今回は追加機能について実装していく。

追加機能について

ここでは、タイマー機能と旗の数機能を実装していく。

タイマー機能はセルを開いたと同時にカウントアップするタイマーだ。

旗の数機能は残りの旗の数を見えるようにする機能だ。

この二つは無くても遊べるが、あった方がゲーム性は確実に向上するだろう。

追加機能の作成 -HTML-

まずはHTMLを使い、マインスイーパーの追加機能を作成していく。

ファイル名 index.html に追記する。

タイマー機能と旗の数機能の追加

タイマーの秒数と旗の個数を表示する要素を配置する。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>マインスイーパー</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="statusBar">
        <div id="timer">タイマー:0秒</div>
        <div id="remainingFlags">旗の数:0個</div>
    </div>
    <div id="gameBoard"></div>

    <script src="script.js"></script>
</body>
</html>

コードの解説

タイマーの表示用

<div id="timer">

初期値は「0秒」となっている。

残りの旗の数を表示

<div id="remainingFlags">

初期値は「0個」となっている。

追加機能の作成 -JavaScript-

次にJavaScriptを使い、マインスイーパーの追加機能を作成していく。

ファイル名 script.js に追記する。

タイマー機能の作成

タイマーの動作と表示の処理を行う。

let timer; // タイマーID
let timeElapsed = 0; // 経過時間(秒)
let isTimerRunning = false; // タイマーが動いているかの状態

// タイマー表示を更新する関数
function updateTimerDisplay() {
    const timerElement = document.getElementById('timer');
    timerElement.textContent = `タイマー:${timeElapsed}秒`;
}

// タイマーをスタートする関数
function startTimer() {
    if (isTimerRunning) return; // タイマーが既に動いている場合はスキップ
    isTimerRunning = true;

    timer = setInterval(() => {
        timeElapsed++;
        updateTimerDisplay();
    }, 1000); // 1秒ごとにカウントアップ
}

// タイマーをリセットする関数
function resetTimer() {
    clearInterval(timer);
    timeElapsed = 0;
    isTimerRunning = false;
    updateTimerDisplay();
}

// タイマーを停止する関数
function stopTimer() {
    clearInterval(timer);
    isTimerRunning = false;
}

// 地雷のセルをクリックしたとき
function gameOver() {
    alert("ゲームオーバー"); // ゲームオーバーのメッセージを表示
    stopTimer(); // タイマーを停止する
    revealAllMines(); // すべての地雷を公開
}

// 地雷以外のセルがすべて公開されたとき
function gameClear() {
    alert("ゲームクリア"); // ゲームクリアのメッセージを表示
    stopTimer(); // タイマーを停止する
    revealAllMines(); // すべての地雷を公開
}

// セルが左クリックされたとき
function handleCellLeftClick(e) {
    if (!isTimerRunning) {
        startTimer(); // 初回クリック時にタイマーを開始
    }

    ...以下省略
}

function handleCellRightClick(e) {
    if (!isTimerRunning) {
        startTimer(); // 初回クリック時にタイマーを開始
    }

    ...以下省略
}

// ゲームを初期化
function initGame() {
    resetTimer(); // タイマーをリセット
    remainingFlags = 10; // 旗の数を初期化

    ...以下省略
}

コードの解説

タイマー機能に使用する変数の定義

let timer; // タイマーID
let timeElapsed = 0; // 経過時間(秒)
let isTimerRunning = false; // タイマーが動いているかの状態

timer はタイマーを制御するための変数を宣言している。

timeElapsed はプレイヤーがゲームを開始してからどれだけの時間が経過したかを記録する。

let isTimerRunning はタイマーが現在動作しているかどうかを示すフラグだ。

タイマーの経過時間を画面に表示する機能

// タイマー表示を更新する関数
function updateTimerDisplay() {
    const timerElement = document.getElementById('timer');
    timerElement.textContent = `タイマー:${timeElapsed}秒`;
}

timerElement は取得した要素を格納する変数だ。

timerElement のテキストには タイマー:${timeElapsed}秒 という形式でテキストを更新し、タイマーを更新する。

タイマーを開始する機能

// タイマーをスタートする関数
function startTimer() {
    if (isTimerRunning) return; // タイマーが既に動いている場合はスキップ
    isTimerRunning = true;

    timer = setInterval(() => {
        timeElapsed++;
        updateTimerDisplay();
    }, 1000); // 1秒ごとにカウントアップ
}

isTimerRunning はタイマーが現在動作中かどうかを示すフラグ(真偽値)である。

これにより、タイマーが既に動作中のときに二重起動することを防ぐ。

setIntervalを使い指定した関数(コールバック)を一定間隔で実行する。

ここでは、1秒(1000ミリ秒)ごとに timeElapsed(経過時間)を1増加させ、updateTimerDisplay(画面上のタイマー表示)を更新する。

タイマーをリセットする機能

// タイマーをリセットする関数
function resetTimer() {
    clearInterval(timer);
    timeElapsed = 0;
    isTimerRunning = false;
    updateTimerDisplay();
}

clearInterval(timer) はタイマー(setIntervalで開始したもの)を停止するための関数だ。

これを実行すると、タイマーの繰り返し処理が終了する。

timeElapsed を0に設定することで、タイマーで記録されていた経過時間(秒単位)をリセットする。

isTimerRunning フラグをfalseに設定することで、次回startTimerを呼び出したときに新しいタイマーが開始されるようになる。

updateTimerDisplay はタイマー表示を更新するための関数であり、リセット後の経過時間(0秒)を画面上に表示する役割を担っている。

タイマーを停止する機能

// タイマーを停止する関数
function stopTimer() {
    clearInterval(timer);
    isTimerRunning = false;
}

clearInterval(timer) はタイマー(setIntervalで開始したもの)を停止するための関数だ。

これを実行すると、タイマーの繰り返し処理が終了する。

isTimerRunning フラグをfalseに設定することで、次回startTimerを呼び出したときに新しいタイマーが開始されるようになる。

旗の数機能の追加

旗の数の加減算と表示の処理を行う。

let remainingFlags = MINES; // 初期の旗の数

// 旗の数を表示する関数
function updateFlagDisplay() {
    const flagElement = document.getElementById('remainingFlags');
    flagElement.textContent = `旗の数:${remainingFlags}個`;
}

// セルが右クリックされたとき
function handleCellRightClick(e) {
    ...以下省略

    // フラグ数を表示に反映
    updateFlagDisplay();
}

function initGame() {
    updateFlagDisplay(); // フラグ数を表示に反映

    ...以下省略
}

コードの解説

旗の数機能に使用する変数の定義

let remainingFlags = MINES; // 初期の旗の数

remainingFlags はプレイヤーが使用可能なフラグ(旗)の数を追跡するし、 MINES(地雷の数)で、ゲーム開始時には地雷と同じ数だけフラグを使用可能とする。

残りの旗の数を表示する機能

// 旗の数を表示する関数
function updateFlagDisplay() {
    const flagElement = document.getElementById('remainingFlags');
    flagElement.textContent = `旗の数:${remainingFlags}個`;
}

flagElement は取得した要素を格納する変数だ。

flagElement のテキストには タイマー:${timeElapsed}秒 という形式でテキストを更新し、タイマーを更新する。

追加機能の作成 -CSS-

最後にCSSを使い、マインスイーパーのデザインを作成していく。

ファイル名 style.css に追記する。

タイマーと旗のスタイル

タイマーにスタイルを適用する。

#statusBar {
    display: inline-flex;
    align-items: center;
}

#timer,
#remainingFlags {
    font-size: 16px;
    padding: 0px 20px;
}

コードの解説

ステータスバー全体のスタイル

#statusBar {
    display: inline-flex;
    align-items: center;
}

ステータスバーのスタイルを適用する。

#statusBar

この要素には、タイマーや旗の残り数が含まれる。

display: inline-flex;

ステータスバーの要素を横並び(inline)で表示し、flexboxを使用して、子要素の配置やレイアウトを柔軟に制御できるようにする。

align-items: center;

子要素(タイマーや旗の数)が、縦方向(ステータスバー内の高さ)に中央揃えされるように設定する。

タイマーと旗の数の共通スタイル

#timer,
#remainingFlags {
    font-size: 16px;
    padding: 0px 20px;
}

タイマーと旗の数にスタイルを適用する。

#timer, #remainingFlags

IDがtimer(タイマー)とremainingFlags(旗の数)の要素に共通のスタイルを適用。

font-size: 16px;

テキストのフォントサイズを16pxに設定する。

padding: 0px 20px;

要素内の上下(0px)と左右(20px)の余白を設定する。

ソースコードのダウンロード

これらのコードはGithubにアップロードしている。

コードのダウンロードはこちら (github.com)

上記のページに、すべてアップロードされているので、必要な方はぜひ使ってみてくれ。

まとめ

いかがだっただろうか。

無事にマインスイーパーに機能の追加は出来ただろうか。

これでまともなマインスイーパーに仕上がったのではないだろうか。

これだけでなく、是非自分なりにもアレンジしてみてくれ。

コメントはこちらから

必須コメント

必須ハンドルネーム