四角を書いてみよう

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body>
        <script src="raphael.js"></script>
        <script>
            var paper = Raphael(0, 0, 500, 500);
            paper.rect(0, 0, 20, 20);
        </script>
    </body>
</html>

サンプル

四角に色を付けてみよう

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body>
        <script src="raphael.js"></script>
        <script>
            var paper = Raphael(0, 0, 500, 500);
            paper.rect(0, 0, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
        </script>
    </body>
</html>

サンプル

ブロックを書いてみよう

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body>
        <script src="raphael.js"></script>
        <script>
            var block = [ 
                [1,1], 
                [0,1], 
                [0,1] 
            ]; 

            var paper = Raphael(0, 0, 500, 500);

            for (var y = 0; y < block.length; y ++) { 
                for (var x = 0; x < block[y].length; x ++) { 
                    if (block[y][x]) { 
                        paper.rect(x * 20, y * 20, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                    } 
                } 
            } 
        </script>
    </body>
</html>

サンプル

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

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body>
        <script src="raphael.js"></script>
        <script>
            var block = [
                [1,1], 
                [0,1], 
                [0,1] 
            ];

            var paper = Raphael(0, 0, 500, 500);

            var blockRects = [];

            for (var y = 0; y < block.length; y ++) { 
                for (var x = 0; x < block[y].length; x ++) { 
                    if (block[y][x]) { 
                        var rect = paper.rect(x * 20, y * 20, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                        blockRects.push(rect);
                    } 
                } 
            } 

            setInterval(function() {
                for (var i = 0; i < blockRects.length; i++) {
                    var rect = blockRects[i];
                    rect.attr({ x: rect.attr('x'), y: rect.attr('y') + 20 });
                }
            }, 1000)
 
        </script>
    </body>
</html>

サンプル

四角クラスとブロッククラスを作る

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body>
        <script src="raphael.js"></script>
        <script>

            var paper = Raphael(0, 0, 500, 500);

            function Rect(x, y) {
                this.impl = paper.rect(0, 0, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                this.move(x, y);
            }

            Rect.prototype.move = function(x, y) {
                this.x = x;
                this.y = y;
                this.impl.attr({ x: this.x * 20, y: this.y * 20 });
            }

            function Block() {
                var block = Block.blocks[Math.floor(Math.random() * Block.blocks.length)];
                this.block = [];
                this.block.length = block.length;
                for (var y = 0; y < block.length; y ++) { 
                    this.block[y] = [];
                    this.block[y].length = block[y].length;
                    for (var x = 0; x < block[y].length; x ++) { 
                        this.block[y][x] = block[y][x] ? new Rect(x, y) : null;
                    } 
                }
            }

            Block.prototype.move = function(offx, offy) {
                this.x = offx;
                this.y = offy;
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.move(x + offx, y + offy);
                        }
                    } 
                }
            };

            Block.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 posx = 0, posy = 0;

            var block = new Block();

            setInterval(function() {
                posy++;
                block.move(posx, posy);
            }, 1000)
 
        </script>
    </body>
</html>

サンプル

外枠クラスを作る

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body>
        <script src="raphael.js"></script>
        <script>

            var paper = Raphael(0, 0, 500, 500);

            function Rect(x, y) {
                this.impl = paper.rect(0, 0, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                this.move(x, y);
            }

            Rect.prototype.move = function(x, y) {
                this.x = x;
                this.y = y;
                this.impl.attr({ x: this.x * 20, y: this.y * 20 });
            }

            function Block() {
                var block = Block.blocks[Math.floor(Math.random() * Block.blocks.length)];
                this.block = [];
                this.block.length = block.length;
                for (var y = 0; y < block.length; y ++) { 
                    this.block[y] = [];
                    this.block[y].length = block[y].length;
                    for (var x = 0; x < block[y].length; x ++) { 
                        this.block[y][x] = block[y][x] ? new Rect(x, y) : null;
                    } 
                }
            }

            Block.prototype.move = function(offx, offy) {
                this.x = offx;
                this.y = offy;
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.move(x + offx, y + offy);
                        }
                    } 
                }
            };

            Block.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]
                ]
            ];

            function Map() {
                this.map = [];
                for (var y = 0; y < 20; y++) {
                    this.map[y] = [];
                    for (var x = 0; x < 10; x++) {
                        this.map[y][x] = 0;
                    }
                }
                this.impl = paper.rect(0, 0, 10 * 20, 20 * 20).attr({ stroke: '#cccccc', fill: '#cccccc' });
            }

            Map.prototype.check = function(block, offsetX, offsetY) {
                if (offsetX < 0 || offsetY < 0) {
                    return false;
                }
                for (var y = 0; y < block.length; y++) {
                    if (y + offsetY >= this.map.length) {
                        return false;
                    }
                    for (var x = 0; x < block[y].length; x++) {
                        if (x + offsetX >= this.map[y].length) {
                            return false;
                        }
                        if (block[y][x] && this.map[y + offsetY][x + offsetX]) {
                            return false;
                        }
                    }
                }
                return true;
            };

            var posx = 0, posy = 0;

            var map = new Map();

            var block = new Block();

            var id = setInterval(function() {
                posy++;
                if (map.check(block.block, posx, posy)) {
                    block.move(posx, posy);
                }
                else {
                    block = new Block();
                    posx = 0;
                    posy = 0;
                }
            }, 1000)
 
        </script>
    </body>
