目次へ戻る

1 HTML とは

HTML とは、誤解を恐れずに言ってしまうとウェブページ(ホームページ)を作るために使われている言語です。 例えば、以下のようなものが HTML です。

<html lang="ja">
  <head>
    <meta charset=utf-8>
    <title>タイトル</title>
  </head>
  <body>

    <h1>見出し</h1>
    <p>
      本文本文本文本文本文本文本文本文本文本文本文本文本文本文
      本文本文<a href="https://en.wikipedia.org/wiki/Hyperlink">ハイパーリンク</a>本文
      本文本文本文本文本文本文本文本文本文本文本文本文本文本文
    </p>
  </body>

</html>

サンプル

イメージ湧きましたか?

では、何故 HTML というものが必要なのでしょうか。 言い方を変えると「シンプルテキストとの違いは?」なんなのでしょうか。 それは、二つあります。

目次へ戻る

1.1 ハイパーリンクとは

ハイパーリンクとはこういったテキストのこと、つまり単語をポチっと押して別の文章に飛ぶ仕組みです。

ハイパーテキスト以前の文章では、関連する事柄を知りたいときに、 その文章に付属する参考文献の章などを調べなければいけませんでした。 それがあたりまえだったのです。 ハイパーリンクはとてつもなく画期的な仕組みだったのです。

また、文章中にハイパーリンクを含んだ文章を、ハイパーテキストといいます。 HyperText Markup Language というのは、元々そういう意味だったんですね。

以下に、ハイパーリンクを張っている HTML の例を示します。

<html lang="ja"><head><meta charset=utf-8><title>タイトル</title></head><body>

<p>
    <a href="https://en.wikipedia.org/wiki/Computer_program">プログラミング</a>ってどんなことだと思いますか?
    一番想像しやすい例をあげると、「ゲームを作る作業」は
    <a href="https://en.wikipedia.org/wiki/Computer_program">プログラミング</a>ですよね。
    そんなイメージありませんか?
    僕も、最初に「<a href="https://en.wikipedia.org/wiki/Computer_program">プログラミング</a>ってどんなこと?」で想像したのは
    「ゲームとかエクセルみたいなのを作ること!」でした。
</p>

</body></html>

サンプル

簡単ですね!

目次へ戻る

1.2 文章を構造化するとは

文章を構造化するとは、段落や見出しなどの「テキストの文章内における役割」を文章中に持たせることです。

たとえば、以下のような文章があったとします。

** 今日買ったもの **

今日買ったものは、以下の通りです。

- りんご
- みかん
- にんじん

もし、この文章を見たのが人間ならば、どこが見出しで、どこが段落で、どこが箇条書きかなどの文章の構造が分かると思います。 しかし、それは機械からは分かりません。

インターネット上に置いた文章は、人間だけが読むものではありません。 検索エンジンなど、様々なプログラムがインターネット上に置いた文章を読む可能性があります。

では、この文章を HTML を使って構造化してみましょう。

<html lang="ja">
  <head>
    <meta charset=utf-8>
    <title>今日買ったもの(タイトル)</title>
  </head>
  <body>
    <h1>今日買ったもの</h1>
    <p>
      今日買ったものは、以下の通りです。
    </p>
    <ul>
        <li>りんご</li>
        <li>みかん</li>
        <li>にんじん</li>
    </ul>
  </body>
</html>

サンプル

簡単ですね!

目次へ戻る

1.3 HTML の様々な仕様

HTML の仕様には、以下のように様々なものがあります。

「どの仕様が正しい」ということはないですが、最近は HTML5 が使われることが多いです。 なお、この講座では以降 HTML5 という仕様を使います。

目次へ戻る

2 JavaScript とは

JavaScript とは、「HTML に動きを付けるためのプログラミング言語」です。 今では Chrome, Firefox, Safari, IE で JavaScript (または、 JavaScript 互換)の言語を使うことができます。

