どうも!LSSです!!
昨日の記事、
のコードの解説記事となります。
実はこっちを先に公開するつもりだったのが、途中行き詰ってしまって、つまづきの記録を2つ公開する事になった、発端の記事が今回の記事ですw
まずは、画面の構造を見てみます
現時点での、アーシさんの「●追い迷路」最新の出題は
↑こちらです。
迷路画面をよく見ると、まず「6×6の枠組み」があり、そのそれぞれの枠の中に「3×3で表現可能な枠組み」がありますね。
そしてその3×3の中央は、黒い線で囲まれた四角があり、「スタートを示すS」と「ゴールを示すG」が書かれている枠以外は使われておらず、その八方周囲に●があったりなかったりで、迷路を構成しています。
簡単なところから始めてみる
最終的には、「6×6のうちのどこに今自分がいるか」を何らかの形で表現して、●をクリックして違う枠に移動する、ってタイプのスクリプト化が考えられます。
が、まずは画面の描画から考えていきます。
いきなり全てを作ろうとせず、「作れて確認できそう」なところから手をつけていくのが良いと思います^^
という事で、最初のコードはこんな感じ。
<style><!--
.box{
display:-ms-grid;
display:grid;
-ms-grid-columns:(48px)[6];
grid-template-columns:repeat(6,48px);
-ms-grid-rows:(48px)[6];
grid-template-rows:repeat(6,48px);
}
.inbox{
border:1px solid black;
}
--></style>
<div id="gamen" class="box"> </div>
<script>
gamen.innerHTML='';
for(i=0;i<36;i++){
gamen.innerHTML+='<div class="inbox"></div>';
}
</script>
ちょっと長くなりますが解説はここをクリック
まず、
.box{
display:-ms-grid;
display:grid;
-ms-grid-columns:(48px)[6];
grid-template-columns:repeat(6,48px);
-ms-grid-rows:(48px)[6];
grid-template-rows:repeat(6,48px);
}
で、48pxのサイズのグリッドを6つ、columns(横)とrows(縦)に用意しています。
ちなみに、-ms-を含んでいる行はgridの実装がちょっと他と違うIEやEDGE用の記述で、それ以外のブラウザ用の記述は
display:grid;
grid-template-columns:repeat(6,48px);
grid-template-rows:repeat(6,48px);
です。
-ms-を含む行は、
display:-ms-grid;
-ms-grid-columns:(48px)[6];
-ms-grid-rows:(48px)[6];
となります。
リピートの書き方がだいぶ違うのが邪魔くさいwですが、これで縦横6つづつの枠組みができました。
.boxに対する指定なので、
<div id="gamen" class="box"> </div>
に対して有効となります。
この、「idはgamen、classはbox」なdiv要素に対して、JavaScriptから、
for(i=0;i<36;i++){
gamen.innerHTML+='<div class="inbox"></div>';
}
ループを回して36回、「classはinbox」なdivを書き込んでいます。
書き出されるHTMLは
<div id="gamen" class="box">
<div class="inbox"></div>
<div class="inbox"></div>
(中略)
<div class="inbox"></div>
<div class="inbox"></div>
</div>
って感じになります。
外側の「<div id="gamen" class="box">」なdiv要素に6×6のgridを指定しているので、中に書かれた36個の「<div class="inbox"></div>」は6×6に整列する事になります。
あとは、取り合えず確認できるようにinboxなdivに枠線(border)だけ
.inbox{
border:1px solid black;
}
と指定しました。
実行(プレビュー)してみると…
↑こんな風になります!
とりあえず「6×6の枠組み」はこれでOKですね^^
(サイズはスマホでも表示できるように小さめになっています)
6×6が上手くいったので、その中に入れる3×3も同様に指定
コードはこんな風に書きました
<style><!--
.box{
display:-ms-grid;
display:grid;
-ms-grid-columns:(48px)[6];
grid-template-columns:repeat(6,48px);
-ms-grid-rows:(48px)[6];
grid-template-rows:repeat(6,48px);
}
.inbox{
display:-ms-grid;
display:grid;
-ms-grid-columns:(16px)[3];
grid-template-columns:repeat(3,16px);
-ms-grid-rows:(16px)[3];
grid-template-rows:repeat(3,16px);
border:1px solid black;
}
--></style>
<div id="gamen" class="box"> </div>
<script>
txt='';
for(i=0;i<36;i++){
txt+='<div class="inbox">';
for(j=0;j<9;j++){
if(j==4){txt+='<div style="border:1px solid black;"></div>';}else{txt+='<div></div>';}
}
txt+='</div>';
}
gamen.innerHTML=txt;
</script>
ちょっと長くなりますが解説はここをクリック
<style>タグ内で 、先に指定した.boxに対する指定と同様に、内側の3×3のマスを構成するためのgridを指定していきます。
.inbox{
display:-ms-grid;
display:grid;
-ms-grid-columns:(16px)[3];
grid-template-columns:repeat(3,16px);
-ms-grid-rows:(16px)[3];
grid-template-rows:repeat(3,16px);
border:1px solid black;
}
という部分ですね。
で、この指定は「3×3」を内包する要素に対する指定なので、
<div class="inbox"></div>
を書き出していた部分に変更を加え、
txt+='<div class="inbox">';
for(j=0;j<9;j++){
if(j==4){txt+='<div style="border:1px solid black;"></div>';}else{txt+='<div></div>';}
}
txt+='</div>';
と、しています。
txt+='<div class="inbox">'; で<div class="inbox">を書き出した後で、その内容に当たる部分を変数jのループで書き出してから、最後にtxt+='</div>';でinboxなdiv要素を閉じています。
内容に当たる部分を書き出しているのは、
if(j==4){txt+='<div style="border:1px solid black;"></div>';}else{txt+='<div></div>';}
の部分です。
「真ん中の四角だけ、枠をつけたdiv('<div style="border:1px solid black;"></div>')」を出力して、「それ以外は枠の無いdiv('<div></div>') 」を出力しています。(j==4の時が真ん中になります)
…あと、6×6の時にはgamen.inneHTMLに直接+=で書き出していましたが、入れ子になると何故かそれでは上手く入れ子にならなかったので、急遽、「一旦、変数txtに全部入れてから、最後にgamen.innerHTMLに書き出す」という形に変更しています。
※参考→【解決】【CSS】gridレイアウトの入れ子に失敗した話【つまづきの記録】
実行(プレビュー)してみると…
↑こんな風になります。
今回の解説はここまでです
基本の型ができたところで、さらに<div>を書き出している部分に変更を加えて、「書き出す内容の場合分け」を行い、完成したのが昨日の
でした^^
迷路に限らず、「大まかな画面」を先に作っておいてから、機能追加や細かい作り込みを都度テストしながら作っていくのが、モチベ的にいいかもですね。
…って思いましたw
ってなとこで、今回はこのへんで!
次回もまた、よろしくお願いします^^