├── .gitignore ├── LICENSE ├── README.md ├── assets ├── animation.meta ├── animation │ ├── end.anim │ ├── end.anim.meta │ ├── label.meta │ ├── label │ │ ├── hideAndShow.anim │ │ └── hideAndShow.anim.meta │ ├── select.meta │ └── select │ │ ├── select.anim │ │ └── select.anim.meta ├── ezaction.meta ├── ezaction │ ├── HActionInstant.js │ ├── HActionInstant.js.meta │ ├── HActionInterval.js │ ├── HActionInterval.js.meta │ ├── HActionJump.js │ ├── HActionJump.js.meta │ ├── HActionTween.js │ ├── HActionTween.js.meta │ ├── HActionTweenBase.js │ ├── HActionTweenBase.js.meta │ ├── HActionTweenBy.js │ ├── HActionTweenBy.js.meta │ ├── HCustomEase.js │ ├── HCustomEase.js.meta │ ├── HEaseDefine.js │ ├── HEaseDefine.js.meta │ ├── core.meta │ ├── core │ │ ├── HAction.js │ │ ├── HAction.js.meta │ │ ├── HActionComponent.js │ │ ├── HActionComponent.js.meta │ │ ├── HActionEngine.js │ │ ├── HActionEngine.js.meta │ │ ├── HActionSequence.js │ │ ├── HActionSequence.js.meta │ │ ├── HActionSpawn.js │ │ ├── HActionSpawn.js.meta │ │ ├── HNodeEx.js │ │ ├── HNodeEx.js.meta │ │ ├── HVars.js │ │ └── HVars.js.meta │ ├── ezaction.d.ts │ ├── ezaction.d.ts.meta │ ├── ezaction.js │ └── ezaction.js.meta ├── prefab.meta ├── prefab │ ├── PlayLayer.prefab │ ├── PlayLayer.prefab.meta │ ├── block.prefab │ ├── block.prefab.meta │ ├── gameEnd.prefab │ └── gameEnd.prefab.meta ├── scene.meta ├── scene │ ├── main.fire │ └── main.fire.meta ├── script.meta └── script │ ├── Camera.ts │ ├── Camera.ts.meta │ ├── CameraManager.ts │ ├── CameraManager.ts.meta │ ├── ConnectLayer.ts │ ├── ConnectLayer.ts.meta │ ├── Data.ts │ ├── Data.ts.meta │ ├── EndLayout.ts │ ├── EndLayout.ts.meta │ ├── Game.ts │ ├── Game.ts.meta │ ├── IGame.ts │ ├── IGame.ts.meta │ ├── ILayout.ts │ ├── ILayout.ts.meta │ ├── IMathVec.ts │ ├── IMathVec.ts.meta │ ├── IScoreManager.ts │ ├── IScoreManager.ts.meta │ ├── ITouchFront.ts │ ├── ITouchFront.ts.meta │ ├── Layout.ts │ ├── Layout.ts.meta │ ├── MathVec.ts │ ├── MathVec.ts.meta │ ├── Model.ts │ ├── Model.ts.meta │ ├── PlayLayer.ts │ ├── PlayLayer.ts.meta │ ├── SceneMediator.ts │ ├── SceneMediator.ts.meta │ ├── ScoreManager.ts │ ├── ScoreManager.ts.meta │ ├── Select.ts │ ├── Select.ts.meta │ ├── StartLayer.ts │ ├── StartLayer.ts.meta │ ├── State.ts │ ├── State.ts.meta │ ├── TouchBlock.ts │ ├── TouchBlock.ts.meta │ ├── TouchFront.ts │ └── TouchFront.ts.meta ├── creator.d.ts ├── jsconfig.json ├── project.json ├── settings ├── builder.json └── project.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | #///////////////////////////////////////////////////////////////////////////// 2 | # Fireball Projects 3 | #///////////////////////////////////////////////////////////////////////////// 4 | 5 | library/ 6 | temp/ 7 | local/ 8 | build/ 9 | 10 | #///////////////////////////////////////////////////////////////////////////// 11 | # Logs and databases 12 | #///////////////////////////////////////////////////////////////////////////// 13 | 14 | *.log 15 | *.sql 16 | *.sqlite 17 | 18 | #///////////////////////////////////////////////////////////////////////////// 19 | # files for debugger 20 | #///////////////////////////////////////////////////////////////////////////// 21 | 22 | *.sln 23 | *.csproj 24 | *.pidb 25 | *.unityproj 26 | *.suo 27 | 28 | #///////////////////////////////////////////////////////////////////////////// 29 | # OS generated files 30 | #///////////////////////////////////////////////////////////////////////////// 31 | 32 | .DS_Store 33 | ehthumbs.db 34 | Thumbs.db 35 | 36 | #///////////////////////////////////////////////////////////////////////////// 37 | # exvim files 38 | #///////////////////////////////////////////////////////////////////////////// 39 | 40 | *UnityVS.meta 41 | *.err 42 | *.err.meta 43 | *.exvim 44 | *.exvim.meta 45 | *.vimentry 46 | *.vimentry.meta 47 | *.vimproject 48 | *.vimproject.meta 49 | .vimfiles.*/ 50 | .exvim.*/ 51 | quick_gen_project_*_autogen.bat 52 | quick_gen_project_*_autogen.bat.meta 53 | quick_gen_project_*_autogen.sh 54 | quick_gen_project_*_autogen.sh.meta 55 | .exvim.app 56 | 57 | #///////////////////////////////////////////////////////////////////////////// 58 | # webstorm files 59 | #///////////////////////////////////////////////////////////////////////////// 60 | 61 | .idea/ 62 | 63 | #////////////////////////// 64 | # VS Code 65 | #////////////////////////// 66 | 67 | .vscode/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 AK-12 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2048-typescript-cocoscreator 2 | 3 | > 动画部分采用[ezaction 动画库](https://github.com/haroel/ezaction) 4 | 5 | size: 683 KB 6 | 7 | 用 typescript 写的 2048,creator 版本 2.0 8 | [点击预览](https://saber2pr.github.io/MyWeb/build/2048/) 9 | 10 | ## 核心代码 11 | 12 | ```ts 13 | /* 14 | * @Author: AK-12 15 | * @Date: 2018-11-02 17:06:17 16 | * @Last Modified by: AK-12 17 | * @Last Modified time: 2018-11-10 10:37:55 18 | */ 19 | import { 20 | transformArray, 21 | visitArray, 22 | alterArray, 23 | moreFunc, 24 | toInt, 25 | PointList, 26 | fillArraySuper, 27 | fillArray, 28 | hasTwiceSuper 29 | } from './MathVec' 30 | /** 31 | *一维数组与合并偏差 32 | * 33 | * @interface ArrAndDelta 34 | */ 35 | interface ArrAndDelta { 36 | arr: number[] 37 | delta: number[] 38 | } 39 | /** 40 | *二维数组与合并偏差 41 | * 42 | * @interface MapAndDelta 43 | */ 44 | interface MapAndDelta { 45 | map: number[][] 46 | delta: number[][] 47 | } 48 | /** 49 | *矩阵合并算法 50 | * 51 | * 单例类 52 | * @export 53 | * @class Data 54 | */ 55 | export default class Data { 56 | private constructor() {} 57 | static instance: Data 58 | static getInstance(): Data { 59 | this.instance = !!this.instance ? this.instance : new Data() 60 | return this.instance 61 | } 62 | private map: Array> 63 | private __map: Array> 64 | private updateTimes: number 65 | private __updateTimes: number 66 | private maxValue: number 67 | private hasNext: boolean 68 | /** 69 | *初始化矩阵数据 70 | * 71 | * @param {number} size 方阵边长 72 | * @param {number} [maxValue=2048] 数字最大值 73 | * @memberof Data 74 | */ 75 | public init(size: number, maxValue: number = 2048): Data { 76 | this.updateTimes = 0 77 | this.__updateTimes = 0 78 | this.maxValue = maxValue 79 | this.map = fillArraySuper(0, { 80 | raw: size, 81 | col: size 82 | }) 83 | this.__map = fillArraySuper(0, { 84 | raw: size, 85 | col: size 86 | }) 87 | return this 88 | } 89 | /** 90 | *当前矩阵 91 | * 92 | * @readonly 93 | * @type {number[][]} 94 | * @memberof Data 95 | */ 96 | get data(): number[][] { 97 | return this.map 98 | } 99 | /** 100 | *得到updateTimes增量 101 | * 102 | * @readonly 103 | * @type {number} 104 | * @memberof Data 105 | */ 106 | get updateValue(): number { 107 | return this.updateTimes - this.__updateTimes 108 | } 109 | /** 110 | *分数 111 | * 112 | * @readonly 113 | * @type {number} 114 | * @memberof Data 115 | */ 116 | get score(): number { 117 | return this.updateTimes 118 | } 119 | /** 120 | *最大值 121 | * 122 | * @readonly 123 | * @type {number} 124 | * @memberof Data 125 | */ 126 | get MaxValue(): number { 127 | return this.maxValue 128 | } 129 | /** 130 | *检测数据是否变动 131 | * 132 | * @readonly 133 | * @type {boolean} 134 | * @memberof Data 135 | */ 136 | get isChanged(): boolean { 137 | return this.__map.toString() !== this.map.toString() 138 | } 139 | /** 140 | *获取updateTimes状态 141 | * 142 | * @readonly 143 | * @type {boolean} 数字超过maxValue则返回true 144 | * @memberof Data 145 | */ 146 | get result(): boolean { 147 | return Boolean(Math.abs(this.updateTimes) % 2) 148 | } 149 | /** 150 | *合并方向, 返回合并偏差二维数组 151 | * 152 | * @param {string} method 153 | * @param {number[][]} [arr=this.map] 154 | * @returns {Array>} 155 | * @memberof Data 156 | */ 157 | public merge( 158 | method: string, 159 | arr: number[][] = this.map 160 | ): Array> { 161 | visitArray(this.map, (raw, col) => { 162 | this.__map[raw][col] = this.map[raw][col] 163 | }) 164 | let delta: Array> 165 | switch (method) { 166 | case 'left': 167 | { 168 | let mapAndDelta = this.mergeSuper(arr, this.mergeLeft) 169 | this.map = mapAndDelta.map 170 | delta = mapAndDelta.delta 171 | } 172 | break 173 | case 'right': 174 | { 175 | let mapAndDelta = this.mergeSuper(arr, this.mergeRight) 176 | this.map = mapAndDelta.map 177 | delta = mapAndDelta.delta 178 | } 179 | break 180 | case 'up': 181 | { 182 | let mapAndDelta = this.mergeSuper(transformArray(arr), this.mergeLeft) 183 | delta = transformArray(mapAndDelta.delta) 184 | this.map = transformArray(mapAndDelta.map) 185 | } 186 | break 187 | case 'down': 188 | { 189 | let mapAndDelta = this.mergeSuper( 190 | transformArray(arr), 191 | this.mergeRight 192 | ) 193 | delta = transformArray(mapAndDelta.delta) 194 | this.map = transformArray(mapAndDelta.map) 195 | } 196 | break 197 | default: 198 | throw new Error('Data merge method error') 199 | } 200 | return delta 201 | } 202 | /** 203 | *反转回调处理矩阵 204 | * 205 | * @private 206 | * @memberof Data 207 | */ 208 | private mergeSuper = ( 209 | arr: number[][], 210 | callback: (arr: number[]) => ArrAndDelta 211 | ): MapAndDelta => { 212 | let map: Array> = new Array>() 213 | let delta: Array> = new Array>() 214 | this.__updateTimes = this.updateTimes 215 | for (var raw of arr) { 216 | let arrAndDelta = callback(raw) 217 | map.push(arrAndDelta.arr) 218 | delta.push(arrAndDelta.delta) 219 | } 220 | return { 221 | map: map, 222 | delta: delta 223 | } 224 | } 225 | /** 226 | *检测矩阵数字是否都不为0, 若都不为0则返回true 227 | * 228 | * @readonly 229 | * @type {boolean} 230 | * @memberof Data 231 | */ 232 | get isFull(): boolean { 233 | this.hasNext = false 234 | visitArray(this.map, (raw, col) => { 235 | if (this.map[raw][col] === 0) { 236 | this.hasNext = true 237 | } 238 | }) 239 | return !this.hasNext 240 | } 241 | /** 242 | *检测矩阵是否存在相邻相同数字, 若存在则返回ture 243 | * 244 | * @readonly 245 | * @type {boolean} 246 | * @memberof Data 247 | */ 248 | get hasTwice(): boolean { 249 | return hasTwiceSuper(this.map) 250 | } 251 | /** 252 | *随机位置添加元素 253 | * 254 | * @param {number} [times=1] 255 | * @returns {boolean} 返回true, 若没有空位则返回false 256 | * @memberof Data 257 | */ 258 | public addRand(times: number = 1): boolean { 259 | let points = PointList() 260 | moreFunc(() => { 261 | visitArray(this.map, (raw, col) => { 262 | if (this.map[raw][col] === 0) { 263 | points.push({ x: raw, y: col }) 264 | this.hasNext = true 265 | } 266 | }) 267 | if (this.hasNext) { 268 | let index = toInt(Math.random() * points.length) 269 | alterArray(this.map, { 270 | raw: points[index].x, 271 | col: points[index].y, 272 | value: 2 273 | }) 274 | } 275 | }, times) 276 | return this.hasNext 277 | } 278 | /** 279 | *向左合并 280 | * 281 | * @private 282 | * @memberof Data 283 | */ 284 | private mergeLeft = (arr: number[]): ArrAndDelta => { 285 | let i, nextI, m 286 | let len = arr.length 287 | let delta = fillArray(0, arr.length) 288 | for (i = 0; i < len; i++) { 289 | nextI = -1 290 | for (m = i + 1; m < len; m++) { 291 | if (arr[m] !== 0) { 292 | nextI = m 293 | if (arr[i] === arr[m]) { 294 | delta[m] = m - i 295 | } else { 296 | if (arr[i] === 0) { 297 | delta[m] = m - i 298 | } else { 299 | delta[m] = m - i - 1 300 | } 301 | } 302 | break 303 | } 304 | } 305 | if (nextI !== -1) { 306 | if (arr[i] === 0) { 307 | arr[i] = arr[nextI] 308 | arr[nextI] = 0 309 | i -= 1 310 | } else if (arr[i] === arr[nextI]) { 311 | arr[i] = arr[i] * 2 312 | this.updateTimes = 313 | arr[i] < this.maxValue 314 | ? this.updateTimes + arr[i] 315 | : this.updateTimes + 1 316 | arr[nextI] = 0 317 | } 318 | } 319 | } 320 | return { 321 | arr: arr, 322 | delta: delta 323 | } 324 | } 325 | /** 326 | *向右合并 327 | * 328 | * @private 329 | * @memberof Data 330 | */ 331 | private mergeRight = (arr: number[]): ArrAndDelta => { 332 | let arr_re = [...arr].reverse() 333 | let arrAndDelta = this.mergeLeft(arr_re) 334 | return { 335 | arr: [...arrAndDelta.arr].reverse(), 336 | delta: [...arrAndDelta.delta].reverse() 337 | } 338 | } 339 | } 340 | ``` 341 | -------------------------------------------------------------------------------- /assets/animation.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "417f938e-99bf-4013-b880-acef77981c40", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/animation/end.anim: -------------------------------------------------------------------------------- 1 | { 2 | "__type__": "cc.AnimationClip", 3 | "_name": "end", 4 | "_objFlags": 0, 5 | "_native": "", 6 | "_duration": 1.2166666666666666, 7 | "sample": 60, 8 | "speed": 5, 9 | "wrapMode": 1, 10 | "curveData": { 11 | "props": { 12 | "scale": [ 13 | { 14 | "frame": 0, 15 | "value": { 16 | "__type__": "cc.Vec2", 17 | "x": 0.5, 18 | "y": 0.5 19 | }, 20 | "curve": "cubicOut" 21 | }, 22 | { 23 | "frame": 1, 24 | "value": { 25 | "__type__": "cc.Vec2", 26 | "x": 1.1, 27 | "y": 1.1 28 | }, 29 | "curve": "cubicIn" 30 | }, 31 | { 32 | "frame": 1.2166666666666666, 33 | "value": { 34 | "__type__": "cc.Vec2", 35 | "x": 1, 36 | "y": 1 37 | } 38 | } 39 | ] 40 | } 41 | }, 42 | "events": [] 43 | } -------------------------------------------------------------------------------- /assets/animation/end.anim.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "30ad6936-806b-4967-b9ba-c0500b5a66f5", 4 | "subMetas": {} 5 | } -------------------------------------------------------------------------------- /assets/animation/label.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "091af0b6-e8ea-4e81-9643-c4f35e1e19b9", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/animation/label/hideAndShow.anim: -------------------------------------------------------------------------------- 1 | { 2 | "__type__": "cc.AnimationClip", 3 | "_name": "hideAndShow", 4 | "_objFlags": 0, 5 | "_native": "", 6 | "_duration": 1, 7 | "sample": 60, 8 | "speed": 0.5, 9 | "wrapMode": "2", 10 | "curveData": { 11 | "props": { 12 | "opacity": [ 13 | { 14 | "frame": 0, 15 | "value": 255 16 | }, 17 | { 18 | "frame": 0.8333333333333334, 19 | "value": 0 20 | }, 21 | { 22 | "frame": 1, 23 | "value": 255 24 | } 25 | ] 26 | } 27 | }, 28 | "events": [] 29 | } -------------------------------------------------------------------------------- /assets/animation/label/hideAndShow.anim.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "514fdb36-ab79-447e-965c-0d73bc1ba655", 4 | "subMetas": {} 5 | } -------------------------------------------------------------------------------- /assets/animation/select.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "cec1348c-0c26-4ba2-9877-c7cc023e5e27", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/animation/select/select.anim: -------------------------------------------------------------------------------- 1 | { 2 | "__type__": "cc.AnimationClip", 3 | "_name": "select", 4 | "_objFlags": 0, 5 | "_native": "", 6 | "_duration": 1, 7 | "sample": 60, 8 | "speed": 1, 9 | "wrapMode": "2", 10 | "curveData": { 11 | "paths": { 12 | "last": { 13 | "props": { 14 | "x": [ 15 | { 16 | "frame": 0, 17 | "value": -127 18 | }, 19 | { 20 | "frame": 0.8333333333333334, 21 | "value": -147 22 | }, 23 | { 24 | "frame": 1, 25 | "value": -127 26 | } 27 | ], 28 | "opacity": [ 29 | { 30 | "frame": 0, 31 | "value": 0 32 | }, 33 | { 34 | "frame": 0.8333333333333334, 35 | "value": 255 36 | }, 37 | { 38 | "frame": 1, 39 | "value": 0 40 | } 41 | ] 42 | } 43 | }, 44 | "next": { 45 | "props": { 46 | "x": [ 47 | { 48 | "frame": 0, 49 | "value": 127 50 | }, 51 | { 52 | "frame": 0.8333333333333334, 53 | "value": 147 54 | }, 55 | { 56 | "frame": 1, 57 | "value": 127 58 | } 59 | ], 60 | "opacity": [ 61 | { 62 | "frame": 0, 63 | "value": 0 64 | }, 65 | { 66 | "frame": 0.8333333333333334, 67 | "value": 255 68 | }, 69 | { 70 | "frame": 1, 71 | "value": 0 72 | } 73 | ] 74 | } 75 | } 76 | } 77 | }, 78 | "events": [] 79 | } -------------------------------------------------------------------------------- /assets/animation/select/select.anim.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "02a57cfd-87f4-4b7b-ae25-327b46c0767e", 4 | "subMetas": {} 5 | } -------------------------------------------------------------------------------- /assets/ezaction.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "072d2789-12a5-4a7a-86e9-ba689d1268ac", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/ezaction/HActionInstant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/30. 5 | * 6 | * 瞬时Action基类 7 | */ 8 | let Instant = cc.Class({ 9 | extends: require("HAction"), 10 | ctor: function () { }, 11 | update: function (rate) { 12 | this.$actionComplete(); 13 | }, 14 | cloneSelf: function () { 15 | let act = new Instant(); 16 | act.init(this.getVars()); 17 | return act; 18 | } 19 | }); 20 | Instant.create = function (vars) { 21 | let mm = new Instant(); 22 | mm.init(vars); 23 | return mm; 24 | }; 25 | module.exports = Instant; 26 | -------------------------------------------------------------------------------- /assets/ezaction/HActionInstant.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "c1ce59b7-088f-49d2-8616-e887a2860385", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/HActionInterval.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/21. 5 | * 6 | * HActionInterval是基于时间调度的动作基类 7 | * 8 | */ 9 | 10 | let HActionInterval = cc.Class({ 11 | extends: require("HAction"), 12 | ctor: function () { 13 | this._duration = 0.001; 14 | this._currentTime = 0; 15 | this._progress = 0; 16 | this._lastprogress = 0; 17 | }, 18 | getCurrentTime: function () { 19 | return this._currentTime; 20 | }, 21 | /** 22 | * 动画运行时间 23 | * 动画的实际运行时间是 duration/speed 24 | */ 25 | getDuration: function () { 26 | return this._duration; 27 | }, 28 | 29 | getProgress: function () { 30 | return this._progress; 31 | }, 32 | 33 | init: function (duration, vars /*null */) { 34 | if (duration > 0) { 35 | this._duration = duration; 36 | } 37 | this._super(vars); 38 | }, 39 | 40 | playAction: function () { 41 | this._super(); 42 | this._currentTime = 0; 43 | this._progress = 0; 44 | this._lastprogress = 0; 45 | }, 46 | /* 47 | * 请重写改方法以实现更多行为 48 | * update Action状态 49 | * @ target : HAction类 50 | * */ 51 | $update: function (dt) { 52 | this._currentTime += dt; 53 | if (this._currentTime >= this._duration) { 54 | this._progress = 1.0; 55 | this.update(this._progress); 56 | this.$actionComplete(); 57 | } else { 58 | this._progress = this._currentTime / this._duration; 59 | this.update(this._progress); 60 | } 61 | }, 62 | /* 63 | * 扩展以实现更多方法 64 | * */ 65 | update: function (rate) { 66 | if ( typeof this._vars["easing"] === 'function') { 67 | let oldProgress = this._lastprogress; 68 | this._progress = this._vars["easing"](this._progress); 69 | this._lastprogress = this._progress; 70 | if (oldProgress < 1 && this._progress > 1) { 71 | if ( typeof this._vars["onArrived"] === 'function') { 72 | this._vars["onArrived"](this); 73 | } 74 | } 75 | } 76 | this._super(this._progress); 77 | //TODO What you want to do next; 78 | 79 | }, 80 | 81 | /** 82 | * 当HAction设置了缓动函数,有可能出现时间还没到,node越过目标参数的情况,当node越过时,func会被触发 83 | * **/ 84 | onArrived(func) { 85 | if (typeof func === "function"){ 86 | this._vars["onArrived"] = func; 87 | } 88 | return this; 89 | }, 90 | /* 91 | * 参数为缓动函数, 函数定义可查看GEaseDefine.js文件 92 | * 你可以传入一个自己定义的函数,该函数必须接受progress值来处理 93 | * */ 94 | easing: function (easeFunc) { 95 | if (typeof easeFunc === "function") { 96 | this._vars["easing"] = easeFunc; 97 | } 98 | return this; 99 | }, 100 | /* cloneSelf 不复制方法 */ 101 | cloneSelf: function () { 102 | let act = new HActionInterval(); 103 | act.init(this.getDuration(), this.getVars()); 104 | return act; 105 | }, 106 | /* 107 | * 仅继承重写,不可外部调用,该方法由ActionComponent自动调用!!!!! 108 | * */ 109 | $destroy: function () { 110 | this._super(); 111 | } 112 | }); 113 | 114 | HActionInterval.create = function (duration, vars) { 115 | let act = new HActionInterval(); 116 | act.init(duration, vars); 117 | return act; 118 | }; 119 | 120 | module.exports = HActionInterval; -------------------------------------------------------------------------------- /assets/ezaction/HActionInterval.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "46ada3b5-4853-4524-beee-79e0b21cfcc4", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/HActionJump.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @CreateTime: Feb 7, 2018 5:44 PM 3 | * @Author: howe 4 | * @Contact: ihowe@outlook.com 5 | * @Last Modified By: howe 6 | * @Last Modified Time: Feb 7, 2018 6:49 PM 7 | * @Description: 8 | * 9 | * 类似cc.jumpBy 和cc.jumpTo 10 | * 11 | */ 12 | 13 | let HActionJumpBy = cc.Class({ 14 | extends: require("HActionInterval"), 15 | ctor: function () { 16 | this._delta = { x: 0, y: 0 }; 17 | this._height = 0; 18 | this._jumps = 1; 19 | this._startPos = {}; 20 | }, 21 | init: function (duration, pos, height, jumps, vars/** null */) { 22 | this._super(duration, vars); 23 | this._delta.x = pos.x; 24 | this._delta.x = pos.y; 25 | this._height = height; 26 | this._jumps = jumps; 27 | }, 28 | 29 | startWithTarget: function (component) { 30 | this._super(component); 31 | this._startPos.x = this.getNode().x; 32 | this._startPos.y = this.getNode().y; 33 | }, 34 | update: function (rate) { 35 | this._super(rate); 36 | let vars = this._vars; 37 | let node = this.getNode(); 38 | let progress = this.getProgress(); 39 | 40 | let frac = rate * this._jumps % 1.0; 41 | let y = this._height * 4 * frac * (1 - frac); 42 | y += this._delta.y * rate; 43 | node.y = this._startPos.y + y; 44 | node.x = this._startPos.x + this._delta.x * dt; 45 | 46 | }, 47 | /* cloneSelf */ 48 | cloneSelf: function () { 49 | let act = new HActionJumpBy(); 50 | act.init(this.getDuration(),this._delta, this._height,this._jumps, this.getVars()); 51 | act.easing(this.easingFunc); 52 | return act; 53 | } 54 | }); 55 | 56 | let HActionJumpTo = cc.Class({ 57 | extends: HActionJumpBy, 58 | ctor: function () { 59 | this._endPos = {x:0,y:0}; 60 | }, 61 | init: function (duration, pos, height, jumps, vars/** null */) { 62 | this._super( duration, pos, height, jumps, vars ); 63 | this._endPos.x = pos.x; 64 | this._endPos.y = pos.y; 65 | }, 66 | 67 | startWithTarget: function (component) { 68 | this._super(component); 69 | this._delta.x = this._endPos.x - this._startPos.x; 70 | this._delta.y = this._endPos.y - this._startPos.y; 71 | }, 72 | /* cloneSelf */ 73 | cloneSelf: function () { 74 | let act = new HActionJumpTo(); 75 | act.init(this.getDuration(), this._endPos, this._height,this._jumps, this.getVars()); 76 | return act; 77 | } 78 | }); 79 | 80 | module.exports = { 81 | jumpBy:HActionJumpBy, 82 | jumpTo:HActionJumpTo 83 | }; -------------------------------------------------------------------------------- /assets/ezaction/HActionJump.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "2835e6f4-a9ac-400a-a946-276b46f6e4f8", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/HActionTween.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/22. 5 | */ 6 | let HActionTween = cc.Class({ 7 | extends: require("HActionTweenBase"), 8 | ctor: function () { 9 | }, 10 | update: function (rate) { 11 | this._super(rate); 12 | let vars = this._vars; 13 | let node = this.getTarget(); 14 | let progress = this.getProgress(); 15 | let pList = this._intialAttrList; 16 | for (let key in pList) { 17 | let _o = pList[key]; 18 | node[key] = _o + (vars[key] - _o) * progress; 19 | 20 | } 21 | }, 22 | /* cloneSelf 不复制方法 */ 23 | cloneSelf: function () { 24 | let act = new HActionTween(); 25 | act.init(this.getDuration(), this.getVars()); 26 | act.easing(this.easingFunc); 27 | return act; 28 | } 29 | }); 30 | 31 | HActionTween.create = function (duration, vars) { 32 | let tween = new HActionTween(); 33 | tween.init(duration, vars); 34 | return tween; 35 | }; 36 | 37 | module.exports = HActionTween; -------------------------------------------------------------------------------- /assets/ezaction/HActionTween.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "e8626483-8696-4221-9055-a51905730713", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/HActionTweenBase.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/4/14. 5 | * 6 | * 属性补间类基类 7 | */ 8 | let HActionTweenBase = cc.Class({ 9 | extends: require("HActionInterval"), 10 | ctor: function () { 11 | this._intialAttrList = null; 12 | this._target = null; 13 | }, 14 | setTarget(objOrNode){ 15 | this._target = objOrNode; 16 | }, 17 | 18 | getTarget(){ 19 | return this._target || this.getNode(); 20 | }, 21 | 22 | playAction: function () { 23 | this._super(); 24 | if (this._intialAttrList) { 25 | // 重置所有属性 26 | let node = this.getTarget(); 27 | let pList = this._intialAttrList; 28 | for (let key in pList) { 29 | node[key] = pList[key]; 30 | } 31 | } 32 | }, 33 | startWithTarget: function (component) { 34 | this._super(component); 35 | this._intialAttrList = {}; 36 | let _node = this.getTarget(); 37 | for (var key in this._vars) { 38 | if (key == 'tag'){ 39 | continue; 40 | } 41 | if (typeof _node[key] === "number") { 42 | let _o = typeof _node[key]; 43 | if (_o === 'number') { 44 | this._intialAttrList[key] = _node[key]; 45 | } 46 | } 47 | } 48 | }, 49 | $destroy: function () { 50 | this._intialAttrList = null; 51 | this._super(); 52 | } 53 | }); 54 | module.exports = HActionTweenBase; -------------------------------------------------------------------------------- /assets/ezaction/HActionTweenBase.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "1c55d93e-6c40-4ba3-a163-cb72b6b40b7d", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/HActionTweenBy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/22. 5 | */ 6 | let HActionTweenBy = cc.Class({ 7 | extends: require("HActionTweenBase"), 8 | ctor: function () { 9 | }, 10 | update: function (rate) { 11 | this._super(rate); 12 | let vars = this._vars; 13 | let node = this.getTarget(); 14 | let progress = this.getProgress(); 15 | let pList = this._intialAttrList; 16 | for (let key in pList) { 17 | let _o = pList[key]; 18 | node[key] = _o + vars[key] * progress; 19 | } 20 | }, 21 | /* cloneSelf 不复制方法 */ 22 | cloneSelf: function () { 23 | let act = new HActionTweenBy(); 24 | act.init(this.getDuration(), this.getVars()); 25 | act.easing(this.easingFunc); 26 | return act; 27 | } 28 | }); 29 | 30 | HActionTweenBy.create = function (duration, vars) { 31 | let tween = new HActionTweenBy(); 32 | tween.init(duration, vars); 33 | return tween; 34 | }; 35 | 36 | module.exports = HActionTweenBy; -------------------------------------------------------------------------------- /assets/ezaction/HActionTweenBy.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "730acab5-5242-4511-b3a3-dc7a7c09768c", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/HCustomEase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @CreateTime: Jul 21, 2018 10:53 AM 3 | * @Author: howe 4 | * @Contact: ihowe@outlook.com 5 | * @Last Modified By: howe 6 | * @Last Modified Time: Jul 21, 2018 11:05 AM 7 | * @Description: Modify Here, Please 8 | * 9 | * 说明: CustomEase库核心算法来自 greensock https://greensock.com/customease 10 | * 本人基于该库移植到cocos creator平台并集成到ezaction 11 | */ 12 | let _CustomEaseConstructor = function (){ 13 | var _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 14 | _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 15 | _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig, 16 | _needsParsingExp = /[cLlsS]/g, 17 | _bezierError = "CustomEase only accepts Cubic Bezier data.", 18 | _bezierToPoints = function (x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) { 19 | var x12 = (x1 + x2) / 2, 20 | y12 = (y1 + y2) / 2, 21 | x23 = (x2 + x3) / 2, 22 | y23 = (y2 + y3) / 2, 23 | x34 = (x3 + x4) / 2, 24 | y34 = (y3 + y4) / 2, 25 | x123 = (x12 + x23) / 2, 26 | y123 = (y12 + y23) / 2, 27 | x234 = (x23 + x34) / 2, 28 | y234 = (y23 + y34) / 2, 29 | x1234 = (x123 + x234) / 2, 30 | y1234 = (y123 + y234) / 2, 31 | dx = x4 - x1, 32 | dy = y4 - y1, 33 | d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx), 34 | d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx), 35 | length; 36 | if (!points) { 37 | points = [{x: x1, y: y1}, {x: x4, y: y4}]; 38 | index = 1; 39 | } 40 | points.splice(index || points.length - 1, 0, {x: x1234, y: y1234}); 41 | if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) { 42 | length = points.length; 43 | _bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index); 44 | _bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 1 + (points.length - length)); 45 | } 46 | return points; 47 | }, 48 | 49 | _pathDataToBezier = function (d) { 50 | var a = (d + "").replace(_scientific, function (m) { 51 | var n = +m; 52 | return (n < 0.0001 && n > -0.0001) ? 0 : n; 53 | }).match(_svgPathExp) || [], //some authoring programs spit out very small numbers in scientific notation like "1e-5", so make sure we round that down to 0 first. 54 | path = [], 55 | relativeX = 0, 56 | relativeY = 0, 57 | elements = a.length, 58 | l = 2, 59 | i, x, y, command, isRelative, segment, startX, startY, prevCommand, difX, difY; 60 | for (i = 0; i < elements; i++) { 61 | prevCommand = command; 62 | if (isNaN(a[i])) { 63 | command = a[i].toUpperCase(); 64 | isRelative = (command !== a[i]); //lower case means relative 65 | } else { //commands like "C" can be strung together without any new command characters between. 66 | i--; 67 | } 68 | x = +a[i + 1]; 69 | y = +a[i + 2]; 70 | if (isRelative) { 71 | x += relativeX; 72 | y += relativeY; 73 | } 74 | if (!i) { 75 | startX = x; 76 | startY = y; 77 | } 78 | if (command === "M") { 79 | if (segment && segment.length < 8) { //if the path data was funky and just had a M with no actual drawing anywhere, skip it. 80 | path.length -= 1; 81 | l = 0; 82 | } 83 | relativeX = startX = x; 84 | relativeY = startY = y; 85 | segment = [x, y]; 86 | l = 2; 87 | path.push(segment); 88 | i += 2; 89 | command = "L"; //an "M" with more than 2 values gets interpreted as "lineTo" commands ("L"). 90 | 91 | } else if (command === "C") { 92 | if (!segment) { 93 | segment = [0, 0]; 94 | } 95 | segment[l++] = x; 96 | segment[l++] = y; 97 | if (!isRelative) { 98 | relativeX = relativeY = 0; 99 | } 100 | segment[l++] = relativeX + a[i + 3] * 1; //note: "*1" is just a fast/short way to cast the value as a Number. WAAAY faster in Chrome, slightly slower in Firefox. 101 | segment[l++] = relativeY + a[i + 4] * 1; 102 | segment[l++] = relativeX = relativeX + a[i + 5] * 1; 103 | segment[l++] = relativeY = relativeY + a[i + 6] * 1; 104 | i += 6; 105 | 106 | } else if (command === "S") { 107 | if (prevCommand === "C" || prevCommand === "S") { 108 | difX = relativeX - segment[l - 4]; 109 | difY = relativeY - segment[l - 3]; 110 | segment[l++] = relativeX + difX; 111 | segment[l++] = relativeY + difY; 112 | } else { 113 | segment[l++] = relativeX; 114 | segment[l++] = relativeY; 115 | } 116 | segment[l++] = x; 117 | segment[l++] = y; 118 | if (!isRelative) { 119 | relativeX = relativeY = 0; 120 | } 121 | segment[l++] = relativeX = relativeX + a[i + 3] * 1; 122 | segment[l++] = relativeY = relativeY + a[i + 4] * 1; 123 | i += 4; 124 | 125 | } else if (command === "L" || command === "Z") { 126 | if (command === "Z") { 127 | x = startX; 128 | y = startY; 129 | segment.closed = true; 130 | } 131 | if (command === "L" || Math.abs(relativeX - x) > 0.5 || Math.abs(relativeY - y) > 0.5) { 132 | segment[l++] = relativeX + (x - relativeX) / 3; 133 | segment[l++] = relativeY + (y - relativeY) / 3; 134 | segment[l++] = relativeX + (x - relativeX) * 2 / 3; 135 | segment[l++] = relativeY + (y - relativeY) * 2 / 3; 136 | segment[l++] = x; 137 | segment[l++] = y; 138 | if (command === "L") { 139 | i += 2; 140 | } 141 | } 142 | relativeX = x; 143 | relativeY = y; 144 | } else { 145 | throw _bezierError; 146 | } 147 | 148 | } 149 | return path[0]; 150 | }, 151 | 152 | _findMinimum = function (values) { 153 | var l = values.length, 154 | min = 999999999999, 155 | i; 156 | for (i = 1; i < l; i += 6) { 157 | if (+values[i] < min) { 158 | min = +values[i]; 159 | } 160 | } 161 | return min; 162 | }, 163 | 164 | _normalize = function (values, height, originY) { //takes all the points and translates/scales them so that the x starts at 0 and ends at 1. 165 | if (!originY && originY !== 0) { 166 | originY = Math.max(+values[values.length-1], +values[1]); 167 | } 168 | var tx = +values[0] * -1, 169 | ty = -originY, 170 | l = values.length, 171 | sx = 1 / (+values[l - 2] + tx), 172 | sy = -height || ((Math.abs(+values[l - 1] - +values[1]) < 0.01 * (+values[l - 2] - +values[0])) ? _findMinimum(values) + ty : +values[l - 1] + ty), 173 | i; 174 | if (sy) { //typically y ends at 1 (so that the end values are reached) 175 | sy = 1 / sy; 176 | } else { //in case the ease returns to its beginning value, scale everything proportionally 177 | sy = -sx; 178 | } 179 | for (i = 0; i < l; i += 2) { 180 | values[i] = (+values[i] + tx) * sx; 181 | values[i + 1] = (+values[i + 1] + ty) * sy; 182 | } 183 | }, 184 | 185 | _getRatio = function (p) { 186 | var point = this.lookup[(p * this.l) | 0] || this.lookup[this.l - 1]; 187 | if (point.nx < p) { 188 | point = point.n; 189 | } 190 | return point.y + ((p - point.x) / point.cx) * point.cy; 191 | }, 192 | 193 | CustomEase = function (id, data, config) { 194 | this._calcEnd = true; 195 | this.id = id; 196 | this.getRatio = _getRatio; //speed optimization, faster lookups. 197 | this.setData(data, config); 198 | }, 199 | p = CustomEase.prototype; 200 | p.setData = function(data, config) { 201 | data = data || "0,0,1,1"; 202 | var values = data.match(_numbersExp), 203 | closest = 1, 204 | points = [], 205 | l, a1, a2, i, inc, j, point, prevPoint, p, precision; 206 | config = config || {}; 207 | precision = config.precision || 1; 208 | this.data = data; 209 | this.lookup = []; 210 | this.points = points; 211 | this.fast = (precision <= 1); 212 | if (_needsParsingExp.test(data) || (data.indexOf("M") !== -1 && data.indexOf("C") === -1)) { 213 | values = _pathDataToBezier(data); 214 | } 215 | l = values.length; 216 | if (l === 4) { 217 | values.unshift(0, 0); 218 | values.push(1, 1); 219 | l = 8; 220 | } else if ((l - 2) % 6) { 221 | throw _bezierError; 222 | } 223 | if (+values[0] !== 0 || +values[l - 2] !== 1) { 224 | _normalize(values, config.height, config.originY); 225 | } 226 | 227 | this.rawBezier = values; 228 | 229 | for (i = 2; i < l; i += 6) { 230 | a1 = {x: +values[i - 2], y: +values[i - 1]}; 231 | a2 = {x: +values[i + 4], y: +values[i + 5]}; 232 | points.push(a1, a2); 233 | _bezierToPoints(a1.x, a1.y, +values[i], +values[i + 1], +values[i + 2], +values[i + 3], a2.x, a2.y, 1 / (precision * 200000), points, points.length - 1); 234 | } 235 | l = points.length; 236 | for (i = 0; i < l; i++) { 237 | point = points[i]; 238 | prevPoint = points[i - 1] || point; 239 | if (point.x > prevPoint.x || (prevPoint.y !== point.y && prevPoint.x === point.x) || point === prevPoint) { //if a point goes BACKWARD in time or is a duplicate, just drop it. 240 | prevPoint.cx = point.x - prevPoint.x; //change in x between this point and the next point (performance optimization) 241 | prevPoint.cy = point.y - prevPoint.y; 242 | prevPoint.n = point; 243 | prevPoint.nx = point.x; //next point's x value (performance optimization, making lookups faster in getRatio()). Remember, the lookup will always land on a spot where it's either this point or the very next one (never beyond that) 244 | if (this.fast && i > 1 && Math.abs(prevPoint.cy / prevPoint.cx - points[i - 2].cy / points[i - 2].cx) > 2) { //if there's a sudden change in direction, prioritize accuracy over speed. Like a bounce ease - you don't want to risk the sampling chunks landing on each side of the bounce anchor and having it clipped off. 245 | this.fast = false; 246 | } 247 | if (prevPoint.cx < closest) { 248 | if (!prevPoint.cx) { 249 | prevPoint.cx = 0.001; //avoids math problems in getRatio() (dividing by zero) 250 | if (i === l - 1) { //in case the final segment goes vertical RIGHT at the end, make sure we end at the end. 251 | prevPoint.x -= 0.001; 252 | closest = Math.min(closest, 0.001); 253 | this.fast = false; 254 | } 255 | } else { 256 | closest = prevPoint.cx; 257 | } 258 | } 259 | } else { 260 | points.splice(i--, 1); 261 | l--; 262 | } 263 | } 264 | l = (1 / closest + 1) | 0; 265 | this.l = l; //record for speed optimization 266 | inc = 1 / l; 267 | j = 0; 268 | point = points[0]; 269 | if (this.fast) { 270 | for (i = 0; i < l; i++) { //for fastest lookups, we just sample along the path at equal x (time) distance. Uses more memory and is slightly less accurate for anchors that don't land on the sampling points, but for the vast majority of eases it's excellent (and fast). 271 | p = i * inc; 272 | if (point.nx < p) { 273 | point = points[++j]; 274 | } 275 | a1 = point.y + ((p - point.x) / point.cx) * point.cy; 276 | this.lookup[i] = {x: p, cx: inc, y: a1, cy: 0, nx: 9}; 277 | if (i) { 278 | this.lookup[i - 1].cy = a1 - this.lookup[i - 1].y; 279 | } 280 | } 281 | this.lookup[l - 1].cy = points[points.length - 1].y - a1; 282 | } else { //this option is more accurate, ensuring that EVERY anchor is hit perfectly. Clipping across a bounce, for example, would never happen. 283 | for (i = 0; i < l; i++) { //build a lookup table based on the smallest distance so that we can instantly find the appropriate point (well, it'll either be that point or the very next one). We'll look up based on the linear progress. So it's it's 0.5 and the lookup table has 100 elements, it'd be like lookup[Math.floor(0.5 * 100)] 284 | if (point.nx < i * inc) { 285 | point = points[++j]; 286 | } 287 | this.lookup[i] = point; 288 | } 289 | 290 | if (j < points.length - 1) { 291 | this.lookup[i-1] = points[points.length-2]; 292 | } 293 | } 294 | this._calcEnd = (points[points.length-1].y !== 1 || points[0].y !== 0); //ensures that we don't run into floating point errors. As long as we're starting at 0 and ending at 1, tell GSAP to skip the final calculation and use 0/1 as the factor. 295 | return this; 296 | }; 297 | 298 | p.getRatio = _getRatio; 299 | return CustomEase; 300 | } 301 | 302 | const CustomEaseConstructor = _CustomEaseConstructor(); 303 | var customease = {}; 304 | customease.create = function (id, data, config){ 305 | return new CustomEaseConstructor(id,data,config); 306 | } 307 | 308 | module.exports = customease; 309 | -------------------------------------------------------------------------------- /assets/ezaction/HCustomEase.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "4f2d44b5-2c31-4b1e-9725-9c517abcb2dd", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/HEaseDefine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/22. 5 | */ 6 | /* 7 | * 8 | * 缓动定义文件, 可以扩展该文件以获得更多的缓动类型算法 9 | * 10 | * HAction默认的缓动只能处理单个参数的缓动 11 | * 如果要处理多参数缓动(比如bezier动画传入控制点参数), 12 | * 请在继承HActionInterval之后的update函数里计算处理, 不要调用this._super(dt); 13 | * 14 | * */ 15 | 16 | var ease = {}; 17 | module.exports = ease; 18 | 19 | let M_PI_X_2 = 3.1415926535 * 2; 20 | 21 | ease.easeIn = function (rate) { 22 | let period = rate; 23 | return function (time) { 24 | return Math.pow(time, period); 25 | } 26 | }; 27 | 28 | ease.easeOut = function (rate) { 29 | let period = rate; 30 | return function (time) { 31 | return Math.pow(time, 1/period); 32 | } 33 | }; 34 | 35 | 36 | ease.easeInOut = function (_rate) { 37 | let rate = _rate; 38 | return function (_time) { 39 | let time = 2 * _time; 40 | if (time < 1) { 41 | return 0.5 * Math.pow(time, rate); 42 | } 43 | else { 44 | return (1.0 - 0.5 * Math.pow(2 - time, rate)); 45 | } 46 | } 47 | }; 48 | ease.backEaseIn = function (rate) { 49 | return function (time) { 50 | let overshoot = 1.70158; 51 | return time * time * ((overshoot + 1) * time - overshoot); 52 | } 53 | } 54 | ease.easeBackOut = function (_rate = 1.70158) { 55 | let rate = _rate || 1.70158; 56 | return function (time) { 57 | let overshoot = rate; 58 | 59 | time = time - 1; 60 | return time * time * ((overshoot + 1) * time + overshoot) + 1; 61 | } 62 | }; 63 | 64 | 65 | ease.EaseElasticIn = function (value) { 66 | let period = value || 0.3; 67 | return function (time) { 68 | let newT = 0; 69 | if (time == 0 || time == 1) { 70 | newT = time; 71 | } 72 | else { 73 | let s = period / 4; 74 | time = time - 1; 75 | newT = -Math.pow(2, 10 * time) * Math.sin((time - s) * M_PI_X_2 / period); 76 | } 77 | return newT; 78 | } 79 | }; 80 | 81 | ease.EaseElasticOut = function (value) { 82 | let period = value || 0.3; 83 | return function (time) { 84 | let newT = 0; 85 | if (time == 0 || time == 1) { 86 | newT = time; 87 | } 88 | else { 89 | let s = period / 4; 90 | newT = Math.pow(2, -10 * time) * Math.sin((time - s) * M_PI_X_2 / period) + 1; 91 | } 92 | 93 | return newT; 94 | } 95 | }; 96 | ease.backEaseOut = function () { 97 | return function (time) { 98 | let overshoot = 1.70158; 99 | 100 | time = time - 1; 101 | return time * time * ((overshoot + 1) * time + overshoot) + 1; 102 | } 103 | }; 104 | 105 | ease.sineEaseOut = function () { 106 | return function (time) { 107 | return Math.sin(time * M_PI_X_2); 108 | } 109 | }; 110 | 111 | ease.sineEaseIn = function () { 112 | return function (time) { 113 | return -1 * Math.cos(time * M_PI_X_2) + 1; 114 | } 115 | }; 116 | 117 | ease.cubicEaseOut = function () { 118 | return function (time) { 119 | time -= 1; 120 | return (time * time * time + 1); 121 | }; 122 | }; 123 | 124 | ease.customEase = function( customEase ){ 125 | let cease = customEase; 126 | return function (time) { 127 | return cease.getRatio(time) 128 | }; 129 | } -------------------------------------------------------------------------------- /assets/ezaction/HEaseDefine.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "5c8c69ec-a3bd-4a75-9d99-c492984ba6f3", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/core.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "fc67b6d5-6ab3-40dc-b2a2-904b8a810fd2", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HAction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/17. 5 | * HAction核心基类 6 | */ 7 | require("HNodeEx"); 8 | let HVars = require("HVars"); 9 | 10 | // 生成唯一ID 11 | let UUID_GENERATOR = (function () { 12 | var i = 0; 13 | return function () { 14 | return "__HAction_uuid_" + i++; 15 | } 16 | })(); 17 | 18 | // HAction核心基类,请不要直接实例化使用 19 | let HAction = cc.Class({ 20 | ctor: function () { 21 | this.$uuid = UUID_GENERATOR(); 22 | this._delay = 0; 23 | this._state = ezaction.State.INITIAL; 24 | 25 | this._finishCallback = null; 26 | this._actionComponent = null; 27 | this.__nextAction = null; 28 | this._vars = new HVars(); 29 | this._isStart = false; 30 | Object.defineProperty(this, "vars", { get: function () { return this._vars; } }); 31 | }, 32 | 33 | setTag(value) { 34 | this._vars.tag = value; 35 | }, 36 | getTag() { 37 | return this._vars.tag; 38 | }, 39 | getState: function () { 40 | return this._state; 41 | }, 42 | isRunning: function () { 43 | return this._state === ezaction.State.RUNNING; 44 | }, 45 | 46 | getSpeed: function () { 47 | return this._vars["speed"]; 48 | }, 49 | /* 是否把加速出啊满地给next */ 50 | setSpeed: function (speedValue) { 51 | if (speedValue<=0){ 52 | cc.warn("HAction -> setSpeed: speed must be positive number"); 53 | return; 54 | } 55 | this._vars["speed"] = speedValue; 56 | return this; 57 | }, 58 | 59 | getVars: function () { 60 | return this._vars; 61 | }, 62 | /* 63 | * 获取HAction作用的cc.Node对象 64 | * */ 65 | getNode: function () { 66 | if (this._actionComponent) { 67 | return this._actionComponent.getTargetNode(); 68 | } 69 | return null; 70 | }, 71 | 72 | getComponent: function () { 73 | return this._actionComponent; 74 | }, 75 | 76 | pause: function () { 77 | if (this._state === ezaction.State.RUNNING){ 78 | this._state = ezaction.State.PAUSED; 79 | } 80 | return this; 81 | }, 82 | resume: function () { 83 | if (this._state === ezaction.State.PAUSED){ 84 | this._state = ezaction.State.RUNNING; 85 | } 86 | return this; 87 | }, 88 | 89 | 90 | /* 91 | * 初始化 (可重写改方法) 92 | * */ 93 | init: function (vars) { 94 | this._vars.patchParams(vars); 95 | }, 96 | /* 97 | * 开始绑定动作 (请继承以实现更多方法) 98 | * @ component: HAactionComponent组件 99 | * @ vars 额外参数 (克隆出需要保留的参数) : 100 | * 系统支持:delay,onUpdate,onComplete,repeat,actionComponent 101 | * */ 102 | startWithTarget: function (component) { 103 | if (this._actionComponent) { 104 | throw new Error("Error, HAction Had been added! "); 105 | return; 106 | } 107 | this._actionComponent = component; 108 | this.playAction(); 109 | }, 110 | 111 | /* 具体实现请继承 */ 112 | playAction: function () { 113 | this._state = ezaction.State.RUNNING; 114 | this._delay = this._vars.delay; 115 | this._isStart = false; 116 | }, 117 | /* 118 | * 执行调度函数, HActionEngine来调度此方法, 外部不可调用! 119 | * 此处需要区分三种update调用 120 | * _$update:由 HActionEngine来执行 121 | * $update:二级调度方法, ActionInterval来继承调用 外部可继承的$update方法 122 | * update: 外部可继承的update方法 123 | * */ 124 | _$update: function (dt) { 125 | let vars = this._vars; 126 | dt = dt * vars.speed; 127 | if (this._state !== ezaction.State.RUNNING) { 128 | return; 129 | } 130 | // 处理延时调用 131 | this._delay -= dt; 132 | if (this._delay <= 0){ 133 | // onStart事件 134 | if ( !this._isStart ){ 135 | this._isStart = true; 136 | if ( typeof vars["onStart"] === 'function') { 137 | vars["onStart"](this); 138 | } 139 | } 140 | this.$update(dt); 141 | if (this.isRunning() && typeof vars["onUpdate"] === 'function') { 142 | vars["onUpdate"](this, dt); 143 | } 144 | } 145 | }, 146 | $update: function (dt) { 147 | this.update(0); 148 | 149 | }, 150 | /* 151 | * 请重写改方法以实现更多行为 152 | * update Action状态 153 | * @ rate : action进度值 0~1 154 | * */ 155 | update: function (rate) { 156 | //TODO What you want to do; 157 | 158 | }, 159 | 160 | /* 161 | * 子类动作结束时请调用该方法 162 | * */ 163 | $actionComplete: function () { 164 | let vars = this._vars; 165 | if (typeof vars["onComplete"] === 'function') { 166 | vars["onComplete"](this); 167 | } 168 | let count = vars.repeat; 169 | if (count > 0) { 170 | this.playAction(); // 重置状态 171 | this.repeat(count - 1); 172 | } else { 173 | this._state = ezaction.State.STOPPED; 174 | if (typeof vars["onStoped"] === 'function') { 175 | vars["onStoped"](this); 176 | } 177 | if (this._finishCallback) { 178 | this._finishCallback(this, this.$getNextAction()); 179 | } 180 | if (this._actionComponent) { 181 | // 注意:playComplete不一定会调用成功,因为某些action是由spawn来维护 182 | this._actionComponent.playComplete(this); 183 | } 184 | } 185 | }, 186 | $setFinishCallback: function (callback) { 187 | this._finishCallback = callback; 188 | }, 189 | 190 | $getNextAction: function () { 191 | return this.__nextAction; 192 | }, 193 | $setNextAction: function (action, index /* null**/) { 194 | let _i = 9999999; 195 | if (typeof index === "number" && index > -1) { 196 | _i = index; 197 | } 198 | let i = 0; 199 | let preAction = this; 200 | let nextAct = this.__nextAction; 201 | while (nextAct) { 202 | if (i === _i) { break; } 203 | preAction = nextAct; 204 | nextAct = nextAct.__nextAction; 205 | if (!nextAct) { 206 | break; 207 | } 208 | ++i; 209 | } 210 | if (nextAct){ 211 | nextAct.destroy(); 212 | } 213 | preAction.__nextAction = action; 214 | return action; 215 | }, 216 | $removeNextAction: function () { 217 | if (this.__nextAction){ 218 | this.__nextAction.destroy(); 219 | } 220 | this.__nextAction = null; 221 | }, 222 | 223 | /* 224 | * then式调用链,可以用链式方法来处理, 225 | * 建议用then方式来取代Sequence 226 | * */ 227 | then: function (act) { 228 | if (this.__nextAction) { 229 | this.__nextAction.$destroy(); 230 | } 231 | this.__nextAction = act; 232 | return this; 233 | }, 234 | /* 235 | * 完备克隆action 236 | * 如果有鏈式结构,会一并克隆下去 237 | * */ 238 | clone: function () { 239 | let target = this.cloneSelf(); 240 | let nextAct = this.$getNextAction(); 241 | while (nextAct) { 242 | target.$setNextAction(nextAct.cloneSelf()); 243 | nextAct = nextAct.$getNextAction(); 244 | } 245 | return target; 246 | }, 247 | /** 248 | * 克隆自身 249 | * 每个子类独立去实现克隆方法 250 | */ 251 | cloneSelf: function () { 252 | return null; 253 | }, 254 | 255 | repeatForever: function () { 256 | this._vars["repeat"] = Number.MAX_VALUE; 257 | return this; 258 | }, 259 | /* 260 | * 重新repeat播放 value 重复次数 261 | * */ 262 | repeat: function (value) { 263 | this._vars["repeat"] = value; 264 | return this; 265 | }, 266 | 267 | onStart: function (func) { 268 | if (typeof func === 'function'){ 269 | this._vars["onStart"] = func; 270 | } 271 | return this; 272 | }, 273 | 274 | onUpdate: function (func) { 275 | if (typeof func === 'function'){ 276 | this._vars["onUpdate"] = func; 277 | } 278 | return this; 279 | }, 280 | onComplete: function (func) { 281 | if (typeof func === 'function'){ 282 | this._vars["onComplete"] = func; 283 | } 284 | return this; 285 | }, 286 | onStoped: function (func) { 287 | if (typeof func === 'function'){ 288 | this._vars["onStoped"] = func; 289 | } 290 | return this; 291 | }, 292 | 293 | destroy:function(){ 294 | if (this._state == ezaction.State.DEAD){ 295 | return; 296 | } 297 | if (this._actionComponent) { 298 | this._state = ezaction.State.DEAD; 299 | this._actionComponent.destroyAction(this); 300 | } else { 301 | this.$destroy(); 302 | } 303 | }, 304 | 305 | $invalid: function () { 306 | if (this._state == ezaction.State.DEAD){ 307 | return; 308 | } 309 | if (this._actionComponent) { 310 | this._state = ezaction.State.DEAD; 311 | this._actionComponent.addActionToInvalidList(this); 312 | } else { 313 | this.$destroy(); 314 | } 315 | }, 316 | /* 317 | * 仅继承重写,不可外部调用!!!!! 318 | * */ 319 | $destroy: function () { 320 | // cc.log("销毁" + this.$uuid); 321 | this._state = ezaction.State.DEAD; 322 | this._vars = null; 323 | this.__nextAction = null; 324 | this._finishCallback = null; 325 | this._actionComponent = null; 326 | } 327 | }); 328 | module.exports = HAction; -------------------------------------------------------------------------------- /assets/ezaction/core/HAction.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "84e0b6f1-556e-481f-a6a8-c160d2ccbd74", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HActionComponent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/21. 5 | * 6 | * hActionComponent是管理父Node节点的组件。 7 | * 不允许外部对其直接访问和修改! 8 | */ 9 | 10 | module.exports = cc.Class({ 11 | extends: cc.Component, 12 | 13 | getTargetNode: function () { 14 | return this._targetNode; 15 | }, 16 | 17 | getActionEngine(){ 18 | if (!this.actionEngine){ 19 | this.actionEngine = require("HActionEngine")(); 20 | } 21 | return this.actionEngine; 22 | }, 23 | 24 | __$init: function (targetNode) { 25 | this._targetNode = targetNode; 26 | }, 27 | // use this for initialization 28 | onLoad: function () { 29 | this._targetNode = this.node; 30 | }, 31 | 32 | addActionToTickQueue: function (hAction) { 33 | if (hAction.getComponent()) { 34 | cc.warn("HActionComponent -> addActionToTickQueue warn: 重复添加HAction可能会带来不可知的问题! "); 35 | return; 36 | } 37 | this.getActionEngine().pushActionToQueue(hAction); 38 | hAction.startWithTarget(this); 39 | }, 40 | 41 | removeAction: function (hAction) { 42 | return this.getActionEngine().removeAction(hAction); 43 | }, 44 | 45 | removeActions: function (actions) { 46 | let ae = this.getActionEngine(); 47 | for (let i = 0; i < actions.length; i++) { 48 | ae.destroyAction(actions[i]); 49 | } 50 | }, 51 | 52 | removeAllActions: function () { 53 | return this.getActionEngine().removeAllActions(this); 54 | }, 55 | 56 | getRunningActions: function () { 57 | return this.getActionEngine().getRunningActions(this); 58 | }, 59 | 60 | getActionByTag: function (tag) { 61 | return this.getActionEngine().getActionByTag(this, tag); 62 | }, 63 | 64 | playComplete: function (hAction) { 65 | return this.getActionEngine().actionPlayComplete(hAction) 66 | }, 67 | 68 | addActionToInvalidList: function (hAction) { 69 | return this.getActionEngine().addActionToInvalidList(hAction); 70 | }, 71 | 72 | destroyAction:function(hAction){ 73 | return this.getActionEngine().__invalidActionAndNext(hAction); 74 | }, 75 | 76 | onDestroy: function () { 77 | if (this.actionEngine){ 78 | this.actionEngine.removeAllActions(this); 79 | } 80 | this.actionEngine = null; 81 | this._targetNode = null; 82 | } 83 | }); 84 | -------------------------------------------------------------------------------- /assets/ezaction/core/HActionComponent.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "dd86c4c9-c284-4b0f-845f-414ad4ac4ec6", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HActionEngine.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @CreateTime: Feb 3, 2018 3:15 PM 3 | * @Author: howe 4 | * @Contact: ihowe@outlook.com 5 | * @Last Modified By: howe 6 | * @Last Modified Time: Mar 29, 2018 12:06 PM 7 | * @Description: EZAction 的驱动引擎 8 | */ 9 | const HAction = require("HAction"); 10 | const HActionComponent = require("HActionComponent"); 11 | 12 | let HActionEngine = cc.Class({ 13 | ctor: function () { 14 | this.uuid = "HActionEngine"; 15 | this._id = this.uuid; 16 | this._actions = []; 17 | this._tempInvalidIds = {}; 18 | 19 | let scheduler = cc.director.getScheduler(); 20 | // scheduler.scheduleUpdateForTarget(this, 0, false); 21 | scheduler.scheduleUpdate(this, 0, false); 22 | }, 23 | 24 | pushActionToQueue: function (hAction) { 25 | if (!(hAction instanceof HAction)) { 26 | cc.error("HActionEngine -> pushActionToQueue error: params must be a subclass of HAction!"); 27 | } 28 | this._actions.push(hAction); 29 | }, 30 | 31 | getActionByTag: function (hactionComponent, tag) { 32 | if (!(hactionComponent instanceof HActionComponent)) { 33 | cc.error("HActionEngine -> getActionByTag error: params must be a instance of HActionComponent!"); 34 | } 35 | let len = this._actions.length; 36 | for (let i = 0; i < len; i++) { 37 | let _action = this._actions[i]; 38 | if (_action.getComponent().uuid === hactionComponent.uuid) { 39 | if (_action.getTag() === tag) { 40 | return _action; 41 | } else { 42 | let preAction = _action; 43 | let nextAction = _action.$getNextAction(); 44 | while (nextAction) { 45 | if (nextAction.getTag() === tag) { 46 | return nextAction; 47 | } 48 | preAction = nextAction; 49 | nextAction = nextAction.$getNextAction(); 50 | } 51 | } 52 | } 53 | } 54 | return null; 55 | }, 56 | 57 | getRunningActions: function (hactionComponent) { 58 | if (!(hactionComponent instanceof HActionComponent)) { 59 | cc.error("HActionEngine -> getRunningActions error: params must be a instance of HActionComponent!"); 60 | } 61 | let ret = []; 62 | let len = this._actions.length; 63 | for (let i = 0; i < len; i++) { 64 | let _action = this._actions[i]; 65 | if (_action.getComponent().uuid === hactionComponent.uuid) { 66 | if (_action.getState() === ezaction.State.RUNNING) { 67 | ret.push(_action); 68 | } 69 | } 70 | } 71 | return ret; 72 | }, 73 | 74 | removeAction: function (hAction) { 75 | if (!(hAction instanceof HAction)) { 76 | cc.error("HActionEngine -> removeAction error: params must be a subclass of HAction!"); 77 | } 78 | if (hAction.getState() === ezaction.State.DEAD){ 79 | return; 80 | } 81 | let uuid = hAction["$uuid"]; 82 | let len = this._actions.length; 83 | for (let i = 0; i < len; i++) { 84 | let _action = this._actions[i]; 85 | if (_action["$uuid"] === uuid) { 86 | this.__invalidActionAndNext(_action); 87 | return true; 88 | } else { 89 | let preAction = _action; 90 | let nextAction = _action.$getNextAction(); 91 | while (nextAction) { 92 | if (nextAction["$uuid"] === uuid) { 93 | preAction.$removeNextAction(); 94 | return true; 95 | } 96 | preAction = nextAction; 97 | nextAction = nextAction.$getNextAction(); 98 | } 99 | } 100 | } 101 | return false; 102 | }, 103 | 104 | removeAllActions: function (hactionComponent) { 105 | if (!(hactionComponent instanceof HActionComponent)) { 106 | cc.error("HActionEngine -> removeAllActions error: params must be a instance of HActionComponent!"); 107 | } 108 | let len = this._actions.length; 109 | for (let i = 0; i < len; i++) { 110 | let _action = this._actions[i]; 111 | if (_action.getComponent().uuid === hactionComponent.uuid) { 112 | this.__invalidActionAndNext(_action); 113 | } 114 | } 115 | }, 116 | 117 | actionPlayComplete: function (hAction) { 118 | let len = this._actions.length; 119 | for (let i = 0; i < len; i++) { 120 | let _action = this._actions[i]; 121 | if (_action["$uuid"] === hAction["$uuid"]) { 122 | let nexthAction = hAction.$getNextAction(); 123 | if (nexthAction) { 124 | // 启动单链表下个节点的Action 125 | nexthAction.startWithTarget(hAction.getComponent()); 126 | this._actions[i] = nexthAction; 127 | } 128 | hAction.$invalid(); 129 | break; 130 | } 131 | } 132 | }, 133 | __invalidActionAndNext: function (hAction) { 134 | let nextAct = hAction.$getNextAction(); 135 | while (nextAct) { 136 | let act = nextAct; 137 | nextAct = act.$getNextAction(); 138 | act.$invalid(); 139 | } 140 | hAction.$invalid(); 141 | }, 142 | 143 | addActionToInvalidList: function (hAction) { 144 | if (!(hAction instanceof HAction)) { 145 | cc.error("HActionEngine -> addActionToInvalidList error: params must be a subclass of HAction!"); 146 | } 147 | this._tempInvalidIds[hAction["$uuid"]] = hAction; // 下一帧销毁 148 | }, 149 | 150 | update: function (dt) { 151 | let arr = this._actions; 152 | if (Object.keys(this._tempInvalidIds).length > 0) { 153 | for (let uuid in this._tempInvalidIds) { 154 | this._tempInvalidIds[uuid].$destroy(); 155 | } 156 | for (let i = 0, flag = true, len = arr.length; i < len; flag ? i++ : i) { 157 | if (arr[i] && this._tempInvalidIds[arr[i]["$uuid"]]) { 158 | arr.splice(i, 1); 159 | flag = false; 160 | } else { 161 | flag = true; 162 | } 163 | } 164 | this._tempInvalidIds = {}; 165 | } 166 | arr.forEach(function (action) { 167 | let comp = action.getComponent(); 168 | if (!comp || !comp.enabled || !comp.isValid) { 169 | return; 170 | } 171 | action["_$update"](dt); 172 | }); 173 | } 174 | }); 175 | let engine = null; 176 | module.exports = function(){ 177 | if (engine){ 178 | return engine; 179 | } 180 | engine = new HActionEngine(); 181 | return engine; 182 | } ; -------------------------------------------------------------------------------- /assets/ezaction/core/HActionEngine.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "31c46ba2-cade-4b2f-9215-03fded127299", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HActionSequence.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/22. 5 | * 6 | * 顺序执行 7 | */ 8 | let HActionSequence = cc.Class({ 9 | extends: require("HAction"), 10 | ctor: function () { 11 | this._actions = []; 12 | }, 13 | setSpeed: function (value) { 14 | value = Math.abs(value); 15 | this._actions.forEach(function (action) { 16 | action.setSpeed(value); 17 | }); 18 | return this._super(value); 19 | }, 20 | pushAction: function (actions, isInhertSpeed){ 21 | for (let i = 0; i < actions.length; i++) { 22 | let act = actions[i]; 23 | if (isInhertSpeed) { 24 | act.setSpeed(this.getSpeed()); 25 | } 26 | this._actions.push(act); 27 | } 28 | }, 29 | playAction: function () { 30 | this._super(); 31 | // 重置所有Action的状态 32 | let len = this._actions.length; 33 | for (let i = 0; i < len; i++) { 34 | let act = this._actions[i]; 35 | while (act) { 36 | act.playAction(); 37 | act = act.$getNextAction(); 38 | } 39 | } 40 | }, 41 | 42 | $update: function (dt) { 43 | this._super(dt); 44 | if (!this._actions) { 45 | this.$actionComplete(); 46 | return; 47 | } 48 | let flag = true; 49 | let len = this._actions.length; 50 | for (let i = 0; i < len; i++) { 51 | let act = this._actions[i]; 52 | while (act) { 53 | if (!act.getNode()) { 54 | act.startWithTarget(this._actionComponent); 55 | } 56 | if (act.isRunning()) { 57 | act["_$update"](dt); 58 | flag = false; 59 | break; 60 | } 61 | act = act.$getNextAction(); 62 | } 63 | if (!flag) { 64 | break; 65 | } 66 | } 67 | if (flag) { 68 | this.$actionComplete(); 69 | } 70 | }, 71 | cloneSelf: function () { 72 | let sequence = new HActionSequence(); 73 | sequence.init(this.getVars()); 74 | if (this._actions) { 75 | let list = []; 76 | this._actions.forEach(function (action) { 77 | list.push(action.clone()); 78 | }); 79 | sequence.pushAction(list, false); 80 | list = null; 81 | } 82 | return sequence; 83 | }, 84 | $invalid: function () { 85 | if (!this._actions) { 86 | // cc.warn(" HActionSequence 重复调用$invalid "); 87 | this._super(); 88 | return; 89 | } 90 | this._actions.forEach(function (action) { 91 | action.destroy(); 92 | }); 93 | this._actions = null; 94 | this._super(); 95 | }, 96 | $destroy: function () { 97 | this._actions = null; 98 | this._super(); 99 | } 100 | }); 101 | 102 | HActionSequence.create = function (actions, vars) { 103 | let act = new HActionSequence(); 104 | act.init(vars); 105 | act.pushAction(actions); 106 | return act; 107 | }; 108 | module.exports = HActionSequence; -------------------------------------------------------------------------------- /assets/ezaction/core/HActionSequence.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "58aa7147-7a0a-49f1-8f25-67fedcc1d32e", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HActionSpawn.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/22. 5 | * 6 | * 同步执行 7 | */ 8 | let HActionSpawn = cc.Class({ 9 | extends: require("HAction"), 10 | ctor: function () { 11 | this._actions = []; 12 | }, 13 | setSpeed: function (value) { 14 | value = Math.abs(value); 15 | for (let i = 0; i < this._actions.length; i++) { 16 | this._actions[i].setSpeed(value); 17 | } 18 | return this._super(value); 19 | }, 20 | pushAction: function (actions, isInhertSpeed) { 21 | for (let i = 0; i < actions.length; i++) { 22 | let act = actions[i]; 23 | if (isInhertSpeed) { 24 | act.setSpeed(this.getSpeed()); 25 | } 26 | this._actions.push(act); 27 | } 28 | }, 29 | playAction: function () { 30 | this._super(); 31 | // 重置所有Action的状态 32 | let len = this._actions.length; 33 | for (let i = 0; i < len; i++) { 34 | let act = this._actions[i]; 35 | while (act) { 36 | act.playAction(); 37 | act = act.$getNextAction(); 38 | } 39 | } 40 | }, 41 | $update: function (dt) { 42 | this._super(dt); 43 | if (!this._actions) { 44 | this.$actionComplete(); 45 | return; 46 | } 47 | let flag = true; 48 | let len = this._actions.length; 49 | for (let i = 0; i < len; i++) { 50 | let act = this._actions[i]; 51 | while (act) { 52 | if (!act.getNode()) { 53 | act.startWithTarget(this._actionComponent); 54 | } 55 | if (act.isRunning()) { 56 | act["_$update"](dt); 57 | flag = false; 58 | break; 59 | } 60 | act = act.$getNextAction(); 61 | } 62 | } 63 | if (flag) { 64 | this.$actionComplete(); 65 | } 66 | }, 67 | cloneSelf: function () { 68 | let spawn = new HActionSpawn(); 69 | spawn.init(this.getVars()); 70 | if (this._actions) { 71 | let list = []; 72 | this._actions.forEach(function (action) { 73 | list.push(action); 74 | }); 75 | spawn.pushAction(list, false); 76 | list = null; 77 | } 78 | return spawn; 79 | }, 80 | $invalid: function () { 81 | if (!this._actions) { 82 | // cc.warn(" HActionSpawn 重复调用$invalid "); 83 | this._super(); 84 | return; 85 | } 86 | this._actions.forEach(function (action) { 87 | action.destroy(); 88 | }); 89 | this._actions = null; 90 | this._super(); 91 | }, 92 | $destroy: function () { 93 | this._actions = null; 94 | this._super(); 95 | } 96 | }); 97 | 98 | HActionSpawn.create = function (actions, vars /* null */) { 99 | let act = new HActionSpawn(); 100 | act.init(vars); 101 | act.pushAction(actions); 102 | return act; 103 | }; 104 | module.exports = HActionSpawn; -------------------------------------------------------------------------------- /assets/ezaction/core/HActionSpawn.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "258d5609-aa6b-44b4-b08d-82a9dbfe21c7", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HNodeEx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/21. 5 | */ 6 | 7 | let HActionComponent = require("HActionComponent"); 8 | 9 | let NodePrototype = cc.Node.prototype; 10 | 11 | NodePrototype.RunAction = function (HAction) { 12 | if (!this._components) { 13 | return; 14 | } 15 | let component = this.getComponent(HActionComponent); 16 | if (!component) { 17 | this.addComponent(HActionComponent); 18 | component = this.getComponent(HActionComponent); 19 | component.__$init(this); 20 | } 21 | component.addActionToTickQueue(HAction); 22 | return HAction; 23 | }; 24 | 25 | NodePrototype.RemoveAction = function (HAction) { 26 | if (!this._components) { 27 | return; 28 | } 29 | let component = this.getComponent(HActionComponent); 30 | if (component) { 31 | component.removeAction(HAction); 32 | } 33 | }; 34 | 35 | NodePrototype.RemoveActionByTag = function (tag){ 36 | if (!this._components) { 37 | return; 38 | } 39 | let act = this.GetActionByTag(tag); 40 | if (act){ 41 | this.RemoveAction(act); 42 | } 43 | } 44 | 45 | NodePrototype.RemoveAllActions = function () { 46 | if (!this._components) { 47 | return; 48 | } 49 | let component = this.getComponent(HActionComponent); 50 | if (component) { 51 | component.removeAllActions(); 52 | } 53 | }; 54 | 55 | NodePrototype.StopAllActions = NodePrototype.RemoveAllActions; 56 | 57 | NodePrototype.GetRunningActions = function (){ 58 | if (!this._components) { 59 | return []; 60 | } 61 | let component = this.getComponent(HActionComponent); 62 | if (component) { 63 | return component.getRunningActions(); 64 | } 65 | return []; 66 | } 67 | 68 | NodePrototype.GetActionByTag = function (tag) { 69 | if (!this._components) { 70 | return null; 71 | } 72 | let component = this.getComponent(HActionComponent); 73 | if (component) { 74 | return component.getActionByTag(tag); 75 | } 76 | return null; 77 | }; 78 | 79 | NodePrototype.RemoveEZActionComponent = function () { 80 | this.removeComponent(HActionComponent); 81 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HNodeEx.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "a4316e17-c45c-4731-9b3c-767d9ad96583", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/core/HVars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/29. 5 | */ 6 | let HVars = function () { 7 | this.tag = 0; 8 | this.speed = 1; 9 | this.repeat = 0; 10 | this.delay = 0; 11 | }; 12 | 13 | HVars.prototype.clone = function (obj) { 14 | let result = obj || {}; 15 | let arr = Object.keys(this); 16 | for (let i = 0; i < arr.length; i++) { 17 | let key = arr[i]; 18 | let _type = typeof this[key]; 19 | if (this[key] instanceof Array) { 20 | result[key] = []; 21 | for (let j = 0; j < this[key].length; j++) { 22 | result[key][j] = this[key][j]; 23 | } 24 | } else { 25 | result[key] = this[key]; 26 | } 27 | } 28 | return result; 29 | }; 30 | 31 | /*参数patch*/ 32 | HVars.prototype.patchParams = function (params) { 33 | if (!params) { 34 | return; 35 | } 36 | if (params instanceof HVars) { 37 | params.clone(this); 38 | return; 39 | } 40 | for (let key in params) { 41 | this[key] = params[key]; 42 | } 43 | }; 44 | 45 | module.exports = HVars; 46 | 47 | -------------------------------------------------------------------------------- /assets/ezaction/core/HVars.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "17a79b10-9a36-4099-bfce-2725acef0b1d", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/ezaction/ezaction.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @CreateTime: Jan 23, 2018 1:49 PM 3 | * @Author: howe 4 | * @Contact: ihowe@outlook.com 5 | * @Last Modified By: howe 6 | * @Last Modified Time: Sep 13, 2018 11:37 AM 7 | * @Description: ezaction的TS接口描述文件 8 | * 9 | */ 10 | 11 | /** require模块方法 */ 12 | declare function require(moduleName:string):any; 13 | 14 | /** 15 | * cc.Node的prototype新增部分方法 16 | */ 17 | declare namespace cc { 18 | export interface Node { 19 | /*** 20 | * Run HAction实例,这个Action的作用对象是当前cc.Node 21 | */ 22 | RunAction(act: ezaction.HAction): ezaction.HAction; 23 | /** 24 | * 删除action 25 | */ 26 | RemoveAction(action: ezaction.HAction): void; 27 | 28 | /** 29 | * 删除action 30 | */ 31 | RemoveActionByTag(tag: number): void; 32 | 33 | /** 34 | * 删除当前节点的所有HAction 35 | */ 36 | RemoveAllActions(): void; 37 | /** 38 | * 停止当前节点的HAction,等同于RemoveAllActions 39 | */ 40 | StopAllActions(): void; 41 | /** 42 | * 获取当前节点上正在运行的action 43 | */ 44 | GetRunningActions(): Array; 45 | /** 46 | * 根据tag获取HAction 47 | */ 48 | GetActionByTag(tag: number): ezaction.HAction; 49 | /** 50 | * 删除HActionComponent,这将导致当前节点的所有的HAction无效 51 | */ 52 | RemoveEZActionComponent(): void; 53 | } 54 | } 55 | 56 | declare namespace ezaction { 57 | 58 | export class CustomEase{ 59 | getRatio(progress:number):number; 60 | } 61 | export class HCustomEase{ 62 | static create(id:string,data:string,config:any = null):CustomEase; 63 | } 64 | /** 65 | * 缓动模块 该模块只对HActionInterval和其子类有效果 66 | */ 67 | export module ease { 68 | function backEaseIn(rate: number = 3.0): Function; 69 | function easeIn(rate: number = 3.0): Function; 70 | function easeOut(rate: number = 2): Function; 71 | function easeInOut(rate?: number): Function; 72 | function easeBackOut(rate?: number = 1.70158): Function; 73 | function EaseElasticIn(rate: number): Function; 74 | function EaseElasticOut(rate: number): Function; 75 | function backEaseOut(rate: number): Function; 76 | function sineEaseOut(rate: number): Function; 77 | function sineEaseIn(rate: number): Function; 78 | function cubicEaseOut(rate: number): Function; 79 | function customEase( customEase: CustomEase ): Function; 80 | } 81 | /** 82 | * HAction的状态 83 | * 0 表示初始化,1表示运行,2表示暂停,3表示停止,4表示销毁 84 | */ 85 | export enum State { 86 | INITIAL = 0, 87 | RUNNING = 1, 88 | PAUSED = 2, 89 | STOPPED = 3, 90 | DEAD = 4 91 | } 92 | 93 | export class HActionComponent extends cc.Component { 94 | } 95 | 96 | export class HAction { 97 | 98 | /** 99 | * 唯一id 100 | */ 101 | readonly $uuid: string; 102 | /** 103 | * vars变量,HVars的实例 104 | */ 105 | readonly vars: any; 106 | /** 107 | * vars变量,HVars的实例 108 | */ 109 | getVars(): any; 110 | 111 | /** 112 | * 设置tag值 113 | * @param value 114 | */ 115 | setTag(value: number): void; 116 | /** 117 | * 获取tag 118 | */ 119 | getTag(): number; 120 | /** 121 | * 当前HAction的状态 122 | */ 123 | getState(): ezaction.State; 124 | /** 125 | * 当前HAction是否正在运行 126 | */ 127 | isRunning(): boolean; 128 | /** 129 | * 当前HAction速度 ,1为正常速度,数字越大,运行越快 130 | */ 131 | getSpeed(): number; 132 | /** 133 | * 设置HAction速度 ,1为正常速度,数字越大,运行越快 134 | */ 135 | setSpeed(value: number): HAction; 136 | 137 | /** 138 | * 当前HAction作用的Node节点 139 | */ 140 | getNode(): cc.Node; 141 | /** 142 | * 当前HAction作用的Node上的 143 | */ 144 | getComponent(): HActionComponent; 145 | /** 146 | * 初始化 147 | * @param vars 任意变量对象 148 | */ 149 | init(vars: any = null): void; 150 | /** 151 | * update调用,请覆盖重新该方法而不要手动去调用 152 | * @param rate 0~1之间 153 | */ 154 | update(rate: number): void; 155 | /** 156 | * 暂停(只有运行状态才可以暂停) 157 | */ 158 | pause(): HAction; 159 | /** 160 | * 恢复(只有暂停状态才可以恢复运行) 161 | */ 162 | resume(): HAction; 163 | /* 164 | * then式调用链,可以用链式方法来处理, 165 | * 建议用then方式来取代Sequence 166 | * */ 167 | then(act: HAction): HAction; 168 | /* 169 | * 完备克隆action 170 | * 如果有鏈式结构,会一并克隆下去 171 | * */ 172 | clone(): HAction; 173 | /** 174 | * 克隆自身 175 | * 每个子类独立去实现克隆方法 176 | */ 177 | cloneSelf(): HAction; 178 | /** 179 | * 无限重复该HAction 180 | */ 181 | repeatForever(): HAction; 182 | /* 183 | * 重新repeat播放 value 重复次数 184 | * */ 185 | repeat(value: number): HAction; 186 | /* 187 | * onUpdate回调 188 | * */ 189 | onStart(callFunc: Function): HAction; 190 | /* 191 | * onUpdate回调 192 | * */ 193 | onUpdate(callFunc: Function): HAction; 194 | /* 195 | * 完成回调,注意如果设置了repeat次数,则该回调会触发repeat次 196 | * */ 197 | onComplete(callFunc: Function): HAction; 198 | /** 199 | * 停止回调,所有的repeat执行完成后调用。在onComplete触发之后 200 | * @param callFunc 201 | */ 202 | onStoped(callFunc: Function): HAction; 203 | /** 204 | * 销毁当前HAction,注意:HAction标记为销毁的节点只会在下一帧才会真正销毁掉。 205 | */ 206 | destroy(); 207 | 208 | protected startWithTarget(component: HActionComponent): void; 209 | 210 | protected playAction(): void; 211 | 212 | protected _$update(dt: number): void; 213 | 214 | protected $update(dt: number): void; 215 | 216 | protected $invalid(): void; 217 | 218 | protected $destroy(): void; 219 | } 220 | /** 221 | * Spawn同时运行Action,类似cc.Spawn 222 | */ 223 | export class HActionSpawn extends HAction { 224 | static create(actions: Array, vars: any = null): HActionSpawn 225 | } 226 | /** 227 | * Spawn串联运行Action,类似cc.Sequence 228 | */ 229 | export class HActionSequence extends HAction { 230 | static create(actions: Array, vars: any = null): HActionSequence 231 | } 232 | /** 233 | * 瞬时执行,执行一帧后完成 234 | */ 235 | export class HActionInstant extends HAction { 236 | static create(vars: any = null): HActionInstant 237 | } 238 | /** 239 | * HActionInterval是基于时间调度的动作基类 240 | */ 241 | export class HActionInterval extends HAction { 242 | getCurrentTime(): number; 243 | 244 | getDuration(): number; 245 | 246 | getProgress(): number; 247 | 248 | init(duration: number, vars:any = null /*null */): void; 249 | /* 250 | * 参数为缓动函数, 函数定义可查看GEaseDefine.js文件 251 | * 你可以传入一个自己定义的函数,该函数必须接受progress值来处理 252 | * */ 253 | easing(easeFunc: Function): HActionInterval 254 | /** 255 | * 当HAction设置了缓动函数,有可能出现时间还没到,node越过目标参数的情况,当node越过时,func会被触发 256 | * **/ 257 | onArrived(func: Function): HActionInterval 258 | 259 | static create(duration: number, vars:any = null): HActionInterval; 260 | } 261 | export class HActionTweenBase extends HActionInterval { 262 | setTarget(objOrNode:any):void; 263 | getTarget():any; 264 | } 265 | 266 | export class HActionTween extends HActionTweenBase { 267 | static create(vars: any = null): HActionTween 268 | } 269 | 270 | export class HActionTweenBy extends HActionTweenBase { 271 | static create(vars: any = null): HActionTweenBy 272 | } 273 | 274 | export class HActionJumpBy extends HActionInterval { 275 | } 276 | 277 | export class HActionJumpTo extends HActionJumpBy { 278 | } 279 | 280 | export function v2(x: number | { x: number, y: number }, y: number): { x: number, y: number }; 281 | 282 | export function callFuncWithParam(func: Function, ...aArgs): ezaction.HActionInstant; 283 | export function callFunc(func: Function, params: any = null, vars:any = null): ezaction.HActionInstant; 284 | 285 | export function delay(duration: number, vars:any = null): ezaction.HActionInterval; 286 | 287 | export function sequence(actions: Array, vars:any = null): ezaction.HActionSequence; 288 | 289 | export function spawn(actions: Array, vars:any = null): ezaction.HActionSpawn; 290 | 291 | export function tween(duration: number, params: any, vars:any = null): ezaction.HActionTween; 292 | 293 | export function tweenBy(duration: number, params: any, vars:any = null): ezaction.HActionTweenBy; 294 | 295 | export function moveTo(duration: number, params: any, vars:any = null): ezaction.HActionTween; 296 | export function moveBy(duration: number, params: any, vars:any = null): ezaction.HActionTweenBy; 297 | 298 | export function scaleTo(duration: number, params: any, vars:any = null): ezaction.HActionTween; 299 | export function scaleBy(duration: number, params: any, vars:any = null): ezaction.HActionTweenBy; 300 | 301 | export function skewTo(duration: number, params: any, vars:any = null): ezaction.HActionTween; 302 | export function skewBy(duration: number, params: any, vars:any = null): ezaction.HActionTweenBy; 303 | 304 | export function rotateTo(duration: number, numberOrObj: number|any, vars:any = null): ezaction.HActionTween; 305 | export function rotateBy(duration: number, numberOrObj: number|any, vars:any = null): ezaction.HActionTweenBy; 306 | 307 | export function fadeTo(duration: number, opacity: number, vars:any = null): ezaction.HActionTween; 308 | export function fadeIn(duration: number, vars:any = null): ezaction.HActionTween; 309 | export function fadeOut(duration: number, vars:any = null): ezaction.HActionTween; 310 | 311 | export function show( vars:any = null): ezaction.HActionInstant; 312 | export function hide( vars:any = null): ezaction.HActionInstant; 313 | 314 | export function jumpBy( duration:number, pos:{x:number,y:number}, height:number, jumps:number, vars:any = null ): ezaction.HActionJumpBy; 315 | export function jumpTo( duration:number, pos:{x:number,y:number}, height:number, jumps:number, vars:any = null ): ezaction.HActionJumpTo; 316 | 317 | } -------------------------------------------------------------------------------- /assets/ezaction/ezaction.d.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "2.0.0", 3 | "uuid": "d63b8a09-37f0-4b73-b230-0d8efe3149c7", 4 | "subMetas": {} 5 | } -------------------------------------------------------------------------------- /assets/ezaction/ezaction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ihowe@outlook.com 3 | * author by haroel 4 | * Created by howe on 2017/3/23. 5 | */ 6 | 7 | let ezaction = ezaction || {}; 8 | module.exports = ezaction; 9 | if (window && typeof window === 'object') { 10 | window.ezaction = ezaction; 11 | } 12 | //0 表示初始化,1表示运行,2表示暂停,3表示停止,4表示销毁 13 | ezaction.State = { 14 | INITIAL: 0, 15 | RUNNING: 1, 16 | PAUSED: 2, 17 | STOPPED: 3, 18 | DEAD: 4 19 | }; 20 | 21 | ezaction.HVars = require("HVars"); 22 | ezaction.ease = require("HEaseDefine"); 23 | 24 | ezaction.HAction = require("HAction"); 25 | ezaction.HActionInstant = require("HActionInstant"); 26 | ezaction.HActionInterval = require("HActionInterval"); 27 | ezaction.HActionTween = require("HActionTween"); 28 | ezaction.HActionTweenBy = require("HActionTweenBy"); 29 | ezaction.HActionSpawn = require("HActionSpawn"); 30 | ezaction.HActionSequence = require("HActionSequence"); 31 | 32 | ezaction.HActionJumpBy = require("HActionJump").jumpBy; 33 | ezaction.HActionJumpTo = require("HActionJump").jumpTo; 34 | ezaction.HCustomEase = require("HCustomEase"); 35 | 36 | let __checkParams = function (params) { 37 | // 剔除参数当中的不需要数据 38 | let obj = {}; 39 | for (let k in params) { 40 | let _o = params[k]; 41 | if (typeof _o === "number") { 42 | obj[k] = _o; 43 | } 44 | } 45 | return obj; 46 | }; 47 | 48 | ezaction.v2 = function (_x, _y) { 49 | if (typeof _x === 'number') { 50 | return { x: _x, y: _y }; 51 | } 52 | return { x: _x.x, y: _x.y }; 53 | }; 54 | 55 | ezaction.callFuncWithParam = function (func, ...aArgs) { 56 | let vars = {}; 57 | vars["onComplete"] = function () { 58 | func(...aArgs); 59 | }; 60 | return ezaction.HActionInstant.create(vars); 61 | }; 62 | 63 | ezaction.callFunc = function (func, params/* null */, vars/* null */) { 64 | vars = vars || {}; 65 | vars["onComplete"] = function () { 66 | func(params); 67 | }; 68 | return ezaction.HActionInstant.create(vars); 69 | }; 70 | 71 | ezaction.delay = function (duration, vars/* null */) { 72 | return ezaction.HActionInterval.create(duration, vars); 73 | }; 74 | ezaction.delayTime = ezaction.delay; 75 | 76 | ezaction.sequence = function (actions, vars/* null */) { 77 | return ezaction.HActionSequence.create(actions, vars); 78 | }; 79 | 80 | ezaction.spawn = function (actions, vars/* null */) { 81 | return ezaction.HActionSpawn.create(actions, vars); 82 | }; 83 | 84 | ezaction.tween = function (duration, params, vars) { 85 | params = __checkParams(params); 86 | let _vars = vars; 87 | if (!_vars) { 88 | _vars = params || {}; 89 | } else { 90 | for (let k in params) { 91 | _vars[k] = params[k] 92 | } 93 | } 94 | let tween = ezaction.HActionTween.create(duration, _vars); 95 | return tween; 96 | }; 97 | 98 | ezaction.tweenBy = function (duration, params, vars) { 99 | params = __checkParams(params); 100 | let _vars = vars; 101 | if (!_vars) { 102 | _vars = params || {}; 103 | } else { 104 | for (let k in params) { 105 | _vars[k] = params[k] 106 | } 107 | } 108 | let tween = ezaction.HActionTweenBy.create(duration, _vars); 109 | return tween; 110 | }; 111 | 112 | ezaction.moveTo = ezaction.tween; 113 | 114 | ezaction.moveBy = ezaction.tweenBy; 115 | 116 | ezaction.scaleTo = ezaction.tween; 117 | 118 | ezaction.scaleBy = ezaction.tweenBy; 119 | 120 | ezaction.skewTo = ezaction.tween; 121 | 122 | ezaction.skewBy = ezaction.tweenBy; 123 | 124 | ezaction.rotateBy = function (duration, numberOrObj, vars) { 125 | let params = null; 126 | if (typeof numberOrObj === "number") { 127 | params = {}; 128 | params.rotationX = numberOrObj; 129 | params.rotationY = numberOrObj; 130 | } else { 131 | params = numberOrObj; 132 | } 133 | return ezaction.tweenBy(duration, params, vars); 134 | }; 135 | ezaction.rotateTo = function (duration, numberOrObj, vars/* null */) { 136 | let params = null; 137 | if (typeof numberOrObj === "number") { 138 | params = {}; 139 | params.rotationX = numberOrObj; 140 | params.rotationY = numberOrObj; 141 | } else { 142 | params = numberOrObj; 143 | } 144 | return ezaction.tween(duration, params, vars); 145 | }; 146 | 147 | ezaction.fadeTo = function (duration, opacity, vars/* null */) { 148 | let params = {}; 149 | params.opacity = opacity; 150 | return ezaction.tween(duration, params, vars); 151 | }; 152 | 153 | ezaction.fadeIn = function (duration, vars/* null */) { 154 | return ezaction.fadeTo(duration, 255, vars) 155 | }; 156 | 157 | ezaction.fadeOut = function (duration, vars/* null */) { 158 | return ezaction.fadeTo(duration, 0, vars) 159 | }; 160 | 161 | ezaction.show = function (vars/* null */) { 162 | vars = vars || {}; 163 | let m = new ezaction.HActionInstant(); 164 | vars.onComplete = function (action) { 165 | action.getNode()._sgNode.setVisible(true); 166 | }; 167 | m.init(vars); 168 | return m; 169 | }; 170 | 171 | ezaction.hide = function (vars/* null */) { 172 | vars = vars || {}; 173 | let m = new ezaction.HActionInstant(); 174 | vars.onComplete = function (action) { 175 | action.getNode()._sgNode.setVisible(false); 176 | }; 177 | m.init(vars); 178 | return m; 179 | }; 180 | 181 | ezaction.jumpBy = function (duration, pos, height, jumps, vars/* null */){ 182 | 183 | let act = new ezaction.HActionJumpBy(); 184 | act.init( duration , pos , height , jumps , vars ); 185 | return act; 186 | } 187 | 188 | ezaction.jumpTo = function (duration, pos, height, jumps, vars/* null */){ 189 | let act = new ezaction.HActionJumpTo(); 190 | act.init( duration , pos , height , jumps , vars ); 191 | return act; 192 | } -------------------------------------------------------------------------------- /assets/ezaction/ezaction.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "c2161f19-f63c-4f2a-8d40-aa1ebc48b214", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "b1f2f3f0-cd90-4fd2-a265-1d40316f0f98", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/prefab/PlayLayer.prefab: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.Prefab", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_native": "", 7 | "data": { 8 | "__id__": 1 9 | }, 10 | "optimizationPolicy": 0, 11 | "asyncLoadAssets": false 12 | }, 13 | { 14 | "__type__": "cc.Node", 15 | "_name": "PlayLayer", 16 | "_objFlags": 0, 17 | "_parent": null, 18 | "_children": [ 19 | { 20 | "__id__": 2 21 | }, 22 | { 23 | "__id__": 27 24 | } 25 | ], 26 | "_active": true, 27 | "_level": 1, 28 | "_components": [ 29 | { 30 | "__id__": 34 31 | } 32 | ], 33 | "_prefab": { 34 | "__id__": 35 35 | }, 36 | "_opacity": 255, 37 | "_color": { 38 | "__type__": "cc.Color", 39 | "r": 255, 40 | "g": 255, 41 | "b": 255, 42 | "a": 255 43 | }, 44 | "_contentSize": { 45 | "__type__": "cc.Size", 46 | "width": 0, 47 | "height": 0 48 | }, 49 | "_anchorPoint": { 50 | "__type__": "cc.Vec2", 51 | "x": 0.5, 52 | "y": 0.5 53 | }, 54 | "_position": { 55 | "__type__": "cc.Vec3", 56 | "x": 1067, 57 | "y": 0, 58 | "z": 0 59 | }, 60 | "_scale": { 61 | "__type__": "cc.Vec3", 62 | "x": 1.11, 63 | "y": 1.11, 64 | "z": 1 65 | }, 66 | "_rotationX": 0, 67 | "_rotationY": 0, 68 | "_quat": { 69 | "__type__": "cc.Quat", 70 | "x": 0, 71 | "y": 0, 72 | "z": 0, 73 | "w": 1 74 | }, 75 | "_skewX": 0, 76 | "_skewY": 0, 77 | "_zIndex": 0, 78 | "groupIndex": 0, 79 | "_id": "" 80 | }, 81 | { 82 | "__type__": "cc.Node", 83 | "_name": "background", 84 | "_objFlags": 0, 85 | "_parent": { 86 | "__id__": 1 87 | }, 88 | "_children": [ 89 | { 90 | "__id__": 3 91 | }, 92 | { 93 | "__id__": 6 94 | }, 95 | { 96 | "__id__": 17 97 | } 98 | ], 99 | "_active": true, 100 | "_level": 3, 101 | "_components": [ 102 | { 103 | "__id__": 25 104 | } 105 | ], 106 | "_prefab": { 107 | "__id__": 26 108 | }, 109 | "_opacity": 255, 110 | "_color": { 111 | "__type__": "cc.Color", 112 | "r": 138, 113 | "g": 180, 114 | "b": 175, 115 | "a": 255 116 | }, 117 | "_contentSize": { 118 | "__type__": "cc.Size", 119 | "width": 480, 120 | "height": 800 121 | }, 122 | "_anchorPoint": { 123 | "__type__": "cc.Vec2", 124 | "x": 0.5, 125 | "y": 0.5 126 | }, 127 | "_position": { 128 | "__type__": "cc.Vec3", 129 | "x": 0, 130 | "y": 0, 131 | "z": 0 132 | }, 133 | "_scale": { 134 | "__type__": "cc.Vec3", 135 | "x": 1, 136 | "y": 1, 137 | "z": 1 138 | }, 139 | "_rotationX": 0, 140 | "_rotationY": 0, 141 | "_quat": { 142 | "__type__": "cc.Quat", 143 | "x": 0, 144 | "y": 0, 145 | "z": 0, 146 | "w": 1 147 | }, 148 | "_skewX": 0, 149 | "_skewY": 0, 150 | "_zIndex": 0, 151 | "groupIndex": 0, 152 | "_id": "" 153 | }, 154 | { 155 | "__type__": "cc.Node", 156 | "_name": "container", 157 | "_objFlags": 0, 158 | "_parent": { 159 | "__id__": 2 160 | }, 161 | "_children": [], 162 | "_active": true, 163 | "_level": 0, 164 | "_components": [ 165 | { 166 | "__id__": 4 167 | } 168 | ], 169 | "_prefab": { 170 | "__id__": 5 171 | }, 172 | "_opacity": 255, 173 | "_color": { 174 | "__type__": "cc.Color", 175 | "r": 153, 176 | "g": 158, 177 | "b": 100, 178 | "a": 255 179 | }, 180 | "_contentSize": { 181 | "__type__": "cc.Size", 182 | "width": 400, 183 | "height": 400 184 | }, 185 | "_anchorPoint": { 186 | "__type__": "cc.Vec2", 187 | "x": 0.5, 188 | "y": 0.5 189 | }, 190 | "_position": { 191 | "__type__": "cc.Vec3", 192 | "x": 0, 193 | "y": 0, 194 | "z": 0 195 | }, 196 | "_scale": { 197 | "__type__": "cc.Vec3", 198 | "x": 1, 199 | "y": 1, 200 | "z": 1 201 | }, 202 | "_rotationX": 0, 203 | "_rotationY": 0, 204 | "_quat": { 205 | "__type__": "cc.Quat", 206 | "x": 0, 207 | "y": 0, 208 | "z": 0, 209 | "w": 1 210 | }, 211 | "_skewX": 0, 212 | "_skewY": 0, 213 | "_zIndex": 0, 214 | "groupIndex": 0, 215 | "_id": "" 216 | }, 217 | { 218 | "__type__": "cc.Sprite", 219 | "_name": "", 220 | "_objFlags": 0, 221 | "node": { 222 | "__id__": 3 223 | }, 224 | "_enabled": true, 225 | "_srcBlendFactor": 770, 226 | "_dstBlendFactor": 771, 227 | "_spriteFrame": { 228 | "__uuid__": "a23235d1-15db-4b95-8439-a2e005bfff91" 229 | }, 230 | "_type": 0, 231 | "_sizeMode": 0, 232 | "_fillType": 0, 233 | "_fillCenter": { 234 | "__type__": "cc.Vec2", 235 | "x": 0, 236 | "y": 0 237 | }, 238 | "_fillStart": 0, 239 | "_fillRange": 0, 240 | "_isTrimmedMode": true, 241 | "_state": 0, 242 | "_atlas": null, 243 | "_id": "" 244 | }, 245 | { 246 | "__type__": "cc.PrefabInfo", 247 | "root": { 248 | "__id__": 1 249 | }, 250 | "asset": { 251 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 252 | }, 253 | "fileId": "83/fMx3j5OGL6q/53CnVS4", 254 | "sync": false 255 | }, 256 | { 257 | "__type__": "cc.Node", 258 | "_name": "score", 259 | "_objFlags": 0, 260 | "_parent": { 261 | "__id__": 2 262 | }, 263 | "_children": [ 264 | { 265 | "__id__": 7 266 | }, 267 | { 268 | "__id__": 10 269 | } 270 | ], 271 | "_active": true, 272 | "_level": 1, 273 | "_components": [], 274 | "_prefab": { 275 | "__id__": 16 276 | }, 277 | "_opacity": 255, 278 | "_color": { 279 | "__type__": "cc.Color", 280 | "r": 255, 281 | "g": 255, 282 | "b": 255, 283 | "a": 255 284 | }, 285 | "_contentSize": { 286 | "__type__": "cc.Size", 287 | "width": 0, 288 | "height": 0 289 | }, 290 | "_anchorPoint": { 291 | "__type__": "cc.Vec2", 292 | "x": 0.5, 293 | "y": 0.5 294 | }, 295 | "_position": { 296 | "__type__": "cc.Vec3", 297 | "x": 81, 298 | "y": 334.3, 299 | "z": 0 300 | }, 301 | "_scale": { 302 | "__type__": "cc.Vec3", 303 | "x": 0.77, 304 | "y": 0.77, 305 | "z": 1 306 | }, 307 | "_rotationX": 0, 308 | "_rotationY": 0, 309 | "_quat": { 310 | "__type__": "cc.Quat", 311 | "x": 0, 312 | "y": 0, 313 | "z": 0, 314 | "w": 1 315 | }, 316 | "_skewX": 0, 317 | "_skewY": 0, 318 | "_zIndex": 0, 319 | "groupIndex": 0, 320 | "_id": "" 321 | }, 322 | { 323 | "__type__": "cc.Node", 324 | "_name": "string", 325 | "_objFlags": 0, 326 | "_parent": { 327 | "__id__": 6 328 | }, 329 | "_children": [], 330 | "_active": true, 331 | "_level": 2, 332 | "_components": [ 333 | { 334 | "__id__": 8 335 | } 336 | ], 337 | "_prefab": { 338 | "__id__": 9 339 | }, 340 | "_opacity": 255, 341 | "_color": { 342 | "__type__": "cc.Color", 343 | "r": 255, 344 | "g": 255, 345 | "b": 255, 346 | "a": 255 347 | }, 348 | "_contentSize": { 349 | "__type__": "cc.Size", 350 | "width": 108.93, 351 | "height": 40 352 | }, 353 | "_anchorPoint": { 354 | "__type__": "cc.Vec2", 355 | "x": 0.5, 356 | "y": 0.5 357 | }, 358 | "_position": { 359 | "__type__": "cc.Vec3", 360 | "x": -8, 361 | "y": 0, 362 | "z": 0 363 | }, 364 | "_scale": { 365 | "__type__": "cc.Vec3", 366 | "x": 1, 367 | "y": 1, 368 | "z": 1 369 | }, 370 | "_rotationX": 0, 371 | "_rotationY": 0, 372 | "_quat": { 373 | "__type__": "cc.Quat", 374 | "x": 0, 375 | "y": 0, 376 | "z": 0, 377 | "w": 1 378 | }, 379 | "_skewX": 0, 380 | "_skewY": 0, 381 | "_zIndex": 0, 382 | "groupIndex": 0, 383 | "_id": "" 384 | }, 385 | { 386 | "__type__": "cc.Label", 387 | "_name": "", 388 | "_objFlags": 0, 389 | "node": { 390 | "__id__": 7 391 | }, 392 | "_enabled": true, 393 | "_srcBlendFactor": 1, 394 | "_dstBlendFactor": 771, 395 | "_useOriginalSize": false, 396 | "_string": "score:", 397 | "_N$string": "score:", 398 | "_fontSize": 40, 399 | "_lineHeight": 40, 400 | "_enableWrapText": true, 401 | "_N$file": null, 402 | "_isSystemFontUsed": true, 403 | "_spacingX": 0, 404 | "_N$horizontalAlign": 1, 405 | "_N$verticalAlign": 1, 406 | "_N$fontFamily": "Arial", 407 | "_N$overflow": 0, 408 | "_id": "" 409 | }, 410 | { 411 | "__type__": "cc.PrefabInfo", 412 | "root": { 413 | "__id__": 1 414 | }, 415 | "asset": { 416 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 417 | }, 418 | "fileId": "44VczsiIFI0Y/AjO4HwzEe", 419 | "sync": false 420 | }, 421 | { 422 | "__type__": "cc.Node", 423 | "_name": "number", 424 | "_objFlags": 0, 425 | "_parent": { 426 | "__id__": 6 427 | }, 428 | "_children": [ 429 | { 430 | "__id__": 11 431 | } 432 | ], 433 | "_active": true, 434 | "_level": 2, 435 | "_components": [ 436 | { 437 | "__id__": 14 438 | } 439 | ], 440 | "_prefab": { 441 | "__id__": 15 442 | }, 443 | "_opacity": 255, 444 | "_color": { 445 | "__type__": "cc.Color", 446 | "r": 255, 447 | "g": 255, 448 | "b": 255, 449 | "a": 255 450 | }, 451 | "_contentSize": { 452 | "__type__": "cc.Size", 453 | "width": 22.25, 454 | "height": 40 455 | }, 456 | "_anchorPoint": { 457 | "__type__": "cc.Vec2", 458 | "x": 0.5, 459 | "y": 0.5 460 | }, 461 | "_position": { 462 | "__type__": "cc.Vec3", 463 | "x": 98, 464 | "y": 0, 465 | "z": 0 466 | }, 467 | "_scale": { 468 | "__type__": "cc.Vec3", 469 | "x": 1, 470 | "y": 1, 471 | "z": 1 472 | }, 473 | "_rotationX": 0, 474 | "_rotationY": 0, 475 | "_quat": { 476 | "__type__": "cc.Quat", 477 | "x": 0, 478 | "y": 0, 479 | "z": 0, 480 | "w": 1 481 | }, 482 | "_skewX": 0, 483 | "_skewY": 0, 484 | "_zIndex": 0, 485 | "groupIndex": 0, 486 | "_id": "" 487 | }, 488 | { 489 | "__type__": "cc.Node", 490 | "_name": "update", 491 | "_objFlags": 0, 492 | "_parent": { 493 | "__id__": 10 494 | }, 495 | "_children": [], 496 | "_active": true, 497 | "_level": 3, 498 | "_components": [ 499 | { 500 | "__id__": 12 501 | } 502 | ], 503 | "_prefab": { 504 | "__id__": 13 505 | }, 506 | "_opacity": 255, 507 | "_color": { 508 | "__type__": "cc.Color", 509 | "r": 176, 510 | "g": 238, 511 | "b": 96, 512 | "a": 255 513 | }, 514 | "_contentSize": { 515 | "__type__": "cc.Size", 516 | "width": 22.25, 517 | "height": 40 518 | }, 519 | "_anchorPoint": { 520 | "__type__": "cc.Vec2", 521 | "x": 0.5, 522 | "y": 0.5 523 | }, 524 | "_position": { 525 | "__type__": "cc.Vec3", 526 | "x": -0.7, 527 | "y": -42.7, 528 | "z": 0 529 | }, 530 | "_scale": { 531 | "__type__": "cc.Vec3", 532 | "x": 1, 533 | "y": 1, 534 | "z": 1 535 | }, 536 | "_rotationX": 0, 537 | "_rotationY": 0, 538 | "_quat": { 539 | "__type__": "cc.Quat", 540 | "x": 0, 541 | "y": 0, 542 | "z": 0, 543 | "w": 1 544 | }, 545 | "_skewX": 0, 546 | "_skewY": 0, 547 | "_zIndex": 0, 548 | "groupIndex": 0, 549 | "_id": "" 550 | }, 551 | { 552 | "__type__": "cc.Label", 553 | "_name": "", 554 | "_objFlags": 0, 555 | "node": { 556 | "__id__": 11 557 | }, 558 | "_enabled": true, 559 | "_srcBlendFactor": 1, 560 | "_dstBlendFactor": 771, 561 | "_useOriginalSize": false, 562 | "_string": "0", 563 | "_N$string": "0", 564 | "_fontSize": 40, 565 | "_lineHeight": 40, 566 | "_enableWrapText": true, 567 | "_N$file": null, 568 | "_isSystemFontUsed": true, 569 | "_spacingX": 0, 570 | "_N$horizontalAlign": 1, 571 | "_N$verticalAlign": 1, 572 | "_N$fontFamily": "Arial", 573 | "_N$overflow": 0, 574 | "_id": "" 575 | }, 576 | { 577 | "__type__": "cc.PrefabInfo", 578 | "root": { 579 | "__id__": 1 580 | }, 581 | "asset": { 582 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 583 | }, 584 | "fileId": "84l5DcTL9GKrbgbdp1qyBx", 585 | "sync": false 586 | }, 587 | { 588 | "__type__": "cc.Label", 589 | "_name": "", 590 | "_objFlags": 0, 591 | "node": { 592 | "__id__": 10 593 | }, 594 | "_enabled": true, 595 | "_srcBlendFactor": 1, 596 | "_dstBlendFactor": 771, 597 | "_useOriginalSize": false, 598 | "_string": "0", 599 | "_N$string": "0", 600 | "_fontSize": 40, 601 | "_lineHeight": 40, 602 | "_enableWrapText": true, 603 | "_N$file": null, 604 | "_isSystemFontUsed": true, 605 | "_spacingX": 0, 606 | "_N$horizontalAlign": 1, 607 | "_N$verticalAlign": 1, 608 | "_N$fontFamily": "Arial", 609 | "_N$overflow": 0, 610 | "_id": "" 611 | }, 612 | { 613 | "__type__": "cc.PrefabInfo", 614 | "root": { 615 | "__id__": 1 616 | }, 617 | "asset": { 618 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 619 | }, 620 | "fileId": "8dGGYdp+NEdY1Sper5mS3d", 621 | "sync": false 622 | }, 623 | { 624 | "__type__": "cc.PrefabInfo", 625 | "root": { 626 | "__id__": 1 627 | }, 628 | "asset": { 629 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 630 | }, 631 | "fileId": "d6WfW3yxBPTr4G6a3ucwH+", 632 | "sync": false 633 | }, 634 | { 635 | "__type__": "cc.Node", 636 | "_name": "bestScore", 637 | "_objFlags": 0, 638 | "_parent": { 639 | "__id__": 2 640 | }, 641 | "_children": [ 642 | { 643 | "__id__": 18 644 | }, 645 | { 646 | "__id__": 21 647 | } 648 | ], 649 | "_active": true, 650 | "_level": 4, 651 | "_components": [], 652 | "_prefab": { 653 | "__id__": 24 654 | }, 655 | "_opacity": 255, 656 | "_color": { 657 | "__type__": "cc.Color", 658 | "r": 255, 659 | "g": 255, 660 | "b": 255, 661 | "a": 255 662 | }, 663 | "_contentSize": { 664 | "__type__": "cc.Size", 665 | "width": 0, 666 | "height": 0 667 | }, 668 | "_anchorPoint": { 669 | "__type__": "cc.Vec2", 670 | "x": 0.5, 671 | "y": 0.5 672 | }, 673 | "_position": { 674 | "__type__": "cc.Vec3", 675 | "x": 69, 676 | "y": 373, 677 | "z": 0 678 | }, 679 | "_scale": { 680 | "__type__": "cc.Vec3", 681 | "x": 0.77, 682 | "y": 0.77, 683 | "z": 1 684 | }, 685 | "_rotationX": 0, 686 | "_rotationY": 0, 687 | "_quat": { 688 | "__type__": "cc.Quat", 689 | "x": 0, 690 | "y": 0, 691 | "z": 0, 692 | "w": 1 693 | }, 694 | "_skewX": 0, 695 | "_skewY": 0, 696 | "_zIndex": 0, 697 | "groupIndex": 0, 698 | "_id": "" 699 | }, 700 | { 701 | "__type__": "cc.Node", 702 | "_name": "string", 703 | "_objFlags": 0, 704 | "_parent": { 705 | "__id__": 17 706 | }, 707 | "_children": [], 708 | "_active": true, 709 | "_level": 5, 710 | "_components": [ 711 | { 712 | "__id__": 19 713 | } 714 | ], 715 | "_prefab": { 716 | "__id__": 20 717 | }, 718 | "_opacity": 255, 719 | "_color": { 720 | "__type__": "cc.Color", 721 | "r": 255, 722 | "g": 255, 723 | "b": 255, 724 | "a": 255 725 | }, 726 | "_contentSize": { 727 | "__type__": "cc.Size", 728 | "width": 195.64, 729 | "height": 40 730 | }, 731 | "_anchorPoint": { 732 | "__type__": "cc.Vec2", 733 | "x": 0.5, 734 | "y": 0.5 735 | }, 736 | "_position": { 737 | "__type__": "cc.Vec3", 738 | "x": -8, 739 | "y": 0, 740 | "z": 0 741 | }, 742 | "_scale": { 743 | "__type__": "cc.Vec3", 744 | "x": 1, 745 | "y": 1, 746 | "z": 1 747 | }, 748 | "_rotationX": 0, 749 | "_rotationY": 0, 750 | "_quat": { 751 | "__type__": "cc.Quat", 752 | "x": 0, 753 | "y": 0, 754 | "z": 0, 755 | "w": 1 756 | }, 757 | "_skewX": 0, 758 | "_skewY": 0, 759 | "_zIndex": 0, 760 | "groupIndex": 0, 761 | "_id": "" 762 | }, 763 | { 764 | "__type__": "cc.Label", 765 | "_name": "", 766 | "_objFlags": 0, 767 | "node": { 768 | "__id__": 18 769 | }, 770 | "_enabled": true, 771 | "_srcBlendFactor": 1, 772 | "_dstBlendFactor": 771, 773 | "_useOriginalSize": false, 774 | "_string": "best score:", 775 | "_N$string": "best score:", 776 | "_fontSize": 40, 777 | "_lineHeight": 40, 778 | "_enableWrapText": true, 779 | "_N$file": null, 780 | "_isSystemFontUsed": true, 781 | "_spacingX": 0, 782 | "_N$horizontalAlign": 1, 783 | "_N$verticalAlign": 1, 784 | "_N$fontFamily": "Arial", 785 | "_N$overflow": 0, 786 | "_id": "" 787 | }, 788 | { 789 | "__type__": "cc.PrefabInfo", 790 | "root": { 791 | "__id__": 1 792 | }, 793 | "asset": { 794 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 795 | }, 796 | "fileId": "1eXFDZcetBtKolekbOBQXM", 797 | "sync": false 798 | }, 799 | { 800 | "__type__": "cc.Node", 801 | "_name": "number", 802 | "_objFlags": 0, 803 | "_parent": { 804 | "__id__": 17 805 | }, 806 | "_children": [], 807 | "_active": true, 808 | "_level": 5, 809 | "_components": [ 810 | { 811 | "__id__": 22 812 | } 813 | ], 814 | "_prefab": { 815 | "__id__": 23 816 | }, 817 | "_opacity": 255, 818 | "_color": { 819 | "__type__": "cc.Color", 820 | "r": 255, 821 | "g": 255, 822 | "b": 255, 823 | "a": 255 824 | }, 825 | "_contentSize": { 826 | "__type__": "cc.Size", 827 | "width": 26.64, 828 | "height": 40 829 | }, 830 | "_anchorPoint": { 831 | "__type__": "cc.Vec2", 832 | "x": 0.5, 833 | "y": 0.5 834 | }, 835 | "_position": { 836 | "__type__": "cc.Vec3", 837 | "x": 140, 838 | "y": 0, 839 | "z": 0 840 | }, 841 | "_scale": { 842 | "__type__": "cc.Vec3", 843 | "x": 1, 844 | "y": 1, 845 | "z": 1 846 | }, 847 | "_rotationX": 0, 848 | "_rotationY": 0, 849 | "_quat": { 850 | "__type__": "cc.Quat", 851 | "x": 0, 852 | "y": 0, 853 | "z": 0, 854 | "w": 1 855 | }, 856 | "_skewX": 0, 857 | "_skewY": 0, 858 | "_zIndex": 0, 859 | "groupIndex": 0, 860 | "_id": "" 861 | }, 862 | { 863 | "__type__": "cc.Label", 864 | "_name": "", 865 | "_objFlags": 0, 866 | "node": { 867 | "__id__": 21 868 | }, 869 | "_enabled": true, 870 | "_srcBlendFactor": 1, 871 | "_dstBlendFactor": 771, 872 | "_useOriginalSize": false, 873 | "_string": "--", 874 | "_N$string": "--", 875 | "_fontSize": 40, 876 | "_lineHeight": 40, 877 | "_enableWrapText": true, 878 | "_N$file": null, 879 | "_isSystemFontUsed": true, 880 | "_spacingX": 0, 881 | "_N$horizontalAlign": 1, 882 | "_N$verticalAlign": 1, 883 | "_N$fontFamily": "Arial", 884 | "_N$overflow": 0, 885 | "_id": "" 886 | }, 887 | { 888 | "__type__": "cc.PrefabInfo", 889 | "root": { 890 | "__id__": 1 891 | }, 892 | "asset": { 893 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 894 | }, 895 | "fileId": "7d2A0cl6FKfKmJ8k4Nfov3", 896 | "sync": false 897 | }, 898 | { 899 | "__type__": "cc.PrefabInfo", 900 | "root": { 901 | "__id__": 1 902 | }, 903 | "asset": { 904 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 905 | }, 906 | "fileId": "9fbo0IBfRKwpUoQlGd6u8Q", 907 | "sync": false 908 | }, 909 | { 910 | "__type__": "cc.Sprite", 911 | "_name": "", 912 | "_objFlags": 0, 913 | "node": { 914 | "__id__": 2 915 | }, 916 | "_enabled": true, 917 | "_srcBlendFactor": 770, 918 | "_dstBlendFactor": 771, 919 | "_spriteFrame": { 920 | "__uuid__": "a23235d1-15db-4b95-8439-a2e005bfff91" 921 | }, 922 | "_type": 0, 923 | "_sizeMode": 0, 924 | "_fillType": 0, 925 | "_fillCenter": { 926 | "__type__": "cc.Vec2", 927 | "x": 0, 928 | "y": 0 929 | }, 930 | "_fillStart": 0, 931 | "_fillRange": 0, 932 | "_isTrimmedMode": true, 933 | "_state": 0, 934 | "_atlas": null, 935 | "_id": "" 936 | }, 937 | { 938 | "__type__": "cc.PrefabInfo", 939 | "root": { 940 | "__id__": 1 941 | }, 942 | "asset": { 943 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 944 | }, 945 | "fileId": "9eyZZuRH1GJ574hUiY605d", 946 | "sync": false 947 | }, 948 | { 949 | "__type__": "cc.Node", 950 | "_name": "back", 951 | "_objFlags": 0, 952 | "_parent": { 953 | "__id__": 1 954 | }, 955 | "_children": [ 956 | { 957 | "__id__": 28 958 | } 959 | ], 960 | "_active": true, 961 | "_level": 3, 962 | "_components": [ 963 | { 964 | "__id__": 31 965 | }, 966 | { 967 | "__id__": 32 968 | } 969 | ], 970 | "_prefab": { 971 | "__id__": 33 972 | }, 973 | "_opacity": 255, 974 | "_color": { 975 | "__type__": "cc.Color", 976 | "r": 255, 977 | "g": 255, 978 | "b": 255, 979 | "a": 255 980 | }, 981 | "_contentSize": { 982 | "__type__": "cc.Size", 983 | "width": 100, 984 | "height": 40 985 | }, 986 | "_anchorPoint": { 987 | "__type__": "cc.Vec2", 988 | "x": 0.5, 989 | "y": 0.5 990 | }, 991 | "_position": { 992 | "__type__": "cc.Vec3", 993 | "x": -175, 994 | "y": 367, 995 | "z": 0 996 | }, 997 | "_scale": { 998 | "__type__": "cc.Vec3", 999 | "x": 1, 1000 | "y": 1, 1001 | "z": 1 1002 | }, 1003 | "_rotationX": 0, 1004 | "_rotationY": 0, 1005 | "_quat": { 1006 | "__type__": "cc.Quat", 1007 | "x": 0, 1008 | "y": 0, 1009 | "z": 0, 1010 | "w": 1 1011 | }, 1012 | "_skewX": 0, 1013 | "_skewY": 0, 1014 | "_zIndex": 0, 1015 | "groupIndex": 0, 1016 | "_id": "" 1017 | }, 1018 | { 1019 | "__type__": "cc.Node", 1020 | "_name": "Label", 1021 | "_objFlags": 0, 1022 | "_parent": { 1023 | "__id__": 27 1024 | }, 1025 | "_children": [], 1026 | "_active": true, 1027 | "_level": 0, 1028 | "_components": [ 1029 | { 1030 | "__id__": 29 1031 | } 1032 | ], 1033 | "_prefab": { 1034 | "__id__": 30 1035 | }, 1036 | "_opacity": 255, 1037 | "_color": { 1038 | "__type__": "cc.Color", 1039 | "r": 0, 1040 | "g": 0, 1041 | "b": 0, 1042 | "a": 255 1043 | }, 1044 | "_contentSize": { 1045 | "__type__": "cc.Size", 1046 | "width": 100, 1047 | "height": 40 1048 | }, 1049 | "_anchorPoint": { 1050 | "__type__": "cc.Vec2", 1051 | "x": 0.5, 1052 | "y": 0.5 1053 | }, 1054 | "_position": { 1055 | "__type__": "cc.Vec3", 1056 | "x": 0, 1057 | "y": 0, 1058 | "z": 0 1059 | }, 1060 | "_scale": { 1061 | "__type__": "cc.Vec3", 1062 | "x": 1, 1063 | "y": 1, 1064 | "z": 1 1065 | }, 1066 | "_rotationX": 0, 1067 | "_rotationY": 0, 1068 | "_quat": { 1069 | "__type__": "cc.Quat", 1070 | "x": 0, 1071 | "y": 0, 1072 | "z": 0, 1073 | "w": 1 1074 | }, 1075 | "_skewX": 0, 1076 | "_skewY": 0, 1077 | "_zIndex": 0, 1078 | "groupIndex": 0, 1079 | "_id": "" 1080 | }, 1081 | { 1082 | "__type__": "cc.Label", 1083 | "_name": "", 1084 | "_objFlags": 0, 1085 | "node": { 1086 | "__id__": 28 1087 | }, 1088 | "_enabled": true, 1089 | "_srcBlendFactor": 1, 1090 | "_dstBlendFactor": 771, 1091 | "_useOriginalSize": false, 1092 | "_string": "back", 1093 | "_N$string": "back", 1094 | "_fontSize": 20, 1095 | "_lineHeight": 40, 1096 | "_enableWrapText": false, 1097 | "_N$file": null, 1098 | "_isSystemFontUsed": true, 1099 | "_spacingX": 0, 1100 | "_N$horizontalAlign": 1, 1101 | "_N$verticalAlign": 1, 1102 | "_N$fontFamily": "Arial", 1103 | "_N$overflow": 1, 1104 | "_id": "" 1105 | }, 1106 | { 1107 | "__type__": "cc.PrefabInfo", 1108 | "root": { 1109 | "__id__": 1 1110 | }, 1111 | "asset": { 1112 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 1113 | }, 1114 | "fileId": "1e2RdW5dtJ+I+YqSDtXz3y", 1115 | "sync": false 1116 | }, 1117 | { 1118 | "__type__": "cc.Sprite", 1119 | "_name": "", 1120 | "_objFlags": 0, 1121 | "node": { 1122 | "__id__": 27 1123 | }, 1124 | "_enabled": true, 1125 | "_srcBlendFactor": 770, 1126 | "_dstBlendFactor": 771, 1127 | "_spriteFrame": { 1128 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 1129 | }, 1130 | "_type": 1, 1131 | "_sizeMode": 0, 1132 | "_fillType": 0, 1133 | "_fillCenter": { 1134 | "__type__": "cc.Vec2", 1135 | "x": 0, 1136 | "y": 0 1137 | }, 1138 | "_fillStart": 0, 1139 | "_fillRange": 0, 1140 | "_isTrimmedMode": true, 1141 | "_state": 0, 1142 | "_atlas": null, 1143 | "_id": "" 1144 | }, 1145 | { 1146 | "__type__": "cc.Button", 1147 | "_name": "", 1148 | "_objFlags": 0, 1149 | "node": { 1150 | "__id__": 27 1151 | }, 1152 | "_enabled": true, 1153 | "transition": 2, 1154 | "pressedColor": { 1155 | "__type__": "cc.Color", 1156 | "r": 255, 1157 | "g": 255, 1158 | "b": 255, 1159 | "a": 255 1160 | }, 1161 | "hoverColor": { 1162 | "__type__": "cc.Color", 1163 | "r": 255, 1164 | "g": 255, 1165 | "b": 255, 1166 | "a": 255 1167 | }, 1168 | "duration": 0.1, 1169 | "zoomScale": 1.2, 1170 | "clickEvents": [], 1171 | "_N$interactable": true, 1172 | "_N$enableAutoGrayEffect": false, 1173 | "_N$normalColor": { 1174 | "__type__": "cc.Color", 1175 | "r": 255, 1176 | "g": 255, 1177 | "b": 255, 1178 | "a": 255 1179 | }, 1180 | "_N$disabledColor": { 1181 | "__type__": "cc.Color", 1182 | "r": 255, 1183 | "g": 255, 1184 | "b": 255, 1185 | "a": 255 1186 | }, 1187 | "_N$normalSprite": { 1188 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 1189 | }, 1190 | "_N$pressedSprite": { 1191 | "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a" 1192 | }, 1193 | "pressedSprite": { 1194 | "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a" 1195 | }, 1196 | "_N$hoverSprite": { 1197 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 1198 | }, 1199 | "hoverSprite": { 1200 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 1201 | }, 1202 | "_N$disabledSprite": { 1203 | "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" 1204 | }, 1205 | "_N$target": { 1206 | "__id__": 27 1207 | }, 1208 | "_id": "" 1209 | }, 1210 | { 1211 | "__type__": "cc.PrefabInfo", 1212 | "root": { 1213 | "__id__": 1 1214 | }, 1215 | "asset": { 1216 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 1217 | }, 1218 | "fileId": "4fah/oQUpGkJ/EYk4jQfC8", 1219 | "sync": false 1220 | }, 1221 | { 1222 | "__type__": "6da04JjlNVHKr2BHpKtrKVk", 1223 | "_name": "", 1224 | "_objFlags": 0, 1225 | "node": { 1226 | "__id__": 1 1227 | }, 1228 | "_enabled": true, 1229 | "background": { 1230 | "__id__": 25 1231 | }, 1232 | "layout": { 1233 | "__id__": 4 1234 | }, 1235 | "blockPrefab": { 1236 | "__uuid__": "d3a940c4-4ccc-4c5a-868c-c67740afd58e" 1237 | }, 1238 | "gameEnd": { 1239 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 1240 | }, 1241 | "score": { 1242 | "__id__": 14 1243 | }, 1244 | "bestScore": { 1245 | "__id__": 22 1246 | }, 1247 | "backBtn": { 1248 | "__id__": 32 1249 | }, 1250 | "_id": "" 1251 | }, 1252 | { 1253 | "__type__": "cc.PrefabInfo", 1254 | "root": { 1255 | "__id__": 1 1256 | }, 1257 | "asset": { 1258 | "__uuid__": "3ae84781-dc13-4e06-bbc7-81615bfda342" 1259 | }, 1260 | "fileId": "57UwPrFVFMfaYRitOCO6Qa", 1261 | "sync": false 1262 | } 1263 | ] -------------------------------------------------------------------------------- /assets/prefab/PlayLayer.prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "3ae84781-dc13-4e06-bbc7-81615bfda342", 4 | "optimizationPolicy": "AUTO", 5 | "asyncLoadAssets": false, 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/prefab/block.prefab: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.Prefab", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_native": "", 7 | "data": { 8 | "__id__": 1 9 | }, 10 | "optimizationPolicy": 0, 11 | "asyncLoadAssets": false 12 | }, 13 | { 14 | "__type__": "cc.Node", 15 | "_name": "block", 16 | "_objFlags": 0, 17 | "_parent": null, 18 | "_children": [ 19 | { 20 | "__id__": 2 21 | } 22 | ], 23 | "_active": true, 24 | "_level": 1, 25 | "_components": [ 26 | { 27 | "__id__": 5 28 | } 29 | ], 30 | "_prefab": { 31 | "__id__": 6 32 | }, 33 | "_opacity": 255, 34 | "_color": { 35 | "__type__": "cc.Color", 36 | "r": 255, 37 | "g": 255, 38 | "b": 255, 39 | "a": 255 40 | }, 41 | "_contentSize": { 42 | "__type__": "cc.Size", 43 | "width": 80, 44 | "height": 80 45 | }, 46 | "_anchorPoint": { 47 | "__type__": "cc.Vec2", 48 | "x": 0.5, 49 | "y": 0.5 50 | }, 51 | "_position": { 52 | "__type__": "cc.Vec3", 53 | "x": -150, 54 | "y": 150, 55 | "z": 0 56 | }, 57 | "_scale": { 58 | "__type__": "cc.Vec3", 59 | "x": 1, 60 | "y": 1, 61 | "z": 1 62 | }, 63 | "_rotationX": 0, 64 | "_rotationY": 0, 65 | "_quat": { 66 | "__type__": "cc.Quat", 67 | "x": 0, 68 | "y": 0, 69 | "z": 0, 70 | "w": 1 71 | }, 72 | "_skewX": 0, 73 | "_skewY": 0, 74 | "_zIndex": 0, 75 | "groupIndex": 0, 76 | "_id": "" 77 | }, 78 | { 79 | "__type__": "cc.Node", 80 | "_name": "label", 81 | "_objFlags": 0, 82 | "_parent": { 83 | "__id__": 1 84 | }, 85 | "_children": [], 86 | "_active": true, 87 | "_level": 2, 88 | "_components": [ 89 | { 90 | "__id__": 3 91 | } 92 | ], 93 | "_prefab": { 94 | "__id__": 4 95 | }, 96 | "_opacity": 255, 97 | "_color": { 98 | "__type__": "cc.Color", 99 | "r": 53, 100 | "g": 49, 101 | "b": 92, 102 | "a": 255 103 | }, 104 | "_contentSize": { 105 | "__type__": "cc.Size", 106 | "width": 22.25, 107 | "height": 40 108 | }, 109 | "_anchorPoint": { 110 | "__type__": "cc.Vec2", 111 | "x": 0.5, 112 | "y": 0.5 113 | }, 114 | "_position": { 115 | "__type__": "cc.Vec3", 116 | "x": 0, 117 | "y": 0, 118 | "z": 0 119 | }, 120 | "_scale": { 121 | "__type__": "cc.Vec3", 122 | "x": 1, 123 | "y": 1, 124 | "z": 1 125 | }, 126 | "_rotationX": 0, 127 | "_rotationY": 0, 128 | "_quat": { 129 | "__type__": "cc.Quat", 130 | "x": 0, 131 | "y": 0, 132 | "z": 0, 133 | "w": 1 134 | }, 135 | "_skewX": 0, 136 | "_skewY": 0, 137 | "_zIndex": 0, 138 | "groupIndex": 0, 139 | "_id": "" 140 | }, 141 | { 142 | "__type__": "cc.Label", 143 | "_name": "", 144 | "_objFlags": 0, 145 | "node": { 146 | "__id__": 2 147 | }, 148 | "_enabled": true, 149 | "_srcBlendFactor": 1, 150 | "_dstBlendFactor": 771, 151 | "_useOriginalSize": false, 152 | "_string": "0", 153 | "_N$string": "0", 154 | "_fontSize": 40, 155 | "_lineHeight": 40, 156 | "_enableWrapText": true, 157 | "_N$file": null, 158 | "_isSystemFontUsed": true, 159 | "_spacingX": 0, 160 | "_N$horizontalAlign": 1, 161 | "_N$verticalAlign": 1, 162 | "_N$fontFamily": "Arial", 163 | "_N$overflow": 0, 164 | "_id": "" 165 | }, 166 | { 167 | "__type__": "cc.PrefabInfo", 168 | "root": { 169 | "__id__": 1 170 | }, 171 | "asset": { 172 | "__uuid__": "d3a940c4-4ccc-4c5a-868c-c67740afd58e" 173 | }, 174 | "fileId": "9aSZJKGEhDParR6XV0mbT7", 175 | "sync": false 176 | }, 177 | { 178 | "__type__": "cc.Sprite", 179 | "_name": "", 180 | "_objFlags": 0, 181 | "node": { 182 | "__id__": 1 183 | }, 184 | "_enabled": true, 185 | "_srcBlendFactor": 770, 186 | "_dstBlendFactor": 771, 187 | "_spriteFrame": { 188 | "__uuid__": "a23235d1-15db-4b95-8439-a2e005bfff91" 189 | }, 190 | "_type": 0, 191 | "_sizeMode": 0, 192 | "_fillType": 0, 193 | "_fillCenter": { 194 | "__type__": "cc.Vec2", 195 | "x": 0, 196 | "y": 0 197 | }, 198 | "_fillStart": 0, 199 | "_fillRange": 0, 200 | "_isTrimmedMode": true, 201 | "_state": 0, 202 | "_atlas": null, 203 | "_id": "" 204 | }, 205 | { 206 | "__type__": "cc.PrefabInfo", 207 | "root": { 208 | "__id__": 1 209 | }, 210 | "asset": { 211 | "__uuid__": "d3a940c4-4ccc-4c5a-868c-c67740afd58e" 212 | }, 213 | "fileId": "9dv7CZsfFFXaIlYtqcunWO", 214 | "sync": false 215 | } 216 | ] -------------------------------------------------------------------------------- /assets/prefab/block.prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "d3a940c4-4ccc-4c5a-868c-c67740afd58e", 4 | "optimizationPolicy": "AUTO", 5 | "asyncLoadAssets": false, 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/prefab/gameEnd.prefab: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.Prefab", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_native": "", 7 | "data": { 8 | "__id__": 1 9 | }, 10 | "optimizationPolicy": 0, 11 | "asyncLoadAssets": false 12 | }, 13 | { 14 | "__type__": "cc.Node", 15 | "_name": "gameEnd", 16 | "_objFlags": 0, 17 | "_parent": null, 18 | "_children": [ 19 | { 20 | "__id__": 2 21 | }, 22 | { 23 | "__id__": 10 24 | }, 25 | { 26 | "__id__": 13 27 | } 28 | ], 29 | "_active": true, 30 | "_level": 1, 31 | "_components": [ 32 | { 33 | "__id__": 20 34 | }, 35 | { 36 | "__id__": 21 37 | }, 38 | { 39 | "__id__": 22 40 | }, 41 | { 42 | "__id__": 23 43 | } 44 | ], 45 | "_prefab": { 46 | "__id__": 24 47 | }, 48 | "_opacity": 200.685, 49 | "_color": { 50 | "__type__": "cc.Color", 51 | "r": 122, 52 | "g": 122, 53 | "b": 122, 54 | "a": 255 55 | }, 56 | "_contentSize": { 57 | "__type__": "cc.Size", 58 | "width": 350, 59 | "height": 300 60 | }, 61 | "_anchorPoint": { 62 | "__type__": "cc.Vec2", 63 | "x": 0.5, 64 | "y": 0.5 65 | }, 66 | "_position": { 67 | "__type__": "cc.Vec3", 68 | "x": 0, 69 | "y": 0, 70 | "z": 0 71 | }, 72 | "_scale": { 73 | "__type__": "cc.Vec3", 74 | "x": 1, 75 | "y": 1, 76 | "z": 1 77 | }, 78 | "_rotationX": 0, 79 | "_rotationY": 0, 80 | "_quat": { 81 | "__type__": "cc.Quat", 82 | "x": 0, 83 | "y": 0, 84 | "z": 0, 85 | "w": 1 86 | }, 87 | "_skewX": 0, 88 | "_skewY": 0, 89 | "_zIndex": 0, 90 | "groupIndex": 0, 91 | "_id": "" 92 | }, 93 | { 94 | "__type__": "cc.Node", 95 | "_name": "score", 96 | "_objFlags": 0, 97 | "_parent": { 98 | "__id__": 1 99 | }, 100 | "_children": [ 101 | { 102 | "__id__": 3 103 | }, 104 | { 105 | "__id__": 6 106 | } 107 | ], 108 | "_active": true, 109 | "_level": 3, 110 | "_components": [], 111 | "_prefab": { 112 | "__id__": 9 113 | }, 114 | "_opacity": 255, 115 | "_color": { 116 | "__type__": "cc.Color", 117 | "r": 255, 118 | "g": 255, 119 | "b": 255, 120 | "a": 255 121 | }, 122 | "_contentSize": { 123 | "__type__": "cc.Size", 124 | "width": 22.25, 125 | "height": 40 126 | }, 127 | "_anchorPoint": { 128 | "__type__": "cc.Vec2", 129 | "x": 0.5, 130 | "y": 0.5 131 | }, 132 | "_position": { 133 | "__type__": "cc.Vec3", 134 | "x": 0, 135 | "y": -52, 136 | "z": 0 137 | }, 138 | "_scale": { 139 | "__type__": "cc.Vec3", 140 | "x": 1, 141 | "y": 1, 142 | "z": 1 143 | }, 144 | "_rotationX": 0, 145 | "_rotationY": 0, 146 | "_quat": { 147 | "__type__": "cc.Quat", 148 | "x": 0, 149 | "y": 0, 150 | "z": 0, 151 | "w": 1 152 | }, 153 | "_skewX": 0, 154 | "_skewY": 0, 155 | "_zIndex": 0, 156 | "groupIndex": 0, 157 | "_id": "" 158 | }, 159 | { 160 | "__type__": "cc.Node", 161 | "_name": "string", 162 | "_objFlags": 0, 163 | "_parent": { 164 | "__id__": 2 165 | }, 166 | "_children": [], 167 | "_active": true, 168 | "_level": 4, 169 | "_components": [ 170 | { 171 | "__id__": 4 172 | } 173 | ], 174 | "_prefab": { 175 | "__id__": 5 176 | }, 177 | "_opacity": 255, 178 | "_color": { 179 | "__type__": "cc.Color", 180 | "r": 255, 181 | "g": 255, 182 | "b": 255, 183 | "a": 255 184 | }, 185 | "_contentSize": { 186 | "__type__": "cc.Size", 187 | "width": 108.93, 188 | "height": 40 189 | }, 190 | "_anchorPoint": { 191 | "__type__": "cc.Vec2", 192 | "x": 0.5, 193 | "y": 0.5 194 | }, 195 | "_position": { 196 | "__type__": "cc.Vec3", 197 | "x": 0, 198 | "y": 83, 199 | "z": 0 200 | }, 201 | "_scale": { 202 | "__type__": "cc.Vec3", 203 | "x": 1, 204 | "y": 1, 205 | "z": 1 206 | }, 207 | "_rotationX": 0, 208 | "_rotationY": 0, 209 | "_quat": { 210 | "__type__": "cc.Quat", 211 | "x": 0, 212 | "y": 0, 213 | "z": 0, 214 | "w": 1 215 | }, 216 | "_skewX": 0, 217 | "_skewY": 0, 218 | "_zIndex": 0, 219 | "groupIndex": 0, 220 | "_id": "" 221 | }, 222 | { 223 | "__type__": "cc.Label", 224 | "_name": "", 225 | "_objFlags": 0, 226 | "node": { 227 | "__id__": 3 228 | }, 229 | "_enabled": true, 230 | "_srcBlendFactor": 1, 231 | "_dstBlendFactor": 771, 232 | "_useOriginalSize": false, 233 | "_string": "score:", 234 | "_N$string": "score:", 235 | "_fontSize": 40, 236 | "_lineHeight": 40, 237 | "_enableWrapText": true, 238 | "_N$file": null, 239 | "_isSystemFontUsed": true, 240 | "_spacingX": 0, 241 | "_N$horizontalAlign": 1, 242 | "_N$verticalAlign": 1, 243 | "_N$fontFamily": "Arial", 244 | "_N$overflow": 0, 245 | "_id": "" 246 | }, 247 | { 248 | "__type__": "cc.PrefabInfo", 249 | "root": { 250 | "__id__": 1 251 | }, 252 | "asset": { 253 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 254 | }, 255 | "fileId": "4daZb676pIQoajIxLkqlNd", 256 | "sync": false 257 | }, 258 | { 259 | "__type__": "cc.Node", 260 | "_name": "number", 261 | "_objFlags": 0, 262 | "_parent": { 263 | "__id__": 2 264 | }, 265 | "_children": [], 266 | "_active": true, 267 | "_level": 4, 268 | "_components": [ 269 | { 270 | "__id__": 7 271 | } 272 | ], 273 | "_prefab": { 274 | "__id__": 8 275 | }, 276 | "_opacity": 255, 277 | "_color": { 278 | "__type__": "cc.Color", 279 | "r": 255, 280 | "g": 255, 281 | "b": 255, 282 | "a": 255 283 | }, 284 | "_contentSize": { 285 | "__type__": "cc.Size", 286 | "width": 22.25, 287 | "height": 40 288 | }, 289 | "_anchorPoint": { 290 | "__type__": "cc.Vec2", 291 | "x": 0.5, 292 | "y": 0.5 293 | }, 294 | "_position": { 295 | "__type__": "cc.Vec3", 296 | "x": 0, 297 | "y": 35, 298 | "z": 0 299 | }, 300 | "_scale": { 301 | "__type__": "cc.Vec3", 302 | "x": 1, 303 | "y": 1, 304 | "z": 1 305 | }, 306 | "_rotationX": 0, 307 | "_rotationY": 0, 308 | "_quat": { 309 | "__type__": "cc.Quat", 310 | "x": 0, 311 | "y": 0, 312 | "z": 0, 313 | "w": 1 314 | }, 315 | "_skewX": 0, 316 | "_skewY": 0, 317 | "_zIndex": 0, 318 | "groupIndex": 0, 319 | "_id": "" 320 | }, 321 | { 322 | "__type__": "cc.Label", 323 | "_name": "", 324 | "_objFlags": 0, 325 | "node": { 326 | "__id__": 6 327 | }, 328 | "_enabled": true, 329 | "_srcBlendFactor": 1, 330 | "_dstBlendFactor": 771, 331 | "_useOriginalSize": false, 332 | "_string": "0", 333 | "_N$string": "0", 334 | "_fontSize": 40, 335 | "_lineHeight": 40, 336 | "_enableWrapText": true, 337 | "_N$file": null, 338 | "_isSystemFontUsed": true, 339 | "_spacingX": 0, 340 | "_N$horizontalAlign": 1, 341 | "_N$verticalAlign": 1, 342 | "_N$fontFamily": "Arial", 343 | "_N$overflow": 0, 344 | "_id": "" 345 | }, 346 | { 347 | "__type__": "cc.PrefabInfo", 348 | "root": { 349 | "__id__": 1 350 | }, 351 | "asset": { 352 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 353 | }, 354 | "fileId": "bct9RhaEpCXatHvSN6lzkv", 355 | "sync": false 356 | }, 357 | { 358 | "__type__": "cc.PrefabInfo", 359 | "root": { 360 | "__id__": 1 361 | }, 362 | "asset": { 363 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 364 | }, 365 | "fileId": "2a1m07TEhJLpOWpXkIDsgf", 366 | "sync": false 367 | }, 368 | { 369 | "__type__": "cc.Node", 370 | "_name": "title", 371 | "_objFlags": 0, 372 | "_parent": { 373 | "__id__": 1 374 | }, 375 | "_children": [], 376 | "_active": true, 377 | "_level": 3, 378 | "_components": [ 379 | { 380 | "__id__": 11 381 | } 382 | ], 383 | "_prefab": { 384 | "__id__": 12 385 | }, 386 | "_opacity": 255, 387 | "_color": { 388 | "__type__": "cc.Color", 389 | "r": 255, 390 | "g": 255, 391 | "b": 255, 392 | "a": 255 393 | }, 394 | "_contentSize": { 395 | "__type__": "cc.Size", 396 | "width": 62.25, 397 | "height": 40 398 | }, 399 | "_anchorPoint": { 400 | "__type__": "cc.Vec2", 401 | "x": 0.5, 402 | "y": 0.5 403 | }, 404 | "_position": { 405 | "__type__": "cc.Vec3", 406 | "x": 0, 407 | "y": 105, 408 | "z": 0 409 | }, 410 | "_scale": { 411 | "__type__": "cc.Vec3", 412 | "x": 1, 413 | "y": 1, 414 | "z": 1 415 | }, 416 | "_rotationX": 0, 417 | "_rotationY": 0, 418 | "_quat": { 419 | "__type__": "cc.Quat", 420 | "x": 0, 421 | "y": 0, 422 | "z": 0, 423 | "w": 1 424 | }, 425 | "_skewX": 0, 426 | "_skewY": 0, 427 | "_zIndex": 0, 428 | "groupIndex": 0, 429 | "_id": "" 430 | }, 431 | { 432 | "__type__": "cc.Label", 433 | "_name": "", 434 | "_objFlags": 0, 435 | "node": { 436 | "__id__": 10 437 | }, 438 | "_enabled": true, 439 | "_srcBlendFactor": 1, 440 | "_dstBlendFactor": 771, 441 | "_useOriginalSize": false, 442 | "_string": "title", 443 | "_N$string": "title", 444 | "_fontSize": 40, 445 | "_lineHeight": 40, 446 | "_enableWrapText": true, 447 | "_N$file": null, 448 | "_isSystemFontUsed": true, 449 | "_spacingX": 0, 450 | "_N$horizontalAlign": 1, 451 | "_N$verticalAlign": 1, 452 | "_N$fontFamily": "Arial", 453 | "_N$overflow": 0, 454 | "_id": "" 455 | }, 456 | { 457 | "__type__": "cc.PrefabInfo", 458 | "root": { 459 | "__id__": 1 460 | }, 461 | "asset": { 462 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 463 | }, 464 | "fileId": "ccN8T/oIpNaIPUcvJPtzrp", 465 | "sync": false 466 | }, 467 | { 468 | "__type__": "cc.Node", 469 | "_name": "restartBtn", 470 | "_objFlags": 0, 471 | "_parent": { 472 | "__id__": 1 473 | }, 474 | "_children": [ 475 | { 476 | "__id__": 14 477 | } 478 | ], 479 | "_active": true, 480 | "_level": 2, 481 | "_components": [ 482 | { 483 | "__id__": 17 484 | }, 485 | { 486 | "__id__": 18 487 | } 488 | ], 489 | "_prefab": { 490 | "__id__": 19 491 | }, 492 | "_opacity": 255, 493 | "_color": { 494 | "__type__": "cc.Color", 495 | "r": 255, 496 | "g": 255, 497 | "b": 255, 498 | "a": 255 499 | }, 500 | "_contentSize": { 501 | "__type__": "cc.Size", 502 | "width": 100, 503 | "height": 40 504 | }, 505 | "_anchorPoint": { 506 | "__type__": "cc.Vec2", 507 | "x": 0.5, 508 | "y": 0.5 509 | }, 510 | "_position": { 511 | "__type__": "cc.Vec3", 512 | "x": 0, 513 | "y": -77, 514 | "z": 0 515 | }, 516 | "_scale": { 517 | "__type__": "cc.Vec3", 518 | "x": 1, 519 | "y": 1, 520 | "z": 1 521 | }, 522 | "_rotationX": 0, 523 | "_rotationY": 0, 524 | "_quat": { 525 | "__type__": "cc.Quat", 526 | "x": 0, 527 | "y": 0, 528 | "z": 0, 529 | "w": 1 530 | }, 531 | "_skewX": 0, 532 | "_skewY": 0, 533 | "_zIndex": 0, 534 | "groupIndex": 0, 535 | "_id": "" 536 | }, 537 | { 538 | "__type__": "cc.Node", 539 | "_name": "Label", 540 | "_objFlags": 0, 541 | "_parent": { 542 | "__id__": 13 543 | }, 544 | "_children": [], 545 | "_active": true, 546 | "_level": 0, 547 | "_components": [ 548 | { 549 | "__id__": 15 550 | } 551 | ], 552 | "_prefab": { 553 | "__id__": 16 554 | }, 555 | "_opacity": 255, 556 | "_color": { 557 | "__type__": "cc.Color", 558 | "r": 0, 559 | "g": 0, 560 | "b": 0, 561 | "a": 255 562 | }, 563 | "_contentSize": { 564 | "__type__": "cc.Size", 565 | "width": 100, 566 | "height": 40 567 | }, 568 | "_anchorPoint": { 569 | "__type__": "cc.Vec2", 570 | "x": 0.5, 571 | "y": 0.5 572 | }, 573 | "_position": { 574 | "__type__": "cc.Vec3", 575 | "x": 0, 576 | "y": 0, 577 | "z": 0 578 | }, 579 | "_scale": { 580 | "__type__": "cc.Vec3", 581 | "x": 1, 582 | "y": 1, 583 | "z": 1 584 | }, 585 | "_rotationX": 0, 586 | "_rotationY": 0, 587 | "_quat": { 588 | "__type__": "cc.Quat", 589 | "x": 0, 590 | "y": 0, 591 | "z": 0, 592 | "w": 1 593 | }, 594 | "_skewX": 0, 595 | "_skewY": 0, 596 | "_zIndex": 0, 597 | "groupIndex": 0, 598 | "_id": "" 599 | }, 600 | { 601 | "__type__": "cc.Label", 602 | "_name": "", 603 | "_objFlags": 0, 604 | "node": { 605 | "__id__": 14 606 | }, 607 | "_enabled": true, 608 | "_srcBlendFactor": 1, 609 | "_dstBlendFactor": 771, 610 | "_useOriginalSize": false, 611 | "_string": "restart", 612 | "_N$string": "restart", 613 | "_fontSize": 20, 614 | "_lineHeight": 40, 615 | "_enableWrapText": false, 616 | "_N$file": null, 617 | "_isSystemFontUsed": true, 618 | "_spacingX": 0, 619 | "_N$horizontalAlign": 1, 620 | "_N$verticalAlign": 1, 621 | "_N$fontFamily": "Arial", 622 | "_N$overflow": 1, 623 | "_id": "" 624 | }, 625 | { 626 | "__type__": "cc.PrefabInfo", 627 | "root": { 628 | "__id__": 1 629 | }, 630 | "asset": { 631 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 632 | }, 633 | "fileId": "28gBmalOBHTaRCE2bWG0pI", 634 | "sync": false 635 | }, 636 | { 637 | "__type__": "cc.Sprite", 638 | "_name": "", 639 | "_objFlags": 0, 640 | "node": { 641 | "__id__": 13 642 | }, 643 | "_enabled": true, 644 | "_srcBlendFactor": 770, 645 | "_dstBlendFactor": 771, 646 | "_spriteFrame": { 647 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 648 | }, 649 | "_type": 1, 650 | "_sizeMode": 0, 651 | "_fillType": 0, 652 | "_fillCenter": { 653 | "__type__": "cc.Vec2", 654 | "x": 0, 655 | "y": 0 656 | }, 657 | "_fillStart": 0, 658 | "_fillRange": 0, 659 | "_isTrimmedMode": true, 660 | "_state": 0, 661 | "_atlas": null, 662 | "_id": "" 663 | }, 664 | { 665 | "__type__": "cc.Button", 666 | "_name": "", 667 | "_objFlags": 0, 668 | "node": { 669 | "__id__": 13 670 | }, 671 | "_enabled": true, 672 | "transition": 2, 673 | "pressedColor": { 674 | "__type__": "cc.Color", 675 | "r": 255, 676 | "g": 255, 677 | "b": 255, 678 | "a": 255 679 | }, 680 | "hoverColor": { 681 | "__type__": "cc.Color", 682 | "r": 255, 683 | "g": 255, 684 | "b": 255, 685 | "a": 255 686 | }, 687 | "duration": 0.1, 688 | "zoomScale": 1.2, 689 | "clickEvents": [], 690 | "_N$interactable": true, 691 | "_N$enableAutoGrayEffect": false, 692 | "_N$normalColor": { 693 | "__type__": "cc.Color", 694 | "r": 255, 695 | "g": 255, 696 | "b": 255, 697 | "a": 255 698 | }, 699 | "_N$disabledColor": { 700 | "__type__": "cc.Color", 701 | "r": 255, 702 | "g": 255, 703 | "b": 255, 704 | "a": 255 705 | }, 706 | "_N$normalSprite": { 707 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 708 | }, 709 | "_N$pressedSprite": { 710 | "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a" 711 | }, 712 | "pressedSprite": { 713 | "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a" 714 | }, 715 | "_N$hoverSprite": { 716 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 717 | }, 718 | "hoverSprite": { 719 | "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952" 720 | }, 721 | "_N$disabledSprite": { 722 | "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" 723 | }, 724 | "_N$target": { 725 | "__id__": 13 726 | }, 727 | "_id": "" 728 | }, 729 | { 730 | "__type__": "cc.PrefabInfo", 731 | "root": { 732 | "__id__": 1 733 | }, 734 | "asset": { 735 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 736 | }, 737 | "fileId": "57XhzDzGxAC4ZaiwW7GRej", 738 | "sync": false 739 | }, 740 | { 741 | "__type__": "cc.Sprite", 742 | "_name": "", 743 | "_objFlags": 0, 744 | "node": { 745 | "__id__": 1 746 | }, 747 | "_enabled": true, 748 | "_srcBlendFactor": 770, 749 | "_dstBlendFactor": 771, 750 | "_spriteFrame": { 751 | "__uuid__": "9bbda31e-ad49-43c9-aaf2-f7d9896bac69" 752 | }, 753 | "_type": 1, 754 | "_sizeMode": 0, 755 | "_fillType": 0, 756 | "_fillCenter": { 757 | "__type__": "cc.Vec2", 758 | "x": 0, 759 | "y": 0 760 | }, 761 | "_fillStart": 0, 762 | "_fillRange": 0, 763 | "_isTrimmedMode": true, 764 | "_state": 0, 765 | "_atlas": null, 766 | "_id": "" 767 | }, 768 | { 769 | "__type__": "cc.Layout", 770 | "_name": "", 771 | "_objFlags": 0, 772 | "node": { 773 | "__id__": 1 774 | }, 775 | "_enabled": true, 776 | "_layoutSize": { 777 | "__type__": "cc.Size", 778 | "width": 350, 779 | "height": 300 780 | }, 781 | "_resize": 0, 782 | "_N$layoutType": 0, 783 | "_N$padding": 0, 784 | "_N$cellSize": { 785 | "__type__": "cc.Size", 786 | "width": 40, 787 | "height": 40 788 | }, 789 | "_N$startAxis": 0, 790 | "_N$paddingLeft": 0, 791 | "_N$paddingRight": 0, 792 | "_N$paddingTop": 0, 793 | "_N$paddingBottom": 0, 794 | "_N$spacingX": 0, 795 | "_N$spacingY": 0, 796 | "_N$verticalDirection": 1, 797 | "_N$horizontalDirection": 0, 798 | "_id": "" 799 | }, 800 | { 801 | "__type__": "64fb6nSVS1CZ4msPhRE0aT0", 802 | "_name": "", 803 | "_objFlags": 0, 804 | "node": { 805 | "__id__": 1 806 | }, 807 | "_enabled": true, 808 | "score": { 809 | "__id__": 7 810 | }, 811 | "title": { 812 | "__id__": 11 813 | }, 814 | "restartBtn": { 815 | "__id__": 18 816 | }, 817 | "_id": "" 818 | }, 819 | { 820 | "__type__": "cc.Animation", 821 | "_name": "", 822 | "_objFlags": 0, 823 | "node": { 824 | "__id__": 1 825 | }, 826 | "_enabled": true, 827 | "_defaultClip": { 828 | "__uuid__": "30ad6936-806b-4967-b9ba-c0500b5a66f5" 829 | }, 830 | "_clips": [ 831 | { 832 | "__uuid__": "30ad6936-806b-4967-b9ba-c0500b5a66f5" 833 | } 834 | ], 835 | "playOnLoad": true, 836 | "_id": "" 837 | }, 838 | { 839 | "__type__": "cc.PrefabInfo", 840 | "root": { 841 | "__id__": 1 842 | }, 843 | "asset": { 844 | "__uuid__": "947dd3a3-13be-47c6-b7fc-799247504437" 845 | }, 846 | "fileId": "67VjkdVMtHVK+UAg5qoagV", 847 | "sync": false 848 | } 849 | ] -------------------------------------------------------------------------------- /assets/prefab/gameEnd.prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "947dd3a3-13be-47c6-b7fc-799247504437", 4 | "optimizationPolicy": "AUTO", 5 | "asyncLoadAssets": false, 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/scene.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "9addf910-1f78-4c79-932b-1eee2a4e2714", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/scene/main.fire.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "4e03d127-8535-47c2-895c-e46afd9a437f", 4 | "asyncLoadAssets": false, 5 | "autoReleaseAssets": false, 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/script.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "286ac4cc-099f-4f23-8c21-7891f0626daa", 4 | "isSubpackage": false, 5 | "subpackageName": "", 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/script/Camera.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-09 17:11:19 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-09 21:16:51 6 | */ 7 | const { ccclass, property } = cc._decorator 8 | import CameraManager from './CameraManager' 9 | 10 | @ccclass 11 | export default class Camera extends cc.Component { 12 | @property({ 13 | type: [cc.Node], 14 | displayName: 'layer节点' 15 | }) 16 | layerList: Array = [] 17 | @property({ 18 | type: cc.SceneAsset, 19 | displayName: '场景' 20 | }) 21 | scene: cc.SceneAsset = null 22 | onLoad() { 23 | CameraManager.getInstance().initCamera( 24 | this.node, 25 | this.layerList, 26 | this.scene 27 | ) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assets/script/Camera.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "f34f04f9-517b-44c4-9e58-b5c9f865076f", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/CameraManager.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-10 12:35:49 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-10 12:35:49 6 | */ 7 | /** 8 | *摄像机控制 9 | * 10 | * 单例类 11 | * @export 12 | * @class CameraManager 13 | */ 14 | export default class CameraManager { 15 | private constructor() {} 16 | static instance: CameraManager 17 | static getInstance(): CameraManager { 18 | this.instance = !!this.instance ? this.instance : new CameraManager() 19 | return this.instance 20 | } 21 | /** 22 | *摄像机节点 23 | * 24 | * @private 25 | * @type {cc.Node} 26 | * @memberof CameraManager 27 | */ 28 | private _camera: cc.Node = null 29 | /** 30 | *摄像机所在场景资源 31 | * 32 | * @private 33 | * @type {cc.SceneAsset} 34 | * @memberof CameraManager 35 | */ 36 | private scene: cc.SceneAsset 37 | /** 38 | *顺序节点列表 39 | * 40 | * @private 41 | * @type {Array} 42 | * @memberof CameraManager 43 | */ 44 | private layerList: Array = null 45 | /** 46 | *节点列表长度 47 | * 48 | * @private 49 | * @type {number} 50 | * @memberof CameraManager 51 | */ 52 | private _length: number 53 | /** 54 | *当前节点序号 55 | * 56 | * @private 57 | * @type {number} 58 | * @memberof CameraManager 59 | */ 60 | private currentIndex: number = null 61 | /** 62 | *摄像机缩放比率 63 | * 64 | * @memberof CameraManager 65 | */ 66 | set zoomRatio(value: number) { 67 | this.camera.zoomRatio = value 68 | } 69 | /** 70 | *上一个Layer节点 71 | * 72 | * @readonly 73 | * @type {cc.Node} 74 | * @memberof CameraManager 75 | */ 76 | get LastLayer(): cc.Node { 77 | return this.layerList[this.currentIndex - 1] 78 | } 79 | /** 80 | *当前可视节点 81 | * 82 | * @readonly 83 | * @type {cc.Node} 84 | * @memberof CameraManager 85 | */ 86 | get CurrentLayer(): cc.Node { 87 | return this.layerList[this.currentIndex] 88 | } 89 | /** 90 | *下一个Layer节点 91 | * 92 | * @readonly 93 | * @type {cc.Node} 94 | * @memberof CameraManager 95 | */ 96 | get NextLayer(): cc.Node { 97 | return this.layerList[this.currentIndex + 1] 98 | } 99 | /** 100 | *获取摄像机组件 101 | * 102 | * @readonly 103 | * @type {cc.Camera} 104 | * @memberof CameraManager 105 | */ 106 | get camera(): cc.Camera { 107 | return this._camera.getComponent(cc.Camera) 108 | } 109 | /** 110 | *摄像机所在场景名字 111 | * 112 | * @readonly 113 | * @type {string} 114 | * @memberof CameraManager 115 | */ 116 | get sceneName(): string { 117 | return this.scene.name 118 | } 119 | /** 120 | *更新摄像机注视位置 121 | * 122 | * @private 123 | * @param {(camera: cc.Node, dpos: cc.Vec2) => void} [callback] 124 | * @memberof CameraManager 125 | */ 126 | private update(callback?: (camera: cc.Node, dpos: cc.Vec2) => void): void { 127 | !!callback 128 | ? callback(this._camera, this.layerList[this.currentIndex].position) 129 | : (this._camera.position = this.layerList[this.currentIndex].position) 130 | } 131 | /** 132 | *初始化摄像机 133 | * 134 | * @param {cc.Node} _camera 135 | * @param {Array} layerList 136 | * @param {cc.SceneAsset} scene 137 | * @memberof CameraManager 138 | */ 139 | public initCamera( 140 | _camera: cc.Node, 141 | layerList: Array, 142 | scene: cc.SceneAsset 143 | ) { 144 | this.currentIndex = 0 145 | this._length = layerList.length 146 | this.layerList = layerList 147 | this._camera = _camera 148 | this.scene = scene 149 | } 150 | /** 151 | *切换当前显示的节点, 152 | * @param -1: 后退 153 | * @param 0: 保持 154 | * @param 1: 前进 155 | * 156 | * @param {number} value 157 | * @param {(camera: cc.Node, dpos: cc.Vec2) => void} [callback] 是否自定义摄像机移动? go之后调用 158 | * @memberof CameraManager 159 | */ 160 | public go( 161 | value: number, 162 | callback?: (camera: cc.Node, dpos: cc.Vec2) => void 163 | ): void { 164 | switch (value) { 165 | case -1: 166 | { 167 | if (this.currentIndex > 0) { 168 | this.currentIndex-- 169 | this.update(callback) 170 | } 171 | } 172 | break 173 | case 0: 174 | this.update(callback) 175 | break 176 | case 1: 177 | { 178 | if (this.currentIndex < this._length - 1) { 179 | this.currentIndex++ 180 | this.update(callback) 181 | } 182 | } 183 | break 184 | default: 185 | throw new Error('CameraManager go error') 186 | } 187 | } 188 | /** 189 | *重载所有layout,然后移动注视 190 | * @param -1: 后退 191 | * @param 0: 保持 192 | * @param 1: 前进 193 | * 194 | * @param {number} value 195 | * @param {Function} callback 196 | * @memberof CameraManager 197 | */ 198 | public reload(value: number, callback?: Function): void { 199 | cc.director.loadScene(this.scene.name, () => { 200 | this.go(value) 201 | !!callback ? callback() : null 202 | }) 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /assets/script/CameraManager.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "91d6079e-40f0-4b57-bf08-952cf5ee32b0", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/ConnectLayer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-09 17:11:30 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-13 16:11:43 6 | */ 7 | const { ccclass, property } = cc._decorator 8 | import SceneMediator from './SceneMediator' 9 | import Model from './Model' 10 | import State from './State' 11 | 12 | @ccclass 13 | export default class ConnectLayer extends cc.Component { 14 | @property(cc.Button) 15 | beforeBtn: cc.Button = null 16 | @property(cc.Button) 17 | nextBtn: cc.Button = null 18 | @property(cc.Prefab) 19 | PlayLayer: cc.Prefab = null 20 | @property(cc.Node) 21 | PlayLayerAnchor: cc.Node = null 22 | 23 | start() { 24 | this.nextBtn.node.on('click', () => { 25 | if (State.getInstance().isActionStop) { 26 | SceneMediator.getInstance().go( 27 | 1, 28 | () => { 29 | let PlayLayer = cc.instantiate(this.PlayLayer) 30 | PlayLayer.setParent(this.PlayLayerAnchor) 31 | PlayLayer.setPosition(0, 0) 32 | Model.getInstance().saveLayerNode(PlayLayer) 33 | }, 34 | undefined, 35 | undefined, 36 | () => { 37 | State.getInstance().isActionStop = false 38 | } 39 | ) 40 | } 41 | }) 42 | this.beforeBtn.node.on('click', () => { 43 | SceneMediator.getInstance().backto() 44 | }) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /assets/script/ConnectLayer.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "7c18c6f0-a911-4a28-8192-51e76e6e0723", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/Data.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-02 17:06:17 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-10 10:37:55 6 | */ 7 | import { 8 | transformArray, 9 | visitArray, 10 | alterArray, 11 | moreFunc, 12 | toInt, 13 | PointList, 14 | fillArraySuper, 15 | fillArray, 16 | hasTwiceSuper 17 | } from './MathVec' 18 | /** 19 | *一维数组与合并偏差 20 | * 21 | * @interface ArrAndDelta 22 | */ 23 | interface ArrAndDelta { 24 | arr: number[] 25 | delta: number[] 26 | } 27 | /** 28 | *二维数组与合并偏差 29 | * 30 | * @interface MapAndDelta 31 | */ 32 | interface MapAndDelta { 33 | map: number[][] 34 | delta: number[][] 35 | } 36 | /** 37 | *矩阵合并算法 38 | * 39 | * 单例类 40 | * @export 41 | * @class Data 42 | */ 43 | export default class Data { 44 | private constructor() {} 45 | static instance: Data 46 | static getInstance(): Data { 47 | this.instance = !!this.instance ? this.instance : new Data() 48 | return this.instance 49 | } 50 | private map: Array> 51 | private __map: Array> 52 | private updateTimes: number 53 | private __updateTimes: number 54 | private maxValue: number 55 | private hasNext: boolean 56 | /** 57 | *初始化矩阵数据 58 | * 59 | * @param {number} size 方阵边长 60 | * @param {number} [maxValue=2048] 数字最大值 61 | * @memberof Data 62 | */ 63 | public init(size: number, maxValue: number = 2048): Data { 64 | this.updateTimes = 0 65 | this.__updateTimes = 0 66 | this.maxValue = maxValue 67 | this.map = fillArraySuper(0, { 68 | raw: size, 69 | col: size 70 | }) 71 | this.__map = fillArraySuper(0, { 72 | raw: size, 73 | col: size 74 | }) 75 | return this 76 | } 77 | /** 78 | *当前矩阵 79 | * 80 | * @readonly 81 | * @type {number[][]} 82 | * @memberof Data 83 | */ 84 | get data(): number[][] { 85 | return this.map 86 | } 87 | /** 88 | *得到updateTimes增量 89 | * 90 | * @readonly 91 | * @type {number} 92 | * @memberof Data 93 | */ 94 | get updateValue(): number { 95 | return this.updateTimes - this.__updateTimes 96 | } 97 | /** 98 | *分数 99 | * 100 | * @readonly 101 | * @type {number} 102 | * @memberof Data 103 | */ 104 | get score(): number { 105 | return this.updateTimes 106 | } 107 | /** 108 | *最大值 109 | * 110 | * @readonly 111 | * @type {number} 112 | * @memberof Data 113 | */ 114 | get MaxValue(): number { 115 | return this.maxValue 116 | } 117 | /** 118 | *检测数据是否变动 119 | * 120 | * @readonly 121 | * @type {boolean} 122 | * @memberof Data 123 | */ 124 | get isChanged(): boolean { 125 | return this.__map.toString() !== this.map.toString() 126 | } 127 | /** 128 | *获取updateTimes状态 129 | * 130 | * @readonly 131 | * @type {boolean} 数字超过maxValue则返回true 132 | * @memberof Data 133 | */ 134 | get result(): boolean { 135 | return Boolean(Math.abs(this.updateTimes) % 2) 136 | } 137 | /** 138 | *合并方向, 返回合并偏差二维数组 139 | * 140 | * @param {string} method 141 | * @param {number[][]} [arr=this.map] 142 | * @returns {Array>} 143 | * @memberof Data 144 | */ 145 | public merge( 146 | method: string, 147 | arr: number[][] = this.map 148 | ): Array> { 149 | visitArray(this.map, (raw, col) => { 150 | this.__map[raw][col] = this.map[raw][col] 151 | }) 152 | let delta: Array> 153 | switch (method) { 154 | case 'left': 155 | { 156 | let mapAndDelta = this.mergeSuper(arr, this.mergeLeft) 157 | this.map = mapAndDelta.map 158 | delta = mapAndDelta.delta 159 | } 160 | break 161 | case 'right': 162 | { 163 | let mapAndDelta = this.mergeSuper(arr, this.mergeRight) 164 | this.map = mapAndDelta.map 165 | delta = mapAndDelta.delta 166 | } 167 | break 168 | case 'up': 169 | { 170 | let mapAndDelta = this.mergeSuper(transformArray(arr), this.mergeLeft) 171 | delta = transformArray(mapAndDelta.delta) 172 | this.map = transformArray(mapAndDelta.map) 173 | } 174 | break 175 | case 'down': 176 | { 177 | let mapAndDelta = this.mergeSuper( 178 | transformArray(arr), 179 | this.mergeRight 180 | ) 181 | delta = transformArray(mapAndDelta.delta) 182 | this.map = transformArray(mapAndDelta.map) 183 | } 184 | break 185 | default: 186 | throw new Error('Data merge method error') 187 | } 188 | return delta 189 | } 190 | /** 191 | *反转回调处理矩阵 192 | * 193 | * @private 194 | * @memberof Data 195 | */ 196 | private mergeSuper = ( 197 | arr: number[][], 198 | callback: (arr: number[]) => ArrAndDelta 199 | ): MapAndDelta => { 200 | let map: Array> = new Array>() 201 | let delta: Array> = new Array>() 202 | this.__updateTimes = this.updateTimes 203 | for (var raw of arr) { 204 | let arrAndDelta = callback(raw) 205 | map.push(arrAndDelta.arr) 206 | delta.push(arrAndDelta.delta) 207 | } 208 | return { 209 | map: map, 210 | delta: delta 211 | } 212 | } 213 | /** 214 | *检测矩阵数字是否都不为0, 若都不为0则返回true 215 | * 216 | * @readonly 217 | * @type {boolean} 218 | * @memberof Data 219 | */ 220 | get isFull(): boolean { 221 | this.hasNext = false 222 | visitArray(this.map, (raw, col) => { 223 | if (this.map[raw][col] === 0) { 224 | this.hasNext = true 225 | } 226 | }) 227 | return !this.hasNext 228 | } 229 | /** 230 | *检测矩阵是否存在相邻相同数字, 若存在则返回ture 231 | * 232 | * @readonly 233 | * @type {boolean} 234 | * @memberof Data 235 | */ 236 | get hasTwice(): boolean { 237 | return hasTwiceSuper(this.map) 238 | } 239 | /** 240 | *随机位置添加元素 241 | * 242 | * @param {number} [times=1] 243 | * @returns {boolean} 返回true, 若没有空位则返回false 244 | * @memberof Data 245 | */ 246 | public addRand(times: number = 1): boolean { 247 | let points = PointList() 248 | moreFunc(() => { 249 | visitArray(this.map, (raw, col) => { 250 | if (this.map[raw][col] === 0) { 251 | points.push({ x: raw, y: col }) 252 | this.hasNext = true 253 | } 254 | }) 255 | if (this.hasNext) { 256 | let index = toInt(Math.random() * points.length) 257 | alterArray(this.map, { 258 | raw: points[index].x, 259 | col: points[index].y, 260 | value: 2 261 | }) 262 | } 263 | }, times) 264 | return this.hasNext 265 | } 266 | /** 267 | *向左合并 268 | * 269 | * @private 270 | * @memberof Data 271 | */ 272 | private mergeLeft = (arr: number[]): ArrAndDelta => { 273 | let i, nextI, m 274 | let len = arr.length 275 | let delta = fillArray(0, arr.length) 276 | for (i = 0; i < len; i++) { 277 | nextI = -1 278 | for (m = i + 1; m < len; m++) { 279 | if (arr[m] !== 0) { 280 | nextI = m 281 | if (arr[i] === arr[m]) { 282 | delta[m] = m - i 283 | } else { 284 | if (arr[i] === 0) { 285 | delta[m] = m - i 286 | } else { 287 | delta[m] = m - i - 1 288 | } 289 | } 290 | break 291 | } 292 | } 293 | if (nextI !== -1) { 294 | if (arr[i] === 0) { 295 | arr[i] = arr[nextI] 296 | arr[nextI] = 0 297 | i -= 1 298 | } else if (arr[i] === arr[nextI]) { 299 | arr[i] = arr[i] * 2 300 | this.updateTimes = 301 | arr[i] < this.maxValue 302 | ? this.updateTimes + arr[i] 303 | : this.updateTimes + 1 304 | arr[nextI] = 0 305 | } 306 | } 307 | } 308 | return { 309 | arr: arr, 310 | delta: delta 311 | } 312 | } 313 | /** 314 | *向右合并 315 | * 316 | * @private 317 | * @memberof Data 318 | */ 319 | private mergeRight = (arr: number[]): ArrAndDelta => { 320 | let arr_re = [...arr].reverse() 321 | let arrAndDelta = this.mergeLeft(arr_re) 322 | return { 323 | arr: [...arrAndDelta.arr].reverse(), 324 | delta: [...arrAndDelta.delta].reverse() 325 | } 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /assets/script/Data.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "119aac66-65e1-41dc-8ee1-201563505a93", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/EndLayout.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-09 17:11:23 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-13 16:05:21 6 | */ 7 | const { ccclass, property } = cc._decorator 8 | import Data from './Data' 9 | import Model from './Model' 10 | import SceneMediator from './SceneMediator' 11 | import State from './State' 12 | 13 | @ccclass 14 | export default class EndLayer extends cc.Component { 15 | @property(cc.Label) 16 | score: cc.Label = null 17 | @property(cc.Label) 18 | title: cc.Label = null 19 | @property(cc.Button) 20 | restartBtn: cc.Button = null 21 | 22 | maxValue: number = null 23 | 24 | onLoad() { 25 | this.maxValue = Data.getInstance().MaxValue 26 | } 27 | start() { 28 | if (Data.getInstance().result) { 29 | this.title.string = 'Win! ' + this.maxValue + '!' 30 | this.score.string = String(Data.getInstance().score - 1) 31 | this.restartBtn.node 32 | .getChildByName('Label') 33 | .getComponent(cc.Label).string = 'continue!' 34 | this.restartBtn.node.on('click', () => { 35 | Model.getInstance().returnPreLayout(this.node) 36 | }) 37 | } else { 38 | this.title.string = 'Over' 39 | this.score.string = String(Data.getInstance().score) 40 | this.restartBtn.node 41 | .getChildByName('Label') 42 | .getComponent(cc.Label).string = 'restart' 43 | this.restartBtn.node.on('click', () => { 44 | Model.getInstance().returnPreLayout(this.node) 45 | SceneMediator.getInstance().go( 46 | -1, 47 | undefined, 48 | undefined, 49 | undefined, 50 | () => { 51 | State.getInstance().isActionStop = true 52 | Model.getInstance() 53 | .getLayerNode() 54 | .destroy() 55 | } 56 | ) 57 | }) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/script/EndLayout.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "64fb69d2-552d-4267-89ac-3e1444d1a4f4", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/Game.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-11 19:41:48 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-11 22:16:38 6 | */ 7 | import Game from './IGame' 8 | /** 9 | * layout数据 10 | */ 11 | let game: Game = { 12 | edge: { 13 | width: { 14 | start: -150, 15 | end: 150 16 | }, 17 | height: { 18 | start: -150, 19 | end: 150 20 | } 21 | }, 22 | type: [ 23 | { 24 | size: 3, 25 | num: 3 * 3, 26 | edgeScale: 0.9, 27 | blockScale: 1.1 28 | }, 29 | { 30 | size: 4, 31 | num: 4 * 4, 32 | edgeScale: 1, 33 | blockScale: 1 34 | }, 35 | { 36 | size: 8, 37 | num: 8 * 8, 38 | edgeScale: 1.1, 39 | blockScale: 0.5 40 | } 41 | ] 42 | } 43 | export default game 44 | -------------------------------------------------------------------------------- /assets/script/Game.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "2efce39f-9fb2-4f04-a8b7-48f676f1bdc7", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/IGame.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-11 19:41:52 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-11 21:22:53 6 | */ 7 | /** 8 | *边界数据结构 9 | * 10 | * @interface Edge 11 | */ 12 | export interface Edge { 13 | width: { 14 | start: number 15 | end: number 16 | } 17 | height: { 18 | start: number 19 | end: number 20 | } 21 | } 22 | /** 23 | *layout数据 24 | * 25 | * @export 26 | * @interface LayoutType 27 | */ 28 | export interface LayoutType { 29 | size: number 30 | num: number 31 | edgeScale: number 32 | blockScale: number 33 | } 34 | /** 35 | *game数据 36 | * 37 | * @interface layout 38 | */ 39 | export default interface Game { 40 | edge: Edge 41 | type: LayoutType[] 42 | } 43 | -------------------------------------------------------------------------------- /assets/script/IGame.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "7d8d257a-f42d-4e5a-8c48-a3bcf39f0dca", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/ILayout.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-02 13:06:06 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-11 18:54:12 6 | */ 7 | export default interface ILayout { 8 | /** 9 | *初始化边界 10 | * 11 | * @param {{width: { start: number; end: number } 12 | * height: { start: number; end: number } 13 | * }} size 14 | * @param {number} [scale] 边界缩放 15 | * @returns {ILayout} 16 | * @memberof ILayout 17 | */ 18 | initEdge( 19 | size: { 20 | width: { start: number; end: number } 21 | height: { start: number; end: number } 22 | }, 23 | scale?: number 24 | ): ILayout 25 | /** 26 | *根据矩阵绘制block组 27 | * 28 | * @param {number[][]} data 矩阵数据 29 | * @memberof Layout 30 | */ 31 | draw(data: number[][], step?: number): void 32 | /** 33 | *根据命令和偏移执行绘图动作 34 | * 35 | * @param {string} command 36 | * @param {number[][]} delta 37 | * @param {Function} callback 结束回调 38 | * @param {number} [speed] 39 | * @memberof Layout 40 | */ 41 | action( 42 | command: string, 43 | delta: number[][], 44 | callback: Function, 45 | speed?: number 46 | ): void 47 | /** 48 | *设置block缩放 49 | * 50 | * @param {number} scale 51 | * @memberof ILayout 52 | */ 53 | setBlockScale(scale: number): ILayout 54 | } 55 | -------------------------------------------------------------------------------- /assets/script/ILayout.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "861c8d99-1f93-48a1-855a-92b0c1f3c5f0", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/IMathVec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-09 17:11:43 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-09 17:11:43 6 | */ 7 | export default interface MathVec {} 8 | 9 | export interface Point { 10 | x: number 11 | y: number 12 | } 13 | -------------------------------------------------------------------------------- /assets/script/IMathVec.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "36d56966-c4a2-4b9b-8e17-603117cfc0d9", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/IScoreManager.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-10 12:36:04 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-10 12:36:04 6 | */ 7 | export default interface IScoreManager { 8 | play(score: number): void 9 | } 10 | -------------------------------------------------------------------------------- /assets/script/IScoreManager.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "3ac56382-f0ae-4edb-8962-cf27b76fca11", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/ITouchFront.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-09 17:11:47 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-09 17:11:47 6 | */ 7 | export default interface ITouchFront { 8 | /** 9 | *触摸方向执行对应回调 10 | * 11 | * @param {Function} [callbackLeft] 12 | * @param {Function} [callbackRight] 13 | * @param {Function} [callbackUp] 14 | * @param {Function} [callbackDown] 15 | * @returns {ITouchFront} 16 | * @memberof ITouchFront 17 | */ 18 | submit( 19 | callbackLeft?: Function, 20 | callbackRight?: Function, 21 | callbackUp?: Function, 22 | callbackDown?: Function 23 | ): ITouchFront 24 | /** 25 | *监听触摸 26 | * 27 | * @memberof TouchFront 28 | */ 29 | listen(): void 30 | } 31 | -------------------------------------------------------------------------------- /assets/script/ITouchFront.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "9cafc3d6-a8eb-4b10-9e97-dcb6338047b0", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/Layout.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-01 20:07:29 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-11 18:57:08 6 | */ 7 | import ILayout from './ILayout' 8 | import Model from './Model' 9 | import { visitArray } from './MathVec' 10 | /** 11 | *Block节点视图的逻辑 12 | * 13 | * 接口类 14 | * @export 15 | * @class Layout 16 | * @implements {ILayout} 17 | */ 18 | export default class Layout implements ILayout { 19 | /** 20 | *layout根节点 21 | * 22 | * @private 23 | * @type {cc.Node} 24 | * @memberof Layout 25 | */ 26 | private background: cc.Node 27 | /** 28 | *锚点方形边界 29 | * 30 | * @private 31 | * @type {{width: { start: number; end: number } height: { start: number; end: number } }} 32 | * @memberof Layout 33 | */ 34 | private edge: { 35 | width: { start: number; end: number } 36 | height: { start: number; end: number } 37 | } 38 | /** 39 | *锚点边界宽度 40 | * 41 | * @private 42 | * @type {number} 43 | * @memberof Layout 44 | */ 45 | private width: number 46 | /** 47 | *锚点边界高度 48 | * 49 | * @private 50 | * @type {number} 51 | * @memberof Layout 52 | */ 53 | private height: number 54 | /** 55 | *方块缩放 56 | * 57 | * @private 58 | * @type {number} 59 | * @memberof Layout 60 | */ 61 | private blockScale: number = 1 62 | /** 63 | *边界原点 64 | * 65 | * @private 66 | * @type {cc.Vec2} 67 | * @memberof Layout 68 | */ 69 | private origin: cc.Vec2 70 | /** 71 | *颜色组 72 | * 73 | * @private 74 | * @memberof Layout 75 | */ 76 | private color = { 77 | 2: cc.color(237, 241, 21, 255), 78 | 4: cc.color(241, 180, 21, 255), 79 | 8: cc.color(171, 241, 21, 255), 80 | 16: cc.color(149, 160, 216, 255), 81 | 32: cc.color(187, 149, 216, 255), 82 | 64: cc.color(216, 149, 209, 255), 83 | 128: cc.color(28, 118, 156, 255), 84 | 256: cc.color(16, 74, 99, 255), 85 | 512: cc.color(168, 85, 25, 255), 86 | 1024: cc.color(236, 122, 38, 255), 87 | 2048: cc.color(236, 86, 33, 255) 88 | } 89 | /** 90 | *Creates an instance of Layout. 91 | * @param {cc.Node} background 92 | * @memberof Layout 93 | */ 94 | constructor(background: cc.Node) { 95 | this.background = background 96 | return this 97 | } 98 | /** 99 | *初始化边界 100 | * 101 | * @memberof Layout 102 | */ 103 | public initEdge = ( 104 | size: { 105 | width: { start: number; end: number } 106 | height: { start: number; end: number } 107 | }, 108 | scale: number = 1 109 | ): Layout => { 110 | this.edge = size 111 | this.origin = cc.v2(size.width.start * scale, -size.width.start * scale) 112 | this.width = (this.edge.width.end - this.edge.width.start) * scale 113 | this.height = (this.edge.height.end - this.edge.height.start) * scale 114 | return this 115 | } 116 | /** 117 | *设置block缩放 118 | * 119 | * @param {number} scale 120 | * @memberof Layout 121 | */ 122 | public setBlockScale(scale: number): Layout { 123 | this.blockScale = scale 124 | return this 125 | } 126 | /** 127 | *根据矩阵绘制block组 128 | * 129 | * @param {number[][]} data 矩阵数据 130 | * @memberof Layout 131 | */ 132 | public draw(data: number[][]): void { 133 | let stepX = this.width / (data[0].length - 1) 134 | let stepY = this.height / (data.length - 1) 135 | Model.getInstance().clearNodeList() 136 | // 遍历block组 137 | visitArray(data, (raw, col) => { 138 | if (data[raw][col] !== 0) { 139 | // 映射锚点位置 140 | let pos = cc.v2( 141 | this.origin.x + stepX * col, 142 | this.origin.y - stepY * raw 143 | ) 144 | // 取对象池节点 145 | let block = Model.getInstance().getBlock() 146 | block.setParent(this.background) 147 | block.setScale(this.blockScale) 148 | block.setPosition(pos) 149 | this.setNodeTarget(block, { 150 | raw: raw, 151 | col: col 152 | }) 153 | block.getChildByName('label').getComponent(cc.Label).string = String( 154 | data[raw][col] 155 | ) 156 | block.color = this.color[String(data[raw][col])] 157 | Model.getInstance().saveNode(block) 158 | } 159 | }) 160 | } 161 | /** 162 | *根据命令和偏移执行绘图动作 163 | * 164 | * @param {string} command 165 | * @param {number[][]} delta 166 | * @param {Function} callback 结束回调 167 | * @param {number} [speed] 168 | * @memberof Layout 169 | */ 170 | public action( 171 | command: string, 172 | delta: number[][], 173 | callback: Function, 174 | speed?: number 175 | ): void { 176 | visitArray(delta, (raw, col) => { 177 | let stepX = this.width / (delta[0].length - 1) 178 | let stepY = this.height / (delta.length - 1) 179 | if (delta[raw][col] !== 0) { 180 | let node = this.getNodeByTarget(this.background, { 181 | raw: raw, 182 | col: col 183 | }) 184 | node 185 | .RunAction( 186 | this.getAction( 187 | command, 188 | { 189 | deltaX: delta[raw][col] * stepX, 190 | deltaY: delta[raw][col] * stepY 191 | }, 192 | speed 193 | ).easing(ezaction.ease.cubicEaseOut(1)) 194 | ) 195 | .onStoped(callback) 196 | } 197 | }) 198 | } 199 | /** 200 | *获取方向偏移动作 201 | * 202 | * @private 203 | * @param {string} command 204 | * @param {number} delta 205 | * @param {number} [speed=0.5] 206 | * @returns {cc.Action} 207 | * @memberof Layout 208 | */ 209 | private getAction( 210 | command: string, 211 | delta: { deltaX: number; deltaY: number }, 212 | speed: number = 0.5 213 | ): ezaction.HActionTweenBy { 214 | switch (command) { 215 | case 'left': 216 | return ezaction.moveBy(speed, cc.v2(-delta.deltaX, 0)) 217 | case 'right': 218 | return ezaction.moveBy(speed, cc.v2(delta.deltaX, 0)) 219 | case 'up': 220 | return ezaction.moveBy(speed, cc.v2(0, delta.deltaY)) 221 | case 'down': 222 | return ezaction.moveBy(speed, cc.v2(0, -delta.deltaY)) 223 | default: 224 | throw new Error('action command error') 225 | } 226 | } 227 | /** 228 | *设置坐标索引 229 | * 230 | * @private 231 | * @param {cc.Node} node 232 | * @param {{ raw: number; col: number }} pos 233 | * @memberof Layout 234 | */ 235 | private setNodeTarget( 236 | node: cc.Node, 237 | pos: { raw: number; col: number } 238 | ): void { 239 | node.name = String(pos.raw + '' + pos.col) 240 | } 241 | /** 242 | *根据坐标索引获取节点 243 | * 244 | * @private 245 | * @param {cc.Node} parent 246 | * @param {{ raw: number; col: number }} pos 247 | * @returns {cc.Node} 248 | * @memberof Layout 249 | */ 250 | private getNodeByTarget( 251 | parent: cc.Node, 252 | pos: { raw: number; col: number } 253 | ): cc.Node { 254 | return parent.getChildByName(String(pos.raw + '' + pos.col)) 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /assets/script/Layout.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "3ac416d6-b5a7-4885-bc6f-2087bdcf305b", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/MathVec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-02 17:06:29 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-04 13:15:51 6 | */ 7 | import IMathVec, { Point } from './IMathVec' 8 | 9 | /** 10 | *获取随机直角坐标点 11 | * 12 | * @export 13 | * @class MathVec 14 | * @implements {IMathVec} 15 | */ 16 | export default class MathVec implements IMathVec { 17 | /** 18 | *Creates an instance of MathVec. 19 | * @param {number} start 初值 20 | * @param {number} step 步长 21 | * @param {number} num 最大阶数 22 | * @example let rand = new MathVec(-150, 100, 4) 23 | * @memberof MathVec 24 | */ 25 | constructor(start: number, step: number, num: number) { 26 | this.start = start 27 | this.step = step 28 | this.num = num 29 | } 30 | private start: number 31 | private step: number 32 | private num: number 33 | public randPos(): cc.Vec2 { 34 | let rand = 35 | this.start + parseInt(String(Math.random() * this.num)) * this.step 36 | return cc.v2(rand, rand) 37 | } 38 | public randVaule(): number { 39 | return this.start + parseInt(String(Math.random() * this.num * this.step)) 40 | } 41 | } 42 | /** 43 | *矩阵行列互换 44 | * 45 | * @export 46 | * @template Type 47 | * @param {Type[][]} arr 48 | * @returns {Type[][]} 49 | */ 50 | export function transformArray(arr: Type[][]): Type[][] { 51 | let newArray: Array> = new Array>() 52 | let raws = arr.length 53 | for (let raw = 0; raw < raws; raw++) { 54 | newArray.push([]) 55 | let cols = arr[raw].length 56 | for (let col = 0; col < cols; col++) { 57 | newArray[raw][col] = arr[col][raw] 58 | } 59 | } 60 | return newArray 61 | } 62 | /** 63 | *遍历二维数组元素 64 | * 65 | * @export 66 | * @template Type 67 | * @param {Type[][]} arr 68 | * @param {(raw: number, col: number) => void} callback 69 | */ 70 | export function visitArray( 71 | arr: Type[][], 72 | callback: (raw: number, col: number) => void 73 | ) { 74 | let raws = arr.length 75 | for (let raw = 0; raw < raws; raw++) { 76 | let cols = arr[raw].length 77 | for (let col = 0; col < cols; col++) { 78 | callback(raw, col) 79 | } 80 | } 81 | } 82 | /** 83 | *随机访问二维数组元素 84 | * 85 | * @export 86 | * @template Type 87 | * @param {Type[][]} arr 88 | * @param {(raw: number, col: number) => void} callback 89 | */ 90 | export function visitArrayRand( 91 | arr: Type[][], 92 | callback: (raw: number, col: number) => void 93 | ) { 94 | let randRow = toInt(Math.random() * arr.length) 95 | let randCol = toInt(Math.random() * arr[randRow].length) 96 | callback(randRow, randCol) 97 | } 98 | /** 99 | *多次执行回调函数 100 | * 101 | * @export 102 | * @param {Function} callback 103 | * @param {number} [times=1] 执行次数 104 | */ 105 | export function moreFunc(callback: Function, times: number = 1): void { 106 | let count = 0 107 | let loop = (): void => { 108 | if (count >= times) { 109 | return 110 | } 111 | count++ 112 | callback() 113 | loop() 114 | } 115 | loop() 116 | } 117 | /** 118 | *转为整型 119 | * 120 | * @export 121 | * @param {*} value 122 | * @returns 123 | */ 124 | export function toInt(value) { 125 | return parseInt(String(value)) 126 | } 127 | /** 128 | *随机概率执行函数 129 | * 130 | * @export 131 | * @param {Function} callback 132 | * @param {number} [value=1.5] 值越大执行回调概率越大 133 | */ 134 | export function randFunc(callback: Function, value: number = 1.5): void { 135 | let rand = Boolean(toInt(Math.random() * value)) 136 | if (rand) { 137 | callback(rand) 138 | } 139 | } 140 | /** 141 | *替换二维数组指定位置的值 142 | * 143 | * @export 144 | * @template Type 145 | * @param {Type[][]} arr 146 | * @param 147 | * { raw: number 148 | * col: number 149 | * } pos 150 | * @param {*} value 151 | */ 152 | export function alterArray( 153 | arr: Type[][], 154 | pos: { 155 | /** 156 | *替换的元素所在行 157 | * 158 | * @type {number} 159 | */ 160 | raw: number 161 | /** 162 | *替换的元素所在列 163 | * 164 | * @type {number} 165 | */ 166 | col: number 167 | /** 168 | *替换后的值 169 | * 170 | * @type {*} 171 | */ 172 | value: any 173 | } 174 | ) { 175 | // arr[pos.raw].splice(pos.col, 1, pos.value) 176 | arr[pos.raw][pos.col] = pos.value 177 | } 178 | 179 | /** 180 | *cc.Vec2的基础运算 181 | * 182 | * @param {cc.Vec2} v1 183 | * @param {string} method 184 | * @param {cc.Vec2} v2 185 | * @returns {cc.Vec2} 186 | * @example computed(cc.v2(0, 0), '+', cc.v2(1, 1)) 187 | * @memberof MathVec 188 | */ 189 | export function computed(v1: cc.Vec2, method: string, v2: cc.Vec2): cc.Vec2 { 190 | let result 191 | switch (method) { 192 | case '+': 193 | result = cc.v2(v1.x + v2.x, v1.y + v2.y) 194 | break 195 | case '-': 196 | result = cc.v2(v1.x - v2.x, v1.y - v2.y) 197 | break 198 | case '*': 199 | result = cc.v2(v1.x * v2.x, v1.y * v2.y) 200 | break 201 | case '/': 202 | result = cc.v2(v1.x / v2.x, v1.y / v2.y) 203 | break 204 | 205 | default: 206 | throw new Error('computed method unknown') 207 | } 208 | return result 209 | } 210 | /** 211 | *PointList得到二维坐标容器 212 | * 213 | * @export 214 | * @returns {Array} 215 | */ 216 | export function PointList(): Array { 217 | return new Array() 218 | } 219 | /** 220 | *判断两个点是否相等 221 | * 222 | * @export 223 | * @param {Point} pos1 224 | * @param {Point} pos2 225 | * @returns {boolean} 226 | */ 227 | export function judgePos(pos1: Point, pos2: Point): boolean { 228 | return pos1.x === pos2.x && pos1.y === pos2.y ? true : false 229 | } 230 | /** 231 | *得到填充数组 232 | * 233 | * @export 234 | * @template Type 235 | * @param {Type} value 236 | * @param {number} [length=1] 237 | * @returns {Type[]} 238 | */ 239 | export function fillArray(value: Type, length: number = 1): Type[] { 240 | let arr = new Array() 241 | for (let i = 0; i < length; i++) { 242 | arr.push(value) 243 | } 244 | return arr 245 | } 246 | /** 247 | *得到填充二维数组 248 | * 249 | * @export 250 | * @template Type 251 | * @param {Type} value 252 | * @param {{ raw: number; col: number }} size 253 | * @returns {Type[][]} 254 | */ 255 | export function fillArraySuper( 256 | value: Type, 257 | size: { raw: number; col: number } 258 | ): Type[][] { 259 | let arr = new Array>() 260 | for (let raw = 0; raw < size.raw; raw++) { 261 | arr.push([]) 262 | for (let col = 0; col < size.col; col++) { 263 | arr[raw][col] = value 264 | } 265 | } 266 | return arr 267 | } 268 | /** 269 | *检测一维数组是否有相邻相同数字 270 | * 271 | * @export 272 | * @param {number[]} arr 273 | * @returns {boolean} 若存在则返回ture 274 | */ 275 | export function hasTwice(arr: number[]): boolean { 276 | let len = arr.length 277 | let result = false 278 | for (let i = 0; i < len - 1; i++) { 279 | if (arr[i] === arr[i + 1]) { 280 | result = true 281 | break 282 | } 283 | } 284 | return result 285 | } 286 | /** 287 | *检测二维数组行方向是否有相邻相同数字 288 | * 289 | * @export 290 | * @param {number[][]} map 291 | * @returns {boolean} 若存在则返回ture 292 | */ 293 | export function testRows(map: number[][]): boolean { 294 | let result: boolean = false 295 | for (let raw of map) { 296 | result = hasTwice(raw) 297 | if (result) { 298 | break 299 | } 300 | } 301 | return result 302 | } 303 | /** 304 | *检测二维数组是否有相邻相同数字 305 | * 306 | * @export 307 | * @param {number[][]} map 308 | * @returns {boolean} 若存在则返回ture 309 | */ 310 | export function hasTwiceSuper(map: number[][]): boolean { 311 | let resultRaw: boolean = false 312 | let resultCol: boolean = false 313 | resultRaw = testRows(map) 314 | let mapTurn = transformArray(map) 315 | resultCol = testRows(mapTurn) 316 | return resultRaw || resultCol 317 | } 318 | -------------------------------------------------------------------------------- /assets/script/MathVec.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "52e98e60-a0e7-43b5-997f-65c8c5b720dc", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/Model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-02 13:06:11 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-12 22:44:19 6 | */ 7 | /** 8 | *对象池管理 9 | * 10 | * 单例类 11 | * @export 12 | * @class Model 13 | */ 14 | export default class Model { 15 | private constructor() { 16 | this._BlockPool = new cc.NodePool() 17 | this._layoutCache = new cc.NodePool() 18 | this._nodeList = new Array() 19 | } 20 | static instance: Model 21 | static getInstance(): Model { 22 | this.instance = !!this.instance ? this.instance : new Model() 23 | return this.instance 24 | } 25 | /** 26 | *对象池 27 | * 28 | * @private 29 | * @type {cc.NodePool} 30 | * @memberof Model 31 | */ 32 | private _BlockPool: cc.NodePool 33 | /** 34 | *保留预置资源引用 35 | * 36 | * @private 37 | * @type {cc.Prefab} 38 | * @memberof Model 39 | */ 40 | private _prafab: cc.Prefab 41 | /** 42 | *节点引用组 43 | * 44 | * @private 45 | * @type {cc.Node[]} 46 | * @memberof Model 47 | */ 48 | private _nodeList: cc.Node[] 49 | /** 50 | *layer引用 51 | * 52 | * @private 53 | * @type {cc.Node} 54 | * @memberof Model 55 | */ 56 | private _playLayer: cc.Node 57 | /** 58 | *预制窗口缓存 59 | * 60 | * @private 61 | * @type {cc.Node} 62 | * @memberof Model 63 | */ 64 | private _layoutCache: cc.NodePool 65 | /** 66 | *加载prefab缓存 67 | * 68 | * @param {cc.Prefab} prefab 69 | * @param {number} size 70 | * @memberof Model 71 | */ 72 | public initPool(prefab: cc.Prefab, size: number): Model { 73 | for (let i = 0; i < size; ++i) { 74 | let block = cc.instantiate(prefab) 75 | this._BlockPool.put(block) 76 | } 77 | this._prafab = prefab 78 | return this 79 | } 80 | /** 81 | *加载预制窗口缓存, 只保存一个实例 82 | * 83 | * @param {cc.Prefab} prefab 84 | * @returns {Model} 85 | * @memberof Model 86 | */ 87 | public initPreLayout(prefab: cc.Prefab): Model { 88 | let layout = cc.instantiate(prefab) 89 | this._layoutCache.put(layout) 90 | return this 91 | } 92 | /** 93 | *获取预制窗口 94 | * 95 | * @readonly 96 | * @type {cc.Node} 97 | * @memberof Model 98 | */ 99 | public getPreLayout(): cc.Node { 100 | if (this._layoutCache.size() > 0) { 101 | return this._layoutCache.get() 102 | } else { 103 | return null 104 | } 105 | } 106 | /** 107 | *返还预制窗口 108 | * 109 | * @param {cc.Node} node 110 | * @memberof Model 111 | */ 112 | public returnPreLayout(node: cc.Node): void { 113 | this._layoutCache.put(node) 114 | } 115 | /** 116 | *获取节点列表 117 | * 118 | * @readonly 119 | * @type {cc.Node[]} 120 | * @memberof Model 121 | */ 122 | get NodeList(): cc.Node[] { 123 | return this._nodeList 124 | } 125 | /** 126 | *从缓存获取block节点 127 | * 128 | * @returns {cc.Node} 129 | * @memberof Model 130 | */ 131 | public getBlock(): cc.Node { 132 | let block = null 133 | if (this._BlockPool.size() > 0) { 134 | block = this._BlockPool.get() 135 | } else { 136 | block = cc.instantiate(this._prafab) 137 | } 138 | return block 139 | } 140 | /** 141 | *保存节点引用 142 | * 143 | * @param {cc.Node} node 144 | * @memberof Model 145 | */ 146 | public saveNode(node: cc.Node): void { 147 | this._nodeList.push(node) 148 | } 149 | /** 150 | *获取layer引用 151 | * 152 | * @returns {cc.Node} 153 | * @memberof Model 154 | */ 155 | public getLayerNode(): cc.Node { 156 | return this._playLayer 157 | } 158 | /** 159 | *保存layer引用 160 | * 161 | * @param {cc.Node} layer 162 | * @memberof Model 163 | */ 164 | public saveLayerNode(layer: cc.Node): void { 165 | this._playLayer = layer 166 | } 167 | /** 168 | *回收全部节点到缓存 169 | * 170 | * @memberof Model 171 | */ 172 | public clearNodeList(): void { 173 | for (var node of this._nodeList) { 174 | this._BlockPool.put(node) 175 | this._nodeList = [] 176 | } 177 | } 178 | /** 179 | *清空缓存 180 | * 181 | * @memberof Model 182 | */ 183 | public ClearPool(): void { 184 | this._nodeList = [] 185 | this._BlockPool.clear() 186 | this._layoutCache.clear() 187 | this._playLayer.destroy() 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /assets/script/Model.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "b7391e1a-5bf3-4d91-850d-e51d72911738", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/PlayLayer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-01 12:51:23 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-13 16:07:25 6 | */ 7 | const { ccclass, property } = cc._decorator 8 | import TouchBlock from './TouchBlock' 9 | import TouchFront from './TouchFront' 10 | import Layout from './Layout' 11 | import Model from './Model' 12 | import Data from './Data' 13 | import SceneMediator from './SceneMediator' 14 | import ScoreManager from './ScoreManager' 15 | import { LayoutType, Edge } from './IGame' 16 | import game from './Game' 17 | import State from './State' 18 | 19 | @ccclass 20 | export default class PlayLayer extends cc.Component { 21 | @property(cc.Sprite) 22 | background: cc.Sprite = null 23 | @property(cc.Sprite) 24 | layout: cc.Sprite = null 25 | @property(cc.Prefab) 26 | blockPrefab: cc.Prefab = null 27 | @property(cc.Prefab) 28 | gameEnd: cc.Prefab = null 29 | @property(cc.Label) 30 | score: cc.Label = null 31 | @property(cc.Label) 32 | bestScore: cc.Label = null 33 | @property(cc.Button) 34 | backBtn: cc.Button = null 35 | 36 | edge: Edge = null 37 | layoutType: LayoutType = null 38 | 39 | onLoad() { 40 | // init game type 41 | ;[this.edge, this.layoutType] = [ 42 | game.edge, 43 | game.type[State.getInstance().layoutTypeIndex] 44 | ] 45 | // init prefab cache 46 | Model.getInstance() 47 | .initPool(this.blockPrefab, this.layoutType.num) 48 | .initPreLayout(this.gameEnd) 49 | //init Data 50 | Data.getInstance() 51 | .init(this.layoutType.size, 2048) 52 | .addRand(2) 53 | this.bestScore.string = String(State.getInstance().bestScore) 54 | // reset the canvas scale 55 | SceneMediator.getInstance().resetScale(0.9) 56 | } 57 | 58 | start() { 59 | // view 60 | this.backBtn.node.on('click', () => { 61 | SceneMediator.getInstance().go( 62 | -1, 63 | undefined, 64 | undefined, 65 | undefined, 66 | () => { 67 | this.onDestroy() 68 | State.getInstance().isActionStop = true 69 | } 70 | ) 71 | }) 72 | let layout = new Layout(this.layout.node) 73 | layout 74 | .initEdge(this.edge, this.layoutType.edgeScale) 75 | .setBlockScale(this.layoutType.blockScale) 76 | .draw(Data.getInstance().data) 77 | // controller 78 | new TouchBlock( 79 | new TouchFront(this.background.node), 80 | layout, 81 | this.score, 82 | this.bestScore, 83 | new ScoreManager(this.score) 84 | ).load() 85 | } 86 | 87 | onDestroy(): void { 88 | // remove cache 89 | Model.getInstance().ClearPool() 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /assets/script/PlayLayer.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "6da04263-94d5-472a-bd81-1e92adaca564", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/SceneMediator.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-10 12:36:21 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-12 22:19:09 6 | */ 7 | import CameraManager from './CameraManager' 8 | /** 9 | *场景切换动画管理 10 | * 11 | * 单例类 12 | * @export 13 | * @class SceneMediator 14 | */ 15 | export default class SceneMediator { 16 | private constructor() {} 17 | static instance: SceneMediator 18 | static getInstance(): SceneMediator { 19 | this.instance = !!this.instance ? this.instance : new SceneMediator() 20 | return this.instance 21 | } 22 | /** 23 | *延时移动 24 | * 25 | * @param {number} value 命令值 26 | * @param {Function} [onStart] 延时前回调 27 | * @param {number} [delay=0] 延时时长 28 | * @param {number} [movespeed=1] move动画速度 29 | * @param {Function} [onStoped] move结束回调 30 | * @memberof SceneMediator 31 | */ 32 | go( 33 | value: number, 34 | onStart?: Function, 35 | delay: number = 0, 36 | movespeed: number = 1, 37 | onStoped?: Function 38 | ): void { 39 | CameraManager.getInstance().go(value, (camera, dpos) => { 40 | camera 41 | .RunAction(ezaction.moveBy(delay, cc.v2(0, 0))) 42 | .onStart(onStart) 43 | .then( 44 | ezaction 45 | .moveTo(movespeed, dpos) 46 | .easing(ezaction.ease.easeBackOut(1)) 47 | .onStoped(onStoped) 48 | ) 49 | }) 50 | } 51 | /** 52 | *layer前进 53 | * 54 | * @param {number} [scaleTospeed=1] 缩放动画速度 55 | * @param {number} [scale=0.9] 缩放动画幅度 56 | * @param {number} [movespeed=1] move动画速度 57 | * @memberof SceneMediator 58 | */ 59 | goto( 60 | scaleTospeed: number = 1, 61 | scale: number = 0.9, 62 | movespeed: number = 1, 63 | callback?: Function 64 | ): void { 65 | this.go( 66 | 1, 67 | () => { 68 | cc.Canvas.instance.node.RunAction( 69 | ezaction 70 | .scaleTo(scaleTospeed, { scale: scale }) 71 | .easing(ezaction.ease.backEaseOut(1)) 72 | ) 73 | }, 74 | scaleTospeed, 75 | movespeed, 76 | callback 77 | ) 78 | } 79 | /** 80 | *layer后退 81 | * 82 | * @param {number} [scaleTospeed=1] 缩放动画速度 83 | * @param {number} [movespeed=1] move动画速度 84 | * @param {Function} [callback] 结束回调 85 | * @memberof SceneMediator 86 | */ 87 | backto( 88 | scaleTospeed: number = 1, 89 | movespeed: number = 1, 90 | callback?: Function 91 | ): void { 92 | this.go(-1, undefined, 0, movespeed, () => { 93 | cc.Canvas.instance.node 94 | .RunAction( 95 | ezaction 96 | .scaleTo(scaleTospeed, { scale: 1 }) 97 | .easing(ezaction.ease.backEaseOut(1)) 98 | ) 99 | .onStoped(callback) 100 | }) 101 | } 102 | /** 103 | *重载layer 104 | * 105 | * @memberof SceneMediator 106 | */ 107 | reload() { 108 | let scale = cc.Canvas.instance.node.scale 109 | CameraManager.getInstance().reload(1, () => { 110 | cc.Canvas.instance.node.scale = scale 111 | }) 112 | } 113 | /** 114 | *重置canvas的缩放 115 | * 116 | * @param {number} testValue 117 | * @memberof SceneMediator 118 | */ 119 | resetScale(testValue: number = 1) { 120 | cc.Canvas.instance.node.scale !== testValue 121 | ? cc.Canvas.instance.node.setScale(testValue) 122 | : null 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /assets/script/SceneMediator.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "e573ce24-6c8f-47ec-9ca7-2b7706dc4404", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/ScoreManager.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-10 10:55:46 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-10 11:23:21 6 | */ 7 | import IScoreManager from './IScoreManager' 8 | /** 9 | *管理分数动画 10 | * 11 | * 接口类 12 | * @export 13 | * @class ScoreManager 14 | * @implements {IScoreManager} 15 | */ 16 | export default class ScoreManager implements IScoreManager { 17 | private p_ori: cc.Vec2 18 | 19 | private score: cc.Label 20 | 21 | constructor(score: cc.Label) { 22 | this.score = score 23 | this.p_ori = this.score.node.children[0].position 24 | this.score.node.children[0].opacity = 0 25 | return this 26 | } 27 | 28 | public play(score: number) { 29 | this.score.node.children[0] 30 | .RunAction(this.action()) 31 | .onStart(() => { 32 | this.score.node.children[0].opacity = 255 33 | this.score.node.children[0].getComponent(cc.Label).string = 34 | '+' + String(score) 35 | }) 36 | .onStoped(() => { 37 | this.score.node.children[0].setPosition(this.p_ori) 38 | this.score.node.children[0].opacity = 0 39 | }) 40 | } 41 | 42 | private action(): ezaction.HAction { 43 | return ezaction.sequence([ 44 | ezaction.spawn([ 45 | ezaction.moveBy(0.5, cc.v2(0, 10)), 46 | ezaction.fadeOut(0.5) 47 | ]), 48 | ezaction.fadeIn(0) 49 | ]) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /assets/script/ScoreManager.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "f2d677b0-1ea0-4842-9d3f-5ab0b871c04d", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/Select.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-11 22:53:29 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-11 22:53:29 6 | */ 7 | const { ccclass, property } = cc._decorator 8 | import State from './State' 9 | 10 | @ccclass 11 | export default class NewClass extends cc.Component { 12 | @property(cc.Node) 13 | left: cc.Node = null 14 | @property(cc.Node) 15 | right: cc.Node = null 16 | @property([cc.Label]) 17 | currentList: cc.Label[] = [] 18 | 19 | currentIndex: number = null 20 | onLoad() { 21 | this.currentIndex = 1 22 | this.updateCurrent() 23 | } 24 | 25 | start() { 26 | this.left.on('touchstart', () => { 27 | if (this.currentIndex > 0) { 28 | this.currentIndex-- 29 | } 30 | this.updateCurrent() 31 | }) 32 | this.right.on('touchstart', () => { 33 | if (this.currentIndex < this.currentList.length - 1) { 34 | this.currentIndex++ 35 | } 36 | this.updateCurrent() 37 | }) 38 | } 39 | 40 | updateCurrent(): void { 41 | for (let item of this.currentList) { 42 | item.node.active = false 43 | } 44 | if (this.currentIndex >= 0 && this.currentIndex < this.currentList.length) { 45 | this.currentList[this.currentIndex].node.active = true 46 | } else { 47 | throw new Error('current select error: ' + this.currentIndex) 48 | } 49 | State.getInstance().layoutTypeIndex = this.currentIndex 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /assets/script/Select.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "50c83254-5025-487e-8519-90a226b1b288", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/StartLayer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-09 17:11:30 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-12 15:42:48 6 | */ 7 | const { ccclass, property } = cc._decorator 8 | import SceneMediator from './SceneMediator' 9 | 10 | @ccclass 11 | export default class StartLayer extends cc.Component { 12 | @property(cc.Node) 13 | background: cc.Node = null 14 | 15 | isTouchOnce: boolean = true 16 | 17 | start() { 18 | this.background.on('touchend', () => { 19 | if (this.isTouchOnce) { 20 | SceneMediator.getInstance().goto(0.7, undefined, 0.4, () => { 21 | this.isTouchOnce = true 22 | }) 23 | } 24 | this.isTouchOnce = false 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /assets/script/StartLayer.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "de82cf9c-a4c9-4fdb-8f8f-a1f72fb7b31e", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/State.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-11 21:08:26 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-13 12:39:03 6 | */ 7 | 8 | /** 9 | *状态管理 10 | * 11 | * 单例类 12 | * @export 13 | * @class State 14 | */ 15 | export default class State { 16 | private constructor() {} 17 | private static instance: State 18 | static getInstance(): State { 19 | this.instance = !!this.instance ? this.instance : new State() 20 | return this.instance 21 | } 22 | private _layoutTypeIndex: number = 0 23 | private _bestScore: number = 0 24 | private _isActionStop: boolean = true 25 | /** 26 | *layout类型 27 | * 28 | * @readonly 29 | * @memberof State 30 | */ 31 | get layoutTypeIndex() { 32 | return this._layoutTypeIndex 33 | } 34 | set layoutTypeIndex(value: number) { 35 | this._layoutTypeIndex = value 36 | } 37 | /** 38 | *最高分 39 | * 40 | * @memberof State 41 | */ 42 | get bestScore() { 43 | return this._bestScore 44 | } 45 | set bestScore(value: number) { 46 | this._bestScore = value 47 | } 48 | /** 49 | *是否结束过渡 50 | * 51 | * @type {boolean} 52 | * @memberof State 53 | */ 54 | get isActionStop(): boolean { 55 | return this._isActionStop 56 | } 57 | set isActionStop(isStop: boolean) { 58 | this._isActionStop = isStop 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/script/State.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "4ec7dc9e-5091-46dc-9851-34bf79b43d25", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/TouchBlock.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-02 13:06:00 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-11 22:50:07 6 | */ 7 | import TouchFront from './ITouchFront' 8 | import Layout from './ILayout' 9 | import ScoreManager from './IScoreManager' 10 | import Data from './Data' 11 | import Model from './Model' 12 | import CameraManager from './CameraManager' 13 | import State from './State' 14 | /** 15 | *建立触摸与block之间关系 16 | * 17 | * @export 18 | * @class TouchBlock 19 | */ 20 | export default class TouchBlock { 21 | /** 22 | *触摸手势api 23 | * 24 | * @private 25 | * @type {TouchFront} 26 | * @memberof TouchBlock 27 | */ 28 | private touchFront: TouchFront 29 | /** 30 | *layout绘图api 31 | * 32 | * @private 33 | * @type {Layout} 34 | * @memberof TouchBlock 35 | */ 36 | private layout: Layout 37 | /** 38 | *得分动画 39 | * 40 | * @private 41 | * @type {ScoreManager} 42 | * @memberof TouchBlock 43 | */ 44 | private scoreUpdate: ScoreManager 45 | /** 46 | *矩阵api 47 | * 48 | * @private 49 | * @type {Data} 50 | * @memberof TouchBlock 51 | */ 52 | private DataStn: Data 53 | /** 54 | *阻止弹窗 55 | * 56 | * @private 57 | * @type {boolean} 58 | * @memberof TouchBlock 59 | */ 60 | private isWinOnce: boolean 61 | /** 62 | *场景score组件label 63 | * 64 | * @private 65 | * @type {cc.Label} 66 | * @memberof TouchBlock 67 | */ 68 | private _score: cc.Label 69 | /** 70 | *最高分数 71 | * 72 | * @private 73 | * @type {cc.Label} 74 | * @memberof TouchBlock 75 | */ 76 | private _bestScore: cc.Label 77 | /** 78 | *Creates an instance of TouchBlock. 79 | * @param {TouchFront} touchFront 80 | * @param {Layout} layout 81 | * @param {cc.Label} score 82 | * @memberof TouchBlock 83 | */ 84 | constructor( 85 | touchFront: TouchFront, 86 | layout: Layout, 87 | score: cc.Label, 88 | bestScore: cc.Label, 89 | scoreManager: ScoreManager 90 | ) { 91 | this.touchFront = touchFront 92 | this.layout = layout 93 | this.scoreUpdate = scoreManager 94 | this._score = score 95 | this.isWinOnce = true 96 | this.DataStn = Data.getInstance() 97 | this._bestScore = bestScore 98 | } 99 | /** 100 | *加载触摸事件 101 | * 102 | * @memberof TouchBlock 103 | */ 104 | public load = (): void => { 105 | // 触摸手势回调 106 | this.touchFront.submit(this.left, this.right, this.up, this.down).listen() 107 | } 108 | /** 109 | *layout绘图引擎 110 | * 111 | * @private 112 | * @param {string} command 113 | * @param {number} [speed=0.2] 114 | * @memberof TouchBlock 115 | */ 116 | private layoutStep(command: string, speed: number = 0.2): void { 117 | let delta = this.DataStn.merge(command) 118 | this.layout.action( 119 | command, 120 | delta, 121 | () => { 122 | this.layout.draw(this.DataStn.data) 123 | this.testResult() 124 | }, 125 | speed 126 | ) 127 | if (this.DataStn.isChanged) { 128 | this.DataStn.addRand() 129 | } 130 | } 131 | /** 132 | *绘图任务 133 | * 134 | * @private 135 | * @memberof TouchBlock 136 | */ 137 | private left = (): void => { 138 | this.layoutStep('left') 139 | } 140 | private right = (): void => { 141 | this.layoutStep('right') 142 | } 143 | private up = (): void => { 144 | this.layoutStep('up') 145 | } 146 | private down = (): void => { 147 | this.layoutStep('down') 148 | } 149 | /** 150 | *判断结果 151 | * 152 | * @private 153 | * @memberof TouchBlock 154 | */ 155 | private testResult = (): void => { 156 | this._score.string = String(this.DataStn.score) 157 | if (State.getInstance().bestScore < Number(this._score.string)) { 158 | State.getInstance().bestScore = Number(this._score.string) 159 | this._bestScore.string = this._score.string 160 | } 161 | if (this.DataStn.updateValue) { 162 | this.scoreUpdate.play(this.DataStn.updateValue) 163 | } 164 | if (this.DataStn.result) { 165 | if (this.isWinOnce) { 166 | this.gameEnd() 167 | this.isWinOnce = !this.isWinOnce 168 | } 169 | this._score.string = String(this.DataStn.score - 1) 170 | } else if (this.DataStn.isFull) { 171 | if (!this.DataStn.hasTwice) { 172 | this._score.string = String(this.DataStn.score) 173 | this.gameEnd() 174 | } 175 | } 176 | } 177 | /** 178 | *游戏结果 179 | * 180 | * @private 181 | * @memberof TouchBlock 182 | */ 183 | private gameEnd = (): void => { 184 | let end = Model.getInstance().getPreLayout() 185 | if (end !== null) { 186 | end.setParent(CameraManager.getInstance().CurrentLayer) 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /assets/script/TouchBlock.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "a6238d4a-f7a0-4e97-baaf-ad4d4450b279", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /assets/script/TouchFront.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: AK-12 3 | * @Date: 2018-11-01 13:31:42 4 | * @Last Modified by: AK-12 5 | * @Last Modified time: 2018-11-09 21:38:08 6 | */ 7 | import ITouchFront from './ITouchFront' 8 | /** 9 | *触摸方向执行对应回调 10 | * 11 | * 接口类 12 | * @export 13 | * @class TouchFront 14 | * @implements {ITouchFront} 15 | */ 16 | export default class TouchFront implements ITouchFront { 17 | private node: cc.Node 18 | private offset: number 19 | private delta: number 20 | private _lock: number 21 | 22 | private callbackLeft: Function 23 | private callbackRight: Function 24 | private callbackUp: Function 25 | private callbackDown: Function 26 | 27 | /** 28 | *Creates an instance of TouchFront. 29 | * @param {cc.Node} node 监听节点 30 | * @param {number} [offset=100] 触摸偏移 ? 100 31 | * @param {number} [delta=200] 灵敏度 ? 200 32 | * @memberof TouchFront 33 | */ 34 | constructor(node: cc.Node, offset: number = 100, delta: number = 200) { 35 | this.node = node 36 | this.offset = offset 37 | this._lock = 0 38 | this.delta = delta 39 | } 40 | public submit = ( 41 | callbackLeft?: Function, 42 | callbackRight?: Function, 43 | callbackUp?: Function, 44 | callbackDown?: Function 45 | ): TouchFront => { 46 | this.callbackLeft = callbackLeft 47 | this.callbackRight = callbackRight 48 | this.callbackUp = callbackUp 49 | this.callbackDown = callbackDown 50 | return this 51 | } 52 | /** 53 | *监听触摸 54 | * 55 | * @memberof TouchFront 56 | */ 57 | public listen = (): void => { 58 | let originPos: cc.Vec2 59 | this.node.on( 60 | cc.Node.EventType.TOUCH_START, 61 | touch => (originPos = touch.getLocation()) 62 | ) 63 | this.node.on(cc.Node.EventType.TOUCH_MOVE, touch => { 64 | this._lock++ 65 | }) 66 | this.node.on(cc.Node.EventType.TOUCH_END, touch => { 67 | this._lock < this.delta 68 | ? this.testPos(originPos, touch.getLocation()) 69 | : null 70 | this._lock = 0 71 | }) 72 | this.node.on(cc.Node.EventType.TOUCH_CANCEL, touch => { 73 | this._lock < this.delta 74 | ? this.testPos(originPos, touch.getLocation()) 75 | : null 76 | this._lock = 0 77 | }) 78 | } 79 | /** 80 | *检测偏移执行回调 81 | * 82 | * @private 83 | * @memberof TouchFront 84 | */ 85 | private testPos = (originPos: cc.Vec2, touchPos: cc.Vec2): void => { 86 | if ( 87 | Math.abs(touchPos.x - originPos.x) < this.offset && 88 | Math.abs(touchPos.y - originPos.y) < this.offset 89 | ) { 90 | return 91 | } 92 | if ( 93 | Math.abs(touchPos.x - originPos.x) > Math.abs(touchPos.y - originPos.y) 94 | ) { 95 | if (touchPos.x - originPos.x > this.offset) { 96 | !!this.callbackRight ? this.callbackRight() : null 97 | } else if (touchPos.x - originPos.x < -this.offset) { 98 | !!this.callbackLeft ? this.callbackLeft() : null 99 | } 100 | } else { 101 | if (touchPos.y - originPos.y > this.offset) { 102 | !!this.callbackUp ? this.callbackUp() : null 103 | } else if (touchPos.y - originPos.y < -this.offset) { 104 | !!this.callbackDown ? this.callbackDown() : null 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /assets/script/TouchFront.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "90bc9070-5b34-4bd7-885e-04d5d6655a20", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "experimentalDecorators": true 6 | }, 7 | "exclude": [ 8 | "node_modules", 9 | ".vscode", 10 | "library", 11 | "local", 12 | "settings", 13 | "temp" 14 | ] 15 | } -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "engine": "cocos-creator-js", 3 | "packages": "packages" 4 | } -------------------------------------------------------------------------------- /settings/builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "android-instant": { 3 | "REMOTE_SERVER_ROOT": "", 4 | "host": "", 5 | "pathPattern": "", 6 | "recordPath": "", 7 | "scheme": "https", 8 | "skipRecord": false 9 | }, 10 | "appKey": "", 11 | "appSecret": "", 12 | "encryptJs": true, 13 | "excludeScenes": [], 14 | "fb-instant-games": {}, 15 | "includeAnySDK": false, 16 | "includeSDKBox": false, 17 | "inlineSpriteFrames": true, 18 | "inlineSpriteFrames_native": true, 19 | "jailbreakPlatform": false, 20 | "md5Cache": false, 21 | "mergeStartScene": false, 22 | "oauthLoginServer": "", 23 | "optimizeHotUpdate": false, 24 | "orientation": { 25 | "landscapeLeft": true, 26 | "landscapeRight": true, 27 | "portrait": false, 28 | "upsideDown": false 29 | }, 30 | "packageName": "org.cocos2d.2048", 31 | "privateKey": "", 32 | "qqplay": { 33 | "REMOTE_SERVER_ROOT": "", 34 | "orientation": "portrait" 35 | }, 36 | "startScene": "4e03d127-8535-47c2-895c-e46afd9a437f", 37 | "title": "2048", 38 | "webOrientation": "portrait", 39 | "wechatgame": { 40 | "REMOTE_SERVER_ROOT": "", 41 | "appid": "wx6ac3f5090a6b99c5", 42 | "isSubdomain": false, 43 | "orientation": "portrait", 44 | "subContext": "" 45 | }, 46 | "xxteaKey": "5dff32d4-a1e2-45", 47 | "zipCompressJs": true 48 | } -------------------------------------------------------------------------------- /settings/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "cocos-analytics": { 3 | "appID": "13798", 4 | "appSecret": "959b3ac0037d0f3c2fdce94f8421a9b2", 5 | "channel": "", 6 | "enable": false, 7 | "version": "" 8 | }, 9 | "collision-matrix": [ 10 | [ 11 | true 12 | ] 13 | ], 14 | "design-resolution-height": 800, 15 | "design-resolution-width": 480, 16 | "excluded-modules": [], 17 | "fit-height": true, 18 | "fit-width": true, 19 | "group-list": [ 20 | "default" 21 | ], 22 | "simulator-orientation": false, 23 | "simulator-resolution": { 24 | "height": 640, 25 | "width": 960 26 | }, 27 | "start-scene": "f24ddf68-0c90-4744-8299-10d2b32caf2f", 28 | "use-customize-simulator": false, 29 | "use-project-simulator-setting": false 30 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "lib": [ "dom", "es5", "es2015.promise" ], 5 | "target": "es5", 6 | "experimentalDecorators": true, 7 | "skipLibCheck": true 8 | }, 9 | "exclude": [ 10 | "node_modules", 11 | "library", 12 | "local", 13 | "temp", 14 | "build", 15 | "settings" 16 | ] 17 | } --------------------------------------------------------------------------------