こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
今回で、いよいよ最後の講義です。
<目次>
実装するもの
今回は、虫取りゲームを作成します。
demoは「こちら」で確認できます。
環境構築
簡単な環境構築をお願いします。
必要なファイルは、以下の通りです。
1 2 3 4 5 6 |
$ tree . ├── index.html ├── script.js └── style.css |
CSS版
ページ(HTML)の作成
最初にページを作成しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" /> <title>Catch The Insect</title> </head> <body> <div class="screen"> <h1>Catch The Insect</h1> <button class="btn" id="start-btn">Play Game</button> </div> <div class="screen"> <h1>What is your "favorite" insect?</h1> <ul class="insects-list"> <li> <button class="choose-insect-btn"> <p>Fly</p> <img src="http://pngimg.com/uploads/fly/fly_PNG3946.png" alt="fly"> </button> </li> <li> <button class="choose-insect-btn"> <p>Mosquito</p> <img src="http://pngimg.com/uploads/mosquito/mosquito_PNG18175.png" alt="mosquito" /> </button> </li> <li> <button class="choose-insect-btn"> <p>Spider</p> <img src="http://pngimg.com/uploads/spider/spider_PNG12.png" alt="spider" /> </button> </li> <li> <button class="choose-insect-btn"> <p>Roach</p> <img src="http://pngimg.com/uploads/roach/roach_PNG12163.png" alt="roach" /> </button> </li> </ul> </div> <div class="screen game-container" id="game-container"> <h3 id="time" class="time">Time: 00:00</h3> <h3 id="score" class="score">Score: 0</h3> <h5 id="message" class="message"> Are you annnoyed yet? <br> You are playing an impossible game!! </h5> </div> <script src="script.js"></script> </body> </html> |
このHTMLをブラウザ上で表示すると以下のようになります。

