Newer
Older
2024-C1232021_kanata / game3.js
// 配列をランダムに並び替える関数
function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

// Leaflet地図の初期化
const map = L.map('map').setView([35.681236, 139.767125], 16);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

let playerMarker; // プレイヤーの現在地マーカー
let activeArea = null; // 現在のアクティブなエリア
const puzzleAreas = []; // パズルエリア
let currentQuestionIndex = 0; // 現在のクイズインデックス
let shuffledQuizData = []; // シャッフルされたクイズデータ

// クイズデータ
const quizData = [
  { location: [35.681236, 139.767125], question: "日本の首都は?", options: ["大阪", "東京", "京都"], answer: "東京" },
  { location: [35.683236, 139.769125], question: "桜の季節はいつ?", options: ["春", "夏", "冬"], answer: "春" },
  { location: [35.685236, 139.771125], question: "日本の通貨単位は?", options: ["ドル", "円", "ユーロ"], answer: "円" },
  { location: [35.687236, 139.773125], question: "日本の国旗は何色?", options: ["赤と白", "青と白", "緑と白"], answer: "赤と白" },
  { location: [35.689236, 139.775125], question: "富士山の高さは約何メートル?", options: ["3776", "2000", "4500"], answer: "3776" },
];

// 距離を計算
function calculateDistance(lat1, lng1, lat2, lng2) {
  const R = 6371000;
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLng = (lng2 - lng1) * Math.PI / 180;
  const a = Math.sin(dLat / 2) ** 2 +
            Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
            Math.sin(dLng / 2) ** 2;
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return R * c;
}

// プレイヤーの初期位置
function initializePlayer() {
  playerMarker = L.marker(shuffledQuizData[0].location, { draggable: true }).addTo(map).bindPopup('現在地');
  map.setView(shuffledQuizData[0].location, 16);

  playerMarker.on('dragend', () => {
    const position = playerMarker.getLatLng();
    checkProximity(position.lat, position.lng);
  });
}

// パズルエリアを初期化
function initializePuzzleAreas() {
  shuffledQuizData.forEach(data => {
    const area = L.circle(data.location, { radius: 100, color: 'blue', fillOpacity: 0.2 }).addTo(map);
    puzzleAreas.push(area);
  });
}

// 距離チェック
function checkProximity(lat, lng) {
  const activeQuiz = shuffledQuizData[currentQuestionIndex];
  const distance = calculateDistance(lat, lng, activeQuiz.location[0], activeQuiz.location[1]);
  document.getElementById('distance').innerText = Math.round(distance);

  if (distance < 100 && activeArea !== activeQuiz) {
    activeArea = activeQuiz;
    showQuizModal(activeQuiz);
  }
}

// クイズモーダルを表示
function showQuizModal(quiz) {
  const modal = document.getElementById('quizModal');
  modal.style.display = 'block';
  document.getElementById('quizQuestion').innerText = quiz.question;

  const optionsContainer = document.getElementById('quizOptions');
  optionsContainer.innerHTML = '';
  quiz.options.forEach(option => {
    const input = document.createElement('input');
    input.type = 'radio';
    input.name = 'quizOption';
    input.value = option;
    input.id = option;

    const label = document.createElement('label');
    label.htmlFor = option;
    label.innerText = option;

    const div = document.createElement('div');
    div.appendChild(input);
    div.appendChild(label);
    optionsContainer.appendChild(div);
  });

  document.getElementById('quizMessage').innerText = '';
}

// 回答をチェック
function checkAnswer() {
  const selectedOption = document.querySelector('input[name="quizOption"]:checked');
  if (!selectedOption) {
    document.getElementById('quizMessage').innerText = '回答を選択してください。';
    return;
  }

  const activeQuiz = shuffledQuizData[currentQuestionIndex];
  if (selectedOption.value === activeQuiz.answer) {
    alert('正解です!次のエリアに進んでください。');
    currentQuestionIndex++;
    if (currentQuestionIndex >= shuffledQuizData.length) {
      alert('ゲームクリア!すべての問題に正解しました!');
      resetGame();
    }
    document.getElementById('quizModal').style.display = 'none';
  } else {
    alert('不正解です。もう一度挑戦してください!');
    activeArea = null; // 不正解時にエリアをリセット
    document.getElementById('quizModal').style.display = 'none';
  }
}

// ゲーム開始
function startGame() {
  shuffledQuizData = shuffleArray([...quizData]);
  currentQuestionIndex = 0;
  activeArea = null;
  initializePlayer();
  initializePuzzleAreas();
}

// リセット
function resetGame() {
  map.eachLayer(layer => {
    if (layer instanceof L.Marker || layer instanceof L.Circle) {
      map.removeLayer(layer);
    }
  });
  startGame();
}

// イベントリスナー
document.getElementById('startGame').addEventListener('click', startGame);
document.getElementById('resetGame').addEventListener('click', resetGame);
document.getElementById('submitAnswer').addEventListener('click', checkAnswer);