<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="ブラウザ上で遊べるかるた取りゲームです。"> <meta name="keywords" content="かるた, 小倉百人一首, ブラウザゲーム, かるた取り"> <title>国民年金かるた</title> <link rel="stylesheet" href="style.css"> <style> body { font-family: Arial, sans-serif; text-align: center; background-color: #f0f8e8; margin: 0; padding: 0; } h1 { margin-top: 20px; color: #333; } #menu, #game-area, #score-board, #result { margin: 20px auto; } #game-area, #score-board, #result, #countdown { display: none; } #countdown { font-size: 6em; font-weight: bold; color: red; margin-top: 50px; } #cards-container { position: relative; width: 100%; height: 500px; margin: 20px auto; } .card { position: absolute; width: 120px; height: 180px; background-color: #fff; border: 2px solid #ccc; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); cursor: pointer; display: flex; justify-content: center; align-items: center; transition: transform 0.3s ease; } .card img { width: 100%; height: 100%; } #text-line { font-size: 1.5em; margin: 20px auto; color: #555; } #score-board { margin-top: 20px; } #result { font-size: 2em; color: #333; } #overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 999; justify-content: center; align-items: center; } #overlay-content { background-color: #fff; padding: 20px; font-size: 3em; color: #333; } #expanded-card { display: none; position: fixed; z-index: 1000; width: 60%; max-width: 500px; height: auto; left: 50%; top: 50%; transform: translate(-50%, -50%); border: 5px solid #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.8); } #how-to-play { display: none; text-align: left; background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); width: 80%; margin: 20px auto; } #how-to-play h2 { margin-top: 0; } #how-to-play ul { list-style-type: disc; padding-left: 20px; } @media screen and (max-width: 768px) { #cards-container { position: relative; display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; justify-items: center; padding: 10px; height: auto; position: static !important; } .card { position: relative !important; width: 20vw; height: 22vw; } #expanded-card { width: 120vw; max-width: none; height: auto; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 5px solid #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.8); background-color: #fff; z-index: 1000; } #how-to-play { width: 95%; } #text-line { font-size: 1em; width: 95%; text-align: center; } } </style> </head> <body> <header> <h1>国民年金かるた</h1> </header> <div id="menu"> <button id="start-btn">ゲーム開始</button> <button id="how-to-play-btn">遊び方</button> </div> <div id="how-to-play"> <h2>遊び方</h2> <p>このゲームでは、ランダムに表示される読み上げ文字をもとに、正しいかるたカードを選んで取ります。</p> <ul> <li>ゲーム開始ボタンを押してゲームを始めます。</li> <li>カウントダウン後に「読み上げ文字」が表示されます。</li> <li>カードエリアにあるかるたの中から、読み上げに合ったカードをクリックしてください。</li> <li>正解すると得点が増え、次のカードに進みます。</li> <li>点数は以下の通り</li> <li>1.5秒以内:10点</li> <li> 3秒以内:5点</li> <li> 5秒以内:3点</li> <li> お手つき:-5点</li> <li>すべてのカードを取ったらゲーム終了です。</li> <li>※遊び方を閉じてから始めてください。</li> <button id="close-how-to-play">閉じる</button> </div> <div id="game-area"> <div id="text-line">ここに読み上げ文字が流れます</div> <div id="cards-container"> </div> </div> <div id="countdown"></div> <div id="score-board"> 得点: <span id="score">0</span> </div> <div id="result"> <p>ゲーム終了!</p> <p>最終得点: <span id="final-score">0</span></p> <button id="retry-btn">もう一度遊ぶ</button> </div> <div id="overlay"> <div id="overlay-content">カウントダウン中...</div> </div> <div id="expanded-card"> <img src="" alt="拡大されたカード" id="expanded-card-img"> </div> <footer> <p>東北公益文科大学 阿部公一ゼミ22期生 国民年金かるた</p> </footer> <script> let score = 0; let correctCard; let usedCards = []; let takenCards = 0; let incorrectCard = null; const startBtn = document.getElementById('start-btn'); const gameArea = document.getElementById('game-area'); const scoreBoard = document.getElementById('score-board'); const textLine = document.getElementById('text-line'); const resultScreen = document.getElementById('result'); const countdownElement = document.getElementById('countdown'); const cardsContainer = document.getElementById('cards-container'); const overlay = document.getElementById('overlay'); const overlayContent = document.getElementById('overlay-content'); const expandedCard = document.getElementById('expanded-card'); const expandedCardImg = document.getElementById('expanded-card-img'); const howToPlayBtn = document.getElementById('how-to-play-btn'); const howToPlaySection = document.getElementById('how-to-play'); const closeHowToPlayBtn = document.getElementById('close-how-to-play'); const cardImages = [ "image0.jpeg", "image1.jpeg", "image2.jpeg", "image3.jpeg", "image4.jpeg", "image5.jpeg", "image6.jpeg", "image7.jpeg", "image8.jpeg", "image9.jpeg" ]; const cardTexts = [ "年金は 未来の自分へ 贈り物", "国民年金 みんなのための 支え合い", "おめでとう 二十歳になれば 自動加入", "クレカでも 納付ができる 保険料", "保険料 猶予されます ガクトクで", "勘違い 老齢年金 だけじゃない", "怪我などで 障害残り 障害年金", "遺族年金 大切な人を 支援する", "受け取る額 繰り下げすれば 増やせます", "長生きで 給付がつづく一生涯" ]; let startTime; startBtn.addEventListener('click', () => { document.getElementById('menu').style.display = 'none'; gameArea.style.display = 'block'; scoreBoard.style.display = 'block'; countdownElement.style.display = 'block'; countdownElement.innerText = '3'; overlay.style.display = 'flex'; setTimeout(() => countdown(2), 1000); }); function countdown(number) { countdownElement.innerText = number; if (number > 0) { setTimeout(() => countdown(number - 1), 1000); } else { startGame(); countdownElement.style.display = 'none'; overlay.style.display = 'none'; } } function startGame() { let availableCards = []; for (let i = 0; i < 10; i++) { if (!usedCards.includes(i)) { availableCards.push(i); } } if (availableCards.length === 0) { gameOver(); return; } correctCard = availableCards[Math.floor(Math.random() * availableCards.length)]; usedCards.push(correctCard); textLine.innerText = cardTexts[correctCard]; startTime = Date.now(); } let canProceed = true; function takeCard(card) { if (!canProceed) return; const cardNumber = parseInt(card.dataset.card); const timeTaken = (Date.now() - startTime) / 1000; if (cardNumber === correctCard) { card.style.opacity = "0.5"; if (incorrectCard !== null) { score += 0; } else { if (timeTaken <= 1) { score += 10 } else if (timeTaken <= 3) { score += 5 } else if (timeTaken <= 5) { score += 3 } } takenCards++; expandedCardImg.src = cardImages[correctCard]; expandedCard.style.display = 'block'; setTimeout(() => { expandedCard.style.display = 'none'; canProceed = true; incorrectCard = null; document.getElementById('score').innerText = score; setTimeout(() => startGame(), 1000); }, 1300); } else { score -= 5; incorrectCard = cardNumber; } document.getElementById('score').innerText = score; } function gameOver() { gameArea.style.display = 'none'; scoreBoard.style.display = 'none'; resultScreen.style.display = 'block'; document.getElementById('final-score').innerText = score; } function randomizeCards() { const cardOrder = Array.from({length: 10}, (_, i) => i); shuffleArray(cardOrder); for (let i = 0; i < 10; i++) { const card = document.createElement('div'); card.classList.add('card'); card.dataset.card = cardOrder[i]; card.style.top = `${Math.floor(i / 5) * 250 + 50}px`; card.style.left = `${(i % 5) * 150 + 50}px`; card.innerHTML = `<img src="image${cardOrder[i]}.jpeg" alt="札${cardOrder[i] + 1}">`; card.addEventListener('click', () => takeCard(card)); cardsContainer.appendChild(card); } } function randomizeCards() { const cardOrder = Array.from({length: 10}, (_, i) => i); shuffleArray(cardOrder); const isMobile = window.innerWidth <= 768; for (let i = 0; i < 10; i++) { const card = document.createElement('div'); card.classList.add('card'); card.dataset.card = cardOrder[i]; if (isMobile) { } else { card.style.position = 'absolute'; card.style.top = `${Math.floor(i / 5) * 250 + 50}px`; card.style.left = `${(i % 5) * 150 + 50}px`; } card.innerHTML = `<img src="image${cardOrder[i]}.jpeg" alt="札${cardOrder[i] + 1}">`; card.addEventListener('click', () => takeCard(card)); cardsContainer.appendChild(card); } } 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; } randomizeCards(); howToPlayBtn.addEventListener('click', () => { howToPlaySection.style.display = 'block'; }); closeHowToPlayBtn.addEventListener('click', () => { howToPlaySection.style.display = 'none'; }); document.getElementById('retry-btn').addEventListener('click', () => { score = 0; usedCards = []; takenCards = 0; incorrectCard = null; document.getElementById('score').innerText = score; document.getElementById('final-score').innerText = ''; resultScreen.style.display = 'none'; gameArea.style.display = 'block'; scoreBoard.style.display = 'block'; cardsContainer.innerHTML = ''; randomizeCards(); startGame(); }); </script> </body> </html>