</html>

サンプル

ブロックがを溜まるようにする

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body>
        <script src="raphael.js"></script>
        <script>

            var paper = Raphael(0, 0, 500, 500);

            function Rect(x, y) {
                this.impl = paper.rect(0, 0, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                this.move(x, y);
            }

            Rect.prototype.move = function(x, y) {
                this.x = x;
                this.y = y;
                this.impl.attr({ x: this.x * 20, y: this.y * 20 });
            }

            Rect.prototype.die = function() {
                this.impl.attr({ fill: '#888888', stroke: '#444444' });
            }

            function Block() {
                var block = Block.blocks[Math.floor(Math.random() * Block.blocks.length)];
                this.block = [];
                this.block.length = block.length;
                for (var y = 0; y < block.length; y ++) { 
                    this.block[y] = [];
                    this.block[y].length = block[y].length;
                    for (var x = 0; x < block[y].length; x ++) { 
                        this.block[y][x] = block[y][x] ? new Rect(x, y) : null;
                    } 
                }
            }

            Block.prototype.move = function(offx, offy) {
                this.x = offx;
                this.y = offy;
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.move(x + offx, y + offy);
                        }
                    } 
                }
            };

            Block.prototype.die = function() {
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.die();
                        }
                    } 
                }
            };

            Block.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]
                ]
            ];

            function Map() {
                this.map = [];
                for (var y = 0; y < 20; y++) {
                    this.map[y] = [];
                    for (var x = 0; x < 10; x++) {
                        this.map[y][x] = null;
                    }
                }
                this.impl = paper.rect(0, 0, 10 * 20, 20 * 20).attr({ stroke: '#cccccc', fill: '#cccccc' });
            }

            Map.prototype.check = function(block, offsetX, offsetY) {
                if (offsetX < 0 || offsetY < 0) {
                    return false;
                }
                for (var y = 0; y < block.length; y++) {
                    if (y + offsetY >= this.map.length) {
                        return false;
                    }
                    for (var x = 0; x < block[y].length; x++) {
                        if (x + offsetX >= this.map[y].length) {
                            return false;
                        }
                        if (block[y][x] && this.map[y + offsetY][x + offsetX]) {
                            return false;
                        }
                    }
                }
                return true;
            };

            Map.prototype.mergeBlock = function(block) {
                for (var y = 0; y < block.block.length; y++) {
                    for (var x = 0; x < block.block[y].length; x++) {
                        this.map[y + block.y][x + block.x] = block.block[y][x];
                    }
                }
            };

            var posx = 0, posy = 0;

            var map = new Map();

            var block = new Block();

            var id = setInterval(function() {
                posy++;
                if (map.check(block.block, posx, posy)) {
                    block.move(posx, posy);
                }
                else {
                    block.die();
                    map.mergeBlock(block);
                    block = new Block();
                    posx = 0;
                    posy = 0;
                    if (!map.check(block.block, posx, posy)) {
                        clearInterval(id);
                    }
                }
            }, 1000)
 
        </script>
    </body>
</html>

サンプル