JavaScript は、 script 要素の中(<script type="text/javascript"> と </script>の間)に記述します。 特に head 要素の中に書く必要はありませんが、慣例的に head 要素の中に書かれることが多いです。

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>

        <script type="text/javascript">
            alert("Hello, world!");
        </script>

    </head>
    <body>
        <p>Hello, world!</p>
    </body>
</html>

サンプル

動きましたか? alert( ... ) の中に書いた値が表示されたんですね! なんとなく分かった感じになってください!

目次へ戻る

3 JavaScript で HTML を書き換えてみよう(1)

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">

            function main() {
                var elm = document.getElementById("target");
                elm.innerHTML = "Hello, <strong>JavaScript!</strong>";
            }

        </script>
    </head>

    <body onload="main()">
        <p id="target">Hello, world!</p>
    </body>
</html>

サンプル

目次へ戻る

4 JavaScript で HTML を書き換えてみよう(2)

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">

            function main() {
                var elm = document.getElementById('target');
                elm.innerHTML = 'Hello, <strong>JavaScript!</strong>';
            }

        </script>
    </head>

    <body>
        <p id="target">Hello, world!</p>
        <input type="button" value="click" onclick="main()" />
    </body>
</html>

サンプル

目次へ戻る

5 足し算をやってみよう!

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">

            function main() {
                var elmTarget = document.getElementById('target');
                var elmValue0 = document.getElementById('value0');
                var elmValue1 = document.getElementById('value1');

                elmTarget.innerHTML = parseInt(elmValue0.value) +
                                            parseInt(elmValue1.value);
            }

        </script>
    </head>

    <body>
        <p id="target">Hello, world!</p>
        <input id="value0" type="text" value="100" />
        +
        <input id="value1" type="text" value="200" />
        <input type="button" value="click" onclick="main()" />
    </body>
</html>

サンプル

目次へ戻る

6 四角を書いてみよう

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">

            function main() {
                var elmTarget = document.getElementById('target');
                var ctx = elmTarget.getContext('2d');

                ctx.fillStyle = 'rgb(255, 0, 0)';
                ctx.fillRect(0, 0, 20, 20);
            }

        </script>
    </head>

    <body>
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
        <input type="button" value="click" onclick="main()" />
    </body>
</html>

サンプル

目次へ戻る

7 四角を書いたり消したりしてみよう!

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');
                ctx.fillStyle = 'rgb(255, 0, 0)';
            }

            function paint() {
                ctx.fillRect(10, 10, 20, 20);
            }

            function clean() {
                ctx.clearRect(0, 0, 200, 400);
            }
        </script>
    </head>

    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
        <input type="button" value="paint"  onclick="paint()" />
        <input type="button" value="clear" onclick="clean()" />
    </body>
</html>

サンプル

目次へ戻る

8 配列をブロックに変換してみよう

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');
                ctx.fillStyle = 'rgb(255, 0, 0)';
            }

            function paint() {
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x]) {
                            ctx.fillRect(x * 20, y * 20, 20, 20);
                        }
                    }
                }
            }

            function clean() {
                ctx.clearRect(0, 0, 200, 400);
            }
        </script>
    </head>

    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
        <input type="button" value="paint"  onclick="paint()" />
        <input type="button" value="clear" onclick="clean()" />
    </body>
</html>

サンプル

目次へ戻る

9 ブロックを動かしてみよう

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');
                ctx.fillStyle = 'rgb(255, 0, 0)';
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x]) {
                            ctx.fillRect((x + posx) * 20, (y + posy) * 20, 20, 20);
                        }
                    }
                }
                posy = posy + 1;
            }
        </script>
    </head>

    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
        <input type="button" value="paint"  onclick="paint()" />
    </body>
</html>

サンプル

目次へ戻る

10 ブロックを自動で動かしてみよう

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');
                ctx.fillStyle = 'rgb(255, 0, 0)';

                setInterval(paint, 200);
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x]) {
                            ctx.fillRect((x + posx) * 20, (y + posy) * 20, 20, 20);
                        }
                    }
                }
                posy = posy + 1;
            }
        </script>
    </head>

    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

