huwhois 6 years ago
parent
commit
b25094208e
13 changed files with 2815 additions and 7 deletions
  1. 3 5
      main.js
  2. 1 2
      mobile.html
  3. 29 0
      support.js
  4. 1 0
      wx/README.md
  5. 6 0
      wx/game.js
  6. 3 0
      wx/game.json
  7. 53 0
      wx/js/base/background.js
  8. 237 0
      wx/js/base/support.js
  9. 17 0
      wx/js/libs/symbol.js
  10. 1529 0
      wx/js/libs/weapp-adapter.js
  11. 462 0
      wx/js/main.back.js
  12. 442 0
      wx/js/main.js
  13. 32 0
      wx/project.config.json

+ 3 - 5
main.js

@@ -86,7 +86,7 @@ function updateBoardView() {
             $("#grid-container").append('<div class="number-cell" id="number-cell-' + i + j + '"></div>');
             var numberCell = $("#number-cell-" + i + j);
             if (board[i][j] == 0) {
-                //设置居中且”不可见“
+                //设置居中且"不可见"
                 numberCell.css({
                     "width": "0px",
                     "height": "0px",
@@ -108,11 +108,10 @@ function updateBoardView() {
                 numberCell.text(getShowTextByNum(board[i][j]));
                 hasConflicted[i][j] = false;
             }
-
         }
     }
     $('.number-cell').css('line-height', cellSideLength + 'px');
-    //    $('.number-cell').css('font-size',0.6*cellSideLength+'px');
+    // $('.number-cell').css('font-size',0.6*cellSideLength+'px');
     $('.number-cell').css('font-size', 0.2 * cellSideLength + 'px');
 }
 
@@ -201,7 +200,6 @@ function moveLeft() {
                     updateTopScore(score);
                     continue;
                 }
-
             }
         }
     }
@@ -246,7 +244,7 @@ function moveRight() {
 }
 
 function isGameOver() {
-    if (isNoSpace(board) && canMove(board)) {
+    if (isNoSpace(board) && !cavMoveAll(board)) {
         gameOver();
     }
 }

+ 1 - 2
mobile.html

@@ -55,7 +55,7 @@
 
         var inner = document.getElementById("grid-container");
 
-        function touchStart(e) { //触摸开始   
+        function touchStart(e) { //触摸开始
             e.preventDefault();
             var touch = e.touches[0];
             startX = touch.pageX; //刚触摸时的坐标
@@ -87,7 +87,6 @@
                     d = 2;
                 }
             }
-
             slideDirection(d);
         }
 

+ 29 - 0
support.js

@@ -133,6 +133,35 @@ function canMoveRight(borad) {
     return false;
 }
 
+function canMoveUp(borad) {
+    for (var i = 0; i < 4; i++) {
+        for (var j = 1; j < 4; j++) {
+            if (board[j][i] != 0) { //可以移动
+                if (board[j - 1][i] == 0 || board[j][i] == board[j - 1][i])
+                    return true;
+            }
+        }
+    }
+    return false;
+}
+
+function canMoveDown(borad) {
+    for (var i = 3; i >= 0; i--) {
+        for (var j = 2; j >= 0; j--) {
+            if (board[j][i] != 0) { //可以移动
+                if (board[j + 1][i] == 0 || board[j][i] == board[j + 1][i])
+                    return true;
+            }
+        }
+    }
+    return false;
+}
+
+function cavMoveAll(borad){
+    res = canMoveLeft(borad) || canMoveRight(borad) || canMoveUp(borad) || canMoveDown(borad);
+    return res;
+}
+
 /**
  *@Desciption:重新构造canMove方法(包括上、下、左、右)
  *@author:LCore

+ 1 - 0
wx/README.md

@@ -0,0 +1 @@
+## 2048之陈小发, 微信小游戏版

+ 6 - 0
wx/game.js

@@ -0,0 +1,6 @@
+import './js/libs/weapp-adapter'
+import './js/libs/symbol'
+
+import Main from './js/main'
+
+new Main()

+ 3 - 0
wx/game.json

@@ -0,0 +1,3 @@
+{
+    "deviceOrientation": "portrait"
+}

+ 53 - 0
wx/js/base/background.js

@@ -0,0 +1,53 @@
+/**
+ * 游戏背景
+ */
+
+export default class BackGround {
+  constructor(ctx, w, h) {
+    // this.w = w
+    // this.h = h
+    this.render(ctx, w, h)
+
+    // 重新开始按钮区域方便简易判断按钮点击
+    this.btnArea = {
+      startX: 0.04*w,
+      startY: 50,
+      endX  : 0.04*w  + 0.2*w,
+      endY  : 50 + 0.16*w
+    }
+  }
+  /**
+   * 背景图重绘函数
+   * 绘制浅色背景图, 大小和屏幕一致
+   * 绘制三个按钮, 即文字
+   * 绘制棋盘背景板
+   */
+  render(ctx, w, h) {
+    ctx.clearRect(0, 0, w, h);
+    ctx.fillStyle = '#F0F0F0'
+    ctx.fillRect(0, 0, w, h)
+
+    ctx.fillStyle = '#F7921E'
+    ctx.font = "30px 微软雅黑"
+    // ctx.textBaseline = "top"
+    ctx.fillText("2048之陈小发", 0.04*w, 0.1*w);
+
+    ctx.fillStyle = '#8F7A66'
+    ctx.fillRect(0.04*w, 50, 0.2*w, 0.16*w)
+    ctx.fillStyle = '#BAAB9E'
+    ctx.fillRect(0.28*w, 50, 0.32*w, 0.16*w)
+    ctx.fillStyle = '#F7921E'
+    ctx.fillRect(0.64*w, 50, 0.32*w, 0.16*w)
+    ctx.fillStyle = 'white'
+    ctx.font = "20px 微软雅黑"
+    ctx.textAlign = "center"
+    ctx.textBaseline = "top"
+    ctx.fillText("重玩", 0.14*w, 50+0.04*w);
+    ctx.fillText("最高分数", 0.44*w, 50);
+    ctx.fillText("当前分数", 0.8*w, 50);
+    // console.log(0.14*w, 50+0.1*w)
+    // 棋盘背景
+    ctx.fillStyle = '#BBADA0'
+    ctx.fillRect(0.04*w, 50+0.3*w, 0.92*w, 0.92*w)
+  }
+}

+ 237 - 0
wx/js/base/support.js

