■解決したいこと
16マスのスライドパズルゲームを勉強で作っています。
body onloadで、パズルがランダムにシャッフルされるようにinit()関数内に書いています。
読み込み時、問題なくシャッフルされます。
しかし、設置したresetボタンに同じinit関数をonclickで呼び出せるようにし、呼び出すとなぜかパズルがシャッフルされません。
綺麗に1から15までの数字が順番に並んでしまいます。
リセット時もシャッフル機能を問題なく動作させたいです。
javascript
1<!DOCTYPE html> 2<html lang="ja" dir="ltr"> 3 <head> 4 <meta charset="utf-8"> 5 <title>16 puzzles</title> 6 <style> 7 .tile{ 8 width:100px; 9 height:100px; 10 border:1px solid #ccc; 11 border-radius:10px; 12 text-align:center; 13 font-size:36px; 14 background-color:white; 15 box-shadow:rgb(128, 128, 128) 5px 5px; 16 } 17 .over{ 18 pointer-events: none; 19 background-color: #ff0000; 20 color:#fff; 21 } 22 </style> 23 </head> 24 <body onload="init()"> 25 <div id="score">0</div> 26 <div id="timer"></div> 27 <table id="table"></table> 28 <div id="reset" onclick="init()">RESET</div> 29 <script> 30 "use strict" 31 32 var tiles = []; 33 34 var timer = document.getElementById("timer"); 35 var score = document.getElementById("score"); 36 var reset = document.getElementById("reset"); 37 var table = document.getElementById("table"); 38 var timeoutId; 39 var time = 180; 40 var min = 0; 41 var sec = 0; 42 var clickcount = 0; 43 44 45 function init(){ 46 table.innerHTML = ""; 47 48 timer.textContent = "03:00" 49 50 for(var i = 0; i < 4; i ++){ 51 var tr = document.createElement("tr"); 52 table.appendChild(tr); 53 for(var j = 0; j < 4; j ++){ 54 var td = document.createElement("td"); 55 var index = i * 4 + j; 56 td.className = "tile"; 57 td.value = index; 58 td.index = index; 59 td.textContent = index == 0 ? "" : index; //indexが0なら空でその他はその数字を代入 60 tiles.push(td); 61 tr.appendChild(td); 62 td.onclick = click; 63 } 64 } 65 for(var i = 0; i < 1000; i++){ 66 clickrandom({srcElement: {index: Math.floor(Math.random() * 16)}}) //e.srcElement.indexのように、srcElementプロパティのindexプロパティ 67 } 68 } 69 70 71 function countdown(){ 72 if(time > 0){ 73 var min = Math.floor(time/60); 74 var sec = time % 60; 75 time--; 76 console.log(time); 77 timeoutId = setTimeout(countdown, 1000); 78 timer.innerHTML = `${String(min).padStart(2, '0')}:${String(sec).padStart(2, '0')}`; 79 finish(); 80 }else{ 81 timer.innerHTML = "TIME UP!"; 82 scoredata(); 83 clearTimeout(timeoutId); 84 var tileElem = document.getElementsByClassName("tile") 85 Array.prototype.forEach.call(tileElem, function(element){ 86 element.classList.add("over"); 87 }); 88 } 89 } 90 91 var first = true;//startTimerの外でtrueにしないとダメ。中だと都度呼び出されてしまう。 92 function startTimer(){ 93 if(first){ 94 countdown(); 95 } 96 first = false; 97 } 98 99 function clickrandom(e){ 100 var i = e.srcElement.index; 101 102 if(i - 4 >= 0 && tiles[i - 4].value == 0){ //一番上の行ではなく、上にあるマスの値が0の時 103 swap(i, i - 4); 104 }else if(i + 4 < 16 && tiles[i + 4].value == 0){ //一番下の行ではなく、下にあるマスの値が0の時 105 swap(i, i + 4); 106 }else if(i % 4 != 0 && tiles[i - 1].value == 0){ //一番下の行ではなく、下にあるマスの値が0の時 107 swap(i, i - 1); 108 }else if(i % 4 != 3 && tiles[i + 1].value == 0){ //一番下の行ではなく、下にあるマスの値が0の時 109 swap(i, i + 1); 110 } 111 112 } 113 114 function click(e){ 115 var i = e.srcElement.index; 116 117 if(i - 4 >= 0 && tiles[i - 4].value == 0){ //一番上の行ではなく、上にあるマスの値が0の時 118 swap(i, i - 4); 119 startTimer(); 120 clickcount++; 121 }else if(i + 4 < 16 && tiles[i + 4].value == 0){ //一番下の行ではなく、下にあるマスの値が0の時 122 swap(i, i + 4); 123 startTimer(); 124 clickcount++; 125 }else if(i % 4 != 0 && tiles[i - 1].value == 0){ //一番下の行ではなく、下にあるマスの値が0の時 126 swap(i, i - 1); 127 startTimer(); 128 clickcount++; 129 }else if(i % 4 != 3 && tiles[i + 1].value == 0){ //一番下の行ではなく、下にあるマスの値が0の時 130 swap(i, i + 1); 131 startTimer(); 132 clickcount++; 133 } 134 } 135 136 function swap(i,j){ 137 var tmp = tiles[i].value; //先にiの値をtmpに代入 138 tiles[i].textContent = tiles[j].textContent; //iにjを代入 139 tiles[i].value = tiles[j].value; //iにjを代入 140 tiles[j].textContent = tmp; //jにiを代入 141 tiles[j].value = tmp; //jにiを代入 142 } 143 144 function scoredata(){ 145 var scoreCount = time * 100 + 200 - clickcount * 10; 146 score.textContent = scoreCount; 147 } 148 149 function finish(){//クリア判定 150 var clear = 0; 151 for(var i = 0; i < 16; i++){//16枚のタイルを判定 152 if(tiles[i].value == i){ 153 clear++//タイルの場所とその数字が同じ場合はポイント追加 154 } 155 } 156 console.log(clear); 157 if(clear == 16){//ポイントが16(つまり全部一致)になったらクリア! 158 clearTimeout(timeoutId); 159 timer.innerHTML = "FINISH!"; 160 scoredata(); 161 } 162 } 163 164 </script> 165 </body> 166</html> 167
ご教授よろしくお願いいたします。
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/19 14:10
2019/07/19 16:18
2019/07/23 07:52