目次へ戻る

11 配列の描画を関数にする

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');
                ctx.fillStyle = 'rgb(255, 0, 0)';

                setInterval(paint, 200);
            }

            function paintMatrix(matrix, offsetx, offsety) {
                for (var y = 0; y < matrix.length; y ++) {
                    for (var x = 0; x < matrix[y].length; x ++) {
                        if (matrix[y][x]) {
                            ctx.fillRect((x + offsetx) * 20, (y + offsety) * 20, 20, 20);
                        }
                    }
                }
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy);
                posy = posy + 1;
            }
        </script>
    </head>

    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

目次へ戻る

12 全体のエリアの配列を作る

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;
            var map, mapWidth = 10, mapHeight = 20;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');

                map = [];
                for (var y = 0; y < mapHeight; y++) {
                    map[y] = [];
                    for (var x = 0; x < mapWidth; x++) {
                        map[y][x] = 0;
                    }
                }

                setInterval(paint, 200);
            }

            function paintMatrix(matrix, offsetx, offsety, color) {
                ctx.fillStyle = color;
                for (var y = 0; y < matrix.length; y ++) {
                    for (var x = 0; x < matrix[y].length; x ++) {
                        if (matrix[y][x]) {
                            ctx.fillRect((x + offsetx) * 20, (y + offsety) * 20, 20, 20);
                        }
                    }
                }
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                posy = posy + 1;
            }
        </script>
    </head>

    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

目次へ戻る

13 ブロックがエリアに溜まるようにする

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;
            var map, mapWidth = 10, mapHeight = 20;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');

                map = [];
                for (var y = 0; y < mapHeight; y++) {
                    map[y] = [];
                    for (var x = 0; x < mapWidth; x++) {
                        map[y][x] = 0;
                    }
                }
                setInterval(paint, 200);
            }

            function paintMatrix(matrix, offsetx, offsety, color) {
                ctx.fillStyle = color;
                for (var y = 0; y < matrix.length; y ++) {
                    for (var x = 0; x < matrix[y].length; x ++) {
                        if (matrix[y][x]) {
                            ctx.fillRect((x + offsetx) * 20, (y + offsety) * 20, 20, 20);
                        }
                    }
                }
            }

            function check(map, block, offsetx, offsety) {
                if (offsetx < 0 || offsety < 0 ||
                    mapHeight < offsety + block.length ||
                    mapWidth  < offsetx + block[0].length) {
                    return false;;
                }
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x] && map[y + offsety][x + offsetx]) { 
                            return false;
                        }
                    }
                }
                return true;
            }

            function mergeMatrix(map, block, offsetx, offsety) {
                for (var y = 0; y < mapHeight; y ++) {
                    for (var x = 0; x < mapWidth; x ++) {
                        if (block[y - offsety] && block[y - offsety][x - offsetx]) {
                            map[y][x]++;
                        }
                    }
                }
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');

                if (check(map, block, posx, posy + 1)) {
                    posy = posy + 1;
                }
                else {
                    mergeMatrix(map, block, posx, posy);
                    posx = 0; posy = 0;
                }
            }
        </script>
    </head>

    <body onload="load()">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

目次へ戻る

