Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div class="column-container" id="Tetris">
  <div class="column-1">
    <canvas width="150" height="300" id="main-screen">error</canvas>
    <table>
      <tr>
        <td><i class="fas fa-arrow-alt-circle-left"></i><i class="fas fa-arrow-alt-circle-right"></i></td>
        <td>Move</td>
      </tr>
      <tr>
        <td><i class="fas fa-arrow-alt-circle-down"></i></td>
        <td>Decision</td>
      </tr>
      <tr>
        <td><i class="fas fa-arrow-alt-circle-up"></i></td>
        <td>Rotation</td>
      </tr>
    </table>
  </div>
  <div class="column-2">
    <div class="group">
      <p>Next</p>
      <canvas width="50" height="50" id="sub-screen">error</canvas>
    </div>
    <div class="group">
      <p>Score</p>
      <div id="score">
      </div>
    </div>
    <div class="group">
      <p id="play">Play</p>
    </div>
  </div>
  <canvas width="130" height="30" id="game-over">error</canvas>
</div>
<p class="credit">
  This Pen is based on <a href="https://codepen.io/hankuro/">Hankuro's</a> Pen <a href="https://codepen.io/hankuro/pen/pWjBgZ/">Tetris</a>.</p>
              
            
!

CSS

              
                @import url("https://fonts.googleapis.com/css?family=Merriweather|Merriweather+Sans");

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

* {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 16px;
  font-family: "Merriweather Sans", sans-serif;
  color: #1a237e;
}

body {
  background: #e8eaf6;
}

.column-container {
  width: 300px;
  height: 400px;
  margin: 25px auto;
  background-color: #9fa8da;
  border: 5px solid #5c6bc0;
  position: relative;
  border-radius: 5px;
  display: flex;
  flex-direction: row;
}

.column-1 {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 200px;
}

.column-1 table {
  text-align: center;
  width: 150px;
  margin: 10px 0 0;
}

.column-2 {
  display: flex;
  flex-direction: column;
  width: 100px;
  padding: 50px 0;
}

.column-2 .group {
  width: 75px;
}

.group p {
  width: 50px;
  padding: 10px 0;
}

#main-screen {
  margin: 10px 0 0;
  width: 150px;
  background-color: #1a237e;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
}

#sub-screen {
  background-color: #1a237e;
  border-radius: 5px;
  color: #ffffff;
  width: 50px;
}

#score {
  margin: 0 0 10px;
}

#play {
  background-color: #5c6bc0;
  margin: 0;
  width: 75px;
  border-radius: 5px;
  cursor: pointer;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  color: #ffffff;
}

#game-over {
  position: absolute;
  top: 200px;
  left: 32.5px;
  display: none;
}

.credit {
  text-align: center;
}
              
            
!

