てけとーぶろぐ。

ソフトウェアの開発と、お絵かきと、雑記と。

AndroidでWebアプリを作る

作成するゲーム

プログラムの詳細には触れないのでファイルを書き換えるだけの単純作業になってしまうかもしれませんが一応ゲームアプリっぽく仕上げてみましょう。

名付けて「10秒で何回タップできるかゲーム」です。

おおよそ察しがついたかと思いますがプレイ画面と一緒にゲームの流れを説明します。

  • WebアプリのURLにアクセスすると「Tap To Start」と表示されます。

  • 画面をタップすると「Ready...」と表示され…

  • ゲーム開始です。「Time」のカウントダウンがはじまります。 ひたすら画面をタップするとスコアがあがっていきます。

  • 「Time」が0になったら終了です。

  • すこしすると「Time」の表示が消えます。 ここで画面をタップするとはじめの画面に戻ります。

画面遷移を整理するとこんなですね。

HTMLファイル

それでは作っていきましょう。 このゲームのWebアプリも既に用意した「index.html」「style.css」「script.js」の3ファイルで構成されています。

まずは「index.html」を以下の内容にします。

<!DOCTYPE html>
<html lang="ja" ontouchstart="handleTouch()">

<head>
    <meta charset="utf-8">
    <meta name="viewport"
        content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <title>Rapid Fire Game</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
</head>

<body>
    <div id="message"></div>
    <div id="remaining-time">Time: <span id="remaining-time-value"></span></div>
    <div id="score">Score: <span id="score-value"></span></div>
    <div id="high-score">High Score: <span id="high-score-value"></span></div>
</body>

</html>

以下のURLからコピーできます。

https://github.com/kurima-yoshida/web-dev-on-android/blob/main/rapid-fire-game/index.html

「メッセージ」「残り時間」「スコア」「ハイスコア」それぞれのために要素を用意してIDを振っています。

CSSファイル

次に「style.css」を以下の内容にします。 これは前の状態から変更なしです。

html {
    height: 100%;
}

body {
    background-color: #00bfff;
    color: white;
    font-size: 40px;
    margin: 0;
    height: 100%;
    user-select: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

以下のURLからコピーできます。

https://github.com/kurima-yoshida/web-dev-on-android/blob/main/rapid-fire-game/style.css

JSファイル

最後に「script.js」を以下の内容にします。

var gameState = 'title';
var elapsedSeconds = 0;
var gameTimer = null;
var touchNumber = 0;
var highScoreTouchNumber = 0;

function handleTouch() {
    if (gameState === 'title') {
        gameState = 'beforeGame'
        elapsedSeconds = 0;
        gameTimer = setInterval(handleTimer, 1000);
        touchNumber = 0;
    } else if (gameState === 'game') {
        touchNumber++;
        if (touchNumber > highScoreTouchNumber) {
            highScoreTouchNumber = touchNumber;
        }
    } else if (gameState === 'result') {
        gameState = 'title'
    }
    updateScreen();
}

function handleTimer() {
    elapsedSeconds++;
    if (elapsedSeconds === 1) {
        gameState = 'game';
    } else if (elapsedSeconds === 1 + 10) {
        gameState = 'afterGame';
    } else if (elapsedSeconds === 1 + 10 + 3) {
        gameState = 'result';
        clearInterval(gameTimer);
        gameTimer = null;
    }
    updateScreen();
}

function updateScreen() {
    if (gameState === 'title') {
        document.getElementById('message').style.display = 'block';
        document.getElementById('remaining-time').style.display = 'none';    
        document.getElementById('score').style.display = 'none';    
        document.getElementById('high-score').style.display = 'none';    
        document.getElementById('message').innerText = 'Tap To Start';
    } else if (gameState === 'beforeGame') {
        document.getElementById('message').innerText = 'Ready...';    
    } else if (gameState === 'game') {
        document.getElementById('message').style.display = 'none';
        document.getElementById('remaining-time').style.display = 'block';    
        document.getElementById('score').style.display = 'block';    
        document.getElementById('high-score').style.display = 'block';    
        var remainingTime = 1 + 10 - elapsedSeconds;
        document.getElementById('remaining-time-value').innerText = remainingTime;    
        document.getElementById('score-value').innerText = touchNumber;    
        document.getElementById('high-score-value').innerText = highScoreTouchNumber;    
    } else if (gameState === 'afterGame') {
        document.getElementById('remaining-time-value').innerText = 0;
    } else if (gameState === 'result') {
        document.getElementById('remaining-time').style.display = 'none';    
    }
}

setTimeout(updateScreen);

以下のURLからコピーできます。

https://github.com/kurima-yoshida/web-dev-on-android/blob/main/rapid-fire-game/script.js

ポイントだけ説明します。

  • touchstartイベントの処理を「handleTouch()」関数に、画面の更新処理を「updateScreen()」関数にまとめて、ゲームの状態を表す変数「gameState」の値に応じて実行する処理を切り替えています。
  • 1秒経過ごとに処理をするために「setInterval()」という命令を使っています。「setInterval(handleTimer, 1000)」とすると1000ミリ秒(=1秒)経過するごとに「handleTimer()」関数が呼び出されます。
動作確認

ファイルを更新したらWebサーバーを起動してうまく動くか確認してみましょう。

問題なければレンタルサーバーにアップロードしてそちらでも動くか確認してみましょう。