関数を一定回数繰り返したい
JavaScript で作っているものがあります。プログラミングは始めて三ヶ月くらいなので自分で書いてわからないコードは極力書きたくないないと思ってます。jQuery(?)というものがあるようですがそれも使ってません。node.js もまだなのでライブラリも使える状況ではありません。自分初の作品として js のみで完結する簡単なじゃんけんゲームを作っています。
大体は書けたのですが、あと一息というとこで躓いています。
「最初はぐー」と表示する関数、「じゃんけんぽん」などのメインの処理をする関数があるのですが、一回目以降から「じゃんけんぽん」のところの serectedAndJudgment 関数を数回繰り返したいです。
for 文で回そうとしたらおそらく onclick のところで詰まってしまったのかと。onclick は任意なので js 側は待ってはくれず表示部分が先に何回も繰り返されてしまったのかと思います。下の「試したこと」にも書きました。
発生している問題・エラーメッセージ
特に出てはないです。
該当のソースコード
HTML
1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>後出しじゃんけんゲーム</title> 8 <link rel="stylesheet" href="copy.css"> 9</head> 10 11<body> 12 <h1 id="title">後出しじゃんけんゲーム!</h1> 13 <button id="start-button">スタート</button> 14 <h1 id="signal-text"></h1> 15 <div id="signal-image"></div> 16 <div id="judgment-area" class="judgment"></div> 17 <h2 id="score-area" class="score"></h2> 18 <div id="janken-area"></div> 19 <script src="copy.js"></script> 20</body> 21 22</html>
JavaScript
1'use strci'; 2const title = document.getElementById('title'); 3const startButton = document.getElementById('start-button'); 4const signalText = document.getElementById('signal-text'); 5const signalImage = document.getElementById('signal-image'); 6const judgmentArea = document.getElementById('judgment-area'); 7const scoreArea = document.getElementById('score-area'); 8const jankenArea = document.getElementById('janken-area'); 9 10// ぐー、ちょき、ぱーの画像 11const images = [ 12 './img/gu.png', // ぐーの画像 13 './img/pa.png', // ぱーの画像 14 './img/choki.png' // ちょきの画像 15]; 16 17// CPU 側のじゃんけん表示エリアを作成 18const opponentImage = document.createElement('img'); 19 20// 関数のトリガー 21startButton.onclick = () => { 22 23 title.remove(); 24 startButton.remove(); 25 //scoreArea.innerText = '0 勝'; 26 27 signal(); 28 serectedAndJudgment(); 29}; 30 31 32//「最初はぐーじゃんけん」の呼びかけの処理 33function signal() { 34 signalText.innerText = '最初はぐー'; 35 opponentImage.src = images[0]; // ぐーを固定化 36 opponentImage.width = "300"; 37 opponentImage.height = "300"; 38 signalImage.appendChild(opponentImage); 39}; 40 41 42// 「ぽん」の呼びかけと遊びの本体の処理 43function serectedAndJudgment() { 44 45 setTimeout(() => { 46 signalText.innerText = 'じゃんけん'; 47 }, 1500); 48 49 setTimeout(() => { 50 // 相手側の表示の処理 51 let imageNo = Math.floor(Math.random() * images.length); // 画像表示時の添え字をランダムで生成 52 signalText.innerText = 'ぽん'; 53 opponentImage.src = images[imageNo]; // 生成した添え字で画像を表示 54 signalImage.appendChild(opponentImage); 55 56 // 正解「〇」不正解「✕」の判定画像の表示エリアを作成 57 const judgment = document.createElement('img'); 58 judgment.width = "300"; 59 judgment.height = "300"; 60 judgmentArea.appendChild(judgment); 61 judgment.style.display = 'none'; 62 63 // 開始時の時刻をメモ 64 let startTime = Date.now(); 65 66 // じゃんけんメインエリアの作成 67 for (let i = 0; i < images.length; i++) { 68 let serect = document.createElement('input'); 69 jankenArea.appendChild(serect); 70 serect.type = "image"; 71 serect.src = images[i]; // iを添え字として画像を表示 72 serect.width = "300"; 73 serect.height = "300"; 74 serect.onclick = () => { 75 jankenArea.children[0].disabled = true; // ぐーを一回限りのボタンに 76 jankenArea.children[1].disabled = true; // ぱーを一回限りのボタンに 77 jankenArea.children[2].disabled = true; // ちょきを一回限りのボタンに 78 if ((Date.now() - startTime) > 1000) { // 2秒以内に押せないなら時間切れ 79 judgment.style.display = ''; 80 judgment.src = './img/time.png'; // 時間切れ 81 82 } else if (imageNo === i) { 83 judgment.style.display = ''; 84 judgment.src = './img/aiko.png'; // あいこ 85 // scoreArea.innerText = 86 } else if (imageNo === 0 && i === 1 || imageNo === 1 && i === 2 || imageNo === 2 && i === 0) { 87 judgment.style.display = ''; 88 judgment.src = './img/maru.png'; 89 //scoreArea.innerText = `${score} 勝`; // 勝ち 90 } else { 91 judgment.style.display = ''; 92 judgment.src = './img/batu.png'; 93 //scoreArea.innerText = '負け'; // 負け 94 } 95 signalText.innerText = "次!"; 96 removeAllChildren(jankenArea); 97 removeAllChildren(judgmentArea); 98 serectedAndJudgment(); 99 } 100 }; 101 }, 2500); 102}; 103 104 105/** 106 * 指定した要素の子どもを全て削除する 107 * @param {HTMLElement} element HTMLの要素 108 */ 109function removeAllChildren(element) { 110 setTimeout(() => { 111 while (element.firstChild) { 112 element.removeChild(element.firstChild); 113 } 114 }, 1000); 115}; 116
試したこと
最初に for 文内で serectedAndJudgment 関数を10 回程度回そうと思っていたのですが、調べたところ js は基本的には非同期だそうなので自分が思っていた通りには動きませんでした。表示部分の画像を三枚 input タグで作るところが 10 回先に繰り返されてしまいました。
Promise や await(?) なども調べてなんども挑戦しましたが自分ではどうしたらいいか…。
今回関係ない部分の詳細
画像を表示するのになんで input タグになっているのかは disabled を付けたかったからです。この辺もあまいところなのかなって思います。
スタートボタンを押したらゲームが開始されるようになっています。一番最初の signal 関数ですが、これは初めの一回しか出番がないの後ほどスタートボタンの処理の中に直接書こうかなって思ってます。
ご教授願います。
回答2件
あなたの回答
tips
プレビュー