素のHTML, CSS, JavaScriptで0から始めるWeb開発【HTML&JavaScript基礎編】

投稿日: カテゴリー: 未分類
Pocket

こんにちは、エムティーアイの井上です。今回はこれからWeb開発を始めたいという方向けにWeb開発の基礎となる部分を紹介します。

このシリーズのゴールはWeb開発に必要な3つの言語 HTML, CSS, JavaScript の仕組みを理解し書けるようになることにあります。HTML, CSS, JavaScriptでテトリスを作りながらそれぞれの仕組みをご紹介いたします。
全体で4部構成になっており今回はその第3弾【HTML&JavaScript基礎編】となります。

第1部 【入門編】Web開発未経験者
第2部 【HTML&CSS基礎編】簡単な仕組みはわかっているという人向け
第3部 【HTML&JavaScript基礎編】簡単な仕組みはわかっているという人向け
第4部 【応用編】Web開発経験者向け

一定時間で繰り返す

JavaScriptでは画面上のさまざまな要素を書き換えることができます。第1弾では文字を書き換えましたね。
今回は一定時間ごとに繰り返す処理を書いてみます。
main.jsを次のように書き加えてみましょう

まず
var count = 0;
の部分でcountという変数を定義します。
そしてsetIntervalというのは一定の間隔で繰り返すための関数です。
setInterval(動かしたい関数, 繰り返す間隔(ms));
という書き方で繰り返しの処理を行うことができます。
今回の例ではcountを1ずつ増やしてタイトルに表示しています。

それではこの繰り返しを用いてブロックが1秒間に1マス落ちるようにしましょう!

第2弾で制作したゲーム盤の一つ一つは<td>タグでしたね。
まずHTML上の<td>タグをすべてJavaScriptから取得します。

このときtd_arrayには全部で200マス分の<td>タグが格納されています。
格納されている順番は次の通りです。

このままではtd_arrayの何番目がどのマスを示しているかわかりずらいですね…
2次元配列にして座標のように扱えるよう変形してみましょう!

これはfor文を用いてcells[何行目][何列目]と指定できるようになります。
cellsの指し示す中身は以下の通りになります。
(あまりに多いので一部のみ掲載します)

cellsの中に入っているのはタグそのものを指し示すためクラスを付けたりなくしたりできます!
これを活用することでそれぞれのマスを示す<td>タグのクラスを一つ下のマスを示す<td>に移すことであたかもブロックが落ちているように見せます!
流れとしては
1. 一番下の行を見る
2. クラスを空にする
3. 下から2番目の行を見る
4. もしもクラスが振られていたら一行下のマスにクラスを写して自分のクラスを空にする
5. 4を一番上の行に達するまで繰り返す
となります。
コードにするとこうなります。

これで1秒ごとにブロックが落ちていくように見えましたか?

さて、これから

  • ランダムにブロックを生成したり
  • ブロックが積み重なるようにしたり
  • そろった行を削除したり
  • 矢印キーでブロックを移動させたり

していくわけですが
それぞれをただ書き続けているとプログラムが読みにくくなってしまいますね…

ここで関数を使ってまとめていきます!

現状のJavaScriptを関数を使って整理してみましょう!
現在行っている処理は大きく分けて二つありますね?

  1. ゲーム盤の状態を2次元配列にまとめる
  2. ブロック(色がついているマス)を一つ下に移動させる

この二つを関数としてloadTablefallBlocksにまとめます。
全体の構成としてはこのようになります。

※関数の中の実装は省略しています

それぞれの関数の中身はすでに実装したコードの一部となります。
しかし、関数でまとめることで上記の全体像のように流れが分かりやすくなりますね。

実際に関数の中身を実装すると次のようになります。

それではこれから記述するプログラムをあらかじめ機能ごとに関数に分けて記述してみましょう!

もちろん現状では中身を実装していないので何も動きませんが、
これから何を実装するかはわかりやすくなりましたね。

それではまず初めに落下中のブロックがあるかを判定する関数を実装します。
この関数があることで、
– ブロックを落とすのか
あるいは
– そろった行を消して新しいブロックを生成するのか
を切り替えることが可能になります。