@@ -0,0 +1,237 @@
+/**
+ * @Description:support.js
+ * @Author:LCore
+ */
+
+// var documentWidth = window.screen.availWidth
+// var gridContainerWidth = 0.92 * documentWidth
+// var cellSideLength = 0.18 * documentWidth
+// var cellSpace = 0.04 * documentWidth
+// var headerWidth = window.screen.availWidth
+var cellSideLength
+var cellSpace
+
+var showText = {
+  '2': '高雄萌妹',
+  '4': '一发入魂',
+  '8': '乱斗王者',
+  '16': 'CAD大师',
+  '32': '斗奶狂魔',
+  '64': '认发作妈',
+  '128': '下岗女工',
+  '256': '梦碎豪门',
+  '512': '太极宗师',
+  '1024': '远离魔都',
+  '2048': '文学巨匠',
+  '4096': '分手大师',
+  '8192': '金牌僚机',
+  '16384': '股海明灯',
+}
+var backgroundColor = {
+  '2': '#eee4da',
+  '4': '#ede0c8',
+  '8': '#f2b179',
+  '16': '#f59563',
+  '32': '#f67c5f',
+  '64': '#f65e3b',
+  '128': '#edcf72',
+  '256': '#edcc61',
+  '512': '#9c0',
+  '1024': '#33b5e5',
+  '2048': '#09c',
+  '4096': '#a6c',
+  '8192': '#93c',
+  '16384': '#e04',
+}
+
+export default class Support {
+  constructor(w, h) {
+    this.w = w
+    this.h = h
+    cellSideLength = 0.18*w
+    cellSpace = 0.04*w
+  }
+
+  
+  getPostionTop(i, j) {
+    return (i * cellSideLength + (i + 1) * cellSpace + 0.3 * this.w + 50);
+  }
+
+  getPostionLeft(i, j) {
+    return (j * cellSideLength + (j + 1) * cellSpace+ 0.04 * this.w);
+  }
+
+  getShowTextByNum(number) {
+    if (number < (16384 + 1)) {
+      return showText[number];
+    }
+
+    return 'fafa';
+  }
+
+  getBackgroundColorByNum(number) {
+    if (number < (16384 + 1)) {
+      return backgroundColor[number];
+    }
+    return "black";
+  }
+
+  getPreColorByNum(number) {
+    if (number <= 4)
+      return "#776e65";
+    return "white";
+  }
+
+  isNoSpace(board) {
+    for (var i = 0; i < 4; i++)
+      for (var j = 0; j < 4; j++)
+        if (board[i][j] == 0)
+          return false;
+
+    return true;
+  }
+
+  canMoveLeft(board) {
+    for (var i = 0; i < 4; i++) {
+      for (var j = 1; j < 4; j++) {
+        if (board[i][j] != 0) {
+          if (board[i][j - 1] == 0 || board[i][j] == board[i][j - 1])
+            return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  canMoveRight(board) {
+    for (var i = 3; i >= 0; i--) {
+      for (var j = 2; j >= 0; j--) {
+        if (board[i][j] != 0) {
+          if (board[i][j + 1] == 0 || board[i][j] == board[i][j + 1])
+            return true;
+        }
+
+      }
+    }
+    return false;
+  }
+
+  /**
+   *@Desciption: 补全原方法, 添加全部方向都不能的判断
+   *@author: huwhois
+   *@pragram board:棋盘格
+   *@pragram direction:移动方向
+   */
+  canMoveUp(board) {
+    for (var i = 0; i < 4; i++) {
+      for (var j = 1; j < 4; j++) {
+        if (board[j][i] != 0) { //可以移动
+          if (board[j - 1][i] == 0 || board[j][i] == board[j - 1][i])
+            return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  canMoveDown(board) {
+    for (var i = 3; i >= 0; i--) {
+      for (var j = 2; j >= 0; j--) {
+        if (board[j][i] != 0) { //可以移动
+          if (board[j + 1][i] == 0 || board[j][i] == board[j + 1][i])
+            return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  canMoveAll(board) {
+    return (this.canMoveLeft(board) || this.canMoveRight(board) || this.canMoveUp(board) || this.canMoveDown(board))
+  }
+
+  /**
+   *@Desciption:重新构造canMove方法(包括上、下、左、右)
+   *@author:LCore
+   *@pragram board:棋盘格
+   *@pragram direction:移动方向
+   */
+
+  canMove(board, direction) {
+    if (direction == 1) {
+      //左移
+      for (var i = 0; i < 4; i++) {
+        for (var j = 1; j < 4; j++) {
+          if (board[i][j] != 0) {
+            if (board[i][j - 1] == 0 || board[i][j] == board[i][j - 1])
+              return true;
+          }
+
+        }
+      }
+    } else if (direction == 2) {
+      //上移
+      for (var i = 0; i < 4; i++) {
+        for (var j = 1; j < 4; j++) {
+          if (board[j][i] != 0) { //可以移动
+            if (board[j - 1][i] == 0 || board[j][i] == board[j - 1][i])
+              return true;
+          }
+        }
+      }
+    } else if (direction == 3) {
+      //下移
+      for (var i = 3; i >= 0; i--) {
+        for (var j = 2; j >= 0; j--) {
+          if (board[j][i] != 0) { //可以移动
+            if (board[j + 1][i] == 0 || board[j][i] == board[j + 1][i])
+              return true;
+          }
+        }
+      }
+    } else if (direction == 4) {
+      //右移
+      for (var i = 3; i >= 0; i--) {
+        for (var j = 2; j >= 0; j--) {
+          if (board[i][j] != 0) {
+            if (board[i][j + 1] == 0 || board[i][j] == board[i][j + 1])
+              return true;
+          }
+
+        }
+      }
+    } else
+      return false;
+
+  }
+
+  /**
+   *@Description:横向判断是否存在障碍物
+   *@pagram row:第几行
+   *@pagram col1:开始索引
+   *@pagram col2:结束索引
+   *@pagram board:棋盘格
+   */
+  noBlockHorizontal(row, col1, col2, board) {
+    for (var i = col1 + 1; i < col2; i++) {
+      if (board[row][i] != 0)
+        return false;
+    }
+    return true;
+  }
+
+  /**
+   *@Description:纵向判断是否存在障碍物
+   *@pagram col:第几列
+   *@pagram row1:开始索引
+   *@pagram row2:结束索引
+   *@pagram board:棋盘格
+   */
+  noBlockVectal(col, row1, row2, board) {
+    for (var i = row1 + 1; i < row2; i++) {
+      if (board[i][col] != 0)
+        return false;
+    }
+    return true;
+  }
+}

+ 17 - 0
wx/js/libs/symbol.js

@@ -0,0 +1,17 @@
+/**
+ * 对于ES6中Symbol的极简兼容
+ * 方便模拟私有变量
+ */
+
+let Symbol  = window.Symbol
+let idCounter = 0
+
+if (!Symbol) {
+  Symbol = function Symbol(key) {
+    return `__${key}_${Math.floor(Math.random() * 1e9)}_${++idCounter}__`
+  }
+
+  Symbol.iterator = Symbol('Symbol.iterator')
+}
+
+window.Symbol = Symbol

+ 1529 - 0
wx/js/libs/weapp-adapter.js

@@ -0,0 +1,1529 @@
+/******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {}
+
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId])
+/******/ 			return installedModules[moduleId].exports
+
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			exports: {},
+/******/ 			id: moduleId,
+/******/ 			loaded: false
+/******/ 		}
+
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)
+
+/******/ 		// Flag the module as loaded
+/******/ 		module.loaded = true
+
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports
+/******/ 	}
+
+
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules
+
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules
+
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = ""
+
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(0)
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	var _window2 = __webpack_require__(1)
+
+	var _window = _interopRequireWildcard(_window2)
+
+	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key] } } newObj.default = obj; return newObj } }
+
+	var global = GameGlobal
+
+	function inject() {
+	  _window.addEventListener = _window.canvas.addEventListener = function (type, listener) {
+	    _window.document.addEventListener(type, listener)
+	  }
+	  _window.removeEventListener = _window.canvas.removeEventListener = function (type, listener) {
+	    _window.document.removeEventListener(type, listener)
+	  }
+
+	  var _wx$getSystemInfoSync = wx.getSystemInfoSync(),
+	      platform = _wx$getSystemInfoSync.platform
+
+	  // 开发者工具无法重定义 window
+
+
+	  if (typeof __devtoolssubcontext === 'undefined' && platform === 'devtools') {
+	    for (var key in _window) {
+	      var descriptor = Object.getOwnPropertyDescriptor(global, key)
+
+	      if (!descriptor || descriptor.configurable === true) {
+	        Object.defineProperty(window, key, {
+	          value: _window[key]
+	        })
+	      }
+	    }
+
+	    for (var _key in _window.document) {
+	      var _descriptor = Object.getOwnPropertyDescriptor(global.document, _key)
+
+	      if (!_descriptor || _descriptor.configurable === true) {
+	        Object.defineProperty(global.document, _key, {
+	          value: _window.document[_key]
+	        })
+	      }
+	    }
+	    window.parent = window
+	  } else {
+	    for (var _key2 in _window) {
+	      global[_key2] = _window[_key2]
+	    }
+	    global.window = _window
+	    window = global
+	    window.top = window.parent = window
+	  }
+	}
+
+	if (!GameGlobal.__isAdapterInjected) {
+	  GameGlobal.__isAdapterInjected = true
+	  inject()
+	}
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+	exports.cancelAnimationFrame = exports.requestAnimationFrame = exports.clearInterval = exports.clearTimeout = exports.setInterval = exports.setTimeout = exports.canvas = exports.location = exports.localStorage = exports.HTMLElement = exports.FileReader = exports.Audio = exports.Image = exports.WebSocket = exports.XMLHttpRequest = exports.navigator = exports.document = undefined
+
+	var _WindowProperties = __webpack_require__(2)
+
+	Object.keys(_WindowProperties).forEach(function (key) {
+	  if (key === "default" || key === "__esModule") return
+	  Object.defineProperty(exports, key, {
+	    enumerable: true,
+	    get: function get() {
+	      return _WindowProperties[key]
+	    }
+	  })
+	})
+
+	var _constructor = __webpack_require__(3)
+
+	Object.keys(_constructor).forEach(function (key) {
+	  if (key === "default" || key === "__esModule") return
+	  Object.defineProperty(exports, key, {
+	    enumerable: true,
+	    get: function get() {
+	      return _constructor[key]
+	    }
+	  })
+	})
+
+	var _Canvas = __webpack_require__(9)
+
+	var _Canvas2 = _interopRequireDefault(_Canvas)
+
+	var _document2 = __webpack_require__(10)
+
+	var _document3 = _interopRequireDefault(_document2)
+
+	var _navigator2 = __webpack_require__(17)
+
+	var _navigator3 = _interopRequireDefault(_navigator2)
+
+	var _XMLHttpRequest2 = __webpack_require__(18)
+
+	var _XMLHttpRequest3 = _interopRequireDefault(_XMLHttpRequest2)
+
+	var _WebSocket2 = __webpack_require__(19)
+
+	var _WebSocket3 = _interopRequireDefault(_WebSocket2)
+
+	var _Image2 = __webpack_require__(11)
+
+	var _Image3 = _interopRequireDefault(_Image2)
+
+	var _Audio2 = __webpack_require__(12)
+
+	var _Audio3 = _interopRequireDefault(_Audio2)
+
+	var _FileReader2 = __webpack_require__(20)
+
+	var _FileReader3 = _interopRequireDefault(_FileReader2)
+
+	var _HTMLElement2 = __webpack_require__(4)
+
+	var _HTMLElement3 = _interopRequireDefault(_HTMLElement2)
+
+	var _localStorage2 = __webpack_require__(21)
+
+	var _localStorage3 = _interopRequireDefault(_localStorage2)
+
+	var _location2 = __webpack_require__(22)
+
+	var _location3 = _interopRequireDefault(_location2)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	exports.document = _document3.default
+	exports.navigator = _navigator3.default
+	exports.XMLHttpRequest = _XMLHttpRequest3.default
+	exports.WebSocket = _WebSocket3.default
+	exports.Image = _Image3.default
+	exports.Audio = _Audio3.default
+	exports.FileReader = _FileReader3.default
+	exports.HTMLElement = _HTMLElement3.default
+	exports.localStorage = _localStorage3.default
+	exports.location = _location3.default
+
+
+	// 暴露全局的 canvas
+	var canvas = new _Canvas2.default()
+
+	exports.canvas = canvas
+	exports.setTimeout = setTimeout
+	exports.setInterval = setInterval
+	exports.clearTimeout = clearTimeout
+	exports.clearInterval = clearInterval
+	exports.requestAnimationFrame = requestAnimationFrame
+	exports.cancelAnimationFrame = cancelAnimationFrame
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports) {
+
+	"use strict"
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _wx$getSystemInfoSync = wx.getSystemInfoSync(),
+	    screenWidth = _wx$getSystemInfoSync.screenWidth,
+	    screenHeight = _wx$getSystemInfoSync.screenHeight,
+	    devicePixelRatio = _wx$getSystemInfoSync.devicePixelRatio
+
+	var innerWidth = exports.innerWidth = screenWidth
+	var innerHeight = exports.innerHeight = screenHeight
+	exports.devicePixelRatio = devicePixelRatio
+	var screen = exports.screen = {
+	  availWidth: innerWidth,
+	  availHeight: innerHeight
+	}
+	var performance = exports.performance = {
+	  now: function now() {
+	    return Date.now() / 1000
+	  }
+	}
+	var ontouchstart = exports.ontouchstart = null
+	var ontouchmove = exports.ontouchmove = null
+	var ontouchend = exports.ontouchend = null
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+	exports.HTMLCanvasElement = exports.HTMLImageElement = undefined
+
+	var _HTMLElement3 = __webpack_require__(4)
+
+	var _HTMLElement4 = _interopRequireDefault(_HTMLElement3)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === "object" || typeof call === "function") ? call : self }
+
+	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass }
+
+	var HTMLImageElement = exports.HTMLImageElement = function (_HTMLElement) {
+	  _inherits(HTMLImageElement, _HTMLElement)
+
+	  function HTMLImageElement() {
+	    _classCallCheck(this, HTMLImageElement)
+
+	    return _possibleConstructorReturn(this, (HTMLImageElement.__proto__ || Object.getPrototypeOf(HTMLImageElement)).call(this, 'img'))
+	  }
+
+	  return HTMLImageElement
+	}(_HTMLElement4.default)
+
+	var HTMLCanvasElement = exports.HTMLCanvasElement = function (_HTMLElement2) {
+	  _inherits(HTMLCanvasElement, _HTMLElement2)
+
+	  function HTMLCanvasElement() {
+	    _classCallCheck(this, HTMLCanvasElement)
+
+	    return _possibleConstructorReturn(this, (HTMLCanvasElement.__proto__ || Object.getPrototypeOf(HTMLCanvasElement)).call(this, 'canvas'))
+	  }
+
+	  return HTMLCanvasElement
+	}(_HTMLElement4.default)
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor } }()
+
+	var _Element2 = __webpack_require__(5)
+
+	var _Element3 = _interopRequireDefault(_Element2)
+
+	var _util = __webpack_require__(8)
+
+	var _WindowProperties = __webpack_require__(2)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === "object" || typeof call === "function") ? call : self }
+
+	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass }
+
+	var HTMLElement = function (_Element) {
+	  _inherits(HTMLElement, _Element)
+
+	  function HTMLElement() {
+	    var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''
+
+	    _classCallCheck(this, HTMLElement)
+
+	    var _this = _possibleConstructorReturn(this, (HTMLElement.__proto__ || Object.getPrototypeOf(HTMLElement)).call(this))
+
+	    _this.className = ''
+	    _this.childern = []
+	    _this.style = {
+	      width: _WindowProperties.innerWidth + 'px',
+	      height: _WindowProperties.innerHeight + 'px'
+	    }
+	    _this.insertBefore = _util.noop
+	    _this.innerHTML = ''
+
+	    _this.tagName = tagName.toUpperCase()
+	    return _this
+	  }
+
+	  _createClass(HTMLElement, [{
+	    key: 'setAttribute',
+	    value: function setAttribute(name, value) {
+	      this[name] = value
+	    }
+	  }, {
+	    key: 'getAttribute',
+	    value: function getAttribute(name) {
+	      return this[name]
+	    }
+	  }, {
+	    key: 'getBoundingClientRect',
+	    value: function getBoundingClientRect() {
+	      return {
+	        top: 0,
+	        left: 0,
+	        width: _WindowProperties.innerWidth,
+	        height: _WindowProperties.innerHeight
+	      }
+	    }
+	  }, {
+	    key: 'focus',
+	    value: function focus() {}
+	  }, {
+	    key: 'clientWidth',
+	    get: function get() {
+	      var ret = parseInt(this.style.fontSize, 10) * this.innerHTML.length
+
+	      return Number.isNaN(ret) ? 0 : ret
+	    }
+	  }, {
+	    key: 'clientHeight',
+	    get: function get() {
+	      var ret = parseInt(this.style.fontSize, 10)
+
+	      return Number.isNaN(ret) ? 0 : ret
+	    }
+	  }])
+
+	  return HTMLElement
+	}(_Element3.default)
+
+	exports.default = HTMLElement
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _Node2 = __webpack_require__(6)
+
+	var _Node3 = _interopRequireDefault(_Node2)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === "object" || typeof call === "function") ? call : self }
+
+	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass }
+
+	var ELement = function (_Node) {
+	  _inherits(ELement, _Node)
+
+	  function ELement() {
+	    _classCallCheck(this, ELement)
+
+	    var _this = _possibleConstructorReturn(this, (ELement.__proto__ || Object.getPrototypeOf(ELement)).call(this))
+
+	    _this.className = ''
+	    _this.children = []
+	    return _this
+	  }
+
+	  return ELement
+	}(_Node3.default)
+
+	exports.default = ELement
+
+/***/ }),
+/* 6 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor } }()
+
+	var _EventTarget2 = __webpack_require__(7)
+
+	var _EventTarget3 = _interopRequireDefault(_EventTarget2)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === "object" || typeof call === "function") ? call : self }
+
+	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass }
+
+	var Node = function (_EventTarget) {
+	  _inherits(Node, _EventTarget)
+
+	  function Node() {
+	    _classCallCheck(this, Node)
+
+	    var _this = _possibleConstructorReturn(this, (Node.__proto__ || Object.getPrototypeOf(Node)).call(this))
+
+	    _this.childNodes = []
+	    return _this
+	  }
+
+	  _createClass(Node, [{
+	    key: 'appendChild',
+	    value: function appendChild(node) {
+	      if (node instanceof Node) {
+	        this.childNodes.push(node)
+	      } else {
+	        throw new TypeError('Failed to executed \'appendChild\' on \'Node\': parameter 1 is not of type \'Node\'.')
+	      }
+	    }
+	  }, {
+	    key: 'cloneNode',
+	    value: function cloneNode() {
+	      var copyNode = Object.create(this)
+
+	      Object.assign(copyNode, this)
+	      return copyNode
+	    }
+	  }, {
+	    key: 'removeChild',
+	    value: function removeChild(node) {
+	      var index = this.childNodes.findIndex(function (child) {
+	        return child === node
+	      })
+
+	      if (index > -1) {
+	        return this.childNodes.splice(index, 1)
+	      }
+	      return null
+	    }
+	  }])
+
+	  return Node
+	}(_EventTarget3.default)
+
+	exports.default = Node
+
+/***/ }),
+/* 7 */
+/***/ (function(module, exports) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor } }()
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	var _events = new WeakMap()
+
+	var EventTarget = function () {
+	  function EventTarget() {
+	    _classCallCheck(this, EventTarget)
+
+	    _events.set(this, {})
+	  }
+
+	  _createClass(EventTarget, [{
+	    key: 'addEventListener',
+	    value: function addEventListener(type, listener) {
+	      var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}
+
+	      var events = _events.get(this)
+
+	      if (!events) {
+	        events = {}
+	        _events.set(this, events)
+	      }
+	      if (!events[type]) {
+	        events[type] = []
+	      }
+	      events[type].push(listener)
+
+	      if (options.capture) {
+	        console.warn('EventTarget.addEventListener: options.capture is not implemented.')
+	      }
+	      if (options.once) {
+	        console.warn('EventTarget.addEventListener: options.once is not implemented.')
+	      }
+	      if (options.passive) {
+	        console.warn('EventTarget.addEventListener: options.passive is not implemented.')
+	      }
+	    }
+	  }, {
+	    key: 'removeEventListener',
+	    value: function removeEventListener(type, listener) {
+	      var listeners = _events.get(this)[type]
+
+	      if (listeners && listeners.length > 0) {
+	        for (var i = listeners.length; i--; i > 0) {
+	          if (listeners[i] === listener) {
+	            listeners.splice(i, 1)
+	            break
+	          }
+	        }
+	      }
+	    }
+	  }, {
+	    key: 'dispatchEvent',
+	    value: function dispatchEvent() {
+	      var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}
+
+	      var listeners = _events.get(this)[event.type]
+
+	      if (listeners) {
+	        for (var i = 0; i < listeners.length; i++) {
+	          listeners[i](event)
+	        }
+	      }
+	    }
+	  }])
+
+	  return EventTarget
+	}()
+
+	exports.default = EventTarget
+
+/***/ }),
+/* 8 */
+/***/ (function(module, exports) {
+
+	"use strict"
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+	exports.noop = noop
+	function noop() {}
+
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+	exports.default = Canvas
+
+	var _constructor = __webpack_require__(3)
+
+	var _HTMLElement = __webpack_require__(4)
+
+	var _HTMLElement2 = _interopRequireDefault(_HTMLElement)
+
+	var _document = __webpack_require__(10)
+
+	var _document2 = _interopRequireDefault(_document)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	var hasModifiedCanvasPrototype = false
+	var hasInit2DContextConstructor = false
+	var hasInitWebGLContextConstructor = false
+
+	function Canvas() {
+	  var canvas = wx.createCanvas()
+
+	  canvas.type = 'canvas'
+
+	  canvas.__proto__.__proto__ = new _HTMLElement2.default('canvas')
+
+	  var _getContext = canvas.getContext
+
+	  canvas.getBoundingClientRect = function () {
+	    var ret = {
+	      top: 0,
+	      left: 0,
+	      width: window.innerWidth,
+	      height: window.innerHeight
+	    }
+	    return ret
+	  }
+
+	  return canvas
+	}
+
+/***/ }),
+/* 10 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _window = __webpack_require__(1)
+
+	var window = _interopRequireWildcard(_window)
+
+	var _HTMLElement = __webpack_require__(4)
+
+	var _HTMLElement2 = _interopRequireDefault(_HTMLElement)
+
+	var _Image = __webpack_require__(11)
+
+	var _Image2 = _interopRequireDefault(_Image)
+
+	var _Audio = __webpack_require__(12)
+
+	var _Audio2 = _interopRequireDefault(_Audio)
+
+	var _Canvas = __webpack_require__(9)
+
+	var _Canvas2 = _interopRequireDefault(_Canvas)
+
+	__webpack_require__(15)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key] } } newObj.default = obj; return newObj } }
+
+	var events = {}
+
+	var document = {
+	  readyState: 'complete',
+	  visibilityState: 'visible',
+	  documentElement: window,
+	  hidden: false,
+	  style: {},
+	  location: window.location,
+	  ontouchstart: null,
+	  ontouchmove: null,
+	  ontouchend: null,
+
+	  head: new _HTMLElement2.default('head'),
+	  body: new _HTMLElement2.default('body'),
+
+	  createElement: function createElement(tagName) {
+	    if (tagName === 'canvas') {
+	      return new _Canvas2.default()
+	    } else if (tagName === 'audio') {
+	      return new _Audio2.default()
+	    } else if (tagName === 'img') {
+	      return new _Image2.default()
+	    }
+
+	    return new _HTMLElement2.default(tagName)
+	  },
+	  getElementById: function getElementById(id) {
+	    if (id === window.canvas.id) {
+	      return window.canvas
+	    }
+	    return null
+	  },
+	  getElementsByTagName: function getElementsByTagName(tagName) {
+	    if (tagName === 'head') {
+	      return [document.head]
+	    } else if (tagName === 'body') {
+	      return [document.body]
+	    } else if (tagName === 'canvas') {
+	      return [window.canvas]
+	    }
+	    return []
+	  },
+	  querySelector: function querySelector(query) {
+	    if (query === 'head') {
+	      return document.head
+	    } else if (query === 'body') {
+	      return document.body
+	    } else if (query === 'canvas') {
+	      return window.canvas
+	    } else if (query === '#' + window.canvas.id) {
+	      return window.canvas
+	    }
+	    return null
+	  },
+	  querySelectorAll: function querySelectorAll(query) {
+	    if (query === 'head') {
+	      return [document.head]
+	    } else if (query === 'body') {
+	      return [document.body]
+	    } else if (query === 'canvas') {
+	      return [window.canvas]
+	    }
+	    return []
+	  },
+	  addEventListener: function addEventListener(type, listener) {
+	    if (!events[type]) {
+	      events[type] = []
+	    }
+	    events[type].push(listener)
+	  },
+	  removeEventListener: function removeEventListener(type, listener) {
+	    var listeners = events[type]
+
+	    if (listeners && listeners.length > 0) {
+	      for (var i = listeners.length; i--; i > 0) {
+	        if (listeners[i] === listener) {
+	          listeners.splice(i, 1)
+	          break
+	        }
+	      }
+	    }
+	  },
+	  dispatchEvent: function dispatchEvent(event) {
+	    var listeners = events[event.type]
+
+	    if (listeners) {
+	      for (var i = 0; i < listeners.length; i++) {
+	        listeners[i](event)
+	      }
+	    }
+	  }
+	}
+
+	exports.default = document
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports) {
+
+	"use strict"
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+	exports.default = Image
+	function Image() {
+	  var image = wx.createImage()
+
+	  return image
+	}
+
+/***/ }),
+/* 12 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor } }()
+
+	var _HTMLAudioElement2 = __webpack_require__(13)
+
+	var _HTMLAudioElement3 = _interopRequireDefault(_HTMLAudioElement2)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === "object" || typeof call === "function") ? call : self }
+
+	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass }
+
+	var HAVE_NOTHING = 0
+	var HAVE_METADATA = 1
+	var HAVE_CURRENT_DATA = 2
+	var HAVE_FUTURE_DATA = 3
+	var HAVE_ENOUGH_DATA = 4
+
+	var _innerAudioContext = new WeakMap()
+	var _src = new WeakMap()
+	var _loop = new WeakMap()
+	var _autoplay = new WeakMap()
+
+	var Audio = function (_HTMLAudioElement) {
+	  _inherits(Audio, _HTMLAudioElement)
+
+	  function Audio(url) {
+	    _classCallCheck(this, Audio)
+
+	    var _this = _possibleConstructorReturn(this, (Audio.__proto__ || Object.getPrototypeOf(Audio)).call(this))
+
+	    _this.HAVE_NOTHING = HAVE_NOTHING
+	    _this.HAVE_METADATA = HAVE_METADATA
+	    _this.HAVE_CURRENT_DATA = HAVE_CURRENT_DATA
+	    _this.HAVE_FUTURE_DATA = HAVE_FUTURE_DATA
+	    _this.HAVE_ENOUGH_DATA = HAVE_ENOUGH_DATA
+	    _this.readyState = HAVE_NOTHING
+
+
+	    _src.set(_this, '')
+
+	    var innerAudioContext = wx.createInnerAudioContext()
+
+	    _innerAudioContext.set(_this, innerAudioContext)
+
+	    innerAudioContext.onCanplay(function () {
+	      _this.dispatchEvent({ type: 'load' })
+	      _this.dispatchEvent({ type: 'loadend' })
+	      _this.dispatchEvent({ type: 'canplay' })
+	      _this.dispatchEvent({ type: 'canplaythrough' })
+	      _this.dispatchEvent({ type: 'loadedmetadata' })
+	      _this.readyState = HAVE_CURRENT_DATA
+	    })
+	    innerAudioContext.onPlay(function () {
+	      _this.dispatchEvent({ type: 'play' })
+	    })
+	    innerAudioContext.onPause(function () {
+	      _this.dispatchEvent({ type: 'pause' })
+	    })
+	    innerAudioContext.onEnded(function () {
+	      _this.dispatchEvent({ type: 'ended' })
+	      _this.readyState = HAVE_ENOUGH_DATA
+	    })
+	    innerAudioContext.onError(function () {
+	      _this.dispatchEvent({ type: 'error' })
+	    })
+
+	    if (url) {
+	      _innerAudioContext.get(_this).src = url
+	    }
+	    return _this
+	  }
+
+	  _createClass(Audio, [{
+	    key: 'load',
+	    value: function load() {
+	      console.warn('HTMLAudioElement.load() is not implemented.')
+	    }
+	  }, {
+	    key: 'play',
+	    value: function play() {
+	      _innerAudioContext.get(this).play()
+	    }
+	  }, {
+	    key: 'pause',
+	    value: function pause() {
+	      _innerAudioContext.get(this).pause()
+	    }
+	  }, {
+	    key: 'canPlayType',
+	    value: function canPlayType() {
+	      var mediaType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''
+
+	      if (typeof mediaType !== 'string') {
+	        return ''
+	      }
+
+	      if (mediaType.indexOf('audio/mpeg') > -1 || mediaType.indexOf('audio/mp4')) {
+	        return 'probably'
+	      }
+	      return ''
+	    }
+	  }, {
+	    key: 'cloneNode',
+	    value: function cloneNode() {
+	      var newAudio = new Audio()
+	      newAudio.loop = _innerAudioContext.get(this).loop
+	      newAudio.autoplay = _innerAudioContext.get(this).loop
+	      newAudio.src = this.src
+	      return newAudio
+	    }
+	  }, {
+	    key: 'currentTime',
+	    get: function get() {
+	      return _innerAudioContext.get(this).currentTime
+	    },
+	    set: function set(value) {
+	      _innerAudioContext.get(this).seek(value)
+	    }
+	  }, {
+	    key: 'src',
+	    get: function get() {
+	      return _src.get(this)
+	    },
+	    set: function set(value) {
+	      _src.set(this, value)
+	      _innerAudioContext.get(this).src = value
+	    }
+	  }, {
+	    key: 'loop',
+	    get: function get() {
+	      return _innerAudioContext.get(this).loop
+	    },
+	    set: function set(value) {
+	      _innerAudioContext.get(this).loop = value
+	    }
+	  }, {
+	    key: 'autoplay',
+	    get: function get() {
+	      return _innerAudioContext.get(this).autoplay
+	    },
+	    set: function set(value) {
+	      _innerAudioContext.get(this).autoplay = value
+	    }
+	  }, {
+	    key: 'paused',
+	    get: function get() {
+	      return _innerAudioContext.get(this).paused
+	    }
+	  }])
+
+	  return Audio
+	}(_HTMLAudioElement3.default)
+
+	exports.default = Audio
+
+/***/ }),
+/* 13 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _HTMLMediaElement2 = __webpack_require__(14)
+
+	var _HTMLMediaElement3 = _interopRequireDefault(_HTMLMediaElement2)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === "object" || typeof call === "function") ? call : self }
+
+	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass }
+
+	var HTMLAudioElement = function (_HTMLMediaElement) {
+	  _inherits(HTMLAudioElement, _HTMLMediaElement)
+
+	  function HTMLAudioElement() {
+	    _classCallCheck(this, HTMLAudioElement)
+
+	    return _possibleConstructorReturn(this, (HTMLAudioElement.__proto__ || Object.getPrototypeOf(HTMLAudioElement)).call(this, 'audio'))
+	  }
+
+	  return HTMLAudioElement
+	}(_HTMLMediaElement3.default)
+
+	exports.default = HTMLAudioElement
+
+/***/ }),
+/* 14 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor } }()
+
+	var _HTMLElement2 = __webpack_require__(4)
+
+	var _HTMLElement3 = _interopRequireDefault(_HTMLElement2)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === "object" || typeof call === "function") ? call : self }
+
+	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass }
+
+	var HTMLMediaElement = function (_HTMLElement) {
+	  _inherits(HTMLMediaElement, _HTMLElement)
+
+	  function HTMLMediaElement(type) {
+	    _classCallCheck(this, HTMLMediaElement)
+
+	    return _possibleConstructorReturn(this, (HTMLMediaElement.__proto__ || Object.getPrototypeOf(HTMLMediaElement)).call(this, type))
+	  }
+
+	  _createClass(HTMLMediaElement, [{
+	    key: 'addTextTrack',
+	    value: function addTextTrack() {}
+	  }, {
+	    key: 'captureStream',
+	    value: function captureStream() {}
+	  }, {
+	    key: 'fastSeek',
+	    value: function fastSeek() {}
+	  }, {
+	    key: 'load',
+	    value: function load() {}
+	  }, {
+	    key: 'pause',
+	    value: function pause() {}
+	  }, {
+	    key: 'play',
+	    value: function play() {}
+	  }])
+
+	  return HTMLMediaElement
+	}(_HTMLElement3.default)
+
+	exports.default = HTMLMediaElement
+
+/***/ }),
+/* 15 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	__webpack_require__(16)
+
+/***/ }),
+/* 16 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	var _window = __webpack_require__(1)
+
+	var window = _interopRequireWildcard(_window)
+
+	var _document = __webpack_require__(10)
+
+	var _document2 = _interopRequireDefault(_document)
+
+	var _util = __webpack_require__(8)
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } }
+
+	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key] } } newObj.default = obj; return newObj } }
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	var TouchEvent = function TouchEvent(type) {
+	  _classCallCheck(this, TouchEvent)
+
+	  this.target = window.canvas
+	  this.currentTarget = window.canvas
+	  this.touches = []
+	  this.targetTouches = []
+	  this.changedTouches = []
+	  this.preventDefault = _util.noop
+	  this.stopPropagation = _util.noop
+
+	  this.type = type
+	}
+
+	function touchEventHandlerFactory(type) {
+	  return function (event) {
+	    var touchEvent = new TouchEvent(type)
+
+	    touchEvent.touches = event.touches
+	    touchEvent.targetTouches = Array.prototype.slice.call(event.touches)
+	    touchEvent.changedTouches = event.changedTouches
+	    touchEvent.timeStamp = event.timeStamp
+	    _document2.default.dispatchEvent(touchEvent)
+	  }
+	}
+
+	wx.onTouchStart(touchEventHandlerFactory('touchstart'))
+	wx.onTouchMove(touchEventHandlerFactory('touchmove'))
+	wx.onTouchEnd(touchEventHandlerFactory('touchend'))
+	wx.onTouchCancel(touchEventHandlerFactory('touchcancel'))
+
+/***/ }),
+/* 17 */
+/***/ (function(module, exports, __webpack_require__) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _util = __webpack_require__(8)
+
+	// TODO 需要 wx.getSystemInfo 获取更详细信息
+	var _wx$getSystemInfoSync = wx.getSystemInfoSync(),
+	    platform = _wx$getSystemInfoSync.platform
+
+	var navigator = {
+	  platform: platform,
+	  language: 'zh-cn',
+	  appVersion: '5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+	  userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 MicroMessenger/6.6.0 MiniGame NetType/WIFI Language/zh_CN',
+	  onLine: true, // TODO 用 wx.getNetworkStateChange 和 wx.onNetworkStateChange 来返回真实的状态
+
+	  // TODO 用 wx.getLocation 来封装 geolocation
+	  geolocation: {
+	    getCurrentPosition: _util.noop,
+	    watchPosition: _util.noop,
+	    clearWatch: _util.noop
+	  }
+	}
+
+	exports.default = navigator
+
+/***/ }),
+/* 18 */
+/***/ (function(module, exports) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor } }()
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	var _url = new WeakMap()
+	var _method = new WeakMap()
+	var _requestHeader = new WeakMap()
+	var _responseHeader = new WeakMap()
+	var _requestTask = new WeakMap()
+
+	function _triggerEvent(type) {
+	  if (typeof this['on' + type] === 'function') {
+	    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+	      args[_key - 1] = arguments[_key]
+	    }
+
+	    this['on' + type].apply(this, args)
+	  }
+	}
+
+	function _changeReadyState(readyState) {
+	  this.readyState = readyState
+	  _triggerEvent.call(this, 'readystatechange')
+	}
+
+	var XMLHttpRequest = function () {
+	  // TODO 没法模拟 HEADERS_RECEIVED 和 LOADING 两个状态
+	  function XMLHttpRequest() {
+	    _classCallCheck(this, XMLHttpRequest)
+
+	    this.onabort = null
+	    this.onerror = null
+	    this.onload = null
+	    this.onloadstart = null
+	    this.onprogress = null
+	    this.ontimeout = null
+	    this.onloadend = null
+	    this.onreadystatechange = null
+	    this.readyState = 0
+	    this.response = null
+	    this.responseText = null
+	    this.responseType = ''
+	    this.responseXML = null
+	    this.status = 0
+	    this.statusText = ''
+	    this.upload = {}
+	    this.withCredentials = false
+
+	    _requestHeader.set(this, {
+	      'content-type': 'application/x-www-form-urlencoded'
+	    })
+	    _responseHeader.set(this, {})
+	  }
+
+	  /*
+	   * TODO 这一批事件应该是在 XMLHttpRequestEventTarget.prototype 上面的
+	   */
+
+
+	  _createClass(XMLHttpRequest, [{
+	    key: 'abort',
+	    value: function abort() {
+	      var myRequestTask = _requestTask.get(this)
+
+	      if (myRequestTask) {
+	        myRequestTask.abort()
+	      }
+	    }
+	  }, {
+	    key: 'getAllResponseHeaders',
+	    value: function getAllResponseHeaders() {
+	      var responseHeader = _responseHeader.get(this)
+
+	      return Object.keys(responseHeader).map(function (header) {
+	        return header + ': ' + responseHeader[header]
+	      }).join('\n')
+	    }
+	  }, {
+	    key: 'getResponseHeader',
+	    value: function getResponseHeader(header) {
+	      return _responseHeader.get(this)[header]
+	    }
+	  }, {
+	    key: 'open',
+	    value: function open(method, url /* async, user, password 这几个参数在小程序内不支持*/) {
+	      _method.set(this, method)
+	      _url.set(this, url)
+	      _changeReadyState.call(this, XMLHttpRequest.OPENED)
+	    }
+	  }, {
+	    key: 'overrideMimeType',
+	    value: function overrideMimeType() {}
+	  }, {
+	    key: 'send',
+	    value: function send() {
+	      var _this = this
+
+	      var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''
+
+	      if (this.readyState !== XMLHttpRequest.OPENED) {
+	        throw new Error("Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.")
+	      } else {
+	        wx.request({
+	          data: data,
+	          url: _url.get(this),
+	          method: _method.get(this),
+	          header: _requestHeader.get(this),
+	          responseType: this.responseType,
+	          success: function success(_ref) {
+	            var data = _ref.data,
+	                statusCode = _ref.statusCode,
+	                header = _ref.header
+
+	            if (typeof data !== 'string' && !(data instanceof ArrayBuffer)) {
+	              try {
+	                data = JSON.stringify(data)
+	              } catch (e) {
+	                data = data
+	              }
+	            }
+
+	            _this.status = statusCode
+	            _responseHeader.set(_this, header)
+	            _triggerEvent.call(_this, 'loadstart')
+	            _changeReadyState.call(_this, XMLHttpRequest.HEADERS_RECEIVED)
+	            _changeReadyState.call(_this, XMLHttpRequest.LOADING)
+
+	            _this.response = data
+
+	            if (data instanceof ArrayBuffer) {
+	              _this.responseText = ''
+	              var bytes = new Uint8Array(data)
+	              var len = bytes.byteLength
+
+	              for (var i = 0; i < len; i++) {
+	                _this.responseText += String.fromCharCode(bytes[i])
+	              }
+	            } else {
+	              _this.responseText = data
+	            }
+	            _changeReadyState.call(_this, XMLHttpRequest.DONE)
+	            _triggerEvent.call(_this, 'load')
+	            _triggerEvent.call(_this, 'loadend')
+	          },
+	          fail: function fail(_ref2) {
+	            var errMsg = _ref2.errMsg
+
+	            // TODO 规范错误
+	            if (errMsg.indexOf('abort') !== -1) {
+	              _triggerEvent.call(_this, 'abort')
+	            } else {
+	              _triggerEvent.call(_this, 'error', errMsg)
+	            }
+	            _triggerEvent.call(_this, 'loadend')
+	          }
+	        })
+	      }
+	    }
+	  }, {
+	    key: 'setRequestHeader',
+	    value: function setRequestHeader(header, value) {
+	      var myHeader = _requestHeader.get(this)
+
+	      myHeader[header] = value
+	      _requestHeader.set(this, myHeader)
+	    }
+	  }])
+
+	  return XMLHttpRequest
+	}()
+
+	XMLHttpRequest.UNSEND = 0
+	XMLHttpRequest.OPENED = 1
+	XMLHttpRequest.HEADERS_RECEIVED = 2
+	XMLHttpRequest.LOADING = 3
+	XMLHttpRequest.DONE = 4
+	exports.default = XMLHttpRequest
+
+/***/ }),
+/* 19 */
+/***/ (function(module, exports) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor } }()
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	var _socketTask = new WeakMap()
+
+	var WebSocket = function () {
+	  // TODO 更新 binaryType
+	  // The connection is in the process of closing.
+	  // The connection is not yet open.
+	  function WebSocket(url) {
+	    var _this = this
+
+	    var protocols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []
+
+	    _classCallCheck(this, WebSocket)
+
+	    this.binaryType = ''
+	    this.bufferedAmount = 0
+	    this.extensions = ''
+	    this.onclose = null
+	    this.onerror = null
+	    this.onmessage = null
+	    this.onopen = null
+	    this.protocol = ''
+	    this.readyState = 3
+
+	    if (typeof url !== 'string' || !/(^ws:\/\/)|(^wss:\/\/)/.test(url)) {
+	      throw new TypeError('Failed to construct \'WebSocket\': The URL \'' + url + '\' is invalid')
+	    }
+
+	    this.url = url
+	    this.readyState = WebSocket.CONNECTING
+
+	    var socketTask = wx.connectSocket({
+	      url: url,
+	      protocols: Array.isArray(protocols) ? protocols : [protocols]
+	    })
+
+	    _socketTask.set(this, socketTask)
+
+	    socketTask.onClose(function (res) {
+	      _this.readyState = WebSocket.CLOSED
+	      if (typeof _this.onclose === 'function') {
+	        _this.onclose(res)
+	      }
+	    })
+
+	    socketTask.onMessage(function (res) {
+	      if (typeof _this.onmessage === 'function') {
+	        _this.onmessage(res)
+	      }
+	    })
+
+	    socketTask.onOpen(function () {
+	      _this.readyState = WebSocket.OPEN
+	      if (typeof _this.onopen === 'function') {
+	        _this.onopen()
+	      }
+	    })
+
+	    socketTask.onError(function (res) {
+	      if (typeof _this.onerror === 'function') {
+	        _this.onerror(new Error(res.errMsg))
+	      }
+	    })
+
+	    return this
+	  } // TODO 小程序内目前获取不到,实际上需要根据服务器选择的 sub-protocol 返回
+	  // TODO 更新 bufferedAmount
+	  // The connection is closed or couldn't be opened.
+
+	  // The connection is open and ready to communicate.
+
+
+	  _createClass(WebSocket, [{
+	    key: 'close',
+	    value: function close(code, reason) {
+	      this.readyState = WebSocket.CLOSING
+	      var socketTask = _socketTask.get(this)
+
+	      socketTask.close({
+	        code: code,
+	        reason: reason
+	      })
+	    }
+	  }, {
+	    key: 'send',
+	    value: function send(data) {
+	      if (typeof data !== 'string' && !(data instanceof ArrayBuffer)) {
+	        throw new TypeError('Failed to send message: The data ' + data + ' is invalid')
+	      }
+
+	      var socketTask = _socketTask.get(this)
+
+	      socketTask.send({
+	        data: data
+	      })
+	    }
+	  }])
+
+	  return WebSocket
+	}()
+
+	WebSocket.CONNECTING = 0
+	WebSocket.OPEN = 1
+	WebSocket.CLOSING = 2
+	WebSocket.CLOSED = 3
+	exports.default = WebSocket
+
+/***/ }),
+/* 20 */
+/***/ (function(module, exports) {
+
+	"use strict"
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function") } }
+
+	/*
+	 * TODO 使用 wx.readFile 来封装 FileReader
+	 */
+	var FileReader = function FileReader() {
+	  _classCallCheck(this, FileReader)
+	}
+
+	exports.default = FileReader
+
+/***/ }),
+/* 21 */
+/***/ (function(module, exports) {
+
+	"use strict"
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+	var localStorage = {
+	  get length() {
+	    var _wx$getStorageInfoSyn = wx.getStorageInfoSync(),
+	        keys = _wx$getStorageInfoSyn.keys
+
+	    return keys.length
+	  },
+
+	  key: function key(n) {
+	    var _wx$getStorageInfoSyn2 = wx.getStorageInfoSync(),
+	        keys = _wx$getStorageInfoSyn2.keys
+
+	    return keys[n]
+	  },
+	  getItem: function getItem(key) {
+	    return wx.getStorageSync(key)
+	  },
+	  setItem: function setItem(key, value) {
+	    return wx.setStorageSync(key, value)
+	  },
+	  removeItem: function removeItem(key) {
+	    wx.removeStorageSync(key)
+	  },
+	  clear: function clear() {
+	    wx.clearStorageSync()
+	  }
+	}
+
+	exports.default = localStorage
+
+/***/ }),
+/* 22 */
+/***/ (function(module, exports) {
+
+	'use strict'
+
+	Object.defineProperty(exports, "__esModule", {
+	  value: true
+	})
+	var location = {
+	  href: 'game.js',
+	  reload: function reload() {}
+	}
+
+	exports.default = location
+
+/***/ })
+/******/ ])