JS

              
                var Tetris = {
  WIDTH: 15,
  HEIGHT: 30,
  NEXT_WIDTH: 5,
  NEXT_HEIGHT: 5,
  BLOCK_SIZE: 10,
  piece_type: [
    [
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 0
        },
        {
          x: 1,
          y: 1
        }
      ]
    ], // O
    [
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 0,
          y: 2
        },
        {
          x: 0,
          y: 3
        }
      ],
      [
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 2,
          y: 1
        },
        {
          x: 3,
          y: 1
        }
      ]
    ], // I
    [
      [
        {
          x: 0,
          y: 1
        },
        {
          x: 0,
          y: 2
        },
        {
          x: 1,
          y: 0
        },
        {
          x: 1,
          y: 1
        }
      ],
      [
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 1,
          y: 2
        },
        {
          x: 2,
          y: 2
        }
      ]
    ], // Z
    [
      [
        {
          x: 1,
          y: 1
        },
        {
          x: 1,
          y: 2
        },
        {
          x: 0,
          y: 0
        },
        {
          x: 0,
          y: 1
        }
      ],
      [
        {
          x: 0,
          y: 2
        },
        {
          x: 1,
          y: 2
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 2,
          y: 1
        }
      ]
    ], // Backwards Z
    [
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 0,
          y: 2
        },
        {
          x: 1,
          y: 2
        }
      ],
      [
        {
          x: 0,
          y: 1
        },
        {
          x: 0,
          y: 2
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 2,
          y: 1
        }
      ],
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 1,
          y: 0
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 1,
          y: 2
        }
      ],
      [
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 2,
          y: 0
        },
        {
          x: 2,
          y: 1
        }
      ]
    ], // L
    [
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 0,
          y: 2
        },
        {
          x: 1,
          y: 0
        }
      ],
      [
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 2,
          y: 1
        },
        {
          x: 2,
          y: 2
        }
      ],
      [
        {
          x: 0,
          y: 2
        },
        {
          x: 1,
          y: 0
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 1,
          y: 2
        }
      ],
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 2,
          y: 1
        }
      ]
    ], // Backwards L
    [
      [
        {
          x: 1,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 2,
          y: 1
        }
      ],
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 0,
          y: 2
        }
      ],
      [
        {
          x: 0,
          y: 0
        },
        {
          x: 1,
          y: 0
        },
        {
          x: 2,
          y: 0
        },
        {
          x: 1,
          y: 1
        }
      ],
      [
        {
          x: 1,
          y: 0
        },
        {
          x: 0,
          y: 1
        },
        {
          x: 1,
          y: 1
        },
        {
          x: 1,
          y: 2
        }
      ]
    ] // T
  ],
  next_piece: [
    [
      {
        x: 15,
        y: 15
      },
      {
        x: 25,
        y: 15
      },
      {
        x: 15,
        y: 25
      },
      {
        x: 25,
        y: 25
      }
    ], // O
    [
      {
        x: 20,
        y: 5
      },
      {
        x: 20,
        y: 15
      },
      {
        x: 20,
        y: 25
      },
      {
        x: 20,
        y: 35
      }
    ], // I
    [
      {
        x: 25,
        y: 10
      },
      {
        x: 15,
        y: 20
      },
      {
        x: 25,
        y: 20
      },
      {
        x: 15,
        y: 30
      }
    ], // Z
    [
      {
        x: 15,
        y: 10
      },
      {
        x: 15,
        y: 20
      },
      {
        x: 25,
        y: 20
      },
      {
        x: 25,
        y: 30
      }
    ], // Backwards Z
    [
      {
        x: 15,
        y: 10
      },
      {
        x: 15,
        y: 20
      },
      {
        x: 15,
        y: 30
      },
      {
        x: 25,
        y: 30
      }
    ], // L
    [
      {
        x: 25,
        y: 10
      },
      {
        x: 25,
        y: 20
      },
      {
        x: 25,
        y: 30
      },
      {
        x: 15,
        y: 30
      }
    ], // Backwards L
    [
      {
        x: 20,
        y: 15
      },
      {
        x: 10,
        y: 25
      },
      {
        x: 20,
        y: 25
      },
      {
        x: 30,
        y: 25
      }
    ] // T
  ],
  lock: false,
  stop: false,
  piece_color: [
    "#FFEB3B",
    "#009688",
    "#F44336",
    "#8BC34A",
    "#FF9800",
    "#2196F3",
    "#9C27B0"
  ],
  Tetris_piece: null,
  Tetris_current_canvas: null,
  Tetris_next_canvas: null,
  Tetris_current_size: null,
  Tetris_next_size: null,
  ready_sw: false,
  level_time: 800,
  level_cnt: 5,
  key_code: {
    UP: 38,
    DOWN: 40,
    LEFT: 37,
    RIGHT: 39,
    BACKSPACE: 8,
    ESC: 27,
    ENTER: 13,
    DELETE: 46,
    TAB: 9,
    DOUBLE: 50,
    SINGLE: 55,
    SPACE: 32
  },
  defineClass: function(constructor, methos, statics) {
    if (methos) this.extend(constructor.prototype, methos);
    if (statics) this.extend(constructor, statics);
    return constructor;
  },
  extend: function(o, p) {
    for (prop in p) o[prop] = p[prop];
    return o;
  },
  log: function(msg) {
    if (!msg) return;
    if (window.console && window.console.log) {
      window.console.log(msg);
    }
  }
};

/*Tetris Piece Class*/