14 左右下に動かす

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;
            var map, mapWidth = 10, mapHeight = 20;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');

                map = [];
                for (var y = 0; y < mapHeight; y++) {
                    map[y] = [];
                    for (var x = 0; x < mapWidth; x++) {
                        map[y][x] = 0;
                    }
                }
                setInterval(paint, 200);
            }

            function paintMatrix(matrix, offsetx, offsety, color) {
                ctx.fillStyle = color;
                for (var y = 0; y < matrix.length; y ++) {
                    for (var x = 0; x < matrix[y].length; x ++) {
                        if (matrix[y][x]) {
                            ctx.fillRect((x + offsetx) * 20, (y + offsety) * 20, 20, 20);
                        }
                    }
                }
            }

            function check(map, block, offsetx, offsety) {
                if (offsetx < 0 || offsety < 0 ||
                    mapHeight < offsety + block.length ||
                    mapWidth < offsetx + block[0].length) {
                    return false;;
                }
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x] && map[y + offsety][x + offsetx]) { 
                            return false;
                        }
                    }
                }
                return true;
            }

            function mergeMatrix(map, block, offsetx, offsety) {
                for (var y = 0; y < mapHeight; y ++) {
                    for (var x = 0; x < mapWidth; x ++) {
                        if (block[y - offsety] && block[y - offsety][x - offsetx]) {
                            map[y][x]++;
                        }
                    }
                }
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');

                if (check(map, block, posx, posy + 1)) {
                    posy = posy + 1;
                }
                else {
                    mergeMatrix(map, block, posx, posy);
                    posx = 0; posy = 0;
                }
            }

            function key(keyCode) {
                switch (keyCode) {
                    case 39:
                        if (!check(map, block, posx + 1, posy)) {
                            return;
                        }
                        posx = posx + 1;
                        break;
                    case 37:
                        if (!check(map, block, posx - 1, posy)) {
                            return;
                        }
                        posx = posx - 1;
                        break;
                    case 40:
                        var y = posy;
                        while (check(map, block, posx, y)) { y++; }
                        posy = y - 1;
                        break;
                    default:
                        return;
                }
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');
            }

        </script>
    </head>

    <body onload="load()" onkeydown="key(event.keyCode)">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

目次へ戻る

15 回転させる

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;
            var map, mapWidth = 10, mapHeight = 20;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');

                map = [];
                for (var y = 0; y < mapHeight; y++) {
                    map[y] = [];
                    for (var x = 0; x < mapWidth; x++) {
                        map[y][x] = 0;
                    }
                }
                setInterval(paint, 200);
            }

            function paintMatrix(matrix, offsetx, offsety, color) {
                ctx.fillStyle = color;
                for (var y = 0; y < matrix.length; y ++) {
                    for (var x = 0; x < matrix[y].length; x ++) {
                        if (matrix[y][x]) {
                            ctx.fillRect((x + offsetx) * 20, (y + offsety) * 20, 20, 20);
                        }
                    }
                }
            }

            function check(map, block, offsetx, offsety) {
                if (offsetx < 0 || offsety < 0 ||
                    mapHeight < offsety + block.length ||
                    mapWidth < offsetx + block[0].length) {
                    return false;;
                }
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x] && map[y + offsety][x + offsetx]) { 
                            return false;
                        }
                    }
                }
                return true;
            }

            function mergeMatrix(map, block, offsetx, offsety) {
                for (var y = 0; y < mapHeight; y ++) {
                    for (var x = 0; x < mapWidth; x ++) {
                        if (block[y - offsety] && block[y - offsety][x - offsetx]) {
                            map[y][x]++;
                        }
                    }
                }
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');

                if (check(map, block, posx, posy + 1)) {
                    posy = posy + 1;
                }
                else {
                    mergeMatrix(map, block, posx, posy);
                    posx = 0; posy = 0;
                }
            }

            function rotate(block) {
                var rotated = [];
                for (var x = 0; x < block[0].length; x ++) {
                    rotated[x] = [];
                    for (var y = 0; y < block.length; y ++) {
                        rotated[x][block.length - y - 1] = block[y][x];
                    }
                }
                return rotated;
            }

            function key(keyCode) {
                switch (keyCode) {
                    case 38:
                        if (!check(map, rotate(block), posx, posy)) {
                            return;
                        }
                        block = rotate(block);
                        break;
                    case 39:
                        if (!check(map, block, posx + 1, posy)) {
                            return;
                        }
                        posx = posx + 1;
                        break;
                    case 37:
                        if (!check(map, block, posx - 1, posy)) {
                            return;
                        }
                        posx = posx - 1;
                        break;
                    case 40:
                        var y = posy;
                        while (check(map, block, posx, y)) { y++; }
                        posy = y - 1;
                        break;
                    default:
                        return;
                }
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');
            }

        </script>
    </head>

    <body onload="load()" onkeydown="key(event.keyCode)">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

