このワークショップでは、HTML、CSS、JavaScriptを使い、タイピングゲームをテーマとしたWebアプリの開発を体験できます!
まずはインプットから始め、HTML、CSS、JavaScriptの基本を学び、その後、実際にタイピングゲームを作りながら、Webアプリの仕組みを理解していきます。
Webアプリとは、インターネットを通じて利用できるアプリケーションのことです。
ブラウザを使って動作するため、特別なインストールは必要ありません。
Webアプリにはどのようなものがあるでしょうか?普段使っているWebアプリを考えてみましょう。
HTMLは、Webページの「骨組み」を作るための言語です。
例えば、文字やボタン、画像など、画面に表示する要素を定義します。
HTMLでは<p>タグを使って、文章やメッセージを表示します。
以下のコードをbodyタグ内に追加すると、画面に「こんにちは!」と表示されます。
<p>こんにちは!</p>見出しを表示するには、<h1>から<h6>までのタグを使います。
<h1>見出し1</h1>
<h2>見出し2</h2>
<h3>見出し3</h3>タイピングゲームでは、ユーザーが文字を入力するためのテキストボックスが必要です。
HTMLでは<input>タグを使います。
<input type="text" />ゲームのリセットボタンなど、クリックして動作を実行するためのボタンを作れます。
<button>リセット</button>ゲームにアイコンや装飾を追加するときには、 <img>タグを使います。
<img src="path/to/image.jpg" alt="画像の説明" />上で学んだ内容をもとに、自己紹介ページを作ってみましょう!
例えば以下のような内容を表示するページを作ってみてください。
- 自己紹介のタイトルを表示する
- 名前、趣味、好きな食べ物などの情報を表示する
- 好きな画像を表示する
<h1>自己紹介</h1>
<p>名前: 〇〇</p>
<p>趣味: △△</p>
<p>好きな食べ物: □□</p>
<img src="path/to/image.jpg" alt="自分の写真" />CSSはWebページのデザインやレイアウトを整えるための言語です。
今回はTailwind CSSというCSSフレームワークを使います。
Tailwind CSSを使うと、あらかじめ用意されたクラス名をHTMLに追加するだけでデザインが適用されるので、とても便利です。
Tailwind CSSを利用するには、HTMLファイルの<head>部分に以下のスクリプトを追加します。
<script src="https://cdn.tailwindcss.com"></script>Tailwind CSSを読み込むと、見出しなどのデフォルトのスタイルがなくなります。
Tailwind CSSを使えば、テキストや背景、ボーダーに簡単に色をつけられます。
<p class="text-red-500">この文字は赤色です。</p>
<p class="text-blue-700">この文字は青色です。</p><div class="bg-green-200">背景が緑色です。</div>
<div class="bg-gray-900 text-white">ダークモード風の背景です。</div><div class="border-2 border-yellow-500">黄色の枠線があります。</div>文字のサイズやボックスの大きさもTailwind CSSで簡単に指定できます。
<p class="text-xl">少し大きな文字です。</p>
<p class="text-4xl">かなり大きな文字です。</p><p class="font-bold">太字の文字です。</p><div class="w-64 h-32 bg-blue-100">幅が64、高さが32のボックス</div>要素の配置を調整する方法を見ていきます。
テキストの揃え方は、text-left、text-center、text-rightを使って簡単に調整できます。
<p class="text-left">左揃え</p>
<p class="text-center">中央揃え</p>
<p class="text-right">右揃え</p>- マージン: 要素の外側の余白
- パディング: 要素の内側の余白
<div class="m-4 p-8 bg-gray-300">
外側に余白(マージン)が4、内側に余白(パディング)が8あります。
</div>要素を横並びに配置するには、親要素に flex クラスを使います。これにより、デフォルトで子要素が横方向に並ぶようになります。
<div class="flex justify-center items-center gap-4 bg-gray-100 p-8">
<div class="bg-blue-500 w-16 h-16"></div>
<div class="bg-red-500 w-8 h-8"></div>
<div class="bg-green-500 w-4 h-4"></div>
</div>flexで子要素が横並びにjustify-centerで水平方向に中央寄せitems-centerで水平方向に中央寄せgap-4で子要素間の間隔を4に
要素に影を追加して立体感を出せます。
<div class="shadow-md p-4 bg-white">このボックスには影があります。</div>角丸のボックスを作るには、roundedクラスを使います。
<div class="rounded bg-blue-500 w-16 h-16"></div>角丸の大きさを調整するには、rounded-[サイズ]クラスを使います。
<div class="rounded-lg bg-blue-500 w-16 h-16"></div>完全に丸いボックスを作るには、rounded-fullクラスを使います。
<div class="rounded-full bg-blue-500 w-16 h-16"></div><div class="opacity-50 bg-red-500">半透明のボックス</div>自己紹介ページにデザインを追加してみましょう!
例えば以下のようなデザインを追加してみてください。
- ページ全体の背景色を変える
- テキストの色を変える
- ボックスの大きさを変える
- テキストの配置を変える
<div class="bg-gray-100 p-8">
<h1 class="text-4xl text-center">自己紹介</h1>
<p class="text-lg text-center">名前: 〇〇</p>
<p class="text-lg text-center">趣味: △△</p>
<p class="text-lg text-center">好きな食べ物: □□</p>
<img src="path/to/image.jpg" alt="自分の写真" class="mx-auto mt-4 rounded-full" />
</div>JavaScriptは、Webページに「動き」を加えるためのプログラミング言語です。 例えば、ボタンを押したらメッセージが表示される、文字が変わる、などの仕組みを作ることができます。
JavaScriptは、ブラウザの中で動いています。特別なアプリをインストールしなくても、みなさんのパソコンやスマートフォンにあるブラウザ(ChromeやSafariなど)で動作します。
今回は、簡単なプログラムを使って、JavaScriptがどのように動いているかを体験してみましょう!
まずscript.jsというファイルを開き、以下のコードを追加します。
alert('Hello, World!');すると、ページをリロードすると、Hello, World!というメッセージが表示されます。
また、console.logを使うと、ブラウザの開発者ツールのコンソールにメッセージを表示することができます。
以下のコードを追加した後、F12キーを押して開発者ツールを開き、コンソールタブを確認してみましょう。
console.log('Hello, World!');変数を使うことで、データを保存しておくことができます。
変数は、letを使って宣言します。
// 文字列を保存する変数
let message = 'Hello, World!';
console.log(message);// 数値を保存する変数
let number = 123;
console.log(number);また、変数は後から値を変更することができます。
let message = 'Hello, World!';
console.log(message);
message = 'Goodbye, World!';
console.log(message);promptを使うと、ユーザーからの入力を受け取ることができます。
let name = prompt('名前を入力してください');
console.log(name);JavaScriptでは、四則演算をはじめ、様々な演算を行うことができます。
let number = 123;
console.log(number);
// 数値を1増やす
// number = number + 1; と同じ
// number++; と同じ
number += 1;
console.log(number);
// 数値を2倍にする
// number = number * 2; と同じ
number *= 2;
console.log(number);
// 数値を1減らす
// number = number - 1; と同じ
number -= 1;
console.log(number);
// 数値を半分にする
// number = number / 2; と同じ
number /= 2;
console.log(number);文字列に+演算子を使うと、文字列を連結することができます。
let message = 'Hello';
console.log(message);
message += ', World!';
console.log(message);バッククォート(`)を使うと、複数行の文字列を書くこともできます。
let message = `こんにちは!
今日はいい天気ですね。
`;
console.log(message);また、文字列の中に変数を埋め込むこともできます。
let name = '山田';
let message = `こんにちは、${name}さん!`;
console.log(message);この${}の中に変数を入れることで、変数の値を文字列に埋め込むことができます。
また、この中で演算を行うこともできます。
let price = 100;
let quantity = 3;
let message = `単価: ${price}円
数量: ${quantity}個
合計: ${price * quantity}円
`;
console.log(message);ページを開いたら、ユーザーに名前を入力してもらい、入力された名前を表示するプログラムを作ってみましょう。
例えば以下のようになると良いです。
- 入力された名前: 山田
- 表示されるメッセージ: こんにちは、山田さん!
解答例
let name = prompt('名前を入力してください');
let message = `こんにちは、${name}さん!`;
alert(message);条件分岐を使うことで、特定の条件に応じて処理を変えることができます。
let age = 20;
if (age >= 20) {
console.log('成人です');
} else {
console.log('未成年です');
}条件の判定には、以下の演算子(比較演算子)を使います。
===: 等しい!==: 等しくない>: より大きい<: より小さい>=: 以上<=: 以下
ageの値を変えて、表示されるメッセージが変わることを確認してみましょう。
文字列の比較を行うこともできます。
let password = 'password';
if (password === 'password') {
console.log('パスワードが一致しました');
} else {
console.log('パスワードが一致しません');
}ループ処理を使うことで、同じ処理を繰り返すことができます。
for (let i = 0; i < 5; i++) {
console.log(i);
}forの中身は、以下のようになっています。
let i = 0: 変数iを0で初期化i < 5:iが5未満の間、以下の処理を繰り返すi++: 処理が終わるたびにiを1増やす
配列を使うことで、複数のデータをまとめて扱うことができます。
let fruits = ['りんご', 'バナナ', 'みかん'];
console.log(fruits[0]); // りんご
console.log(fruits[1]); // バナナ
console.log(fruits[2]); // みかん配列の番号(インデックス)は、0から始まることに注意してください。
また、配列の要素数は、lengthプロパティで取得できます。
let fruits = ['りんご', 'バナナ', 'みかん'];
console.log(fruits.length); // 3これを使って、forループを使って配列の要素を順番に表示することができます。
let fruits = ['りんご', 'バナナ', 'みかん'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}ここでは、とてもシンプルなタイピングゲームを作ってみましょう。
ここに果物の一覧があります。
let fruits = ['apple', 'banana', 'orange', 'grape', 'melon'];これらの果物を順番に表示し、ユーザーに入力してもらい、正解かどうかを判定するプログラムを作ってみましょう。
例えば以下のようになると良いです。
- 表示される果物: apple
- ユーザーの入力: apple
- 正解の場合: 正解!
- 不正解の場合: 不正解・・・
- これを5回繰り返す
これは少し難しいですが、頑張ってみてください!
解答例
let fruits = ['apple', 'banana', 'orange', 'grape', 'melon'];
for (let i = 0; i < fruits.length; i++) {
let answer = prompt(fruits[i]);
if (answer === fruits[i]) {
alert('正解!');
} else {
alert('不正解・・・');
}
}もっと難しい問題に挑戦したい方は、正解数をカウントするプログラムに挑戦してみてください!
最後に
- 正解数
- 不正解数
- 正解率 (%)
を表示するようにしてみましょう。
解答例
let fruits = ['apple', 'banana', 'orange', 'grape', 'melon'];
let correct = 0;
for (let i = 0; i < fruits.length; i++) {
let answer = prompt(fruits[i]);
if (answer === fruits[i]) {
alert('正解!');
correct++;
} else {
alert('不正解・・・');
}
}
let output = `正解数: ${correct}
不正解数: ${fruits.length - correct}
正解率: ${correct / fruits.length * 100}%`;
alert(output);ここからは、JavaScriptとHTMLを連携させて、Webページに動きをつける方法を学びます。
HTMLに以下の要素があるとします。
<!-- index.html -->
<p id="example">こんにちは</p>この要素をJavaScriptで取得するには、document.getElementByIdを使います。
// script.js
let element = document.getElementById('example');
console.log(element);これは、exampleというIDを持つ要素を取得して、elementという変数に保存しています。
また、取得した要素のテキストを取得するには、innerTextプロパティを使います。
// script.js
let element = document.getElementById('example');
console.log(element.innerText);inputタグの入力欄の値を取得するにはinnerTextのかわりにvalueを使います。
<!-- index.html -->
<input id="input" type="text" />// script.js
let input = document.getElementById('input');
console.log(input.value);pタグなどの要素のテキストを変更するには、innerTextプロパティに新しい値を代入します。
// script.js
let element = document.getElementById('example');
element.innerText = 'こんばんは';このコードを実行すると、こんにちはというテキストがこんばんはに変わります。
inputタグの中身を変更する場合はvalueを使います。
// script.js
let input = document.getElementById('input');
input.value = 'こんにちは';要素のスタイルを変更するには、styleプロパティを使います。
// script.js
let element = document.getElementById('example');
let fontSize = 24;
element.style.fontSize = `${fontSize}px`;上のように、フォントサイズなどのスタイルを動的に変更することができます。
また、classListプロパティを使うと、CSSのクラスを追加・削除することができとても便利です。
<!-- index.html -->
<p id="example" class="hidden">こんにちは</p>// script.js
let element = document.getElementById('example');
element.classList.remove('hidden'); // hiddenクラスを削除して表示
element.classList.add('text-red-500', 'font-bold', 'text-2xl'); // 複数のクラスを追加イベントリスナーは、ユーザーの操作(クリック、キーボード入力など)に応じて動作するコードを指定する方法です。
JavaScriptでは、addEventListenerメソッドを使って、イベントリスナーを登録します。
以下のコードは、ボタンがクリックされたときにアラートを表示するプログラムです。
<!-- index.html -->
<button id="button" class="p-2 text-white font-bold bg-blue-500 rounded-md shadow-md">クリックしてください</button>// script.js
let button = document.getElementById('button');
button.addEventListener('click', () => {
alert('クリックされました');
});イベントリスナーでは、clickの他にも、mouseover(マウスが要素に乗ったとき)、keydown(キーボードが押されたとき)など、様々なイベントを指定することができます。
以下はkeydownイベントを使ったプログラムです。
<!-- index.html -->
<input id="input" type="text" class="p-2 border-2" />// script.js
let input = document.getElementById('input');
input.addEventListener('keydown', (e) => {
console.log(e.key);
if (e.key === 'Enter') {
alert('Enterが押されました');
}
});このようにe.keyを使うことで、押されたキーの情報を取得することができます。
HTMLとJavaScriptの両方を使って、タイピングゲームを少し進化させてみましょう!
まずは以下のコードを準備します。
<!-- index.html -->
<div class="text-center p-5">
<!-- 問題文 -->
<p id="question"></p>
<!-- 入力欄 -->
<input id="input" class="border-2 mt-3" />
</div>script.jsを編集して、以下の機能を追加してみましょう。
- 問題を表示する
- 入力された文字が正解かどうかを判定
- 正解の場合は
scoreを1増やす
- 正解の場合は
- 入力欄を空にする
- これを問題数分繰り返す
- 最後の問題まで終わったら、スコアをアラートで表示する
- 正解数
- 不正解数
- 正解率 (%)
かなり難易度が上がってきましたが、これまでのチェックポイントなどを参考にして挑戦してみてください!
詰まったら、まずはヒントを見てみてください。
ヒント
JavaScriptのテンプレートを用意しました!
// ここに処理を追加の部分を編集してください。
// script.js
let questions = ['apple', 'banana', 'orange', 'grape', 'melon'];
let input = document.getElementById('input'); // 入力欄
let questionLabel = document.getElementById('question'); // 問題文
let index = 0; // 問題の番号
let score = 0; // 正解数
questionLabel.innerText = questions[index]; // 1つ目の問題を表示
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
// ここに処理を追加
}
});解答例
// script.js
let questions = ['apple', 'banana', 'orange', 'grape', 'melon'];
let input = document.getElementById('input'); // 入力欄
let questionLabel = document.getElementById('question'); // 問題文
let index = 0; // 問題の番号
let score = 0; // 正解数
questionLabel.innerText = questions[index]; // 1つ目の問題を表示
input.addEventListener('keydown', (e) => {
// Enterが押されたとき
if (e.key === 'Enter') {
// 入力された文字が正解かどうか
if (input.value === questions[index]) {
score++; // 正解数を1増やす
}
input.value = ''; // 入力欄を空にする
index++; // 次の問題へ
// 問題が残っているかどうか
if (index < questions.length) {
questionLabel.innerText = questions[index]; // 次の問題を表示
} else {
let output = `正解数: ${score}
不正解数: ${questions.length - score}
正解率: ${(score / questions.length) * 100}%`;
alert(output); // スコアを表示
}
}
});