もぐらたたきは、穴からランダムに顔を出すもぐらを素早くたたくアクションゲームです。ランダムなタイミングでの出現制御、クリック/タップの判定処理、カウントダウンタイマーの管理など、リアルタイムゲームの基本がまとまって学べる初心者にぴったりのゲームです。
もぐらたたきは、DOM要素で3x3の穴を作ります。各穴の中にもぐらの要素を配置し、CSSアニメーションでもぐらが出たり引っ込んだりする演出をつけましょう。まずはゲームの定数と状態変数を用意します。
var GAME_DURATION = 30; // ゲーム時間(秒)
var SCORE_PER_HIT = 10; // 1回のヒットで得るスコア
var INITIAL_MOLE_INTERVAL = 1200; // もぐらの出現間隔(ミリ秒)
var MIN_MOLE_INTERVAL = 500; // 出現間隔の最小値
var INITIAL_MOLE_DURATION = 1000; // もぐらがいる時間(ミリ秒)
var MIN_MOLE_DURATION = 450; // もぐら表示時間の最小値
var HOLE_COUNT = 9; // 穴の数(3x3)
var score = 0;
var timeLeft = GAME_DURATION;
var gameRunning = false;
var activeMoles = {}; // 現在出ているもぐらの管理
var lastMoleIndex = -1; // 直前に出たもぐらの穴番号
activeMolesオブジェクトで、どの穴にもぐらが出ているかを管理します。lastMoleIndexで前回と同じ穴に連続して出るのを防ぎます。
もぐらが出る穴をランダムに選びますが、既にもぐらが出ている穴や、直前に出た穴を避けることで、自然な出現パターンになります。時間の経過とともに出現間隔を短くして、難易度を上げましょう。
// ランダムな穴を選ぶ(前回と同じ穴を避ける)
function getRandomHoleIndex() {
var available = [];
for (var i = 0; i < HOLE_COUNT; i++) {
if (!activeMoles[i] && i !== lastMoleIndex) {
available.push(i);
}
}
if (available.length === 0) return -1;
return available[Math.floor(Math.random() * available.length)];
}
// 難易度に応じた出現間隔を計算
function getMoleInterval() {
var elapsed = GAME_DURATION - timeLeft;
var progress = elapsed / GAME_DURATION;
var interval = INITIAL_MOLE_INTERVAL
- (INITIAL_MOLE_INTERVAL - MIN_MOLE_INTERVAL) * progress;
return Math.max(interval, MIN_MOLE_INTERVAL);
}
progressは0から1に変化する値で、ゲームの経過割合を表します。時間が進むほどintervalが小さくなり、もぐらの出現が速くなります。
function showMole(index) {
if (index < 0 || activeMoles[index]) return;
var mole = moles[index];
mole.classList.add('active');
lastMoleIndex = index;
// 一定時間後にもぐらを引っ込める
var duration = getMoleDuration();
activeMoles[index] = setTimeout(function () {
hideMole(index);
}, duration);
}
function scheduleMole() {
if (!gameRunning) return;
var index = getRandomHoleIndex();
if (index >= 0) showMole(index);
// 次のもぐらをスケジュール
var interval = getMoleInterval();
moleSpawnTimer = setTimeout(scheduleMole, interval);
}
setTimeoutを使って、もぐらが自動的に引っ込む処理と、次のもぐらの出現を連鎖的にスケジュールします。scheduleMoleが自分自身を再スケジュールすることで、ゲーム中ずっともぐらが出続けます。
穴をクリック(またはタップ)したとき、そこにもぐらが出ていればヒットとしてスコアを加算します。既にたたかれたもぐらを二重にカウントしないよう、whackedクラスでガードしましょう。
function whackMole(index) {
if (!gameRunning) return;
if (!activeMoles[index]) return; // もぐらが出ていない
var mole = moles[index];
if (mole.classList.contains('whacked')) return; // 既にたたかれた
// たたくエフェクト
mole.classList.add('whacked');
// スコア加算
score += SCORE_PER_HIT;
updateScore();
// 少し遅延してから引っ込める
clearTimeout(activeMoles[index]);
activeMoles[index] = setTimeout(function () {
hideMole(index);
}, 300);
}
// 各穴にクリック・タッチイベントを設定
for (var i = 0; i < holes.length; i++) {
(function (index) {
holes[index].addEventListener('click', function (e) {
e.preventDefault();
whackMole(index);
});
holes[index].addEventListener('touchstart', function (e) {
e.preventDefault();
whackMole(index);
}, { passive: false });
})(i);
}
クロージャ(即時関数)を使って、ループ変数iの値を各イベントハンドラにキャプチャしています。touchstartイベントも追加することで、スマートフォンでも快適に遊べます。
このチュートリアルでは、ランダムな出現制御、クリック判定とスコア管理、動的な難易度変化の仕組みを学びました。さらに発展させるなら、特別なもぐら(たたくとボーナスや減点)、コンボシステム(連続ヒットでボーナス)、もぐらの出現アニメーション強化、難易度選択モードなどを追加してみましょう。
A: はい、大丈夫です。このチュートリアルではステップごとにコードを書いていくので、初めての方でも順番に進めれば完成できます。わからないところがあれば、ひなテックの教室で質問もできますよ。
A: 基本部分は約30分〜1時間で作れます。見た目をこだわったり機能を追加すると、さらに楽しく発展させられます。