画像は、pingimg.comから取得しています。
スタイル(CSS)を装飾
次は、ページにスタイルをつけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
@import url('https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap'); * { box-sizing: border-box; } body { background-color: #516dff; color: #fff; font-family: 'Press Start 2P', sans-serif; height: 100vh; overflow: hidden; margin: 0; text-align: center; } a { color: #fff; } h1 { line-height: 1.4; } .btn { border: 0; background-color: #fff; color: #516dff; padding: 15px 20px; font-family: inherit; cursor: pointer; } .btn:hover { opacity: 0.9; } .btn:focus { outline: 0; } .screen { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; width: 100vw; transition: margin 0.5s ease-out; } .screen.up { margin-top: -100vh; } .insects-list { display: flex; flex-wrap: wrap; justify-content: center; list-style-type: none; padding: 0; } .insects-list li { margin: 10px; } .choose-insect-btn { background-color: transparent; border: 2px solid #fff; color: #fff; cursor: pointer; font-family: inherit; width: 150px; height: 150px; } .choose-insect-btn:hover { background-color: #fff; color: #516dff; } .choose-insect-btn:active { background-color: rgba(255, 255, 255, 0.7); } .choose-insect-btn img { width: 100px; height: 100px; object-fit: contain; } .game-container { position: relative; } .time, .score { position: absolute; top: 20px; } .time { left: 20px; } .score { right: 20px; } .message { line-height: 1.7; background-color: rgba(0, 0, 0, 0.5); width: 100%; padding: 20px; z-index: 100; text-align: center; opacity: 0; position: absolute; top: 0; left: 50%; transform: translate(-50%, -150%); transition: transform 0.4s ease-in; } .message.visible { transform: translate(-50%, 150%); opacity: 1; } .insect { cursor: pointer; display: flex; align-items: center; justify-content: center; width: 100px; height: 100px; position: absolute; transform: translate(-50%, -50%) scale(1); transition: transform 0.3s ease-in-out; } .insect.caught { transform: translate(-50%, -50%) scale(0); } .insect img { width: 100px; height: 100px; } |
ここまで実装すると以下のようになります。

JavaScriptの実装
要素を取得
最初に、画面操作に必要な要素を取得します。
1 2 3 4 5 6 7 8 |
// 要素の取得 const screens = document.querySelectorAll('.screen'); const choose_insect_btns = document.querySelectorAll('.choose-insect-btn'); const start_btn = document.getElementById('start-btn') const game_container = document.getElementById('game-container') const timeEl = document.getElementById('time') const scoreEl = document.getElementById('score') const message = document.getElementById('message') |
プロパティを定義
プログラム全体で使用するプロパティを定義します。
1 2 3 4 |
// プロパティ let seconds = 0 let score = 0 let selected_insect = {} |
Play Gameイベントの登録
Play Gameボタンを押下した時に、clickイベントを発火するようにします。
1 2 |
// Play Gameボタンにクリックイベントを登録 start_btn.addEventListener('click', () => screens[0].classList.add('up')) |
虫選択イベントの登録
虫選択時にclickイベントを発火するようにします。
1 2 3 4 5 6 |
// 虫のキャッチボタンにclickイベントを登録 choose_insect_btns.forEach(btn => { btn.addEventListener('click', () => { ... }) }) |
このイベントが発火したら、以下の処理を実行します。
- インセクト情報を取得
- 虫の増加処理を1秒後に停止
- ゲームの開始
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
choose_insect_btns.forEach(btn => { btn.addEventListener('click', () => { // HTMLからインセクト情報を取得 const img = btn.querySelector('img') const src = img.getAttribute('src') const alt = img.getAttribute('alt') // {src, alt}形式のオブジェクトにする selected_insect = { src, alt } // upクラスを付与 screens[1].classList.add('up') // 1秒後にcreateInsectを実行 setTimeout(createInsect, 1000) // これから実装 // ゲームを実行 startGame() // これから実装 }) }) |
虫作成処理
次は、虫を作成する処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 虫を増やす function createInsect() { // div要素を作成 const insect = document.createElement('div') // insectクラスを付与 insect.classList.add('insect') const { x, y } = getRandomLocation() // これから実装 // スタイルをつける insect.style.top = `${y}px` insect.style.left = `${x}px` insect.innerHTML = `<img src="${selected_insect.src}" alt="${selected_insect.alt}" style="transform: rotate(${Math.random() * 360}deg)" />` // 作成した要素がクリックされた時、catchInsectを実行 insect.addEventListener('click', catchInsect) // これから実装う // 子要素として追加 game_container.appendChild(insect) } |
虫の表示ポジション
次は、虫の表示ポジションを取得する処理を実装します。
1 2 3 4 5 6 7 8 |
// 虫を表示させる場所をランダムに取得 function getRandomLocation() { const width = window.innerWidth const height = window.innerHeight const x = Math.random() * (width - 200) + 100 const y = Math.random() * (height - 200) + 100 return { x, y } } |
虫をキャッチ
次は、虫を捕まえる処理を実装します。
1 2 3 4 5 6 7 |
// 虫を捕まえる function catchInsect() { increaseScore() this.classList.add('caught') setTimeout(() => this.remove(), 2000) addInsects() } |
画面上の虫は、CSSスタイルのcaughtクラスを付与すれば消すことができます。
スコア追加
虫を捕まえたらスコアを追加する処理を実装しましょう。
1 2 3 4 5 6 7 8 |
// スコアを追加 function increaseScore() { score++ if(score > 19) { message.classList.add('visible') } scoreEl.innerHTML = `Score: ${score}` } |
虫の追加
虫を捕まえたら画面上に新しい虫を追加します。
1 2 3 4 5 |
// 虫を追加 function addInsects() { setTimeout(createInsect, 1000) setTimeout(createInsect, 1500) } |
ゲーム開始処理
最後に、ゲーム開始処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function startGame() { // 1秒ごとにincreaseTimeを実行 setInterval(increaseTime, 1000) // これから実装する } // 時間を進める function increaseTime() { let m = Math.floor(seconds / 60) let s = seconds % 60 m = m < 10 ? `0${m}` : m s = s < 10 ? `0${s}` : s // 時間更新 timeEl.innerHTML = `Time: ${m}:${s}` seconds++ } |
これで完成です。
おわりに
本記事で「50 Projects In 50 Days – HTML, CSS & JavaScript」の講義は以上です。50日間の学習で、だいぶJavaScriptの実装に慣れたと思います。
次は、CSSを勉強したいですね^^
それでは、また!
JavaScriptまとめ
JavaScript ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
// 要素の取得 const screens = document.querySelectorAll('.screen'); const choose_insect_btns = document.querySelectorAll('.choose-insect-btn'); const start_btn = document.getElementById('start-btn') const game_container = document.getElementById('game-container') const timeEl = document.getElementById('time') const scoreEl = document.getElementById('score') const message = document.getElementById('message') // プロパティ let seconds = 0 let score = 0 let selected_insect = {} // Play Gameボタンにクリックイベントを登録 start_btn.addEventListener('click', () => screens[0].classList.add('up')) // 虫のキャッチボタンにclickイベントを登録 choose_insect_btns.forEach(btn => { btn.addEventListener('click', () => { // HTMLからインセクト情報を取得 const img = btn.querySelector('img') const src = img.getAttribute('src') const alt = img.getAttribute('alt') // {src, alt}形式のオブジェクトにする selected_insect = { src, alt } // upクラスを付与 screens[1].classList.add('up') // 1秒後にcreateInsectを実行 setTimeout(createInsect, 1000) // ゲームを実行 startGame() }) }) function startGame() { // 1秒ごとにincreaseTimeを実行 setInterval(increaseTime, 1000) } // 時間を進める function increaseTime() { let m = Math.floor(seconds / 60) let s = seconds % 60 m = m < 10 ? `0${m}` : m s = s < 10 ? `0${s}` : s // 時間更新 timeEl.innerHTML = `Time: ${m}:${s}` seconds++ } // 虫を増やす function createInsect() { // div要素を作成 const insect = document.createElement('div') // insectクラスを付与 insect.classList.add('insect') const { x, y } = getRandomLocation() // スタイルをつける insect.style.top = `${y}px` insect.style.left = `${x}px` insect.innerHTML = `<img src="${selected_insect.src}" alt="${selected_insect.alt}" style="transform: rotate(${Math.random() * 360}deg)" />` // 作成した要素がクリックされた時、catchInsectを実行 insect.addEventListener('click', catchInsect) // 子要素として追加 game_container.appendChild(insect) } // 虫を表示させる場所をランダムに取得 function getRandomLocation() { const width = window.innerWidth const height = window.innerHeight const x = Math.random() * (width - 200) + 100 const y = Math.random() * (height - 200) + 100 return { x, y } } // 虫を捕まえる function catchInsect() { increaseScore() this.classList.add('caught') setTimeout(() => this.remove(), 2000) addInsects() } // 虫を追加 function addInsects() { setTimeout(createInsect, 1000) setTimeout(createInsect, 1500) } // スコアを追加 function increaseScore() { score++ if(score > 19) { message.classList.add('visible') } scoreEl.innerHTML = `Score: ${score}` } |
コメントを残す
コメントを投稿するにはログインしてください。