LoginSignup
19
12

More than 5 years have passed since last update.

vue.jsで作るテトリス

Posted at

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を保存しておけば
表示状態まで簡単に元通りに出来て便利です。

簡易版 デモ

index.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時間強で作ってみた【実況解説】」

19
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
12