+ 462 - 0
wx/js/main.back.js

@@ -0,0 +1,462 @@
+import Support from "./base/support";
+// import Animation from "./base/animation";
+// 
+let support = new Support()
+// let animation = new Animation()
+
+var board = new Array();
+var score = 0;
+var topScore = 0;
+var hasConflicted = new Array();
+var direction = {
+  left: 1,
+  up: 2,
+  down: 3,
+  right: 4
+};
+
+
+// import Player     from './player/index'
+// import Support  from '../js/base/support'
+/**
+ * 底层背景, 读取屏幕的宽高, 设置棋盘边长
+ */
+let context = canvas.getContext('2d')
+var bgw = canvas.width
+var bgh = canvas.height
+console.log(bgw, bgh)
+var bdsl = 0.92 * bgw
+
+
+
+
+let startX //触摸时的坐标   
+let startY
+let x //滑动的距离   
+let y
+let aboveY = 0 // 设一个全局变量记录上一次内部块滑动的位置  
+
+/**
+ * 游戏主函数
+ */
+export default class Main {
+  constructor() {
+
+    this.backGround()
+
+    // 维护当前requestAnimationFrame的id
+    this.aniId = 0
+
+    this.restart()
+  }
+
+  backGround() {
+    context.fillStyle = '#F0F0F0'
+    context.fillRect(0, 0, bgw, bgh)
+    context.fillStyle = '#8F7A66'
+    context.fillRect(0.05 * bgw, 50, 0.2 * bgw, 0.16 * bgw)
+    context.fillStyle = '#BAAB9E'
+    context.fillRect(0.3 * bgw, 50, 0.3 * bgw, 0.16 * bgw)
+    context.fillStyle = '#F7921E'
+    context.fillRect(0.65 * bgw, 50, 0.3 * bgw, 0.16 * bgw)
+    context.fillStyle = 'white'
+    context.font = "30px Arial"
+    context.fillText("重玩", 0.07 * bgw, 50 + 0.1 * bgw);
+    context.font = "20px Arial"
+    context.fillText("最高分数", 0.35 * bgw, 50 + 0.06 * bgw);
+    context.fillText("当前分数", 0.7 * bgw, 50 + 0.06 * bgw);
+
+    // 棋盘背景
+    context.fillStyle = '#BBADA0'
+    context.fillRect(0.04 * bgw, 0.45 * bgw, bdsl, bdsl)
+  }
+
+  restart() {
+    //初始化棋盘格
+    this.init();
+    //在随机两个格子生成数字
+    this.generateOneNumber();
+    this.generateOneNumber();
+    this.updateBoardView();
+    score = 0;
+
+    // canvas.removeEventListener(
+    //   'touchstart',
+    //   this.touchHandler
+    // )
+
+    // this.bg       = new BackGround(ctx)
+    // this.player   = new Player(ctx)
+    // this.gameinfo = new GameInfo()
+    // this.music    = new Music()
+
+    // this.bindLoop     = this.loop.bind(this)
+    this.hasEventBind = false
+
+    // 清除上一局的动画
+    // window.cancelAnimationFrame(this.aniId);
+
+    // this.aniId = window.requestAnimationFrame(
+    //   this.bindLoop,
+    //   canvas
+    // )
+    // 监听滑动事件
+    canvas.addEventListener('touchstart', this.touchStart.bind(this), false);
+    canvas.addEventListener('touchmove', this.touchMove.bind(this), false);
+    canvas.addEventListener('touchend', this.touchEnd.bind(this), false);
+  }
+
+  init() {
+    for (var i = 0; i < 4; i++) {
+      for (var j = 0; j < 4; j++) {
+        context.fillStyle = '#CCC0B3'
+        context.fillRect(support.getPostionLeft(i, j) + 0.03 * bgw, support.getPostionTop(i, j) + 0.44 * bgw, 0.214 * bdsl, 0.214 * bdsl)
+      }
+    }
+
+    //初始化棋盘
+    for (var i = 0; i < 4; i++) {
+      board[i] = new Array();
+      hasConflicted[i] = new Array();
+      for (var j = 0; j < 4; j++) {
+        board[i][j] = 0;
+        hasConflicted[i][j] = false;
+      }
+    }
+    console.log(board);
+    //更新面板
+    this.updateBoardView();
+  }
+
+  updateBoardView() {
+    // context.clearRect(0.04*bgw, 0.45*bgw, bdsl, bdsl) //更新之前先删除元素
+    // context.fillRect(0.04*bgw, 0.45*bgw, bdsl, bdsl)
+    for (var i = 0; i < 4; i++) {
+      for (var j = 0; j < 4; j++) {
+        //重新生成16个矩形, 并添加到容器中
+        var offScreenCanvas = wx.createCanvas()
+        var offContext = offScreenCanvas.getContext('2d')
+
+        if (board[i][j] == 0) {
+          offContext.fillStyle = '#CCC0B3'
+          offContext.fillRect(support.getPostionLeft(i, j) + 0.04 * bgw, support.getPostionTop(i, j) + 0.44 * bgw, 0.214 * bdsl, 0.214 * bdsl)
+          // 绘制无字空图
+          context.drawImage(offScreenCanvas, 0, 0)
+        } else {
+          //根据数字颜色设置器背景色
+          offContext.fillStyle = support.getBackgroundColorByNum(board[i][j])
+          offContext.fillRect(support.getPostionLeft(i, j) + 0.04 * bgw, support.getPostionTop(i, j) + 0.44 * bgw, 0.214 * bdsl, 0.214 * bdsl)
+          //设置前景字颜色
+          offContext.fillStyle = support.getPreColorByNum(board[i][j])
+          //显示数字(文字)
+          offContext.font = "18px Arial"
+          offContext.fillText(support.getShowTextByNum(board[i][j]), support.getPostionLeft(i, j) + 0.05 * bgw, support.getPostionTop(i, j) + 0.55 * bgw);
+
+          context.drawImage(offScreenCanvas, 0, 0)
+          hasConflicted[i][j] = false;
+        }
+      }
+    }
+  }
+
+  generateOneNumber() {
+    if (support.isNoSpace(board)) {
+      return false;
+    }
+    //随机一个位置
+    var randx = parseInt(Math.floor(Math.random() * 4));
+    var randy = parseInt(Math.floor(Math.random() * 4));
+    //判断生成的坐标是否合理(无值,位置即可使用)
+    while (true) {
+      if (board[randx][randy] === 0)
+        break;
+      //若果该坐标存在了值,即不合理,继续生成随机一个位置
+      randx = parseInt(Math.floor(Math.random() * 4));
+      randy = parseInt(Math.floor(Math.random() * 4));
+    }
+
+    //随机一个数字
+    var randNum = Math.random() < 0.4 ? 2 : 4;
+    board[randx][randy] = randNum;
+    showNumberWithAnimation(randx, randy, randNum);
+    return true;
+  }
+
+  /**
+   * 滑动处理 1, 左滑; 2, 上滑, 3, 右滑; 4, 下滑
+   */
+  slideDirection(numm) {
+    switch (numm) {
+      case 1: //left
+        if (this.moveLeft()) {
+          setTimeout(this.generateOneNumber, 210);
+          setTimeout(this.isGameOver, 300);
+        }
+        break;
+      case 2: //up
+        if (this.moveUp()) {
+          setTimeout(this.generateOneNumber, 210);
+          setTimeout(this.isGameOver, 300);
+        }
+        break;
+      case 3: //right
+        if (this.moveRight()) {
+          setTimeout(this.generateOneNumber, 210);
+          setTimeout(this.isGameOver, 300);
+        }
+        break;
+      case 4: //down
+        if (this.moveDown()) {
+          setTimeout(this.generateOneNumber, 210);
+          setTimeout(this.isGameOver, 300);
+        }
+        break;
+      default:
+        break;
+    }
+  }
+
+  moveLeft() {
+    if (!support.canMove(board, direction.left))
+      return false;
+    //左移
+    for (var i = 0; i < 4; i++) {
+      for (var j = 1; j < 4; j++) {
+        if (board[i][j] !== 0) {
+          for (var k = 0; k < j; k++)
+            //可以一次移动多个格子
+            if (board[i][k] == 0 && support.noBlockHorizontal(i, k, j, board)) {
+              //move
+              // showMoveAnimation(i, j, i, k);
+              board[i][k] = board[i][j];
+              board[i][j] = 0;
+              continue;
+            } else if (board[i][k] == board[i][j] && support.noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) {
+            //move
+            // showMoveAnimation(i, j, i, k);
+            //add
+            board[i][k] += board[i][j];
+            board[i][j] = 0;
+            // var element = $("#grid-cell-" + i + k);
+            // anp(element, board[i][k])
+            score += board[i][k];
+            this.updateScore(score);
+            // updateTopScore(score);
+            continue;
+          }
+        }
+      }
+    }
+    setTimeout(this.updateBoardView, 200);  //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  moveRight() {
+    if (!support.canMove(board, direction.right))
+      return false;
+    //右移
+    for (var i = 3; i >= 0; i--) {
+      for (var j = 2; j >= 0; j--) {
+        //该位置不等于0即可进行移动
+        if (board[i][j] != 0)
+          for (var k = 3; k > j; k--) {
+            //如果可以一次移动多个格子
+            if (board[i][k] == 0 && support.noBlockHorizontal(i, j, k, board)) {
+              //move
+              // showMoveAnimation(i, j, i, k);
+              board[i][k] = board[i][j];
+              board[i][j] = 0;
+              continue;
+            } else if (board[i][k] == board[i][j] && support.noBlockHorizontal(i, j, k, board) && !hasConflicted[i][k]) {
+              //move
+              // showMoveAnimation(i, j, i, k);
+              //add
+              board[i][k] += board[i][j];
+              board[i][j] = 0;
+              score += board[i][k];
+              // var element = $("#grid-cell-" + i + k);
+              // anp(element, board[i][k])
+              this.updateScore(score);
+              // updateTopScore(score);
+              continue;
+            }
+          }
+      }
+    }
+    setTimeout(this.updateBoardView, 200);  //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  /**
+    先判断第一列*/
+  moveUp() {
+    if (!support.canMove(board, direction.up))
+      return false;
+    for (var i = 0; i < 4; i++) {
+      for (var j = 1; j < 4; j++) {
+        //该位置不为0即可进行移动
+        if (board[j][i] != 0) {
+          for (var k = 0; k < j; k++) {
+            if (board[k][i] == 0 && support.noBlockVectal(i, k, j, board)) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] = board[j][i];
+              board[j][i] = 0;
+              continue;
+            } else if (board[k][i] == board[j][i] && support.noBlockVectal(i, k, j, board) && !hasConflicted[k][i]) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] += board[j][i];
+              board[j][i] = 0;
+              score += board[k][i];
+              // var element = $("#grid-cell-" + k + i);
+              // anp(element, board[k][i])
+              this.updateScore(score);
+              continue;
+            }
+          }
+        }
+      }
+    }
+    setTimeout(this.updateBoardView, 200);  //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  /**
+    先判断第一列*/
+  moveDown() {
+    if (!support.canMove(board, direction.down))
+      return false;
+    for (var i = 3; i >= 0; i--) {
+      for (var j = 2; j >= 0; j--) {
+        //该位置不为0即可进行移动
+        if (board[j][i] != 0) {
+          for (var k = 3; k > j; k--) {
+            if (board[k][i] == 0 && support.noBlockVectal(i, j, k, board)) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] = board[j][i];
+              board[j][i] = 0;
+              continue;
+            } else if (board[k][i] == board[j][i] && support.noBlockVectal(i, j, k, board) && !hasConflicted[k][i]) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] += board[j][i];
+              board[j][i] = 0;
+              score += board[k][i];
+              // var element = $("#grid-cell-" + k + i);
+              // anp(element, board[k][i])
+              this.updateScore(score);
+              continue;
+            }
+          }
+        }
+      }
+    }
+    // this.updateBoardView()
+    setTimeout(this.updateBoardView, 200); //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  isGameOver() {
+    if (support.isNoSpace(board) && !support.canMoveALL(board)) {
+      this.gameOver();
+    }
+  }
+
+  gameOver() {
+    alert("游戏结束!");
+  }
+
+  touchStart(e) { //触摸开始
+    e.preventDefault();
+    var touch = e.touches[0];
+    startX = touch.pageX; //刚触摸时的坐标
+    startY = touch.pageY; //刚触摸时的坐标
+  }
+
+  touchMove(e) { //滑动
+    e.preventDefault();
+    var touch = e.touches[0];
+    x = touch.pageX - startX; //滑动的距离
+    y = touch.pageY - startY; //滑动的距离      
+  }
+
+  touchEnd(e) { //手指离开屏幕
+    // console.log(x);
+    // console.log(y);
+    
+    var xy = Math.abs(x) - Math.abs(y);
+    var d = 0;
+    if (xy > 0) {
+      if (x >= 0) {
+        d = 3;
+      } else {
+        d = 1;
+      }
+    } else {
+      if (y >= 0) {
+        d = 4;
+      } else {
+        d = 2;
+      }
+    }
+
+    this.slideDirection(d);
+  }
+
+
+  /**
+   * 
+   * 更新最新分数和最高分数
+   */
+  updateScore(score) {
+    // $("#score").text(score);
+    if (topScore < score) {
+      // $("#top_score").text(score);
+      topScore = score;
+      return true;
+    } else {
+      return true;
+      // $("#top_score").text(topScore);
+    }
+  }
+
+  // 游戏结束后的触摸事件处理逻辑
+  // touchEventHandler(e) {
+  //   e.preventDefault()
+
+  //   let x = e.touches[0].clientX
+  //   let y = e.touches[0].clientY
+
+  //   let area = this.gameinfo.btnArea
+
+  //   if (x >= area.startX &&
+  //     x <= area.endX &&
+  //     y >= area.startY &&
+  //     y <= area.endY)
+  //     this.restart()
+  // }
+}
+
+
+/********************* animation */
+function showNumberWithAnimation(randx, randy, randNum) {
+  var offScreenCanvas = wx.createCanvas()
+  var offContext = offScreenCanvas.getContext('2d')
+  offContext.fillStyle = support.getBackgroundColorByNum(randNum)
+  offContext.fillRect(support.getPostionLeft(randx, randy) + 0.03 * bgw, support.getPostionTop(randx, randy) + 0.44 * bgw, 0.22 * bdsl, 0.214 * bdsl)
+
+  offContext.fillStyle = support.getPreColorByNum(randNum)
+  offContext.font = "18px Arial"
+  //显示数字
+  offContext.fillText(support.getShowTextByNum(randNum), support.getPostionLeft(randx, randy) + 0.05 * bgw, support.getPostionTop(randx, randy) + 0.55 * bgw)
+
+  context.drawImage(offScreenCanvas, 0, 0)
+  // numberCell.animate({
+  //   width: cellSideLength,
+  //   height: cellSideLength,
+  //   top: getPostionTop(randx, randy),
+  //   left: getPostionLeft(randx, randy)
+  // }, 100);
+}