実装としては落下中かどうかをフラグ(変数)で持ちブロックを落とすときに判断します。
ブロックが一番下の行に達した時に落下中のフラグはfalseになります。
落下中のフラグは変数isFallingで保持します。

これで一番下までブロックが来た時にブロックが落ちなくなりましたね?

それでは次にランダムにブロックを生成する関数を実装しましょう!

ブロックにはいくつかのパターンがあり、それぞれのパターンには決められたクラスが存在します。
これらをif文ですべて分岐していたら大変なのでJavaScriptのObjectを使って管理します。
Objectとは配列に似た機能を用い複数のデータをまとめるときに使用します。
今回の場合、「パターン名」「クラス名」「ブロックの配置パターン」をまとめることになります。
配列との違いはそれぞれの要素を番号ではなく名前で呼び出せることにあります。
例えば配列の場合
hoge[0],hoge[1]と呼び出していましたが、
Objectの場合
hoge["title"],hoge["desc"]と呼び出せます。
こちらの方がコードが読みやすいですね。
それでは「パターン名」「クラス名」「ブロックの配置パターン」を持ったObjectを定義します。

i型(横一列)のブロックを例に説明します。
まずi型のブロックのみを表す部分は以下の部分です。

まずi : { ... }となっている塊がi型ブロック自身を示しており、blocks["i"]で呼び出すことができます。
そしてclass: "i"という要素はblocks["i"].classで呼び出すことができその値は"i"になります。
同様にpatternに関してもblocks["i"].patternで呼び出すことができます。
patternは2次元配列を用いて1の部分にはブロックを置き、0のところにはブロックを置かないものとしてブロックの配置パターンを定義しています。
i型の場合は横一列に4ブロック並ぶので

t型なら

となります。

このブロックパターンからランダムにパターンを選出しゲーム盤の一番上に配置します。
この処理は3つの処理に分けて考えることができますね。
コメントアウトで記述すると下記のとおりです。

それではまずブロックパターンからランダムに一つパターンを選びます。

JavaScriptのObjectはそれぞれの名前(String)で要素を指定するため一工夫必要です。
まず初めに名前の配列を取得します(1行目)
次に名前の一覧から要素をランダムに選びます(2行目)
最後にランダムに選んだ名前をもとに要素を取得します(3行目)
2行目のランダムに配列の要素を取得している部分では0から1までの乱数を生成するMath.random()に配列が何個あるか(keys.length)を掛け、それをMath.floor()によって小数点以下を切りすてることで選んでいます。

次に選んだパターンからブロックを配置します。
このときブロックがゲーム盤の中央上部に登場するよう左から4番目のマスから配置していきます。

これでブロックが一番下まで達したときに新たにブロックが生成されるようになります。
しかし、このままでは落下中のブロックがあるとは思わず、1秒経った時にまたブロックを生成し続けてしまいます。
それを防ぐために、isFallingtrueにしておきましょう。

さて、これで一見正しく動きそうですが、実は動きません…
なぜかというと、現在のフローでは

このときの条件である一番下の行にブロックが達したかですが、どのブロックでも一番下にあれば新しくブロックを生成してしまうため理想的な動きではありません。
そこで生成したブロックに番号を振り、落下中だったブロックが落ちなくなったら新しくブロックを生成するようにします。

まず、この実装のために最初から配置していたブロックをなくします。
(index.htmlからclass="*"を削除します)

そして、最初の段階ではisFalling(落ちているブロック)はないはずなのでfalseで初期化します。

次にブロックを生成する際に番号を振り、その番号をfallingBlockNumという変数で保持します。

そして、fallBlocks関数ではただブロックを落とすだけではなく、1マス落としていいのかどうか正しく判定する必要が出てきました。
(これまでのプログラムでは落としていいかどうかはほとんど判定していない)
ただし、チェックしなければいけない条件はいたってシンプルです。

  1. 底についていないか?
  2. 1マス下に別のブロックがないか?

これを実装します。

これでだいぶゲームらしくなってきたのではないのでしょうか?

それでは次回以降で

  • そろった行を消す
  • キーボードでブロックを操作する
  • 積みあがったらゲームオーバーとする

といった機能の説明をいたします。

今回の記事でJavaScriptの動きがだいぶつかめてきたでしょうか?

次回、いよいよゲームを完成させましょう!

Pocket