Tetris.Piece = Tetris.defineClass(
  function(type, color, n) {
    this.type = type;
    this.color = color;
    this.no = n;
    this.next = Tetris.next_piece[this.no];
    this.index = 0;
    this.position = {
      x: 0,
      y: 0
    };
  },
  {
    set_position: function(x, y) {
      this.position.x = x;
      this.position.y = y;
      if (this.end_down()) Tetris.Control.game_over = true;
    },
    check_down: function() {
      if (this.end_down()) return true;
      this.position.y++;
      return false;
    },
    end_down: function() {
      var pos = this.get_position(),
        i;
      var check = false;
      for (i = 0; i < pos.length; i++) {
        if (pos[i].y + 1 >= Tetris.HEIGHT) return true;
        if (Tetris.Tetris_piece[pos[i].y + 1][pos[i].x] != -1) return true;
      }
      return false;
    },
    set_piece: function() {
      var pos = this.get_position();
      var no = this.no;
      pos.forEach(function(e, i, a) {
        Tetris.Tetris_piece[e.y][e.x] = no;
      });
    },
    down_piece: function() {
      var i;
      for (i = 0; i < 3; i++) {
        if (this.check_down()) {
          return true;
        }
      }
      return false;
    },
    current_draw: function() {
      var pos = this.get_position();
      var color = this.color;
      pos.forEach(function(e, i, a) {
        Tetris.Control.current_draw(e.x, e.y, color);
      });
    },
    next_draw: function() {
      var color = this.color;
      this.next.forEach(function(e, i, a) {
        Tetris.Control.next_draw(e.x, e.y, color);
      });
    },
    get_position: function() {
      var pos = [];
      var position = this.position;
      this.type[this.index].forEach(function(e, i, a) {
        pos.push({
          x: e.x + position.x,
          y: e.y + position.y
        });
      });
      return pos;
    },
    get_size: function() {
      var size = this.get_rect();
      return {
        width: size.right.x + 1,
        height: size.bottom.y + 1
      };
    },
    get_rect: function() {
      var left = {
          x: 0,
          y: 0
        },
        right = {
          x: 0,
          y: 0
        },
        top = {
          x: 0,
          y: 0
        },
        bottom = {
          x: 0,
          y: 0
        };
      this.type[this.index].forEach(function(e, i, a) {
        if (e.x < left.x) Tetris.extend(left, e);
        if (e.x > right.x) Tetris.extend(right, e);
        if (e.y > bottom.y) Tetris.extend(bottom, e);
      });
      return {
        left: left,
        right: right,
        top: top,
        bottom: bottom
      };
    },
    left: function() {
      var pos = this.get_position(),
        i;
      for (i = 0; i < pos.length; i++) {
        if (pos[i].x - 1 < 0) {
          return false;
        }
        if (Tetris.Tetris_piece[pos[i].y][pos[i].x - 1] != -1) {
          return false;
        }
      }
      this.position.x--;
      return true;
    },
    right: function() {
      var pos = this.get_position(),
        i;
      for (i = 0; i < pos.length; i++) {
        if (pos[i].x + 2 > Tetris.WIDTH) {
          return false;
        }
        if (Tetris.Tetris_piece[pos[i].y][pos[i].x + 1] != -1) {
          return false;
        }
      }
      this.position.x++;
      return true;
    },
    rotation: function() {
      var save_index = this.index,
        i,
        check_out = false;
      this.index = (this.index + 1) % this.type.length;
      var pos = this.get_position();
      for (i = 0; i < pos.length; i++) {
        if (pos[i].x < 0) {
          check_out = true;
          break;
        }
        if (Tetris.Tetris_piece[pos[i].y][pos[i].x] != -1) {
          check_out = true;
          break;
        }
        if (pos[i].x + 1 > Tetris.WIDTH) {
          check_out = true;
          break;
        }
        if (Tetris.Tetris_piece[pos[i].y][pos[i].x] != -1) {
          check_out = true;
          break;
        }
        if (pos[i].y >= Tetris.HEIGHT) {
          check_out = true;
          break;
        }
        if (Tetris.Tetris_piece[pos[i].y][pos[i].x] != -1) {
          check_out = true;
          break;
        }
      }
      if (check_out) {
        this.index = save_index;
        return false;
      }
      return true;
    }
  }
);

/*Tetris Control*/

