├── .gitignore ├── README.md ├── assets ├── Scene.meta ├── Scene │ ├── helloworld.fire │ └── helloworld.fire.meta ├── Script.meta ├── Script │ ├── controllers.meta │ ├── controllers │ │ ├── AbstractController.js │ │ ├── AbstractController.js.meta │ │ ├── HelloController.js │ │ ├── HelloController.js.meta │ │ ├── MainController.js │ │ └── MainController.js.meta │ ├── decorators.meta │ ├── decorators │ │ ├── CCClass.meta │ │ ├── CCClass │ │ │ ├── CCClass1.3.js │ │ │ ├── CCClass1.3.js.meta │ │ │ ├── CCClass1.4.js │ │ │ └── CCClass1.4.js.meta │ │ ├── ComponentDecorators.js │ │ └── ComponentDecorators.js.meta │ ├── libs.meta │ ├── libs │ │ ├── i18n.meta │ │ └── i18n │ │ │ ├── LabelLocalized.js │ │ │ ├── LabelLocalized.js.meta │ │ │ ├── data.meta │ │ │ ├── data │ │ │ ├── en.js │ │ │ ├── en.js.meta │ │ │ ├── zh.js │ │ │ └── zh.js.meta │ │ │ ├── i18n.js │ │ │ ├── i18n.js.meta │ │ │ ├── polyglot.js │ │ │ └── polyglot.js.meta │ ├── models.meta │ ├── models │ │ ├── AbstractModel.js │ │ ├── AbstractModel.js.meta │ │ ├── HelloModel.js │ │ └── HelloModel.js.meta │ ├── plugins.meta │ ├── plugins │ │ ├── Fetch.js │ │ ├── Fetch.js.meta │ │ ├── TypeScriptHelper.js │ │ └── TypeScriptHelper.js.meta │ ├── views.meta │ └── views │ │ ├── AbstractComponent.js │ │ ├── AbstractComponent.js.meta │ │ ├── AbstractSimpleComponent.js │ │ ├── AbstractSimpleComponent.js.meta │ │ ├── HelloView.js │ │ └── HelloView.js.meta ├── Texture.meta └── Texture │ ├── HelloWorld.png │ ├── HelloWorld.png.meta │ ├── singleColor.png │ └── singleColor.png.meta ├── creator.d.ts ├── jsconfig.json ├── package.json ├── project.json ├── settings ├── builder.json ├── builder.panel.json └── project.json ├── tsconfig.json └── typescript ├── controllers ├── AbstractController.ts └── HelloController.ts ├── decorators ├── CCClass │ ├── CCClass1.3.js │ └── CCClass1.4.js └── ComponentDecorators.ts ├── libs └── i18n │ ├── LabelLocalized.ts │ ├── Readme.md │ ├── data │ ├── en.ts │ └── zh.ts │ ├── i18n.ts │ └── polyglot.js ├── models ├── AbstractModel.ts └── HelloModel.ts ├── plugins ├── Fetch.js └── TypeScriptHelper.js ├── types ├── GlobalNameSpace.d.ts ├── models │ └── HelloModel.d.ts └── plugins │ └── Fetch.d.ts └── views ├── AbstractComponent.ts ├── AbstractSimpleComponent.ts └── HelloView.ts /.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Creator-TypeScript-Boilerplate 2 | 在Cocos Creator中使用TypeScript的示例项目。 3 | ## 环境搭建 4 |         此项目已经在Creator 1.3.2, 1.3.3-beta1, 1.4.0-beta1, 1.4.0-beta2中测试运行正常(Chrome与Windows模拟器下),直接打开即可运行。但是如果你需要更改TypeScript代码,还需要以下步骤搭建运行环境。如果你需要在自己的项目中使用TypeScript,请务必备份好自己的项目,并阅读文末的“注意事项”。 5 | 1. 克隆或下载解压此项目至本地目录(假设为project)。 6 | 2. 安装nodejs, npm(国内用户推荐使用cnpm,https://npm.taobao.org/)。 7 | 3. 命令行中运行该命令全局安装TypeScript: `cnpm install typescript -g`。 8 | 4. 在IDE(如WebStorm)中开启TypeScript自动编译功能(WebStorm开启方法:File->Settings->Languages & Frameworks->TypeScript,右边 勾选Use TypeScript Service与Enable TypeScript Compiler)。若你使用的IDE无此功能(如Visual Studio Code),使用命令行进入project目录并运行`tsc -w`使TypeScript自动监视文件修改并自动编译。   9 | 5. 在project/typescript目录下编辑你的代码,它们将被自动编译至project/assets/Script/目录下(在project/tsconfig.json中修改outDir字段以更改目标目录)。   10 | 11 | > 此项目需要TypeScript 2.1或以上的版本。~~如果你使用的是Visual Studio Code,它最新版自带的TypeScript版本为2.0.10。你需要用命令行进行project目录并运行`cnpm install typescript -S`来在项目文件夹中安装最新版的TypeScript(当前为2.1.4),并在关闭Visual Studio Code,重新打开project时,在弹出的TypeScript版本提示框中选择使用项目目录的新版TypeScript。~~Visual Studio Code 1.8自带的TypeScript版本已经是2.1了。   12 | 13 | ## 功能介绍 14 |         为了简单展示TypeScript的功能,此项目使用TypeScript的类与泛型功能实现了一个简单的MVC架构(请看AbstractController, AbstractModel与AbstractComponent三个类),并在此之上实现了Hello模块(请看HelloController, HelloModel与HelloView),实现了使用async, await异步使用fetch请求本机IP并查询IP对应的国家、城市、区域的功能。(数据是向我的一个快要废弃的服务器请求的,只是为了展示怎样使用async, await, fetch进行网络请求,可能随时停用导致请求不到数据。) 15 | >不需要Controller和Model的View直接继承AbstractSimpleComponent即可。 16 | 17 | >已集成了Fetch的Polyfill。Fetch的使用请参考:[MDN Fetch文档](https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch)   18 | 19 | ## 使用说明 20 |         为了充分利用TypeScript,请不要使用cc.Class来创建类,而应充分使用class, extends, implements等关键字来定义和扩展类。并使用import关键字取代require()来导入模块,export关键字取代module.exports来导出模块。 21 | >小提示:使用export而不是export default,从而在IDE中获得更好的重构体验(如在WebStrom中使用export时,对导出的模块重命名也会重命名其它文件中该模块的名字,而export default不会)。 22 | 23 |         另外,import from后面的路径需要是完整的相对路径而不像require()只需要文件名。 24 | >如果你使用WebStorm等较为智能的IDE,完整路径并不会成为问题,反而能让你一眼明白文件的位置。例如在WebStorm中,你只需要在编辑器中打出想引入的类名的前几个字符,IDE会自动提示出完整的类名,当你选中正确的类名并回车后,完整的import from路径会自动添加到文件头。你甚至不用自己写任何一行import。 25 | 26 |         有一种特殊情况是,继承自cc.Component的类(在Creator中可以拖到节点属性编辑器上的脚本)是无法用TypeScript的extends cc.Component关键字来实现的,因为cc.Class内部还会做一些额外的工作。 27 |         为了解决此问题,你需要使用project/typescript/decorators/ComponentDecorators.ts中提供的四个装饰器:@CCComponent, @CCEditor, @CCProperty, @CCMixins(除了@CCComponent外其它装饰器对于一个Component来说都是可选的)。   28 | 29 | 一个简单的Component定义像这样:![简单Component示例](http://forum.cocos.com//uploads/default/original/2X/5/54eb817d45a898229c686cf903e610f122f72814.gif) 30 | 四个装饰器完整的使用方法如下,熟悉cc.Class()函数的童鞋应该一眼就能认出对应的功能:   31 | ```js 32 | // ComplicateComponent.ts: 33 | import {CCComponent, CCEditor, CCProperty, CCMixins} from "../decorators/ComponentDecorators"; 34 | // 不使用Mixin功能的童鞋请忽略这个import 35 | import {mixin1, mixin2, mixin3} from "./Mixins"; 36 | // 定义该Component的Editor属性,对应JS中传入cc.Class()的editor参数。 37 | @CCEditor({ 38 |   executeInEditMode: true 39 | }) 40 | // 将某个类转换为Creator可识别的Component 41 | @CCComponent 42 | // 定义该Component的Mixin(如果不知道什么是Mixin或不使用Mixin的,请忽略该装饰器)。 43 | // 注意:@CCMixins装饰器必须先于@CCComponent使用(即写在@CCComponent下面,更靠近类的定义的地方)。 44 | // 注意:每个Mixin作为@CCMixins装饰器的一个参数传入,而非传入一个Mixin数组。 45 | @CCMixins(mixin1, mixin2, mixin3) 46 | export class ComplicateComponent extends cc.Component { 47 |   // 定义一个Component属性,对应JS中传入cc.Class()的properties字段的参数。 48 |   @CCProperty(cc.Label) 49 | private someLabel: cc.Label; 50 | @CCProperty({ 51 | default: 1, 52 | min: 1, 53 | max: 10, 54 | step: 1, 55 | notify() { 56 | this.updateLabel(); 57 | } 58 | }) 59 | private someInteger: number; 60 | 61 | public onLoad() { 62 | this.someInteger = 5; 63 | } 64 | 65 | private updateLabel() { 66 | this.someLabel.string = this.someInteger + ""; 67 | } 68 | } 69 | ``` 70 | 71 | ## 注意事项(请在开始之前仔细阅读本节)   72 | 1. 需要重命名或移动某个代码文件时,请**务必**先在Creator中先重命名或移动assets下的js文件,再同样操作typescript目录下的ts文件(最好在WebStorm下进行ts文件的重命名、移动等操作,它会自动修正其它文件中对该文件的import)。因为当你在Creator中移动js文件的时候,Creator会自动修正所有场景和prefab中对该js文件的引用。 73 | >一个典型的错误是:你先在typesciprt目录下移动了ts文件,这个ts文件会被自动编译为assets目录的对应新路径下的js文件,但是同时assets中的旧的js文件依旧存在。Creator会报文件重复的错误。这时如果你简单地删掉旧js文件,所有引用旧js文件的场景和prefab都会丢失这个引用。 74 | 75 | 2. 只有在需要声明Component的时候,才使用@CCComponent等装饰器。其它类不需要使用@CCComponent。 76 | 3. TypeScript的类型声明文件请使用.d.ts后缀。以.d.ts为后缀的文件只会被TypeScript用作代码提示和检查,不会编译到assets目录下。所有的类型声明文件建议统一放到typescript/types目录下。 77 | 78 | >用.ts作文件后缀也可以写类型声明,但是会编译一个空文件到assets目录下。 79 | 80 | 4. 可以在typescript/types目录下的GlobalNameSpace.d.ts中定义全局变量的类型,但是注意不要改动第一行的: 81 | 82 | /// 83 | 正是这一行引入了Creator自带的creator.d.ts。 84 | 5. 此项目的creator.d.ts被做了一些修正,以提供更好的代码提示。例如getComponent()的函数签名被改为: 85 | 86 | // 如果传入的参数是一个newable的类,则返回该类的实例 87 | getComponent(typeOrClassName: (new()=>T)): T; 88 | // 函数重载,如果传入的参数是string则返回any 89 | getComponent(typeOrClassName: string): any; 90 | 这样如果你传入getComponent()的是一个类(注意不是字符串形式的类名),TypeScript就会知道返回的是这个类的实例。这样你在IDE中输入`this.getComponent(cc.Graphics).`的时候,IDE会自动提示出cc.Graphics的方法。该功能也适用于任何自定义的Component,例如:![getComponent示例](http://forum.cocos.com/uploads/default/original/2X/b/b855b64b4957fe865234a3103f3d5b9772e95542.gif) 91 | 6. 文件重命名、类重命名、变量重命名、方法重命名,请统统使用IDE的重构功能。WebStorm中重命名的快捷键是Shift+F6,或者右击文件、类名、变量名、方法名,弹出的菜单中选择refactor->rename。因为TypeScript对你的代码结构有着非常好的了解,所有IDE可以正确地修改所有对重命名对象的引用。例如:![Refactor示例](http://forum.cocos.com/uploads/default/original/2X/c/c48fc71257f6e59c07110b1768af184580de736e.gif) 92 | 从此再也不用担心变量命名啦!先写完再说,哪里不爽改哪里!   93 | > 注意:若你正在将项目的js代码升级为ts,在升级完成前请慎用重构功能。因为此时TypeScript对你的代码了解不完全,IDE有可能发生错误重构,例如上例中有可能将`B.t`也命名为`B.tt`。所有代码转换为ts之后,我还没有发现过WebStorm有重构错误。 94 | 95 | 7. assets/Script/plugins下的文件请保持在Creator中设置为插件的状态。 96 | 8. Component的四个装饰器的实现依赖引擎CCClass.js中的两个函数,但是当前cc.Class没有将这两个方法暴露出来,因此我只好将引擎的CCClass拷贝一份到decorators目录下简单修改并export这两个方法(分了1.3和1.4两个版本)。Jare大神已经同意在Creator 1.5中暴露出这两个方法或类似API,到时就不用再集成一次CCClass了。 97 | 98 | ## 将已有的JS项目升级为TS 99 | 0. 在决定开始之前,请先备份好你的项目! 100 | 1. TypeScript环境搭建(见开头“环境搭建”部分) 101 | 2. 将此项目的creator.d.ts与tsconfig.json拷贝至你的项目根目录。 102 | 3. 在你的项目根目录下新建typescript目录,拷贝assets中的所有js代码至typescript目录。 103 | 4. 将此项目的typescript/decorators目录复制到你的typescript目录。 104 | 5. 将此项目的typescript/plugins/TypeScriptHelper.js复制到你的typescript目录,***并在编译到assets目录后在Creator中将该文件设置为插件!*** 这是TypeScript的“运行库”。 105 | 6. 如果需要在原生平台使用Promise和Fetch,还需要将此项目的typescript/plugins/Fetch.js复制到你的typescript目录,***并在编译到assets目录后在Creator中将该文件设置为插件!*** 106 | 7. 将typescript目录下你的代码全部重命名为.ts。然后使用import代替require,用export代替module.exports,用ES6的class代替cc.Class,用@CCComponent, @CCProperty, @CCEditor来实现你的Component。   107 | 108 | ## 参考资料 109 | [TypeScript文档](http://tslang.cn/docs/handbook/basic-types.html) 110 | [TypeScript编译选项](http://tslang.cn/docs/handbook/compiler-options.html) 111 | [MDN Promise文档](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise) 112 | [MDN Fetch文档](https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch) 113 | -------------------------------------------------------------------------------- /assets/Scene.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "29f52784-2fca-467b-92e7-8fd9ef8c57b7", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Scene/helloworld.fire: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.SceneAsset", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_rawFiles": null, 7 | "scene": { 8 | "__id__": 1 9 | } 10 | }, 11 | { 12 | "__type__": "cc.Scene", 13 | "_objFlags": 0, 14 | "_opacity": 255, 15 | "_color": { 16 | "__type__": "cc.Color", 17 | "r": 255, 18 | "g": 255, 19 | "b": 255, 20 | "a": 255 21 | }, 22 | "_cascadeOpacityEnabled": true, 23 | "_parent": null, 24 | "_anchorPoint": { 25 | "__type__": "cc.Vec2", 26 | "x": 0, 27 | "y": 0 28 | }, 29 | "_contentSize": { 30 | "__type__": "cc.Size", 31 | "width": 0, 32 | "height": 0 33 | }, 34 | "_children": [ 35 | { 36 | "__id__": 2 37 | } 38 | ], 39 | "_localZOrder": 0, 40 | "_globalZOrder": 0, 41 | "_tag": -1, 42 | "_opacityModifyRGB": false, 43 | "_id": "2d2f792f-a40c-49bb-a189-ed176a246e49", 44 | "autoReleaseAssets": false 45 | }, 46 | { 47 | "__type__": "cc.Node", 48 | "_name": "Canvas", 49 | "_objFlags": 0, 50 | "_opacity": 255, 51 | "_color": { 52 | "__type__": "cc.Color", 53 | "r": 252, 54 | "g": 252, 55 | "b": 252, 56 | "a": 255 57 | }, 58 | "_cascadeOpacityEnabled": true, 59 | "_parent": { 60 | "__id__": 1 61 | }, 62 | "_anchorPoint": { 63 | "__type__": "cc.Vec2", 64 | "x": 0.5, 65 | "y": 0.5 66 | }, 67 | "_contentSize": { 68 | "__type__": "cc.Size", 69 | "width": 960, 70 | "height": 640 71 | }, 72 | "_children": [ 73 | { 74 | "__id__": 3 75 | }, 76 | { 77 | "__id__": 6 78 | }, 79 | { 80 | "__id__": 8 81 | }, 82 | { 83 | "__id__": 10 84 | }, 85 | { 86 | "__id__": 12 87 | }, 88 | { 89 | "__id__": 14 90 | } 91 | ], 92 | "_rotationX": 0, 93 | "_rotationY": 0, 94 | "_scaleX": 1, 95 | "_scaleY": 1, 96 | "_position": { 97 | "__type__": "cc.Vec2", 98 | "x": 480, 99 | "y": 320 100 | }, 101 | "_skewX": 0, 102 | "_skewY": 0, 103 | "_localZOrder": 0, 104 | "_globalZOrder": 0, 105 | "_tag": -1, 106 | "_opacityModifyRGB": false, 107 | "_id": "a286bbGknJLZpRpxROV6M94", 108 | "_active": true, 109 | "_components": [ 110 | { 111 | "__id__": 16 112 | }, 113 | { 114 | "__id__": 17 115 | } 116 | ], 117 | "_prefab": null, 118 | "groupIndex": 0 119 | }, 120 | { 121 | "__type__": "cc.Node", 122 | "_name": "background", 123 | "_objFlags": 0, 124 | "_opacity": 255, 125 | "_color": { 126 | "__type__": "cc.Color", 127 | "r": 27, 128 | "g": 38, 129 | "b": 46, 130 | "a": 255 131 | }, 132 | "_cascadeOpacityEnabled": true, 133 | "_parent": { 134 | "__id__": 2 135 | }, 136 | "_anchorPoint": { 137 | "__type__": "cc.Vec2", 138 | "x": 0.5, 139 | "y": 0.5 140 | }, 141 | "_contentSize": { 142 | "__type__": "cc.Size", 143 | "width": 960, 144 | "height": 640 145 | }, 146 | "_children": [], 147 | "_rotationX": 0, 148 | "_rotationY": 0, 149 | "_scaleX": 1, 150 | "_scaleY": 1, 151 | "_position": { 152 | "__type__": "cc.Vec2", 153 | "x": 0, 154 | "y": 0 155 | }, 156 | "_skewX": 0, 157 | "_skewY": 0, 158 | "_localZOrder": 0, 159 | "_globalZOrder": 0, 160 | "_tag": -1, 161 | "_opacityModifyRGB": false, 162 | "_id": "e2e0crkOLxGrpMxpbC4iQg1", 163 | "_active": true, 164 | "_components": [ 165 | { 166 | "__id__": 4 167 | }, 168 | { 169 | "__id__": 5 170 | } 171 | ], 172 | "_prefab": null, 173 | "groupIndex": 0 174 | }, 175 | { 176 | "__type__": "cc.Widget", 177 | "_name": "", 178 | "_objFlags": 0, 179 | "node": { 180 | "__id__": 3 181 | }, 182 | "_enabled": true, 183 | "isAlignOnce": true, 184 | "_alignFlags": 45, 185 | "_left": 0, 186 | "_right": 0, 187 | "_top": 0, 188 | "_bottom": 0, 189 | "_verticalCenter": 0, 190 | "_horizontalCenter": 0, 191 | "_isAbsLeft": true, 192 | "_isAbsRight": true, 193 | "_isAbsTop": true, 194 | "_isAbsBottom": true, 195 | "_isAbsHorizontalCenter": true, 196 | "_isAbsVerticalCenter": true, 197 | "_originalWidth": 200, 198 | "_originalHeight": 150 199 | }, 200 | { 201 | "__type__": "cc.Sprite", 202 | "_name": "", 203 | "_objFlags": 0, 204 | "node": { 205 | "__id__": 3 206 | }, 207 | "_enabled": true, 208 | "_spriteFrame": { 209 | "__uuid__": "410fb916-8721-4663-bab8-34397391ace7" 210 | }, 211 | "_type": 1, 212 | "_sizeMode": 0, 213 | "_fillType": 0, 214 | "_fillCenter": { 215 | "__type__": "cc.Vec2", 216 | "x": 0, 217 | "y": 0 218 | }, 219 | "_fillStart": 0, 220 | "_fillRange": 0, 221 | "_isTrimmedMode": true, 222 | "_srcBlendFactor": 770, 223 | "_dstBlendFactor": 771, 224 | "_atlas": null 225 | }, 226 | { 227 | "__type__": "cc.Node", 228 | "_name": "cocos", 229 | "_objFlags": 0, 230 | "_opacity": 255, 231 | "_color": { 232 | "__type__": "cc.Color", 233 | "r": 255, 234 | "g": 255, 235 | "b": 255, 236 | "a": 255 237 | }, 238 | "_cascadeOpacityEnabled": true, 239 | "_parent": { 240 | "__id__": 2 241 | }, 242 | "_anchorPoint": { 243 | "__type__": "cc.Vec2", 244 | "x": 0.5, 245 | "y": 0.5 246 | }, 247 | "_contentSize": { 248 | "__type__": "cc.Size", 249 | "width": 195, 250 | "height": 270 251 | }, 252 | "_children": [], 253 | "_rotationX": 0, 254 | "_rotationY": 0, 255 | "_scaleX": 1, 256 | "_scaleY": 1, 257 | "_position": { 258 | "__type__": "cc.Vec2", 259 | "x": 0, 260 | "y": 50 261 | }, 262 | "_skewX": 0, 263 | "_skewY": 0, 264 | "_localZOrder": 0, 265 | "_globalZOrder": 0, 266 | "_tag": -1, 267 | "_opacityModifyRGB": false, 268 | "_id": "c4f30YOS65G64U2TwufdJ+2", 269 | "_active": true, 270 | "_components": [ 271 | { 272 | "__id__": 7 273 | } 274 | ], 275 | "_prefab": null, 276 | "groupIndex": 0 277 | }, 278 | { 279 | "__type__": "cc.Sprite", 280 | "_name": "", 281 | "_objFlags": 0, 282 | "node": { 283 | "__id__": 6 284 | }, 285 | "_enabled": true, 286 | "_spriteFrame": { 287 | "__uuid__": "31bc895a-c003-4566-a9f3-2e54ae1c17dc" 288 | }, 289 | "_type": 0, 290 | "_sizeMode": 1, 291 | "_fillType": 0, 292 | "_fillCenter": { 293 | "__type__": "cc.Vec2", 294 | "x": 0, 295 | "y": 0 296 | }, 297 | "_fillStart": 0, 298 | "_fillRange": 0, 299 | "_isTrimmedMode": true, 300 | "_srcBlendFactor": 770, 301 | "_dstBlendFactor": 771, 302 | "_atlas": null 303 | }, 304 | { 305 | "__type__": "cc.Node", 306 | "_name": "ipLabel", 307 | "_objFlags": 0, 308 | "_opacity": 255, 309 | "_color": { 310 | "__type__": "cc.Color", 311 | "r": 255, 312 | "g": 255, 313 | "b": 255, 314 | "a": 255 315 | }, 316 | "_cascadeOpacityEnabled": true, 317 | "_parent": { 318 | "__id__": 2 319 | }, 320 | "_anchorPoint": { 321 | "__type__": "cc.Vec2", 322 | "x": 0.5, 323 | "y": 0.5 324 | }, 325 | "_contentSize": { 326 | "__type__": "cc.Size", 327 | "width": 0, 328 | "height": 60 329 | }, 330 | "_children": [], 331 | "_rotationX": 0, 332 | "_rotationY": 0, 333 | "_scaleX": 1, 334 | "_scaleY": 1, 335 | "_position": { 336 | "__type__": "cc.Vec2", 337 | "x": 0, 338 | "y": -128 339 | }, 340 | "_skewX": 0, 341 | "_skewY": 0, 342 | "_localZOrder": 0, 343 | "_globalZOrder": 0, 344 | "_tag": -1, 345 | "_opacityModifyRGB": false, 346 | "_id": "31f1bH7V69Ajr1iXhluMpTB", 347 | "_active": true, 348 | "_components": [ 349 | { 350 | "__id__": 9 351 | } 352 | ], 353 | "_prefab": null, 354 | "groupIndex": 0 355 | }, 356 | { 357 | "__type__": "cc.Label", 358 | "_name": "", 359 | "_objFlags": 0, 360 | "node": { 361 | "__id__": 8 362 | }, 363 | "_enabled": true, 364 | "_useOriginalSize": false, 365 | "_actualFontSize": 60, 366 | "_fontSize": 60, 367 | "_lineHeight": 60, 368 | "_enableWrapText": true, 369 | "_N$file": null, 370 | "_isSystemFontUsed": true, 371 | "_N$string": "", 372 | "_N$horizontalAlign": 1, 373 | "_N$verticalAlign": 1, 374 | "_N$overflow": 0 375 | }, 376 | { 377 | "__type__": "cc.Node", 378 | "_name": "countryLabel", 379 | "_objFlags": 0, 380 | "_opacity": 255, 381 | "_color": { 382 | "__type__": "cc.Color", 383 | "r": 255, 384 | "g": 255, 385 | "b": 255, 386 | "a": 255 387 | }, 388 | "_cascadeOpacityEnabled": true, 389 | "_parent": { 390 | "__id__": 2 391 | }, 392 | "_anchorPoint": { 393 | "__type__": "cc.Vec2", 394 | "x": 0.5, 395 | "y": 0.5 396 | }, 397 | "_contentSize": { 398 | "__type__": "cc.Size", 399 | "width": 0, 400 | "height": 30 401 | }, 402 | "_children": [], 403 | "_rotationX": 0, 404 | "_rotationY": 0, 405 | "_scaleX": 1, 406 | "_scaleY": 1, 407 | "_position": { 408 | "__type__": "cc.Vec2", 409 | "x": -300, 410 | "y": -210 411 | }, 412 | "_skewX": 0, 413 | "_skewY": 0, 414 | "_localZOrder": 0, 415 | "_globalZOrder": 0, 416 | "_tag": -1, 417 | "_opacityModifyRGB": false, 418 | "_id": "4c2b8TONepJHoUymnef8WDD", 419 | "_active": true, 420 | "_components": [ 421 | { 422 | "__id__": 11 423 | } 424 | ], 425 | "_prefab": null, 426 | "groupIndex": 0 427 | }, 428 | { 429 | "__type__": "cc.Label", 430 | "_name": "", 431 | "_objFlags": 0, 432 | "node": { 433 | "__id__": 10 434 | }, 435 | "_enabled": true, 436 | "_useOriginalSize": false, 437 | "_actualFontSize": 30, 438 | "_fontSize": 30, 439 | "_lineHeight": 30, 440 | "_enableWrapText": true, 441 | "_N$file": null, 442 | "_isSystemFontUsed": true, 443 | "_N$string": "", 444 | "_N$horizontalAlign": 1, 445 | "_N$verticalAlign": 1, 446 | "_N$overflow": 0 447 | }, 448 | { 449 | "__type__": "cc.Node", 450 | "_name": "cityLabel", 451 | "_objFlags": 0, 452 | "_opacity": 255, 453 | "_color": { 454 | "__type__": "cc.Color", 455 | "r": 255, 456 | "g": 255, 457 | "b": 255, 458 | "a": 255 459 | }, 460 | "_cascadeOpacityEnabled": true, 461 | "_parent": { 462 | "__id__": 2 463 | }, 464 | "_anchorPoint": { 465 | "__type__": "cc.Vec2", 466 | "x": 0.5, 467 | "y": 0.5 468 | }, 469 | "_contentSize": { 470 | "__type__": "cc.Size", 471 | "width": 0, 472 | "height": 30 473 | }, 474 | "_children": [], 475 | "_rotationX": 0, 476 | "_rotationY": 0, 477 | "_scaleX": 1, 478 | "_scaleY": 1, 479 | "_position": { 480 | "__type__": "cc.Vec2", 481 | "x": 0, 482 | "y": -210 483 | }, 484 | "_skewX": 0, 485 | "_skewY": 0, 486 | "_localZOrder": 0, 487 | "_globalZOrder": 0, 488 | "_tag": -1, 489 | "_opacityModifyRGB": false, 490 | "_id": "85b24udfBNBsrQcKGNHdP6d", 491 | "_active": true, 492 | "_components": [ 493 | { 494 | "__id__": 13 495 | } 496 | ], 497 | "_prefab": null, 498 | "groupIndex": 0 499 | }, 500 | { 501 | "__type__": "cc.Label", 502 | "_name": "", 503 | "_objFlags": 0, 504 | "node": { 505 | "__id__": 12 506 | }, 507 | "_enabled": true, 508 | "_useOriginalSize": false, 509 | "_actualFontSize": 30, 510 | "_fontSize": 30, 511 | "_lineHeight": 30, 512 | "_enableWrapText": true, 513 | "_N$file": null, 514 | "_isSystemFontUsed": true, 515 | "_N$string": "", 516 | "_N$horizontalAlign": 1, 517 | "_N$verticalAlign": 1, 518 | "_N$overflow": 0 519 | }, 520 | { 521 | "__type__": "cc.Node", 522 | "_name": "countyLabel", 523 | "_objFlags": 0, 524 | "_opacity": 255, 525 | "_color": { 526 | "__type__": "cc.Color", 527 | "r": 255, 528 | "g": 255, 529 | "b": 255, 530 | "a": 255 531 | }, 532 | "_cascadeOpacityEnabled": true, 533 | "_parent": { 534 | "__id__": 2 535 | }, 536 | "_anchorPoint": { 537 | "__type__": "cc.Vec2", 538 | "x": 0.5, 539 | "y": 0.5 540 | }, 541 | "_contentSize": { 542 | "__type__": "cc.Size", 543 | "width": 0, 544 | "height": 30 545 | }, 546 | "_children": [], 547 | "_rotationX": 0, 548 | "_rotationY": 0, 549 | "_scaleX": 1, 550 | "_scaleY": 1, 551 | "_position": { 552 | "__type__": "cc.Vec2", 553 | "x": 300, 554 | "y": -210 555 | }, 556 | "_skewX": 0, 557 | "_skewY": 0, 558 | "_localZOrder": 0, 559 | "_globalZOrder": 0, 560 | "_tag": -1, 561 | "_opacityModifyRGB": false, 562 | "_id": "dc233rFgqpEd7J3xnTZXFKM", 563 | "_active": true, 564 | "_components": [ 565 | { 566 | "__id__": 15 567 | } 568 | ], 569 | "_prefab": null, 570 | "groupIndex": 0 571 | }, 572 | { 573 | "__type__": "cc.Label", 574 | "_name": "", 575 | "_objFlags": 0, 576 | "node": { 577 | "__id__": 14 578 | }, 579 | "_enabled": true, 580 | "_useOriginalSize": false, 581 | "_actualFontSize": 30, 582 | "_fontSize": 30, 583 | "_lineHeight": 30, 584 | "_enableWrapText": true, 585 | "_N$file": null, 586 | "_isSystemFontUsed": true, 587 | "_N$string": "", 588 | "_N$horizontalAlign": 1, 589 | "_N$verticalAlign": 1, 590 | "_N$overflow": 0 591 | }, 592 | { 593 | "__type__": "cc.Canvas", 594 | "_name": "", 595 | "_objFlags": 0, 596 | "node": { 597 | "__id__": 2 598 | }, 599 | "_enabled": true, 600 | "_designResolution": { 601 | "__type__": "cc.Size", 602 | "width": 960, 603 | "height": 640 604 | }, 605 | "_fitWidth": false, 606 | "_fitHeight": true 607 | }, 608 | { 609 | "__type__": "109f0ywvmdEmo4C36cvMTBE", 610 | "_name": "", 611 | "_objFlags": 0, 612 | "node": { 613 | "__id__": 2 614 | }, 615 | "_enabled": true, 616 | "ipLabel": { 617 | "__id__": 9 618 | }, 619 | "countryLabel": { 620 | "__id__": 11 621 | }, 622 | "cityLabel": { 623 | "__id__": 13 624 | }, 625 | "countyLabel": { 626 | "__id__": 15 627 | } 628 | } 629 | ] -------------------------------------------------------------------------------- /assets/Scene/helloworld.fire.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "2d2f792f-a40c-49bb-a189-ed176a246e49", 4 | "asyncLoadAssets": false, 5 | "autoReleaseAssets": false, 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/Script.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "4734c20c-0db8-4eb2-92ea-e692f4d70934", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/controllers.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "6cb1fc90-407c-4683-b9d2-9b83463e5405", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/controllers/AbstractController.js: -------------------------------------------------------------------------------- 1 | var AbstractController = (function () { 2 | function AbstractController() { 3 | } 4 | Object.defineProperty(AbstractController.prototype, "view", { 5 | get: function () { 6 | return this._view; 7 | }, 8 | set: function (value) { 9 | this._view = value; 10 | }, 11 | enumerable: true, 12 | configurable: true 13 | }); 14 | Object.defineProperty(AbstractController.prototype, "model", { 15 | get: function () { 16 | return this._model; 17 | }, 18 | set: function (value) { 19 | this._model = value; 20 | }, 21 | enumerable: true, 22 | configurable: true 23 | }); 24 | return AbstractController; 25 | }()); 26 | export { AbstractController }; 27 | -------------------------------------------------------------------------------- /assets/Script/controllers/AbstractController.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "d550eac2-2ae4-44b8-92fd-5b9d235c670d", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/controllers/HelloController.js: -------------------------------------------------------------------------------- 1 | import { AbstractController } from "./AbstractController"; 2 | import { HelloModel } from "../models/HelloModel"; 3 | var HelloController = (function (_super) { 4 | __extends(HelloController, _super); 5 | function HelloController() { 6 | return _super.apply(this, arguments) || this; 7 | } 8 | HelloController.prototype.init = function (view) { 9 | this.view = view; 10 | this.model = new HelloModel(); 11 | this.hello(); 12 | }; 13 | HelloController.prototype.hello = function () { 14 | return __awaiter(this, void 0, void 0, function () { 15 | var ipResult, ipInfoResult; 16 | return __generator(this, function (_a) { 17 | switch (_a.label) { 18 | case 0: return [4 /*yield*/, this.model.getIP()]; 19 | case 1: 20 | ipResult = _a.sent(); 21 | this.view.updateIP(ipResult); 22 | if (!(ipResult.code == 0 && ipResult.data !== null)) 23 | return [3 /*break*/, 3]; 24 | return [4 /*yield*/, this.model.getIPInfo(ipResult.data.ip)]; 25 | case 2: 26 | ipInfoResult = _a.sent(); 27 | this.view.updateIPInfo(ipInfoResult); 28 | _a.label = 3; 29 | case 3: return [2 /*return*/]; 30 | } 31 | }); 32 | }); 33 | }; 34 | return HelloController; 35 | }(AbstractController)); 36 | export { HelloController }; 37 | -------------------------------------------------------------------------------- /assets/Script/controllers/HelloController.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "ff4a7fc7-2c71-4a1b-bd55-ec094007242e", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/controllers/MainController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __extends = (this && this.__extends) || function (d, b) { 3 | for (var p in b) 4 | if (b.hasOwnProperty(p)) 5 | d[p] = b[p]; 6 | function __() { this.constructor = d; } 7 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 8 | }; 9 | var AbstractComponent_1 = require("../views/AbstractComponent"); 10 | var MainController = (function (_super) { 11 | __extends(MainController, _super); 12 | function MainController() { 13 | return _super.apply(this, arguments) || this; 14 | } 15 | return MainController; 16 | }(AbstractComponent_1.AbstractComponent)); 17 | exports.MainController = MainController; 18 | -------------------------------------------------------------------------------- /assets/Script/controllers/MainController.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "1dc91246-59e1-4dc0-b1a9-0b90f90e3b3b", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/decorators.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "3528d4de-01eb-4334-9b45-aaa638b73537", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/decorators/CCClass.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "8c01cf48-01d4-4307-adc7-9a7831678717", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/decorators/CCClass/CCClass1.3.js: -------------------------------------------------------------------------------- 1 | var JS = cc.js; 2 | var Enum = cc.Enum; 3 | var _isPlainEmptyObj_DEV = function (obj) { 4 | if (!obj || obj.constructor !== Object) { 5 | return false; 6 | } 7 | for (var k in obj) { 8 | return false; 9 | } 10 | return true; 11 | }; 12 | var _cloneable_DEV = function (obj) { 13 | return obj && typeof obj.clone === 'function' && 14 | (obj.constructor.prototype.hasOwnProperty('clone') || obj.hasOwnProperty('clone')); 15 | }; 16 | var Attr = cc.Class.Attr; 17 | var getTypeChecker = Attr.getTypeChecker; 18 | var SerializableAttrs = { 19 | url: { 20 | canUsedInGet: true 21 | }, 22 | default: {}, 23 | serializable: {}, 24 | editorOnly: {}, 25 | rawType: {}, 26 | }; 27 | function parseNotify(val, propName, notify, properties) { 28 | if (val.get || val.set) { 29 | if (CC_DEV) { 30 | cc.warn('"notify" can\'t work with "get/set" !'); 31 | } 32 | return; 33 | } 34 | if (val.hasOwnProperty('default')) { 35 | var newKey = "_N$" + propName; 36 | val.get = function () { 37 | return this[newKey]; 38 | }; 39 | val.set = function (value) { 40 | var oldValue = this[newKey]; 41 | this[newKey] = value; 42 | notify.call(this, oldValue); 43 | }; 44 | var newValue = {}; 45 | properties[newKey] = newValue; 46 | for (var attr in SerializableAttrs) { 47 | var v = SerializableAttrs[attr]; 48 | if (val.hasOwnProperty(attr)) { 49 | newValue[attr] = val[attr]; 50 | if (!v.canUsedInGet) { 51 | delete val[attr]; 52 | } 53 | } 54 | } 55 | } 56 | else if (CC_DEV) { 57 | cc.warn('"notify" must work with "default" !'); 58 | } 59 | } 60 | function checkUrl(val, className, propName, url) { 61 | if (Array.isArray(url)) { 62 | if (url.length > 0) { 63 | url = url[0]; 64 | } 65 | else if (CC_EDITOR) { 66 | return cc.error('Invalid url of %s.%s', className, propName); 67 | } 68 | } 69 | if (CC_EDITOR) { 70 | if (url == null) { 71 | return cc.warn('The "url" attribute of "%s.%s" is undefined when loading script.', className, propName); 72 | } 73 | if (typeof url !== 'function' || !cc.isChildClassOf(url, cc.RawAsset)) { 74 | return cc.error('The "url" type of "%s.%s" must be child class of cc.RawAsset.', className, propName); 75 | } 76 | if (cc.isChildClassOf(url, cc.Asset)) { 77 | return cc.error('The "url" type of "%s.%s" must not be child class of cc.Asset, ' + 78 | 'otherwise you should use "type: %s" instead.', className, propName, cc.js.getClassName(url)); 79 | } 80 | if (val.type) { 81 | return cc.warn('Can not specify "type" attribute for "%s.%s", because its "url" is already defined.', className, propName); 82 | } 83 | } 84 | val.type = url; 85 | } 86 | function parseType(val, type, className, propName) { 87 | if (Array.isArray(type)) { 88 | if (CC_EDITOR) { 89 | var isArray = function (defaultVal) { 90 | defaultVal = getDefault(defaultVal); 91 | return Array.isArray(defaultVal); 92 | }; 93 | if (!isArray(val.default)) { 94 | cc.warn('The "default" attribute of "%s.%s" must be an array', className, propName); 95 | } 96 | } 97 | if (type.length > 0) { 98 | val.type = type = type[0]; 99 | } 100 | else { 101 | return cc.error('Invalid type of %s.%s', className, propName); 102 | } 103 | } 104 | if (CC_EDITOR) { 105 | if (typeof type === 'function') { 106 | if (cc.RawAsset.isRawAssetType(type)) { 107 | cc.warn('The "type" attribute of "%s.%s" must be child class of cc.Asset, ' + 108 | 'otherwise you should use "url: %s" instead', className, propName, cc.js.getClassName(type)); 109 | } 110 | } 111 | else if (type === 'Number') { 112 | cc.warn('The "type" attribute of "%s.%s" can not be "Number", use "Float" or "Integer" instead please.', className, propName); 113 | } 114 | else if (type == null) { 115 | cc.warn('The "type" attribute of "%s.%s" is undefined when loading script.', className, propName); 116 | } 117 | } 118 | } 119 | function postCheckType(val, type, className, propName) { 120 | if (CC_EDITOR && typeof type === 'function') { 121 | if (cc.Class._isCCClass(type) && val.serializable !== false && !cc.js._getClassId(type, false)) { 122 | cc.warn('Can not serialize "%s.%s" because the specified type is anonymous, please provide a class name or set the "serializable" attribute of "%s.%s" to "false".', className, propName, className, propName); 123 | } 124 | } 125 | } 126 | function getBaseClassWherePropertyDefined_DEV(propName, cls) { 127 | if (CC_DEV) { 128 | var res; 129 | for (; cls && cls.__props__ && cls.__props__.indexOf(propName) !== -1; cls = cls.$super) { 130 | res = cls; 131 | } 132 | if (!res) { 133 | cc.error('unknown error'); 134 | } 135 | return res; 136 | } 137 | } 138 | var preprocessAttrs = function (properties, className, cls) { 139 | for (var propName in properties) { 140 | var val = properties[propName]; 141 | var isLiteral = val && val.constructor === Object; 142 | if (!isLiteral) { 143 | if (Array.isArray(val) && val.length > 0) { 144 | val = { 145 | default: [], 146 | type: val 147 | }; 148 | } 149 | else if (typeof val === 'function') { 150 | var type = val; 151 | if (cc.RawAsset.isRawAssetType(type)) { 152 | val = { 153 | default: '', 154 | url: type 155 | }; 156 | } 157 | else { 158 | val = cc.isChildClassOf(type, cc.ValueType) ? { 159 | default: new type() 160 | } : { 161 | default: null, 162 | type: val 163 | }; 164 | } 165 | } 166 | else { 167 | val = { 168 | default: val 169 | }; 170 | } 171 | properties[propName] = val; 172 | } 173 | if (val) { 174 | if (CC_EDITOR) { 175 | if ('default' in val) { 176 | if (val.get) { 177 | cc.error('The "default" value of "%s.%s" should not be used with a "get" function.', className, propName); 178 | } 179 | else if (val.set) { 180 | cc.error('The "default" value of "%s.%s" should not be used with a "set" function.', className, propName); 181 | } 182 | } 183 | else if (!val.get && !val.set) { 184 | cc.error('Property "%s.%s" must define at least one of "default", "get" or "set".', className, propName); 185 | } 186 | } 187 | if (CC_DEV && !val.override && cls.__props__.indexOf(propName) !== -1) { 188 | var baseClass = cc.js.getClassName(getBaseClassWherePropertyDefined_DEV(propName, cls)); 189 | cc.warn('"%s.%s" hides inherited property "%s.%s". To make the current property override that implementation, add the `override: true` attribute please.', className, propName, baseClass, propName); 190 | } 191 | var notify = val.notify; 192 | if (notify) { 193 | parseNotify(val, propName, notify, properties); 194 | } 195 | if ('type' in val) { 196 | parseType(val, val.type, className, propName); 197 | } 198 | if ('url' in val) { 199 | checkUrl(val, className, propName, val.url); 200 | } 201 | if ('type' in val) { 202 | postCheckType(val, val.type, className, propName); 203 | } 204 | } 205 | } 206 | }; 207 | var BUILTIN_ENTRIES = ['name', 'extends', 'mixins', 'ctor', 'properties', 'statics', 'editor']; 208 | var TYPO_TO_CORRECT = CC_DEV && { 209 | extend: 'extends', 210 | property: 'properties', 211 | static: 'statics', 212 | constructor: 'ctor' 213 | }; 214 | var INVALID_STATICS = CC_DEV && ['name', '__ctors__', '__props__', 'arguments', 'call', 'apply', 'caller', 215 | 'length', 'prototype']; 216 | var deferredInitializer = { 217 | datas: null, 218 | push: function (data) { 219 | if (this.datas) { 220 | this.datas.push(data); 221 | } 222 | else { 223 | this.datas = [data]; 224 | var self = this; 225 | setTimeout(function () { 226 | self.init(); 227 | }, 0); 228 | } 229 | }, 230 | init: function () { 231 | var datas = this.datas; 232 | if (datas) { 233 | for (var i = 0; i < datas.length; ++i) { 234 | var data = datas[i]; 235 | var cls = data.cls; 236 | var properties = data.props; 237 | if (typeof properties === 'function') { 238 | properties = properties(); 239 | } 240 | var name = JS.getClassName(cls); 241 | if (properties) { 242 | declareProperties(cls, name, properties, cls.$super, data.mixins); 243 | } 244 | else { 245 | cc.error('Properties function of "%s" should return an object!', name); 246 | } 247 | } 248 | this.datas = null; 249 | } 250 | } 251 | }; 252 | function appendProp(cls, name) { 253 | if (CC_DEV) { 254 | if (name.indexOf('.') !== -1) { 255 | cc.error('Disallow to use "." in property name'); 256 | return; 257 | } 258 | } 259 | var index = cls.__props__.indexOf(name); 260 | if (index < 0) { 261 | cls.__props__.push(name); 262 | } 263 | } 264 | function defineProp(cls, className, propName, defaultValue, attrs) { 265 | if (CC_DEV) { 266 | if (typeof defaultValue === 'object' && defaultValue) { 267 | if (Array.isArray(defaultValue)) { 268 | if (defaultValue.length > 0) { 269 | cc.error('Default array must be empty, set default value of %s.%s to [], ' + 270 | 'and initialize in "onLoad" or "ctor" please. (just like "this.%s = [...];")', className, propName, propName); 271 | return; 272 | } 273 | } 274 | else if (!_isPlainEmptyObj_DEV(defaultValue)) { 275 | if (!_cloneable_DEV(defaultValue)) { 276 | cc.error('Do not set default value to non-empty object, ' + 277 | 'unless the object defines its own "clone" function. Set default value of %s.%s to null or {}, ' + 278 | 'and initialize in "onLoad" or "ctor" please. (just like "this.%s = {foo: bar};")', className, propName, propName); 279 | return; 280 | } 281 | } 282 | } 283 | for (var base = cls.$super; base; base = base.$super) { 284 | if (base.prototype.hasOwnProperty(propName)) { 285 | cc.error('Can not declare %s.%s, it is already defined in the prototype of %s', className, propName, className); 286 | return; 287 | } 288 | } 289 | } 290 | Attr.setClassAttr(cls, propName, 'default', defaultValue); 291 | appendProp(cls, propName); 292 | if (attrs) { 293 | var onAfterProp = null; 294 | for (var i = 0; i < attrs.length; i++) { 295 | var attr = attrs[i]; 296 | Attr.attr(cls, propName, attr); 297 | if (attr._onAfterProp) { 298 | onAfterProp = onAfterProp || []; 299 | onAfterProp.push(attr._onAfterProp); 300 | } 301 | } 302 | if (onAfterProp) { 303 | for (var c = 0; c < onAfterProp.length; c++) { 304 | onAfterProp[c](cls, propName); 305 | } 306 | } 307 | } 308 | } 309 | function defineGetSet(cls, name, propName, val, attrs) { 310 | var getter = val.get; 311 | var setter = val.set; 312 | var proto = cls.prototype; 313 | var d = Object.getOwnPropertyDescriptor(proto, propName); 314 | if (getter) { 315 | if (CC_DEV && d && d.get) { 316 | cc.error('"%s": the getter of "%s" is already defined!', name, propName); 317 | return; 318 | } 319 | if (attrs) { 320 | for (var i = 0; i < attrs.length; ++i) { 321 | var attr = attrs[i]; 322 | if (CC_DEV && attr._canUsedInGetter === false) { 323 | cc.error('Can not apply the specified attribute to the getter of "%s.%s", ' + 324 | 'attribute index: %s', name, propName, i); 325 | continue; 326 | } 327 | Attr.attr(cls, propName, attr); 328 | if (CC_DEV && (attr.serializable === false || attr.editorOnly === true)) { 329 | cc.warn('No need to use "serializable: false" or "editorOnly: true" for ' + 330 | 'the getter of "%s.%s", every getter is actually non-serialized.', name, propName); 331 | } 332 | } 333 | } 334 | var ForceSerializable = false; 335 | if (!ForceSerializable) { 336 | Attr.attr(cls, propName, Attr.NonSerialized); 337 | } 338 | if (ForceSerializable || CC_DEV) { 339 | appendProp(cls, propName); 340 | } 341 | if (d) { 342 | Object.defineProperty(proto, propName, { 343 | get: getter 344 | }); 345 | } 346 | else { 347 | Object.defineProperty(proto, propName, { 348 | get: getter, 349 | configurable: true, 350 | enumerable: true 351 | }); 352 | } 353 | if (CC_DEV) { 354 | Attr.setClassAttr(cls, propName, 'hasGetter', true); 355 | } 356 | } 357 | if (setter) { 358 | if (CC_DEV) { 359 | if (d && d.set) { 360 | return cc.error('"%s": the setter of "%s" is already defined!', name, propName); 361 | } 362 | Object.defineProperty(proto, propName, { 363 | set: setter, 364 | configurable: true, 365 | enumerable: true 366 | }); 367 | Attr.setClassAttr(cls, propName, 'hasSetter', true); 368 | } 369 | else { 370 | if (d) { 371 | Object.defineProperty(proto, propName, { 372 | set: setter 373 | }); 374 | } 375 | else { 376 | Object.defineProperty(proto, propName, { 377 | set: setter, 378 | configurable: true, 379 | enumerable: true 380 | }); 381 | } 382 | } 383 | } 384 | } 385 | function getDefault(defaultVal) { 386 | if (typeof defaultVal === 'function') { 387 | if (CC_EDITOR) { 388 | try { 389 | return defaultVal(); 390 | } 391 | catch (e) { 392 | cc._throw(e); 393 | return undefined; 394 | } 395 | } 396 | else { 397 | return defaultVal(); 398 | } 399 | } 400 | return defaultVal; 401 | } 402 | var DELIMETER = Attr.DELIMETER; 403 | function instantiateProps(instance, itsClass) { 404 | var attrs = Attr.getClassAttrs(itsClass); 405 | var propList = itsClass.__props__; 406 | if (propList === null) { 407 | deferredInitializer.init(); 408 | propList = itsClass.__props__; 409 | } 410 | for (var i = 0; i < propList.length; i++) { 411 | var prop = propList[i]; 412 | var attrKey = prop + DELIMETER + 'default'; 413 | if (attrKey in attrs) { 414 | var def = attrs[attrKey]; 415 | if (def) { 416 | if (typeof def === 'object' && def) { 417 | if (typeof def.clone === 'function') { 418 | def = def.clone(); 419 | } 420 | else if (Array.isArray(def)) { 421 | def = []; 422 | } 423 | else { 424 | def = {}; 425 | } 426 | } 427 | else if (typeof def === 'function') { 428 | def = getDefault(def); 429 | } 430 | } 431 | instance[prop] = def; 432 | } 433 | } 434 | } 435 | function doDefine(className, baseClass, mixins, constructor, options) { 436 | var fireClass = _createCtor(constructor, baseClass, mixins, className, options); 437 | Object.defineProperty(fireClass, 'extend', { 438 | value: function (options) { 439 | options.extends = this; 440 | return CCClass(options); 441 | }, 442 | writable: true, 443 | configurable: true 444 | }); 445 | if (baseClass) { 446 | JS.extend(fireClass, baseClass); 447 | fireClass.$super = baseClass; 448 | } 449 | if (mixins) { 450 | for (var m = 0; m < mixins.length; ++m) { 451 | var mixin = mixins[m]; 452 | JS.mixin(fireClass.prototype, mixin.prototype); 453 | for (var p in mixin) 454 | if (mixin.hasOwnProperty(p) && INVALID_STATICS.indexOf(p) < 0) 455 | fireClass[p] = mixin[p]; 456 | if (CCClass._isCCClass(mixin)) { 457 | JS.mixin(Attr.getClassAttrs(fireClass).constructor.prototype, Attr.getClassAttrs(mixin).constructor.prototype); 458 | } 459 | } 460 | fireClass.prototype.constructor = fireClass; 461 | } 462 | JS.setClassName(className, fireClass); 463 | return fireClass; 464 | } 465 | function define(className, baseClasses, mixins, constructor, options) { 466 | if (cc.isChildClassOf(baseClasses, cc.Component)) { 467 | var frame = cc._RFpeek(); 468 | if (frame) { 469 | if (CC_DEV && constructor) { 470 | cc.warn('Should not define constructor for cc.Component %s.', className); 471 | } 472 | if (frame.beh) { 473 | cc.error('Each script can have at most one Component.'); 474 | return cls; 475 | } 476 | var uuid = frame.uuid; 477 | if (uuid) { 478 | if (CC_EDITOR && className) { 479 | cc.warn('Should not specify class name %s for Component which defines in project.', className); 480 | } 481 | } 482 | className = className || frame.script; 483 | var cls = doDefine(className, baseClasses, mixins, constructor, options); 484 | if (uuid) { 485 | JS._setClassId(uuid, cls); 486 | if (CC_EDITOR) { 487 | cc.Component._addMenuItem(cls, 'i18n:MAIN_MENU.component.scripts/' + className, -1); 488 | cls.prototype.__scriptUuid = Editor.UuidUtils.decompressUuid(uuid); 489 | } 490 | } 491 | frame.beh = cls; 492 | return cls; 493 | } 494 | } 495 | return doDefine(className, baseClasses, mixins, constructor, options); 496 | } 497 | function _checkCtor(ctor, className) { 498 | if (CC_DEV) { 499 | if (CCClass._isCCClass(ctor)) { 500 | cc.error('ctor of "%s" can not be another CCClass', className); 501 | return; 502 | } 503 | if (typeof ctor !== 'function') { 504 | cc.error('ctor of "%s" must be function type', className); 505 | return; 506 | } 507 | if (ctor.length > 0) { 508 | cc.warn('Can not instantiate CCClass "%s" with arguments.', className); 509 | return; 510 | } 511 | } 512 | } 513 | function normalizeClassName(className) { 514 | if (CC_DEV) { 515 | var DefaultName = 'CCClass'; 516 | if (className) { 517 | className = className.replace(/\./g, '_'); 518 | className = className.split('').filter(function (x) { return /^[a-zA-Z0-9_$]/.test(x); }).join(''); 519 | if (/^[0-9]/.test(className[0])) { 520 | className = '_' + className; 521 | } 522 | try { 523 | eval('function ' + className + '(){}'); 524 | } 525 | catch (e) { 526 | className = 'FireClass_' + className; 527 | try { 528 | eval('function ' + className + '(){}'); 529 | } 530 | catch (e) { 531 | return DefaultName; 532 | } 533 | } 534 | return className; 535 | } 536 | return DefaultName; 537 | } 538 | } 539 | function _createCtor(ctor, baseClass, mixins, className, options) { 540 | var useTryCatch = !(className && className.startsWith('cc.')); 541 | var shouldAddProtoCtor; 542 | if (CC_EDITOR && ctor && baseClass) { 543 | var originCtor = ctor; 544 | if (SuperCallReg.test(ctor)) { 545 | cc.warn(cc._LogInfos.Editor.Class.callSuperCtor, className); 546 | ctor = function () { 547 | this._super = function () { }; 548 | var ret = originCtor.apply(this, arguments); 549 | this._super = null; 550 | return ret; 551 | }; 552 | } 553 | if (/\bprototype.ctor\b/.test(originCtor)) { 554 | cc.warn(cc._LogInfos.Editor.Class.callSuperCtor, className); 555 | shouldAddProtoCtor = true; 556 | } 557 | } 558 | var superCallBounded = options && baseClass && boundSuperCalls(baseClass, options); 559 | if (ctor && CC_DEV) { 560 | _checkCtor(ctor, className); 561 | } 562 | var ctors = []; 563 | var baseOrMixins = [baseClass].concat(mixins); 564 | for (var b = 0; b < baseOrMixins.length; b++) { 565 | var baseOrMixin = baseOrMixins[b]; 566 | if (baseOrMixin) { 567 | if (CCClass._isCCClass(baseOrMixin)) { 568 | var baseCtors = baseOrMixin.__ctors__; 569 | if (baseCtors) { 570 | ctors = ctors.concat(baseCtors); 571 | } 572 | } 573 | else if (baseOrMixin) { 574 | ctors.push(baseOrMixin); 575 | } 576 | } 577 | } 578 | if (ctor) { 579 | ctors.push(ctor); 580 | } 581 | var body; 582 | if (CC_DEV) { 583 | body = '(function ' + normalizeClassName(className) + '(){\n'; 584 | } 585 | else { 586 | body = '(function(){\n'; 587 | } 588 | if (superCallBounded) { 589 | body += 'this._super=null;\n'; 590 | } 591 | body += 'instantiateProps(this,fireClass);\n'; 592 | if (ctors.length > 0) { 593 | body += 'var cs=fireClass.__ctors__;\n'; 594 | if (useTryCatch) { 595 | body += 'try{\n'; 596 | } 597 | if (ctors.length <= 5) { 598 | for (var i = 0; i < ctors.length; i++) { 599 | body += '(cs[' + i + ']).apply(this,arguments);\n'; 600 | } 601 | } 602 | else { 603 | body += 'for(var i=0,l=cs.length;i 0 ? ctors : null, 614 | }); 615 | if (CC_EDITOR && shouldAddProtoCtor) { 616 | fireClass.prototype.ctor = function () { }; 617 | } 618 | return fireClass; 619 | } 620 | var SuperCallReg = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/; 621 | function _boundSuperCall(func, funcName, base) { 622 | var superFunc = null; 623 | var pd = JS.getPropertyDescriptor(base.prototype, funcName); 624 | if (pd) { 625 | superFunc = pd.value; 626 | if (typeof superFunc === 'function') { 627 | var hasSuperCall = SuperCallReg.test(func); 628 | if (hasSuperCall) { 629 | return function () { 630 | var tmp = this._super; 631 | this._super = superFunc; 632 | var ret = func.apply(this, arguments); 633 | this._super = tmp; 634 | return ret; 635 | }; 636 | } 637 | } 638 | } 639 | return null; 640 | } 641 | function boundSuperCalls(baseClass, options) { 642 | var hasSuperCall = false; 643 | for (var funcName in options) { 644 | if (BUILTIN_ENTRIES.indexOf(funcName) < 0) { 645 | var func = options[funcName]; 646 | if (typeof func === 'function') { 647 | var bounded = _boundSuperCall(func, funcName, baseClass); 648 | if (bounded) { 649 | hasSuperCall = true; 650 | options[funcName] = bounded; 651 | } 652 | } 653 | } 654 | } 655 | return hasSuperCall; 656 | } 657 | function declareProperties(cls, className, properties, baseClass, mixins) { 658 | cls.__props__ = []; 659 | if (baseClass && baseClass.__props__) { 660 | cls.__props__ = baseClass.__props__.slice(); 661 | } 662 | if (mixins) { 663 | for (var m = 0; m < mixins.length; ++m) { 664 | var mixin = mixins[m]; 665 | if (mixin.__props__) { 666 | cls.__props__ = cls.__props__.concat(mixin.__props__.filter(function (x) { 667 | return cls.__props__.indexOf(x) < 0; 668 | })); 669 | } 670 | } 671 | } 672 | if (properties) { 673 | preprocessAttrs(properties, className, cls); 674 | for (var propName in properties) { 675 | var val = properties[propName]; 676 | var attrs = parseAttributes(val, className, propName); 677 | if ('default' in val) { 678 | defineProp(cls, className, propName, val.default, attrs); 679 | } 680 | else { 681 | defineGetSet(cls, className, propName, val, attrs); 682 | } 683 | } 684 | } 685 | } 686 | function CCClass(options) { 687 | if (arguments.length === 0) { 688 | return define(); 689 | } 690 | if (!options) { 691 | cc.error('cc.Class: Option must be non-nil'); 692 | return define(); 693 | } 694 | var name = options.name; 695 | var base = options.extends; 696 | var mixins = options.mixins; 697 | var cls; 698 | cls = define(name, base, mixins, options.ctor, options); 699 | if (!name) { 700 | name = cc.js.getClassName(cls); 701 | } 702 | var properties = options.properties; 703 | if (typeof properties === 'function' || 704 | (base && base.__props__ === null) || 705 | (mixins && mixins.some(function (x) { 706 | return x.__props__ === null; 707 | }))) { 708 | deferredInitializer.push({ cls: cls, props: properties, mixins: mixins }); 709 | cls.__props__ = null; 710 | } 711 | else { 712 | declareProperties(cls, name, properties, base, options.mixins); 713 | } 714 | var statics = options.statics; 715 | if (statics) { 716 | var staticPropName; 717 | if (CC_DEV) { 718 | for (staticPropName in statics) { 719 | if (INVALID_STATICS.indexOf(staticPropName) !== -1) { 720 | cc.error('Cannot define %s.%s because static member name can not be "%s".', name, staticPropName, staticPropName); 721 | } 722 | } 723 | } 724 | for (staticPropName in statics) { 725 | cls[staticPropName] = statics[staticPropName]; 726 | } 727 | } 728 | for (var funcName in options) { 729 | if (BUILTIN_ENTRIES.indexOf(funcName) >= 0) { 730 | continue; 731 | } 732 | if (CC_EDITOR && funcName === 'constructor') { 733 | cc.error('Can not define a member called "constructor" in the class "%s", please use "ctor" instead.', name); 734 | continue; 735 | } 736 | var func = options[funcName]; 737 | if (typeof func === 'function' || func === null) { 738 | Object.defineProperty(cls.prototype, funcName, { 739 | value: func, 740 | enumerable: true, 741 | configurable: true, 742 | writable: true, 743 | }); 744 | } 745 | else if (CC_DEV) { 746 | if (func === false && base && base.prototype) { 747 | var overrided = base.prototype[funcName]; 748 | if (typeof overrided === 'function') { 749 | var baseFuc = JS.getClassName(base) + '.' + funcName; 750 | var subFuc = name + '.' + funcName; 751 | cc.warn('"%s" overrided "%s" but "%s" is defined as "false" so the super method will not be called. You can set "%s" to null to disable this warning.', subFuc, baseFuc, subFuc, subFuc); 752 | } 753 | } 754 | var correct = TYPO_TO_CORRECT[funcName]; 755 | if (correct) { 756 | cc.warn('Unknown type of %s.%s, maybe you want is "%s".', name, funcName, correct); 757 | } 758 | else if (func) { 759 | cc.error('Unknown type of %s.%s, property should be defined in "properties" or "ctor"', name, funcName); 760 | } 761 | } 762 | } 763 | if (CC_DEV) { 764 | var editor = options.editor; 765 | if (editor) { 766 | if (cc.isChildClassOf(base, cc.Component)) { 767 | cc.Component._registerEditorProps(cls, editor); 768 | } 769 | else { 770 | cc.warn('Can not use "editor" attribute, "%s" not inherits from Components.', name); 771 | } 772 | } 773 | } 774 | return cls; 775 | } 776 | CCClass._isCCClass = function (constructor) { 777 | return !!constructor && typeof constructor.__ctors__ !== 'undefined'; 778 | }; 779 | var PrimitiveTypes = { 780 | Integer: 'Number', 781 | Float: 'Number', 782 | Boolean: 'Boolean', 783 | String: 'String', 784 | }; 785 | var tmpAttrs = []; 786 | function parseAttributes(attrs, className, propName) { 787 | var ERR_Type = CC_DEV ? 'The %s of %s must be type %s' : ''; 788 | tmpAttrs.length = 0; 789 | var result = tmpAttrs; 790 | var type = attrs.type; 791 | if (type) { 792 | var primitiveType = PrimitiveTypes[type]; 793 | if (primitiveType) { 794 | result.push({ 795 | type: type, 796 | _onAfterProp: getTypeChecker(primitiveType, 'cc.' + type) 797 | }); 798 | } 799 | else if (type === 'Object') { 800 | if (CC_DEV) { 801 | cc.error('Please define "type" parameter of %s.%s as the actual constructor.', className, propName); 802 | } 803 | } 804 | else { 805 | if (type === Attr.ScriptUuid) { 806 | var attr = Attr.ObjectType(cc.ScriptAsset); 807 | attr.type = 'Script'; 808 | result.push(attr); 809 | } 810 | else { 811 | if (typeof type === 'object') { 812 | if (Enum.isEnum(type)) { 813 | result.push({ 814 | type: 'Enum', 815 | enumList: Enum.getList(type) 816 | }); 817 | } 818 | else if (CC_DEV) { 819 | cc.error('Please define "type" parameter of %s.%s as the constructor of %s.', className, propName, type); 820 | } 821 | } 822 | else if (typeof type === 'function') { 823 | if (attrs.url) { 824 | result.push({ 825 | type: 'Object', 826 | ctor: type, 827 | _onAfterProp: getTypeChecker('String', 'cc.String') 828 | }); 829 | } 830 | else { 831 | result.push(Attr.ObjectType(type)); 832 | } 833 | } 834 | else if (CC_DEV) { 835 | cc.error('Unknown "type" parameter of %s.%s:%s', className, propName, type); 836 | } 837 | } 838 | } 839 | } 840 | function parseSimpleAttr(attrName, expectType, attrCreater) { 841 | if (attrName in attrs) { 842 | var val = attrs[attrName]; 843 | if (typeof val === expectType) { 844 | if (!attrCreater) { 845 | var attr = {}; 846 | attr[attrName] = val; 847 | result.push(attr); 848 | } 849 | else { 850 | result.push(typeof attrCreater === 'function' ? attrCreater(val) : attrCreater); 851 | } 852 | } 853 | else if (CC_DEV) { 854 | cc.error(ERR_Type, attrName, className, propName, expectType); 855 | } 856 | } 857 | } 858 | parseSimpleAttr('rawType', 'string', Attr.RawType); 859 | parseSimpleAttr('editorOnly', 'boolean', Attr.EditorOnly); 860 | if (CC_DEV) { 861 | parseSimpleAttr('displayName', 'string'); 862 | parseSimpleAttr('multiline', 'boolean', { multiline: true }); 863 | parseSimpleAttr('readonly', 'boolean', { readonly: true }); 864 | parseSimpleAttr('tooltip', 'string'); 865 | parseSimpleAttr('slide', 'boolean'); 866 | } 867 | if (attrs.url) { 868 | result.push({ saveUrlAsAsset: true }); 869 | } 870 | if (attrs.serializable === false) { 871 | result.push(Attr.NonSerialized); 872 | } 873 | if (CC_EDITOR) { 874 | if ('animatable' in attrs && !attrs.animatable) { 875 | result.push({ animatable: false }); 876 | } 877 | } 878 | if (CC_DEV) { 879 | var visible = attrs.visible; 880 | if (typeof visible !== 'undefined') { 881 | if (!visible) { 882 | result.push({ visible: false }); 883 | } 884 | else if (typeof visible === 'function') { 885 | result.push({ visible: visible }); 886 | } 887 | } 888 | else { 889 | var startsWithUS = (propName.charCodeAt(0) === 95); 890 | if (startsWithUS) { 891 | result.push({ visible: false }); 892 | } 893 | } 894 | } 895 | var range = attrs.range; 896 | if (range) { 897 | if (Array.isArray(range)) { 898 | if (range.length >= 2) { 899 | result.push({ min: range[0], max: range[1], step: range[2] }); 900 | } 901 | else if (CC_DEV) { 902 | cc.error('The length of range array must be equal or greater than 2'); 903 | } 904 | } 905 | else if (CC_DEV) { 906 | cc.error(ERR_Type, 'range', className, propName, 'array'); 907 | } 908 | } 909 | parseSimpleAttr('min', 'number'); 910 | parseSimpleAttr('max', 'number'); 911 | parseSimpleAttr('step', 'number'); 912 | return result; 913 | } 914 | module.exports = { 915 | define: define, 916 | declareProperties: declareProperties 917 | }; 918 | -------------------------------------------------------------------------------- /assets/Script/decorators/CCClass/CCClass1.3.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "c7fabe95-5349-4ef5-8cd2-b7b097ef8afc", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/decorators/CCClass/CCClass1.4.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "0102e173-f81c-4a81-be6d-d1763d0c0952", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/decorators/ComponentDecorators.js: -------------------------------------------------------------------------------- 1 | import { define as define13, declareProperties as declareProperties13 } from "./CCClass/CCClass1.3"; 2 | import { define as define14, declareProperties as declareProperties14 } from "./CCClass/CCClass1.4"; 3 | var define, declareProperties; 4 | // CCClass of v1.4.x is different. 5 | if (/^1.4/.test(cc.ENGINE_VERSION)) { 6 | define = define14; 7 | declareProperties = declareProperties14; 8 | } 9 | else { 10 | define = define13; 11 | declareProperties = declareProperties13; 12 | } 13 | var currentProperties = {}; 14 | var currentMixins = {}; 15 | var currentEditor = {}; 16 | var defined = {}; 17 | var definedClass = {}; 18 | // Get the UUID of currently compiling script 19 | function getUUID() { 20 | return cc._RFpeek().uuid; 21 | } 22 | // Get the name of currently compiling script 23 | function getScriptName() { 24 | return cc._RFpeek().script; 25 | } 26 | /* 27 | Decorator of components that inherit cc.Component. Usage: 28 | -------------------------- 29 | @CCComponent 30 | export class ComponentName extends cc.Component {} 31 | -------------------------- 32 | */ 33 | export function CCComponent(constructor) { 34 | if (constructor.length > 0) { 35 | cc.warn("Please do not define parameters for a component constructor in " + getScriptName() + "!"); 36 | } 37 | var uuid = getUUID(); 38 | if (defined[uuid]) 39 | return definedClass[uuid]; 40 | constructor.$super = cc.Component; 41 | var cls = define(void 0, constructor, currentMixins[uuid], void 0, {}); 42 | var name = cc.js.getClassName(cls); 43 | declareProperties(cls, name, currentProperties[uuid], constructor, void 0); 44 | if (currentEditor.hasOwnProperty(uuid)) { 45 | cc.Component._registerEditorProps(constructor, currentEditor[uuid]); 46 | } 47 | currentProperties = {}; 48 | currentMixins = {}; 49 | currentEditor = {}; 50 | defined[uuid] = true; 51 | definedClass[uuid] = cls; 52 | return cls; 53 | } 54 | /* 55 | Decorator of a property in cc.Component. 56 | @CCProperty must be used with @CCComponent. Usage: 57 | -------------------------- 58 | @CCComponent 59 | export class ComponentName extends cc.Component { 60 | @CCProperty({ 61 | default: null, 62 | type: cc.Node 63 | }) 64 | public someNode: cc.Node; 65 | @CCProperty(cc.Button) 66 | public someButton: cc.Button; 67 | } 68 | -------------------------- 69 | */ 70 | export function CCProperty(option) { 71 | return function (constructor, propertyName) { 72 | var uuid = getUUID(); 73 | if (!currentProperties.hasOwnProperty(uuid)) 74 | currentProperties[uuid] = {}; 75 | currentProperties[uuid][propertyName] = option; 76 | }; 77 | } 78 | /* 79 | Decorator of editor properties. 80 | @CCEditor must be used with @CCComponent. Usage: 81 | -------------------------- 82 | @CCEditor({ 83 | executeInEditMode: true 84 | }) 85 | @CCComponent 86 | export class ComponentName extends cc.Component {} 87 | -------------------------- 88 | */ 89 | export function CCEditor(editor) { 90 | return function (constructor) { 91 | if (CC_EDITOR) { 92 | var uuid = getUUID(); 93 | if (!defined.hasOwnProperty(uuid) || !defined[uuid]) { 94 | currentEditor[uuid] = editor; 95 | } 96 | else { 97 | cc.Component._registerEditorProps(constructor, editor); 98 | } 99 | } 100 | return constructor; 101 | }; 102 | } 103 | /* 104 | Decorator of mixins. 105 | @CCMixins must be used before @CCComponent. Usage: 106 | -------------------------- 107 | @CCComponent 108 | @CCMixins(mixin1, mixin2, mixin3, ...) 109 | export class ComponentName extends cc.Component {} 110 | -------------------------- 111 | */ 112 | export function CCMixins() { 113 | var args = []; 114 | for (var _i = 0; _i < arguments.length; _i++) { 115 | args[_i] = arguments[_i]; 116 | } 117 | return function (cls) { 118 | var uuid = getUUID(); 119 | if (CC_EDITOR && defined.hasOwnProperty(uuid) && defined[uuid]) { 120 | cc.error("@CCMixins should be used before @CCComponent in " + getScriptName() + "!"); 121 | } 122 | currentMixins[uuid] = args; 123 | return cls; 124 | }; 125 | } 126 | -------------------------------------------------------------------------------- /assets/Script/decorators/ComponentDecorators.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "a559ca93-7257-4602-aa8c-73d1b3513d4c", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/libs.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "38b7923e-dcd2-4056-80be-85d5bfa3eb4d", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/libs/i18n.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "97caf019-8252-478c-91b3-44d0216f884a", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/libs/i18n/LabelLocalized.js: -------------------------------------------------------------------------------- 1 | import { CCComponent, CCProperty } from "../../decorators/ComponentDecorators"; 2 | import { i18n } from "./i18n"; 3 | var LabelLocalized = (function (_super) { 4 | __extends(LabelLocalized, _super); 5 | function LabelLocalized() { 6 | return _super.apply(this, arguments) || this; 7 | } 8 | return LabelLocalized; 9 | }(cc.Label)); 10 | __decorate([ 11 | CCProperty({ 12 | default: "TEXT_KEY", 13 | multiline: true, 14 | tooltip: "Enter i18n key here", 15 | notify: function () { 16 | if (this._sgNode) { 17 | this._sgNode.setString(this.string); 18 | this._updateNodeSize(); 19 | } 20 | } 21 | }) 22 | ], LabelLocalized.prototype, "textKey", void 0); 23 | __decorate([ 24 | CCProperty({ 25 | override: true, 26 | tooltip: "Here shows the localized string of Text Key", 27 | get: function () { 28 | return i18n.t(this.textKey); 29 | }, 30 | set: function (value) { 31 | cc.warn("Please set label text key in Text Key property."); 32 | } 33 | }) 34 | ], LabelLocalized.prototype, "string", void 0); 35 | LabelLocalized = __decorate([ 36 | CCComponent 37 | ], LabelLocalized); 38 | export { LabelLocalized }; 39 | -------------------------------------------------------------------------------- /assets/Script/libs/i18n/LabelLocalized.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "dd779fe7-9551-4196-850d-bfc8eb0c2232", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/libs/i18n/data.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "bdfc05b2-92fc-428a-aa85-4ead716aecd0", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/libs/i18n/data/en.js: -------------------------------------------------------------------------------- 1 | export var en = { 2 | "lang": "English" 3 | }; 4 | -------------------------------------------------------------------------------- /assets/Script/libs/i18n/data/en.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "2d629f08-b50c-4e2a-81fc-15b0ae131aa7", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/libs/i18n/data/zh.js: -------------------------------------------------------------------------------- 1 | export var zh = { 2 | "lang": "简体中文" 3 | }; 4 | -------------------------------------------------------------------------------- /assets/Script/libs/i18n/data/zh.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "fb544ee3-4e7c-454a-98f6-bf2c1e30493a", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/libs/i18n/i18n.js: -------------------------------------------------------------------------------- 1 | import { zh } from "./data/zh"; 2 | var Polyglot = require("polyglot"); 3 | var language = zh; // update this to set your default displaying language in editor 4 | // let polyglot = null; 5 | var polyglot = new Polyglot({ phrases: language }); 6 | export var i18n = { 7 | /** 8 | * This method allow you to switch language during runtime, language argument should be the same as your data file name 9 | * such as when language is 'zh', it will load your 'zh.ts' data source. 10 | * @method init 11 | * @param language - the language specific data file name, such as 'zh' to load 'zh.ts' 12 | */ 13 | init: function (language) { 14 | var data = require(language); 15 | polyglot.replace(data); 16 | }, 17 | /** 18 | * this method takes a text key as input, and return the localized string 19 | * Please read https://github.com/airbnb/polyglot.js for details 20 | * @method t 21 | * @return {String} localized string 22 | * @example 23 | * 24 | * let myText = i18n.t('MY_TEXT_KEY'); 25 | * 26 | * // if your data source is defined as 27 | * // {"hello_name": "Hello, %{name}"} 28 | * // you can use the following to interpolate the text 29 | * let greetingText = i18n.t('hello_name', {name: 'nantas'}); // Hello, nantas 30 | */ 31 | t: function (key, opt) { 32 | return polyglot.t(key, opt); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /assets/Script/libs/i18n/i18n.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "bc63aa5f-5f43-42bb-be41-8fb632c6c3ca", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/libs/i18n/polyglot.js: -------------------------------------------------------------------------------- 1 | // (c) 2012-2016 Airbnb, Inc. 2 | // 3 | // polyglot.js may be freely distributed under the terms of the BSD 4 | // license. For all licensing information, details, and documention: 5 | // http://airbnb.github.com/polyglot.js 6 | // 7 | // 8 | // Polyglot.js is an I18n helper library written in JavaScript, made to 9 | // work both in the browser and in Node. It provides a simple solution for 10 | // interpolation and pluralization, based off of Airbnb's 11 | // experience adding I18n functionality to its Backbone.js and Node apps. 12 | // 13 | // Polylglot is agnostic to your translation backend. It doesn't perform any 14 | // translation; it simply gives you a way to manage translated phrases from 15 | // your client- or server-side JavaScript application. 16 | // 17 | (function (root, factory) { 18 | if (typeof define === "function" && define.amd) { 19 | define([], function () { 20 | return factory(root); 21 | }); 22 | } 23 | else if (typeof exports === "object") { 24 | module.exports = factory(root); 25 | } 26 | else { 27 | root.Polyglot = factory(root); 28 | } 29 | }(typeof global !== "undefined" ? global : this, function (root) { 30 | "use strict"; 31 | var replace = String.prototype.replace; 32 | // ### Polyglot class constructor 33 | function Polyglot(options) { 34 | options = options || {}; 35 | this.phrases = {}; 36 | this.extend(options.phrases || {}); 37 | this.currentLocale = options.locale || "en"; 38 | this.allowMissing = !!options.allowMissing; 39 | this.warn = options.warn || warn; 40 | } 41 | // ### Version 42 | Polyglot.VERSION = "1.0.0"; 43 | // ### polyglot.locale([locale]) 44 | // 45 | // Get or set locale. Internally, Polyglot only uses locale for pluralization. 46 | Polyglot.prototype.locale = function (newLocale) { 47 | if (newLocale) 48 | this.currentLocale = newLocale; 49 | return this.currentLocale; 50 | }; 51 | // ### polyglot.extend(phrases) 52 | // 53 | // Use `extend` to tell Polyglot how to translate a given key. 54 | // 55 | // polyglot.extend({ 56 | // "hello": "Hello", 57 | // "hello_name": "Hello, %{name}" 58 | // }); 59 | // 60 | // The key can be any string. Feel free to call `extend` multiple times; 61 | // it will override any phrases with the same key, but leave existing phrases 62 | // untouched. 63 | // 64 | // It is also possible to pass nested phrase objects, which get flattened 65 | // into an object with the nested keys concatenated using dot notation. 66 | // 67 | // polyglot.extend({ 68 | // "nav": { 69 | // "hello": "Hello", 70 | // "hello_name": "Hello, %{name}", 71 | // "sidebar": { 72 | // "welcome": "Welcome" 73 | // } 74 | // } 75 | // }); 76 | // 77 | // console.log(polyglot.phrases); 78 | // // { 79 | // // 'nav.hello': 'Hello', 80 | // // 'nav.hello_name': 'Hello, %{name}', 81 | // // 'nav.sidebar.welcome': 'Welcome' 82 | // // } 83 | // 84 | // `extend` accepts an optional second argument, `prefix`, which can be used 85 | // to prefix every key in the phrases object with some string, using dot 86 | // notation. 87 | // 88 | // polyglot.extend({ 89 | // "hello": "Hello", 90 | // "hello_name": "Hello, %{name}" 91 | // }, "nav"); 92 | // 93 | // console.log(polyglot.phrases); 94 | // // { 95 | // // 'nav.hello': 'Hello', 96 | // // 'nav.hello_name': 'Hello, %{name}' 97 | // // } 98 | // 99 | // This feature is used internally to support nested phrase objects. 100 | Polyglot.prototype.extend = function (morePhrases, prefix) { 101 | var phrase; 102 | for (var key in morePhrases) { 103 | if (morePhrases.hasOwnProperty(key)) { 104 | phrase = morePhrases[key]; 105 | if (prefix) 106 | key = prefix + "." + key; 107 | if (typeof phrase === "object") { 108 | this.extend(phrase, key); 109 | } 110 | else { 111 | this.phrases[key] = phrase; 112 | } 113 | } 114 | } 115 | }; 116 | // ### polyglot.unset(phrases) 117 | // Use `unset` to selectively remove keys from a polyglot instance. 118 | // 119 | // polyglot.unset("some_key"); 120 | // polyglot.unset({ 121 | // "hello": "Hello", 122 | // "hello_name": "Hello, %{name}" 123 | // }); 124 | // 125 | // The unset method can take either a string (for the key), or an object hash with 126 | // the keys that you would like to unset. 127 | Polyglot.prototype.unset = function (morePhrases, prefix) { 128 | var phrase; 129 | if (typeof morePhrases === "string") { 130 | delete this.phrases[morePhrases]; 131 | } 132 | else { 133 | for (var key in morePhrases) { 134 | if (morePhrases.hasOwnProperty(key)) { 135 | phrase = morePhrases[key]; 136 | if (prefix) 137 | key = prefix + "." + key; 138 | if (typeof phrase === "object") { 139 | this.unset(phrase, key); 140 | } 141 | else { 142 | delete this.phrases[key]; 143 | } 144 | } 145 | } 146 | } 147 | }; 148 | // ### polyglot.clear() 149 | // 150 | // Clears all phrases. Useful for special cases, such as freeing 151 | // up memory if you have lots of phrases but no longer need to 152 | // perform any translation. Also used internally by `replace`. 153 | Polyglot.prototype.clear = function () { 154 | this.phrases = {}; 155 | }; 156 | // ### polyglot.replace(phrases) 157 | // 158 | // Completely replace the existing phrases with a new set of phrases. 159 | // Normally, just use `extend` to add more phrases, but under certain 160 | // circumstances, you may want to make sure no old phrases are lying around. 161 | Polyglot.prototype.replace = function (newPhrases) { 162 | this.clear(); 163 | this.extend(newPhrases); 164 | }; 165 | // ### polyglot.t(key, options) 166 | // 167 | // The most-used method. Provide a key, and `t` will return the 168 | // phrase. 169 | // 170 | // polyglot.t("hello"); 171 | // => "Hello" 172 | // 173 | // The phrase value is provided first by a call to `polyglot.extend()` or 174 | // `polyglot.replace()`. 175 | // 176 | // Pass in an object as the second argument to perform interpolation. 177 | // 178 | // polyglot.t("hello_name", {name: "Spike"}); 179 | // => "Hello, Spike" 180 | // 181 | // If you like, you can provide a default value in case the phrase is missing. 182 | // Use the special option key "_" to specify a default. 183 | // 184 | // polyglot.t("i_like_to_write_in_language", { 185 | // _: "I like to write in %{language}.", 186 | // language: "JavaScript" 187 | // }); 188 | // => "I like to write in JavaScript." 189 | // 190 | Polyglot.prototype.t = function (key, options) { 191 | var phrase, result; 192 | options = options == null ? {} : options; 193 | // allow number as a pluralization shortcut 194 | if (typeof options === "number") { 195 | options = { smart_count: options }; 196 | } 197 | if (typeof this.phrases[key] === "string") { 198 | phrase = this.phrases[key]; 199 | } 200 | else if (typeof options._ === "string") { 201 | phrase = options._; 202 | } 203 | else if (this.allowMissing) { 204 | phrase = key; 205 | } 206 | else { 207 | this.warn("Missing translation for key: \"" + key + "\""); 208 | result = key; 209 | } 210 | if (typeof phrase === "string") { 211 | options = clone(options); 212 | result = choosePluralForm(phrase, this.currentLocale, options.smart_count); 213 | result = interpolate(result, options); 214 | } 215 | return result; 216 | }; 217 | // ### polyglot.has(key) 218 | // 219 | // Check if polyglot has a translation for given key 220 | Polyglot.prototype.has = function (key) { 221 | return key in this.phrases; 222 | }; 223 | // #### Pluralization methods 224 | // The string that separates the different phrase possibilities. 225 | var delimeter = "||||"; 226 | // Mapping from pluralization group plural logic. 227 | var pluralTypes = { 228 | chinese: function (n) { return 0; }, 229 | german: function (n) { return n !== 1 ? 1 : 0; }, 230 | french: function (n) { return n > 1 ? 1 : 0; }, 231 | russian: function (n) { return n % 10 === 1 && n % 100 !== 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2; }, 232 | czech: function (n) { return (n === 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2; }, 233 | polish: function (n) { return (n === 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); }, 234 | icelandic: function (n) { return (n % 10 !== 1 || n % 100 === 11) ? 1 : 0; } 235 | }; 236 | // Mapping from pluralization group to individual locales. 237 | var pluralTypeToLanguages = { 238 | chinese: ["fa", "id", "ja", "ko", "lo", "ms", "th", "tr", "zh"], 239 | german: ["da", "de", "en", "es", "fi", "el", "he", "hu", "it", "nl", "no", "pt", "sv"], 240 | french: ["fr", "tl", "pt-br"], 241 | russian: ["hr", "ru"], 242 | czech: ["cs", "sk"], 243 | polish: ["pl"], 244 | icelandic: ["is"] 245 | }; 246 | function langToTypeMap(mapping) { 247 | var type, langs, l, ret = {}; 248 | for (type in mapping) { 249 | if (mapping.hasOwnProperty(type)) { 250 | langs = mapping[type]; 251 | for (l in langs) { 252 | ret[langs[l]] = type; 253 | } 254 | } 255 | } 256 | return ret; 257 | } 258 | // Trim a string. 259 | var trimRe = /^\s+|\s+$/g; 260 | function trim(str) { 261 | return replace.call(str, trimRe, ""); 262 | } 263 | // Based on a phrase text that contains `n` plural forms separated 264 | // by `delimeter`, a `locale`, and a `count`, choose the correct 265 | // plural form, or none if `count` is `null`. 266 | function choosePluralForm(text, locale, count) { 267 | var ret, texts, chosenText; 268 | if (count != null && text) { 269 | texts = text.split(delimeter); 270 | chosenText = texts[pluralTypeIndex(locale, count)] || texts[0]; 271 | ret = trim(chosenText); 272 | } 273 | else { 274 | ret = text; 275 | } 276 | return ret; 277 | } 278 | function pluralTypeName(locale) { 279 | var langToPluralType = langToTypeMap(pluralTypeToLanguages); 280 | return langToPluralType[locale] || langToPluralType.en; 281 | } 282 | function pluralTypeIndex(locale, count) { 283 | return pluralTypes[pluralTypeName(locale)](count); 284 | } 285 | // ### interpolate 286 | // 287 | // Does the dirty work. Creates a `RegExp` object for each 288 | // interpolation placeholder. 289 | var dollarRegex = /\$/g; 290 | var dollarBillsYall = "$$$$"; 291 | function interpolate(phrase, options) { 292 | for (var arg in options) { 293 | if (arg !== "_" && options.hasOwnProperty(arg)) { 294 | // Ensure replacement value is escaped to prevent special $-prefixed 295 | // regex replace tokens. the "$$$$" is needed because each "$" needs to 296 | // be escaped with "$" itself, and we need two in the resulting output. 297 | var replacement = options[arg]; 298 | if (typeof replacement === "string") { 299 | replacement = replace.call(options[arg], dollarRegex, dollarBillsYall); 300 | } 301 | // We create a new `RegExp` each time instead of using a more-efficient 302 | // string replace so that the same argument can be replaced multiple times 303 | // in the same phrase. 304 | phrase = replace.call(phrase, new RegExp("%\\{" + arg + "\\}", "g"), replacement); 305 | } 306 | } 307 | return phrase; 308 | } 309 | // ### warn 310 | // 311 | // Provides a warning in the console if a phrase key is missing. 312 | function warn(message) { 313 | // root.console && root.console.warn && root.console.warn('WARNING: ' + message); 314 | } 315 | // ### clone 316 | // 317 | // Clone an object. 318 | function clone(source) { 319 | var ret = {}; 320 | for (var prop in source) { 321 | ret[prop] = source[prop]; 322 | } 323 | return ret; 324 | } 325 | return Polyglot; 326 | })); 327 | -------------------------------------------------------------------------------- /assets/Script/libs/i18n/polyglot.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "6264fb3d-7bec-4fc5-9a63-6d429fa4a6f3", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/models.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "6ed8c6f2-08da-41c2-84ae-3e01d540de5a", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/models/AbstractModel.js: -------------------------------------------------------------------------------- 1 | var AbstractModel = (function () { 2 | function AbstractModel() { 3 | } 4 | Object.defineProperty(AbstractModel.prototype, "view", { 5 | get: function () { 6 | return this._view; 7 | }, 8 | set: function (value) { 9 | this._view = value; 10 | }, 11 | enumerable: true, 12 | configurable: true 13 | }); 14 | Object.defineProperty(AbstractModel.prototype, "controller", { 15 | get: function () { 16 | return this._controller; 17 | }, 18 | set: function (value) { 19 | this._controller = value; 20 | }, 21 | enumerable: true, 22 | configurable: true 23 | }); 24 | return AbstractModel; 25 | }()); 26 | export { AbstractModel }; 27 | -------------------------------------------------------------------------------- /assets/Script/models/AbstractModel.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "e150b404-5b7b-454a-b89d-f8eb4428587b", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/models/HelloModel.js: -------------------------------------------------------------------------------- 1 | import { AbstractModel } from "./AbstractModel"; 2 | var HelloModel = (function (_super) { 3 | __extends(HelloModel, _super); 4 | function HelloModel() { 5 | var _this = _super.apply(this, arguments) || this; 6 | _this.serverAddress = "http://52.58.118.63"; 7 | return _this; 8 | } 9 | //noinspection JSMethodCanBeStatic 10 | HelloModel.prototype.getIP = function () { 11 | return __awaiter(this, void 0, void 0, function () { 12 | var res, e_1; 13 | return __generator(this, function (_a) { 14 | switch (_a.label) { 15 | case 0: 16 | _a.trys.push([0, 3, , 4]); 17 | return [4 /*yield*/, fetch(this.serverAddress + "/getIP.php")]; 18 | case 1: 19 | res = _a.sent(); 20 | return [4 /*yield*/, res.json()]; 21 | case 2: return [2 /*return*/, _a.sent()]; 22 | case 3: 23 | e_1 = _a.sent(); 24 | cc.log(e_1); 25 | return [2 /*return*/, { code: 1, data: null }]; 26 | case 4: return [2 /*return*/]; 27 | } 28 | }); 29 | }); 30 | }; 31 | //noinspection JSMethodCanBeStatic 32 | HelloModel.prototype.getIPInfo = function (ip) { 33 | return __awaiter(this, void 0, void 0, function () { 34 | var res, e_2; 35 | return __generator(this, function (_a) { 36 | switch (_a.label) { 37 | case 0: 38 | _a.trys.push([0, 3, , 4]); 39 | return [4 /*yield*/, fetch(this.serverAddress + "/getIPInfo.php?ip=" + ip)]; 40 | case 1: 41 | res = _a.sent(); 42 | return [4 /*yield*/, res.json()]; 43 | case 2: return [2 /*return*/, _a.sent()]; 44 | case 3: 45 | e_2 = _a.sent(); 46 | cc.log(e_2); 47 | return [2 /*return*/, { code: 2, data: null }]; 48 | case 4: return [2 /*return*/]; 49 | } 50 | }); 51 | }); 52 | }; 53 | return HelloModel; 54 | }(AbstractModel)); 55 | export { HelloModel }; 56 | -------------------------------------------------------------------------------- /assets/Script/models/HelloModel.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "f6e0f5cf-cc0a-4631-aa74-577d1c0c42b3", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/plugins.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "2e3e0d9e-e5ae-442b-8f7e-a7349e8d4f50", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/plugins/Fetch.js: -------------------------------------------------------------------------------- 1 | !function (t, e) { "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : t.ES6Promise = e(); }(this, function () { 2 | "use strict"; 3 | function t(t) { return "function" == typeof t || "object" == typeof t && null !== t; } 4 | function e(t) { return "function" == typeof t; } 5 | function n(t) { I = t; } 6 | function r(t) { J = t; } 7 | function o() { return function () { return process.nextTick(a); }; } 8 | function i() { return "undefined" != typeof H ? function () { H(a); } : c(); } 9 | function s() { var t = 0, e = new V(a), n = document.createTextNode(""); return e.observe(n, { characterData: !0 }), function () { n.data = t = ++t % 2; }; } 10 | function u() { var t = new MessageChannel; return t.port1.onmessage = a, function () { return t.port2.postMessage(0); }; } 11 | function c() { var t = setTimeout; return function () { return t(a, 1); }; } 12 | function a() { for (var t = 0; t < G; t += 2) { 13 | var e = $[t], n = $[t + 1]; 14 | e(n), $[t] = void 0, $[t + 1] = void 0; 15 | } G = 0; } 16 | function f() { try { 17 | var t = require, e = t("vertx"); 18 | return H = e.runOnLoop || e.runOnContext, i(); 19 | } 20 | catch (n) { 21 | return c(); 22 | } } 23 | function l(t, e) { var n = arguments, r = this, o = new this.constructor(p); void 0 === o[et] && k(o); var i = r._state; return i ? !function () { var t = n[i - 1]; J(function () { return x(i, o, t, r._result); }); }() : E(r, o, t, e), o; } 24 | function h(t) { var e = this; if (t && "object" == typeof t && t.constructor === e) 25 | return t; var n = new e(p); return g(n, t), n; } 26 | function p() { } 27 | function v() { return new TypeError("You cannot resolve a promise with itself"); } 28 | function d() { return new TypeError("A promises callback cannot return that same promise."); } 29 | function _(t) { try { 30 | return t.then; 31 | } 32 | catch (e) { 33 | return it.error = e, it; 34 | } } 35 | function y(t, e, n, r) { try { 36 | t.call(e, n, r); 37 | } 38 | catch (o) { 39 | return o; 40 | } } 41 | function m(t, e, n) { J(function (t) { var r = !1, o = y(n, e, function (n) { r || (r = !0, e !== n ? g(t, n) : S(t, n)); }, function (e) { r || (r = !0, j(t, e)); }, "Settle: " + (t._label || " unknown promise")); !r && o && (r = !0, j(t, o)); }, t); } 42 | function b(t, e) { e._state === rt ? S(t, e._result) : e._state === ot ? j(t, e._result) : E(e, void 0, function (e) { return g(t, e); }, function (e) { return j(t, e); }); } 43 | function w(t, n, r) { n.constructor === t.constructor && r === l && n.constructor.resolve === h ? b(t, n) : r === it ? j(t, it.error) : void 0 === r ? S(t, n) : e(r) ? m(t, n, r) : S(t, n); } 44 | function g(e, n) { e === n ? j(e, v()) : t(n) ? w(e, n, _(n)) : S(e, n); } 45 | function A(t) { t._onerror && t._onerror(t._result), P(t); } 46 | function S(t, e) { t._state === nt && (t._result = e, t._state = rt, 0 !== t._subscribers.length && J(P, t)); } 47 | function j(t, e) { t._state === nt && (t._state = ot, t._result = e, J(A, t)); } 48 | function E(t, e, n, r) { var o = t._subscribers, i = o.length; t._onerror = null, o[i] = e, o[i + rt] = n, o[i + ot] = r, 0 === i && t._state && J(P, t); } 49 | function P(t) { var e = t._subscribers, n = t._state; if (0 !== e.length) { 50 | for (var r = void 0, o = void 0, i = t._result, s = 0; s < e.length; s += 3) 51 | r = e[s], o = e[s + n], r ? x(n, r, o, i) : o(i); 52 | t._subscribers.length = 0; 53 | } } 54 | function T() { this.error = null; } 55 | function M(t, e) { try { 56 | return t(e); 57 | } 58 | catch (n) { 59 | return st.error = n, st; 60 | } } 61 | function x(t, n, r, o) { var i = e(r), s = void 0, u = void 0, c = void 0, a = void 0; if (i) { 62 | if (s = M(r, o), s === st ? (a = !0, u = s.error, s = null) : c = !0, n === s) 63 | return void j(n, d()); 64 | } 65 | else 66 | s = o, c = !0; n._state !== nt || (i && c ? g(n, s) : a ? j(n, u) : t === rt ? S(n, s) : t === ot && j(n, s)); } 67 | function C(t, e) { try { 68 | e(function (e) { g(t, e); }, function (e) { j(t, e); }); 69 | } 70 | catch (n) { 71 | j(t, n); 72 | } } 73 | function O() { return ut++; } 74 | function k(t) { t[et] = ut++, t._state = void 0, t._result = void 0, t._subscribers = []; } 75 | function Y(t, e) { this._instanceConstructor = t, this.promise = new t(p), this.promise[et] || k(this.promise), B(e) ? (this._input = e, this.length = e.length, this._remaining = e.length, this._result = new Array(this.length), 0 === this.length ? S(this.promise, this._result) : (this.length = this.length || 0, this._enumerate(), 0 === this._remaining && S(this.promise, this._result))) : j(this.promise, q()); } 76 | function q() { return new Error("Array Methods must be provided an Array"); } 77 | function F(t) { return new Y(this, t).promise; } 78 | function D(t) { var e = this; return new e(B(t) ? function (n, r) { for (var o = t.length, i = 0; i < o; i++) 79 | e.resolve(t[i]).then(n, r); } : function (t, e) { return e(new TypeError("You must pass an array to race.")); }); } 80 | function K(t) { var e = this, n = new e(p); return j(n, t), n; } 81 | function L() { throw new TypeError("You must pass a resolver function as the first argument to the promise constructor"); } 82 | function N() { throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); } 83 | function U(t) { this[et] = O(), this._result = this._state = void 0, this._subscribers = [], p !== t && ("function" != typeof t && L(), this instanceof U ? C(this, t) : N()); } 84 | function W() { var t = void 0; if ("undefined" != typeof global) 85 | t = global; 86 | else if ("undefined" != typeof self) 87 | t = self; 88 | else 89 | try { 90 | t = Function("return this")(); 91 | } 92 | catch (e) { 93 | throw new Error("polyfill failed because global object is unavailable in this environment"); 94 | } var n = t.Promise; if (n) { 95 | var r = null; 96 | try { 97 | r = Object.prototype.toString.call(n.resolve()); 98 | } 99 | catch (e) { } 100 | if ("[object Promise]" === r && !n.cast) 101 | return; 102 | } t.Promise = U; } 103 | var z = void 0; 104 | z = Array.isArray ? Array.isArray : function (t) { return "[object Array]" === Object.prototype.toString.call(t); }; 105 | var B = z, G = 0, H = void 0, I = void 0, J = function (t, e) { $[G] = t, $[G + 1] = e, G += 2, 2 === G && (I ? I(a) : tt()); }, Q = "undefined" != typeof window ? window : void 0, R = Q || {}, V = R.MutationObserver || R.WebKitMutationObserver, X = "undefined" == typeof self && "undefined" != typeof process && "[object process]" === {}.toString.call(process), Z = "undefined" != typeof Uint8ClampedArray && "undefined" != typeof importScripts && "undefined" != typeof MessageChannel, $ = new Array(1e3), tt = void 0; 106 | tt = X ? o() : V ? s() : Z ? u() : void 0 === Q && "function" == typeof require ? f() : c(); 107 | var et = Math.random().toString(36).substring(16), nt = void 0, rt = 1, ot = 2, it = new T, st = new T, ut = 0; 108 | return Y.prototype._enumerate = function () { for (var t = this.length, e = this._input, n = 0; this._state === nt && n < t; n++) 109 | this._eachEntry(e[n], n); }, Y.prototype._eachEntry = function (t, e) { var n = this._instanceConstructor, r = n.resolve; if (r === h) { 110 | var o = _(t); 111 | if (o === l && t._state !== nt) 112 | this._settledAt(t._state, e, t._result); 113 | else if ("function" != typeof o) 114 | this._remaining--, this._result[e] = t; 115 | else if (n === U) { 116 | var i = new n(p); 117 | w(i, t, o), this._willSettleAt(i, e); 118 | } 119 | else 120 | this._willSettleAt(new n(function (e) { return e(t); }), e); 121 | } 122 | else 123 | this._willSettleAt(r(t), e); }, Y.prototype._settledAt = function (t, e, n) { var r = this.promise; r._state === nt && (this._remaining--, t === ot ? j(r, n) : this._result[e] = n), 0 === this._remaining && S(r, this._result); }, Y.prototype._willSettleAt = function (t, e) { var n = this; E(t, void 0, function (t) { return n._settledAt(rt, e, t); }, function (t) { return n._settledAt(ot, e, t); }); }, U.all = F, U.race = D, U.resolve = h, U.reject = K, U._setScheduler = n, U._setAsap = r, U._asap = J, U.prototype = { constructor: U, then: l, "catch": function (t) { return this.then(null, t); } }, U.polyfill = W, U.Promise = U, U; 124 | }), ES6Promise.polyfill(); 125 | (function (self) { 126 | 'use strict'; 127 | if (self.fetch) { 128 | return; 129 | } 130 | function normalizeName(name) { 131 | if (typeof name !== 'string') { 132 | name = name.toString(); 133 | } 134 | if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) { 135 | throw new TypeError('Invalid character in header field name'); 136 | } 137 | return name.toLowerCase(); 138 | } 139 | function normalizeValue(value) { 140 | if (typeof value !== 'string') { 141 | value = value.toString(); 142 | } 143 | return value; 144 | } 145 | function Headers(headers) { 146 | this.map = {}; 147 | var self = this; 148 | if (headers instanceof Headers) { 149 | headers.forEach(function (name, values) { 150 | values.forEach(function (value) { 151 | self.append(name, value); 152 | }); 153 | }); 154 | } 155 | else if (headers) { 156 | Object.getOwnPropertyNames(headers).forEach(function (name) { 157 | self.append(name, headers[name]); 158 | }); 159 | } 160 | } 161 | Headers.prototype.append = function (name, value) { 162 | name = normalizeName(name); 163 | value = normalizeValue(value); 164 | var list = this.map[name]; 165 | if (!list) { 166 | list = []; 167 | this.map[name] = list; 168 | } 169 | list.push(value); 170 | }; 171 | Headers.prototype['delete'] = function (name) { 172 | delete this.map[normalizeName(name)]; 173 | }; 174 | Headers.prototype.get = function (name) { 175 | var values = this.map[normalizeName(name)]; 176 | return values ? values[0] : null; 177 | }; 178 | Headers.prototype.getAll = function (name) { 179 | return this.map[normalizeName(name)] || []; 180 | }; 181 | Headers.prototype.has = function (name) { 182 | return this.map.hasOwnProperty(normalizeName(name)); 183 | }; 184 | Headers.prototype.set = function (name, value) { 185 | this.map[normalizeName(name)] = [normalizeValue(value)]; 186 | }; 187 | // Instead of iterable for now. 188 | Headers.prototype.forEach = function (callback) { 189 | var self = this; 190 | Object.getOwnPropertyNames(this.map).forEach(function (name) { 191 | callback(name, self.map[name]); 192 | }); 193 | }; 194 | function consumed(body) { 195 | if (body.bodyUsed) { 196 | return fetch.Promise.reject(new TypeError('Already read')); 197 | } 198 | body.bodyUsed = true; 199 | } 200 | function fileReaderReady(reader) { 201 | return new fetch.Promise(function (resolve, reject) { 202 | reader.onload = function () { 203 | resolve(reader.result); 204 | }; 205 | reader.onerror = function () { 206 | reject(reader.error); 207 | }; 208 | }); 209 | } 210 | function readBlobAsArrayBuffer(blob) { 211 | var reader = new FileReader(); 212 | reader.readAsArrayBuffer(blob); 213 | return fileReaderReady(reader); 214 | } 215 | function readBlobAsText(blob) { 216 | var reader = new FileReader(); 217 | reader.readAsText(blob); 218 | return fileReaderReady(reader); 219 | } 220 | var support = { 221 | blob: 'FileReader' in self && 'Blob' in self && (function () { 222 | try { 223 | new Blob(); 224 | return true; 225 | } 226 | catch (e) { 227 | return false; 228 | } 229 | })(), 230 | formData: 'FormData' in self 231 | }; 232 | function Body() { 233 | this.bodyUsed = false; 234 | this._initBody = function (body) { 235 | this._bodyInit = body; 236 | if (typeof body === 'string') { 237 | this._bodyText = body; 238 | } 239 | else if (support.blob && Blob.prototype.isPrototypeOf(body)) { 240 | this._bodyBlob = body; 241 | } 242 | else if (support.formData && FormData.prototype.isPrototypeOf(body)) { 243 | this._bodyFormData = body; 244 | } 245 | else if (!body) { 246 | this._bodyText = ''; 247 | } 248 | else { 249 | throw new Error('unsupported BodyInit type'); 250 | } 251 | }; 252 | if (support.blob) { 253 | this.blob = function () { 254 | var rejected = consumed(this); 255 | if (rejected) { 256 | return rejected; 257 | } 258 | if (this._bodyBlob) { 259 | return fetch.Promise.resolve(this._bodyBlob); 260 | } 261 | else if (this._bodyFormData) { 262 | throw new Error('could not read FormData body as blob'); 263 | } 264 | else { 265 | return fetch.Promise.resolve(new Blob([this._bodyText])); 266 | } 267 | }; 268 | this.arrayBuffer = function () { 269 | return this.blob().then(readBlobAsArrayBuffer); 270 | }; 271 | this.text = function () { 272 | var rejected = consumed(this); 273 | if (rejected) { 274 | return rejected; 275 | } 276 | if (this._bodyBlob) { 277 | return readBlobAsText(this._bodyBlob); 278 | } 279 | else if (this._bodyFormData) { 280 | throw new Error('could not read FormData body as text'); 281 | } 282 | else { 283 | return fetch.Promise.resolve(this._bodyText); 284 | } 285 | }; 286 | } 287 | else { 288 | this.text = function () { 289 | var rejected = consumed(this); 290 | return rejected ? rejected : fetch.Promise.resolve(this._bodyText); 291 | }; 292 | } 293 | if (support.formData) { 294 | this.formData = function () { 295 | return this.text().then(decode); 296 | }; 297 | } 298 | this.json = function () { 299 | return this.text().then(function (text) { 300 | return JSON.parse(text); 301 | }); 302 | }; 303 | return this; 304 | } 305 | // HTTP methods whose capitalization should be normalized 306 | var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']; 307 | function normalizeMethod(method) { 308 | var upcased = method.toUpperCase(); 309 | return (methods.indexOf(upcased) > -1) ? upcased : method; 310 | } 311 | function Request(url, options) { 312 | options = options || {}; 313 | this.url = url; 314 | this.credentials = options.credentials || 'omit'; 315 | this.headers = new Headers(options.headers); 316 | this.method = normalizeMethod(options.method || 'GET'); 317 | this.mode = options.mode || null; 318 | this.referrer = null; 319 | if ((this.method === 'GET' || this.method === 'HEAD') && options.body) { 320 | throw new TypeError('Body not allowed for GET or HEAD requests'); 321 | } 322 | this._initBody(options.body); 323 | } 324 | function decode(body) { 325 | var form = new FormData(); 326 | body.trim().split('&').forEach(function (bytes) { 327 | if (bytes) { 328 | var split = bytes.split('='); 329 | var name = split.shift().replace(/\+/g, ' '); 330 | var value = split.join('=').replace(/\+/g, ' '); 331 | form.append(decodeURIComponent(name), decodeURIComponent(value)); 332 | } 333 | }); 334 | return form; 335 | } 336 | function headers(xhr) { 337 | var head = new Headers(); 338 | var pairs = xhr.getAllResponseHeaders().trim().split('\n'); 339 | pairs.forEach(function (header) { 340 | var split = header.trim().split(':'); 341 | var key = split.shift().trim(); 342 | var value = split.join(':').trim(); 343 | head.append(key, value); 344 | }); 345 | return head; 346 | } 347 | var noXhrPatch = typeof window !== 'undefined' && !!window.ActiveXObject && !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent); 348 | function getXhr() { 349 | // from backbone.js 1.1.2 350 | // https://github.com/jashkenas/backbone/blob/1.1.2/backbone.js#L1181 351 | if (noXhrPatch && !(/^(get|post|head|put|delete|options)$/i.test(this.method))) { 352 | this.usingActiveXhr = true; 353 | return new ActiveXObject("Microsoft.XMLHTTP"); 354 | } 355 | return new XMLHttpRequest(); 356 | } 357 | Body.call(Request.prototype); 358 | function Response(bodyInit, options) { 359 | if (!options) { 360 | options = {}; 361 | } 362 | this._initBody(bodyInit); 363 | this.type = 'default'; 364 | this.url = null; 365 | this.status = options.status; 366 | this.ok = this.status >= 200 && this.status < 300; 367 | this.statusText = options.statusText; 368 | this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers); 369 | this.url = options.url || ''; 370 | } 371 | Body.call(Response.prototype); 372 | self.Headers = Headers; 373 | self.Request = Request; 374 | self.Response = Response; 375 | self.fetch = function (input, init) { 376 | // TODO: Request constructor should accept input, init 377 | var request; 378 | if (Request.prototype.isPrototypeOf(input) && !init) { 379 | request = input; 380 | } 381 | else { 382 | request = new Request(input, init); 383 | } 384 | return new fetch.Promise(function (resolve, reject) { 385 | var xhr = getXhr(); 386 | if (request.credentials === 'cors') { 387 | xhr.withCredentials = true; 388 | } 389 | function responseURL() { 390 | if ('responseURL' in xhr) { 391 | return xhr.responseURL; 392 | } 393 | // Avoid security warnings on getResponseHeader when not allowed by CORS 394 | if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) { 395 | return xhr.getResponseHeader('X-Request-URL'); 396 | } 397 | return; 398 | } 399 | function onload() { 400 | if (xhr.readyState !== 4) { 401 | return; 402 | } 403 | var status = (xhr.status === 1223) ? 204 : xhr.status; 404 | if (status < 100 || status > 599) { 405 | reject(new TypeError('Network request failed')); 406 | return; 407 | } 408 | var options = { 409 | status: status, 410 | statusText: xhr.statusText, 411 | headers: headers(xhr), 412 | url: responseURL() 413 | }; 414 | var body = 'response' in xhr ? xhr.response : xhr.responseText; 415 | resolve(new Response(body, options)); 416 | } 417 | xhr.onreadystatechange = onload; 418 | if (!self.usingActiveXhr) { 419 | xhr.onload = onload; 420 | xhr.onerror = function () { 421 | reject(new TypeError('Network request failed')); 422 | }; 423 | } 424 | xhr.open(request.method, request.url, true); 425 | if ('responseType' in xhr && support.blob) { 426 | xhr.responseType = 'blob'; 427 | } 428 | request.headers.forEach(function (name, values) { 429 | values.forEach(function (value) { 430 | xhr.setRequestHeader(name, value); 431 | }); 432 | }); 433 | xhr.send(); 434 | }); 435 | }; 436 | fetch.Promise = self.Promise; // you could change it to your favorite alternative 437 | self.fetch.polyfill = true; 438 | })(window); 439 | -------------------------------------------------------------------------------- /assets/Script/plugins/Fetch.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "d76a8e98-dacc-445c-9b06-eb58fd813ebc", 4 | "isPlugin": true, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/plugins/TypeScriptHelper.js: -------------------------------------------------------------------------------- 1 | window.__extends = function (d, b) { 2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 3 | function __() { this.constructor = d; } 4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 5 | }; 6 | window.__assign = Object.assign || function (t) { 7 | for (var s, i = 1, n = arguments.length; i < n; i++) { 8 | s = arguments[i]; 9 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 10 | } 11 | return t; 12 | }; 13 | window.__rest = function (s, e) { 14 | var t = {}; 15 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 16 | t[p] = s[p]; 17 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 18 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) 19 | t[p[i]] = s[p[i]]; 20 | return t; 21 | }; 22 | window.__decorate = function (decorators, target, key, desc) { 23 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 24 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 25 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 26 | return c > 3 && r && Object.defineProperty(target, key, r), r; 27 | }; 28 | window.__param = function (paramIndex, decorator) { 29 | return function (target, key) { decorator(target, key, paramIndex); } 30 | }; 31 | window.__metadata = function (metadataKey, metadataValue) { 32 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 33 | }; 34 | window.__awaiter = function (thisArg, _arguments, P, generator) { 35 | return new (P || (P = Promise))(function (resolve, reject) { 36 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 37 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 38 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 39 | step((generator = generator.apply(thisArg, _arguments)).next()); 40 | }); 41 | }; 42 | window.__generator = function (thisArg, body) { 43 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; 44 | return { next: verb(0), "throw": verb(1), "return": verb(2) }; 45 | function verb(n) { return function (v) { return step([n, v]); }; } 46 | function step(op) { 47 | if (f) throw new TypeError("Generator is already executing."); 48 | while (_) try { 49 | if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; 50 | if (y = 0, t) op = [0, t.value]; 51 | switch (op[0]) { 52 | case 0: case 1: t = op; break; 53 | case 4: _.label++; return { value: op[1], done: false }; 54 | case 5: _.label++; y = op[1]; op = [0]; continue; 55 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 56 | default: 57 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 58 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 59 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 60 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 61 | if (t[2]) _.ops.pop(); 62 | _.trys.pop(); continue; 63 | } 64 | op = body.call(thisArg, _); 65 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 66 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 67 | } 68 | }; -------------------------------------------------------------------------------- /assets/Script/plugins/TypeScriptHelper.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "aee5d507-1c06-477e-8e5b-1e0ee059c749", 4 | "isPlugin": true, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/views.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "aec1c71c-227d-4633-86f9-b0620a7ec26f", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Script/views/AbstractComponent.js: -------------------------------------------------------------------------------- 1 | import { CCComponent } from "../decorators/ComponentDecorators"; 2 | import { AbstractSimpleComponent } from "./AbstractSimpleComponent"; 3 | var AbstractComponent = (function (_super) { 4 | __extends(AbstractComponent, _super); 5 | function AbstractComponent() { 6 | return _super.apply(this, arguments) || this; 7 | } 8 | Object.defineProperty(AbstractComponent.prototype, "model", { 9 | get: function () { 10 | return this._model; 11 | }, 12 | set: function (value) { 13 | this._model = value; 14 | }, 15 | enumerable: true, 16 | configurable: true 17 | }); 18 | Object.defineProperty(AbstractComponent.prototype, "controller", { 19 | get: function () { 20 | return this._controller; 21 | }, 22 | set: function (value) { 23 | this._controller = value; 24 | }, 25 | enumerable: true, 26 | configurable: true 27 | }); 28 | return AbstractComponent; 29 | }(AbstractSimpleComponent)); 30 | AbstractComponent = __decorate([ 31 | CCComponent 32 | ], AbstractComponent); 33 | export { AbstractComponent }; 34 | -------------------------------------------------------------------------------- /assets/Script/views/AbstractComponent.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "375cf74b-c517-47b5-95f6-d78082e9a472", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/views/AbstractSimpleComponent.js: -------------------------------------------------------------------------------- 1 | import { CCComponent } from "../decorators/ComponentDecorators"; 2 | var AbstractSimpleComponent = (function (_super) { 3 | __extends(AbstractSimpleComponent, _super); 4 | function AbstractSimpleComponent() { 5 | return _super.apply(this, arguments) || this; 6 | } 7 | return AbstractSimpleComponent; 8 | }(cc.Component)); 9 | AbstractSimpleComponent = __decorate([ 10 | CCComponent 11 | ], AbstractSimpleComponent); 12 | export { AbstractSimpleComponent }; 13 | -------------------------------------------------------------------------------- /assets/Script/views/AbstractSimpleComponent.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "e256f4de-a62d-439c-9291-07ade240beb2", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Script/views/HelloView.js: -------------------------------------------------------------------------------- 1 | import { CCComponent, CCProperty, CCEditor } from "../decorators/ComponentDecorators"; 2 | import { AbstractComponent } from "./AbstractComponent"; 3 | import { HelloController } from "../controllers/HelloController"; 4 | var HelloView = (function (_super) { 5 | __extends(HelloView, _super); 6 | function HelloView() { 7 | return _super.apply(this, arguments) || this; 8 | } 9 | HelloView.prototype.onLoad = function () { 10 | this.initLabels(); 11 | this.controller = new HelloController(); 12 | this.controller.init(this); 13 | this.move10(); 14 | }; 15 | HelloView.prototype.initLabels = function () { 16 | this.ipLabel.string = "正在加载IP..."; 17 | this.countryLabel.string = ""; 18 | this.cityLabel.string = ""; 19 | this.countyLabel.string = ""; 20 | }; 21 | HelloView.prototype.updateIP = function (res) { 22 | if (res.code == 0 && res.data !== null) { 23 | this.ipLabel.string = res.data.ip; 24 | this.countryLabel.string = "正在加载国家信息"; 25 | this.cityLabel.string = "正在加载城市信息"; 26 | this.countyLabel.string = "正在加载区域信息"; 27 | } 28 | else { 29 | this.ipLabel.string = "获取IP失败"; 30 | } 31 | }; 32 | HelloView.prototype.updateIPInfo = function (res) { 33 | if (res.code == 0 && res.data !== null) { 34 | this.countryLabel.string = res.data.country; 35 | this.cityLabel.string = res.data.city; 36 | this.countyLabel.string = res.data.county; 37 | } 38 | else { 39 | this.countryLabel.string = "加载国家信息失败"; 40 | this.cityLabel.string = "加载城市信息失败"; 41 | this.countyLabel.string = "加载区域信息失败"; 42 | } 43 | }; 44 | HelloView.prototype.move10 = function () { 45 | return __awaiter(this, void 0, void 0, function () { 46 | var i; 47 | return __generator(this, function (_a) { 48 | switch (_a.label) { 49 | case 0: 50 | i = 0; 51 | _a.label = 1; 52 | case 1: 53 | if (!(i < 10)) 54 | return [3 /*break*/, 4]; 55 | return [4 /*yield*/, this.asyncRunAction(this.ipLabel.node, cc.sequence(cc.moveBy(0.5, -10, 0), cc.moveBy(0.5, 10, 0)))]; 56 | case 2: 57 | _a.sent(); 58 | _a.label = 3; 59 | case 3: 60 | i++; 61 | return [3 /*break*/, 1]; 62 | case 4: return [2 /*return*/]; 63 | } 64 | }); 65 | }); 66 | }; 67 | HelloView.prototype.asyncRunAction = function (node, action) { 68 | return __awaiter(this, void 0, void 0, function () { 69 | return __generator(this, function (_a) { 70 | return [2 /*return*/, new Promise(function (resolve, reject) { 71 | node.runAction(cc.sequence(action, cc.callFunc(resolve))); 72 | })]; 73 | }); 74 | }); 75 | }; 76 | return HelloView; 77 | }(AbstractComponent)); 78 | __decorate([ 79 | CCProperty(cc.Label) 80 | ], HelloView.prototype, "ipLabel", void 0); 81 | __decorate([ 82 | CCProperty(cc.Label) 83 | ], HelloView.prototype, "countryLabel", void 0); 84 | __decorate([ 85 | CCProperty(cc.Label) 86 | ], HelloView.prototype, "cityLabel", void 0); 87 | __decorate([ 88 | CCProperty(cc.Label) 89 | ], HelloView.prototype, "countyLabel", void 0); 90 | HelloView = __decorate([ 91 | CCEditor({ 92 | executeInEditMode: true 93 | }), 94 | CCComponent 95 | ], HelloView); 96 | export { HelloView }; 97 | -------------------------------------------------------------------------------- /assets/Script/views/HelloView.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.2", 3 | "uuid": "109f0cb0-be67-449a-8e02-dfa72f313044", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "subMetas": {} 8 | } -------------------------------------------------------------------------------- /assets/Texture.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.1", 3 | "uuid": "7b81d4e8-ec84-4716-968d-500ac1d78a54", 4 | "isGroup": false, 5 | "subMetas": {} 6 | } -------------------------------------------------------------------------------- /assets/Texture/HelloWorld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddlxt/Creator-TypeScript-Boilerplate/2c9d7438e8a8cec4ce98878ec53a114df896a0f6/assets/Texture/HelloWorld.png -------------------------------------------------------------------------------- /assets/Texture/HelloWorld.png.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "6aa0aa6a-ebee-4155-a088-a687a6aadec4", 4 | "type": "sprite", 5 | "wrapMode": "clamp", 6 | "filterMode": "bilinear", 7 | "subMetas": { 8 | "HelloWorld": { 9 | "ver": "1.0.3", 10 | "uuid": "31bc895a-c003-4566-a9f3-2e54ae1c17dc", 11 | "rawTextureUuid": "6aa0aa6a-ebee-4155-a088-a687a6aadec4", 12 | "trimType": "auto", 13 | "trimThreshold": 1, 14 | "rotated": false, 15 | "offsetX": 0, 16 | "offsetY": 0, 17 | "trimX": 0, 18 | "trimY": 0, 19 | "width": 195, 20 | "height": 270, 21 | "rawWidth": 195, 22 | "rawHeight": 270, 23 | "borderTop": 0, 24 | "borderBottom": 0, 25 | "borderLeft": 0, 26 | "borderRight": 0, 27 | "subMetas": {} 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /assets/Texture/singleColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddlxt/Creator-TypeScript-Boilerplate/2c9d7438e8a8cec4ce98878ec53a114df896a0f6/assets/Texture/singleColor.png -------------------------------------------------------------------------------- /assets/Texture/singleColor.png.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "a8027877-d8d6-4645-97a0-52d4a0123dba", 4 | "type": "sprite", 5 | "wrapMode": "clamp", 6 | "filterMode": "bilinear", 7 | "subMetas": { 8 | "singleColor": { 9 | "ver": "1.0.3", 10 | "uuid": "410fb916-8721-4663-bab8-34397391ace7", 11 | "rawTextureUuid": "a8027877-d8d6-4645-97a0-52d4a0123dba", 12 | "trimType": "auto", 13 | "trimThreshold": 1, 14 | "rotated": false, 15 | "offsetX": 0, 16 | "offsetY": 0, 17 | "trimX": 0, 18 | "trimY": 0, 19 | "width": 2, 20 | "height": 2, 21 | "rawWidth": 2, 22 | "rawHeight": 2, 23 | "borderTop": 0, 24 | "borderBottom": 0, 25 | "borderLeft": 0, 26 | "borderRight": 0, 27 | "subMetas": {} 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs" 5 | }, 6 | "exclude": [ 7 | "node_modules", 8 | "library", 9 | "local", 10 | "settings", 11 | "temp" 12 | ] 13 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Creator-TypeScript-Boilerplate", 3 | "version": "0.1.0", 4 | "dependencies": { 5 | "fetch-polyfill": "^0.8.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "engine": "cocos2d-html5", 3 | "packages": "packages" 4 | } -------------------------------------------------------------------------------- /settings/builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "excludeScenes": [], 3 | "orientation": { 4 | "landscapeLeft": true, 5 | "landscapeRight": true, 6 | "portrait": false, 7 | "upsideDown": false 8 | }, 9 | "packageName": "org.cocos2d.helloworld", 10 | "startScene": "2d2f792f-a40c-49bb-a189-ed176a246e49", 11 | "title": "hello_world", 12 | "webOrientation": "auto" 13 | } -------------------------------------------------------------------------------- /settings/builder.panel.json: -------------------------------------------------------------------------------- 1 | { 2 | "excludeScenes": [], 3 | "packageName": "org.cocos2d.helloworld", 4 | "platform": "web-mobile", 5 | "startScene": "2d2f792f-a40c-49bb-a189-ed176a246e49", 6 | "title": "HelloWorld" 7 | } -------------------------------------------------------------------------------- /settings/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "collision-matrix": [ 3 | [ 4 | true 5 | ] 6 | ], 7 | "excluded-modules": [], 8 | "group-list": [ 9 | "default" 10 | ], 11 | "start-scene": "2d2f792f-a40c-49bb-a189-ed176a246e49" 12 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "target": "es5", 5 | "noImplicitReturns": true, 6 | "outDir": "assets/Script/", 7 | "allowJs": true, 8 | "lib": ["dom", "es5", "es2015.promise"], 9 | "allowSyntheticDefaultImports": true, 10 | "experimentalDecorators": true, 11 | "pretty": true, 12 | "noEmitHelpers": true 13 | }, 14 | "include": [ 15 | "typescript/**/*" 16 | ], 17 | "exclude": [ 18 | "node_modules", 19 | "assets" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /typescript/controllers/AbstractController.ts: -------------------------------------------------------------------------------- 1 | import {AbstractComponent} from "../views/AbstractComponent"; 2 | import {AbstractModel} from "../models/AbstractModel"; 3 | export abstract class AbstractController, TModel extends AbstractModel> { 4 | public get view(): TView { 5 | return this._view; 6 | } 7 | 8 | public set view(value: TView) { 9 | this._view = value; 10 | } 11 | 12 | public get model(): TModel { 13 | return this._model; 14 | } 15 | 16 | public set model(value: TModel) { 17 | this._model = value; 18 | } 19 | 20 | private _model: TModel; 21 | private _view: TView; 22 | } -------------------------------------------------------------------------------- /typescript/controllers/HelloController.ts: -------------------------------------------------------------------------------- 1 | import {AbstractController} from "./AbstractController"; 2 | import {HelloModel} from "../models/HelloModel"; 3 | import {HelloView} from "../views/HelloView"; 4 | export class HelloController extends AbstractController { 5 | public init(view: HelloView) { 6 | this.view = view; 7 | this.model = new HelloModel(); 8 | this.hello(); 9 | } 10 | 11 | private async hello() { 12 | let ipResult = await this.model.getIP(); 13 | this.view.updateIP(ipResult); 14 | if (ipResult.code == 0 && ipResult.data !== null) { 15 | let ipInfoResult = await this.model.getIPInfo(ipResult.data.ip); 16 | this.view.updateIPInfo(ipInfoResult); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /typescript/decorators/CCClass/CCClass1.3.js: -------------------------------------------------------------------------------- 1 | var JS = cc.js; 2 | var Enum = cc.Enum; 3 | var _isPlainEmptyObj_DEV = function (obj) { 4 | if (!obj || obj.constructor !== Object) { 5 | return false; 6 | } 7 | for (var k in obj) { 8 | return false; 9 | } 10 | return true; 11 | }; 12 | var _cloneable_DEV = function (obj) { 13 | return obj && typeof obj.clone === 'function' && 14 | (obj.constructor.prototype.hasOwnProperty('clone') || obj.hasOwnProperty('clone')); 15 | }; 16 | var Attr = cc.Class.Attr; 17 | var getTypeChecker = Attr.getTypeChecker; 18 | var SerializableAttrs = { 19 | url: { 20 | canUsedInGet: true 21 | }, 22 | default: {}, 23 | serializable: {}, 24 | editorOnly: {}, 25 | rawType: {}, 26 | }; 27 | function parseNotify(val, propName, notify, properties) { 28 | if (val.get || val.set) { 29 | if (CC_DEV) { 30 | cc.warn('"notify" can\'t work with "get/set" !'); 31 | } 32 | return; 33 | } 34 | if (val.hasOwnProperty('default')) { 35 | var newKey = "_N$" + propName; 36 | val.get = function () { 37 | return this[newKey]; 38 | }; 39 | val.set = function (value) { 40 | var oldValue = this[newKey]; 41 | this[newKey] = value; 42 | notify.call(this, oldValue); 43 | }; 44 | var newValue = {}; 45 | properties[newKey] = newValue; 46 | for (var attr in SerializableAttrs) { 47 | var v = SerializableAttrs[attr]; 48 | if (val.hasOwnProperty(attr)) { 49 | newValue[attr] = val[attr]; 50 | if (!v.canUsedInGet) { 51 | delete val[attr]; 52 | } 53 | } 54 | } 55 | } 56 | else if (CC_DEV) { 57 | cc.warn('"notify" must work with "default" !'); 58 | } 59 | } 60 | function checkUrl(val, className, propName, url) { 61 | if (Array.isArray(url)) { 62 | if (url.length > 0) { 63 | url = url[0]; 64 | } 65 | else if (CC_EDITOR) { 66 | return cc.error('Invalid url of %s.%s', className, propName); 67 | } 68 | } 69 | if (CC_EDITOR) { 70 | if (url == null) { 71 | return cc.warn('The "url" attribute of "%s.%s" is undefined when loading script.', className, propName); 72 | } 73 | if (typeof url !== 'function' || !cc.isChildClassOf(url, cc.RawAsset)) { 74 | return cc.error('The "url" type of "%s.%s" must be child class of cc.RawAsset.', className, propName); 75 | } 76 | if (cc.isChildClassOf(url, cc.Asset)) { 77 | return cc.error('The "url" type of "%s.%s" must not be child class of cc.Asset, ' + 78 | 'otherwise you should use "type: %s" instead.', className, propName, cc.js.getClassName(url)); 79 | } 80 | if (val.type) { 81 | return cc.warn('Can not specify "type" attribute for "%s.%s", because its "url" is already defined.', className, propName); 82 | } 83 | } 84 | val.type = url; 85 | } 86 | function parseType(val, type, className, propName) { 87 | if (Array.isArray(type)) { 88 | if (CC_EDITOR) { 89 | var isArray = function (defaultVal) { 90 | defaultVal = getDefault(defaultVal); 91 | return Array.isArray(defaultVal); 92 | }; 93 | if (!isArray(val.default)) { 94 | cc.warn('The "default" attribute of "%s.%s" must be an array', className, propName); 95 | } 96 | } 97 | if (type.length > 0) { 98 | val.type = type = type[0]; 99 | } 100 | else { 101 | return cc.error('Invalid type of %s.%s', className, propName); 102 | } 103 | } 104 | if (CC_EDITOR) { 105 | if (typeof type === 'function') { 106 | if (cc.RawAsset.isRawAssetType(type)) { 107 | cc.warn('The "type" attribute of "%s.%s" must be child class of cc.Asset, ' + 108 | 'otherwise you should use "url: %s" instead', className, propName, cc.js.getClassName(type)); 109 | } 110 | } 111 | else if (type === 'Number') { 112 | cc.warn('The "type" attribute of "%s.%s" can not be "Number", use "Float" or "Integer" instead please.', className, propName); 113 | } 114 | else if (type == null) { 115 | cc.warn('The "type" attribute of "%s.%s" is undefined when loading script.', className, propName); 116 | } 117 | } 118 | } 119 | function postCheckType(val, type, className, propName) { 120 | if (CC_EDITOR && typeof type === 'function') { 121 | if (cc.Class._isCCClass(type) && val.serializable !== false && !cc.js._getClassId(type, false)) { 122 | cc.warn('Can not serialize "%s.%s" because the specified type is anonymous, please provide a class name or set the "serializable" attribute of "%s.%s" to "false".', className, propName, className, propName); 123 | } 124 | } 125 | } 126 | function getBaseClassWherePropertyDefined_DEV(propName, cls) { 127 | if (CC_DEV) { 128 | var res; 129 | for (; cls && cls.__props__ && cls.__props__.indexOf(propName) !== -1; cls = cls.$super) { 130 | res = cls; 131 | } 132 | if (!res) { 133 | cc.error('unknown error'); 134 | } 135 | return res; 136 | } 137 | } 138 | var preprocessAttrs = function (properties, className, cls) { 139 | for (var propName in properties) { 140 | var val = properties[propName]; 141 | var isLiteral = val && val.constructor === Object; 142 | if (!isLiteral) { 143 | if (Array.isArray(val) && val.length > 0) { 144 | val = { 145 | default: [], 146 | type: val 147 | }; 148 | } 149 | else if (typeof val === 'function') { 150 | var type = val; 151 | if (cc.RawAsset.isRawAssetType(type)) { 152 | val = { 153 | default: '', 154 | url: type 155 | }; 156 | } 157 | else { 158 | val = cc.isChildClassOf(type, cc.ValueType) ? { 159 | default: new type() 160 | } : { 161 | default: null, 162 | type: val 163 | }; 164 | } 165 | } 166 | else { 167 | val = { 168 | default: val 169 | }; 170 | } 171 | properties[propName] = val; 172 | } 173 | if (val) { 174 | if (CC_EDITOR) { 175 | if ('default' in val) { 176 | if (val.get) { 177 | cc.error('The "default" value of "%s.%s" should not be used with a "get" function.', className, propName); 178 | } 179 | else if (val.set) { 180 | cc.error('The "default" value of "%s.%s" should not be used with a "set" function.', className, propName); 181 | } 182 | } 183 | else if (!val.get && !val.set) { 184 | cc.error('Property "%s.%s" must define at least one of "default", "get" or "set".', className, propName); 185 | } 186 | } 187 | if (CC_DEV && !val.override && cls.__props__.indexOf(propName) !== -1) { 188 | var baseClass = cc.js.getClassName(getBaseClassWherePropertyDefined_DEV(propName, cls)); 189 | cc.warn('"%s.%s" hides inherited property "%s.%s". To make the current property override that implementation, add the `override: true` attribute please.', className, propName, baseClass, propName); 190 | } 191 | var notify = val.notify; 192 | if (notify) { 193 | parseNotify(val, propName, notify, properties); 194 | } 195 | if ('type' in val) { 196 | parseType(val, val.type, className, propName); 197 | } 198 | if ('url' in val) { 199 | checkUrl(val, className, propName, val.url); 200 | } 201 | if ('type' in val) { 202 | postCheckType(val, val.type, className, propName); 203 | } 204 | } 205 | } 206 | }; 207 | var BUILTIN_ENTRIES = ['name', 'extends', 'mixins', 'ctor', 'properties', 'statics', 'editor']; 208 | var TYPO_TO_CORRECT = CC_DEV && { 209 | extend: 'extends', 210 | property: 'properties', 211 | static: 'statics', 212 | constructor: 'ctor' 213 | }; 214 | var INVALID_STATICS = CC_DEV && ['name', '__ctors__', '__props__', 'arguments', 'call', 'apply', 'caller', 215 | 'length', 'prototype']; 216 | var deferredInitializer = { 217 | datas: null, 218 | push: function (data) { 219 | if (this.datas) { 220 | this.datas.push(data); 221 | } 222 | else { 223 | this.datas = [data]; 224 | var self = this; 225 | setTimeout(function () { 226 | self.init(); 227 | }, 0); 228 | } 229 | }, 230 | init: function () { 231 | var datas = this.datas; 232 | if (datas) { 233 | for (var i = 0; i < datas.length; ++i) { 234 | var data = datas[i]; 235 | var cls = data.cls; 236 | var properties = data.props; 237 | if (typeof properties === 'function') { 238 | properties = properties(); 239 | } 240 | var name = JS.getClassName(cls); 241 | if (properties) { 242 | declareProperties(cls, name, properties, cls.$super, data.mixins); 243 | } 244 | else { 245 | cc.error('Properties function of "%s" should return an object!', name); 246 | } 247 | } 248 | this.datas = null; 249 | } 250 | } 251 | }; 252 | function appendProp(cls, name) { 253 | if (CC_DEV) { 254 | if (name.indexOf('.') !== -1) { 255 | cc.error('Disallow to use "." in property name'); 256 | return; 257 | } 258 | } 259 | var index = cls.__props__.indexOf(name); 260 | if (index < 0) { 261 | cls.__props__.push(name); 262 | } 263 | } 264 | function defineProp(cls, className, propName, defaultValue, attrs) { 265 | if (CC_DEV) { 266 | if (typeof defaultValue === 'object' && defaultValue) { 267 | if (Array.isArray(defaultValue)) { 268 | if (defaultValue.length > 0) { 269 | cc.error('Default array must be empty, set default value of %s.%s to [], ' + 270 | 'and initialize in "onLoad" or "ctor" please. (just like "this.%s = [...];")', className, propName, propName); 271 | return; 272 | } 273 | } 274 | else if (!_isPlainEmptyObj_DEV(defaultValue)) { 275 | if (!_cloneable_DEV(defaultValue)) { 276 | cc.error('Do not set default value to non-empty object, ' + 277 | 'unless the object defines its own "clone" function. Set default value of %s.%s to null or {}, ' + 278 | 'and initialize in "onLoad" or "ctor" please. (just like "this.%s = {foo: bar};")', className, propName, propName); 279 | return; 280 | } 281 | } 282 | } 283 | for (var base = cls.$super; base; base = base.$super) { 284 | if (base.prototype.hasOwnProperty(propName)) { 285 | cc.error('Can not declare %s.%s, it is already defined in the prototype of %s', className, propName, className); 286 | return; 287 | } 288 | } 289 | } 290 | Attr.setClassAttr(cls, propName, 'default', defaultValue); 291 | appendProp(cls, propName); 292 | if (attrs) { 293 | var onAfterProp = null; 294 | for (var i = 0; i < attrs.length; i++) { 295 | var attr = attrs[i]; 296 | Attr.attr(cls, propName, attr); 297 | if (attr._onAfterProp) { 298 | onAfterProp = onAfterProp || []; 299 | onAfterProp.push(attr._onAfterProp); 300 | } 301 | } 302 | if (onAfterProp) { 303 | for (var c = 0; c < onAfterProp.length; c++) { 304 | onAfterProp[c](cls, propName); 305 | } 306 | } 307 | } 308 | } 309 | function defineGetSet(cls, name, propName, val, attrs) { 310 | var getter = val.get; 311 | var setter = val.set; 312 | var proto = cls.prototype; 313 | var d = Object.getOwnPropertyDescriptor(proto, propName); 314 | if (getter) { 315 | if (CC_DEV && d && d.get) { 316 | cc.error('"%s": the getter of "%s" is already defined!', name, propName); 317 | return; 318 | } 319 | if (attrs) { 320 | for (var i = 0; i < attrs.length; ++i) { 321 | var attr = attrs[i]; 322 | if (CC_DEV && attr._canUsedInGetter === false) { 323 | cc.error('Can not apply the specified attribute to the getter of "%s.%s", ' + 324 | 'attribute index: %s', name, propName, i); 325 | continue; 326 | } 327 | Attr.attr(cls, propName, attr); 328 | if (CC_DEV && (attr.serializable === false || attr.editorOnly === true)) { 329 | cc.warn('No need to use "serializable: false" or "editorOnly: true" for ' + 330 | 'the getter of "%s.%s", every getter is actually non-serialized.', name, propName); 331 | } 332 | } 333 | } 334 | var ForceSerializable = false; 335 | if (!ForceSerializable) { 336 | Attr.attr(cls, propName, Attr.NonSerialized); 337 | } 338 | if (ForceSerializable || CC_DEV) { 339 | appendProp(cls, propName); 340 | } 341 | if (d) { 342 | Object.defineProperty(proto, propName, { 343 | get: getter 344 | }); 345 | } 346 | else { 347 | Object.defineProperty(proto, propName, { 348 | get: getter, 349 | configurable: true, 350 | enumerable: true 351 | }); 352 | } 353 | if (CC_DEV) { 354 | Attr.setClassAttr(cls, propName, 'hasGetter', true); 355 | } 356 | } 357 | if (setter) { 358 | if (CC_DEV) { 359 | if (d && d.set) { 360 | return cc.error('"%s": the setter of "%s" is already defined!', name, propName); 361 | } 362 | Object.defineProperty(proto, propName, { 363 | set: setter, 364 | configurable: true, 365 | enumerable: true 366 | }); 367 | Attr.setClassAttr(cls, propName, 'hasSetter', true); 368 | } 369 | else { 370 | if (d) { 371 | Object.defineProperty(proto, propName, { 372 | set: setter 373 | }); 374 | } 375 | else { 376 | Object.defineProperty(proto, propName, { 377 | set: setter, 378 | configurable: true, 379 | enumerable: true 380 | }); 381 | } 382 | } 383 | } 384 | } 385 | function getDefault(defaultVal) { 386 | if (typeof defaultVal === 'function') { 387 | if (CC_EDITOR) { 388 | try { 389 | return defaultVal(); 390 | } 391 | catch (e) { 392 | cc._throw(e); 393 | return undefined; 394 | } 395 | } 396 | else { 397 | return defaultVal(); 398 | } 399 | } 400 | return defaultVal; 401 | } 402 | var DELIMETER = Attr.DELIMETER; 403 | function instantiateProps(instance, itsClass) { 404 | var attrs = Attr.getClassAttrs(itsClass); 405 | var propList = itsClass.__props__; 406 | if (propList === null) { 407 | deferredInitializer.init(); 408 | propList = itsClass.__props__; 409 | } 410 | for (var i = 0; i < propList.length; i++) { 411 | var prop = propList[i]; 412 | var attrKey = prop + DELIMETER + 'default'; 413 | if (attrKey in attrs) { 414 | var def = attrs[attrKey]; 415 | if (def) { 416 | if (typeof def === 'object' && def) { 417 | if (typeof def.clone === 'function') { 418 | def = def.clone(); 419 | } 420 | else if (Array.isArray(def)) { 421 | def = []; 422 | } 423 | else { 424 | def = {}; 425 | } 426 | } 427 | else if (typeof def === 'function') { 428 | def = getDefault(def); 429 | } 430 | } 431 | instance[prop] = def; 432 | } 433 | } 434 | } 435 | function doDefine(className, baseClass, mixins, constructor, options) { 436 | var fireClass = _createCtor(constructor, baseClass, mixins, className, options); 437 | Object.defineProperty(fireClass, 'extend', { 438 | value: function (options) { 439 | options.extends = this; 440 | return CCClass(options); 441 | }, 442 | writable: true, 443 | configurable: true 444 | }); 445 | if (baseClass) { 446 | JS.extend(fireClass, baseClass); 447 | fireClass.$super = baseClass; 448 | } 449 | if (mixins) { 450 | for (var m = 0; m < mixins.length; ++m) { 451 | var mixin = mixins[m]; 452 | JS.mixin(fireClass.prototype, mixin.prototype); 453 | for (var p in mixin) 454 | if (mixin.hasOwnProperty(p) && INVALID_STATICS.indexOf(p) < 0) 455 | fireClass[p] = mixin[p]; 456 | if (CCClass._isCCClass(mixin)) { 457 | JS.mixin(Attr.getClassAttrs(fireClass).constructor.prototype, Attr.getClassAttrs(mixin).constructor.prototype); 458 | } 459 | } 460 | fireClass.prototype.constructor = fireClass; 461 | } 462 | JS.setClassName(className, fireClass); 463 | return fireClass; 464 | } 465 | function define(className, baseClasses, mixins, constructor, options) { 466 | if (cc.isChildClassOf(baseClasses, cc.Component)) { 467 | var frame = cc._RFpeek(); 468 | if (frame) { 469 | if (CC_DEV && constructor) { 470 | cc.warn('Should not define constructor for cc.Component %s.', className); 471 | } 472 | if (frame.beh) { 473 | cc.error('Each script can have at most one Component.'); 474 | return cls; 475 | } 476 | var uuid = frame.uuid; 477 | if (uuid) { 478 | if (CC_EDITOR && className) { 479 | cc.warn('Should not specify class name %s for Component which defines in project.', className); 480 | } 481 | } 482 | className = className || frame.script; 483 | var cls = doDefine(className, baseClasses, mixins, constructor, options); 484 | if (uuid) { 485 | JS._setClassId(uuid, cls); 486 | if (CC_EDITOR) { 487 | cc.Component._addMenuItem(cls, 'i18n:MAIN_MENU.component.scripts/' + className, -1); 488 | cls.prototype.__scriptUuid = Editor.UuidUtils.decompressUuid(uuid); 489 | } 490 | } 491 | frame.beh = cls; 492 | return cls; 493 | } 494 | } 495 | return doDefine(className, baseClasses, mixins, constructor, options); 496 | } 497 | function _checkCtor(ctor, className) { 498 | if (CC_DEV) { 499 | if (CCClass._isCCClass(ctor)) { 500 | cc.error('ctor of "%s" can not be another CCClass', className); 501 | return; 502 | } 503 | if (typeof ctor !== 'function') { 504 | cc.error('ctor of "%s" must be function type', className); 505 | return; 506 | } 507 | if (ctor.length > 0) { 508 | cc.warn('Can not instantiate CCClass "%s" with arguments.', className); 509 | return; 510 | } 511 | } 512 | } 513 | function normalizeClassName(className) { 514 | if (CC_DEV) { 515 | var DefaultName = 'CCClass'; 516 | if (className) { 517 | className = className.replace(/\./g, '_'); 518 | className = className.split('').filter(function (x) { return /^[a-zA-Z0-9_$]/.test(x); }).join(''); 519 | if (/^[0-9]/.test(className[0])) { 520 | className = '_' + className; 521 | } 522 | try { 523 | eval('function ' + className + '(){}'); 524 | } 525 | catch (e) { 526 | className = 'FireClass_' + className; 527 | try { 528 | eval('function ' + className + '(){}'); 529 | } 530 | catch (e) { 531 | return DefaultName; 532 | } 533 | } 534 | return className; 535 | } 536 | return DefaultName; 537 | } 538 | } 539 | function _createCtor(ctor, baseClass, mixins, className, options) { 540 | var useTryCatch = !(className && className.startsWith('cc.')); 541 | var shouldAddProtoCtor; 542 | if (CC_EDITOR && ctor && baseClass) { 543 | var originCtor = ctor; 544 | if (SuperCallReg.test(ctor)) { 545 | cc.warn(cc._LogInfos.Editor.Class.callSuperCtor, className); 546 | ctor = function () { 547 | this._super = function () { }; 548 | var ret = originCtor.apply(this, arguments); 549 | this._super = null; 550 | return ret; 551 | }; 552 | } 553 | if (/\bprototype.ctor\b/.test(originCtor)) { 554 | cc.warn(cc._LogInfos.Editor.Class.callSuperCtor, className); 555 | shouldAddProtoCtor = true; 556 | } 557 | } 558 | var superCallBounded = options && baseClass && boundSuperCalls(baseClass, options); 559 | if (ctor && CC_DEV) { 560 | _checkCtor(ctor, className); 561 | } 562 | var ctors = []; 563 | var baseOrMixins = [baseClass].concat(mixins); 564 | for (var b = 0; b < baseOrMixins.length; b++) { 565 | var baseOrMixin = baseOrMixins[b]; 566 | if (baseOrMixin) { 567 | if (CCClass._isCCClass(baseOrMixin)) { 568 | var baseCtors = baseOrMixin.__ctors__; 569 | if (baseCtors) { 570 | ctors = ctors.concat(baseCtors); 571 | } 572 | } 573 | else if (baseOrMixin) { 574 | ctors.push(baseOrMixin); 575 | } 576 | } 577 | } 578 | if (ctor) { 579 | ctors.push(ctor); 580 | } 581 | var body; 582 | if (CC_DEV) { 583 | body = '(function ' + normalizeClassName(className) + '(){\n'; 584 | } 585 | else { 586 | body = '(function(){\n'; 587 | } 588 | if (superCallBounded) { 589 | body += 'this._super=null;\n'; 590 | } 591 | body += 'instantiateProps(this,fireClass);\n'; 592 | if (ctors.length > 0) { 593 | body += 'var cs=fireClass.__ctors__;\n'; 594 | if (useTryCatch) { 595 | body += 'try{\n'; 596 | } 597 | if (ctors.length <= 5) { 598 | for (var i = 0; i < ctors.length; i++) { 599 | body += '(cs[' + i + ']).apply(this,arguments);\n'; 600 | } 601 | } 602 | else { 603 | body += 'for(var i=0,l=cs.length;i 0 ? ctors : null, 614 | }); 615 | if (CC_EDITOR && shouldAddProtoCtor) { 616 | fireClass.prototype.ctor = function () { }; 617 | } 618 | return fireClass; 619 | } 620 | var SuperCallReg = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/; 621 | function _boundSuperCall(func, funcName, base) { 622 | var superFunc = null; 623 | var pd = JS.getPropertyDescriptor(base.prototype, funcName); 624 | if (pd) { 625 | superFunc = pd.value; 626 | if (typeof superFunc === 'function') { 627 | var hasSuperCall = SuperCallReg.test(func); 628 | if (hasSuperCall) { 629 | return function () { 630 | var tmp = this._super; 631 | this._super = superFunc; 632 | var ret = func.apply(this, arguments); 633 | this._super = tmp; 634 | return ret; 635 | }; 636 | } 637 | } 638 | } 639 | return null; 640 | } 641 | function boundSuperCalls(baseClass, options) { 642 | var hasSuperCall = false; 643 | for (var funcName in options) { 644 | if (BUILTIN_ENTRIES.indexOf(funcName) < 0) { 645 | var func = options[funcName]; 646 | if (typeof func === 'function') { 647 | var bounded = _boundSuperCall(func, funcName, baseClass); 648 | if (bounded) { 649 | hasSuperCall = true; 650 | options[funcName] = bounded; 651 | } 652 | } 653 | } 654 | } 655 | return hasSuperCall; 656 | } 657 | function declareProperties(cls, className, properties, baseClass, mixins) { 658 | cls.__props__ = []; 659 | if (baseClass && baseClass.__props__) { 660 | cls.__props__ = baseClass.__props__.slice(); 661 | } 662 | if (mixins) { 663 | for (var m = 0; m < mixins.length; ++m) { 664 | var mixin = mixins[m]; 665 | if (mixin.__props__) { 666 | cls.__props__ = cls.__props__.concat(mixin.__props__.filter(function (x) { 667 | return cls.__props__.indexOf(x) < 0; 668 | })); 669 | } 670 | } 671 | } 672 | if (properties) { 673 | preprocessAttrs(properties, className, cls); 674 | for (var propName in properties) { 675 | var val = properties[propName]; 676 | var attrs = parseAttributes(val, className, propName); 677 | if ('default' in val) { 678 | defineProp(cls, className, propName, val.default, attrs); 679 | } 680 | else { 681 | defineGetSet(cls, className, propName, val, attrs); 682 | } 683 | } 684 | } 685 | } 686 | function CCClass(options) { 687 | if (arguments.length === 0) { 688 | return define(); 689 | } 690 | if (!options) { 691 | cc.error('cc.Class: Option must be non-nil'); 692 | return define(); 693 | } 694 | var name = options.name; 695 | var base = options.extends; 696 | var mixins = options.mixins; 697 | var cls; 698 | cls = define(name, base, mixins, options.ctor, options); 699 | if (!name) { 700 | name = cc.js.getClassName(cls); 701 | } 702 | var properties = options.properties; 703 | if (typeof properties === 'function' || 704 | (base && base.__props__ === null) || 705 | (mixins && mixins.some(function (x) { 706 | return x.__props__ === null; 707 | }))) { 708 | deferredInitializer.push({ cls: cls, props: properties, mixins: mixins }); 709 | cls.__props__ = null; 710 | } 711 | else { 712 | declareProperties(cls, name, properties, base, options.mixins); 713 | } 714 | var statics = options.statics; 715 | if (statics) { 716 | var staticPropName; 717 | if (CC_DEV) { 718 | for (staticPropName in statics) { 719 | if (INVALID_STATICS.indexOf(staticPropName) !== -1) { 720 | cc.error('Cannot define %s.%s because static member name can not be "%s".', name, staticPropName, staticPropName); 721 | } 722 | } 723 | } 724 | for (staticPropName in statics) { 725 | cls[staticPropName] = statics[staticPropName]; 726 | } 727 | } 728 | for (var funcName in options) { 729 | if (BUILTIN_ENTRIES.indexOf(funcName) >= 0) { 730 | continue; 731 | } 732 | if (CC_EDITOR && funcName === 'constructor') { 733 | cc.error('Can not define a member called "constructor" in the class "%s", please use "ctor" instead.', name); 734 | continue; 735 | } 736 | var func = options[funcName]; 737 | if (typeof func === 'function' || func === null) { 738 | Object.defineProperty(cls.prototype, funcName, { 739 | value: func, 740 | enumerable: true, 741 | configurable: true, 742 | writable: true, 743 | }); 744 | } 745 | else if (CC_DEV) { 746 | if (func === false && base && base.prototype) { 747 | var overrided = base.prototype[funcName]; 748 | if (typeof overrided === 'function') { 749 | var baseFuc = JS.getClassName(base) + '.' + funcName; 750 | var subFuc = name + '.' + funcName; 751 | cc.warn('"%s" overrided "%s" but "%s" is defined as "false" so the super method will not be called. You can set "%s" to null to disable this warning.', subFuc, baseFuc, subFuc, subFuc); 752 | } 753 | } 754 | var correct = TYPO_TO_CORRECT[funcName]; 755 | if (correct) { 756 | cc.warn('Unknown type of %s.%s, maybe you want is "%s".', name, funcName, correct); 757 | } 758 | else if (func) { 759 | cc.error('Unknown type of %s.%s, property should be defined in "properties" or "ctor"', name, funcName); 760 | } 761 | } 762 | } 763 | if (CC_DEV) { 764 | var editor = options.editor; 765 | if (editor) { 766 | if (cc.isChildClassOf(base, cc.Component)) { 767 | cc.Component._registerEditorProps(cls, editor); 768 | } 769 | else { 770 | cc.warn('Can not use "editor" attribute, "%s" not inherits from Components.', name); 771 | } 772 | } 773 | } 774 | return cls; 775 | } 776 | CCClass._isCCClass = function (constructor) { 777 | return !!constructor && typeof constructor.__ctors__ !== 'undefined'; 778 | }; 779 | var PrimitiveTypes = { 780 | Integer: 'Number', 781 | Float: 'Number', 782 | Boolean: 'Boolean', 783 | String: 'String', 784 | }; 785 | var tmpAttrs = []; 786 | function parseAttributes(attrs, className, propName) { 787 | var ERR_Type = CC_DEV ? 'The %s of %s must be type %s' : ''; 788 | tmpAttrs.length = 0; 789 | var result = tmpAttrs; 790 | var type = attrs.type; 791 | if (type) { 792 | var primitiveType = PrimitiveTypes[type]; 793 | if (primitiveType) { 794 | result.push({ 795 | type: type, 796 | _onAfterProp: getTypeChecker(primitiveType, 'cc.' + type) 797 | }); 798 | } 799 | else if (type === 'Object') { 800 | if (CC_DEV) { 801 | cc.error('Please define "type" parameter of %s.%s as the actual constructor.', className, propName); 802 | } 803 | } 804 | else { 805 | if (type === Attr.ScriptUuid) { 806 | var attr = Attr.ObjectType(cc.ScriptAsset); 807 | attr.type = 'Script'; 808 | result.push(attr); 809 | } 810 | else { 811 | if (typeof type === 'object') { 812 | if (Enum.isEnum(type)) { 813 | result.push({ 814 | type: 'Enum', 815 | enumList: Enum.getList(type) 816 | }); 817 | } 818 | else if (CC_DEV) { 819 | cc.error('Please define "type" parameter of %s.%s as the constructor of %s.', className, propName, type); 820 | } 821 | } 822 | else if (typeof type === 'function') { 823 | if (attrs.url) { 824 | result.push({ 825 | type: 'Object', 826 | ctor: type, 827 | _onAfterProp: getTypeChecker('String', 'cc.String') 828 | }); 829 | } 830 | else { 831 | result.push(Attr.ObjectType(type)); 832 | } 833 | } 834 | else if (CC_DEV) { 835 | cc.error('Unknown "type" parameter of %s.%s:%s', className, propName, type); 836 | } 837 | } 838 | } 839 | } 840 | function parseSimpleAttr(attrName, expectType, attrCreater) { 841 | if (attrName in attrs) { 842 | var val = attrs[attrName]; 843 | if (typeof val === expectType) { 844 | if (!attrCreater) { 845 | var attr = {}; 846 | attr[attrName] = val; 847 | result.push(attr); 848 | } 849 | else { 850 | result.push(typeof attrCreater === 'function' ? attrCreater(val) : attrCreater); 851 | } 852 | } 853 | else if (CC_DEV) { 854 | cc.error(ERR_Type, attrName, className, propName, expectType); 855 | } 856 | } 857 | } 858 | parseSimpleAttr('rawType', 'string', Attr.RawType); 859 | parseSimpleAttr('editorOnly', 'boolean', Attr.EditorOnly); 860 | if (CC_DEV) { 861 | parseSimpleAttr('displayName', 'string'); 862 | parseSimpleAttr('multiline', 'boolean', { multiline: true }); 863 | parseSimpleAttr('readonly', 'boolean', { readonly: true }); 864 | parseSimpleAttr('tooltip', 'string'); 865 | parseSimpleAttr('slide', 'boolean'); 866 | } 867 | if (attrs.url) { 868 | result.push({ saveUrlAsAsset: true }); 869 | } 870 | if (attrs.serializable === false) { 871 | result.push(Attr.NonSerialized); 872 | } 873 | if (CC_EDITOR) { 874 | if ('animatable' in attrs && !attrs.animatable) { 875 | result.push({ animatable: false }); 876 | } 877 | } 878 | if (CC_DEV) { 879 | var visible = attrs.visible; 880 | if (typeof visible !== 'undefined') { 881 | if (!visible) { 882 | result.push({ visible: false }); 883 | } 884 | else if (typeof visible === 'function') { 885 | result.push({ visible: visible }); 886 | } 887 | } 888 | else { 889 | var startsWithUS = (propName.charCodeAt(0) === 95); 890 | if (startsWithUS) { 891 | result.push({ visible: false }); 892 | } 893 | } 894 | } 895 | var range = attrs.range; 896 | if (range) { 897 | if (Array.isArray(range)) { 898 | if (range.length >= 2) { 899 | result.push({ min: range[0], max: range[1], step: range[2] }); 900 | } 901 | else if (CC_DEV) { 902 | cc.error('The length of range array must be equal or greater than 2'); 903 | } 904 | } 905 | else if (CC_DEV) { 906 | cc.error(ERR_Type, 'range', className, propName, 'array'); 907 | } 908 | } 909 | parseSimpleAttr('min', 'number'); 910 | parseSimpleAttr('max', 'number'); 911 | parseSimpleAttr('step', 'number'); 912 | return result; 913 | } 914 | module.exports = { 915 | define: define, 916 | declareProperties: declareProperties 917 | }; -------------------------------------------------------------------------------- /typescript/decorators/ComponentDecorators.ts: -------------------------------------------------------------------------------- 1 | import {define as define13, declareProperties as declareProperties13} from "./CCClass/CCClass1.3"; 2 | import {define as define14, declareProperties as declareProperties14} from "./CCClass/CCClass1.4"; 3 | let define, declareProperties; 4 | // CCClass of v1.4.x is different. 5 | if (/^1.4/.test(cc.ENGINE_VERSION)) { 6 | define = define14; 7 | declareProperties = declareProperties14; 8 | } else { 9 | define = define13; 10 | declareProperties = declareProperties13; 11 | } 12 | declare interface ICCProperty { 13 | type?: any; 14 | visible?: boolean; 15 | displayName?: string; 16 | tooltip?: string; 17 | multiline?: boolean; 18 | readonly?: boolean; 19 | min?: number; 20 | max?: number; 21 | step?: number; 22 | range?: Array; 23 | slide?: boolean; 24 | serializable?: boolean; 25 | editorOnly?: boolean; 26 | default?: any; 27 | url?: any; 28 | notify?: (oldValue: any)=>void; 29 | override?: boolean; 30 | animatable?: boolean; 31 | get?: ()=>any; 32 | set?: (newValue: any)=>void 33 | } 34 | declare interface ICCProperties { 35 | [propertyName: string]: ICCProperty 36 | } 37 | declare interface ICCEditor { 38 | requireComponent?: cc.Component; 39 | disallowMultiple?: cc.Component; 40 | menu?: string; 41 | executeInEditMode?: boolean; 42 | playOnFocus?: boolean; 43 | inspector?: string; 44 | icon?: string; 45 | help?: string; 46 | } 47 | let currentProperties: {[uuid: string]: ICCProperties} = {}; 48 | let currentMixins: {[uuid: string]: Array} = {}; 49 | let currentEditor: {[uuid: string]: ICCEditor} = {}; 50 | let defined: {[uuid: string]: boolean} = {}; 51 | let definedClass: {[uuid: string]: any} = {}; 52 | // Get the UUID of currently compiling script 53 | function getUUID() { 54 | return cc._RFpeek().uuid; 55 | } 56 | // Get the name of currently compiling script 57 | function getScriptName() { 58 | return cc._RFpeek().script; 59 | } 60 | /* 61 | Decorator of components that inherit cc.Component. Usage: 62 | -------------------------- 63 | @CCComponent 64 | export class ComponentName extends cc.Component {} 65 | -------------------------- 66 | */ 67 | export function CCComponent(constructor) { 68 | if (constructor.length > 0) { 69 | cc.warn(`Please do not define parameters for a component constructor in ${getScriptName()}!`); 70 | } 71 | let uuid = getUUID(); 72 | if (defined[uuid]) return definedClass[uuid]; 73 | constructor.$super = cc.Component; 74 | let cls = define(void 0, constructor, currentMixins[uuid], void 0, {}); 75 | let name = cc.js.getClassName(cls); 76 | declareProperties(cls, name, currentProperties[uuid], constructor, void 0); 77 | if (currentEditor.hasOwnProperty(uuid)) { 78 | cc.Component._registerEditorProps(constructor, currentEditor[uuid]); 79 | } 80 | currentProperties = {}; 81 | currentMixins = {}; 82 | currentEditor = {}; 83 | defined[uuid] = true; 84 | definedClass[uuid] = cls; 85 | return cls; 86 | } 87 | /* 88 | Decorator of a property in cc.Component. 89 | @CCProperty must be used with @CCComponent. Usage: 90 | -------------------------- 91 | @CCComponent 92 | export class ComponentName extends cc.Component { 93 | @CCProperty({ 94 | default: null, 95 | type: cc.Node 96 | }) 97 | public someNode: cc.Node; 98 | @CCProperty(cc.Button) 99 | public someButton: cc.Button; 100 | } 101 | -------------------------- 102 | */ 103 | export function CCProperty(option: ICCProperty) { 104 | return function (constructor, propertyName) { 105 | let uuid = getUUID(); 106 | if (!currentProperties.hasOwnProperty(uuid)) currentProperties[uuid] = {}; 107 | currentProperties[uuid][propertyName] = option; 108 | } 109 | } 110 | /* 111 | Decorator of editor properties. 112 | @CCEditor must be used with @CCComponent. Usage: 113 | -------------------------- 114 | @CCEditor({ 115 | executeInEditMode: true 116 | }) 117 | @CCComponent 118 | export class ComponentName extends cc.Component {} 119 | -------------------------- 120 | */ 121 | export function CCEditor(editor: ICCEditor) { 122 | return function (constructor: any) { 123 | if (CC_EDITOR) { 124 | let uuid = getUUID(); 125 | if (!defined.hasOwnProperty(uuid) || !defined[uuid]) { 126 | currentEditor[uuid] = editor; 127 | } else { 128 | cc.Component._registerEditorProps(constructor, editor); 129 | } 130 | } 131 | return constructor; 132 | } 133 | } 134 | /* 135 | Decorator of mixins. 136 | @CCMixins must be used before @CCComponent. Usage: 137 | -------------------------- 138 | @CCComponent 139 | @CCMixins(mixin1, mixin2, mixin3, ...) 140 | export class ComponentName extends cc.Component {} 141 | -------------------------- 142 | */ 143 | export function CCMixins(...args) { 144 | return function (cls) { 145 | let uuid = getUUID(); 146 | if (CC_EDITOR && defined.hasOwnProperty(uuid) && defined[uuid]) { 147 | cc.error(`@CCMixins should be used before @CCComponent in ${getScriptName()}!`); 148 | } 149 | currentMixins[uuid] = args; 150 | return cls; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /typescript/libs/i18n/LabelLocalized.ts: -------------------------------------------------------------------------------- 1 | import {CCComponent, CCProperty} from "../../decorators/ComponentDecorators"; 2 | import {i18n} from "./i18n"; 3 | @CCComponent 4 | export class LabelLocalized extends cc.Label { 5 | @CCProperty({ 6 | default: "TEXT_KEY", 7 | multiline: true, 8 | tooltip: "Enter i18n key here", 9 | notify: function () { 10 | if (this._sgNode) { 11 | this._sgNode.setString(this.string); 12 | this._updateNodeSize(); 13 | } 14 | } 15 | }) 16 | public textKey: string; 17 | @CCProperty({ 18 | override: true, 19 | tooltip: "Here shows the localized string of Text Key", 20 | get: function () { 21 | return i18n.t(this.textKey); 22 | }, 23 | set: function (value) { 24 | cc.warn("Please set label text key in Text Key property."); 25 | } 26 | }) 27 | public string: string; 28 | } -------------------------------------------------------------------------------- /typescript/libs/i18n/Readme.md: -------------------------------------------------------------------------------- 1 | # i18n 多语言显示插件使用方法 2 | 3 | 本插件适用于 Cocos Creator v1.0 或更高版本,插件将会在您的项目里添加以下内容: 4 | 5 | - `i18n/i18n.js`: 负责本地化文本数据的初始化和运行时提供翻译输出的方法。 6 | - `i18n/polyglot.js`: 来自 airbnb 的 i18n 本地化代码库,查看 https://github.com/airbnb/polyglot.js 来获取完整的文档参考 7 | - `i18n/data/zh.ts`: 中文语言数据模板,您应该在这里添加您的翻译字典 8 | - `i18n/data/en.ts`: 英文语言数据模板,您应该在这里添加您的翻译字典 9 | - `i18n/LabelLocalized.js`: 用这个组件替换原来的 Label,在该组件的 `Text Key` 属性中填入翻译字典中的 key 值,就会在编辑器和运行时显示正确的翻译后文本。 10 | 11 | ## 工作流程 12 | 13 | 将插件包解压到你项目的 `assets` 目录下,应该会形成如下的目录结构: 14 | 15 | ``` 16 | assets 17 | |-i18n 18 | |-data 19 | | |-en.ts 20 | | |-zh.ts 21 | |-i18n.js 22 | |-LabelLocalized.js 23 | |-polyglot.js 24 | |-Readme.md 25 | ``` 26 | 27 | ### 定制本地化数据 28 | 29 | 接下来您应该首先根据多语言种类的需要,定制 `assets/i18n/data` 目录下的数据源文件,每个文件的格式是这样的: 30 | 31 | ```js 32 | // zh.ts 33 | module.exports = { 34 | "HELLO": "你好", 35 | "WORLD": "世界" 36 | } 37 | ``` 38 | 39 | 其中 `HELLO` 是 key,后面的值就是翻译后的文本。这里采用 js 格式定义数据,以便能够被引擎正常引用。 40 | 41 | 42 | 数据的内容是一个标准的 JavaScript Object,因此您可以使用嵌套的结构: 43 | 44 | ```js 45 | module.exports = { 46 | 'GREETINGS': { 47 | 'HELLO': '您好', 48 | 'WORLD': '世界' 49 | } 50 | } 51 | ``` 52 | 53 | 然后通过 'GREETINGS.HELLO' 形式的 key 来访问。 54 | 55 | 56 | 您可以根据需要制作多份数据源文件,每个数据源文件的文件名就是该语言的标识,如 `fr.js` 的语言标识就是 `fr`,后面我们会介绍如何通过语言标识来切换显示语言。 57 | 58 | 59 | ### 设置场景编辑器的默认显示语言 60 | 61 | 场景编辑器里显示的语言,是由 `assets/i18n/i18n.js` 里的 62 | 63 | ```js 64 | const language = require('zh'); 65 | ``` 66 | 67 | 来控制的,将上述代码中的 `zh` 替换成 `en` 或其他语言标识,就可以更改场景预览时显示的语言。 68 | 69 | ### 运行时的文本翻译 70 | 71 | 在代码中,您可以随时调用 72 | 73 | ```js 74 | var i18n = require('i18n'); // 通常会在脚本最开始调用 75 | i18n.init('zh');// init 的参数就是语言标识,如 'zh', 'en' 等 76 | var myLocalizedText = i18n.t('TEXT_KEY'); 77 | ``` 78 | 79 | 来通过文本数据源字典里的 key 来获得本地化后的字符串。 80 | 81 | #### 文本融合 82 | 83 | 您可以在数据源中用如下形式的定义: 84 | 85 | ```js 86 | module.exports = { 87 | "hello_name": "Hello, %{name}" 88 | } 89 | ``` 90 | 91 | 来声明一个可以融合到最终文本里的参数,在使用时: 92 | 93 | ```js 94 | var greetingText = i18n.t('hello_name', {name: 'nantas'}); // Hello, nantas 95 | ``` 96 | 97 | 就可以在输入文本时添加一个参数,来将代码动态获取到的字符串和预设的翻译文本融合。 98 | 99 | 100 | ### 在场景编辑时渲染翻译后的效果 101 | 102 | 在场景中,我们需要使用 `LabelLocalized` 组件代替原来的 `Label`,`LabelLocalized` 组件比 `Label` 增加了一个属性 `Text Key`, 103 | 我们在属性检查器中只要将 `Text Key` 设为字典里的 key 值,`LabelLocalized` 就会在场景中显示出翻译后的文本。 104 | 105 | 同时 LabelLocalized.string 属性现在变成只读,不能通过这个接口再写入了。 -------------------------------------------------------------------------------- /typescript/libs/i18n/data/en.ts: -------------------------------------------------------------------------------- 1 | export let en = { 2 | "lang": "English" 3 | }; -------------------------------------------------------------------------------- /typescript/libs/i18n/data/zh.ts: -------------------------------------------------------------------------------- 1 | export let zh = { 2 | "lang": "简体中文" 3 | }; -------------------------------------------------------------------------------- /typescript/libs/i18n/i18n.ts: -------------------------------------------------------------------------------- 1 | import {zh} from "./data/zh"; 2 | const Polyglot = require("polyglot"); 3 | const language = zh;// update this to set your default displaying language in editor 4 | 5 | // let polyglot = null; 6 | let polyglot = new Polyglot({phrases: language}); 7 | declare interface ITranslateOption { 8 | [key: string]: string|number; 9 | } 10 | export let i18n = { 11 | /** 12 | * This method allow you to switch language during runtime, language argument should be the same as your data file name 13 | * such as when language is 'zh', it will load your 'zh.ts' data source. 14 | * @method init 15 | * @param language - the language specific data file name, such as 'zh' to load 'zh.ts' 16 | */ 17 | init (language) { 18 | let data = require(language); 19 | polyglot.replace(data); 20 | }, 21 | /** 22 | * this method takes a text key as input, and return the localized string 23 | * Please read https://github.com/airbnb/polyglot.js for details 24 | * @method t 25 | * @return {String} localized string 26 | * @example 27 | * 28 | * let myText = i18n.t('MY_TEXT_KEY'); 29 | * 30 | * // if your data source is defined as 31 | * // {"hello_name": "Hello, %{name}"} 32 | * // you can use the following to interpolate the text 33 | * let greetingText = i18n.t('hello_name', {name: 'nantas'}); // Hello, nantas 34 | */ 35 | t (key: string, opt?: ITranslateOption) { 36 | return polyglot.t(key, opt); 37 | } 38 | }; -------------------------------------------------------------------------------- /typescript/libs/i18n/polyglot.js: -------------------------------------------------------------------------------- 1 | // (c) 2012-2016 Airbnb, Inc. 2 | // 3 | // polyglot.js may be freely distributed under the terms of the BSD 4 | // license. For all licensing information, details, and documention: 5 | // http://airbnb.github.com/polyglot.js 6 | // 7 | // 8 | // Polyglot.js is an I18n helper library written in JavaScript, made to 9 | // work both in the browser and in Node. It provides a simple solution for 10 | // interpolation and pluralization, based off of Airbnb's 11 | // experience adding I18n functionality to its Backbone.js and Node apps. 12 | // 13 | // Polylglot is agnostic to your translation backend. It doesn't perform any 14 | // translation; it simply gives you a way to manage translated phrases from 15 | // your client- or server-side JavaScript application. 16 | // 17 | 18 | 19 | (function(root, factory) { 20 | if (typeof define === "function" && define.amd) { 21 | define([], function() { 22 | return factory(root); 23 | }); 24 | } else if (typeof exports === "object") { 25 | module.exports = factory(root); 26 | } else { 27 | root.Polyglot = factory(root); 28 | } 29 | }(typeof global !== "undefined" ? global : this, function(root) { 30 | "use strict"; 31 | 32 | var replace = String.prototype.replace; 33 | 34 | // ### Polyglot class constructor 35 | function Polyglot(options) { 36 | options = options || {}; 37 | this.phrases = {}; 38 | this.extend(options.phrases || {}); 39 | this.currentLocale = options.locale || "en"; 40 | this.allowMissing = !!options.allowMissing; 41 | this.warn = options.warn || warn; 42 | } 43 | 44 | // ### Version 45 | Polyglot.VERSION = "1.0.0"; 46 | 47 | // ### polyglot.locale([locale]) 48 | // 49 | // Get or set locale. Internally, Polyglot only uses locale for pluralization. 50 | Polyglot.prototype.locale = function(newLocale) { 51 | if (newLocale) this.currentLocale = newLocale; 52 | return this.currentLocale; 53 | }; 54 | 55 | // ### polyglot.extend(phrases) 56 | // 57 | // Use `extend` to tell Polyglot how to translate a given key. 58 | // 59 | // polyglot.extend({ 60 | // "hello": "Hello", 61 | // "hello_name": "Hello, %{name}" 62 | // }); 63 | // 64 | // The key can be any string. Feel free to call `extend` multiple times; 65 | // it will override any phrases with the same key, but leave existing phrases 66 | // untouched. 67 | // 68 | // It is also possible to pass nested phrase objects, which get flattened 69 | // into an object with the nested keys concatenated using dot notation. 70 | // 71 | // polyglot.extend({ 72 | // "nav": { 73 | // "hello": "Hello", 74 | // "hello_name": "Hello, %{name}", 75 | // "sidebar": { 76 | // "welcome": "Welcome" 77 | // } 78 | // } 79 | // }); 80 | // 81 | // console.log(polyglot.phrases); 82 | // // { 83 | // // 'nav.hello': 'Hello', 84 | // // 'nav.hello_name': 'Hello, %{name}', 85 | // // 'nav.sidebar.welcome': 'Welcome' 86 | // // } 87 | // 88 | // `extend` accepts an optional second argument, `prefix`, which can be used 89 | // to prefix every key in the phrases object with some string, using dot 90 | // notation. 91 | // 92 | // polyglot.extend({ 93 | // "hello": "Hello", 94 | // "hello_name": "Hello, %{name}" 95 | // }, "nav"); 96 | // 97 | // console.log(polyglot.phrases); 98 | // // { 99 | // // 'nav.hello': 'Hello', 100 | // // 'nav.hello_name': 'Hello, %{name}' 101 | // // } 102 | // 103 | // This feature is used internally to support nested phrase objects. 104 | Polyglot.prototype.extend = function(morePhrases, prefix) { 105 | var phrase; 106 | 107 | for (var key in morePhrases) { 108 | if (morePhrases.hasOwnProperty(key)) { 109 | phrase = morePhrases[key]; 110 | if (prefix) key = prefix + "." + key; 111 | if (typeof phrase === "object") { 112 | this.extend(phrase, key); 113 | } else { 114 | this.phrases[key] = phrase; 115 | } 116 | } 117 | } 118 | }; 119 | 120 | // ### polyglot.unset(phrases) 121 | // Use `unset` to selectively remove keys from a polyglot instance. 122 | // 123 | // polyglot.unset("some_key"); 124 | // polyglot.unset({ 125 | // "hello": "Hello", 126 | // "hello_name": "Hello, %{name}" 127 | // }); 128 | // 129 | // The unset method can take either a string (for the key), or an object hash with 130 | // the keys that you would like to unset. 131 | Polyglot.prototype.unset = function(morePhrases, prefix) { 132 | var phrase; 133 | 134 | if (typeof morePhrases === "string") { 135 | delete this.phrases[morePhrases]; 136 | } else { 137 | for (var key in morePhrases) { 138 | if (morePhrases.hasOwnProperty(key)) { 139 | phrase = morePhrases[key]; 140 | if (prefix) key = prefix + "." + key; 141 | if (typeof phrase === "object") { 142 | this.unset(phrase, key); 143 | } else { 144 | delete this.phrases[key]; 145 | } 146 | } 147 | } 148 | } 149 | }; 150 | 151 | // ### polyglot.clear() 152 | // 153 | // Clears all phrases. Useful for special cases, such as freeing 154 | // up memory if you have lots of phrases but no longer need to 155 | // perform any translation. Also used internally by `replace`. 156 | Polyglot.prototype.clear = function() { 157 | this.phrases = {}; 158 | }; 159 | 160 | // ### polyglot.replace(phrases) 161 | // 162 | // Completely replace the existing phrases with a new set of phrases. 163 | // Normally, just use `extend` to add more phrases, but under certain 164 | // circumstances, you may want to make sure no old phrases are lying around. 165 | Polyglot.prototype.replace = function(newPhrases) { 166 | this.clear(); 167 | this.extend(newPhrases); 168 | }; 169 | 170 | 171 | // ### polyglot.t(key, options) 172 | // 173 | // The most-used method. Provide a key, and `t` will return the 174 | // phrase. 175 | // 176 | // polyglot.t("hello"); 177 | // => "Hello" 178 | // 179 | // The phrase value is provided first by a call to `polyglot.extend()` or 180 | // `polyglot.replace()`. 181 | // 182 | // Pass in an object as the second argument to perform interpolation. 183 | // 184 | // polyglot.t("hello_name", {name: "Spike"}); 185 | // => "Hello, Spike" 186 | // 187 | // If you like, you can provide a default value in case the phrase is missing. 188 | // Use the special option key "_" to specify a default. 189 | // 190 | // polyglot.t("i_like_to_write_in_language", { 191 | // _: "I like to write in %{language}.", 192 | // language: "JavaScript" 193 | // }); 194 | // => "I like to write in JavaScript." 195 | // 196 | Polyglot.prototype.t = function(key, options) { 197 | var phrase, result; 198 | options = options == null ? {} : options; 199 | // allow number as a pluralization shortcut 200 | if (typeof options === "number") { 201 | options = {smart_count: options}; 202 | } 203 | if (typeof this.phrases[key] === "string") { 204 | phrase = this.phrases[key]; 205 | } else if (typeof options._ === "string") { 206 | phrase = options._; 207 | } else if (this.allowMissing) { 208 | phrase = key; 209 | } else { 210 | this.warn("Missing translation for key: \""+key+"\""); 211 | result = key; 212 | } 213 | if (typeof phrase === "string") { 214 | options = clone(options); 215 | result = choosePluralForm(phrase, this.currentLocale, options.smart_count); 216 | result = interpolate(result, options); 217 | } 218 | return result; 219 | }; 220 | 221 | 222 | // ### polyglot.has(key) 223 | // 224 | // Check if polyglot has a translation for given key 225 | Polyglot.prototype.has = function(key) { 226 | return key in this.phrases; 227 | }; 228 | 229 | 230 | // #### Pluralization methods 231 | // The string that separates the different phrase possibilities. 232 | var delimeter = "||||"; 233 | 234 | // Mapping from pluralization group plural logic. 235 | var pluralTypes = { 236 | chinese: function(n) { return 0; }, 237 | german: function(n) { return n !== 1 ? 1 : 0; }, 238 | french: function(n) { return n > 1 ? 1 : 0; }, 239 | russian: function(n) { return n % 10 === 1 && n % 100 !== 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2; }, 240 | czech: function(n) { return (n === 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2; }, 241 | polish: function(n) { return (n === 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); }, 242 | icelandic: function(n) { return (n % 10 !== 1 || n % 100 === 11) ? 1 : 0; } 243 | }; 244 | 245 | // Mapping from pluralization group to individual locales. 246 | var pluralTypeToLanguages = { 247 | chinese: ["fa", "id", "ja", "ko", "lo", "ms", "th", "tr", "zh"], 248 | german: ["da", "de", "en", "es", "fi", "el", "he", "hu", "it", "nl", "no", "pt", "sv"], 249 | french: ["fr", "tl", "pt-br"], 250 | russian: ["hr", "ru"], 251 | czech: ["cs", "sk"], 252 | polish: ["pl"], 253 | icelandic: ["is"] 254 | }; 255 | 256 | function langToTypeMap(mapping) { 257 | var type, langs, l, ret = {}; 258 | for (type in mapping) { 259 | if (mapping.hasOwnProperty(type)) { 260 | langs = mapping[type]; 261 | for (l in langs) { 262 | ret[langs[l]] = type; 263 | } 264 | } 265 | } 266 | return ret; 267 | } 268 | 269 | // Trim a string. 270 | var trimRe = /^\s+|\s+$/g; 271 | function trim(str){ 272 | return replace.call(str, trimRe, ""); 273 | } 274 | 275 | // Based on a phrase text that contains `n` plural forms separated 276 | // by `delimeter`, a `locale`, and a `count`, choose the correct 277 | // plural form, or none if `count` is `null`. 278 | function choosePluralForm(text, locale, count){ 279 | var ret, texts, chosenText; 280 | if (count != null && text) { 281 | texts = text.split(delimeter); 282 | chosenText = texts[pluralTypeIndex(locale, count)] || texts[0]; 283 | ret = trim(chosenText); 284 | } else { 285 | ret = text; 286 | } 287 | return ret; 288 | } 289 | 290 | function pluralTypeName(locale) { 291 | var langToPluralType = langToTypeMap(pluralTypeToLanguages); 292 | return langToPluralType[locale] || langToPluralType.en; 293 | } 294 | 295 | function pluralTypeIndex(locale, count) { 296 | return pluralTypes[pluralTypeName(locale)](count); 297 | } 298 | 299 | // ### interpolate 300 | // 301 | // Does the dirty work. Creates a `RegExp` object for each 302 | // interpolation placeholder. 303 | var dollarRegex = /\$/g; 304 | var dollarBillsYall = "$$$$"; 305 | function interpolate(phrase, options) { 306 | for (var arg in options) { 307 | if (arg !== "_" && options.hasOwnProperty(arg)) { 308 | // Ensure replacement value is escaped to prevent special $-prefixed 309 | // regex replace tokens. the "$$$$" is needed because each "$" needs to 310 | // be escaped with "$" itself, and we need two in the resulting output. 311 | var replacement = options[arg]; 312 | if (typeof replacement === "string") { 313 | replacement = replace.call(options[arg], dollarRegex, dollarBillsYall); 314 | } 315 | // We create a new `RegExp` each time instead of using a more-efficient 316 | // string replace so that the same argument can be replaced multiple times 317 | // in the same phrase. 318 | phrase = replace.call(phrase, new RegExp("%\\{"+arg+"\\}", "g"), replacement); 319 | } 320 | } 321 | return phrase; 322 | } 323 | 324 | // ### warn 325 | // 326 | // Provides a warning in the console if a phrase key is missing. 327 | function warn(message) { 328 | // root.console && root.console.warn && root.console.warn('WARNING: ' + message); 329 | } 330 | 331 | // ### clone 332 | // 333 | // Clone an object. 334 | function clone(source) { 335 | var ret = {}; 336 | for (var prop in source) { 337 | ret[prop] = source[prop]; 338 | } 339 | return ret; 340 | } 341 | 342 | return Polyglot; 343 | })); 344 | -------------------------------------------------------------------------------- /typescript/models/AbstractModel.ts: -------------------------------------------------------------------------------- 1 | import {AbstractController} from "../controllers/AbstractController"; 2 | import {AbstractComponent} from "../views/AbstractComponent"; 3 | export abstract class AbstractModel, TView extends AbstractComponent> { 4 | public get view(): TView { 5 | return this._view; 6 | } 7 | 8 | public set view(value: TView) { 9 | this._view = value; 10 | } 11 | 12 | public get controller(): TController { 13 | return this._controller; 14 | } 15 | 16 | public set controller(value: TController) { 17 | this._controller = value; 18 | } 19 | 20 | private _controller: TController; 21 | private _view: TView; 22 | } -------------------------------------------------------------------------------- /typescript/models/HelloModel.ts: -------------------------------------------------------------------------------- 1 | import {AbstractModel} from "./AbstractModel"; 2 | import {HelloController} from "../controllers/HelloController"; 3 | import {HelloView} from "../views/HelloView"; 4 | export class HelloModel extends AbstractModel { 5 | private serverAddress = "http://52.58.118.63"; 6 | //noinspection JSMethodCanBeStatic 7 | public async getIP(): Promise { 8 | try { 9 | let res = await fetch(`${this.serverAddress}/getIP.php`); 10 | return await res.json() as any as IPFetchResult; 11 | } catch (e) { 12 | cc.log(e); 13 | return {code: 1, data: null}; 14 | } 15 | } 16 | 17 | //noinspection JSMethodCanBeStatic 18 | public async getIPInfo(ip): Promise { 19 | try { 20 | let res = await fetch(`${this.serverAddress}/getIPInfo.php?ip=${ip}`); 21 | return await res.json() as any as IPInfoFetchResult; 22 | } catch (e) { 23 | cc.log(e); 24 | return {code: 2, data: null}; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /typescript/plugins/Fetch.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.ES6Promise=e()}(this,function(){"use strict";function t(t){return"function"==typeof t||"object"==typeof t&&null!==t}function e(t){return"function"==typeof t}function n(t){I=t}function r(t){J=t}function o(){return function(){return process.nextTick(a)}}function i(){return"undefined"!=typeof H?function(){H(a)}:c()}function s(){var t=0,e=new V(a),n=document.createTextNode("");return e.observe(n,{characterData:!0}),function(){n.data=t=++t%2}}function u(){var t=new MessageChannel;return t.port1.onmessage=a,function(){return t.port2.postMessage(0)}}function c(){var t=setTimeout;return function(){return t(a,1)}}function a(){for(var t=0;t -1) ? upcased : method 207 | } 208 | 209 | function Request(url, options) { 210 | options = options || {} 211 | this.url = url 212 | 213 | this.credentials = options.credentials || 'omit' 214 | this.headers = new Headers(options.headers) 215 | this.method = normalizeMethod(options.method || 'GET') 216 | this.mode = options.mode || null 217 | this.referrer = null 218 | 219 | if ((this.method === 'GET' || this.method === 'HEAD') && options.body) { 220 | throw new TypeError('Body not allowed for GET or HEAD requests') 221 | } 222 | this._initBody(options.body) 223 | } 224 | 225 | function decode(body) { 226 | var form = new FormData() 227 | body.trim().split('&').forEach(function(bytes) { 228 | if (bytes) { 229 | var split = bytes.split('=') 230 | var name = split.shift().replace(/\+/g, ' ') 231 | var value = split.join('=').replace(/\+/g, ' ') 232 | form.append(decodeURIComponent(name), decodeURIComponent(value)) 233 | } 234 | }) 235 | return form 236 | } 237 | 238 | function headers(xhr) { 239 | var head = new Headers() 240 | var pairs = xhr.getAllResponseHeaders().trim().split('\n') 241 | pairs.forEach(function(header) { 242 | var split = header.trim().split(':') 243 | var key = split.shift().trim() 244 | var value = split.join(':').trim() 245 | head.append(key, value) 246 | }) 247 | return head 248 | } 249 | 250 | var noXhrPatch = 251 | typeof window !== 'undefined' && !!window.ActiveXObject && !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent); 252 | 253 | function getXhr() { 254 | // from backbone.js 1.1.2 255 | // https://github.com/jashkenas/backbone/blob/1.1.2/backbone.js#L1181 256 | if (noXhrPatch && !(/^(get|post|head|put|delete|options)$/i.test(this.method))) { 257 | this.usingActiveXhr = true; 258 | return new ActiveXObject("Microsoft.XMLHTTP"); 259 | } 260 | return new XMLHttpRequest(); 261 | } 262 | 263 | Body.call(Request.prototype) 264 | 265 | function Response(bodyInit, options) { 266 | if (!options) { 267 | options = {} 268 | } 269 | 270 | this._initBody(bodyInit) 271 | this.type = 'default' 272 | this.url = null 273 | this.status = options.status 274 | this.ok = this.status >= 200 && this.status < 300 275 | this.statusText = options.statusText 276 | this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers) 277 | this.url = options.url || '' 278 | } 279 | 280 | Body.call(Response.prototype) 281 | 282 | self.Headers = Headers; 283 | self.Request = Request; 284 | self.Response = Response; 285 | 286 | self.fetch = function(input, init) { 287 | // TODO: Request constructor should accept input, init 288 | var request 289 | if (Request.prototype.isPrototypeOf(input) && !init) { 290 | request = input 291 | } else { 292 | request = new Request(input, init) 293 | } 294 | 295 | return new fetch.Promise(function(resolve, reject) { 296 | var xhr = getXhr(); 297 | if (request.credentials === 'cors') { 298 | xhr.withCredentials = true; 299 | } 300 | 301 | function responseURL() { 302 | if ('responseURL' in xhr) { 303 | return xhr.responseURL 304 | } 305 | 306 | // Avoid security warnings on getResponseHeader when not allowed by CORS 307 | if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) { 308 | return xhr.getResponseHeader('X-Request-URL') 309 | } 310 | 311 | return; 312 | } 313 | 314 | function onload() { 315 | if (xhr.readyState !== 4) { 316 | return 317 | } 318 | var status = (xhr.status === 1223) ? 204 : xhr.status 319 | if (status < 100 || status > 599) { 320 | reject(new TypeError('Network request failed')) 321 | return 322 | } 323 | var options = { 324 | status: status, 325 | statusText: xhr.statusText, 326 | headers: headers(xhr), 327 | url: responseURL() 328 | } 329 | var body = 'response' in xhr ? xhr.response : xhr.responseText; 330 | resolve(new Response(body, options)) 331 | } 332 | 333 | xhr.onreadystatechange = onload; 334 | if (!self.usingActiveXhr) { 335 | xhr.onload = onload; 336 | xhr.onerror = function() { 337 | reject(new TypeError('Network request failed')) 338 | } 339 | } 340 | 341 | xhr.open(request.method, request.url, true) 342 | 343 | if ('responseType' in xhr && support.blob) { 344 | xhr.responseType = 'blob' 345 | } 346 | 347 | request.headers.forEach(function(name, values) { 348 | values.forEach(function(value) { 349 | xhr.setRequestHeader(name, value) 350 | }) 351 | }) 352 | xhr.send() 353 | }) 354 | } 355 | fetch.Promise = self.Promise; // you could change it to your favorite alternative 356 | self.fetch.polyfill = true 357 | })(window); 358 | -------------------------------------------------------------------------------- /typescript/plugins/TypeScriptHelper.js: -------------------------------------------------------------------------------- 1 | window.__extends = function (d, b) { 2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 3 | function __() { this.constructor = d; } 4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 5 | }; 6 | window.__assign = Object.assign || function (t) { 7 | for (var s, i = 1, n = arguments.length; i < n; i++) { 8 | s = arguments[i]; 9 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 10 | } 11 | return t; 12 | }; 13 | window.__rest = function (s, e) { 14 | var t = {}; 15 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 16 | t[p] = s[p]; 17 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 18 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) 19 | t[p[i]] = s[p[i]]; 20 | return t; 21 | }; 22 | window.__decorate = function (decorators, target, key, desc) { 23 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 24 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 25 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 26 | return c > 3 && r && Object.defineProperty(target, key, r), r; 27 | }; 28 | window.__param = function (paramIndex, decorator) { 29 | return function (target, key) { decorator(target, key, paramIndex); } 30 | }; 31 | window.__metadata = function (metadataKey, metadataValue) { 32 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 33 | }; 34 | window.__awaiter = function (thisArg, _arguments, P, generator) { 35 | return new (P || (P = Promise))(function (resolve, reject) { 36 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 37 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 38 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 39 | step((generator = generator.apply(thisArg, _arguments)).next()); 40 | }); 41 | }; 42 | window.__generator = function (thisArg, body) { 43 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; 44 | return { next: verb(0), "throw": verb(1), "return": verb(2) }; 45 | function verb(n) { return function (v) { return step([n, v]); }; } 46 | function step(op) { 47 | if (f) throw new TypeError("Generator is already executing."); 48 | while (_) try { 49 | if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; 50 | if (y = 0, t) op = [0, t.value]; 51 | switch (op[0]) { 52 | case 0: case 1: t = op; break; 53 | case 4: _.label++; return { value: op[1], done: false }; 54 | case 5: _.label++; y = op[1]; op = [0]; continue; 55 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 56 | default: 57 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 58 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 59 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 60 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 61 | if (t[2]) _.ops.pop(); 62 | _.trys.pop(); continue; 63 | } 64 | op = body.call(thisArg, _); 65 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 66 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 67 | } 68 | }; -------------------------------------------------------------------------------- /typescript/types/GlobalNameSpace.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // Global Namespace 3 | declare let jsb: any; 4 | declare let dragonBones: any; 5 | declare let CC_EDITOR: boolean; 6 | declare let CC_DEV: boolean; 7 | declare let require: (string)=>any; -------------------------------------------------------------------------------- /typescript/types/models/HelloModel.d.ts: -------------------------------------------------------------------------------- 1 | declare interface IFetchResult { 2 | code: number; 3 | data: TData | null; 4 | } 5 | 6 | declare interface IPData { 7 | ip: string; 8 | } 9 | 10 | declare interface IPFetchResult extends IFetchResult { 11 | } 12 | 13 | declare interface IPInfoData { 14 | area: string; 15 | area_id: string; 16 | city: string; 17 | city_id: string; 18 | country: string; 19 | country_id: string; 20 | county: string; 21 | county_id: string; 22 | ip: string; 23 | isp: string; 24 | isp_id: string; 25 | region: string; 26 | region_id: string; 27 | } 28 | 29 | declare interface IPInfoFetchResult extends IFetchResult { 30 | } -------------------------------------------------------------------------------- /typescript/types/plugins/Fetch.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for fetch API 2 | // Spec: https://fetch.spec.whatwg.org/ 3 | // Polyfill: https://github.com/github/fetch 4 | // Definitions by: Ryan Graham 5 | 6 | interface FetchOptions { 7 | method?: "GET" | "POST" | "DELETE" | "PATCH" | "PUT" | "HEAD" | "OPTIONS" | "CONNECT"; 8 | headers?: any; 9 | body?: any; 10 | mode?: "cors" | "no-cors" | "same-origin"; 11 | credentials?: "omit" | "same-origin" | "include"; 12 | cache?: "default" | "no-store" | "reload" | "no-cache" | "force-cache" | "only-if-cached"; 13 | redirect?: "follow" | "error" | "manual"; 14 | referrer?: string; 15 | referrerPolicy?: "referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "unsafe-url"; 16 | integrity?: any; 17 | } 18 | 19 | declare enum ResponseType { 20 | Basic, 21 | Cors, 22 | Default, 23 | Error, 24 | Opaque 25 | } 26 | 27 | interface Headers { 28 | append(name: string, value: string): void; 29 | delete(name: string): void; 30 | get(name: string): string; 31 | getAll(name: string): Array; 32 | has(name: string): boolean; 33 | set(name: string, value: string): void; 34 | } 35 | 36 | interface Body { 37 | bodyUsed: boolean; 38 | arrayBuffer(): Promise; 39 | blob(): Promise; 40 | formData(): Promise; 41 | json(): Promise; 42 | text(): Promise; 43 | } 44 | 45 | interface Response extends Body { 46 | error(): Response; 47 | redirect(url: string, status?: number): Response; 48 | type: ResponseType; 49 | url: string; 50 | status: number; 51 | ok: boolean; 52 | statusText: string; 53 | headers: Headers; 54 | clone(): Response; 55 | } 56 | declare function fetch(url: string, options?: FetchOptions): Promise; -------------------------------------------------------------------------------- /typescript/views/AbstractComponent.ts: -------------------------------------------------------------------------------- 1 | import {AbstractController} from "../controllers/AbstractController"; 2 | import {CCComponent} from "../decorators/ComponentDecorators"; 3 | import {AbstractSimpleComponent} from "./AbstractSimpleComponent"; 4 | import {AbstractModel} from "../models/AbstractModel"; 5 | @CCComponent 6 | export abstract class AbstractComponent , 7 | TModel extends AbstractModel> extends AbstractSimpleComponent 8 | { 9 | public get model(): TModel { 10 | return this._model; 11 | } 12 | 13 | public set model(value: TModel) { 14 | this._model = value; 15 | } 16 | 17 | public get controller(): TController { 18 | return this._controller; 19 | } 20 | 21 | public set controller(value: TController) { 22 | this._controller = value; 23 | } 24 | 25 | private _controller: TController; 26 | private _model: TModel; 27 | } -------------------------------------------------------------------------------- /typescript/views/AbstractSimpleComponent.ts: -------------------------------------------------------------------------------- 1 | import {CCComponent} from "../decorators/ComponentDecorators"; 2 | @CCComponent 3 | export abstract class AbstractSimpleComponent extends cc.Component { 4 | } -------------------------------------------------------------------------------- /typescript/views/HelloView.ts: -------------------------------------------------------------------------------- 1 | import {CCComponent, CCProperty, CCEditor} from "../decorators/ComponentDecorators"; 2 | import {AbstractComponent} from "./AbstractComponent"; 3 | import {HelloController} from "../controllers/HelloController"; 4 | import {HelloModel} from "../models/HelloModel"; 5 | @CCEditor({ 6 | executeInEditMode: true 7 | }) 8 | @CCComponent 9 | export class HelloView extends AbstractComponent { 10 | @CCProperty(cc.Label) 11 | private ipLabel: cc.Label; 12 | @CCProperty(cc.Label) 13 | private countryLabel: cc.Label; 14 | @CCProperty(cc.Label) 15 | private cityLabel: cc.Label; 16 | @CCProperty(cc.Label) 17 | private countyLabel: cc.Label; 18 | 19 | public onLoad() { 20 | this.initLabels(); 21 | this.controller = new HelloController(); 22 | this.controller.init(this); 23 | this.move10(); 24 | } 25 | 26 | private initLabels() { 27 | this.ipLabel.string = "正在加载IP..."; 28 | this.countryLabel.string = ""; 29 | this.cityLabel.string = ""; 30 | this.countyLabel.string = ""; 31 | } 32 | 33 | public updateIP(res: IPFetchResult) { 34 | if (res.code == 0 && res.data !== null) { 35 | this.ipLabel.string = res.data.ip; 36 | this.countryLabel.string = "正在加载国家信息"; 37 | this.cityLabel.string = "正在加载城市信息"; 38 | this.countyLabel.string = "正在加载区域信息"; 39 | } else { 40 | this.ipLabel.string = "获取IP失败"; 41 | } 42 | } 43 | 44 | public updateIPInfo(res: IPInfoFetchResult) { 45 | if (res.code == 0 && res.data !== null) { 46 | this.countryLabel.string = res.data.country; 47 | this.cityLabel.string = res.data.city; 48 | this.countyLabel.string = res.data.county; 49 | } else { 50 | this.countryLabel.string = "加载国家信息失败"; 51 | this.cityLabel.string = "加载城市信息失败"; 52 | this.countyLabel.string = "加载区域信息失败"; 53 | } 54 | } 55 | 56 | private async move10() { 57 | for (let i = 0; i < 10; i++) { 58 | await this.asyncRunAction(this.ipLabel.node, cc.sequence( 59 | cc.moveBy(0.5, -10, 0), 60 | cc.moveBy(0.5, 10, 0) 61 | )); 62 | } 63 | } 64 | 65 | private async asyncRunAction(node: cc.Node, action: cc.Action) { 66 | return new Promise((resolve, reject) => { 67 | node.runAction(cc.sequence( 68 | action, 69 | cc.callFunc(resolve) 70 | )); 71 | }); 72 | } 73 | } --------------------------------------------------------------------------------