vue.jsで作るテトリス

###Vue.jsのdata保存と復元
データ保存

````
this.saveData = JSON.stringify(this.$data);
````
復元

````
var obj = JSON.parse(this.saveData);
for (var k in obj) this[k] = obj[k];
````
初期値や任意の場所のdataを保存しておけば
表示状態まで簡単に元通りに出来て便利です。
### 簡易版　デモ
https://jsfiddle.net/kebvw0sh/1/

![index.jpeg](https://qiita-image-store.s3.amazonaws.com/0/54926/f917bc07-45f7-b881-1273-f578d6f4aeb3.jpeg)

```
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>vue.js 落ち物パズルゲーム</title>
<style>
.container {display: flex;}
.waku {width: 20px;height: 20px;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.min.js"></script>
</head>
<body>
<div id="app">
   <h3>vue.js 落ち物パズルゲーム</h3>
   <p>startを押してからキーボードの矢印キーで操作します</p>
   <input type="button" @click="startFn" value="START" v-if="gameStart == false">
   <p v-if="gameOver">GAME OVER</p>
   <div v-for="i in 20" class="container" v-if="gameStart">
      <div v-for="j in 10" class="waku" :style="{ backgroundColor: ['gray', 'green'][yx[i-1][j-1]] }">
         {{ yx[i-1][j-1] }}
      </div>
   </div>
</div>
<script>
var blocks = [
   [[0, 0], [1, 0], [0, 1], [1, 1]],  // square
   [[-1, 0], [0, 0], [1, 0], [2, 0]],  // tetris
   [[-1, 0], [0, 0], [0, 1], [1, 1]],  // key1
   [[-1, 1], [0, 1], [0, 0], [1, 0]],  // key2
   [[-1, 0], [0, 0], [1, 0], [-1, 1]],  // L1
   [[-1, 0], [0, 0], [1, 0], [1, 1]],  // L2
   [[-1, 0], [0, 0], [1, 0], [0, 1]],  // T
];

var vm = new Vue({
   el: '#app',
   data: {
      yx: [],
      block: [],
      blockX: 0,
      blockY: 0,
      blockMemo: [],
      timerID: null,
      gameStart: false,
      gameOver: false,
   },
   methods: {
      startFn: function() {
         for (var i = 0; i < 20; i++) {
            this.yx[i] = [];
            for (var j = 0; j < 10; j++) {
               this.yx[i][j] = 0;
            }
         }
         this.gameStart = true;
         this.createFn();
         this.timerID = setInterval(this.fallFn, 500);
      },
      keydownFn: function(rotate, dx, dy) {
         if (!this.gameOver && this.checkFn(rotate, dx, dy)) this.drawFn(rotate, dx, dy);
      },
      checkFn: function(rotate, dx, dy) {
         var yx = this.yx.map(v => v.slice());
         var block = this.block.map(v => v.slice());
         this.blockMemo.forEach(v => {
            yx[v[0]][v[1]] = 0;
         });
         if (rotate) block = block.map(v => [v[1] * -1, v[0]]);
         var flag = block.every(v => {
            var x = v[0] + this.blockX + dx;
            var y = v[1] + this.blockY + dy;
            return (y >= 0 && y < 20 && x >= 0 && x < 10 && yx[y][x] == 0);
         });
         return flag;
      },
      drawFn: function(rotate, dx, dy) {
         this.blockMemo.forEach(v => {
            this.yx[v[0]][v[1]] = 0;
         });
         this.blockMemo = [];
         if (rotate) this.block = this.block.map(v => [v[1] * -1, v[0]]);
         this.blockX += dx;
         this.blockY += dy;
         this.block.forEach(v => {
            if (this.yx[v[1] + this.blockY][v[0] + this.blockX] != 0) this.gameOver = true;
            this.yx[v[1] + this.blockY][v[0] + this.blockX] = 1;
            this.blockMemo.push([v[1] + this.blockY, v[0] + this.blockX]);
         });
         if (this.gameOver) clearInterval(this.timerID);
         this.yx.push();
      },
      createFn: function() {
         this.blockMemo = [];
         this.blockX = 4;
         this.blockY = 1;
         this.block = blocks[Math.floor(Math.random() * 7)].map(v => [v[0], v[1]]);
         this.drawFn(false, 0, 0);
      },
      deleteFn: function() {
         this.yx = this.yx.filter(v => (v.join("") != "1111111111"));
         while (this.yx.length < 20) {
            this.yx.unshift([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
         }
      },
      fallFn: function() {
         if (this.checkFn(false, 0, 1)) {
            this.drawFn(false, 0, 1);
         } else {
            this.deleteFn();
            this.createFn();
         }
      }
   },
});

document.onkeydown = function(e) {
   if (e.keyCode == 38) vm.keydownFn(true, 0, 0); //up
   else if (e.keyCode == 37) vm.keydownFn(false, -1, 0); //left
   else if (e.keyCode == 40) vm.keydownFn(false, 0, 1); //down
   else if (e.keyCode == 39) vm.keydownFn(false, 1, 0); //right
};
</script>
</body>
</html>
```
JavaScriptで落ち物パズルゲーム
http://pie.karou.jp/zh.html
### 参考
ニコニコ動画「テトリスを1時間強で作ってみた【実況解説】」