Tetris.Control = {
  setup: function() {
    var tetris = Tetris;
    Tetris.Timer.setup();
    Tetris.KeyBoard.setup();
    Tetris.Tetris_current_canvas = $("#main-screen")[0].getContext("2d");
    Tetris.Tetris_next_canvas = $("#sub-screen")[0].getContext("2d");
    Tetris.Tetris_current_size = get_size("main-screen");
    Tetris.Tetris_next_size = get_size("sub-screen");
    Tetris.KeyBoard.add({
      object: this,
      id: "DOWN",
      post: this.keydown.bind(this)
    });
    Tetris.KeyBoard.add({
      object: this,
      id: "RIGHT",
      post: this.keyright.bind(this)
    });
    Tetris.KeyBoard.add({
      object: this,
      id: "LEFT",
      post: this.keyleft.bind(this)
    });
    Tetris.KeyBoard.add({
      object: this,
      id: "SPACE",
      post: this.keyspace.bind(this)
    });
    Tetris.KeyBoard.add({
      object: this,
      id: "UP",
      post: this.keyspace.bind(this)
    });
    this.lock = true;

    function get_size(p) {
      var w = $("#" + p)[0].width;
      var h = $("#" + p)[0].height;
      return {
        w: w,
        h: h
      };
    }
  },
  game_start: function() {
    this.init_screen();
    this.screen_clear();
    this.lock = false;
    this.game_over = false;
    this.now_time = new Date().getTime();
    Tetris.Timer.remove(this);
    Tetris.Timer.add({
      object: this,
      post: this.onLoop.bind(this)
    });
    Tetris.Score.setup();
    this.level_time = Tetris.level_time;
    this.level_cnt = Tetris.level_cnt;
    var current = this.random(),
      next = this.random();
    this.current_piece = new Tetris.Piece(
      Tetris.piece_type[current],
      Tetris.piece_color[current],
      current
    );
    this.next_piece = new Tetris.Piece(
      Tetris.piece_type[next],
      Tetris.piece_color[next],
      next
    );
    var y = 0;
    var x = Math.floor(
      Tetris.WIDTH / 2 - this.current_piece.get_size().width / 2
    );
    this.current_piece.set_position(x, y);
    this.onLoop();
  },
  init_screen: function() {
    var i, j;
    Tetris.Tetris_piece = [];
    for (i = 0; i < Tetris.HEIGHT; i++) {
      Tetris.Tetris_piece[i] = [];
      for (j = 0; j < Tetris.WIDTH; j++) {
        Tetris.Tetris_piece[i][j] = -1;
      }
    }
  },
  screen_clear: function() {
    Tetris.Tetris_current_canvas.clearRect(
      0,
      0,
      Tetris.Tetris_current_size.w,
      Tetris.Tetris_current_size.h
    );
    Tetris.Tetris_next_canvas.clearRect(
      0,
      0,
      Tetris.Tetris_next_size.w,
      Tetris.Tetris_next_size.h
    );
  },
  onLoop: function() {
    var now = new Date().getTime();
    if (now - this.now_time < this.level_time) return;
    this.now_time = now;
    this.draw();
    if (this.lock) return;
    if (this.current_piece.check_down()) this.set_next();
    this.line_check();
  },
  keydown: function() {
    if (this.lock) return;
    this.down_key();
  },
  keyright: function() {
    if (this.lock) return;
    if (this.current_piece.right()) this.draw();
  },
  keyleft: function() {
    if (this.lock) return;
    if (this.current_piece.left()) this.draw();
  },
  keyspace: function() {
    if (this.lock) return;
    if (this.current_piece.rotation()) this.draw();
  },
  down_key: function() {
    this.down_sw = true;
    this.lock = true;
    var timer_id = {};
    var key_down = {
      object: timer_id,
      post: function() {
        if (this.current_piece.down_piece()) {
          this.draw();
          this.lock = false;
          Tetris.Timer.remove(timer_id);
          return;
        }
        this.draw();
      }.bind(this)
    };
    Tetris.Timer.add(key_down);
  },
  set_next: function() {
    this.current_piece.set_piece();
    var next = this.random();
    this.current_piece = this.next_piece;
    this.next_piece = new Tetris.Piece(
      Tetris.piece_type[next],
      Tetris.piece_color[next],
      next
    );
    var y = 0;
    var x = Math.floor(Tetris.WIDTH / 2 - this.next_piece.get_size().width / 2);
    this.current_piece.set_position(x, y);
    this.draw();
    if (this.game_over) this.gameOver();
  },
  line_check: function() {
    var i;
    for (i = Tetris.HEIGHT - 1; i > 0; i--) {
      if (this.check_block(i)) {
        this.line_light(
          i,
          function() {
            Tetris.Score.add();
            this.timer_down();
            this.line_clear(i);
            this.draw();
            this.block_down(i);
          }.bind(this)
        );
        return;
      }
    }
  },
  timer_down: function() {
    if (this.level_cnt - 1 < 0) {
      this.level_cnt = Tetris.level_cnt;
      if (this.level_time - 100 > 100) {
        this.level_time -= 200;
      }
    } else this.level_cnt--;
  },
  line_light: function(i, p) {
    var line = i,
      post = p;
    var timer_id = {};
    var index = 0;
    this.lock = true;
    var ligth_timer = {
      object: timer_id,
      post: function() {
        if (index + 1 == Tetris.WIDTH) {
          Tetris.Timer.remove(timer_id);
          this.lock = false;
          post();
          return;
        }
        Tetris.Tetris_piece[line][index++] = -1;
        this.draw();
      }.bind(this)
    };
    Tetris.Timer.add(ligth_timer);
  },
  line_clear: function(line) {
    var i;
    for (i = 0; i < Tetris.WIDTH; i++) {
      Tetris.Tetris_piece[line][i] = -1;
    }
  },
  block_down: function(n) {
    var line = n,
      timer,
      i,
      end_block = false;
    var timer_id = {};
    var now_time = new Date().getTime();
    var block_down = {
      object: timer_id,
      post: function() {
        var now = new Date().getTime();
        if (now - now_time < 30) return;
        now_time = now;
        var down_line = line - 1;
        if (this.check_off_block(down_line)) end_block = true;
        for (i = 0; i < Tetris.WIDTH; i++) {
          Tetris.Tetris_piece[line][i] = Tetris.Tetris_piece[down_line][i];
        }
        this.line_clear(down_line);
        if (end_block) {
          Tetris.Timer.remove(timer_id);
          this.lock = false;
          this.line_check();
          return;
        }
        line--;
        this.draw();
      }.bind(this)
    };
    Tetris.Timer.add(block_down);
    this.lock = true;
  },
  check_block: function(line) {
    var i;
    for (i = 0; i < Tetris.WIDTH; i++) {
      if (Tetris.Tetris_piece[line][i] == -1) return false;
    }
    return true;
  },
  check_off_block: function(line) {
    var i;
    for (i = 0; i < Tetris.WIDTH; i++) {
      if (Tetris.Tetris_piece[line][i] != -1) return false;
    }
    return true;
  },
  gameOver: function() {
    this.lock = true;
    $("#game-over").fadeIn("slow");
    $("#play").fadeIn("slow");
  },
  random: function() {
    var no = Math.floor(Math.random() * 10);
    return no % Tetris.piece_type.length;
  },
  draw: function() {
    this.screen_clear();
    this.current_piece.current_draw();
    this.next_piece.next_draw();
    var y, x;
    for (y = 0; y < Tetris.HEIGHT; y++) {
      for (x = 0; x < Tetris.WIDTH; x++) {
        var index = Tetris.Tetris_piece[y][x];
        if (index != -1) {
          var color = Tetris.piece_color[index];
          this.current_draw(x, y, color);
        }
      }
    }
  },
  current_draw: function(x, y, c) {
    var current_x = x * Tetris.BLOCK_SIZE;
    var current_y = y * Tetris.BLOCK_SIZE;
    Tetris.Tetris_current_canvas.fillStyle = c;
    Tetris.Tetris_current_canvas.fillRect(
      current_x,
      current_y,
      Tetris.BLOCK_SIZE,
      Tetris.BLOCK_SIZE
    );
  },
  next_draw: function(x, y, c) {
    Tetris.Tetris_next_canvas.fillStyle = c;
    Tetris.Tetris_next_canvas.fillRect(
      x,
      y,
      Tetris.BLOCK_SIZE,
      Tetris.BLOCK_SIZE
    );
  }
};