目次へ戻る

16 揃ったら消す

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var block = [
                [1,1],
                [0,1],
                [0,1]
            ];
            var posx = 0, posy = 0;
            var map, mapWidth = 10, mapHeight = 20;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');

                map = [];
                for (var y = 0; y < mapHeight; y++) {
                    map[y] = [];
                    for (var x = 0; x < mapWidth; x++) {
                        map[y][x] = 0;
                    }
                }
                setInterval(paint, 200);
            }

            function paintMatrix(matrix, offsetx, offsety, color) {
                ctx.fillStyle = color;
                for (var y = 0; y < matrix.length; y ++) {
                    for (var x = 0; x < matrix[y].length; x ++) {
                        if (matrix[y][x]) {
                            ctx.fillRect((x + offsetx) * 20, (y + offsety) * 20, 20, 20);
                        }
                    }
                }
            }

            function check(map, block, offsetx, offsety) {
                if (offsetx < 0 || offsety < 0 ||
                    mapHeight < offsety + block.length ||
                    mapWidth < offsetx + block[0].length) {
                    return false;;
                }
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x] && map[y + offsety][x + offsetx]) { 
                            return false;
                        }
                    }
                }
                return true;
            }

            function mergeMatrix(map, block, offsetx, offsety) {
                for (var y = 0; y < mapHeight; y ++) {
                    for (var x = 0; x < mapWidth; x ++) {
                        if (block[y - offsety] && block[y - offsety][x - offsetx]) {
                            map[y][x]++;
                        }
                    }
                }
            }

            function clearRows(map) {
                for (var y = 0; y < mapHeight; y ++) {
                    var full = true;
                    for (var x = 0; x < mapWidth; x ++) {
                        if (!map[y][x]) {
                            full = false;
                        }
                    }
                    if (full) {
                        map.splice(y, 1);
                        var newRow = [];
                        for (var i = 0; i < mapWidth; i ++) {
                            newRow[i] = 0;
                        }
                        map.unshift(newRow);
                    }
                }
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');

                if (check(map, block, posx, posy + 1)) {
                    posy = posy + 1;
                }
                else {
                    mergeMatrix(map, block, posx, posy);
                    clearRows(map);
                    posx = 0; posy = 0;
                }
            }

            function rotate(block) {
                var rotated = [];
                for (var x = 0; x < block[0].length; x ++) {
                    rotated[x] = [];
                    for (var y = 0; y < block.length; y ++) {
                        rotated[x][block.length - y - 1] = block[y][x];
                    }
                }
                return rotated;
            }

            function key(keyCode) {
                switch (keyCode) {
                    case 38:
                        if (!check(map, rotate(block), posx, posy)) {
                            return;
                        }
                        block = rotate(block);
                        break;
                    case 39:
                        if (!check(map, block, posx + 1, posy)) {
                            return;
                        }
                        posx = posx + 1;
                        break;
                    case 37:
                        if (!check(map, block, posx - 1, posy)) {
                            return;
                        }
                        posx = posx - 1;
                        break;
                    case 40:
                        var y = posy;
                        while (check(map, block, posx, y)) { y++; }
                        posy = y - 1;
                        break;
                    default:
                        return;
                }
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');
            }

        </script>
    </head>

    <body onload="load()" onkeydown="key(event.keyCode)">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

目次へ戻る

