【GASでWEBアプリ】HTML・CSS・JavaScriptで作る〇×ゲーム

がいの部屋

Google Apps Script(GAS)を活用して、HTML・CSS・JavaScriptで〇×ゲームを作成!

初心者でも手軽にGASを利用したWEBゲーム開発を簡単に始めることができるように、詳しいコードの解説を入れたサイトです。

初めに

GASを使ってHTML CSS JavaScriptでつくる〇×ゲームをご紹介します。

2人のプレイヤーが交互に”X”と”O”をマスに配置し、先に3つ並べたプレイヤーが勝者となります。

以下はゲームの特徴です。

  • 直感的なプレイ: プレイヤーはクリックするだけでマスに”X”または”O”を配置できます。
  • 美しいデザイン: シンプルで清潔なデザインが、ゲームプレイをより楽しくします。
  • 結果表示: 勝者が決まると、または引き分けの場合には結果が表示されます。

HTML CSS JavaScriptのファイルを準備

HTMLファイル、CSSファイル、JavaScriptファイルをそれぞれindex.html、style.html、java.htmlとして保存してください。

HTML、CSS、JavaScriptのコードはそれぞれ別のファイルに分割保存して、メインのHTMLファイルにインポートします。

詳しくは下記のサイトをご覧ください。

HTML サービス: ベスト プラクティス  |  Apps Script  |  Google for Developers

GASの作成

GASでは下記の4つのファイルを作成します。

コード.gs

function doGet() {
   return HtmlService.createTemplateFromFile('index').evaluate().addMetaTag('viewport', 'width=device-width, initial-scale=1');
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}
doGet()関数

WEBアプリがリクエストを受け取ったときに呼び出され、レスポンスとしてHTMLコンテンツを返します。GASのWEBアプリは、doGet() または doPost() 関数がエントリーポイントになります。

ユーザーがWEBアプリのURLにアクセスすると、この関数が実行され、テンプレートファイル(index.html)がレンダリングされてブラウザに返されます。

include()関数

他のHTMLファイルを読み込み、その内容を返す汎用関数です。主に、index.html 内で別のHTMLファイルをインクルード(埋め込み)する際に使用されます。

HtmlService.createHtmlOutputFromFile(filename)

  • 引数として渡された filename(例: 'header')に対応するHTMLファイルを読み込みます。
  • ファイル名には拡張子 .html を含める必要はありません。

.getContent()

  • 読み込んだHTMLの中身(文字列)を取得し、返します。
  • この関数をテンプレート内で呼び出すことで、動的に別のHTMLファイルを埋め込むことができます。
全体の流れ
  1. リクエストが来た場合
    ユーザーがWEBアプリのURLにアクセスすると、doGet() が実行されます。
  2. HTMLテンプレートの評価と返送
    • doGet() では index.html をテンプレートとして処理し、その結果をブラウザに返します。
    • 必要に応じて include() 関数を利用して、他のHTMLファイルを動的に挿入します。
  3. レスポンシブ対応
    • ビューポートメタタグを追加することで、スマートフォンやタブレットでの表示が最適化されます。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?!= include('style'); ?>
    <title>Tic Tac Toe</title>
</head>
<body>
    <div id="board" class="board">
        <div class="cell" onclick="handleClick(0)"></div>
        <div class="cell" onclick="handleClick(1)"></div>
        <div class="cell" onclick="handleClick(2)"></div>
        <div class="cell" onclick="handleClick(3)"></div>
        <div class="cell" onclick="handleClick(4)"></div>
        <div class="cell" onclick="handleClick(5)"></div>
        <div class="cell" onclick="handleClick(6)"></div>
        <div class="cell" onclick="handleClick(7)"></div>
        <div class="cell" onclick="handleClick(8)"></div>
    </div>
    <div id="result" class="result"></div>
    <?!= include('java') ?>
</body>
</html>

<!DOCTYPE html>: HTML5で書かれていることを示します。

<html lang="ja">: ページの言語を日本語(ja)として設定。

<meta charset="UTF-8">: 文字コードをUTF-8に設定し、日本語を含むすべての文字を正しく表示。