/*KeyBoard Task*/

Tetris.KeyBoard = {
  setup: function() {
    window.focus();
    this.qt = [];
    this.down_sw = false;
    $(document).bind("keydown", this.keydown.bind(this));
    $(document).bind(
      "keyup",
      function() {
        window.focus();
        this.down_sw = false;
      }.bind(this)
    );
  },
  add: function(p) {
    var evet = Tetris.extend(
      {
        object: null,
        id: null,
        post: null
      },
      p || {}
    );
    this.qt.push(evet);
  },
  remove: function(p) {
    for (var i = 0; i < this.qt.length; i++) {
      if (this.qt[i].object == p) {
        this.qt.splice(i, 1);
        break;
      }
    }
  },
  keydown: function(e) {
    if (this.down_sw) return;
    window.focus();
    switch (e.keyCode) {
      case Tetris.key_code.UP:
        this.post("UP");
        return false;
      case Tetris.key_code.DOWN:
        this.post("DOWN");
        return false;
      case Tetris.key_code.RIGHT:
        this.post("RIGHT");
        return false;
      case Tetris.key_code.LEFT:
        this.post("LEFT");
        return false;
      case Tetris.key_code.SPACE:
        this.post("UP");
        return false;
    }
  },
  post: function(i) {
    var id = i;
    this.qt.forEach(function(e, i, a) {
      if (e.id == id) e.post();
    });
  }
};