17 ランダムなブロックを出す

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
        <script type="text/javascript">
            var ctx;
            var blocks = [
                [
                    [1,1],
                    [0,1],
                    [0,1]
                ],
                [
                    [1,1],
                    [1,0],
                    [1,0]
                ],
                [
                    [1,1],
                    [1,1]
                ],
                [
                    [1,0],
                    [1,1],
                    [1,0]
                ],
                [
                    [1,0],
                    [1,1],
                    [0,1]
                ],
                [
                    [0,1],
                    [1,1],
                    [1,0]
                ],
                [
                    [1],
                    [1],
                    [1],
                    [1]
                ]
            ];

            var block = blocks[Math.floor(Math.random() * blocks.length)];
            var posx = 0, posy = 0;
            var map, mapWidth = 10, mapHeight = 20;

            function load() {
                var elmTarget = document.getElementById('target');
                ctx = elmTarget.getContext('2d');

                map = [];
                for (var y = 0; y < mapHeight; y++) {
                    map[y] = [];
                    for (var x = 0; x < mapWidth; x++) {
                        map[y][x] = 0;
                    }
                }
                setInterval(paint, 200);
            }

            function paintMatrix(matrix, offsetx, offsety, color) {
                ctx.fillStyle = color;
                for (var y = 0; y < matrix.length; y ++) {
                    for (var x = 0; x < matrix[y].length; x ++) {
                        if (matrix[y][x]) {
                            ctx.fillRect((x + offsetx) * 20, (y + offsety) * 20, 20, 20);
                        }
                    }
                }
            }

            function check(map, block, offsetx, offsety) {
                if (offsetx < 0 || offsety < 0 ||
                    mapHeight < offsety + block.length ||
                    mapWidth < offsetx + block[0].length) {
                    return false;
                }
                for (var y = 0; y < block.length; y ++) {
                    for (var x = 0; x < block[y].length; x ++) {
                        if (block[y][x] && map[y + offsety][x + offsetx]) { 
                            return false;
                        }
                    }
                }
                return true;
            }

            function mergeMatrix(map, block, offsetx, offsety) {
                for (var y = 0; y < mapHeight; y ++) {
                    for (var x = 0; x < mapWidth; x ++) {
                        if (block[y - offsety] && block[y - offsety][x - offsetx]) {
                            map[y][x]++;
                        }
                    }
                }
            }

            function clearRows(map) {
                for (var y = 0; y < mapHeight; y ++) {
                    var full = true;
                    for (var x = 0; x < mapWidth; x ++) {
                        if (!map[y][x]) {
                            full = false;
                        }
                    }
                    if (full) {
                        map.splice(y, 1);
                        var newRow = [];
                        for (var i = 0; i < mapWidth; i ++) {
                            newRow[i] = 0;
                        }
                        map.unshift(newRow);
                    }
                }
            }

            function paint() {
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');

                if (check(map, block, posx, posy + 1)) {
                    posy = posy + 1;
                }
                else {
                    mergeMatrix(map, block, posx, posy);
                    clearRows(map);
                    posx = 0; posy = 0;
                    block = blocks[Math.floor(Math.random() * blocks.length)];
                }
            }

            function rotate(block) {
                var rotated = [];
                for (var x = 0; x < block[0].length; x ++) {
                    rotated[x] = [];
                    for (var y = 0; y < block.length; y ++) {
                        rotated[x][block.length - y - 1] = block[y][x];
                    }
                }
                return rotated;
            }

            function key(keyCode) {
                switch (keyCode) {
                    case 38:
                        if (!check(map, rotate(block), posx, posy)) {
                            return;
                        }
                        block = rotate(block);
                        break;
                    case 39:
                        if (!check(map, block, posx + 1, posy)) {
                            return;
                        }
                        posx = posx + 1;
                        break;
                    case 37:
                        if (!check(map, block, posx - 1, posy)) {
                            return;
                        }
                        posx = posx - 1;
                        break;
                    case 40:
                        var y = posy;
                        while (check(map, block, posx, y)) { y++; }
                        posy = y - 1;
                        break;
                    default:
                        return;
                }
                ctx.clearRect(0, 0, 200, 400);
                paintMatrix(block, posx, posy, 'rgb(255, 0, 0)');
                paintMatrix(map, 0, 0, 'rgb(128, 128, 128)');
            }

        </script>
    </head>

    <body onload="load()" onkeydown="key(event.keyCode)">
        <canvas id="target" style="border: 5px solid gray" width="200" height="400"></canvas>
    </body>
</html>

サンプル

やった!これで動くようになりました!