左右下に動かせるようにする

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body onload="document.body.focus();" onkeydown="key(event.keyCode)">
        <script src="raphael.js"></script>
        <script>
 
            var paper = Raphael(0, 0, 500, 500);

            function Rect(x, y) {
                this.impl = paper.rect(0, 0, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                this.move(x, y);
            }

            Rect.prototype.move = function(x, y) {
                this.x = x;
                this.y = y;
                this.impl.attr({ x: this.x * 20, y: this.y * 20 });
            }

            Rect.prototype.die = function() {
                this.impl.attr({ fill: '#888888', stroke: '#444444' });
            }

            function Block() {
                var block = Block.blocks[Math.floor(Math.random() * Block.blocks.length)];
                this.block = [];
                this.block.length = block.length;
                for (var y = 0; y < block.length; y ++) { 
                    this.block[y] = [];
                    this.block[y].length = block[y].length;
                    for (var x = 0; x < block[y].length; x ++) { 
                        this.block[y][x] = block[y][x] ? new Rect(x, y) : null;
                    } 
                }
            }

            Block.prototype.move = function(offx, offy) {
                this.x = offx;
                this.y = offy;
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.move(x + offx, y + offy);
                        }
                    } 
                }
            };

            Block.prototype.die = function() {
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.die();
                        }
                    } 
                }
            };

            Block.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]
                ]
            ];

            function Map() {
                this.map = [];
                for (var y = 0; y < 20; y++) {
                    this.map[y] = [];
                    for (var x = 0; x < 10; x++) {
                        this.map[y][x] = null;
                    }
                }
                this.impl = paper.rect(0, 0, 10 * 20, 20 * 20).attr({ stroke: '#cccccc', fill: '#cccccc' });
            }

            Map.prototype.check = function(block, offsetX, offsetY) {
                if (offsetX < 0 || offsetY < 0) {
                    return false;
                }
                for (var y = 0; y < block.length; y++) {
                    if (y + offsetY >= this.map.length) {
                        return false;
                    }
                    for (var x = 0; x < block[y].length; x++) {
                        if (x + offsetX >= this.map[y].length) {
                            return false;
                        }
                        if (block[y][x] && this.map[y + offsetY][x + offsetX]) {
                            return false;
                        }
                    }
                }
                return true;
            };

            Map.prototype.mergeBlock = function(block) {
                for (var y = 0; y < block.block.length; y++) {
                    for (var x = 0; x < block.block[y].length; x++) {
                        if (block.block[y][x]) {
                            this.map[y + block.y][x + block.x] = block.block[y][x];
                        }
                    }
                }
            };

            var posx = 0, posy = 0;

            var map = new Map();

            var block = new Block();

            var id = setInterval(function() {
                posy++;
                if (map.check(block.block, posx, posy)) {
                    block.move(posx, posy);
                }
                else {
                    block.die();
                    map.mergeBlock(block);
                    block = new Block();
                    posx = 0;
                    posy = 0;
                    if (!map.check(block.block, posx, posy)) {
                        clearInterval(id);
                    }
                }
            }, 1000)
 
            function key(keyCode) { 
                switch (keyCode) { 
                    case 39: 
                        if (!map.check(block.block, posx + 1, posy)) { 
                            return; 
                        } 
                        posx = posx + 1; 
                        break; 
                    case 37: 
                        if (!map.check(block.block, posx - 1, posy)) { 
                            return; 
                        } 
                        posx = posx - 1; 
                        break; 
                    case 40: 
                        var y = posy; 
                        while (map.check(block.block, posx, y)) { y++; } 
                        posy = y - 1; 
                        break; 
                    default: 
                        return; 
                } 
                block.move(posx, posy);
            } 
 
        </script>
    </body>
</html>

サンプル