/*Timer Task*/

Tetris.Timer = {
  setup: function() {
    this.qt = [];
    this.timer = setInterval(this.onLoop.bind(this), 33);
  },
  add: function(p) {
    var evet = Tetris.extend(
      {
        object: null,
        post: null
      },
      p || {}
    );
    this.qt.push(evet);
  },
  remove: function(p) {
    for (var i = 0; i < this.qt.length; i++) {
      if (this.qt[i].object == p) {
        this.qt.splice(i, 1);
        break;
      }
    }
  },
  onLoop: function() {
    this.qt.forEach(function(e, i, a) {
      e.post();
    });
  }
};

/*Score Task*/

Tetris.Score = {
  setup: function() {
    this.qt = [];
    this.score = 0;
    this.current_dom = $("<p>")
      .text("00000")
      .css({
        position: "relative",
        width: "75px",
        height: "35px",
        paddingLeft: "5px",
        paddingRight: "5px",
        backgroundColor: "#ffffff"
      })
      .appendTo("#score");
    this.lock = false;
  },
  add: function() {
    this.score += 10;
    var data = "00000" + String(this.score);
    var pos = data.length - 5;
    data = data.substring(pos);
    var dom = $("<p>")
      .text(data)
      .css({
        position: "relative",
        width: "75px",
        height: "35px",
        paddingLeft: "5px",
        paddingRight: "5px",
        backgroundColor: "#ffffff"
      });
    this.qt.push(dom);
    this.score_up();
  },
  score_up: function() {
    if (this.qt.length != 0 && !this.lock) {
      this.lock = true;
      var dom = this.qt.shift();
      $(dom).appendTo("#score");
      $(dom).animate(
        {
          top: 0
        },
        {
          duration: 1000,
          complete: function() {
            this.lock = false;
            $(this.current_dom).remove();
            this.current_dom = dom;
            if (this.qt.length != 0) this.score_up();
          }.bind(this)
        }
      );
    }
  }
};

/*Game Over*/

Tetris.GameOver = function() {
  var Context = $("#game-over")[0].getContext("2d");
  $("#game-over").hide();
  Context.font = "24px Merriweather Sans";
  Context.fillStyle = "#ffffff";
  Context.textBaseline = "top";
  Context.fillText("Game Over", 0, 0);
};

/*OnLoad*/
$(function() {
  Tetris.Control.setup();
  Tetris.GameOver();
  $("#play").click(function() {
    $(this).fadeOut("slow");
    $("#game-over").fadeOut("slow");
    Tetris.Control.game_start();
  });
});

              
            
!
999px

Console