<meta name="viewport" content="width=device-width, initial-scale=1.0">: モバイルデバイスで適切に表示されるように設定。<title>: ページのタイトルを「シンプルなTic Tac Toeゲーム」と設定。

<div id="board" class="board">: ゲームボードを定義。

<div class="cell" onclick="handleClick(0)">: 各マス(セル)を定義。クリック時にhandleClick関数を呼び出す。

style.html

<style>
body {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
}

.board {
    display: grid;
    grid-template-columns: repeat(3, 100px);
    grid-gap: 5px;
}

.cell {
    width: 100px;
    height: 100px;
    background-color: #fff;
    border: 2px solid #ccc;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    font-weight: bold;
    cursor: pointer;
}

.cell:hover {
    background-color: #e0e0e0;
}

.result {
    margin-top: 20px;
    font-size: 36px; /* 大きな文字サイズ */
    font-weight: bold;
    color: #333;
    text-align: center; /* 中央揃え */
    position: absolute; /* 画面中央に配置 */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
</style>

display: flex;
Flexboxを使用して、要素を中央揃えにします。

align-itemsjustify-content
縦横中央に整列します。

background-color: #f0f0f0;
背景色を淡いグレーに設定。

display: grid;
グリッドレイアウトを使用して3×3のマスを配置。

grid-template-columns
3列(100px幅)を設定。

grid-gap
各セル間の間隔を5pxに設定。

セルのデザイン:
白背景、境界線、クリック時のポインター表示などを設定。

java.html

<script>
let currentPlayer = 'X';
let board = ['', '', '', '', '', '', '', '', ''];
let gameActive = true;

function handleClick(index) {
    if (gameActive && board[index] === '') {
        board[index] = currentPlayer;
        document.getElementsByClassName('cell')[index].innerText = currentPlayer;

        if (checkWinner()) {
            document.getElementById('result').innerText = `${currentPlayer} wins!`;
            gameActive = false;
            document.body.style.backgroundColor = "rgba(0, 0, 0, 0.8)"; /* 背景を暗く */
            document.getElementById('result').style.color = "#ff0000"; /* メッセージを赤に変更 */


        } else if (board.every(cell => cell !== '')) {
            document.getElementById('result').innerText = 'It\'s a draw!';
            gameActive = false;
        } else {
            currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
        }
    }
}

function checkWinner() {
    const winningCombos = [
        [0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows
        [0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns
        [0, 4, 8], [2, 4, 6]             // Diagonals
    ];

    return winningCombos.some(combo =>
        combo.every(index => board[index] === currentPlayer)
    );
}
</script>

currentPlayer: 現在のプレイヤーを管理する変数(最初はX)。

board: 各マスの状態を記録する配列(空文字''は未使用のマス)。

gameActive: ゲームが終了したかどうかを示すフラグ。

handleClick(index)
クリックされたセル(index)の処理を行う。

セルが未使用の場合、現在のプレイヤーを設定。勝敗判定をcheckWinner()で確認。全マスが埋まった場合は引き分けメッセージを表示。

checkWinner()
勝利条件を定義した配列winningCombosをチェック。

    いずれかの組み合わせ(行、列、斜め)が全て同じプレイヤーである場合に勝利と判定。

    デプロイ

    最後にデプロイして動作を確認してみましょう。

    プレイヤーがマスをクリックすると、handleClick関数が呼び出されます。

    セルが空であれば、現在のプレイヤーがそのセルを埋めます。

    勝利条件や引き分けをチェックし、結果を表示します。

    ターンが交代して次のプレイヤーが動きます。

    勝者または引き分けが確定した場合、ゲームが終了します。

    遊び方

    1. プレイヤー1は”X”で、プレイヤー2は”O”です。
    2. 交互に空いているマスをクリックして”X”または”O”を配置します。
    3. 先に横、縦、または斜めに3つ並べたプレイヤーが勝者となります。
    4. ゲームが引き分けになるか、どちらかが勝つと結果が表示されます。

    クリックすることでこのようになればうまく動作しています。

    タイトルとURLをコピーしました