### 中文介绍 请查看 [README.md](https://github.com/binaryify/vue-tetris/blob/master/README.md) ---- ## Use Vue, Vuex, Immutable to code Tetris. Inspired by [react-tetris]((https://github.com/chvin/react-tetris), cause I prefer Vue to React, so I use Vue to code it, my idea is to think of components and methods as functions, to ensure that an input (props/params) gets a determined output (view/return value), and use Vuex instead of Redux. Open [http://binaryify.github.io/vue-tetris/](http://binaryify.github.io/vue-tetris/) to play! ### Responsive ![Responsive](https://img.alicdn.com/tps/TB1AdjZNXXXXXcCapXXXXXXXXXX-480-343.gif) Not only refers to the screen adaptation, `but the change of input depending on your platform, use of the keyboard in the PC and in the phone using the touch as input`: ![phone](https://img.alicdn.com/tps/TB1kvJyOVXXXXbhaFXXXXXXXXXX-320-555.gif) ### Data persistence [video](https://www.youtube.com/watch?v=SzTNX7rg9Qg) What's the worst can happen when you're playing stand-alone games? Power outage. The state is stored in the `localStorage` by subscribing to `store.subscribe`, which records exactly all the state. Web page refreshes, the program crashes, the phone is dead, just re-open the connection and you can continue playing. ### Vuex state preview ([Vue DevTools extension](https://github.com/vuejs/vue-devtools)) ![preview](http://7xkm8j.com1.z0.glb.clouddn.com/vuex.gif) [video](https://www.youtube.com/watch?v=iuoSSTqSAUE) Vuex manages all the state that should be stored, which is a guarantee to be persisted as mentioned above. ---- The Game framework is the use of [Vue](https://github.com/vuejs/vue) + [Vuex](https://github.com/vuejs/vuex), together with [Immutable.js](https://facebook.github.io/immutable-js/). ## 1. What is Immutable.js? Immutable is data that can not be changed once it is created. Any modification or addition to or deletion of an Immutable object returns a new Immutable object. ### Acquaintance: Let's look at the following code: ``` JavaScript function keyLog(touchFn) { let data = { key: 'value' }; f(data); console.log(data.key); // Guess what will be printed? } ``` If we do not look at `f`, and do not know what it did to `data`, we can not confirm what will be printed. But if `data` is *Immutable*, you can be sure that `data` haven't changed and `value` is printed: ``` JavaScript function keyLog(touchFn) { let data = Immutable.Map({ key: 'value' }); f(data); console.log(data.get('key')); // value } ``` JavaScript uses a reference assignment, meaning that the new object simply refers to the original object, changing the new will also affect the old: ``` JavaScript foo = {a: 1}; bar = foo; bar.a = 2; foo.a // 2 ``` Although this can save memory, when the application is complex, it can result in the state not being controllable, posing a big risk. The advantages of saving memory, in this case, become more harm than good. With Immutable.js the same doesn't happen: ``` JavaScript foo = Immutable.Map({ a: 1 }); bar = foo.set('a', 2); foo.get('a') // 1 ``` ### About “===”: We know that ```===``` operator for the `Object` and `Array` compares the reference to the address of the object rather than its "value comparison", such as: ``` JavaScript {a:1, b:2, c:3} === {a:1, b:2, c:3}; // false [1, 2, [3, 4]] === [1, 2, [3, 4]]; // false ``` To achieve the above we could only `deepCopy` and `deepCompare` to traverse the objects, but this is not only cumbersome it also harms performance. Let's check `Immutable.js` approach! ``` JavaScript map1 = Immutable.Map({a:1, b:2, c:3}); map2 = Immutable.Map({a:1, b:2, c:3}); Immutable.is(map1, map2); // true // List1 = Immutable.List([1, 2, Immutable.List[3, 4]]); List1 = Immutable.fromJS([1, 2, [3, 4]]); List2 = Immutable.fromJS([1, 2, [3, 4]]); Immutable.is(List1, List2); // true ``` Immutable learning materials: * [Immutable.js](http://facebook.github.io/immutable-js/) ## 2. Web Audio Api There are many different sound effects in the game, but in fact we keep only a reference to a sound file: [/build/music.mp3](https://github.com/binaryify/vue-tetris/blob/master/build/music.mp3). With the help of `Web Audio Api`, you can play audio in millisecond precision, with a high frequency, which is not possible with the `