improve
This commit is contained in:
72
README-EN.md
72
README-EN.md
@@ -2,7 +2,7 @@
|
||||
请查看 [README.md](https://github.com/binaryify/vue-tetris/blob/master/README.md)
|
||||
|
||||
----
|
||||
## Use Vue, Vuex, Immutable to code Tetris.
|
||||
## Use Vue, Vuex 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!
|
||||
@@ -28,67 +28,13 @@ What's the worst can happen when you're playing stand-alone games? Power outage.
|
||||
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/).
|
||||
The Game framework is the use of [Vue](https://github.com/vuejs/vue) + [Vuex](https://github.com/vuejs/vuex)
|
||||
|
||||
|
||||
## 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
|
||||
## 1. 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 `<audio>` tag. Press the arrow keys to move the box while the game is in progress, you can hear high-frequency sound.
|
||||
|
||||

|
||||
@@ -133,13 +79,11 @@ Web Audio Api learning materials:
|
||||
## 4. Experience in Development
|
||||
The Vue version and the React version of the core code are essentially the same, but there are a few problems when writing components, such as:
|
||||
|
||||
1. React version store uses the immutable data structure, the store on the vuex if you use the immutable structure, not use to monitor data changes, so all the data in the store to use the common data, in the place where need these data provided by immutable fromJS conversion, where need common data is converted to common data, through the immutable toJS in the process of actual refactoring, I try to stay away from the core game logic, actually I didn't understand the game implementation logic is in the reconstruction of the complete, just ensure the consistency of input and output method, just be patience
|
||||
1. How to rewrite the React components into the Vue, my train of thought is to put the components as a function, ensure that an input (props) can get a certain output (view), and then do the same with different methods is also, React setState would trigger the render method, so can be defined in the methods from the render method to manually trigger the render method after the state change
|
||||
|
||||
2. How to rewrite the React components into the Vue, my train of thought is to put the components as a function, ensure that an input (props) can get a certain output (view), and then do the same with different methods is also, React setState would trigger the render method, so can be defined in the methods from the render method to manually trigger the render method after the state change
|
||||
2. Life cycle, in simple terms, the React of corresponding Vue componentWillMount beforeMount, React componentDidMount corresponding Vue mounted, React to optimize the performance of shouldComponentUpdate in Vue does not need, does not need manual optimization is one of the reason that I like the Vue
|
||||
|
||||
3. Life cycle, in simple terms, the React of corresponding Vue componentWillMount beforeMount, React componentDidMount corresponding Vue mounted, React to optimize the performance of shouldComponentUpdate in Vue does not need, does not need manual optimization is one of the reason that I like the Vue
|
||||
|
||||
4. Vue does not have the React component of componentWillReceiveProps' life cycle, and my solution is to use watch to work with deep: true to listen for changes in props such as:
|
||||
3. Vue does not have the React component of componentWillReceiveProps' life cycle, and my solution is to use watch to work with deep: true to listen for changes in props such as:
|
||||
```js
|
||||
watch: {
|
||||
$props: {
|
||||
@@ -151,7 +95,7 @@ The Vue version and the React version of the core code are essentially the same,
|
||||
}
|
||||
```
|
||||
|
||||
5. Usx jsx and 'render' functions when necessary, yes, Vue support jsx, in this project, matrix component logic is more complex, the use of template template to render components has been inappropriate, React each setState will trigger 'render' method, so we can customize the 'render' method in the methods customizing the 'render' method after the state changes, but this method will become cumbersome for components with complex logic, and my solution is through the Vue jsx conversion Plugin [babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx) to use the jsx syntax to render the page, when the props or state changes automatically trigger 'render' method, the other to note that the Vue jsx and React jsx write a little difference , the template syntax will be invalidated when the 'render' method exists. The 'render' function is a useful utility in developing a file like a [React-log](https://github.com/diegomura/react-log) that does not need to render html only need to execute some methods. , Because this time does not need to render dom, and if the 'render' function, simply in the 'render' function in the return False on the line, such as: [React-log](https://github.com/diegomura/react-log/blob/b1bb695a6997cd1be399170186cf6ff1e27393d7/src/Log.js#L33)
|
||||
4. Usx jsx and 'render' functions when necessary, yes, Vue support jsx, in this project, matrix component logic is more complex, the use of template template to render components has been inappropriate, React each setState will trigger 'render' method, so we can customize the 'render' method in the methods customizing the 'render' method after the state changes, but this method will become cumbersome for components with complex logic, and my solution is through the Vue jsx conversion Plugin [babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx) to use the jsx syntax to render the page, when the props or state changes automatically trigger 'render' method, the other to note that the Vue jsx and React jsx write a little difference , the template syntax will be invalidated when the 'render' method exists. The 'render' function is a useful utility in developing a file like a [React-log](https://github.com/diegomura/react-log) that does not need to render html only need to execute some methods. , Because this time does not need to render dom, and if the 'render' function, simply in the 'render' function in the return False on the line, such as: [React-log](https://github.com/diegomura/react-log/blob/b1bb695a6997cd1be399170186cf6ff1e27393d7/src/Log.js#L33)
|
||||
|
||||
[http://localhost:8080](http://localhost:8080)
|
||||
|
||||
|
||||
72
README.md
72
README.md
@@ -1,7 +1,7 @@
|
||||
### English introduction
|
||||
Please view [README.md](https://github.com/Binaryify/vue-tetris/blob/master/README-EN.md)
|
||||
|
||||
## 用Vue、Vuex、Immutable做俄罗斯方块
|
||||
## 用Vue、Vuex 做俄罗斯方块
|
||||
|
||||
----
|
||||
本项目灵感来源于 React 版的[俄罗斯方块](https://github.com/chvin/react-tetris),由于对其实现原理较感兴趣,而且相比于 React 更喜欢 Vue, 于是把 React 版的重构为了 Vue 版的,大致思路是把组件当成一个个函数,保证一个输入(props)能得到一个确定的输出(view),然后对不同方法也是做同样处理,对于 Redux 使用 Vuex 精简化
|
||||
@@ -35,69 +35,13 @@ Please view [README.md](https://github.com/Binaryify/vue-tetris/blob/master/READ
|
||||
Vuex 设计管理了所有应存的状态,这是上面持久化的保证。
|
||||
|
||||
----
|
||||
游戏框架使用的是 [Vue](https://github.com/vuejs/vue) + [Vuex](https://github.com/vuejs/vuex),其中再加入了 [Immutable.js](https://facebook.github.io/immutable-js/),确保性能和数据可靠性
|
||||
游戏框架使用的是 [Vue](https://github.com/vuejs/vue) + [Vuex](https://github.com/vuejs/vuex)
|
||||
|
||||
|
||||
## 1、什么是 Immutable?
|
||||
Immutable 是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。
|
||||
|
||||
### 初识:
|
||||
让我们看下面一段代码:
|
||||
``` JavaScript
|
||||
function keyLog(touchFn) {
|
||||
let data = { key: 'value' };
|
||||
f(data);
|
||||
console.log(data.key); // 猜猜会打印什么?
|
||||
}
|
||||
```
|
||||
不查看f,不知道它对 `data` 做了什么,无法确认会打印什么。但如果 `data` 是 Immutable,你可以确定打印的是 `value`:
|
||||
``` JavaScript
|
||||
function keyLog(touchFn) {
|
||||
let data = Immutable.Map({ key: 'value' });
|
||||
f(data);
|
||||
console.log(data.get('key')); // value
|
||||
}
|
||||
```
|
||||
|
||||
JavaScript 中的`Object`与`Array`等使用的是引用赋值,新的对象简单的引用了原始对象,改变新也将影响旧的:
|
||||
``` JavaScript
|
||||
foo = {a: 1}; bar = foo; bar.a = 2;
|
||||
foo.a // 2
|
||||
```
|
||||
虽然这样做可以节约内存,但当应用复杂后,造成了状态不可控,是很大的隐患,节约的内存优点变得得不偿失。
|
||||
|
||||
Immutable则不一样,相应的:
|
||||
``` JavaScript
|
||||
foo = Immutable.Map({ a: 1 }); bar = foo.set('a', 2);
|
||||
foo.get('a') // 1
|
||||
```
|
||||
|
||||
### 关于 “===”:
|
||||
我们知道对于`Object`与`Array`的`===`比较,是对引用地址的比较而不是“值比较”,如:
|
||||
``` JavaScript
|
||||
{a:1, b:2, c:3} === {a:1, b:2, c:3}; // false
|
||||
[1, 2, [3, 4]] === [1, 2, [3, 4]]; // false
|
||||
```
|
||||
对于上面只能采用 `deepCopy`、`deepCompare`来遍历比较,不仅麻烦且好性能。
|
||||
|
||||
我们感受来一下`Immutable`的做法!
|
||||
``` 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学习资料:
|
||||
* [Immutable.js](http://facebook.github.io/immutable-js/)
|
||||
|
||||
|
||||
## 2、Web Audio Api
|
||||
## 1、Web Audio Api
|
||||
游戏里有很多不同的音效,而实际上只引用了一个音效文件:[/build/music.mp3](https://github.com/Binaryify/vue-tetris/blob/master/build/music.mp3)。借助`Web Audio Api`能够以毫秒级精确、高频率的播放音效,这是`<audio>`标签所做不到的。在游戏进行中按住方向键移动方块,便可以听到高频率的音效。
|
||||
|
||||

|
||||
@@ -140,13 +84,11 @@ Web Audio Api 学习资料:
|
||||
## 4、开发中的经验梳理,以及如何把 React 项目重构为 Vue 版本
|
||||
Vue 版本和 React 版本核心代码基本相同,但在编写组件的时候遇到了几个问题,比如:
|
||||
|
||||
1. React 版的 store 使用了 immutable 结构的数据,vuex 上的 store 如果使用了 immutable 结构,不利用监听数据变化,故把store 的数据全部使用了普通的数据,在需要这些数据的地方通过 immutable 提供的 `fromJS` 转换,在需要普通数据的地方再通过 immutable 的 `toJS` 转换成普通数据,在实际重构过程中,我尽量避开了核心游戏实现逻辑,实际上我是在没弄懂游戏实现逻辑的情况下完成重构的,只是保证了方法的输入和输出的一致性,要做的只是耐心
|
||||
1. 如何把 React 组件改写成 Vue 的,我的思路是把组件当成函数,保证一个输入(props)能得到一个确定的输出(view),然后对不同方法也是做同样处理, React 的 setState 会触发 render 方法,所以可以在 methods 自定义 render 方法再在 state 变化后手动触发 render 方法
|
||||
|
||||
2. 如何把 React 组件改写成 Vue 的,我的思路是把组件当成函数,保证一个输入(props)能得到一个确定的输出(view),然后对不同方法也是做同样处理, React 的 setState 会触发 render 方法,所以可以在 methods 自定义 render 方法再在 state 变化后手动触发 render 方法
|
||||
2. 生命周期,简单来说, React 的 `componentWillMount` 对应 Vue 的 `beforeMount`, React 的 `componentDidMount` 对应 Vue 的 `mounted`,React 的用来优化性能的 `shouldComponentUpdate` 在 Vue 里并不需要,不需要手动优化这也是我喜欢 Vue 的一点
|
||||
|
||||
3. 生命周期,简单来说, React 的 `componentWillMount` 对应 Vue 的 `beforeMount`, React 的 `componentDidMount` 对应 Vue 的 `mounted`,React 的用来优化性能的 `shouldComponentUpdate` 在 Vue 里并不需要,不需要手动优化这也是我喜欢 Vue 的一点
|
||||
|
||||
4. Vue 没有 React 的`componentWillReceiveProps` 的生命周期,我的解决方法是使用 watch 配合 `deep:true` 来监听 props 的变化,如:
|
||||
3. Vue 没有 React 的`componentWillReceiveProps` 的生命周期,我的解决方法是使用 watch 配合 `deep:true` 来监听 props 的变化,如:
|
||||
```js
|
||||
watch: {
|
||||
$props: {
|
||||
@@ -158,7 +100,7 @@ Vue 版本和 React 版本核心代码基本相同,但在编写组件的时候
|
||||
}
|
||||
```
|
||||
|
||||
5. 在必要时候使用 jsx 和 'render' 函数,是的, vue 支持 jsx,在这个项目中`matrix 组件` 的功能逻辑较复杂,使用 `template` 模版来渲染组件已经不合适了, React 每次 setState 会触发 'render' 方法,所以我们可以在 methods自定义 'render' 方法再在 state 变化后手动触发 'render' 方法,但是这个方法对有复杂逻辑的组件来说会变得很繁琐,我的解决方法是通过 Vue 的 jsx 转换插件[babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)来使用 jsx 语法对页面进行渲染,当 props 或 state 变化了自动触发 'render' 方法,另外要注意的是 vue 的 jsx 和 React 的 jsx 书写上有一点的差异, 当 'render' 方法存在时,template 语法会失效. 'render' 函数一个比较实用的用处是在开发类似 React-log 之类的不需要渲染 html 只需要执行一些方法的组件时 template 会显得很多余,因为这时候并不需要渲染 dom 了,如果用了 'render' 函数,简单的在 'render' 函数里 return false 就行,如: [react-log](https://github.com/diegomura/react-log/blob/b1bb695a6997cd1be399170186cf6ff1e27393d7/src/Log.js#L33)
|
||||
4. 在必要时候使用 jsx 和 'render' 函数,是的, vue 支持 jsx,在这个项目中`matrix 组件` 的功能逻辑较复杂,使用 `template` 模版来渲染组件已经不合适了, React 每次 setState 会触发 'render' 方法,所以我们可以在 methods自定义 'render' 方法再在 state 变化后手动触发 'render' 方法,但是这个方法对有复杂逻辑的组件来说会变得很繁琐,我的解决方法是通过 Vue 的 jsx 转换插件[babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)来使用 jsx 语法对页面进行渲染,当 props 或 state 变化了自动触发 'render' 方法,另外要注意的是 vue 的 jsx 和 React 的 jsx 书写上有一点的差异, 当 'render' 方法存在时,template 语法会失效. 'render' 函数一个比较实用的用处是在开发类似 React-log 之类的不需要渲染 html 只需要执行一些方法的组件时 template 会显得很多余,因为这时候并不需要渲染 dom 了,如果用了 'render' 函数,简单的在 'render' 函数里 return false 就行,如: [react-log](https://github.com/diegomura/react-log/blob/b1bb695a6997cd1be399170186cf6ff1e27393d7/src/Log.js#L33)
|
||||
|
||||
## 5、架构差异
|
||||
Redux 的数据流向是通过 `mapStateToProps` 把 store 的状态转化为 props 然后通过`connect` 函数注入到 根组件,根组件再把这些 props 传入不同组件,当 store 的状态变化,根组件会重新 render, 更新子组件上的 props,子组件再 根据新 props重新 render
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
<head>
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="description" content="使用 Vue、Vuex、Immutable制作的俄罗斯方块" />
|
||||
<meta name="keywords" content="俄罗斯方块,Tetris,Vue,Vuex,Immuatble,JavaScript">
|
||||
<meta name="description" content="使用 Vue、Vuex 制作的俄罗斯方块" />
|
||||
<meta name="keywords" content="俄罗斯方块,Tetris,Vue,Vuex,JavaScript">
|
||||
<meta name="format-detection" content="telephone=no"/>
|
||||
<script>;(function(){var w=parseInt(window.screen.width),s=w/640,u=navigator.userAgent.toLowerCase(),m='<meta name="viewport" content="width=640,';if(/android (\d+\.\d+)/.test(u)){if(parseFloat(RegExp.$1)>2.3)m+='minimum-scale='+s+',maximum-scale='+s+',';}else{m+='user-scalable=no,';}m+='target-densitydpi=device-dpi">';document.write(m);}());</script>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
5
package-lock.json
generated
5
package-lock.json
generated
@@ -2607,11 +2607,6 @@
|
||||
"integrity": "sha1-lOB77sBlk4bxrvuEsiIuiEBUhc0=",
|
||||
"optional": true
|
||||
},
|
||||
"immutable": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "http://registry.npm.taobao.org/immutable/download/immutable-3.8.1.tgz",
|
||||
"integrity": "sha1-IAgH8Rqw9ycQ6khVQt4IgHX2jNI="
|
||||
},
|
||||
"indexes-of": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "http://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-tetris",
|
||||
"version": "1.0.3",
|
||||
"version": "1.1.0",
|
||||
"description": "A Vue.js project",
|
||||
"author": "binaryify <zhuangtongfa@qq.com>",
|
||||
"private": true,
|
||||
@@ -10,7 +10,6 @@
|
||||
"build": "node build/build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"immutable": "^3.8.1",
|
||||
"vue": "^2.3.3",
|
||||
"vuex": "^2.3.1"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { transform, i18n, lan } from '../../unit/const'
|
||||
import { i18n, lan } from '../../unit/const'
|
||||
import { isMobile } from '../../unit'
|
||||
export default {
|
||||
name: 'Guide',
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
QRTitle: () => i18n.QRNotice[lan],
|
||||
QRSrc: () =>
|
||||
window.location.protocol +
|
||||
'//binaryify.github.io/vue-tetris/static/qr.jpeg'
|
||||
'//raw.githubusercontent.com/Binaryify/vue-tetris/master/static/qr.jpeg'
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('resize', this.resize.bind(this), true)
|
||||
|
||||
@@ -127,7 +127,7 @@ export default {
|
||||
over(nextProps) {
|
||||
let overState = this.getResult(nextProps)
|
||||
|
||||
this.overState = JSON.parse(JSON.stringify(overState))
|
||||
this.overState = [...overState]
|
||||
const exLine = index => {
|
||||
if (index <= 19) {
|
||||
overState[19 - index]=fillLine
|
||||
@@ -137,7 +137,7 @@ export default {
|
||||
states.overEnd()
|
||||
return
|
||||
}
|
||||
this.overState = JSON.parse(JSON.stringify(overState))
|
||||
this.overState = [...overState]
|
||||
// console.log(JSON.stringify(overState))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,88 +1,88 @@
|
||||
import { want } from '../../unit/'
|
||||
import event from '../../unit/event'
|
||||
import states from '../states'
|
||||
import { music } from '../../unit/music'
|
||||
import { want } from "../../unit/";
|
||||
import event from "../../unit/event";
|
||||
import states from "../states";
|
||||
import { music } from "../../unit/music";
|
||||
const down = store => {
|
||||
store.commit('key_down', true)
|
||||
store.commit("key_down", true);
|
||||
if (store.state.cur !== null) {
|
||||
event.down({
|
||||
key: 'down',
|
||||
key: "down",
|
||||
begin: 40,
|
||||
interval: 40,
|
||||
callback: stopDownTrigger => {
|
||||
const state = store.state
|
||||
const state = store.state;
|
||||
if (state.lock) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
if (music.move) {
|
||||
music.move()
|
||||
music.move();
|
||||
}
|
||||
const cur = state.cur
|
||||
const cur = state.cur;
|
||||
if (cur === null) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
if (state.pause) {
|
||||
states.pause(false)
|
||||
return
|
||||
states.pause(false);
|
||||
return;
|
||||
}
|
||||
const next = cur.fall()
|
||||
const next = cur.fall();
|
||||
if (want(next, state.matrix)) {
|
||||
store.commit('moveBlock', next)
|
||||
store.commit("moveBlock", next);
|
||||
// store.dispatch(actions.moveBlock(next));
|
||||
states.auto()
|
||||
states.auto();
|
||||
} else {
|
||||
let matrix =JSON.parse(JSON.stringify( state.matrix))
|
||||
const shape = cur.shape
|
||||
const xy = cur.xy
|
||||
let matrix = JSON.parse(JSON.stringify(state.matrix));
|
||||
const shape = cur.shape;
|
||||
const xy = cur.xy;
|
||||
shape.forEach((m, k1) =>
|
||||
m.forEach((n, k2) => {
|
||||
if (n && xy[0] + k1 >= 0) {
|
||||
// 竖坐标可以为负
|
||||
let line = matrix[xy[0] + k1]
|
||||
line[xy[1] + k2]=1
|
||||
|
||||
matrix[xy[0] + k1]=line
|
||||
let line = matrix[xy[0] + k1];
|
||||
line[xy[1] + k2] = 1;
|
||||
|
||||
matrix[xy[0] + k1] = line;
|
||||
}
|
||||
})
|
||||
)
|
||||
states.nextAround(matrix, stopDownTrigger)
|
||||
);
|
||||
states.nextAround(matrix, stopDownTrigger);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
} else {
|
||||
event.down({
|
||||
key: 'down',
|
||||
key: "down",
|
||||
begin: 200,
|
||||
interval: 100,
|
||||
callback: () => {
|
||||
if (store.state.lock) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
const state = store.state
|
||||
const cur = state.cur
|
||||
const state = store.state;
|
||||
const cur = state.cur;
|
||||
if (cur) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
if (music.move) {
|
||||
music.move()
|
||||
music.move();
|
||||
}
|
||||
let startLines = state.startLines
|
||||
startLines = startLines - 1 < 0 ? 10 : startLines - 1
|
||||
store.commit('startLines', startLines)
|
||||
let startLines = state.startLines;
|
||||
startLines = startLines - 1 < 0 ? 10 : startLines - 1;
|
||||
store.commit("startLines", startLines);
|
||||
// store.dispatch(actions.startLines(startLines));
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const up = store => {
|
||||
store.commit('key_down', false)
|
||||
store.commit("key_down", false);
|
||||
event.up({
|
||||
key: 'down'
|
||||
})
|
||||
}
|
||||
key: "down"
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
down,
|
||||
up
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import { music } from '../../unit/music'
|
||||
const down = store => {
|
||||
store.commit('key_rotate', true)
|
||||
if (store.state.cur !== null) {
|
||||
console.log("rotate")
|
||||
event.down({
|
||||
key: 'rotate',
|
||||
once: true,
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
import { want } from '../../unit/'
|
||||
import event from '../../unit/event'
|
||||
import states from '../states'
|
||||
import { music } from '../../unit/music'
|
||||
import { want } from "../../unit/";
|
||||
import event from "../../unit/event";
|
||||
import states from "../states";
|
||||
import { music } from "../../unit/music";
|
||||
const down = store => {
|
||||
store.commit('key_drop', true)
|
||||
store.commit("key_drop", true);
|
||||
event.down({
|
||||
key: 'space',
|
||||
key: "space",
|
||||
once: true,
|
||||
callback: () => {
|
||||
const state = store.state
|
||||
const state = store.state;
|
||||
if (state.lock) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
const cur = state.cur
|
||||
const cur = state.cur;
|
||||
if (cur !== null) {
|
||||
// 置底
|
||||
if (state.pause) {
|
||||
states.pause(false)
|
||||
return
|
||||
states.pause(false);
|
||||
return;
|
||||
}
|
||||
if (music.fall) {
|
||||
music.fall()
|
||||
music.fall();
|
||||
}
|
||||
let index = 0
|
||||
let bottom = cur.fall(index)
|
||||
let index = 0;
|
||||
let bottom = cur.fall(index);
|
||||
while (want(bottom, state.matrix)) {
|
||||
bottom = cur.fall(index)
|
||||
index++
|
||||
bottom = cur.fall(index);
|
||||
index++;
|
||||
}
|
||||
let matrix =JSON.parse(JSON.stringify( state.matrix))
|
||||
bottom = cur.fall(index - 2)
|
||||
store.commit('moveBlock', bottom)
|
||||
const shape = bottom.shape
|
||||
const xy = bottom.xy
|
||||
let matrix = JSON.parse(JSON.stringify(state.matrix));
|
||||
bottom = cur.fall(index - 2);
|
||||
store.commit("moveBlock", bottom);
|
||||
const shape = bottom.shape;
|
||||
const xy = bottom.xy;
|
||||
shape.forEach((m, k1) =>
|
||||
m.forEach((n, k2) => {
|
||||
if (n && xy[0] + k1 >= 0) {
|
||||
// 竖坐标可以为负
|
||||
let line = matrix[xy[0] + k1]
|
||||
line[xy[1] + k2]=1
|
||||
matrix[xy[0] + k1]=line
|
||||
let line = matrix[xy[0] + k1];
|
||||
line[xy[1] + k2] = 1;
|
||||
matrix[xy[0] + k1] = line;
|
||||
}
|
||||
})
|
||||
)
|
||||
store.commit('drop', true)
|
||||
);
|
||||
store.commit("drop", true);
|
||||
setTimeout(() => {
|
||||
store.commit('drop', false)
|
||||
}, 100)
|
||||
states.nextAround(matrix)
|
||||
store.commit("drop", false);
|
||||
}, 100);
|
||||
states.nextAround(matrix);
|
||||
} else {
|
||||
states.start()
|
||||
states.start();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const up = store => {
|
||||
store.commit('key_drop', false)
|
||||
store.commit("key_drop", false);
|
||||
event.up({
|
||||
key: 'space'
|
||||
})
|
||||
}
|
||||
key: "space"
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
down,
|
||||
up
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,7 +63,7 @@ class Block {
|
||||
}
|
||||
|
||||
result[index].push(n)
|
||||
const tempK = JSON.parse(JSON.stringify(result[index]))
|
||||
const tempK = [...result[index]]
|
||||
result[index]=tempK
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user