+ 442 - 0
wx/js/main.js

@@ -0,0 +1,442 @@
+import BackGround from './base/background'
+import Support from "./base/support"
+
+wx.setPreferredFramesPerSecond(12)
+wx.showShareMenu()
+
+let ctx = canvas.getContext('2d')
+var w = canvas.width
+var h = canvas.height
+var csl = 0.18 * w
+var fsz = 0.07 * w
+
+var fontstyle = fsz + "px 楷体"
+
+
+let sp = new Support(w, h)
+
+var board = new Array();
+var score = 0;
+var topScore = 0;
+var hasConflicted = new Array();
+var direction = {
+  left: 1,
+  up: 2,
+  down: 3,
+  right: 4
+};
+
+
+let startX //触摸时的坐标   
+let startY
+let x //滑动的距离   
+let y
+
+/**
+ * 游戏主函数
+ */
+export default class Main {
+  constructor() {
+    // 维护当前requestAnimationFrame的id
+    this.aniId = 0
+
+    this.restart()
+    // 激活重启按钮事件
+    wx.onTouchStart(this.touchEventHandler.bind(this))
+
+    // 开启滑动事件监听
+    wx.onTouchStart(this.touchStart)
+    wx.onTouchMove(this.touchMove)
+    wx.onTouchEnd(this.touchEnd.bind(this))
+  }
+
+  restart() {
+    // console.log(w, h)
+    this.bg = new BackGround(ctx, w, h)
+
+    // 获取本地存储的最高分数(若有)
+    wx.getStorage({
+      key: "topScore",
+      success(res) {
+        // console.log(res.data)
+        topScore = res.data
+      }
+    })
+    // 重置当前分数
+    score = 0;
+    // 显示新分数
+    this.updateScore(score)
+
+    // 初始化棋盘格
+    this.init();
+    // 在随机两个格子生成数字
+    this.generateOneNumber();
+    this.generateOneNumber();
+    // 更新游戏面板
+    this.render();
+  }
+
+  init() {
+    for (var i = 0; i < 4; i++) {
+      for (var j = 0; j < 4; j++) {
+        ctx.fillStyle = '#CCC0B3'
+        ctx.fillRect(sp.getPostionLeft(i, j), sp.getPostionTop(i, j), csl, csl)
+      }
+    }
+
+    //初始化棋盘
+    for (var i = 0; i < 4; i++) {
+      board[i] = new Array();
+      hasConflicted[i] = new Array();
+      for (var j = 0; j < 4; j++) {
+        board[i][j] = 0;
+        hasConflicted[i][j] = false;
+      }
+    }
+    // console.log(board);
+    //更新面板
+    this.render();
+  }
+
+  // 棋盘重绘
+  render() {
+    // 清空棋盘, 重新刷新
+    ctx.clearRect(20.04 * w, 50 + 0.3 * w, 0.92 * w, 0.92 * w);
+    ctx.fillStyle = '#BBADA0'
+    ctx.fillRect(0.04 * w, 50 + 0.3 * w, 0.92 * w, 0.92 * w)
+    for (var i = 0; i < 4; i++) {
+      for (var j = 0; j < 4; j++) {
+        if (board[i][j] == 0) {
+          // 绘制无字空图
+          ctx.fillStyle = '#CCC0B3'
+          ctx.fillRect(sp.getPostionLeft(i, j), sp.getPostionTop(i, j), csl, csl)
+        } else {
+          // 根据数字颜色设置器背景色
+          ctx.fillStyle = sp.getBackgroundColorByNum(board[i][j])
+          ctx.fillRect(sp.getPostionLeft(i, j), sp.getPostionTop(i, j), csl, csl)
+          // 设置文字颜色, 大小, 字体, 对其方式
+          ctx.fillStyle = sp.getPreColorByNum(board[i][j])
+          // 显示数字(文字)
+          ctx.font = fontstyle
+          ctx.textAlign = "left"
+          ctx.textBaseline = "top"
+          // 获取文字
+          var st = sp.getShowTextByNum(board[i][j])
+          // 将4字分两行绘制(有5字的份为前3后2)
+
+          var st2 = st.slice(-2)
+          var st1 = st.slice(0, st.length - 2)
+
+          ctx.fillText(st1, sp.getPostionLeft(i, j) + 0.02 * w, sp.getPostionTop(i, j) + 0.01 * w);
+          ctx.fillText(st2, sp.getPostionLeft(i, j) + 0.02 * w, sp.getPostionTop(i, j) + fsz + 0.02 * w);
+
+          hasConflicted[i][j] = false;
+        }
+      }
+    }
+  }
+
+  generateOneNumber() {
+    if (sp.isNoSpace(board)) {
+      return false;
+    }
+    //随机一个位置
+    var randx = parseInt(Math.floor(Math.random() * 4));
+    var randy = parseInt(Math.floor(Math.random() * 4));
+    //判断生成的坐标是否合理(无值,位置即可使用)
+    while (true) {
+      if (board[randx][randy] === 0)
+        break;
+      //若果该坐标存在了值,即不合理,继续生成随机一个位置
+      randx = parseInt(Math.floor(Math.random() * 4));
+      randy = parseInt(Math.floor(Math.random() * 4));
+    }
+
+    //随机一个数字
+    var randNum = Math.random() < 0.6 ? 2 : 4;
+    board[randx][randy] = randNum;
+    // showNumberWithAnimation(randx, randy, randNum);
+    this.render()
+    return true;
+  }
+
+  /**
+   * 滑动处理 1, 左滑; 2, 上滑, 3, 右滑; 4, 下滑
+   */
+  slideDirection(numm) {
+    switch (numm) {
+      case 1: //left
+        if (this.moveLeft()) {
+          setTimeout(this.generateOneNumber.bind(this), 210);
+          setTimeout(this.isGameOver.bind(this), 300);
+        }
+        break;
+      case 2: //up
+        if (this.moveUp()) {
+          setTimeout(this.generateOneNumber.bind(this), 210);
+          setTimeout(this.isGameOver.bind(this), 300);
+        }
+        break;
+      case 3: //right
+        if (this.moveRight()) {
+          setTimeout(this.generateOneNumber.bind(this), 210);
+          setTimeout(this.isGameOver.bind(this), 300);
+        }
+        break;
+      case 4: //down
+        if (this.moveDown()) {
+          setTimeout(this.generateOneNumber.bind(this), 210);
+          setTimeout(this.isGameOver.bind(this), 300);
+        }
+        break;
+      default:
+        break;
+    }
+  }
+
+  moveLeft() {
+    if (!sp.canMove(board, direction.left))
+      return false;
+    //左移
+    for (var i = 0; i < 4; i++) {
+      for (var j = 1; j < 4; j++) {
+        if (board[i][j] !== 0) {
+          for (var k = 0; k < j; k++)
+            //可以一次移动多个格子
+            if (board[i][k] == 0 && sp.noBlockHorizontal(i, k, j, board)) {
+              //move
+              // showMoveAnimation(i, j, i, k);
+              board[i][k] = board[i][j];
+              board[i][j] = 0;
+              continue;
+            } else if (board[i][k] == board[i][j] && sp.noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) {
+            //move
+            // showMoveAnimation(i, j, i, k);
+            //add
+            board[i][k] += board[i][j];
+            board[i][j] = 0;
+            // var element = $("#grid-cell-" + i + k);
+            // anp(element, board[i][k])
+            score += board[i][k];
+            this.updateScore(score)
+            continue;
+          }
+        }
+      }
+    }
+    setTimeout(this.render, 200); //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  moveRight() {
+    if (!sp.canMove(board, direction.right))
+      return false;
+    //右移
+    for (var i = 3; i >= 0; i--) {
+      for (var j = 2; j >= 0; j--) {
+        //该位置不等于0即可进行移动
+        if (board[i][j] != 0)
+          for (var k = 3; k > j; k--) {
+            //如果可以一次移动多个格子
+            if (board[i][k] == 0 && sp.noBlockHorizontal(i, j, k, board)) {
+              //move
+              // showMoveAnimation(i, j, i, k);
+              board[i][k] = board[i][j];
+              board[i][j] = 0;
+              continue;
+            } else if (board[i][k] == board[i][j] && sp.noBlockHorizontal(i, j, k, board) && !hasConflicted[i][k]) {
+              //move
+              // showMoveAnimation(i, j, i, k);
+              //add
+              board[i][k] += board[i][j];
+              board[i][j] = 0;
+              score += board[i][k];
+              // var element = $("#grid-cell-" + i + k);
+              // anp(element, board[i][k])
+              this.updateScore(score)
+              continue;
+            }
+          }
+      }
+    }
+    setTimeout(this.render, 200); //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  /**
+    先判断第一列*/
+  moveUp() {
+    if (!sp.canMove(board, direction.up))
+      return false;
+    for (var i = 0; i < 4; i++) {
+      for (var j = 1; j < 4; j++) {
+        //该位置不为0即可进行移动
+        if (board[j][i] != 0) {
+          for (var k = 0; k < j; k++) {
+            if (board[k][i] == 0 && sp.noBlockVectal(i, k, j, board)) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] = board[j][i];
+              board[j][i] = 0;
+              continue;
+            } else if (board[k][i] == board[j][i] && sp.noBlockVectal(i, k, j, board) && !hasConflicted[k][i]) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] += board[j][i];
+              board[j][i] = 0;
+              score += board[k][i];
+              // var element = $("#grid-cell-" + k + i);
+              // anp(element, board[k][i])
+              this.updateScore(score);
+              continue;
+            }
+          }
+        }
+      }
+    }
+    setTimeout(this.render, 200); //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  /**
+    先判断第一列*/
+  moveDown() {
+    if (!sp.canMove(board, direction.down))
+      return false;
+    for (var i = 3; i >= 0; i--) {
+      for (var j = 2; j >= 0; j--) {
+        //该位置不为0即可进行移动
+        if (board[j][i] != 0) {
+          for (var k = 3; k > j; k--) {
+            if (board[k][i] == 0 && sp.noBlockVectal(i, j, k, board)) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] = board[j][i];
+              board[j][i] = 0;
+              continue;
+            } else if (board[k][i] == board[j][i] && sp.noBlockVectal(i, j, k, board) && !hasConflicted[k][i]) {
+              //move
+              // showMoveAnimation(j, i, k, i);
+              board[k][i] += board[j][i];
+              board[j][i] = 0;
+              score += board[k][i];
+              // var element = $("#grid-cell-" + k + i);
+              // anp(element, board[k][i])
+              this.updateScore(score);
+              continue;
+            }
+          }
+        }
+      }
+    }
+    // this.render()
+    setTimeout(this.render, 200) //等待200在执行更新面板操作,避免动画效果被冲掉
+    return true
+  }
+
+  isGameOver() {
+    if (sp.isNoSpace(board) && !sp.canMoveAll(board)) {
+      this.gameOver()
+    }
+  }
+
+  gameOver() {
+    // 本地存储最高分数
+    wx.setStorage({
+      key: "topScore",
+      data: topScore
+    })
+    // 棋盘中出现 游戏结束!C2B6AB
+    ctx.fillStyle = '#F7921E'
+    ctx.fillRect(0.2 * w, 50 + 0.56 * w, 0.6 * w, 0.4 * w)
+    ctx.fillStyle = 'white'
+    ctx.font = "40px 微软雅黑"
+    ctx.textAlign = "center"
+    ctx.textBaseline = "middle"
+    ctx.fillText("游戏结束!", 0.5 * w, 50 + 0.76 * w);
+    console.log("游戏结束!")
+    // alert("游戏结束!")
+  }
+
+  /**
+   * 滑动处理 touchStart 记录起点; touchMove 记录x,y方向分别移动的距离; touchEnd 判断移动方向
+   */
+  touchStart(e) {
+    var touch = e.touches[0]
+    startX = touch.pageX //刚触摸时的坐标
+    startY = touch.pageY //刚触摸时的坐标
+  }
+
+  touchMove(e) { //滑动
+    var touch = e.touches[0]
+    x = touch.pageX - startX //滑动的距离
+    y = touch.pageY - startY //滑动的距离      
+  }
+
+  touchEnd(e) { //手指离开屏幕
+    // console.log(x)
+    // console.log(y)
+    var xy = Math.abs(x) - Math.abs(y)
+    var d = 0
+    if (xy > 0) {
+      if (x >= 0) {
+        d = 3
+      } else {
+        d = 1
+      }
+    } else {
+      if (y >= 0) {
+        d = 4
+      } else {
+        d = 2
+      }
+    }
+
+    this.slideDirection(d)
+  }
+
+  /**
+   * 
+   * 更新最新分数和最高分数
+   */
+  updateScore(score) {
+    // 清除去原分数
+    ctx.clearRect(0.28 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w);
+    ctx.fillStyle = '#BAAB9E'
+    ctx.fillRect(0.28 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w)
+    ctx.clearRect(0.64 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w);
+    ctx.fillStyle = '#F7921E'
+    ctx.fillRect(0.64 * w, 50 + 0.08 * w, 0.32 * w, 0.08 * w)
+
+    if (topScore < score) {
+      topScore = score;
+    }
+    // 显示新分数
+    ctx.fillStyle = 'white'
+    ctx.font = "20px 微软雅黑"
+    ctx.textAlign = "center"
+    ctx.textBaseline = "top"
+    ctx.fillText(score, 0.8 * w, 50 + 0.08 * w);
+    ctx.fillText(topScore, 0.44 * w, 50 + 0.08 * w);
+
+    return true;
+  }
+
+  /**
+   * 游戏结束激活处理事件
+   */
+  touchEventHandler(e) {
+    var touch = e.touches[0]
+    var cx = touch.clientX
+    var cy = touch.clientY
+
+    var area = this.bg.btnArea
+
+    if (cx >= area.startX &&
+      cx <= area.endX &&
+      cy >= area.startY &&
+      cy <= area.endY) {
+      this.restart()
+    }
+  }
+}

+ 32 - 0
wx/project.config.json

@@ -0,0 +1,32 @@
+{
+	"description": "项目配置文件。",
+	"setting": {
+		"urlCheck": false,
+		"es6": true,
+		"postcss": true,
+		"minified": true,
+		"newFeature": true
+	},
+	"compileType": "game",
+	"libVersion": "2.4.0",
+	"appid": "wx09004548f578e32c",
+	"projectname": "2048之陈小发",
+	"condition": {
+		"search": {
+			"current": -1,
+			"list": []
+		},
+		"conversation": {
+			"current": -1,
+			"list": []
+		},
+		"game": {
+			"currentL": -1,
+			"list": []
+		},
+		"miniprogram": {
+			"current": -1,
+			"list": []
+		}
+	}
+}