回転できるようにする

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body onload="document.body.focus();" onkeydown="key(event.keyCode)">
        <script src="raphael.js"></script>
        <script>

            var paper = Raphael(0, 0, 500, 500);

            function Rect(x, y) {
                this.impl = paper.rect(0, 0, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                this.move(x, y);
            }

            Rect.prototype.move = function(x, y) {
                this.x = x;
                this.y = y;
                this.impl.attr({ x: this.x * 20, y: this.y * 20 });
            }

            Rect.prototype.die = function() {
                this.impl.attr({ fill: '#888888', stroke: '#444444' });
            }

            function Block() {
                var block = Block.blocks[Math.floor(Math.random() * Block.blocks.length)];
                this.block = [];
                this.block.length = block.length;
                for (var y = 0; y < block.length; y ++) { 
                    this.block[y] = [];
                    this.block[y].length = block[y].length;
                    for (var x = 0; x < block[y].length; x ++) { 
                        this.block[y][x] = block[y][x] ? new Rect(x, y) : null;
                    } 
                }
            }

            Block.prototype.move = function(offx, offy) {
                this.x = offx;
                this.y = offy;
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.move(x + offx, y + offy);
                        }
                    } 
                }
            };

            Block.prototype.die = function() {
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.die();
                        }
                    } 
                }
            };

            Block.prototype.calcRotate = function(dir) {
                var rotated = [];
                var i = 0;
                for (var x = 0; x < this.block[0].length; x ++) {
                    var rx = x;
                    rotated[rx] = []; 
                    for (var y = 0; y < this.block.length; y ++) { 
                        var ry = this.block.length - y - 1;
                        rotated[rx][ry] = this.block[y][x];
                    } 
                }
                return rotated;
            };

            Block.prototype.rotate = function() {
                this.block = this.calcRotate();
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        if (this.block[y][x]) { 
                            this.block[y][x].move(x, y);
                        } 
                    } 
                }
            };
 
            Block.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]
                ]
            ];

            function Map() {
                this.map = [];
                for (var y = 0; y < 20; y++) {
                    this.map[y] = [];
                    for (var x = 0; x < 10; x++) {
                        this.map[y][x] = null;
                    }
                }
                this.impl = paper.rect(0, 0, 10 * 20, 20 * 20).attr({ stroke: '#cccccc', fill: '#cccccc' });
            }

            Map.prototype.check = function(block, offsetX, offsetY) {
                if (offsetX < 0 || offsetY < 0) {
                    return false;
                }
                for (var y = 0; y < block.length; y++) {
                    if (y + offsetY >= this.map.length) {
                        return false;
                    }
                    for (var x = 0; x < block[y].length; x++) {
                        if (x + offsetX >= this.map[y].length) {
                            return false;
                        }
                        if (block[y][x] && this.map[y + offsetY][x + offsetX]) {
                            return false;
                        }
                    }
                }
                return true;
            };

            Map.prototype.mergeBlock = function(block) {
                for (var y = 0; y < block.block.length; y++) {
                    for (var x = 0; x < block.block[y].length; x++) {
                        if (block.block[y][x]) {
                            this.map[y + block.y][x + block.x] = block.block[y][x];
                        }
                    }
                }
            };

            var posx = 0, posy = 0;

            var map = new Map();

            var block = new Block();

            var id = setInterval(function() {
                posy++;
                if (map.check(block.block, posx, posy)) {
                    block.move(posx, posy);
                }
                else {
                    block.die();
                    map.mergeBlock(block);
                    block = new Block();
                    posx = 0;
                    posy = 0;
                    if (!map.check(block.block, posx, posy)) {
                        clearInterval(id);
                    }
                }
            }, 1000)
 
 
            function key(keyCode) { 
                switch (keyCode) { 
                    case 38: 
                        if (!map.check(block.calcRotate(), posx, posy)) { 
                            return;
                        } 
                        block.rotate();
                        break; 
                    case 39: 
                        if (!map.check(block.block, posx + 1, posy)) { 
                            return; 
                        } 
                        posx = posx + 1; 
                        break; 
                    case 37: 
                        if (!map.check(block.block, posx - 1, posy)) { 
                            return; 
                        } 
                        posx = posx - 1; 
                        break; 
                    case 40: 
                        var y = posy; 
                        while (map.check(block.block, posx, y)) { y++; } 
                        posy = y - 1; 
                        break; 
                    default: 
                        return; 
                } 
                block.move(posx, posy);
            } 
 
        </script>
    </body>
</html>

サンプル

揃った行が消えるようにする

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Sample</title>
    </head>
 
    <body onload="document.body.focus();" onkeydown="key(event.keyCode)">
        <script src="raphael.js"></script>
        <script>

            var paper = Raphael(0, 0, 500, 500);

            function Rect(x, y) {
                this.impl = paper.rect(0, 0, 20, 20).attr({ fill: 'pink', stroke: '#ff8888' });
                this.move(x, y);
            }

            Rect.prototype.move = function(x, y) {
                this.x = x;
                this.y = y;
                this.impl.attr({ x: this.x * 20, y: this.y * 20 });
            }

            Rect.prototype.die = function() {
                this.impl.attr({ fill: '#888888', stroke: '#444444' });
            }

            Rect.prototype.remove = function() {
                this.impl.remove();
            }

            function Block() {
                var block = Block.blocks[Math.floor(Math.random() * Block.blocks.length)];
                this.block = [];
                this.block.length = block.length;
                for (var y = 0; y < block.length; y ++) { 
                    this.block[y] = [];
                    this.block[y].length = block[y].length;
                    for (var x = 0; x < block[y].length; x ++) { 
                        this.block[y][x] = block[y][x] ? new Rect(x, y) : null;
                    } 
                }
            }

            Block.prototype.move = function(offx, offy) {
                this.x = offx;
                this.y = offy;
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.move(x + offx, y + offy);
                        }
                    } 
                }
            };

            Block.prototype.die = function() {
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        var rect = this.block[y][x]
                        if (rect) {
                            rect.die();
                        }
                    } 
                }
            };

            Block.prototype.calcRotate = function(dir) {
                var rotated = [];
                var i = 0;
                for (var x = 0; x < this.block[0].length; x ++) {
                    var rx = x;
                    rotated[rx] = []; 
                    for (var y = 0; y < this.block.length; y ++) { 
                        var ry = this.block.length - y - 1;
                        rotated[rx][ry] = this.block[y][x];
                    } 
                }
                return rotated;
            };

            Block.prototype.rotate = function() {
                this.block = this.calcRotate();
                for (var y = 0; y < this.block.length; y ++) { 
                    for (var x = 0; x < this.block[y].length; x ++) { 
                        if (this.block[y][x]) { 
                            this.block[y][x].move(x, y);
                        } 
                    } 
                }
            };
 
            Block.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]
                ]
            ];

            function Map() {
                this.map = [];
                for (var y = 0; y < 20; y++) {
                    this.map[y] = [];
                    for (var x = 0; x < 10; x++) {
                        this.map[y][x] = null;
                    }
                }
                this.impl = paper.rect(0, 0, 10 * 20, 20 * 20).attr({ stroke: '#cccccc', fill: '#cccccc' });
            }

            Map.prototype.check = function(block, offsetX, offsetY) {
                if (offsetX < 0 || offsetY < 0) {
                    return false;
                }
                for (var y = 0; y < block.length; y++) {
                    if (y + offsetY >= this.map.length) {
                        return false;
                    }
                    for (var x = 0; x < block[y].length; x++) {
                        if (x + offsetX >= this.map[y].length) {
                            return false;
                        }
                        if (block[y][x] && this.map[y + offsetY][x + offsetX]) {
                            return false;
                        }
                    }
                }
                return true;
            };

            Map.prototype.mergeBlock = function(block) {
                for (var y = 0; y < block.block.length; y++) {
                    for (var x = 0; x < block.block[y].length; x++) {
                        if (block.block[y][x]) {
                            this.map[y + block.y][x + block.x] = block.block[y][x];
                        }
                    }
                }
            };

            Map.prototype.clearRow = function() {
                for (var y = 0; y < this.map.length; y++) {
                    var full = true;
                    for (var x = 0; x < this.map[y].length; x++) {
                        if (!this.map[y][x]) {
                            full = false;
                            break;
                        }
                    }
                    if (full) {
                        for (var x = 0; x < this.map[y].length; x++) {
                            this.map[y][x].remove();
                            this.map[y][x] = null;
                        }
                        for (var cy = y - 1; cy >= 0; cy--) {
                            for (var x = 0; x < this.map[cy].length; x++) {
                                var rect = this.map[cy][x];
                                if (rect) {
                                    this.map[cy + 1][x] = rect;
                                    this.map[cy][x] = null;
                                    rect.move(x, cy + 1);
                                }
                            }
                        }
                    }
                }
            }

            var posx = 0, posy = 0;

            var map = new Map();

            var block = new Block();

            var id = setInterval(function() {
                posy++;
                if (map.check(block.block, posx, posy)) {
                    block.move(posx, posy);
                }
                else {
                    block.die();
                    map.mergeBlock(block);
                    map.clearRow();
                    block = new Block();
                    posx = 0;
                    posy = 0;
                    if (!map.check(block.block, posx, posy)) {
                        clearInterval(id);
                    }
                }
            }, 1000)
 
 
            function key(keyCode) { 
                switch (keyCode) { 
                    case 38: 
                        if (!map.check(block.calcRotate(), posx, posy)) { 
                            return;
                        } 
                        block.rotate();
                        break; 
                    case 39: 
                        if (!map.check(block.block, posx + 1, posy)) { 
                            return; 
                        } 
                        posx = posx + 1; 
                        break; 
                    case 37: 
                        if (!map.check(block.block, posx - 1, posy)) { 
                            return; 
                        } 
                        posx = posx - 1; 
                        break; 
                    case 40: 
                        var y = posy; 
                        while (map.check(block.block, posx, y)) { y++; } 
                        posy = y - 1; 
                        break; 
                    default: 
                        return; 
                } 
                block.move(posx, posy);
            } 
 
        </script>
    </body>
</html>

サンプル