Commit e61c7309 authored by 邱旭's avatar 邱旭

init

parents
node_modules/
dist/
build/
released/
yarn-error.log
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="HtmlRequiredAltAttribute" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="PROJECT" libraries="{spark.base.fz.wxpollyfill}" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/template.iml" filepath="$PROJECT_DIR$/.idea/template.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<excludeFolder url="file://$MODULE_DIR$/released" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="spark.base.fz.wxpollyfill" level="application" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebResourcesPaths">
<contentEntries>
<entry url="file://$PROJECT_DIR$">
<entryData>
<resourceRoots>
<path value="file://$PROJECT_DIR$/resource" />
<path value="file://$PROJECT_DIR$/psd" />
<path value="file://$PROJECT_DIR$/lotties" />
</resourceRoots>
</entryData>
</entry>
</contentEntries>
</component>
</project>
\ No newline at end of file
# 最新模板
### psd命名规则
按钮单图 图层名字_btn_id
按钮多图 组名_btn_id (里面多图层,0常态,1不可点击,2按钮)
普通图片png 图层名字_id
普通图片jpg 图层名字_jpg_id
矩形 图层名字_id
文本 图层名字_id (默认都居左,未改文本前, 调整调用Tool里方法changeTextAlign)
贴图 图层名字_tex (只切图,不进皮肤)
作为item的皮肤不进root 组名_item (比如自定义的类或滚动列表的item)
(组名,图层名字,id均为动态)
(id为英文,显示对象原属性名不能作为id,比如"name")
(同名的的图片只要图片相同就行,用clearSameImg脚本将同图移进common)
(能合并的图自行合并)
(视图模块名字命名成...Panel,...Scene,例如StartScene,RulePanel,方便生成模块传参,否则自行修改createModule脚本里的参数)
(id必须是英文,作为item的组名必须是英文,因为会生成类)
### psd解析
生成./resource/skinJson.json和./src/SkinJson.ts,
初始一致,json只用于脚本createModule.js生成场景或弹框模块,实际作用数据是ts,有需要自行修改SkinJson.ts
执行,会刷新资源配置及覆盖SkinJson.ts,注意
```shell script
#多视图解析,会解析./psd文件夹内所有psd及内视图
npm run psd
#单视图解析,主要用于处理后添加的视图,传参./psd文件夹内psd名字,
#资源及皮肤数据skin.json会在./psd文件夹内生成,自行处理进./resource/skin.json和./src/SkinJson.ts文件
npm run psdSin
```
### 生成模块 有psd生成皮肤数据时使用
会根据参数Panel或者Scene生成ts文件写入./src/panels或./src/scenes文件夹
```shell script
npm run createModule RulePanel
```
### 资源配置刷新
有资源删除或增加时执行
会根据resource里的子级文件夹分组
文件夹名字用于各模块里的groupNames,用于按需资源加载
```shell script
npm run flushRes
```
### 本地开发
```shell script
npm run dev
```
### 图集工具安装
```shell script
#全局安装
cnpm install pack_textures -g
#终端输入packTextures检查环境变量是否存在
```
### 淘宝打包流程
```shell script
#带资源打包,并生成./released/resource文件夹和./released/output.js文件
npm run build
#只打包代码,
npm run buildTS
#脚本copyJs.js自行修改小程序output.js文件路径,嫌麻烦自行修改package.json里的build和buildTS,也可自行复制output.js
npm run copyJs
```
### web打包流程
```shell script
#带资源打包,并生成./released/resource文件夹和./output.js文件及./released/index.html,可复制进皮肤
npm run buildWeb
#只打包代码,并生成./output.js文件及./released/index.html,会打印版本号,可直接更换皮肤的版本号
npm run buildWebTS
```
### 适配
./module/views/layers.ts可设置所有层级适配(弹框场景等等)
单独模块的适配自行在模块里处理,修改this.y
### psd导出文本
部分文案尺寸错误自行在SkinJson,ts里修改
居中居右,在未修改文本字号字符等属性前调用Tools.changeTextAlign修改,可与psd表现保持一致
\ No newline at end of file
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>game_template</title>
<meta name="viewport"
content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="full-screen" content="true"/>
<meta name="screen-orientation" content="portrait"/>
<meta name="x5-fullscreen" content="true"/>
<meta name="360-fullscreen" content="true"/>
<!-- polyfill -->
<script src="//yun.duiba.com.cn/db_games/libs0924/polyfill_220525.js" crossorigin="anonymous"></script>
<!-- 渲染引擎 -->
<script src="//yun.duiba.com.cn/db_games/libs0924/fyge2044.min.js" crossorigin="anonymous"></script>
<!--<script src="libs/fyge.min.js" crossorigin="anonymous"></script>-->
<!-- svga解析库 -->
<script src="//yun.duiba.com.cn/db_games/libs0924/svgaParser.minWeb.js" crossorigin="anonymous"></script>
<!-- 放声音的 -->
<script src="//yun.duiba.com.cn/db_games/libs0924/howler.min.js" crossorigin="anonymous"></script>
<style>
html,
body {
padding: 0;
margin: 0;
border: 0;
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
background-color: #ffffff;
/* background: linear-gradient(#93dbb7,#ff0,#b5d89a); */
/* background: linear-gradient(#93dbb7,#b5d89a); */
/* 背景图片,解决加载太慢,白屏问题,加了这个下面的__loading__可以删掉了 */
/* background-size: 100%;
background-position: center;
background-image: url("https://yun.duiba.com.cn/db_games/activity/game/1550472986/resource/assets/playscene/playscenebg.jpg"); */
}
</style>
</head>
<body>
<div id="__loading__" style="position:absolute;left:50%;top:50%;margin-left:-45px;color:#ffffff">拼命加载中...</div>
<div id="cusEngine" style="line-height:0;font-size:0;position: absolute;">
<canvas id="canvas" style="width: 100%;height: 100%"></canvas>
</div>
<!-- 帧率检测 -->
<!-- <script src="https://yun.duiba.com.cn/db_games/libs0126/stats.js"></script> -->
<script>
const app = {
checkMember: () => {
return false;
}
};
function getApp() {
return app;
}
document.oncontextmenu = () => false;
</script>
<script>
var CFG = CFG || {};
CFG.projectId = 'pa525eacc';//线上直接写死
CFG.appID = '76177';//线上直接写死
//TODO我的奖品链接
window["recordUrl"] = "fe071865b.html";
window.addEventListener("load", function () {
//获取canvas
var canvas = document.getElementById("canvas");
canvas.width = document.body.clientWidth * (window.devicePixelRatio || 1)
canvas.height = document.body.clientHeight * (window.devicePixelRatio || 1)
var main = new output.Main(canvas);
var mouseEvent = main.stage.onMouseEvent.bind(main.stage);
canvas.addEventListener("touchstart", mouseEvent, false);
canvas.addEventListener('touchmove', mouseEvent, false);
canvas.addEventListener('touchend', mouseEvent, false);
window.stage = main.stage
})
</script>
<!-- 构建的js -->
<script src="./build/output.js" crossorigin="anonymous"></script>
</body>
</html>
This source diff could not be displayed because it is too large. You can view the blob instead.
declare module SvgaParser {
/**
* 加载方法
* @param url 资源路径
* @param success
* @param failure
*/
export function loadSvga(url: string, success: (videoItem: VideoEntity) => void, failure?: (err: string) => void): void;
/**
* 导出只是当作类型接口用
*/
export interface VideoEntity {
/**
* SVGA 文件版本
*/
version: string;
/**
* 影片尺寸
*/
videoSize: {
width: number;
height: number;
};
/**
* 帧率,60,30等每秒
*/
FPS: number;
/**
* 总帧数
*/
frames: number;
/**
* base64图片数据记录
*/
images: {
[key: string]: string
};
/**
* 图片是否已被缓存,缓存全局,注意名字覆盖
*/
hasBeenCached: boolean;
/**
* sprite对象数据
*/
sprites: SpriteEntity[];
}
interface SpriteEntity {
/**
* 标识
*/
matteKey: string;
/**
* 图片key值
*/
imageKey: string;
/**
* 帧数据数组
*/
frames: FrameEntity[];
}
/**
* 还有很多其他数据,暂不需要,比如矢量路径和遮罩路径暂时都无
*/
interface FrameEntity {
/**
* 透明度
*/
alpha: number;
/**
* 2维矩阵数据
*/
transform: {
a: number,
b: number,
c: number,
d: number,
tx: number,
ty: number,
};
}
}
declare module "svga-parser" { export = SvgaParser; }
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
// Type definitions for howler.js v2.1.1
// Project: https://github.com/goldfire/howler.js
// Definitions by: Pedro Casaubon <https://github.com/xperiments>
// Alexander Leon <https://github.com/alien35>
// Nicholas Higgins <https://github.com/nicholashza>
// Carlos Urango <https://github.com/cjurango>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
interface HowlerGlobal {
mute(muted: boolean): this;
volume(): number;
volume(volume: number): this;
codecs(ext: string): boolean;
unload(): this;
usingWebAudio: boolean;
html5PoolSize: number;
noAudio: boolean;
autoUnlock: boolean;
autoSuspend: boolean;
ctx: AudioContext;
masterGain: GainNode;
stereo(pan: number): this;
pos(x: number, y: number, z: number): this | void;
orientation(x: number, y: number, z: number, xUp: number, yUp: number, zUp: number): this | void;
}
declare let Howler: HowlerGlobal;
interface IHowlSoundSpriteDefinition {
[name: string]: [number, number] | [number, number, boolean]
}
interface IHowlProperties {
src: string | string[];
volume?: number;
html5?: boolean;
loop?: boolean;
preload?: boolean;
autoplay?: boolean;
mute?: boolean;
sprite?: IHowlSoundSpriteDefinition;
rate?: number;
pool?: number;
format?: string[] | string;
xhrWithCredentials?: boolean;
onload?: () => void;
onloaderror?: (soundId: number, error: any) => void;
onplay?: (soundId: number) => void;
onplayerror?: (soundId: number, error: any) => void;
onend?: (soundId: number) => void;
onpause?: (soundId: number) => void;
onstop?: (soundId: number) => void;
onmute?: (soundId: number) => void;
onvolume?: (soundId: number) => void;
onrate?: (soundId: number) => void;
onseek?: (soundId: number) => void;
onfade?: (soundId: number) => void;
onunlock?: (soundId: number) => void;
}
interface Howl {
play(spriteOrId?: string | number): number; // .play() is not chainable; the other methods are
pause(id?: number): this;
stop(id?: number): this;
mute(): boolean;
mute(muted: boolean, id?: number): this;
volume(): number;
volume(idOrSetVolume: number): this | number;
volume(volume: number, id: number): this;
fade(from: number, to: number, duration: number, id?: number): this;
rate(): number;
rate(idOrSetRate: number): this | number;
rate(rate: number, id: number): this;
seek(seek?: number, id?: number): this | number;
loop(id?: number): boolean;
loop(loop: boolean, id?: number): this;
playing(id?: number): boolean;
duration(id?: number): number;
state(): 'unloaded' | 'loading' | 'loaded';
load(): this;
unload(): void;
on(event: 'load', callback: () => void, id?: number): this;
on(event: 'loaderror', callback: (soundId: number, error: any) => void, id?: number): this;
on(event: 'play', callback: (soundId: number) => void, id?: number): this;
on(event: 'playerror', callback: (soundId: number, error: any) => void, id?: number): this;
on(event: 'end', callback: (soundId: number) => void, id?: number): this;
on(event: 'pause', callback: (soundId: number) => void, id?: number): this;
on(event: 'stop', callback: (soundId: number) => void, id?: number): this;
on(event: 'mute', callback: (soundId: number) => void, id?: number): this;
on(event: 'volume', callback: (soundId: number) => void, id?: number): this;
on(event: 'rate', callback: (soundId: number) => void, id?: number): this;
on(event: 'seek', callback: (soundId: number) => void, id?: number): this;
on(event: 'fade', callback: (soundId: number) => void, id?: number): this;
on(event: string, callback: Function, id?: number): this;
on(event: 'unlock', callback: (soundId: number) => void, id?: number): this;
once(event: 'load', callback: () => void, id?: number): this;
once(event: 'loaderror', callback: (soundId: number, error: any) => void, id?: number): this;
once(event: 'play', callback: (soundId: number) => void, id?: number): this;
once(event: 'playerror', callback: (soundId: number, error: any) => void, id?: number): this;
once(event: 'end', callback: (soundId: number) => void, id?: number): this;
once(event: 'pause', callback: (soundId: number) => void, id?: number): this;
once(event: 'stop', callback: (soundId: number) => void, id?: number): this;
once(event: 'mute', callback: (soundId: number) => void, id?: number): this;
once(event: 'volume', callback: (soundId: number) => void, id?: number): this;
once(event: 'rate', callback: (soundId: number) => void, id?: number): this;
once(event: 'seek', callback: (soundId: number) => void, id?: number): this;
once(event: 'fade', callback: (soundId: number) => void, id?: number): this;
once(event: string, callback: Function, id?: number): this;
once(event: 'unlock', callback: (soundId: number) => void, id?: number): this;
off(event: string, callback?: Function, id?: number): this;
off(): this;
stereo(pan: number, id?: number): this | void;
pos(x: number, y: number, z: number, id?: number): this | void;
orientation(x: number, y: number, z: number, xUp: number, yUp: number, zUp: number): this | void;
pannerAttr(o: {
coneInnerAngle?: number,
coneOuterAngle?: number, coneOuterGain?: number,
distanceModel: 'inverse' | 'linear', maxDistance: number,
panningModel: 'HRTF' | 'equalpower', refDistance: number, rolloffFactor: number
}, id?: number): this;
}
interface HowlStatic {
new(properties: IHowlProperties): Howl;
}
declare let Howl: HowlStatic;
declare module "howler" {
export let Howler: HowlerGlobal;
export let Howl: HowlStatic;
}
/* Polyfill service DEVELOPMENT MODE - for live use set NODE_ENV to 'production'
* Disable minification (remove `.min` from URL path) for more info */
(function(self, undefined) {function ArrayCreate(r){if(1/r==-1/0&&(r=0),r>Math.pow(2,32)-1)throw new RangeError("Invalid array length");var a=[];return a.length=r,a}function Call(t,l){var n=arguments.length>2?arguments[2]:[];if(!1===IsCallable(t))throw new TypeError(Object.prototype.toString.call(t)+"is not a function.");return t.apply(l,n)}function CreateDataProperty(e,r,t){var a={value:t,writable:!0,enumerable:!0,configurable:!0};try{return Object.defineProperty(e,r,a),!0}catch(e){return!1}}function CreateDataPropertyOrThrow(t,r,o){var e=CreateDataProperty(t,r,o);if(!e)throw new TypeError("Cannot assign value `"+Object.prototype.toString.call(o)+"` to property `"+Object.prototype.toString.call(r)+"` on object `"+Object.prototype.toString.call(t)+"`");return e}function CreateMethodProperty(e,r,t){var a={value:t,writable:!0,enumerable:!1,configurable:!0};Object.defineProperty(e,r,a)}function Get(n,t){return n[t]}function IsCallable(n){return"function"==typeof n}function RequireObjectCoercible(e){if(null===e||void 0===e)throw TypeError(Object.prototype.toString.call(e)+" is not coercible to Object.");return e}function SameValueNonNumber(e,n){return e===n}function ToBoolean(o){return Boolean(o)}function ToObject(r){if(null===r||void 0===r)throw TypeError();return Object(r)}function GetV(t,e){return ToObject(t)[e]}function GetMethod(e,l){var t=GetV(e,l);if(null!==t&&void 0!==t){if(!1===IsCallable(t))throw new TypeError("Method not callable: "+l);return t}}function Invoke(n,e){var t=arguments.length>2?arguments[2]:[],l=GetV(n,e);return Call(l,n,t)}function Type(e){switch(typeof e){case"undefined":return"undefined";case"boolean":return"boolean";case"number":return"number";case"string":return"string";case"symbol":return"symbol";default:return null===e?"null":"Symbol"in self&&(e instanceof self.Symbol||e.constructor===self.Symbol)?"symbol":"object"}}function CreateIterResultObject(e,r){if("boolean"!==Type(r))throw new Error;var t={};return CreateDataProperty(t,"value",e),CreateDataProperty(t,"done",r),t}function GetPrototypeFromConstructor(t,o){var r=Get(t,"prototype");return"object"!==Type(r)&&(r=o),r}function OrdinaryCreateFromConstructor(r,e){var t=arguments[2]||{},o=GetPrototypeFromConstructor(r,e),a=Object.create(o);for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&Object.defineProperty(a,n,{configurable:!0,enumerable:!1,writable:!0,value:t[n]});return a}var GetSubstitution=function(){function e(e){return/^[0-9]$/.test(e)}return function t(n,r,l,i,a,f){for(var s=n.length,h=r.length,c=l+s,u=i.length,v="",g=0;g<f.length;g+=1){var o=f.charAt(g),$=g+1>=f.length,d=g+2>=f.length;if("$"!==o||$)v+=f.charAt(g);else{var p=f.charAt(g+1);if("$"===p)v+="$",g+=1;else if("&"===p)v+=n,g+=1;else if("`"===p)v+=0===l?"":r.slice(0,l-1),g+=1;else if("'"===p)v+=c>=h?"":r.slice(c),g+=1;else{var A=d?null:f.charAt(g+2);if(!e(p)||"0"===p||!d&&e(A))if(e(p)&&(d||e(A))){var y=p+A,I=parseInt(y,10)-1;v+=y<=u&&"Undefined"===Type(i[I])?"":i[I],g+=2}else v+="$";else{var T=parseInt(p,10);v+=T<=u&&"Undefined"===Type(i[T-1])?"":i[T-1],g+=1}}}}return v}}();function IsConstructor(t){return"object"===Type(t)&&("function"==typeof t&&!!t.prototype)}function Construct(r){var t=arguments.length>2?arguments[2]:r,o=arguments.length>1?arguments[1]:[];if(!IsConstructor(r))throw new TypeError("F must be a constructor.");if(!IsConstructor(t))throw new TypeError("newTarget must be a constructor.");if(t===r)return new(Function.prototype.bind.apply(r,[null].concat(o)));var n=OrdinaryCreateFromConstructor(t,Object.prototype);return Call(r,n,o)}function IsRegExp(e){if("object"!==Type(e))return!1;var t="Symbol"in self&&"match"in self.Symbol?Get(e,self.Symbol.match):void 0;if(void 0!==t)return ToBoolean(t);try{var l=e.lastIndex;return e.lastIndex=0,RegExp.prototype.exec.call(e),!0}catch(e){}finally{e.lastIndex=l}return!1}function IteratorClose(r,t){if("object"!==Type(r["[[Iterator]]"]))throw new Error(Object.prototype.toString.call(r["[[Iterator]]"])+"is not an Object.");var e=r["[[Iterator]]"],o=GetMethod(e,"return");if(void 0===o)return t;try{var n=Call(o,e)}catch(r){var a=r}if(t)return t;if(a)throw a;if("object"!==Type(n))throw new TypeError("Iterator's return method returned a non-object.");return t}function IteratorComplete(t){if("object"!==Type(t))throw new Error(Object.prototype.toString.call(t)+"is not an Object.");return ToBoolean(Get(t,"done"))}function IteratorNext(t){if(arguments.length<2)var e=Call(t["[[NextMethod]]"],t["[[Iterator]]"]);else e=Call(t["[[NextMethod]]"],t["[[Iterator]]"],[arguments[1]]);if("object"!==Type(e))throw new TypeError("bad iterator");return e}function IteratorStep(t){var r=IteratorNext(t);return!0!==IteratorComplete(r)&&r}function IteratorValue(t){if("object"!==Type(t))throw new Error(Object.prototype.toString.call(t)+"is not an Object.");return Get(t,"value")}function OrdinaryToPrimitive(r,t){if("string"===t)var e=["toString","valueOf"];else e=["valueOf","toString"];for(var i=0;i<e.length;++i){var n=e[i],a=Get(r,n);if(IsCallable(a)){var o=Call(a,r);if("object"!==Type(o))return o}}throw new TypeError("Cannot convert to primitive.")}function RegExpExec(e,l){var r=Get(e,"exec");if(IsCallable(r)){var t=Call(r,e,[l]);if("object"!==Type(t)&&"null"!==Type(t))throw new TypeError("Invalid result: must be an object or null.");return t}return Call(RegExp.prototype.exec,e,[l])}function SameValueZero(e,a){return Type(e)===Type(a)&&("number"===Type(e)?!(!isNaN(e)||!isNaN(a))||(1/e==1/0&&1/a==-1/0||(1/e==-1/0&&1/a==1/0||e===a)):SameValueNonNumber(e,a))}function SpeciesConstructor(o,r){var t=Get(o,"constructor");if(void 0===t)return r;if("object"!==Type(t))throw new TypeError("O.constructor is not an Object");var e="function"==typeof self.Symbol&&"symbol"==typeof self.Symbol.species?t[self.Symbol.species]:void 0;if(void 0===e||null===e)return r;if(IsConstructor(e))return e;throw new TypeError("No constructor found")}function StringIndexOf(r,n,e){var f=r.length;if(""===n&&e<=f)return e;for(var t=n.length,a=e,i=-1;a+t<=f;){for(var g=!0,o=0;o<t;o+=1)if(r[a+o]!==n[o]){g=!1;break}if(g){i=a;break}a+=1}return i}function ToInteger(r){if("symbol"===Type(r))throw new TypeError("Cannot convert a Symbol value to a number");var o=Number(r);return isNaN(o)?0:1/o==1/0||1/o==-1/0||o===1/0||o===-1/0?o:(o<0?-1:1)*Math.floor(Math.abs(o))}function ToLength(n){var t=ToInteger(n);return t<=0?0:Math.min(t,Math.pow(2,53)-1)}function ToPrimitive(e){var t=arguments.length>1?arguments[1]:void 0;if("object"===Type(e)){if(arguments.length<2)var i="default";else t===String?i="string":t===Number&&(i="number");var r="function"==typeof self.Symbol&&"symbol"==typeof self.Symbol.toPrimitive?GetMethod(e,self.Symbol.toPrimitive):void 0;if(void 0!==r){var o=Call(r,e,[i]);if("object"!==Type(o))return o;throw new TypeError("Cannot convert exotic object to primitive.")}return"default"===i&&(i="number"),OrdinaryToPrimitive(e,i)}return e}function ToString(t){switch(Type(t)){case"symbol":throw new TypeError("Cannot convert a Symbol value to a string");case"object":return ToString(ToPrimitive(t,String));default:return String(t)}}function ToPropertyKey(r){var i=ToPrimitive(r,String);return"symbol"===Type(i)?i:ToString(i)}function TrimString(e,u){var r=RequireObjectCoercible(e),t=ToString(r),n=/[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/.source;if("start"===u)var p=String.prototype.replace.call(t,new RegExp("^"+n,"g"),"");else p="end"===u?String.prototype.replace.call(t,new RegExp(n+"$","g"),""):String.prototype.replace.call(t,new RegExp("^"+n+"|"+n+"$","g"),"");return p}function UTF16Decode(e,n){return 1024*(e-55296)+(n-56320)+65536}CreateMethodProperty(Array.prototype,"includes",function e(r){"use strict";var t=ToObject(this),o=ToLength(Get(t,"length"));if(0===o)return!1;var n=ToInteger(arguments[1]);if(n>=0)var a=n;else(a=o+n)<0&&(a=0);for(;a<o;){var i=Get(t,ToString(a));if(SameValueZero(r,i))return!0;a+=1}return!1});"use strict";var origSort=Array.prototype.sort;CreateMethodProperty(Array.prototype,"sort",function r(t){if(void 0!==t&&!1===IsCallable(t))throw new TypeError("The comparison function must be either a function or undefined");if(void 0===t)origSort.call(this);else{var e=Array.prototype.map.call(this,function(r,t){return{item:r,index:t}});origSort.call(e,function(r,e){var o=t.call(void 0,r.item,e.item);return 0===o?r.index-e.index:o});for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&e[o].item!==this[o]&&(this[o]=e[o].item)}return this});CreateMethodProperty(Number,"isInteger",function e(r){return"number"===Type(r)&&(!isNaN(r)&&r!==1/0&&r!==-1/0&&ToInteger(r)===r)});Object.defineProperty(Number,"MAX_SAFE_INTEGER",{enumerable:!1,configurable:!1,writable:!1,value:Math.pow(2,53)-1});!function(){var t=Object.getOwnPropertyDescriptor,r={}.toString,e="".split;CreateMethodProperty(Object,"getOwnPropertyDescriptor",function o(n,c){var i=ToObject(n);i=("string"===Type(i)||i instanceof String)&&"[object String]"==r.call(n)?e.call(n,""):Object(n);var p=ToPropertyKey(c);return t(i,p)})}();!function(e){CreateMethodProperty(Object,"isExtensible",function t(n){return"object"===Type(n)&&(!e||e(n))})}(Object.isExtensible);CreateMethodProperty(Object,"keys",function(){"use strict";function t(){var t;try{t=Object.create({})}catch(t){return!0}return o.call(t,"__proto__")}function r(t){var r=n.call(t),e="[object Arguments]"===r;return e||(e="[object Array]"!==r&&null!==t&&"object"==typeof t&&"number"==typeof t.length&&t.length>=0&&"[object Function]"===n.call(t.callee)),e}var e=Object.prototype.hasOwnProperty,n=Object.prototype.toString,o=Object.prototype.propertyIsEnumerable,c=!o.call({toString:null},"toString"),l=o.call(function(){},"prototype"),i=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],u=function(t){var r=t.constructor;return r&&r.prototype===t},a={$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},f=function(){if("undefined"==typeof window)return!1;for(var t in window)try{if(!a["$"+t]&&e.call(window,t)&&null!==window[t]&&"object"==typeof window[t])try{u(window[t])}catch(t){return!0}}catch(t){return!0}return!1}(),p=function(t){if("undefined"==typeof window||!f)return u(t);try{return u(t)}catch(t){return!1}};return function o(u){var a="[object Function]"===n.call(u),f=r(u),s="[object String]"===n.call(u),y=[];if(void 0===u||null===u)throw new TypeError("Cannot convert undefined or null to object");var h=l&&a;if(s&&u.length>0&&!e.call(u,0))for(var g=0;g<u.length;++g)y.push(String(g));if(f&&u.length>0)for(var w=0;w<u.length;++w)y.push(String(w));else for(var $ in u)t()&&"__proto__"===$||h&&"prototype"===$||!e.call(u,$)||y.push(String($));if(c)for(var d=p(u),b=0;b<i.length;++b)d&&"constructor"===i[b]||!e.call(u,i[b])||y.push(i[b]);return y}}());function EnumerableOwnProperties(e,r){for(var t=Object.keys(e),n=[],s=t.length,a=0;a<s;a++){var i=t[a];if("string"===Type(i)){var u=Object.getOwnPropertyDescriptor(e,i);if(u&&u.enumerable)if("key"===r)n.push(i);else{var p=Get(e,i);if("value"===r)n.push(p);else{var f=[i,p];n.push(f)}}}}return n}!function(){var e={}.toString,t="".split;CreateMethodProperty(Object,"entries",function r(n){var i=ToObject(n);return i=("string"===Type(i)||i instanceof String)&&"[object String]"==e.call(n)?t.call(n,""):Object(n),EnumerableOwnProperties(i,"key+value")})}();CreateMethodProperty(Object,"assign",function t(e,r){var o=ToObject(e);if(1===arguments.length)return o;var c,a,l,n,i=Array.prototype.slice.call(arguments,1);for(c=0;c<i.length;c++){var p=i[c];for(void 0===p||null===p?l=[]:(n="[object String]"===Object.prototype.toString.call(p)?String(p).split(""):ToObject(p),l=Object.keys(n)),a=0;a<l.length;a++){var b,y=l[a];try{var g=Object.getOwnPropertyDescriptor(n,y);b=void 0!==g&&!0===g.enumerable}catch(t){b=Object.prototype.propertyIsEnumerable.call(n,y)}if(b){var j=Get(n,y);o[y]=j}}}return o});!function(){var t={}.toString,e="".split,r=[].concat,o=Object.prototype.hasOwnProperty,c=Object.getOwnPropertyNames||Object.keys,n="object"==typeof self?c(self):[];CreateMethodProperty(Object,"getOwnPropertyNames",function l(a){var p=ToObject(a);if("[object Window]"===t.call(p))try{return c(p)}catch(t){return r.call([],n)}p="[object String]"==t.call(p)?e.call(p,""):Object(p);for(var i=c(p),s=["length","prototype"],O=0;O<s.length;O++){var b=s[O];o.call(p,b)&&!i.includes(b)&&i.push(b)}if(i.includes("__proto__")){var f=i.indexOf("__proto__");i.splice(f,1)}return i})}();!function(){if(!Object.setPrototypeOf){var t,e,o=Object.getOwnPropertyNames,r=Object.getOwnPropertyDescriptor,n=Object.create,c=Object.defineProperty,_=Object.getPrototypeOf,f=Object.prototype,p=function(t,e){return o(e).forEach(function(o){c(t,o,r(e,o))}),t},O=function t(e,o){return p(n(o),e)};try{t=r(f,"__proto__").set,t.call({},null),e=function e(o,r){return t.call(o,r),o}}catch(o){t={__proto__:null},t instanceof Object?e=O:(t.__proto__=f,e=t instanceof Object?function t(e,o){return e.__proto__=o,e}:function t(e,o){return _(e)?(e.__proto__=o,e):O(e,o)})}CreateMethodProperty(Object,"setPrototypeOf",e)}}();!function(){var t={}.toString,e="".split;CreateMethodProperty(Object,"values",function r(n){var c="[object String]"==t.call(n)?e.call(n,""):ToObject(n);return Object.keys(c).map(function(t){return c[t]})})}();Object.defineProperty(RegExp.prototype,"flags",{configurable:!0,enumerable:!1,get:function(){var e=this;if("object"!==Type(e))throw new TypeError("Method called on incompatible type: must be an object.");var o="";return ToBoolean(Get(e,"global"))&&(o+="g"),ToBoolean(Get(e,"ignoreCase"))&&(o+="i"),ToBoolean(Get(e,"multiline"))&&(o+="m"),ToBoolean(Get(e,"unicode"))&&(o+="u"),ToBoolean(Get(e,"sticky"))&&(o+="y"),o}});CreateMethodProperty(String.prototype,"codePointAt",function t(e){var r=RequireObjectCoercible(this),o=ToString(r),i=ToInteger(e),n=o.length;if(!(i<0||i>=n)){var c=String.prototype.charCodeAt.call(o,i);if(c<55296||c>56319||i+1===n)return c;var a=String.prototype.charCodeAt.call(o,i+1);return a<56320||a>57343?c:UTF16Decode(c,a)}});function AdvanceStringIndex(e,n,t){if(n>Number.MAX_SAFE_INTEGER)throw new TypeError("Assertion failed: `index` must be <= 2**53");return!1===t?n+1:n+1>=e.length?n+1:n+e.codePointAt(n).length}CreateMethodProperty(String.prototype,"includes",function t(e){"use strict";var r=arguments.length>1?arguments[1]:void 0,n=RequireObjectCoercible(this),o=ToString(n);if(IsRegExp(e))throw new TypeError("First argument to String.prototype.includes must not be a regular expression");var i=ToString(e),g=ToInteger(r),a=o.length,p=Math.min(Math.max(g,0),a);return-1!==String.prototype.indexOf.call(o,i,p)});CreateMethodProperty(String.prototype,"repeat",function r(e){"use strict";var t=RequireObjectCoercible(this),n=ToString(t),o=ToInteger(e);if(o<0)throw new RangeError("Invalid count value");if(o===1/0)throw new RangeError("Invalid count value");return 0===o?"":new Array(o+1).join(n)});CreateMethodProperty(String.prototype,"trim",function t(){"use strict";var r=this;return TrimString(r,"start+end")});!function(r,t){var e=function t(e){var a=String(e).trim(),o=r(a);return 0===o&&"-"==a.charAt(0)?-0:o};CreateMethodProperty(t,"parseFloat",e),CreateMethodProperty(Number,"parseFloat",t.parseFloat)}(parseFloat,this);!function(t,r){var e=function r(e,n){var a=String(e).trim();return t(a,n>>>0||(/^[-+]?0[xX]/.test(a)?16:10))};CreateMethodProperty(r,"parseInt",e),CreateMethodProperty(Number,"parseInt",r.parseInt)}(parseInt,this);CreateMethodProperty(String.prototype,"trimEnd",function t(){"use strict";var r=this;return TrimString(r,"end")});CreateMethodProperty(String.prototype,"trimStart",function t(){"use strict";var r=this;return TrimString(r,"start")});!function(r,t,n){"use strict";function e(r){if("symbol"===Type(r))return r;throw TypeError(r+" is not a symbol")}var o,u=0,i=""+Math.random(),a="__symbol:",l=a.length,c="__symbol@@"+i,f={},s="defineProperty",v="defineProperties",y="getOwnPropertyNames",b="getOwnPropertyDescriptor",h="propertyIsEnumerable",p=r.prototype,m=p.hasOwnProperty,g=p[h],d=p.toString,w=Array.prototype.concat,S=r.getOwnPropertyNames?r.getOwnPropertyNames(self):[],P=r[y],O=function r(t){if("[object Window]"===d.call(t))try{return P(t)}catch(r){return w.call([],S)}return P(t)},j=r[b],E=r.create,N=r.keys,T=r.freeze||r,_=r[s],k=r[v],F=j(r,y),I=function(r,t,n){if(!m.call(r,c))try{_(r,c,{enumerable:!1,configurable:!1,writable:!1,value:{}})}catch(t){r[c]={}}r[c]["@@"+t]=n},x=function(r,t){var n=E(r);return O(t).forEach(function(r){W.call(t,r)&&K(n,r,t[r])}),n},z=function(r){var t=E(r);return t.enumerable=!1,t},A=function r(){},D=function(r){return r!=c&&!m.call(G,r)},M=function(r){return r!=c&&m.call(G,r)},W=function r(t){var n=""+t;return M(n)?m.call(this,n)&&this[c]&&this[c]["@@"+n]:g.call(this,t)},q=function(t){var n={enumerable:!1,configurable:!0,get:A,set:function(r){o(this,t,{enumerable:!1,configurable:!0,writable:!0,value:r}),I(this,t,!0)}};try{_(p,t,n)}catch(r){p[t]=n.value}G[t]=_(r(t),"constructor",H);var e=j(C.prototype,"description");return e&&_(G[t],"description",e),T(G[t])},B=function(r){var t=e(r);if(X){var n=U(t);if(""!==n)return n.slice(1,-1)}if(void 0!==f[t])return f[t];var o=t.toString(),u=o.lastIndexOf("0.");return""!==(o=o.slice(10,u))?o:void 0},C=function r(){var t=arguments[0];if(this instanceof r)throw new TypeError("Symbol is not a constructor");var n=a.concat(t||"",i,++u);return void 0===t||null!==t&&!isNaN(t)&&""!==String(t)||(f[n]=String(t)),q(n)},G=E(null),H={value:C},J=function(r){return G[r]},K=function r(t,n,e){var u=""+n;return M(u)?(o(t,u,e.enumerable?z(e):e),I(t,u,!!e.enumerable)):_(t,n,e),t},L=function(r){return function(t){return m.call(r,c)&&m.call(r[c],"@@"+t)}},Q=function r(t){return O(t).filter(t===p?L(t):M).map(J)};F.value=K,_(r,s,F),F.value=Q,_(r,"getOwnPropertySymbols",F),F.value=function r(t){return O(t).filter(D)},_(r,y,F),F.value=function r(t,n){var e=Q(n);return e.length?N(n).concat(e).forEach(function(r){W.call(n,r)&&K(t,r,n[r])}):k(t,n),t},_(r,v,F),F.value=W,_(p,h,F),F.value=C,_(n,"Symbol",F),F.value=function(r){var t=a.concat(a,r,i);return t in p?G[t]:q(t)},_(C,"for",F),F.value=function(r){if(D(r))throw new TypeError(r+" is not a symbol");return m.call(G,r)?r.slice(2*l,-i.length):void 0},_(C,"keyFor",F),F.value=function r(t,n){var e=j(t,n);return e&&M(n)&&(e.enumerable=W.call(t,n)),e},_(r,b,F),F.value=function r(t,n){return 1===arguments.length||void 0===n?E(t):x(t,n)},_(r,"create",F);var R=null===function(){return this}.call(null);if(F.value=R?function(){var r=d.call(this);return"[object String]"===r&&M(this)?"[object Symbol]":r}:function(){if(this===window)return"[object Null]";var r=d.call(this);return"[object String]"===r&&M(this)?"[object Symbol]":r},_(p,"toString",F),o=function(r,t,n){var e=j(p,t);delete p[t],_(r,t,n),r!==p&&_(p,t,e)},function(){try{var t={};return r.defineProperty(t,"t",{configurable:!0,enumerable:!1,get:function(){return!0},set:void 0}),!!t.t}catch(r){return!1}}()){var U;try{U=Function("s","var v = s.valueOf(); return { [v]() {} }[v].name;")}catch(r){}var V=function(){},X=U&&"inferred"===V.name?U:null;r.defineProperty(n.Symbol.prototype,"description",{configurable:!0,enumerable:!1,get:function(){return B(this)}})}}(Object,0,self);Object.defineProperty(self.Symbol,"iterator",{value:self.Symbol("iterator")});function GetIterator(t){var e=arguments.length>1?arguments[1]:GetMethod(t,Symbol.iterator),r=Call(e,t);if("object"!==Type(r))throw new TypeError("bad iterator");var o=GetV(r,"next"),a=Object.create(null);return a["[[Iterator]]"]=r,a["[[NextMethod]]"]=o,a["[[Done]]"]=!1,a}Object.defineProperty(Symbol,"matchAll",{value:Symbol("matchAll")});Object.defineProperty(Symbol,"replace",{value:Symbol("replace")});CreateMethodProperty(String.prototype,"replaceAll",function e(r,t){"use strict";var i=RequireObjectCoercible(this);if(void 0!==r&&null!==r){if(IsRegExp(r)){var o=Get(r,"flags");if(!("flags"in RegExp.prototype||!0===r.global))throw TypeError("");if("flags"in RegExp.prototype&&(RequireObjectCoercible(o),-1===ToString(o).indexOf("g")))throw TypeError("")}var l="Symbol"in self&&"replace"in self.Symbol?GetMethod(r,self.Symbol.replace):void 0;if(void 0!==l)return Call(l,r,[i,t])}var n=ToString(i),a=ToString(r),g=IsCallable(t);!1===g&&(t=ToString(t));for(var f=a.length,s=Math.max(1,f),p=[],v=StringIndexOf(n,a,0);-1!==v;)p.push(v),v=StringIndexOf(n,a,v+s);for(var b=0,u="",S=0;S<p.length;S++){var d=n.substring(b,p[S]);if(g)var h=ToString(Call(t,void 0,[a,p[S],n]));else{var c=[];h=GetSubstitution(a,n,p[S],c,void 0,t)}u=u+d+h,b=p[S]+f}return b<n.length&&(u+=n.substring(b)),u});Object.defineProperty(Symbol,"species",{value:Symbol("species")});!function(e){function t(e,t){if("object"!==Type(e))throw new TypeError("createMapIterator called on incompatible receiver "+Object.prototype.toString.call(e));if(!0!==e._es6Map)throw new TypeError("createMapIterator called on incompatible receiver "+Object.prototype.toString.call(e));var r=Object.create(y);return Object.defineProperty(r,"[[Map]]",{configurable:!0,enumerable:!1,writable:!0,value:e}),Object.defineProperty(r,"[[MapNextIndex]]",{configurable:!0,enumerable:!1,writable:!0,value:0}),Object.defineProperty(r,"[[MapIterationKind]]",{configurable:!0,enumerable:!1,writable:!0,value:t}),r}var r=0,o=Symbol("meta_"+(1e8*Math.random()+"").replace(".","")),a=function(e){if("object"==typeof e?null!==e:"function"==typeof e){if(!Object.isExtensible(e))return!1;if(!Object.prototype.hasOwnProperty.call(e,o)){var t=typeof e+"-"+ ++r;Object.defineProperty(e,o,{configurable:!1,enumerable:!1,writable:!1,value:t})}return e[o]}return""+e},p=function(e,t){var r=a(t);if(!1===r)return i(e,t);var o=e._table[r];return void 0!==o&&o},i=function(e,t){for(var r=0;r<e._keys.length;r++){var o=e._keys[r];if(o!==l&&SameValueZero(o,t))return r}return!1},n=function(e,t,r){var o=a(t);return!1!==o&&(!1===r?delete e._table[o]:e._table[o]=r,!0)},l=Symbol("undef"),c=function e(){if(!(this instanceof e))throw new TypeError('Constructor Map requires "new"');var t=OrdinaryCreateFromConstructor(this,e.prototype,{_table:{},_keys:[],_values:[],_size:0,_es6Map:!0}),r=arguments.length>0?arguments[0]:void 0;if(null===r||void 0===r)return t;var o=t.set;if(!IsCallable(o))throw new TypeError("Map.prototype.set is not a function");try{for(var a=GetIterator(r);;){var p=IteratorStep(a);if(!1===p)return t;var i=IteratorValue(p);if("object"!==Type(i))try{throw new TypeError("Iterator value "+i+" is not an entry object")}catch(e){return IteratorClose(a,e)}try{var n=i[0],l=i[1];o.call(t,n,l)}catch(e){return IteratorClose(a,e)}}}catch(e){if(Array.isArray(r)||"[object Arguments]"===Object.prototype.toString.call(r)){var c,y=r.length;for(c=0;c<y;c++)o.call(t,r[c][0],r[c][1])}}return t};Object.defineProperty(c,"prototype",{configurable:!1,enumerable:!1,writable:!1,value:{}}),Object.defineProperty(c,Symbol.species,{configurable:!0,enumerable:!1,get:function(){return this},set:void 0}),CreateMethodProperty(c.prototype,"clear",function e(){var t=this;if("object"!==Type(t))throw new TypeError("Method Map.prototype.clear called on incompatible receiver "+Object.prototype.toString.call(t));if(!0!==t._es6Map)throw new TypeError("Method Map.prototype.clear called on incompatible receiver "+Object.prototype.toString.call(t));for(var r=t._keys,o=0;o<r.length;o++)t._keys[o]=l,t._values[o]=l;this._size=0,this._table={}}),CreateMethodProperty(c.prototype,"constructor",c),CreateMethodProperty(c.prototype,"delete",function(e){var t=this;if("object"!==Type(t))throw new TypeError("Method Map.prototype.clear called on incompatible receiver "+Object.prototype.toString.call(t));if(!0!==t._es6Map)throw new TypeError("Method Map.prototype.clear called on incompatible receiver "+Object.prototype.toString.call(t));var r=p(t,e);if(!1!==r){var o=t._keys[r];if(o!==l&&SameValueZero(o,e))return this._keys[r]=l,this._values[r]=l,this._size=--this._size,n(this,e,!1),!0}return!1}),CreateMethodProperty(c.prototype,"entries",function e(){return t(this,"key+value")}),CreateMethodProperty(c.prototype,"forEach",function(e){var t=this;if("object"!==Type(t))throw new TypeError("Method Map.prototype.forEach called on incompatible receiver "+Object.prototype.toString.call(t));if(!0!==t._es6Map)throw new TypeError("Method Map.prototype.forEach called on incompatible receiver "+Object.prototype.toString.call(t));if(!IsCallable(e))throw new TypeError(Object.prototype.toString.call(e)+" is not a function.");if(arguments[1])var r=arguments[1];for(var o=t._keys,a=0;a<o.length;a++)t._keys[a]!==l&&t._values[a]!==l&&e.call(r,t._values[a],t._keys[a],t)}),CreateMethodProperty(c.prototype,"get",function e(t){var r=this;if("object"!==Type(r))throw new TypeError("Method Map.prototype.get called on incompatible receiver "+Object.prototype.toString.call(r));if(!0!==r._es6Map)throw new TypeError("Method Map.prototype.get called on incompatible receiver "+Object.prototype.toString.call(r));var o=p(r,t);if(!1!==o){var a=r._keys[o];if(a!==l&&SameValueZero(a,t))return r._values[o]}}),CreateMethodProperty(c.prototype,"has",function e(t){var r=this;if("object"!=typeof r)throw new TypeError("Method Map.prototype.has called on incompatible receiver "+Object.prototype.toString.call(r));if(!0!==r._es6Map)throw new TypeError("Method Map.prototype.has called on incompatible receiver "+Object.prototype.toString.call(r));var o=p(r,t);if(!1!==o){var a=r._keys[o];if(a!==l&&SameValueZero(a,t))return!0}return!1}),CreateMethodProperty(c.prototype,"keys",function e(){return t(this,"key")}),CreateMethodProperty(c.prototype,"set",function e(t,r){var o=this;if("object"!==Type(o))throw new TypeError("Method Map.prototype.set called on incompatible receiver "+Object.prototype.toString.call(o));if(!0!==o._es6Map)throw new TypeError("Method Map.prototype.set called on incompatible receiver "+Object.prototype.toString.call(o));var a=p(o,t);if(!1!==a)o._values[a]=r;else{-0===t&&(t=0);var i={"[[Key]]":t,"[[Value]]":r};o._keys.push(i["[[Key]]"]),o._values.push(i["[[Value]]"]),n(o,t,o._keys.length-1),++o._size}return o}),Object.defineProperty(c.prototype,"size",{configurable:!0,enumerable:!1,get:function(){var e=this;if("object"!==Type(e))throw new TypeError("Method Map.prototype.size called on incompatible receiver "+Object.prototype.toString.call(e));if(!0!==e._es6Map)throw new TypeError("Method Map.prototype.size called on incompatible receiver "+Object.prototype.toString.call(e));return this._size},set:void 0}),CreateMethodProperty(c.prototype,"values",function e(){return t(this,"value")}),CreateMethodProperty(c.prototype,Symbol.iterator,c.prototype.entries),"name"in c||Object.defineProperty(c,"name",{configurable:!0,enumerable:!1,writable:!1,value:"Map"});var y={};Object.defineProperty(y,"isMapIterator",{configurable:!1,enumerable:!1,writable:!1,value:!0}),CreateMethodProperty(y,"next",function e(){var t=this;if("object"!==Type(t))throw new TypeError("Method %MapIteratorPrototype%.next called on incompatible receiver "+Object.prototype.toString.call(t));if(!t.isMapIterator)throw new TypeError("Method %MapIteratorPrototype%.next called on incompatible receiver "+Object.prototype.toString.call(t));var r=t["[[Map]]"],o=t["[[MapNextIndex]]"],a=t["[[MapIterationKind]]"];if(void 0===r)return CreateIterResultObject(void 0,!0);if(!r._es6Map)throw new Error(Object.prototype.toString.call(r)+" has a [[MapData]] internal slot.");for(var p=r._keys,i=p.length;o<i;){var n=Object.create(null);if(n["[[Key]]"]=r._keys[o],n["[[Value]]"]=r._values[o],o+=1,t["[[MapNextIndex]]"]=o,n["[[Key]]"]!==l){if("key"===a)var c=n["[[Key]]"];else if("value"===a)c=n["[[Value]]"];else{if("key+value"!==a)throw new Error;c=[n["[[Key]]"],n["[[Value]]"]]}return CreateIterResultObject(c,!1)}}return t["[[Map]]"]=void 0,CreateIterResultObject(void 0,!0)}),CreateMethodProperty(y,Symbol.iterator,function e(){return this}),CreateMethodProperty(e,"Map",c)}(self);!function(e){function t(e,t){if("object"!=typeof e)throw new TypeError("createSetIterator called on incompatible receiver "+Object.prototype.toString.call(e));if(!0!==e._es6Set)throw new TypeError("createSetIterator called on incompatible receiver "+Object.prototype.toString.call(e));var r=Object.create(i);return Object.defineProperty(r,"[[IteratedSet]]",{configurable:!0,enumerable:!1,writable:!0,value:e}),Object.defineProperty(r,"[[SetNextIndex]]",{configurable:!0,enumerable:!1,writable:!0,value:0}),Object.defineProperty(r,"[[SetIterationKind]]",{configurable:!0,enumerable:!1,writable:!0,value:t}),r}var r=Symbol("undef"),o=function e(){if(!(this instanceof e))throw new TypeError('Constructor Set requires "new"');var t=OrdinaryCreateFromConstructor(this,e.prototype,{_values:[],_size:0,_es6Set:!0}),r=arguments.length>0?arguments[0]:void 0;if(null===r||void 0===r)return t;var o=t.add;if(!IsCallable(o))throw new TypeError("Set.prototype.add is not a function");try{for(var a=GetIterator(r);;){var i=IteratorStep(a);if(!1===i)return t;var n=IteratorValue(i);try{o.call(t,n)}catch(e){return IteratorClose(a,e)}}}catch(e){if(!Array.isArray(r)&&"[object Arguments]"!==Object.prototype.toString.call(r))throw e;var l,p=r.length;for(l=0;l<p;l++)o.call(t,r[l])}return t};Object.defineProperty(o,"prototype",{configurable:!1,enumerable:!1,writable:!1,value:{}}),Object.defineProperty(o,Symbol.species,{configurable:!0,enumerable:!1,get:function(){return this},set:void 0}),CreateMethodProperty(o.prototype,"add",function e(t){var o=this;if("object"!=typeof o)throw new TypeError("Method Set.prototype.add called on incompatible receiver "+Object.prototype.toString.call(o));if(!0!==o._es6Set)throw new TypeError("Method Set.prototype.add called on incompatible receiver "+Object.prototype.toString.call(o));for(var a=o._values,i=0;i<a.length;i++){var n=a[i];if(n!==r&&SameValueZero(n,t))return o}return 0===t&&1/t==-1/0&&(t=0),o._values.push(t),this._size=++this._size,o}),CreateMethodProperty(o.prototype,"clear",function e(){var t=this;if("object"!=typeof t)throw new TypeError("Method Set.prototype.clear called on incompatible receiver "+Object.prototype.toString.call(t));if(!0!==t._es6Set)throw new TypeError("Method Set.prototype.clear called on incompatible receiver "+Object.prototype.toString.call(t));for(var o=t._values,a=0;a<o.length;a++)o[a]=r;this._size=0}),CreateMethodProperty(o.prototype,"constructor",o),CreateMethodProperty(o.prototype,"delete",function(e){var t=this;if("object"!=typeof t)throw new TypeError("Method Set.prototype.delete called on incompatible receiver "+Object.prototype.toString.call(t));if(!0!==t._es6Set)throw new TypeError("Method Set.prototype.delete called on incompatible receiver "+Object.prototype.toString.call(t));for(var o=t._values,a=0;a<o.length;a++){var i=o[a];if(i!==r&&SameValueZero(i,e))return o[a]=r,this._size=--this._size,!0}return!1}),CreateMethodProperty(o.prototype,"entries",function e(){return t(this,"key+value")}),CreateMethodProperty(o.prototype,"forEach",function e(t){var o=this;if("object"!=typeof o)throw new TypeError("Method Set.prototype.forEach called on incompatible receiver "+Object.prototype.toString.call(o));if(!0!==o._es6Set)throw new TypeError("Method Set.prototype.forEach called on incompatible receiver "+Object.prototype.toString.call(o));if(!IsCallable(t))throw new TypeError(Object.prototype.toString.call(t)+" is not a function.");if(arguments[1])var a=arguments[1];for(var i=o._values,n=0;n<i.length;n++){var l=i[n];l!==r&&t.call(a,l,l,o)}}),CreateMethodProperty(o.prototype,"has",function e(t){var o=this;if("object"!=typeof o)throw new TypeError("Method Set.prototype.forEach called on incompatible receiver "+Object.prototype.toString.call(o));if(!0!==o._es6Set)throw new TypeError("Method Set.prototype.forEach called on incompatible receiver "+Object.prototype.toString.call(o));for(var a=o._values,i=0;i<a.length;i++){var n=a[i];if(n!==r&&SameValueZero(n,t))return!0}return!1});var a=function e(){return t(this,"value")};CreateMethodProperty(o.prototype,"values",a),CreateMethodProperty(o.prototype,"keys",a),Object.defineProperty(o.prototype,"size",{configurable:!0,enumerable:!1,get:function(){var e=this;if("object"!=typeof e)throw new TypeError("Method Set.prototype.size called on incompatible receiver "+Object.prototype.toString.call(e));if(!0!==e._es6Set)throw new TypeError("Method Set.prototype.size called on incompatible receiver "+Object.prototype.toString.call(e));for(var t=e._values,o=0,a=0;a<t.length;a++){t[a]!==r&&(o+=1)}return o},set:void 0}),CreateMethodProperty(o.prototype,Symbol.iterator,a),"name"in o||Object.defineProperty(o,"name",{configurable:!0,enumerable:!1,writable:!1,value:"Set"});var i={};Object.defineProperty(i,"isSetIterator",{configurable:!1,enumerable:!1,writable:!1,value:!0}),CreateMethodProperty(i,"next",function e(){var t=this;if("object"!=typeof t)throw new TypeError("Method %SetIteratorPrototype%.next called on incompatible receiver "+Object.prototype.toString.call(t));if(!t.isSetIterator)throw new TypeError("Method %SetIteratorPrototype%.next called on incompatible receiver "+Object.prototype.toString.call(t));var o=t["[[IteratedSet]]"],a=t["[[SetNextIndex]]"],i=t["[[SetIterationKind]]"];if(void 0===o)return CreateIterResultObject(void 0,!0);if(!o._es6Set)throw new Error(Object.prototype.toString.call(o)+" does not have [[SetData]] internal slot.");for(var n=o._values,l=n.length;a<l;){var p=n[a];if(a+=1,t["[[SetNextIndex]]"]=a,p!==r)return"key+value"===i?CreateIterResultObject([p,p],!1):CreateIterResultObject(p,!1)}return t["[[IteratedSet]]"]=void 0,CreateIterResultObject(void 0,!0)}),CreateMethodProperty(i,Symbol.iterator,function e(){return this}),CreateMethodProperty(e,"Set",o)}(self);!function(){function r(r){return"string"==typeof r||"object"==typeof r&&"[object String]"===t.call(r)}var t=Object.prototype.toString,e=String.prototype.match;CreateMethodProperty(Array,"from",function t(o){var a=this,n=arguments.length>1?arguments[1]:void 0;if(void 0===n)var i=!1;else{if(!1===IsCallable(n))throw new TypeError(Object.prototype.toString.call(n)+" is not a function.");var l=arguments.length>2?arguments[2]:void 0;if(void 0!==l)var c=l;else c=void 0;i=!0}var u=GetMethod(o,Symbol.iterator);if(void 0!==u){if(IsConstructor(a))var v=Construct(a);else v=ArrayCreate(0);for(var f=GetIterator(o,u),s=0;;){if(s>=Math.pow(2,53)-1){var h=new TypeError("Iteration count can not be greater than or equal 9007199254740991.");return IteratorClose(f,h)}var y=ToString(s),C=IteratorStep(f);if(!1===C)return v.length=s,v;var g=IteratorValue(C);if(i)try{var p=Call(n,c,[g,s])}catch(r){return IteratorClose(f,r)}else p=g;try{CreateDataPropertyOrThrow(v,y,p)}catch(r){return IteratorClose(f,r)}s+=1}}if(r(o))var I=e.call(o,/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[^\uD800-\uDFFF]|./g)||[];else I=ToObject(o);var b=ToLength(Get(I,"length"));for(v=IsConstructor(a)?Construct(a,[b]):ArrayCreate(b),s=0;s<b;){y=ToString(s);var d=Get(I,y);p=!0===i?Call(n,c,[d,s]):d,CreateDataPropertyOrThrow(v,y,p),s+=1}return v.length=b,v})}();Object.defineProperty(Symbol,"toStringTag",{value:Symbol("toStringTag")});function CreateRegExpStringIterator(e,t,r,n){var a={};return CreateMethodProperty(a,"next",function a(){if(!0===this["[[Done]]"])return CreateIterResultObject(void 0,!0);var i=RegExpExec(e,t);if(null===i)return this["[[Done]]"]=!0,CreateIterResultObject(void 0,!0);if(!1===r){var o=CreateIterResultObject(i,!1);return this["[[Done]]"]=!0,o}if(""===ToString(Get(i,"0"))){var u=ToLength(Get(e,"lastIndex")),l=AdvanceStringIndex(t,u,n);e.lastIndex=l}return CreateIterResultObject(i,!1)}),Object.defineProperty(a,Symbol.toStringTag,{configurable:!0,enumerable:!1,writable:!1,value:"RegExp String Iterator"}),CreateMethodProperty(a,Symbol.iterator,function e(){return this}),a}var supportsRegexpLiteralConstructorWithFlags=function(){try{return new RegExp(/x/,"g"),!0}catch(t){return!1}}();CreateMethodProperty(RegExp.prototype,Symbol.matchAll,function(t){"use strict";var e=this;if("object"!==Type(e))throw new TypeError("Method called on incompatible type: must be an object.");var r=ToString(t),o=SpeciesConstructor(e,RegExp),n=ToString(Get(e,"flags"));"flags"in RegExp.prototype||(n="",!0===e.global&&(n+="g"),!0===e.ignoreCase&&(n+="i"),!0===e.multiline&&(n+="m"));var a=Construct(o,[supportsRegexpLiteralConstructorWithFlags?e:e.source,n]),i=ToLength(Get(e,"lastIndex"));a.lastIndex=i;var p=n.indexOf("g")>-1,s=n.indexOf("u")>-1;return CreateRegExpStringIterator(a,r,p,s)});CreateMethodProperty(String.prototype,"matchAll",function e(l){"use strict";var r=RequireObjectCoercible(this);if(void 0!==l&&null!==l){if(IsRegExp(l)){var t=Get(l,"flags");if(!("flags"in RegExp.prototype||!0===l.global))throw TypeError("");if("flags"in RegExp.prototype&&(RequireObjectCoercible(t),-1===ToString(t).indexOf("g")))throw TypeError("")}var o="Symbol"in self&&"matchAll"in self.Symbol?GetMethod(l,self.Symbol.matchAll):void 0;if(void 0!==o)return Call(o,l,[r])}var i=ToString(r),n=new RegExp(l,"g");return Invoke(n,"Symbol"in self&&"matchAll"in self.Symbol&&self.Symbol.matchAll,[i])});var Iterator=function(){var e=function(){return this.length=0,this},t=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e},_=function(e,n){if(!(this instanceof _))return new _(e,n);Object.defineProperties(this,{__list__:{writable:!0,value:e},__context__:{writable:!0,value:n},__nextIndex__:{writable:!0,value:0}}),n&&(t(n.on),n.on("_add",this._onAdd.bind(this)),n.on("_delete",this._onDelete.bind(this)),n.on("_clear",this._onClear.bind(this)))};return Object.defineProperties(_.prototype,Object.assign({constructor:{value:_,configurable:!0,enumerable:!1,writable:!0},_next:{value:function(){var e;if(this.__list__)return this.__redo__&&void 0!==(e=this.__redo__.shift())?e:this.__nextIndex__<this.__list__.length?this.__nextIndex__++:void this._unBind()},configurable:!0,enumerable:!1,writable:!0},next:{value:function(){return this._createResult(this._next())},configurable:!0,enumerable:!1,writable:!0},_createResult:{value:function(e){return void 0===e?{done:!0,value:void 0}:{done:!1,value:this._resolve(e)}},configurable:!0,enumerable:!1,writable:!0},_resolve:{value:function(e){return this.__list__[e]},configurable:!0,enumerable:!1,writable:!0},_unBind:{value:function(){this.__list__=null,delete this.__redo__,this.__context__&&(this.__context__.off("_add",this._onAdd.bind(this)),this.__context__.off("_delete",this._onDelete.bind(this)),this.__context__.off("_clear",this._onClear.bind(this)),this.__context__=null)},configurable:!0,enumerable:!1,writable:!0},toString:{value:function(){return"[object Iterator]"},configurable:!0,enumerable:!1,writable:!0}},{_onAdd:{value:function(e){if(!(e>=this.__nextIndex__)){if(++this.__nextIndex__,!this.__redo__)return void Object.defineProperty(this,"__redo__",{value:[e],configurable:!0,enumerable:!1,writable:!1});this.__redo__.forEach(function(t,_){t>=e&&(this.__redo__[_]=++t)},this),this.__redo__.push(e)}},configurable:!0,enumerable:!1,writable:!0},_onDelete:{value:function(e){var t;e>=this.__nextIndex__||(--this.__nextIndex__,this.__redo__&&(t=this.__redo__.indexOf(e),-1!==t&&this.__redo__.splice(t,1),this.__redo__.forEach(function(t,_){t>e&&(this.__redo__[_]=--t)},this)))},configurable:!0,enumerable:!1,writable:!0},_onClear:{value:function(){this.__redo__&&e.call(this.__redo__),this.__nextIndex__=0},configurable:!0,enumerable:!1,writable:!0}})),Object.defineProperty(_.prototype,Symbol.iterator,{value:function(){return this},configurable:!0,enumerable:!1,writable:!0}),Object.defineProperty(_.prototype,Symbol.toStringTag,{value:"Iterator",configurable:!1,enumerable:!1,writable:!0}),_}();var ArrayIterator=function(){var e=function(t,r){if(!(this instanceof e))return new e(t,r);Iterator.call(this,t),r=r?String.prototype.includes.call(r,"key+value")?"key+value":String.prototype.includes.call(r,"key")?"key":"value":"value",Object.defineProperty(this,"__kind__",{value:r,configurable:!1,enumerable:!1,writable:!1})};return Object.setPrototypeOf&&Object.setPrototypeOf(e,Iterator.prototype),e.prototype=Object.create(Iterator.prototype,{constructor:{value:e,configurable:!0,enumerable:!1,writable:!0},_resolve:{value:function(e){return"value"===this.__kind__?this.__list__[e]:"key+value"===this.__kind__?[e,this.__list__[e]]:e},configurable:!0,enumerable:!1,writable:!0},toString:{value:function(){return"[object Array Iterator]"},configurable:!0,enumerable:!1,writable:!0}}),e}();CreateMethodProperty(Array.prototype,"entries",function r(){var e=ToObject(this);return new ArrayIterator(e,"key+value")});!function(){"use strict";function n(){return tn[q][B]||D}function t(n){return n&&"object"==typeof n}function e(n){return"function"==typeof n}function r(n,t){return n instanceof t}function o(n){return r(n,A)}function i(n,t,e){if(!t(n))throw a(e)}function u(){try{return b.apply(R,arguments)}catch(n){return Y.e=n,Y}}function c(n,t){return b=n,R=t,u}function f(n,t){function e(){for(var e=0;e<o;)t(r[e],r[e+1]),r[e++]=T,r[e++]=T;o=0,r.length>n&&(r.length=n)}var r=L(n),o=0;return function(n,t){r[o++]=n,r[o++]=t,2===o&&tn.nextTick(e)}}function s(n,t){var o,i,u,f,s=0;if(!n)throw a(N);var l=n[tn[q][z]];if(e(l))i=l.call(n);else{if(!e(n.next)){if(r(n,L)){for(o=n.length;s<o;)t(n[s],s++);return s}throw a(N)}i=n}for(;!(u=i.next()).done;)if((f=c(t)(u.value,s++))===Y)throw e(i[G])&&i[G](),f.e;return s}function a(n){return new TypeError(n)}function l(n){return(n?"":Q)+(new A).stack}function h(n,t){var e="on"+n.toLowerCase(),r=F[e];E&&E.listeners(n).length?n===X?E.emit(n,t._v,t):E.emit(n,t):r?r({reason:t._v,promise:t}):tn[n](t._v,t)}function v(n){return n&&n._s}function _(n){if(v(n))return new n(Z);var t,r,o;return t=new n(function(n,e){if(t)throw a();r=n,o=e}),i(r,e),i(o,e),t}function d(n,t){var e=!1;return function(r){e||(e=!0,I&&(n[M]=l(!0)),t===U?g(n,r):y(n,t,r))}}function p(n,t,r,o){return e(r)&&(t._onFulfilled=r),e(o)&&(n[J]&&h(W,n),t._onRejected=o),I&&(t._p=n),n[n._c++]=t,n._s!==$&&rn(n,t),t}function m(n){if(n._umark)return!0;n._umark=!0;for(var t,e=0,r=n._c;e<r;)if(t=n[e++],t._onRejected||m(t))return!0}function w(n,t){function e(n){return r.push(n.replace(/^\s+|\s+$/g,""))}var r=[];return I&&(t[M]&&e(t[M]),function n(t){t&&K in t&&(n(t._next),e(t[K]+""),n(t._p))}(t)),(n&&n.stack?n.stack:n)+("\n"+r.join("\n")).replace(nn,"")}function j(n,t){return n(t)}function y(n,t,e){var r=0,i=n._c;if(n._s===$)for(n._s=t,n._v=e,t===O&&(I&&o(e)&&(e.longStack=w(e,n)),on(n));r<i;)rn(n,n[r++]);return n}function g(n,r){if(r===n&&r)return y(n,O,a(V)),n;if(r!==S&&(e(r)||t(r))){var o=c(k)(r);if(o===Y)return y(n,O,o.e),n;e(o)?(I&&v(r)&&(n._next=r),v(r)?x(n,r,o):tn.nextTick(function(){x(n,r,o)})):y(n,U,r)}else y(n,U,r);return n}function k(n){return n.then}function x(n,t,e){var r=c(e,t)(function(e){t&&(t=S,g(n,e))},function(e){t&&(t=S,y(n,O,e))});r===Y&&t&&(y(n,O,r.e),t=S)}var T,b,R,S=null,C="object"==typeof self,F=self,P=F.Promise,E=F.process,H=F.console,I=!0,L=Array,A=Error,O=1,U=2,$=3,q="Symbol",z="iterator",B="species",D=q+"("+B+")",G="return",J="_uh",K="_pt",M="_st",N="Invalid argument",Q="\nFrom previous ",V="Chaining cycle detected for promise",W="rejectionHandled",X="unhandledRejection",Y={e:S},Z=function(){},nn=/^.+\/node_modules\/yaku\/.+\n?/gm,tn=function(n){var r,o=this;if(!t(o)||o._s!==T)throw a("Invalid this");if(o._s=$,I&&(o[K]=l()),n!==Z){if(!e(n))throw a(N);r=c(n)(d(o,U),d(o,O)),r===Y&&y(o,O,r.e)}};tn.default=tn,function en(n,t){for(var e in t)n[e]=t[e]}(tn.prototype,{then:function(n,t){if(void 0===this._s)throw a();return p(this,_(tn.speciesConstructor(this,tn)),n,t)},catch:function(n){return this.then(T,n)},finally:function(n){return this.then(function(t){return tn.resolve(n()).then(function(){return t})},function(t){return tn.resolve(n()).then(function(){throw t})})},_c:0,_p:S}),tn.resolve=function(n){return v(n)?n:g(_(this),n)},tn.reject=function(n){return y(_(this),O,n)},tn.race=function(n){var t=this,e=_(t),r=function(n){y(e,U,n)},o=function(n){y(e,O,n)},i=c(s)(n,function(n){t.resolve(n).then(r,o)});return i===Y?t.reject(i.e):e},tn.all=function(n){function t(n){y(o,O,n)}var e,r=this,o=_(r),i=[];return(e=c(s)(n,function(n,u){r.resolve(n).then(function(n){i[u]=n,--e||y(o,U,i)},t)}))===Y?r.reject(e.e):(e||y(o,U,[]),o)},tn.Symbol=F[q]||{},c(function(){Object.defineProperty(tn,n(),{get:function(){return this}})})(),tn.speciesConstructor=function(t,e){var r=t.constructor;return r?r[n()]||e:e},tn.unhandledRejection=function(n,t){H&&H.error("Uncaught (in promise)",I?t.longStack:w(n,t))},tn.rejectionHandled=Z,tn.enableLongStackTrace=function(){I=!0},tn.nextTick=C?function(n){P?new P(function(n){n()}).then(n):setTimeout(n)}:E.nextTick,tn._s=1;var rn=f(999,function(n,t){var e,r;return(r=n._s!==O?t._onFulfilled:t._onRejected)===T?void y(t,n._s,n._v):(e=c(j)(r,n._v))===Y?void y(t,O,e.e):void g(t,e)}),on=f(9,function(n){m(n)||(n[J]=1,h(X,n))});F.Promise=tn}();})('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
\ No newline at end of file
{"v":"5.6.10","fr":30,"ip":0,"op":25,"w":464,"h":464,"nm":"点击光晕","ddd":0,"assets":[{"id":"0","w":40,"h":36,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAkBAMAAAAJEmUlAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJFBMVEVHcEz///////////////////////////////////////////8Uel1nAAAADHRSTlMAAgYWDSEtPE5t3J8u7P32AAABLUlEQVQoz32S/XGDMAzF8Qa2N4DzBoYFwBtwZgPMBpAs0CYbpNcNyASU5fokDAHai/783ZP09JEk70IIcUZSURyxUCpFKHVgOqNI91qhssyYElTueoA550DVRoUmlufOocAKlTausgiiIibrDKz2HnQroFLjbOERNi8BJfvOTGV9E4Kv7VoVfiBswtAHb13J+VzS+jAMQ2hr5LNXgoUPl9uNpUsnKons69djgVwUzQG7+zx97iCUzXUex/E59XUOpyu8/wCO08cGNdK7y/c8P/p29fRfIylIuVhqX420JvPd0Xwcs8PwvBFWctHTQtCJpL6h1bm4urjkgpdcbldC/uscKokUUldVuOcyzuHEe8ZSNDP0DHL/XvFtTg8GptROSAvgV5R/PhQqKd989S8i62hSglkILgAAAABJRU5ErkJggg==","e":1},{"id":"1","w":40,"h":36,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAkBAMAAAAJEmUlAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJFBMVEVHcEz///////////////////////////////////////////8Uel1nAAAADHRSTlMABAsTHCc0TN5tq4+3c1CoAAABLElEQVQoz32S7W2EMAyGyQYOGxA2IGyA2QCzAckGoG6A2gFOpy5Q3Q1Qqbdc7YRAKFL988kb+/VHUfwboK6IGfzhoENAzpTSuhSqzkLDUeVS1lUCyzwB6NIYaxtjNMCesTS1bYVWuoBUhRlydIEGVvBnZkQDWoYqZaxbpNERYsMGVPqN/ejcRCyNpQRaJOcXR0OX/nPKloXLMk9D10QYUvajv99nR1w/+FcCafSv141LNSGpEtj7z691fX/Og01Kw/Bn5fi4DbE8iBLJvz0e3/OEec5YiI2Ke4gjantKlqKy0Jt5F8zH6cc26WjzNJCRsGu23qX8PjrpUm0rOoac9gFSn9eB1sqS1L442ZutcxZchcivIRyI3MKx4e0c9IWJNpzShcJJuD9dwSH7BXaDVTvBQtwXAAAAAElFTkSuQmCC","e":1},{"id":"2","w":3,"h":62,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAA+BAMAAAD+PqeGAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAHlBMVEX/ryH/qiX/qiT/qiT/qiP/qiP/qiT/qiT/qiP/qiT+my6IAAAACnRSTlMDDholL1R8aJBAe3LT/wAAAGpJREFUCNdjYAADRgUGZkMGFkcGkYkMIpMYJIEoCIpEIaiIQbUYhNQhKBmE1JIZzIAohcGsBYQswMgDFQFFzJrBasCK1cAaoYYAzQSiIBAShVg3EWz1RLAzHBmEgcgQ5DAmBRBiFAAhGAAAfJUd5q7Fp1UAAAAASUVORK5CYII=","e":1},{"id":"3","w":242,"h":227,"u":"","p":"data:image/png;base64,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","e":1},{"id":"4","w":251,"h":250,"u":"","p":"data:image/png;base64,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","e":1},{"id":"5","w":20,"h":50,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAyBAMAAACuUuYVAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAIVBMVEVHcEz//N7/663/6af/8cH/5qH/6LL/7rX/+Nb/6av//fS/VPvmAAAAC3RSTlMAA0s4aycMWoAXleZLH2UAAACuSURBVCjPbdI7C8IwEMDxuyWQLVncCxk6Wij0K4hTsUNXFwVHt+KnKIjf18vlcUEv049/X3kUgMbBQRm3a+Vlr1xnjZNwbHjUGFT2ldgPGjeNZuv+iZG8DgRzkkp0lBHBSrVcKTtvz090/FRiqV2phugRYmVKdfTSWF/pXp7DgPFzdIEIufLU09vi2koNuZLDnMUssxy1rcZm16ddO6yGi/AtB/sRPoR3+Qk8/IwvsV8dlZtoBVMAAAAASUVORK5CYII=","e":1},{"id":"6","w":3,"h":41,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAApBAMAAADg7ZWlAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJFBMVEX/tRf/qyX/qiP/qiT/qyT/qiT/qiT/qiT/qiT/qiT/qiT/qiQYBbxQAAAADHRSTlMBEAghLRh+OFhqlEYbz77OAAAAX0lEQVQI12NgYGBgFGJQdmRQKWVQ2cqgDkTNDNrNDNLNDBKTGSSmMEikMETCUNgSBrPlIGQFRhC22RKGMJiCiMlgXZNB2qVbwaZtZVApBJkPRKxGDIxBDExCDAwKQGsBZLIZVgs6k9MAAAAASUVORK5CYII=","e":1},{"id":"7","w":142,"h":4,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI4AAAAEBAMAAACq+BqFAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAKlBMVEX/rB3/qiT/qiP/qiT/qiP/qiT/qiT/qyT/qiT/qiP/qiP/qiT/qiT/qiSaS68eAAAADnRSTlMBCjIjPxRWS3eJZqTLuacbDhQAAACoSURBVBjTdc7BDYMgFAZg2EAOLmCdQOMChgWIYYXXxHNTVqAbSHonDRs0xA3aDdpd+j+0R78TvPD/PCGEqm0PXdewttWFgyvtcL7wsLxo+HU/TZYpEIW0nXZEKaWH9wHuOed1/cLn9ffmK+b5GcKyeJ9SpLPTI0oHa7Ymue+Dn/Y9iOa51PobFwcEOZpiJKSd1iMKTsgM20biSFVJqYq6ttYYU86YHiZ+c+1U9WT2vMYAAAAASUVORK5CYII=","e":1},{"id":"8","w":53,"h":138,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADUAAACKBAMAAAD4VB/jAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAeUExURUdwTP/46//56v/45v/45//35P/35f/24//24f/13w2BpBIAAAAKdFJOUwAKFig8UmqFpMftbWYuAAACtElEQVRIx61X7XXbMAwUOgGhTiBqA9IbSNlA8gS1vYGcDaxsYG/bA22nCcVj+vLCv/fuAJD4YtN8/zj5FigiDWc6dRSyQ1VVGQiDqtSicqJTAytEAsJeq8p5bYXYtUojbKmq09ZrhUhBVe9p/HeQiLYcM17HvAHmKQbRzlUwLho9vRofAhMV31OitjEGZdHHGImotP0uehZFHwcmqv1uoKL9bhyoQWBE1LCRGWzjOMaOOTNOzCCweQzlrJGEodxcGYOoFGvx926eYbBQ4oIg5sMUinkKbH+cQqeyQVEUwCBaqH5JvMOAlMo7lVUvMIha1cgmm3b70zJFEHXTLYCdlySahy8JOx+GsEli9IPesGMSlTwJDbvAIEJ0mZse2Ou6/IHoxhffj8BgMOa1D14cj6/r5TDGrNpMM76cgBUM6h27rss05AVlOf9yWt/WZR4yHjQTdruezaCWeLdrcibjAZtPb4ZNOS9dC7AbHB2yAN+xNWG5PVzLAwufeHj1B3ZNQTjCA/bZz//iXX+OJxVe0jy/x+f4vXSSv8NsvMvR7iz3M73DrfAOX72fYWvp3VEONF9ay7P1kWfb3LX8XI8pP7e5uy/mdfOslUI9pDrChV7Mlc0s+FB/eR0pHP1Xt9sR+Kz3vG196BPbCZr6xOkumfGefWkMpWn+7Ge2zRR5aLxdYQt69Nau1FwNm+99dwv61K+10MwdhtU8xU4q86EpDYE0c0J5c/zVjxiAZI71fI7ZjKOzMWJukpmKHslmMZ4IyUfnO1saxDCyFzjkfOD7RGSrlu02ZH8R7DaeSvrA1x6+oKEaqGRlr5O0ujm2m1ZXPhK4069o1FzL7ksBkVVYteuoJ4axzdsk+feB/ErQWShNjMb+Ofy74ri1RKv9uYT+qlzlr1b5/gn9jLnKj1Kk+enDFf8CbzHuJ3K7ZXYAAAAASUVORK5CYII=","e":1}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"组 9","refId":"0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":4,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":11.509,"s":[100]},{"t":18,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.38,"y":1},"o":{"x":0.224,"y":0},"t":0,"s":[211,230.815,0],"to":[28.178,0,0],"ti":[-28.178,0,0]},{"t":16,"s":[380.068,230.815,0]}],"ix":2},"a":{"a":0,"k":[20,18,0],"ix":1},"s":{"a":0,"k":[163,163,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"组 8","refId":"1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":4,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":11.509,"s":[100]},{"t":18,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[211.19,230.815,0],"to":[-25.655,0,0],"ti":[25.655,0,0]},{"t":16,"s":[57.258,230.815,0]}],"ix":2},"a":{"a":0,"k":[20,18,0],"ix":1},"s":{"a":0,"k":[163,163,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"图层 8 拷贝 2","refId":"2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8.785,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12.08,"s":[100]},{"t":20.866,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[178.002,318.655,0],"to":[0,-5.5,0],"ti":[0,5.5,0]},{"t":18,"s":[178.002,285.655,0]}],"ix":2},"a":{"a":0,"k":[1.5,31,0],"ix":1},"s":{"a":0,"k":[163,163,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"571053203a2b4.png","cl":"png","refId":"3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":4.847,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16.357,"s":[100]},{"t":21.384,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[231.287,232,0],"ix":2},"a":{"a":0,"k":[120.25,121.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.645,0.645,0.667],"y":[-13.335,0.857,1]},"o":{"x":[0.776,0.776,0.333],"y":[0,0,0]},"t":0,"s":[100,0,100]},{"i":{"x":[0.606,0.606,0.833],"y":[1,1,1]},"o":{"x":[0.124,0.124,0.167],"y":[0.175,0.175,0]},"t":9.334,"s":[100,100,100]},{"t":21.384,"s":[137,137,100]}],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"组 10","refId":"4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4.038,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17.345,"s":[100]},{"t":23,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[217.171,232.325,0],"ix":2},"a":{"a":0,"k":[125.653,123.006,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[0.876,0.876,1]},"o":{"x":[0.662,0.662,0.333],"y":[0,0,0]},"t":0,"s":[30,30,100]},{"i":{"x":[0.379,0.379,0.667],"y":[1,1,1]},"o":{"x":[0.239,0.239,0.333],"y":[0.379,0.379,0]},"t":10.499,"s":[110,110,100]},{"t":23,"s":[133,133,100]}],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"组 7","refId":"5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8.785,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12.08,"s":[100]},{"t":20.866,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":0,"s":[245.648,257.655,0],"to":[0,11.333,0],"ti":[0,-11.333,0]},{"t":18,"s":[245.648,325.655,0]}],"ix":2},"a":{"a":0,"k":[10,25,0],"ix":1},"s":{"a":0,"k":[163,163,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"图层 11","refId":"6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8.785,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12.08,"s":[100]},{"t":20.866,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[228.533,184.47,0],"to":[0,12.333,0],"ti":[0,-12.333,0]},{"t":18,"s":[228.533,258.47,0]}],"ix":2},"a":{"a":0,"k":[1.5,20.5,0],"ix":1},"s":{"a":0,"k":[163,163,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":2,"nm":"图层 10","refId":"7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":8.785,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12.08,"s":[100]},{"t":20.866,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[313.447,257.655,0],"to":[-22.167,0,0],"ti":[22.167,0,0]},{"t":18,"s":[180.447,257.655,0]}],"ix":2},"a":{"a":0,"k":[71,2,0],"ix":1},"s":{"a":0,"k":[163,163,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":2,"nm":"爆开光.png","cl":"png","parent":12,"refId":"8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[35.568]},"o":{"x":[0.333],"y":[0]},"t":2,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0.154]},"t":11,"s":[100]},{"t":15,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-111.062,-2.5,0],"ix":2},"a":{"a":0,"k":[-4,67.5,0],"ix":1},"s":{"a":0,"k":[-212.5,212.5,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":2,"nm":"爆开光.png","cl":"png","parent":12,"refId":"8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[35.568]},"o":{"x":[0.333],"y":[0]},"t":2,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0.154]},"t":11,"s":[100]},{"t":15,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[106.437,-2.5,0],"ix":2},"a":{"a":0,"k":[-4,67.5,0],"ix":1},"s":{"a":0,"k":[212.5,212.5,100],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":3,"nm":"Null 4","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[232,232,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.088,0.088,0.25],"y":[1,1,1]},"o":{"x":[0.226,0.226,0.33],"y":[0,0,0]},"t":0,"s":[40,40,100]},{"t":15,"s":[100,100,100]}],"ix":6}},"ao":0,"ip":0,"op":25,"st":0,"bm":0}],"markers":[],"tiny":0.4}
\ No newline at end of file
{
"code": "000000",
"data": {
"isOpenMember": 1,
"newerBelongPrize": "",
"memberGrade": 0,
"showNotice": false,
"end": false,
"detail": {
"feedTime": 1623242500923,
"showNewGiftPop": true,
"milkCreateTime": 1623242500923,
"feedWeight": 500,
"activityId": "60a60966114fbb7eb9b576ab",
"delTaskInfoTag": true,
"cowName": "小Q",
"guideStep": 4,
"userNick": "我",
"grassGrowTime": 1623242663382,
"gainCowMilkBottlesTime": 1623240837744,
"taskInfo": {
"foreverLimit": {
"focusShop": [],
"beMember": []
}
},
"tag": 0,
"reduceMilkDropsCount": 0,
"nextMilkCreateTime": 1623242950923,
"milkDrops": [],
"cowId": "60c0a3f667f1372ade1bb80b",
"guideisEnd": true,
"clickCrazyGainGrassTime": "",
"feedInfo": "",
"updateTime": 1623242663403,
"avatar": "http://wwc.alicdn.com/avatar/getAvatar.do?userIdStr=O8gbM07HMG9eOHRhPFxYMF*evCHbPHReMC-HP0cWMCcT&width=80&height=80&type=sns",
"cowMilkBottles": 2,
"cowLevel": 2,
"growthValue": 12,
"gainCowMilkBottlesTotal": 2,
"clickCrazyGainGrassCount": 0,
"progressGrassWeight": 107,
"milkWeight": 250,
"_id": "60c0a3f60cb7332a070d5c9c",
"createGrassWeight": 0
},
"shopUrl": "//market.m.taobao.com/apps/market/shopmember/index.html?wh_weex=true&sellerId=2207623078795&extraInfo=%7B%22source%22%3A%22isvapp%22%2C%22entrance%22%3A%22duiba%22%7D",
"contentArr": [
"玉立测试活动",
"玉立测试活动"
],
"newerBelongPrizeIsReceived": false,
"isVip": false
},
"success": true,
"message": "成功"
}
{
"code": "000000",
"data": {
"feedTime": 1623242500923,
"showNewGiftPop": true,
"milkCreateTime": 1623242500923,
"feedWeight": 500,
"activityId": "60a60966114fbb7eb9b576ab",
"delTaskInfoTag": true,
"cowName": "小Q",
"guideStep": 4,
"userNick": "我",
"grassGrowTime": 1623242693835,
"gainCowMilkBottlesTime": 1623240837744,
"end": false,
"taskInfo": {
"foreverLimit": {
"focusShop": [],
"beMember": []
}
},
"tag": 0,
"nextMilkCreateTime": 1623242890923,
"milkDrops": [],
"cowId": "60c0a3f667f1372ade1bb80b",
"guideisEnd": true,
"clickCrazyGainGrassTime": "",
"newerBelongPrize": "",
"feedInfo": "",
"updateTime": 1623242693847,
"avatar": "http://wwc.alicdn.com/avatar/getAvatar.do?userIdStr=O8gbM07HMG9eOHRhPFxYMF*evCHbPHReMC-HP0cWMCcT&width=80&height=80&type=sns",
"cowMilkBottles": 2,
"milkProduceGap": 450000,
"cowLevel": 2,
"growthValue": 12,
"gainCowMilkBottlesTotal": 2,
"clickCrazyGainGrassCount": 0,
"progressGrassWeight": 111,
"milkWeight": 250,
"_id": "60c0a3f60cb7332a070d5c9c",
"createGrassWeight": 0,
"newerBelongPrizeIsReceived": false
},
"success": true,
"message": "成功"
}
{
"code": "0000000000",
"data": {
"creditsConf": {
"creditsUp": 100,
"creditsType": "virtual",
"creditsDown": 50,
"prize": [
{
"img": "adsfsadf",
"credits": 20,
"id": 4,
"title": "0.3"
},
{
"img": "sadfasdf",
"credits": 150,
"id": 3,
"title": "1.5倍"
},
{
"img": "sadfasdf",
"credits": 100,
"id": 2,
"title": "1倍"
},
{
"img": "sadfasdf",
"credits": 50,
"id": 1,
"title": "0.5倍"
}
]
},
"floating": {
"jsTest": "//yun1.duiba.com.cn/h5/showCouponPrize/4.0.0/index_201710191434.js",
"cssTest": "//yun1.duiba.com.cn/h5/showCouponPrize/4.0.0/index_201710191440.css"
},
"options": [
{
"itemId": 47861,
"hidden": false,
"prizeType": "thanks",
"name": "谢谢参与",
"description": "",
"logo": "//yun1.duiba.com.cn/upload/uP99F1462438316972.png",
"id": 15581
},
{
"itemId": 47862,
"hidden": false,
"prizeType": "lucky",
"name": "幸运福袋",
"description": "",
"logo": "//yun1.duiba.com.cn/webapp/img/luckynewn.png",
"id": 15582
},
{
"itemId": 47863,
"scoreArea": "",
"hidden": false,
"prizeType": "alipay",
"name": "支付宝1",
"description": "",
"logo": "//yun1.duiba.com.cn/developer/img/activityTool/slotMachine/alipay.png",
"id": 15585
},
{
"itemId": 47864,
"scoreArea": "",
"hidden": false,
"prizeType": "alipay",
"name": "支付宝1",
"description": "",
"logo": "//yun1.duiba.com.cn/developer/img/activityTool/slotMachine/alipay.png",
"id": 15585
}
],
"rule": "adsfasdfasd啊实打实爱的额求稳怕哦i求稳怕请问赔钱片尾曲哦物品i区乌日千万人i去我日哦确认iqo【iadsfasdfasd啊实打实爱的额求稳怕哦i求稳怕请问赔钱片尾曲哦物品i区乌日千万人i去我日哦确认iqo【iadsfasdfasd啊实打实爱的额求稳怕哦i求稳怕请问赔钱片尾曲哦物品i区乌日千万人i去我日哦确认iqo【i",
"type": "hdtool",
"element": {
"isCreditsTypeOpen": false,
"myCreditsLong": 999999632167,
"freeLimit": 5,
"success": false,
"myCredits": "999999632167",
"needCredits": "100",
"freeEmpty": true,
"needCreditsLong": 9,
"status": 7
},
"coinPusherConf": {
"exchangeRate": 60,
"creditsGear": "25,60,75,80"
}
},
"success": true,
"desc": "OK",
"timestamp": 1548832971636
}
\ No newline at end of file
{
"code": "0000000000",
"data": {
"creditsConf": {
"creditsUp": 100,
"creditsType": "virtual",
"creditsDown": 50,
"prize": [
{
"img": "adsfsadf",
"credits": 20,
"id": 4,
"title": "0.3"
},
{
"img": "sadfasdf",
"credits": 150,
"id": 3,
"title": "1.5倍"
},
{
"img": "sadfasdf",
"credits": 100,
"id": 2,
"title": "1倍"
},
{
"img": "sadfasdf",
"credits": 50,
"id": 1,
"title": "0.5倍"
}
]
},
"floating": {
"jsTest": "//yun1.duiba.com.cn/h5/showCouponPrize/4.0.0/index_201710191434.js",
"cssTest": "//yun1.duiba.com.cn/h5/showCouponPrize/4.0.0/index_201710191440.css"
},
"options": [
{
"itemId": 47861,
"hidden": false,
"prizeType": "thanks",
"name": "谢谢参与",
"description": "",
"logo": "//yun1.duiba.com.cn/upload/uP99F1462438316972.png",
"id": 15581
},
{
"itemId": 47862,
"hidden": false,
"prizeType": "lucky",
"name": "幸运福袋",
"description": "",
"logo": "//yun1.duiba.com.cn/webapp/img/luckynewn.png",
"id": 15582
},
{
"itemId": 47863,
"scoreArea": "",
"hidden": false,
"prizeType": "alipay",
"name": "支付宝1",
"description": "",
"logo": "//yun1.duiba.com.cn/developer/img/activityTool/slotMachine/alipay.png",
"id": 15585
},
{
"itemId": 47864,
"scoreArea": "",
"hidden": false,
"prizeType": "alipay",
"name": "支付宝1",
"description": "",
"logo": "//yun1.duiba.com.cn/developer/img/activityTool/slotMachine/alipay.png",
"id": 15585
}
],
"rule": "adsfasdfasd啊实打实爱的额求稳怕哦i求稳怕请问赔钱片尾曲哦物品i区乌日千万人i去我日哦确认iqo【iadsfasdfasd啊实打实爱的额求稳怕哦i求稳怕请问赔钱片尾曲哦物品i区乌日千万人i去我日哦确认iqo【iadsfasdfasd啊实打实爱的额求稳怕哦i求稳怕请问赔钱片尾曲哦物品i区乌日千万人i去我日哦确认iqo【i",
"type": "hdtool",
"element": {
"isCreditsTypeOpen": false,
"myCreditsLong": 999999632167,
"freeLimit": 5,
"success": false,
"myCredits": "999999632167",
"needCredits": "100",
"freeEmpty": true,
"needCreditsLong": 9,
"status": 7
},
"coinPusherConf": {
"exchangeRate": 60,
"creditsGear": "25,60,75,80"
}
},
"success": true,
"desc": "OK",
"timestamp": 1548832971636
}
\ No newline at end of file
{
"success":true,
"code":"0000000000",
"desc":"OK",
"timestamp":1548915321930,
"data":123456
}
\ No newline at end of file
{
"code": "000000",
"data": {
"showNewGiftPop": false,
"activityId": "5f855a0a738989848ebb5050",
"guideStep": 4,
"userNick": "卿卿我我",
"gainCowMilkBottlesTime": "",
"end": false,
"taskInfo": {
"freeReceive": 2,
"foreverLimit": {
"focusShop": [
{
"grass": 12222,
"isReceive": false,
"time": 1602727797457
}
],
"beMember": [
{
"grass": 12,
"isReceive": false,
"time": 1602727797427
}
]
},
"2020/10/15": {
"todayCompleteTaskTimes": 2
}
},
"tag": 0,
"nextMilkCreateTime": 1602904190337,
"milkDrops": [
{
"createTime": 1602679659133
},
{
"createTime": 1602679809133
},
{
"createTime": 1602679959133
},
{
"createTime": 1602680109133
},
{
"createTime": 1602680259133
},
{
"createTime": 1602680409133
},
{
"createTime": 1602680559133
},
{
"createTime": 1602680709133
},
{
"createTime": 1602680859133
},
{
"createTime": 1602681009133
},
{
"createTime": 1602681159133
},
{
"createTime": 1602681309133
},
{
"createTime": 1602681459133
},
{
"createTime": 1602681609133
},
{
"createTime": 1602681759133
},
{
"createTime": 1602681909133
},
{
"createTime": 1602682059133
},
{
"createTime": 1602682209133
},
{
"createTime": 1602682359133
},
{
"createTime": 1602682509133
}
],
"cowId": "5f86f0ede5c0d7316b457dd8",
"guideisEnd": true,
"clickCrazyGainGrassTime": "",
"newerBelongPrize": "",
"feedInfo": {},
"eachDropReduceTime": 5,
"updateTime": 1602903776711,
"milkProduceGap": 450000,
"gainCowMilkBottlesTotal": 0,
"clickCrazyGainGrassCount": 0,
"milkWeight": 250,
"_id": "5f86f0ed964f97d1ee73633a",
"speedUpEndTime": 1602683250085,
"newerBelongPrizeIsReceived": false
},
"success": true,
"message": "成功"
}
{
"code": "33000",
"data": {
"isOpenMember": false,
"newerBelongPrize": "",
"memberGrade": 1,
"showNotice": false,
"end": false,
"milkProduceGap": 450000,
"detail": {
"showNewGiftPop": false,
"activityId": "5f6fee6f114fbbc8c9935e9c",
"guideStep": 4,
"userNick": "卿卿我我",
"gainCowMilkBottlesTime": "",
"taskInfo": {
"freeReceive": 2,
"foreverLimit": {
"focusShop": [],
"beMember": []
},
"feedReceive": 2
},
"tag": 0,
"reduceMilkDropsCount": 0,
"nextMilkCreateTime": 1601272292257,
"milkDrops": [],
"cowId": "5f715eae0cb733e89283e0a2",
"guideisEnd": true,
"clickCrazyGainGrassTime": "",
"feedInfo": {},
"updateTime": 1601276726110,
"gainCowMilkBottlesTotal": 0,
"clickCrazyGainGrassCount": 0,
"milkWeight": 250,
"_id": "5f715eae52bbded304b20111"
},
"shopUrl": "//market.m.taobao.com/apps/market/shopmember/index.html?wh_weex=true&sellerId=2207623078795&extraInfo=%7B%22source%22%3A%22isvapp%22%2C%22entrance%22%3A%22duiba%22%7D",
"contentArr": [
"中秋节快乐1",
"中秋节快乐2",
"中秋节快乐3"
],
"newerBelongPrizeIsReceived": false,
"isVip": true
},
"success": true,
"message": "成功"
}
{
"success":true,
"code":"0000000000",
"desc":"OK",
"timestamp":1550570639368,
"data":{
"orderId":"883006813674240289",
"submitToken":"d895deb9118f4b938d0b70a3dd2ace19",
"credits":"999999491765",
"unitName":"金币",
"consumerCredits":999999491765
}
}
\ No newline at end of file
{
"success":true,
"code":"0000000000",
"desc":"OK",
"timestamp":1548923950498,
"data":{
"element":{
"success":false,
"isCreditsTypeOpen":false,
"needCredits":"100",
"myCredits":"1123",
"myCreditsLong":1123,
"needCreditsLong":9,
"freeLimit":2,
"status":6,
"freeEmpty":true
},
"lottery":{
"id":null,
"type":"111",
"imgUrl":"//yun.duiba.com.cn/images/201607/73htz55ih9.jpg",
"link":null,
"title":"重复券测试grape",
"itemId":null,
"appItemId":null,
"bonus":null,
"bonusMin":null,
"bonusMax":null,
"needAccount":null,
"appLucky":null,
"tip":null,
"useBtnText":null,
"validate":null,
"couponCode":null,
"couponKey":null,
"stInfoDpmImg":null,
"stInfoDpmClose":null,
"stInfoDpmGoUse":null,
"showUse":null,
"openUrl":null,
"iosDownloadUrl":null,
"androidDownloadUrl":null,
"isDownloadUrl":null,
"confirm":null,
"phaseNumber":null,
"happyCode":null,
"appHidden":true,
"zybangJson":null
},
"exposure":11111,
"creditsInfo":{
"activityId":82567,
"prizeId":4,
"orderNum":null,
"developerBizId":"3029576",
"score":null,
"recordStatus":1,
"errorMsg":null
},
"againTag":null
}
}
\ No newline at end of file
{
"success":true,
"code":"0000000000",
"desc":"OK",
"timestamp":1550646190489,
"data":{
"score":100,
"maxScore":100
}
}
\ No newline at end of file
{
"data": {
"isContinue": true
},
"success": true,
"code": "veniam",
"message": "amet"
}
{"code":"430009","success":false,"message":"只有新会员才能助力哦~"}
{
"success": true,
"message": "ok",
"code": "111111",
"data": {
"_id": "1111",
"openId": "mfk",
"rule": "mfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfkmfk",
"startTime": 1599131034611,
"endTime": 1598585357782,
"activityStatus": 2,
"openPrizeStatus": 2,
"totalScore": 52000001,
"showImage": "https://yun.duiba.com.cn/aurora/assets/70c7fdc45ed8139bdc0a23ac004facc07abf3cfd.jpg"
}
}
{
"data": {
"score": 123456,
"gameTimes": 1,
"isFirstEnterGame": false
},
"success": true,
"code": "1",
"message": "ok"
}
{
"code": "111",
"success": true,
"message": "ok",
"data": {
"showAwardDialog": true,
"prize": {
"id": "id",
"useUrl": "useUrl",
"drawStatus": 1,
"type": 5,
"image": "https://yun.duiba.com.cn/aurora/assets/39c89bfa28c4c022436c23f56547b2995cb2b65c.png",
"name": "name"
},
"rank": {
"score": 0,
"rank": 200
}
}
}
{
"code": "111",
"success": true,
"message": "ok",
"data": {
"list": [
{
"useUrl": "useUrl",
"id": "id1",
"prizeId": "prizeId1",
"type": 4,
"image": "https://yun.duiba.com.cn/aurora/assets/39c89bfa28c4c022436c23f56547b2995cb2b65c.png",
"name": "name1",
"drawStatus": 1,
"addressDetail": "addressDetail",
"rank": "1-2"
},
{
"useUrl": "useUrl",
"id": "id2",
"prizeId": "prizeId2",
"type": 4,
"image": "https://yun.duiba.com.cn/aurora/assets/39c89bfa28c4c022436c23f56547b2995cb2b65c.png",
"name": "name2",
"drawStatus": 1,
"addressDetail": "addressDetail",
"rank": "3-5"
},
{
"useUrl": "useUrl",
"id": "id3",
"prizeId": "prizeId3",
"type": 4,
"image": "https://yun.duiba.com.cn/aurora/assets/39c89bfa28c4c022436c23f56547b2995cb2b65c.png",
"name": "name3",
"drawStatus": 1,
"addressDetail": "addressDetail",
"rank": "6-10"
}
]
}
}
{
"data": {
"rank": 11,
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"userNick": "userNick",
"list": [
{
"rank": 1,
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"score": 123456,
"userNick": "userNick1"
},
{
"rank": 2,
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"score": 12345,
"userNick": "userNick2"
},
{
"rank": 3,
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"score": 1234,
"userNick": "userNick3"
},
{
"rank": 4,
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"score": 123,
"userNick": "userNick4"
},
{
"rank": 5,
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"score": 12,
"userNick": "userNick5"
},
{
"rank": 6,
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"score": 1,
"userNick": "userNick6"
}
],
"score": "66666"
},
"success": true,
"code": "111",
"message": "ok"
}
{
"success": true,
"data": {
"isVip": true,
"url": "https://www.baidu.com/"
}
}
{
"data": {
"gameId": 12345,
"beMember": false,
"isFirstEnterGame": false
},
"success": true,
"code": "123",
"message": "ok"
}
{
"data": {
"prizeInfo": {
"id": "id",
"image": "https://img.alicdn.com/imgextra/i1/2275046294/O1CN01xTeKMI1wMhRux48Y6_!!2275046294-2-miniprogram.png",
"name": "name",
"type": 4
},
"score": 6666,
"rank": 12,
"userNick": "hycv",
"avatar": "esse veniam ut",
"gameTimes": 0,
"maxScore": 1234,
"getScore": 66
},
"success": true,
"code": "1",
"message": "ok"
}
{
"success": true,
"data": {
"avatar": "https://source.unsplash.com/user/erondu/76x76",
"nickName": "我啊是大请问",
"activityId": "string",
"inviteId": "",
"isFollow": true,
"openId": "string",
"firstLoginToday": true,
"newUser": false
}
}
{
"success": false,
"code": "ipsum voluptate est pariatur aliqua",
"message": "commodo ipsum tempor",
"data": "123"
}
\ No newline at end of file
{
"success": false,
"code": "ipsum voluptate est pariatur aliqua",
"message": "commodo ipsum tempor",
"data": "123"
}
\ No newline at end of file
{
"success": true,
"code": "ipsum voluptate est pariatur aliqua",
"message": "commodo ipsum tempor",
"data": "123"
}
\ No newline at end of file
{
"code": null,
"data": {
"creditsUnit": "人民币123123",
"difficulty": 1,
"freeTimes": 0,
"levelInfo": [
{
"name": "D",
"score": 50
},
{
"name": "C",
"score": 100
},
{
"name": "B",
"score": 150
},
{
"name": "A",
"score": 200
},
{
"name": "A+",
"score": 300
},
{
"name": "S",
"score": 500
},
{
"name": "SSS",
"score": 1000
}
],
"music": false,
"spNum": [
{
"num": 200,
"spName": "游戏积分",
"ticketType": "start"
},
{
"num": 150,
"spName": "复活积分",
"ticketType": "resurgence"
},
{
"num": 1,
"spName": "直冲云霄积分",
"ticketType": "fly"
},
{
"num": 8,
"spName": "双倍金币续费积分",
"ticketType": "gold_double_renew"
},
{
"num": 33,
"spName": "三倍金币积分",
"ticketType": "gold_triple"
},
{
"num": 21,
"spName": "金身续费积分",
"ticketType": "invincible_renew"
}
]
},
"message": null,
"success": true
}
\ No newline at end of file
{
"success": true,
"code": "ipsum voluptate est pariatur aliqua",
"message": "commodo ipsum tempor",
"data": {
"startId": "77777",
"scorePreRound": -59955755.34276232
}
}
\ No newline at end of file
{
"success": true,
"code": "ipsum voluptate est pariatur aliqua",
"message": "commodo ipsum tempor",
"data": {
"startId": "77777",
"scorePreRound": 1234,
"firstDouble": false,
"firstInvincible": false
}
}
\ No newline at end of file
{
"success": true,
"code": "sed tempor proident Excepteur in",
"message": "magna incididunt",
"data": {
"prizeId": "sp",
"url": "aliquip veniam",
"name": "xxxxx",
"icon": "//yun.duiba.com.cn/spark/assets/9ff9e1f358db0ea9027edaca04247e62fd52b22d.png"
}
}
\ No newline at end of file
{
"success": true,
"code": "labore qui nulla dolor mollit",
"message": "deserunt"
}
\ No newline at end of file
{
"success": true,
"message": "ut ipsum",
"data": "1"
}
\ No newline at end of file
{
"data": 1,
"success": "true",
"message": "Lorem dolore ea aliquip Duis"
}
\ No newline at end of file
{
"code": "000000",
"data": {
"prizeList": [
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i1/676606897/O1CN01LSRArg20osHsZ0WIr_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 1,
"probability": "",
"openId": "AAGMBAINAMTJSjCbJXOUEPSv",
"updateTime": 1599704766652,
"goodId": "616444374083",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599457433502,
"deleteStatus": 1,
"name": "1111",
"rank": "1-5",
"_id": "5f55c899964f9706aac97635",
"stock": "",
"desc": "12"
},
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i4/676606897/O1CN011wSmP820osHsfbQVt_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 2,
"probability": "",
"updateTime": 1599704766657,
"goodId": "619250976552",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599630352681,
"deleteStatus": 1,
"name": "2222",
"rank": "6-10",
"_id": "5f586c10738989c8b3699c36",
"stock": "",
"desc": "请问"
},
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i2/676606897/O1CN01jSu8pl20osHpoItcH_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 3,
"probability": "",
"updateTime": 1599704766662,
"goodId": "619551785682",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599630352691,
"deleteStatus": 1,
"name": "333",
"rank": "11-15",
"_id": "5f586c10ef5071ef85b121d8",
"stock": "",
"desc": "问问"
},
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i4/676606897/O1CN01052oCs20osHpgeJo1_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 4,
"probability": "",
"updateTime": 1599704766667,
"goodId": "619551785682",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599630352702,
"deleteStatus": 1,
"name": "444",
"rank": "16-25",
"_id": "5f586c10114fbb8f6d936a84",
"stock": "",
"desc": "抬头"
},
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i1/676606897/O1CN01Eomi5d20osHqufhQS_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 5,
"probability": "",
"updateTime": 1599704766671,
"goodId": "619250976552",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599631028489,
"deleteStatus": 1,
"name": "5555",
"rank": "26-190",
"_id": "5f586eb40cb7330c942fa945",
"stock": "",
"desc": "55555"
},
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i3/676606897/O1CN01c5dDdr20osHnlbxH8_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 6,
"probability": "",
"updateTime": 1599704766678,
"goodId": "",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599704598695,
"deleteStatus": 1,
"name": "123",
"rank": "191-192",
"_id": "5f598e16e5c0d7361f94443c",
"stock": "",
"desc": "12"
},
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i4/676606897/O1CN018xPsWm20osHsVvmQ4_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 7,
"probability": "",
"updateTime": 1599704766682,
"goodId": "",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599704598700,
"deleteStatus": 1,
"name": "123",
"rank": "193-194",
"_id": "5f598e1685a7496423364b2c",
"stock": "",
"desc": "123"
},
{
"switchStock": 2,
"image": "https://img.alicdn.com/imgextra/i2/676606897/O1CN01ZfJo7d20osHtzfobK_!!676606897-0-miniprogram.jpg",
"useUrl": "",
"level": 8,
"probability": "",
"updateTime": 1599704766687,
"goodId": "",
"type": 3,
"prizeDataType": 1,
"activityId": "5f55c899964f9706aac97634",
"ename": "",
"credits": "",
"createTime": 1599704598706,
"deleteStatus": 1,
"name": "123",
"rank": "195-196",
"_id": "5f598e1667f1376654eb7d4d",
"stock": "",
"desc": "314"
}
],
"detail": {
"userNick": "金刚猫燕",
"rank": 15,
"totalScore": 190
},
"list": [
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "啊大苏打",
"totalScore": 123123
},
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "qweqwe",
"totalScore": 123123
},
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "啊实打实的",
"totalScore": 123123
},
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "趣味请问",
"totalScore": 123123
},
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "q123123",
"totalScore": 123123
},
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "啊大苏打",
"totalScore": 3444
},
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "啊大苏打",
"totalScore": 54345
},
{
"_id": "ea cupidatat occaecat dolor",
"avatar": "deserunt occaecat proident ex Lorem",
"openId": "pariatur",
"userNick": "啊大苏打",
"totalScore": 5663454
}
]
},
"success": true,
"message": "成功"
}
{
"success": true,
"message": "",
"code": "",
"data": {
"ruleIdList": [
"ru_1",
"ru_2",
"ru_3",
"ru_4"
],
"drawStatus": 12,
"prizeId": "aa",
"gameCounts": 1
}
}
\ No newline at end of file
{
"success": true,
"message": "",
"code": "",
"data": 1234
}
\ No newline at end of file
{
"success": true,
"message": "",
"code": "",
"data": {
"type": 1,
"status": 1,
"prize": {
"prizeId": "sp_1",
"prizeType": 1,
"optionId": "sdhjfhjhjjj",
"optionName": "10元话费",
"optionImg": "https://www.baidu.com/xxoo2.png",
"userRecordId": 1235,
"url": "https://www.baidu.com/order/1235"
}
}
}
\ No newline at end of file
{
"success": true,
"message": "",
"data": "<p class=\"p1\">1、什么人可以参与抽奖?</p><p class=\"p1\">同时持有中信银行借记卡和信用卡的客户,活动期间内预约报名(每个自然月均可报名),完成绑定中信银行借记卡并用中信银行手机银行app对本人绑定的信用卡进行自动还款任务即视为达标获得抽奖资格。达标用户将以短信形式通知抽奖。 </p><p>  </p><p class=\"p1\">2、抽奖的时间是什么时候?</p><p class=\"p1\">报名成功次月10日-15日。每期的抽奖资格当期有效,若满足抽奖资格未在有效期内抽奖,资格不保留。首轮达标客户的抽奖开启时间为:7月10-15日。</p><p>  </p><p class=\"p1\">3、活动说明:</p><p class=\"p1\">1)点击“立即抽奖”按钮,摇奖机开始转动,最终摇奖机中间停留的即为您所中的奖品。</p><p class=\"p1\">2)活动期间,每位客户每个自然月均可报名参与活动,预约报名并完成绑定中信银行借记卡并用中信银行手机银行app对本人绑定的信用卡进行自动还款任务即视为达标获得抽奖资格,可获抽奖资格,每位客户每个自然月最多可获一次抽奖机会,请在抽奖有效期内(报名次月10日—15日)通过短信路径或登录手机银行首页——特色服务——还款抽奖——进入页面抽奖,每期的抽奖资格当期有效,若满足抽奖资格未在有效期内抽奖,资格不保留。</p><p class=\"p1\">3)客户抽中的“10元话费”奖励将在当月30日前直接充值到您预留报名的手机号码中,请注意查收;</p><p class=\"p1\">4)大牌券奖励中奖后客户可在活动页面右上角的【我的奖品】中找到,奖品具体使用规则可在奖品详情页查看,大牌权益奖励兑换及使用将会跳转至权益对应的提供方平台,您填写的信息仅用于奖品或权益发放时使用(如姓名、手机号、地址等)。本活动服务由第三方杭州兑吧网络科技有限公司提供,相关责任将由杭州兑吧网络科技有限公司承担,如有问题请咨询该公司客服。中信银行仅为相关活动提供链接服务,不提供任何形式的担保和承诺。大牌券的领取使用有任何问题请致电兑吧客服专线:400-609-0828;</p><p class=\"p1\">5)为保证活动的公平公正,通过不当手段、利用系统漏洞恶意套取奖励等不当途径参与本活动抽奖的客户,中信银行有权终止该客户参与活动的权利并取消其获奖资格;</p><p class=\"p1\">6)凡参与活动的客户,即视为接受活动所有规则,在法律允许范围内,中信银行保留对本次活动的解释权、随时调整本活动优惠信息、变更活动的权利;</p><p class=\"p1\">7)通过本软件参加的任何商业活动,均与Apple Inc.无关;</p><p><span style=\"font-size:10.5ptpx\">8)本次活动授权杭州兑吧网络科技有限公司提供营销服务,若有相关疑问,请致电兑吧客服专线:400-609-0828。</span></p>"
}
\ No newline at end of file
{}
\ No newline at end of file
import { GDispatcher } from "../src/Main";
interface ResData {
/**
* 分组数据
*/
groups: GroupInt[];
//暂时没有工具,不用
resources?: any;
path?: string;
}
interface GroupInt {
/**
* 所有的资源名字,根据,分割,根据后缀区分类型
*
*/
keys: string;//"aa.png,bb.jpg,name.json"
/**
* 文件夹名字吧
*/
name: string;
/**
* 图集
* 线上打包合图可能有多张,暂时发现texturePacker版本问题只有一张
*/
atlas: {
[name: string]: {
"x": number,
"y": number,
"w": number,
"h": number,
"ox": number,
"oy": number,
"sw": number,
"sh": number,
"ro": boolean
},
};
}
interface SkinInt {
name: string,
x: 0,
y: 0,
type: 'container' | 'text' | 'button' | 'sprite' | 'rect' | 'item',//item的不初始化进节点,只作为数据
children?: SkinInt[],
id?: string,
alpha: number,
props?: {
source?: string,
text: string,
size: number,
fillColor: string,
textAlpha: number,
width: number,
height: number,
tUp: string,
tDown: string,
tDisable: string
}
}
/**
* 简单点,有工具的话像egret那样玩,可以自动生成图片组数据
*/
export namespace RES {
let resData: ResData
/**
* 资源路径
*/
export let resPath: string;
/**
* RES单独缓存一下纹理,全局的FYGE缓存纹理对于多page有覆盖的问题;
*/
let textureHash: {
[name: string]: FYGE.Texture;
} = {};
/**
* movieClip的ve数据
*/
let videoEntityHash: {
[name: string]: SvgaParser.VideoEntity
} = {};
/**
* 音频的加载
*/
let soundHash = {}
/**
* 记录组加载完成
*/
let groupsCompleteHash: {
[name: string]: boolean
} = {}
/**
* 记录加载的promise
*/
let groupsPromiseHash: {
[name: string]: Promise<any>
} = {}
/**
* 单独资源加载的promise记录
*/
let singleResPromiseHash: {
[name: string]: Promise<any>
} = {}
/**
*
* @param res 资源数据,就是对象,不考虑加载json先
* res格式{
* path:1111/
* groups: [
* {
*
* }
* ];
* }
* @param path
*/
export function loadConfig(res) {
resData = res;
resPath = res.path;
}
/**
* 根据组名加载一组资源,通常用于加载一个视图的的所有资源
* 里的promise的resolve并没有返回值
* @param name
*/
export function loadGroup(name: string): Promise<void> {
//已经加载完成的直接返回
if (groupsCompleteHash[name]) {//其实直接return就行
return new Promise((resolve) => {
resolve()
})
}
//如果是正在加载中的,返回正在加载中的promise
if (groupsPromiseHash[name]) {
return groupsPromiseHash[name];
}
//如果首次加载
//获取资源组
let arr = getGroupResByName(name);
//如果不存在arr,直接返回空p,且标记完成
if (!arr || !arr.length) {
groupsCompleteHash[name] = true;
return new Promise((resolve) => {
resolve()
})
}
// 建一个promise
let p: Promise<void> = new Promise((resolve, reject) => {
loadResList((s) => {
//移除
delete groupsPromiseHash[name];
if (s) {
groupsCompleteHash[name] = true;
resolve()
} else {
reject();
}
}, arr/*, resPath + name*/)
})
groupsPromiseHash[name] = p;
return p;
}
/**
* var textue = await RES.getResAsync(str);
* @param str 可以是网络图片路径或键值
* @param comFun 加载回调
* @param thisObj this指向
*/
export function getResAsync(str: string, comFun?: (res: any, str: string) => void, thisObj?: any): Promise<any> {
// var arr = str.split(".");
var type = str.substring(str.lastIndexOf(".") + 1, str.length);
//如果是图片
if (type == "png" || type == "jpg") {
//原先就有了,加载过的,且已加载完成的
let cached = textureHash[str] || FYGE.TextureCache[str];
if (cached) {
//回调形式
comFun && comFun.call(thisObj, cached, str)
// return cached;
return new Promise((r) => { //为了能.then
r(cached)
})
}
//未加载完成的
else if (singleResPromiseHash[str]) {
return returnSingleResPromise(str, comFun, thisObj)
}
else {
//判断是否在资源里,判断是否要加载图集,注意已排除jpg
var groupName = hasRes(str);
if (groupName && type != "jpg") {
var group = getGroupByName(groupName);
if (group && group.atlas) {
//加载图集,现在就一张,以后有机会改
var json = groupName + ".json"//group.atlas.split(",")[0];
//找json是否在加载中
if (singleResPromiseHash[json]) {
return singleResPromiseHash[json].then(
(r) => {
//正在加载中,getResAsync首次加载的回调会缓存,完成后返回需要的,
let cached = textureHash[str] || FYGE.TextureCache[str]
comFun && comFun.call(thisObj, cached, str)
return cached;
},
() => {
comFun && comFun.call(thisObj, null, str)
return null
}
)
} else {
return getResAsync(json)
.then(() => {
let cached = textureHash[str] || FYGE.TextureCache[str]
comFun && comFun.call(thisObj, cached, str)
return cached
}, () => {
comFun && comFun.call(thisObj, null, str)
return null
})
}
}
}
var src = groupName ? resPath + groupName + "/" + str : str;
var p = new Promise((resolve, reject) => {
FYGE.GlobalLoader.loadImage((s, image) => {
//移除
delete singleResPromiseHash[str];
//入缓存
if (s) {
let cached = FYGE.Texture.from(image);
//入RES,
textureHash[str] = cached;
//入全局
FYGE.Texture.addToCache(cached, str);
comFun && comFun.call(thisObj, cached, str)
resolve(cached)
} else {
comFun && comFun.call(thisObj, null, str)
reject()
}
}, src)
})
singleResPromiseHash[str] = p
return p
}
}
else if (type == "svga") {
if (videoEntityHash[str]) {
comFun && comFun.call(thisObj, videoEntityHash[str], str)
return new Promise((r) => {
r(videoEntityHash[str])
})
}
//未加载完成的
else if (singleResPromiseHash[str]) {
return returnSingleResPromise(str, comFun, thisObj)
} else {
var groupName = hasRes(str);
var src = groupName ? resPath + groupName + "/" + str : str;
var p = new Promise((resolve, reject) => {
SvgaParser.loadSvga(
src,
(v) => {
delete singleResPromiseHash[str];
videoEntityHash[str] = v;
comFun && comFun.call(thisObj, v, str)
resolve(v)
},
(err) => {
delete singleResPromiseHash[str];
comFun && comFun.call(thisObj, null, str)
reject(err)
}
)
})
singleResPromiseHash[str] = p;
return p
}
}
//json图集的话,不晓得用啥判断加载完成,所以不删除promise吧,其实json可能只是数据,不管先
else if (type == "json") {
if (singleResPromiseHash[str]) {
return returnSingleResPromise(str, comFun, thisObj)
} else {
var groupName = hasRes(str);//json现在肯定在内,暂时不能加载其他域名的json
var src = groupName ? resPath + groupName + "/" + str : str;
var p = new Promise((resolve, reject) => {
var jsonData = getGroupByName(groupName).atlas
FYGE.GlobalLoader.loadImage((s, data) => {
if (s) {
//createTextureSheet会自行缓存全局
var t = FYGE.createTextureSheet(new FYGE.BaseTexture(data/*.img*/), jsonData)
//缓存进RES
for (let key in t) textureHash[key] = t[key];
comFun && comFun.call(thisObj, t, str)
resolve(t)
} else {
//加载失败,移除要,否则再次触发加载会出问题
delete singleResPromiseHash[str];
comFun && comFun.call(thisObj, null, str)
reject()
}
}, src.replace("json", "png"))
})
singleResPromiseHash[str] = p
return p
}
}
}
/**
* 待写,根据网络路径加载图片
*/
export function getResByUrl() {
}
/**
* 获取素材,
* @param str
* @return 已加载好得素材或null
*/
export function getRes(str: string)/*: Texture | VideoEntity*/ {
if (!str) return null;
var type = str.substring(str.lastIndexOf(".") + 1, str.length);
if (type == "png" || type == "jpg") {
return textureHash[str] || FYGE.TextureCache[str] || null;
}
else if (type == "svga") {
return videoEntityHash[str] || null;
}
else if (type == "mp3") {
return soundHash[str] || null;
}
}
/**
* 偷懒的方法,加载配置里所有的资源,基本也不用
*/
export function loadAllGroup() {
var groups = resData.groups;
var p = []
groups.forEach((g) => {
p.push(loadGroup(g.name))
})
return Promise.all(p)
}
/***乱改 */
export function loadAllGroupForProgress() {
return new Promise(r => {
var groups = resData.groups;
let index = 0
groups.forEach(async (g) => {
await loadGroup(g.name)
index++
GDispatcher.dispatchEvent("loadPer", index / (groups.length - 1))
if (index == groups.length - 1) {
r(0)
}
})
})
}
/**
* 判断是否在资源组里
* 考虑是否init就做表
* 有就返回组名,为了加载路径,不然以后有工具可以放入resources
*/
function hasRes(str: string): string {
for (var i = 0; i < resData.groups.length; i++) {
var group = resData.groups[i];
var keys = group.keys;
if (keys && keys.split(",").indexOf(str) > -1) {
return group.name;
}
//如果是图集的json,altas现在是图集
if (group.atlas && group.name + ".json" == str) {
return group.name;
}
}
return null
}
/**
* 处理数据,获得所有资源单项
* @param name
*/
function getGroupResByName(name: string) {
var group: GroupInt = getGroupByName(name);
if (!group) return null;
//判断加载图集还是单图
if (group.atlas) {
// var arr: string[] = [].concat(group.atlas.split(","));
var arr = [name + ".json"]
//再添加非图片的资源,和图集已排除jpg
if (group.keys) {
arr = arr.concat(group.keys.split(",").filter((k: string) => {
return k.substr(-4) != ".png" //&& k.substr(-4) != ".jpg"
}))
}
return arr
}
else if (group.keys) {
return group.keys.split(",")
} else {
return null
}
}
/**
* 根据名字找组
* @param name
*/
function getGroupByName(name: string): GroupInt {
var groups = resData.groups;
var group: GroupInt;
for (var i = 0; i < groups.length; i++) {
if (groups[i].name === name) {
group = groups[i];
break;
}
}
return group
}
/**
* 新版的加载一列资源
* @param callback
* @param arr
*/
function loadResList(callback: (allLoaded: boolean) => void, arr: string[]) {
let count = 0;
let countAll = arr.length;
if (!countAll) callback(true);
let mark = true;
for (var i = 0; i < countAll; i++) {
let resName = arr[i];
getResAsync(resName, (res, str) => {
//标记失败,如果有一项资源加载失败,标记下
if (!res) mark = false
if (++count == countAll) callback(mark);
}, this)
}
}
/**
*
* @param str
* @param comFun
* @param thisObj
*/
function returnSingleResPromise(str: string, comFun?: (res: any, str: string) => void, thisObj?: any) {
//已判断是否存在
singleResPromiseHash[str].then(
(r) => {
comFun && comFun.call(thisObj, r, str)
},
() => {
comFun && comFun.call(thisObj, null, str)
}
)
return singleResPromiseHash[str];
}
//皮肤相关的也放在RES吧
let skinData: SkinInt
/**
* 添加皮肤配置文件
*/
export function loadSkinConfig(skinJson) {
skinData = skinJson;
}
/**
* 根据
* @param con 添加显示对象的容器
* @param skin 皮肤名字或数据
* @param root 根容器,为了添加自定义引用
*/
export function initSkinDisplay(con: FYGE.Container, skin: string | SkinInt, root?: FYGE.Container) {
//@ts-ignore
var data: SkinInt = typeof (skin) == 'string' ? getSkinDataByName(skin) : skin;
if (!data.children || !data.children.length) return;
// for (var i = data.children.length - 1; i >= 0; i--) {
for (var i = 0; i < data.children.length; i++) {
var child = data.children[i];
if (child.type == "item") continue;
var dis = con.addChild(getDisplayByData(child));
if (root && child.id) root[child.id] = dis;
if (child.type == "container") initSkinDisplay(dis, child, root);
}
}
/**
* 遍历根据名字找节点数据,只会是container的
* @param skinName
*/
export function getSkinDataByName(skinName: string, skinNode: SkinInt = skinData): SkinInt {
if (!skinNode || !skinNode.children || !skinNode.children.length) return null;
for (var i = 0; i < skinNode.children.length; i++) {
var child = skinNode.children[i];
if (child.name == skinName && (child.type == "container" || child.type == "item")) return child;
var gson = getSkinDataByName(skinName, child);
if (gson) return gson
}
return null;
}
/**
* 通过数据创建显示对象
* @param data
*/
function getDisplayByData(data: SkinInt): FYGE.Container {
var dis: FYGE.Container;
switch (data.type) {
case "container":
dis = new FYGE.Container();
break;
case "button":
dis = new FYGE.Button(
getRes(data.props.tUp),
data.props.tDown ? getRes(data.props.tDown) : null,
data.props.tDisable ? getRes(data.props.tDisable) : null,
);
break;
case "text":
dis = new FYGE.TextField();
for (let key in data.props) dis[key] = data.props[key];
break;
case "sprite":
dis = new FYGE.Sprite(getRes(data.props.source));
break;
case "rect":
// dis = new FYGE.Graphics()
// .beginFill(data.props.fillColor)
// .drawRect(0, 0, data.props.width, data.props.height)
// .endFill();
dis = new FYGE.Shape()
//@ts-ignore
dis.beginFill(FYGE.string2hex(data.props.fillColor))
//@ts-ignore
dis.drawRect(0, 0, data.props.width, data.props.height)
//@ts-ignore
dis.endFill();
break;
}
dis.name = data.name;
dis.alpha = data.alpha || 1;
dis.position.set(data.x, data.y);
// if (data.type == "text") dis.y -= 4;//文本莫名偏下,移动下,手机调试的时候也试试
return dis;
}
/**
* 销毁组纹理
* 线上才有用,待测试,TODO
* @param name
*/
export function destroyGroup(name: string) {
var group: GroupInt = getGroupByName(name);
if (!group) return;
var arr = [];
if (group.keys) {
arr = group.keys.split(",")
}
var removedBase = [];
//散图清除
for (var i = 0; i < arr.length; i++) {
var t: FYGE.Texture = getRes(arr[i]);
if (t) {
//base的清除,不要重复清除
if (removedBase.indexOf(t.baseTexture) == -1) {
t.baseTexture.destroy();
removedBase.push(t.baseTexture)
}
//自己纹理清除
t.destroy();
}
//RES里单独缓存的清除
delete textureHash[arr[i]]
}
}
//貌似不需要,为了加载过一次的资源不用重新加载
function destroyRES() {
}
}
/**
* 到时放到Loader里,增加open类型、headers、参数、等等
* @param options
*/
export function ajax(options: ajaxParameterInt) {
/**
* 默认为GET请求
*/
options.type = options.type || "GET";
/**
* 返回值类型默认为json
*/
options.dataType = options.dataType || 'json';
/**
* 默认为异步请求
*/
options.async = options.async === false ? false : true;
/**
* 对需要传入的参数的处理
*/
var params = getParams(options.data);
var xhr: XMLHttpRequest;
/**
* 创建一个 ajax请求
* W3C标准和IE标准
*/
if (window["XMLHttpRequest"]) {
//W3C标准
xhr = new window["XMLHttpRequest"]();
} else if (window["ActiveXObject"]) {
//@ts-ignore IE标准
xhr = new ActiveXObject('Microsoft.XMLHTTP')
} else {
console.error("当前浏览器不支持XHR请求")
return
}
//返回类型
xhr.responseType = options.dataType;
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var status = xhr.status;
if (status >= 200 && status < 300) {
options.success && options.success(xhr.response);
} else {
options.error && options.error(status || "error");
}
}
};
if (options.type == 'GET') {
xhr.open("GET", options.url + '?' + params, options.async);
xhr.send(null)
} else if (options.type == 'POST') {
/**
*打开请求
*/
xhr.open('POST', options.url, options.async);//待测试,post请求
/**
* POST请求设置请求头
*/
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
if (options.headers) {
for (let key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
}
/**
* 发送请求参数
*/
xhr.send(params);
}
}
/**
* jsonp模拟,不考虑回调
* @param url
* @param params
*/
export function jsonp(url: string, params: any) {
const src = url + '?' + getParams(params);
const scriptEl = document.createElement('script');
scriptEl.src = src;
scriptEl.onload = function () {//docment考虑改成head
document.body.removeChild(scriptEl);
};
scriptEl.onerror = function () {
document.body.removeChild(scriptEl);
};
document.body.appendChild(scriptEl);
}
/**
* 对象参数的处理
* @param data
* @returns {string}
*/
function getParams(data): string {
if (!data) return "";//没有就返回空字符
var arr = [];
for (var param in data) {
arr.push(encodeURIComponent(param) + '=' + encodeURIComponent(data[param]));
}
//不缓存
arr.push('_=' + Date.now());
return arr.join('&');
}
//基本没用到过cache,先不加
interface ajaxParameterInt {
url: string,
data?: any,
type?: "GET" | "POST",
async?: boolean,
dataType?: 'text' | 'json' | 'arraybuffer',
headers?: any,
success?: (res: any) => void,
error?: (err: any) => void
}
/**
* 对封装好的ajax请求进行调用
* */
// ajax({
// url: "", //请求地址
// type: 'GET', //请求方式
// data: { name: 'zhangsan', age: '23', email: '2372734044@qq.com' }, //请求参数
// dataType: "json", // 返回值类型的设定
// async: false, //是否异步
// headers: {},
// success: function (response) {
// console.log(response); // 此处执行请求成功后的代码
// },
// error: function (status) {
// console.log('状态码为' + status); // 此处为执行成功后的代码
// }
// });
import { destroyWaiting } from "./waitingCtrl";
import PanelCtrl from "./panelCtrl";
import SceneCtrl from "./sceneCtrl";
import { destroyToast } from "./toastCtrl";
import ConfirmPanel from "../../src/common/IConfirmPanel";
export { showToast } from "./toastCtrl";
export * from "./waitingCtrl";
/**
* 展示弹框
* @param panel 弹框类
* @param data 数据
*/
export const showPanel = (panel: any, data?: any) => {
return PanelCtrl.instance.show(panel, data)
}
export const showConfirm = (panel: any, data?: any) => {
const confirmPanel: ConfirmPanel = PanelCtrl.instance.show(panel, data);
return confirmPanel.makePromise();
}
/**
* 关闭所有弹框
*/
export const closeAllPanels = () => {
PanelCtrl.instance.closeAll();
}
/**
* 关闭当前弹框
*/
export const closeCurrentPanel = () => {
PanelCtrl.instance.closeCurrent();
}
/**
* 替换场景
* @param scene
* @param data
*/
export const changeScene = (scene: any, data?: any) => {
SceneCtrl.instance.change(scene, data)
}
/**
* 获取当前场景
*/
export function getCurrentScene(): any {
return SceneCtrl.instance.currentScene
}
/**
* 获取当前弹框
*/
export function getCurrentPanel(): any {
return PanelCtrl.instance.currentPanel
}
/**
* 淘宝小程序的alert
* @param {string} title
* @param {string} content
*/
export const showAlert = (title?: string, content?: string) => {
//@ts-ignore
if (my) {
//@ts-ignore
my.alert({
title: title || "",
content: content || ""
});
} else {
console.log(title, content)
}
}
/**
* 替换setTimeout 因为页面销毁时setTimeout不会停
* 所以干脆用Tween的
* @param {Function} callback
* @param {number} time 毫秒计
*/
export function wait(callback: () => void, time: number): {} {
let obj = {};
FYGE.Tween.get(obj)
.wait(time)
.call(callback)
return obj
}
export function clearWait(obj: {}) {
obj && FYGE.Tween.removeTweens(obj);
}
/**
* 递归清除显示对象里面所有的Tween
* @param obj
* @param isRecursive 默认true,递归移除子级
*/
export function removeTweens(obj, isRecursive: boolean = true) {
if (!obj) return
FYGE.Tween.removeTweens(obj);
if (!isRecursive || !obj.children || !obj.children.length) return
obj.children.forEach(child => {
removeTweens(child)
});
}
/**
* 销毁方法
*/
export function destroyAllCtrls() {
destroyToast();
destroyWaiting();
PanelCtrl.instance.destroy();
SceneCtrl.instance.destroy();
}
import { Panel } from "../views/Panel";
import { layers } from "../views/layers";
import { showWaiting, hideWaiting } from "./waitingCtrl";
import { showToast } from "./toastCtrl";
export default class PanelCtrl {
/**
* 父级容器
*/
private _parent: FYGE.Container;
/**
* 半透明黑色背景
*/
private _bg: FYGE.Shape;//FYGE.Graphics;
/**
* 所有的弹框
*/
private stacks: Panel[] = [];
private static _instance: PanelCtrl;
static get instance() {
return PanelCtrl._instance || (PanelCtrl._instance = new PanelCtrl())
}
init(parent: FYGE.Container) {
this._parent = parent;
let bg = new FYGE.Shape();//Graphics()//Shape();
bg.beginFill(0);
bg.drawRect(//引用适配
layers.stageOffsetX - parent.x,
layers.stageOffsetY - parent.y,
layers.stageWidth,
layers.stageHeight
);
bg.endFill();
bg.hitTestByPixel = false;
bg.visible = false;
this._parent.addChild(bg);
this._bg = bg;
}
/**
* 关闭所有弹框
*/
closeAll() {
this.stacks.forEach(e => e.hidePanel());
}
show<T extends Panel>(cls: any, data?: any): T {
showWaiting()
const panel: T = new cls(data);
this.add(panel);
this.stacks.push(panel);
panel.onLoaded = () => {
panel.y = -(1624 - layers.stageHeight >> 1)
hideWaiting();
this.updateView(false);//这里更新不显示动画先,自行判断是否显示
//start只执行一边
panel.start(data);
//如果是最后一个才显示动画
if (panel.visible) panel.showAni();
}
//资源加载失败时
panel.onLoadError = () => {
hideWaiting();
showToast("资源加载失败")
panel.removeEventListener('onDestroy', this.onPanelHide, this);
this.remove(panel);
}
return panel;
}
private bgAni: "hide" | "show";
private updateView(showPanelAni: boolean = true) {
//没有弹框的时候
if (!this.stacks.length) {
// this._bg.visible = false;
// this._current = null;
// this._parent.visible = false;
if (this._bg.visible) {//原先背景存在时,待测试
this.bgAni = "hide"
FYGE.Tween.removeTweens(this._bg);
FYGE.Tween.get(this._bg)
.to({ alpha: 0 }, 200, FYGE.Ease.cubicOut)
.call(() => {
this._bg.visible = false;
this._current = null;
this._parent.visible = false;
})
}
} else {
//显示弹框层
this._parent.visible = true;
if (this.bgAni == "hide") {//如果正在执行蒙层消失动画,
this.bgAni = "show"
FYGE.Tween.removeTweens(this._bg);
this._bg.alpha = 0.7;
}
//如果首次出现弹框,加个动画
if (this._bg.visible === false) {
this._bg.visible = true;
this._bg.alpha = 0;
FYGE.Tween.get(this._bg).to({ alpha: 0.7 }, 200, FYGE.Ease.cubicOut)
}
}
for (let i = 0; i < this.stacks.length; i++) {
if (i < this.stacks.length - 1) {
this.stacks[i].visible = false;
} else {
this.stacks[i].visible = true;
if (showPanelAni) this.stacks[i].showAni();
this._current = this.stacks[i];
}
}
}
/**
* 添加进父级并添加事件
* @param panel
*/
private add(panel: Panel) {
this._parent.addChild(panel);
panel.addEventListener('onDestroy', this.onPanelHide, this);
}
/**
* 移除
* @param panel
*/
private remove(panel: Panel) {
this._parent.removeChild(panel);
this.stacks = this.stacks.filter(e => e != panel);
}
/**
* 弹框移除时执行
* @param e
*/
private onPanelHide(e: FYGE.Event) {
const panel = e.target as Panel;
panel.removeEventListener('onDestroy', this.onPanelHide, this);
this.remove(panel);
this.updateView();
}
//当前弹框
private _current: Panel;
get currentPanel() {
return this._current
}
/**
* 关闭当前弹框
*/
closeCurrent() {
if (this._current) {
this._current.hidePanel();
// this._current.removeEventListener('onDestroy', this.onPanelHide, this);
// this.remove(this._current);
// this.updateView();
}
}
destroy() {
PanelCtrl._instance = null;
this.stacks = null;
this._current = null;
this._parent = null;
FYGE.Tween.removeTweens(this._bg);
this._bg = null;
}
}
\ No newline at end of file
import { Scene } from "../views/Scene";
import { showWaiting, hideWaiting } from "./waitingCtrl";
import { showToast } from "./toastCtrl";
export default class SceneCtrl {
private _parent: FYGE.Container;
private _currentScene: Scene;
private static _instance: SceneCtrl;
static get instance() {
return SceneCtrl._instance || (SceneCtrl._instance = new SceneCtrl())
}
init(parent: FYGE.Container) {
this._parent = parent;
}
change(cls: any, data?: any) {
//如果是同一个场景,考虑是替换还是return
// if (this._currentScene && this._currentScene instanceof cls) return;//new一个得了,playScene维护太蛋疼,到时看性能吧
let scene: Scene = new cls(data);
scene.visible = false;
showWaiting();
let preScene: Scene = this._currentScene;
scene.onLoaded = () => {
hideWaiting();
scene.showAni(() => {
if (preScene) preScene.destroy();
})
scene.visible = true;
//start里可能处理资源信息,所以在onLoaded后执行
scene.start(data);
}
//加载失败,继续用之前的场景,移除scene
scene.onLoadError = () => {
hideWaiting();
showToast("资源加载失败")
this._currentScene = preScene || null;
this._parent.removeChild(scene);
}
this._currentScene = scene;
this._parent.addChild(scene);
}
get currentScene() {
return this._currentScene
}
destroy() {
SceneCtrl._instance = null;
this._currentScene = null;
this._parent = null;
}
}
\ No newline at end of file
import { layers } from "../views/layers";
import { RES } from "../RES";
let inited = false;
let _toast: Toast;
let _parent: FYGE.Container;
let startY: number
let endY: number
const initToast = () => {
if (!inited) {
inited = true;
_toast = new Toast();
_parent = layers.toastLayer;
_toast.alpha = 0;
_toast.x = layers.stageOffsetX - _parent.x + (layers.stageWidth - _toast.width) / 2;
var h = _toast.height;
var y = layers.stageOffsetY - _parent.y;
startY = y - h;
endY = y + (layers.stageHeight - h) / 2;
}
}
export const showToast = (msg: string) => {
initToast();
_toast.show(msg)
_parent.addChild(_toast);
FYGE.Tween.removeTweens(_toast);
FYGE.Tween.get(_toast)//动画看需求
.set({ y: startY, alpha: 1 })
.to({ y: endY }, 500, FYGE.Ease.quartOut)
.wait(800)
.to({ alpha: 0 }, 300)
.call(() => {
_parent.removeChild(_toast);
})
}
/**
* 对于之前淘宝小程序遇到的问题,需要销毁,否则会出问题
*/
export const destroyToast = () => {
if (inited && _toast && !_toast.destroyed) {
_toast.destroy();
_toast = null;
_parent = null;
inited = false;
}
}
/**
* toast类,不对外导出,适配居中有问题,有时间改
* 自身居中,
*/
class Toast extends FYGE.Container {
msg: FYGE.TextField;
bg: FYGE.Sprite;
PADDING = 40;
constructor() {
super();
this.mouseChildren = false;
this.mouseEnable = false;
var toastBgTexture: FYGE.Texture = RES.getRes("toastBg.png");
this.bg = new FYGE.Sprite(toastBgTexture);
// this.bg.x = (750 - 460) / 2// (layers.stageWidth - this.bg.width) / 2
this.addChild(this.bg);
this.msg = new FYGE.TextField();
this.msg.size = 28;
this.msg.fillColor = "0xffffff";
this.msg.text = "";
this.msg.verticalAlign = FYGE.VERTICAL_ALIGN.MIDDLE;
this.msg.textHeight = toastBgTexture.height;
this.msg.textAlign = FYGE.TEXT_ALIGN.CENTER;
this.addChild(this.msg)
}
/**
* 显示时调用
* @param msg
*/
show(msg: string) {
this.msg.text = msg;
//文本居中适配
this.msg.x = (this.bg.width - this.msg.textWidth) / 2//(layers.stageWidth - this.msg.textWidth) / 2;
//是否需要根据文本宽度缩放背景
// this.bg.width = Math.min(this.msg.textWidth + this.PADDING * 2, 523);
//背景居中适配,由于上面一行注释,那这行就构造函数里只执行一次吧
// this.bg.x = (layers.stageWidth - this.bg.width) / 2
}
destroy() {
FYGE.Tween.removeTweens(this);
super.destroy();
this.msg = null
this.bg = null;
}
}
\ No newline at end of file
import { RES } from "../RES";
import { layers } from "../views/layers";
import { showAlert } from ".";
let inited = false;
let _waiting: Waiting;
let _parent: FYGE.Container
const initWaiting = () => {
if (!inited) {
inited = true;
const waiting = new Waiting();
_parent = layers.topLayer;
_waiting = waiting;
//居中偏移
var offX = (layers.stageWidth - 160/*_waiting.width*/) / 2;
var offY = (layers.stageHeight - _waiting.height) / 2;
//位置适配
_waiting.x = layers.stageOffsetX - _parent.x + offX;
_waiting.y = layers.stageOffsetY - _parent.y + offY;
//阻止事件用
var bg: FYGE.Graphics = new FYGE.Graphics()
.beginFill(0x000000)
.drawRect(-offX, -offY, layers.stageWidth, layers.stageHeight)
.endFill();
bg.alpha = 0;
_waiting.addChildAt(bg, 0);
}
}
/**
* 显示菊花圈
* @param msg 尽量三个字
*/
export const showWaiting = (msg?: string) => {
initWaiting();
_waiting.show(msg)
_parent.addChild(_waiting);
}
/**
* 隐藏菊花圈
*/
export const hideWaiting = () => {
_parent.removeChild(_waiting);
}
export const destroyWaiting = () => {
if (inited && _waiting && !_waiting.destroyed) {
_waiting.destroy();
_waiting = null;
_parent = null;
inited = false;
}
}
/**
* 菊花圈,有机会重写,应该适应所有场景居中
*/
class Waiting extends FYGE.Container {
msg: FYGE.TextField;
constructor() {
super();
//圆角矩形背景
var rectBgTexture: FYGE.Texture = RES.getRes("waitingBg.png")
var rectBg = new FYGE.Sprite(rectBgTexture);
this.addChild(rectBg);
var rotTexture: FYGE.Texture = RES.getRes("waitingRot.png")
let rot = new FYGE.Sprite(rotTexture);
rot.x = (rectBgTexture.width - rotTexture.width) / 2
rot.y = 47//533;
rot.anchorX = rotTexture.width / 2;
rot.anchorY = rotTexture.height / 2;
this.addChild(rot);
let count = 0;
rot.addEventListener(FYGE.Event.ENTER_FRAME, () => {
count++;
if (count % 30 == 0) rot.rotation += 45;
}, this)
this.msg = new FYGE.TextField();
this.msg.y = 125;
this.msg.textWidth = rectBgTexture.width;
this.msg.textAlign = FYGE.TEXT_ALIGN.CENTER;
this.msg.size = 26
this.msg.fillColor = "#ffffff";
this.addChild(this.msg);
}
show(msg: string = "加载中") {
this.msg.text = msg;
}
destroy() {
super.destroy();
this.msg = null;
}
}
const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
/**
* base64编码汉字,
* 一般用于链接参数传递,
* 先base64.encode,再encodeURIComponent后带入,取参数时会decodeURIComponent,然后再base64.decode后
* 直接调用Base64.ins
*/
export class Base64 {
// private property
// _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
private static instance: Base64;
public static get ins(): Base64 {
if (!this.instance) {
this.instance = new Base64();
}
return this.instance;
}
constructor() {
}
// public method for encoding
encode(input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = this._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
decode(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = this._utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
private _utf8_encode(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
private _utf8_decode(utftext) {
var string = "";
var i = 0;
var c = 0;
var c2 = 0;
var c3 = 0
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
\ No newline at end of file
/**
* 回收池
*/
export class GPool {
private static pool = {};
/**
* 取出
* @param name
*/
public static takeOut(name: string) {
if (this.pool[name] && this.pool[name].length) {
return this.pool[name].shift();
}
return null;
}
/**
* 回收
* @param name
* @param obj
*/
public static recover(name: string, obj) {
if (!this.pool[name]) {
this.pool[name] = [];
}
this.pool[name].push(obj);
}
}
\ No newline at end of file
/**
* 用到的和业务相关的
* 各种静态方法汇总
*
* 获取修改链接参数
* 获取cookie
* 缓存相关
* 数组相关
*
*/
export class GTool {
/**
* 读取缓存
*/
public static readCache(key: string/*, type: string = 'localStorage'*/) {
//@ts-ignore
return my ? my.getStorageSync({ key: key }).data : localStorage ? localStorage.getItem(key) : null;
// if (!window.localStorage) {
// return false;
// }
// return window[type].getItem(key);
}
/**
* 写缓存
*/
public static writeCache(key: string, value: any = 'true'/*, type: string = 'localStorage'*/) {
//@ts-ignore
my ? my.setStorageSync({ key: key, data: value }) : localStorage && localStorage.setItem(key, value);
// if (!window.localStorage) {
// // trace(Func.replace(SysLang.lang_012, [type]));
// return;
// }
// window[type].setItem(key, value);
}
/**
* 获得cacheKey今日次数
* 第二天归0重新计数
* @param cacheKey
*/
public static returnTodayTimes(cacheKey: string): number {
var year1 = this.readCache("year" + cacheKey);
var month1 = this.readCache("month" + cacheKey);
var day1 = this.readCache("day" + cacheKey);
var date = new Date();
var year2 = date.getFullYear().toString();
var month2 = date.getMonth().toString();
var day2 = date.getDate().toString();
if (this.int(year2) <= this.int(year1)) {
if (this.int(month2) <= this.int(month1)) {
if (this.int(day2) <= this.int(day1)) {
return this.int(this.readCache(cacheKey));
}
}
}
//如果不是同一天了,归0
var today = "0";
this.writeCache("year" + cacheKey, year2);
this.writeCache("month" + cacheKey, month2);
this.writeCache("day" + cacheKey, day2);
this.writeCache(cacheKey, today);
return 0;
}
/**
* 随机,两个参数时是数值范围,比如randomT(1,10),一个参数时是数组
* @param e
* @param n
*/
public static randomT(e, n?) {
return e && "number" == typeof e.length && e.length ? e[Math.floor(Math.random() * e.length)] : ("number" != typeof n && (n = e || 1, e = 0), e + Math.random() * (n - e))
}
/**
* 从数组中移除一个元素
* @param e 元素
* @param arr 数组
*/
public static removeEle(e, arr) {
var index = arr.indexOf(e);
if (index >= 0) {
arr.splice(index, 1)
}
}
/**
* 数组中插入一个数值,按顺序的
* 数组是从小到大的
* @param num
* @param arr
*/
public static insert(num, arr) {
for (var i = arr.length - 1; i >= 0; i--) {
if (num > arr[i]) {
//在arr[i]后加num
arr.splice(i + 1, 0, num);
break
}
}
}
/**
* 获取start到end里的n个整数
* @param start 0
* @param end 19
* @param n 3
*/
public static getRandomNumber(start: number, end: number, n: number): number[] {
var arr = [];
for (var i = 0; i < n; i++) {
var number = Math.floor(Math.random() * (end - start + 1) + start);
if (arr.indexOf(number) < 0) {
arr.push(number);
} else {
i--;
}
}
return arr;
}
/**
* 打乱数字数组,改变原数组
* @param arr
*/
public static disturbNumberArr(arr: number[]) {
arr.sort(function () {
return (0.5 - Math.random());
});
}
public static disturbArr(arr: any[]) {
return arr.sort(function () {
return (0.5 - Math.random());
});
}
/**
* 其实打乱数组取前几个就行
* 随机取数组arr中count个元素,不改变原数组
* @param arr
* @param count
*/
public static getRandomArrayElements(arr: any[], count: number) {
var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
//如果count大于等于数组长度,返回所有数组
if (min <= 0) return shuffled;
if (count <= 0) return [];
//随机排序,然后取出后面的元素
while (i-- > min) {
index = Math.floor((i + 1) * Math.random());
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
return shuffled.slice(min);
}
/**
* 随机取数组arr中count个元素,原数组减少count个
* @param arr
* @param count
*/
public static getRandomArrayElementsEx(arr: any[], count: number): any[] {
//如果count大于等于数组长度,返回所有数组
if (arr.length <= count) return arr.slice();
if (count <= 0) return [];
var arrCopy = arr.slice();
var outArr = [];
while (count--) {
var rand = Math.floor(Math.random() * arrCopy.length);
var ele = arrCopy.splice(rand, 1)[0];
outArr.push(ele);
}
return outArr
}
/**
* 向下取整,或把字符串执行parseInt(字符串转数字取整数部分)
* @param n 数字或字符串
*/
private static int(n: any): number {
return n >> 0;//~~n
};
/**
* emoji正则式
*/
public static emojiReg = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig
/**
* 在字符串间加空格
* @param str
*/
public static addSpaceInString(str: string) {
if (!str.length || str.length == 1) return str;
var txt = "";
//每个字符后加空格
for (var i = 0; i < str.length - 1; i++) {
txt = txt + str[i] + " ";
}
txt = txt + str[str.length - 1]
return txt
}
/**
* 毫秒剩余时间转成时分秒
* 1小时1分1秒
* @param timeStamp
*/
public static getShiFenMiaoByTimeStamp(timeStamp: number) {
var hours: any = Math.floor((timeStamp % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes: any = Math.floor((timeStamp % (1000 * 60 * 60)) / (1000 * 60));
// var seconds: any = (timeStamp % (1000 * 60)) / 1000;
var seconds: any = Math.floor((timeStamp % (1000 * 60)) / 1000);
hours = hours < 10 ? ('0' + hours) : hours;
minutes = minutes < 10 ? ('0' + minutes) : minutes;
seconds = seconds < 10 && seconds >= 1 ? ('0' + seconds) : seconds;
// return hours + " :" + minutes + " :" + seconds;
return hours + "小时" + minutes + "分" + seconds + "秒";
}
/**
* 获取字符串真实长度,中文算两个
* @param str
*/
static getRealStringLength(str: string): number {
var realLength = 0, len = str.length, charCode = -1;
for (var i = 0; i < len; i++) {
charCode = str.charCodeAt(i);
if (charCode >= 0 && charCode <= 128) realLength += 1;
else realLength += 2;
}
return realLength;
}
/**
* 切字符串
* @param str
* @param realLength
* @param tailStr
*/
static cutStringAcoRealLength(str: string, limit: number, tailStr: string = "...") {
let length = 0;
let out = "";
for (let i of str) {
let charCode = i.charCodeAt(0);
if (charCode >= 0 && charCode <= 128) length += 1;
else length += 2;
if (length <= limit) {
out = out.concat(i);
} else {
out = out.concat(tailStr);
break;
}
}
return out;
}
}
\ No newline at end of file
/////这里集成一些只有web环境才会用到的方法,链接参数,cookie参数等等
let urlParams: { [key: string]: string | true };
/**
* 获取链接参数
* @param key
*/
export function getUrlParams(key: string): string | true {
if (urlParams) return urlParams[key];
urlParams = {};
let search = window.location.search;
try {
search = top.location.search; //尝试获取顶层的链接
} catch (e) {
}
//获取链接参数
for (let item of search.replace('?', '').split('&')) {
let arr = item.split('=');
urlParams[arr[0]] = arr.length === 1 ? true : decodeURIComponent(arr[1]);
}
return urlParams[key];
}
export const duiba_md5 = (function (/*$*/) {
// function safe_add(x, y) {
// var lsw = (x & 65535) + (y & 65535), msw = (x >> 16) + (y >> 16) + (lsw >> 16);
// return (msw << 16) | (lsw & 65535)
// }
function bit_rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt))
}
function md5_cmn(q, a, b, x, s, t) {
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
}
function md5_ff(a, b, c, d, x, s, t) {
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t)
}
function md5_gg(a, b, c, d, x, s, t) {
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t)
}
function md5_hh(a, b, c, d, x, s, t) {
return md5_cmn(b ^ c ^ d, a, b, x, s, t)
}
function md5_ii(a, b, c, d, x, s, t) {
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t)
}
function binl_md5(x, len) {
x[len >> 5] |= 128 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var i, olda, oldb, oldc, oldd, a = 1732584193, b = -271733879, c = -1732584194, d = 271733878;
for (i = 0; i < x.length; i += 16) {
olda = a;
oldb = b;
oldc = c;
oldd = d;
a = md5_ff(a, b, c, d, x[i], 7, -680876936);
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i], 20, -373897302);
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5_hh(d, a, b, c, x[i], 11, -358537222);
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i], 6, -198630844);
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd)
}
return [a, b, c, d]
}
function binl2rstr(input) {
var i, output = "";
for (i = 0; i < input.length * 32; i += 8) {
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 255)
}
return output
}
function rstr2binl(input) {
var i, output = [];
output[(input.length >> 2) - 1] = undefined;
for (i = 0; i < output.length; i += 1) {
output[i] = 0
}
for (i = 0; i < input.length * 8; i += 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 255) << (i % 32)
}
return output
}
function rstr_md5(s) {
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8))
}
function rstr_hmac_md5(key, data) {
var i, bkey = rstr2binl(key), ipad = [], opad = [], hash;
ipad[15] = opad[15] = undefined;
if (bkey.length > 16) {
bkey = binl_md5(bkey, key.length * 8)
}
for (i = 0; i < 16; i += 1) {
ipad[i] = bkey[i] ^ 909522486;
opad[i] = bkey[i] ^ 1549556828
}
hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
return binl2rstr(binl_md5(opad.concat(hash), 512 + 128))
}
function rstr2hex(input) {
var hex_tab = "0123456789abcdef", output = "", x, i;
for (i = 0; i < input.length; i += 1) {
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 15) + hex_tab.charAt(x & 15)
}
return output
}
function str2rstr_utf8(input) {
return unescape(encodeURIComponent(input))
}
function raw_md5(s) {
return rstr_md5(str2rstr_utf8(s))
}
function hex_md5(s) {
return rstr2hex(raw_md5(s))
}
function raw_hmac_md5(k, d) {
return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))
}
function hex_hmac_md5(k, d) {
return rstr2hex(raw_hmac_md5(k, d))
}
var duiba_md5 = function (string, key?, raw?) {
if (!key) {
if (!raw) {
return hex_md5(string)
} else {
return raw_md5(string)
}
}
if (!raw) {
return hex_hmac_md5(key, string)
} else {
return raw_hmac_md5(key, string)
}
};
var hexcase = 0;
var b64pad = "";
var chrsz = 8;
// $.extend({
// duiba_b64_sha: function (input) {
// return binb2b64(core_sha1(str2binb(input), input.length * chrsz))
// }
// });
function core_sha1(x, len) {
x[len >> 5] |= 128 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16) {
w[j] = x[i + j]
} else {
w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1)
}
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde)
}
return Array(a, b, c, d, e)
}
function sha1_ft(t, b, c, d) {
if (t < 20) {
return (b & c) | ((~b) & d)
}
if (t < 40) {
return b ^ c ^ d
}
if (t < 60) {
return (b & c) | (b & d) | (c & d)
}
return b ^ c ^ d
}
function sha1_kt(t) {
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514
}
function core_hmac_sha1(key, data) {
var bkey = str2binb(key);
if (bkey.length > 16) {
bkey = core_sha1(bkey, key.length * chrsz)
}
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 909522486;
opad[i] = bkey[i] ^ 1549556828
}
var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 512 + 160)
}
function safe_add(x, y) {
var lsw = (x & 65535) + (y & 65535);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 65535)
}
function rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt))
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz) {
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i % 32)
}
return bin
}
function binb2str(bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz) {
str += String.fromCharCode((bin[i >> 5] >>> (32 - chrsz - i % 32)) & mask)
}
return str
}
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 15) + hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 15)
}
return str
}
function binb2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 255) << 16) | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 255) << 8) | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 255);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) {
str += b64pad
} else {
str += tab.charAt((triplet >> 6 * (3 - j)) & 63)
}
}
}
str = str + "=";
return str
}
// window.duiba_md5 = duiba_md5;
return duiba_md5
}(/*Zepto*/));
\ No newline at end of file
///////////////////时间相关的方法放这里
/**
* 判断当前时间是否在指定时间区间内,每日,注意没判断起始时间是否肯定小于结束时间
* @param beginTime 形如"9:30","09:30",起始时间
* @param endTime 形如"21:30",结束时间
*/
export function checkAuditDayTime(beginTime: string, endTime: string): boolean {
return !checkBeforeDayTime(beginTime) && checkBeforeDayTime(endTime)
}
/**
* 判断当前时间是否在给定时间前,每天
* 精确到分,有需要自行改造截取方法和setHours传参
* @param time 形如"11:30","09:30",小时 0(午夜) ~ 23(晚上11点),分0 ~ 59 之间,负数或超出,会进行进制换算
* @returns 返回true表示当前时间小于传入时间,即未到传入时间
*/
export function checkBeforeDayTime(time: string): boolean {
var nowDate = new Date();
var timeDate = new Date(nowDate);
var index = time.lastIndexOf("\:");
var hour = time.substring(0, index);
var minue = time.substring(index + 1, time.length);
timeDate.setHours(+hour, +minue, 0, 0);
return nowDate.getTime() < timeDate.getTime()
}
/**
* 毫秒剩余时间转成时分秒,具体格式自行修改
* 01时01分01秒
* @param timeStamp
*/
export function getShiFenMiaoByTimeStamp(timeStamp: number): string {
var hours: any = Math.floor((timeStamp % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes: any = Math.floor((timeStamp % (1000 * 60 * 60)) / (1000 * 60));
var seconds: any = Math.floor((timeStamp % (1000 * 60)) / 1000);
hours = hours < 10 ? ('0' + hours) : hours;
minutes = minutes < 10 ? ('0' + minutes) : minutes;
seconds = seconds < 10 ? ('0' + seconds) : seconds;
// return hours + ":" + minutes + ":" + seconds;
return hours + "时" + minutes + "分" + seconds + "秒";
}
/**
* 根据时间戳返回各种格式,自行修改,到时加枚举
* @param timeStamp 时间戳
* @return 20190606 09:05:33 2019-06-06 09:05:33 2019/06/06 09:05:33 2019年3月12日10时9分29秒
*/
export function getDateTime(timeStamp: number): string {
function add0(m: number) {
return m < 10 ? '0' + m : m
}
var time = new Date(timeStamp);
var y = time.getFullYear();
var m = time.getMonth() + 1;
var d = time.getDate();
var h = time.getHours();
var mm = time.getMinutes();
var s = time.getSeconds();
// return "" + y + add0(m) + add0(d) + ' ' + add0(h) + ':' + add0(mm) + ':' + add0(s);
// return "" + y + '-' + add0(m) + '-' + add0(d) + ' ' + add0(h) + ':' + add0(mm) + ':' + add0(s);
// return "" + y + '/' + add0(m) + '/' + add0(d) + ' ' + add0(h) + ':' + add0(mm) + ':' + add0(s);
return y + "年" + m + '月' + d + '日' + h + '时' + mm + '分' + s + '秒'
}
/**
* 日期格式转时间戳
* 时间格式得用/,ios用-有问题,"2019/06/17 00:00:00",,,,ios也不能直接用Number(new Date())
* @param date "2019/06/17 00:00:00" "2019-06-17 00:00:00"
*/
export function getTimeStampByDate(date: string) {
return new Date(date.replace(/-/g, "/")).getTime();
}
/**
* 快速获取年月日时分秒 "2021-02-01 18:32:32"
* @param timeStamp 不传表示当前
*/
export function getDate(timeStamp: number = Date.now()): string {
//有局限性,但是无妨 19暂时年份不会超
return new Date(timeStamp + 8 * 3600 * 1000).toJSON().substr(0, 19).replace("T", " ");
}
/**
* 判断两个时间戳是否为同一天
* @param time1
* @param time2
*/
export function checkSameDay(time1: number, time2: number): boolean {
return new Date(time1).toDateString() === new Date(time2).toDateString()
}
import { ajax } from "../ajax";
// sdk 不能加crossorign
// <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
// 小程序分享得用这个
// <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
/**
* 判断是否是微信环境
*/
export function isWxClient() {
var ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) && ua.match(/MicroMessenger/i)[0] == "micromessenger") {
return true;
}
return false;
};
/**
* 初始化微信分享配置
*/
export function initWxConfig(callback?: (s: boolean) => void, debug: boolean = false) {
if (!isWxClient()) {
callback && callback(false)
return;
}
//微信分享,获取分享签名
ajax({
type: 'GET',
url: '/wechatShare/getShareInfo/v2',
data: { url: window.location.href },//有问题再检查链接//部分链接参数会导致初始化失败,以后中文参数用base,%用自定字符替换
dataType: 'json',
success: function (data) {
if (data.success) {
console.log("微信配置获取:")
window["wx"].config({
debug,
appId: data.wxappid,
timestamp: data.wxtimestamp,
nonceStr: data.wxnonceStr,
signature: data.wxsignature,
jsApiList: ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'chooseImage']
});
callback && callback(true)
} else {
callback && callback(false)
}
},
error: function (data) {
callback && callback(false)
}
});
}
/**
* 初始化分享信息
* @param title 标题
* @param desc 描述,朋友圈无
* @param link 主域名一致的链接,且是https
* @param imgUrl 图片必须是https
*/
export function initWxShare(
title: string,
desc: string,
link: string,
imgUrl: string
) {
//执行ready可重新设置分享信息
window["wx"].ready(function () {
window["wx"].onMenuShareTimeline({
title,
link,
imgUrl,
success: function (res) {
}
});
//监听“分享给朋友”按钮点击、自定义分享内容及分享结果接口
window["wx"].onMenuShareAppMessage({
title,
desc,
link,
imgUrl,
success: function (res) {
}
});
})
}
//模拟下$ TODO
// 或者引个zepto
// <script crossorigin="anonymous" src="//yun.duiba.com.cn/db_games/libs/zepto_security_downloadApp.min.js"></script>
//易盾的sdk
// <script type="text/javascript" src="//cstaticdun.126.net/load.min.js"></script> -->
var $ = window["$"]
/**
* @note 极验 - 第三方插件
* @author 张晨辰
* @email zcc@duiba.com.cn
* @create 2017-04-19 12:01:45
* @update 2017-06-28 10:06:00
* @des https://www.163yun.com/help/documents/294963579379175424
* @dependencies <script type="text/javascript" src="//c.dun.163yun.com/js/c.js"></script>
* 2.0 <script src="//cstaticdun.126.net/load.min.js"></script> 用下面这个
*/
let captchaIns;
export function initNECaptcha(options) {
if (!options.captchaId) {
return false;
}
$('body').append('<div class="captcha"><div id="check_wrapper" class="neCaptcha-dialog"></div></div>');
var opts = {
element: '#check_wrapper', // 可以是验证码容器id,也可以是HTMLElement
captchaId: options.captchaId, // 这里填入申请到的验证码id
width: options.width || 270, // 验证码组件显示宽度
mode: options.mode || 'embed',
onVerify: function (err, data) {
if (!err) {
$(".captcha").unbind("click");
$('.captcha').remove();
// data.validate = base64.encode(data.validate);
options.callback && options.callback(data);
}
}
}
window["initNECaptcha"] && window["initNECaptcha"](opts, function (instance) {
captchaIns = instance
$(".captcha").click(function (e) {
if (e.target.className == "captcha") {
if (captchaIns) captchaIns.refresh()
}
});
}, function (err) {
console.log(err, 55655665)
//初始化失败,点击黑色区域重新初始
$(".captcha").click(function (e) {
// if (e.target.className == "captcha") {
$(".captcha").unbind("click");
$('.captcha').remove();
initNECaptcha(options)
// }
});
});
window["loading"] && window["loading"].close();
$('.captcha').show();
};
//例子
initNECaptcha({
captchaId: /*Tools.captchId*/111, //a869bfdfb9bd4cdf88e1ff2f8667a114
callback: function (ret) {
console.log(ret.validate)
}
})
/* 易盾css*/
.captcha {
display: none;
position: fixed;
z-index: 10000;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.6);
}
.captcha .neCaptcha-dialog {
background-color: #fff;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.35);
-webkit-box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.35);
position: absolute;
left: 50%;
top: 45%;
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
width: 270px;
height: 134px;
}
.captcha .neCaptcha-dialog::after {
position: absolute;
content: '单次游戏结束,请拖动滑块提交分数';
width: 100%;
height: 30px;
top: -40px;
left: 0;
text-align: center;
line-height: 30px;
font-size: 16px;
color: #ffff00;
}
.captcha .neCaptcha-dialog::before {
background-color: #fff;
content: '';
display: block;
width: 280px;
height: 144px;
position: absolute;
top: -5px;
left: -5px;
z-index: -1;
}
\ No newline at end of file
import { RES } from "./RES";
export async function getPic() {
// await RES.loadGroup("bitmapNumber")
// await RES.loadGroup("character")
// await RES.loadGroup("ctBigNumber")
// await RES.loadGroup("level")
// await RES.loadGroup("resurreaction")
// await RES.loadGroup("gameLevel")
// await RES.loadGroup("goalTip")
// let textures = {
// "1":RES.getRes("st_1.png"),
// "2":RES.getRes("st_2.png"),
// "3":RES.getRes("st_3.png"),
// "4":RES.getRes("st_4.png"),
// "5":RES.getRes("st_5.png"),
// "6":RES.getRes("st_6.png"),
// "7":RES.getRes("st_7.png"),
// "8":RES.getRes("st_8.png"),
// "9":RES.getRes("st_9.png"),
// "0":RES.getRes("st_0.png"),
// "小": RES.getRes('meici_11.png'),
// "免": RES.getRes('free_freeText.png'),
// }
// let character = {
// "双": RES.getRes('qietu_03.png'),
// "倍": RES.getRes('qietu_04.png'),
// "金": RES.getRes('qietu_05.png'),
// "币": RES.getRes('qietu_06.png'),
// "即": RES.getRes('qietu_07.png'),
// "将": RES.getRes('qietu_08.png'),
// "到": RES.getRes('qietu_09.png'),
// "期": RES.getRes('qietu_10.png'),
// "仅": RES.getRes('qietu_14.png'),
// "需": RES.getRes('qietu_15.png'),
// "花": RES.getRes('qietu_16.png'),
// "费": RES.getRes('qietu_17.png'),
// "3": RES.getRes('st_3.png'),
// "0": RES.getRes('st_0.png'),
// "6":RES.getRes("st_6.png"),
// "小": RES.getRes('qietu_19.png'),
// "豆": RES.getRes('qietu_20.png'),
// "可": RES.getRes('qietu_22.png'),
// "续": RES.getRes('qietu_23.png'),
// "1": RES.getRes('qietu_25.png'),
// "5": RES.getRes('qietu_26.png'),
// "s": RES.getRes('qietu_27.png'),
// "金身": RES.getRes('jinshen_03.png'),
// "传": RES.getRes('tianjiang_07.png'),
// "继": RES.getRes('yunxiao_07.png'),
// }
// let countNumber = {
// "1":RES.getRes("ct_1.png"),
// "2":RES.getRes("ct_2.png"),
// "3":RES.getRes("ct_3.png"),
// "4":RES.getRes("ct_4.png"),
// "5":RES.getRes("ct_5.png"),
// "6":RES.getRes("ct_6.png"),
// "7":RES.getRes("ct_7.png"),
// "8":RES.getRes("ct_8.png"),
// "9":RES.getRes("ct_9.png"),
// "0":RES.getRes("ct_0.png"),
// }
// let level = {
// "+":RES.getRes("plus.png"),
// "A":RES.getRes("A.png"),
// "S":RES.getRes("S.png"),
// }
// let resurrectionNumber = {
// "1":RES.getRes("fh_1.png"),
// "2":RES.getRes("fh_2.png"),
// "3":RES.getRes("fh_3.png"),
// "4":RES.getRes("fh_4.png"),
// "5":RES.getRes("fh_5.png"),
// "6":RES.getRes("fh_6.png"),
// "7":RES.getRes("fh_7.png"),
// "8":RES.getRes("fh_8.png"),
// "9":RES.getRes("fh_9.png"),
// "0":RES.getRes("fh_0.png"),
// }
// let gameLevel = {
// "1":RES.getRes("level_1.png"),
// "2":RES.getRes("level_2.png"),
// "3":RES.getRes("level_3.png"),
// "4":RES.getRes("level_4.png"),
// "5":RES.getRes("level_5.png"),
// "6":RES.getRes("level_6.png"),
// "7":RES.getRes("level_7.png"),
// "8":RES.getRes("level_8.png"),
// "9":RES.getRes("level_9.png"),
// "0":RES.getRes("level_0.png"),
// "A":RES.getRes("level_A.png"),
// "S":RES.getRes("level_S.png"),
// "+":RES.getRes("level_plus.png"),
// }
// let goalTip = {
// "1":RES.getRes("gl_1.png"),
// "2":RES.getRes("gl_2.png"),
// "3":RES.getRes("gl_3.png"),
// "4":RES.getRes("gl_4.png"),
// "5":RES.getRes("gl_5.png"),
// "6":RES.getRes("gl_6.png"),
// "7":RES.getRes("gl_7.png"),
// "8":RES.getRes("gl_8.png"),
// "9":RES.getRes("gl_9.png"),
// "0":RES.getRes("gl_0.png"),
// "A":RES.getRes("gl_A.png"),
// "S":RES.getRes("gl_S.png"),
// "+":RES.getRes("gl_plus.png"),
// "距": RES.getRes("tipText_01.png"),
// "只": RES.getRes("tipText_03.png"),
// "金": RES.getRes("tipText_05.png"),
// }
let commonNumber = {
"1":RES.getRes("1.png"),
"2":RES.getRes("2.png"),
"3":RES.getRes("3.png"),
"4":RES.getRes("4.png"),
"5":RES.getRes("5.png"),
"6":RES.getRes("6.png"),
"7":RES.getRes("7.png"),
"8":RES.getRes("8.png"),
"9":RES.getRes("9.png"),
"0":RES.getRes("0.png"),
}
return {
// textures,
// character,
// countNumber,
// level,
// resurrectionNumber,
// gameLevel,
// goalTip,
commonNumber
}
}
import { RES } from "../RES";
/**
* 暂时用列表的接口
*/
export class Item extends FYGE.Container implements FYGE.IScrollListItem {
get skinName(): string { return null };
constructor(data?) {
super();
if (this.skinName) RES.initSkinDisplay(this, this.skinName, this);
/*setTimeout(() => {*/ this.initUi(data); /*})*///考虑是否可以不加延时,加了会有问题,自行调用的updateData会先执行,不加的话继承类里initUi里的属性。。。
}
/**
* 自定义的初始布局方法
* 注意声明的变量会覆盖initUi里赋值的变量,
*/
initUi(data?) {
}
/**
* 自行调用的更新数据方法
*/
updateData(data?) {
}
/**
* 滚动列表的数据更新方法
* @param id
* @param data
*/
initData(id: number, data: any): void {
this.id = id;//这两个直接赋值吧
this.data = data;
this.resetData();
}
id: number;
data: any;
/**
* 滚动列表ScrollList里专用
* 重置item里属性及显示对象属性的方法,
* 在每次initData会调用
*/
resetData() {
}
}
import { RES } from "../RES";
import { removeTweens } from "../ctrls";
/**
*
*/
export class Module extends FYGE.Container {
protected data: any;
constructor(data?: any) {
super();
this.data = data;
this.init();
}
/**
* 初始化资源和皮肤
*/
private init() {
this.preLoadRes().then(
() => {
//添加皮肤配置
if (this.skinName) RES.initSkinDisplay(this, this.skinName, this);
this.initUi();
this.onLoaded && this.onLoaded();
},
() => {
this.onLoadError && this.onLoadError();
}
);
}
/**
* 提前加载的资源
*/
protected preLoadRes() {
return new Promise<void>((resolve, reject) => {
if (this.groupNames && this.groupNames.length) {
var arr: Promise<any>[] = [];
for (var i = 0; i < this.groupNames.length; i++) {
arr.push(RES.loadGroup(this.groupNames[i]))
}
// @ts-ignore
Promise.all(arr).then(resolve, reject)
} else {
resolve()
}
})
}
/**
* 初始化ui
* 子类修改
*/
protected initUi() {
}
/**
* 资源加载完成后执行,用于场景及弹框控制
*/
onLoaded: () => void
/**
* 资源加载失败时执行,用于场景及弹框控制
*/
onLoadError: () => void;
/**
* 可以有多个组
*/
get groupNames(): string[] { return null }
/**
* 皮肤名字
*/
get skinName(): string { return null };
/**
* 在构造函数后执行
*/
start(data?: any) {
this.initEvents();
}
/**
* 添加事件
*/
initEvents(): void {
}
/**
* 移除事件
*/
removeEvents(): void {
}
/**
* 鼠标事件
* @param enable
*/
protected enableMouseEvt(enable: boolean): void {
this.mouseEnable = enable;
this.mouseChildren = enable;
}
/**
* 延时防连点
* @param target
* @param {number} delay
*/
protected btnDelay(target, delay = 2000) {
target.mouseEnable = false;
target.mouseChildren = false;
setTimeout(() => {
target.mouseEnable = true;
target.mouseChildren = true;
}, delay);
}
public destroy(): void {
//以防有些地方用了showAni
removeTweens(this);
// this.data = null;//看情况吧,有时候hidePanel后用了data,注意,还是先去掉吧
//移除事件
this.removeEvents();
//派发销毁事件,主要用于场景及弹框控制
this.dispatchEvent("onDestroy");
super.destroy();
}
}
import { Module } from "./Module";
export class Panel extends Module {
protected isShowing: boolean
showAni() {
if (this.isShowing) return;
this.isShowing = true;
let oriY = this.y || 0;
this.y = -200;
FYGE.Tween.get(this)
.to({y: oriY}, 500, FYGE.Ease.quartOut)
.call(() => {
this.isShowing = false;
})
}
initEvents() {
this.closeBtns.forEach(
btn => {
if (btn) btn.addEventListener(FYGE.MouseEvent.CLICK, this.hidePanel, this)
}
)
}
removeEvents() {
this.closeBtns.forEach(
btn => {
if (btn) btn.removeEventListener(FYGE.MouseEvent.CLICK, this.hidePanel, this)
}
)
}
/**
* 需要的放入,不重复写关闭按钮事件
*/
protected get closeBtns(): any[] {
return [this['closeBtn']]
}
hidePanel() {
this.destroy();
}
}
import { Module } from "./Module";
export class Scene extends Module {
/**
* 显示动画
* 继承时注意,回调要加
* 因为这种动画基本原场景最好不消失
*/
showAni(callback: Function) {
callback()
}
/**
* 统一更新方法
*/
updateScene() {
}
}
\ No newline at end of file
import PanelCtrl from "../ctrls/panelCtrl";
import SceneCtrl from "../ctrls/sceneCtrl";
/**
* 添加进舞台的所有层级
* 仿白鹭的那套
*/
class Layers extends FYGE.Container {
private _bottomLayer: FYGE.Container;
private _sceneLayer: FYGE.Container;
private _popupLayer: FYGE.Container;
private _toastLayer: FYGE.Container;
private _topLayer: FYGE.Container;
private _shareLayer: FYGE.Container;
init(stage: FYGE.Stage) {
stage.addChild(this);
var arr = [
"_bottomLayer",
"_sceneLayer",
"_popupLayer",
"_toastLayer",
"_topLayer",
"_shareLayer"
];
for (var i = 0; i < arr.length; i++) {
this[arr[i]] = new FYGE.Container();
//有些时候,定宽的时候,部分layer置顶,部分居中,再处理
//为了都置顶和置左,stage的方式永远居中视窗,要么改stage永远左上为00
// this[arr[i]].y = this.stageOffsetY;
//如果定宽这里没必要,肯定是0
// this[arr[i]].x = this.stageOffsetX;//去掉,定高时就居中了
this.addChild(this[arr[i]]);
}
//都以顶部适配
// this.sceneLayer.y = this.stageOffsetY;
// this.popupLayer.y = this.stageOffsetY;
//都以底部适配
// this.sceneLayer.y = -this.stageOffsetY;
// this.popupLayer.y = -this.stageOffsetY;
//这个因为psd弹框不规范
// this.popupLayer.y -= 420 / 2;
this.shareLayer.y = -this.stageOffsetY;
//初始化场景层级
SceneCtrl.instance.init(this.sceneLayer)
//初始化弹框层级
PanelCtrl.instance.init(this.popupLayer)
}
/**
* 底图所在层级,比如统一的背景
*/
get bottomLayer() { return this._bottomLayer }
/**
* 场景
*/
get sceneLayer() { return this._sceneLayer }
/**
* 弹框
*/
get popupLayer() { return this._popupLayer }
/**
* toast所在层级
*/
get toastLayer() { return this._toastLayer }
/**
* 顶层,比如统一标题栏等
*/
get topLayer() { return this._topLayer }
/**
* 分享引导层
*/
get shareLayer() { return this._shareLayer }
/**
* 舞台信息都放在layers里吧
* 舞台可见高度,初始化后才能使用
*/
get stageHeight() {
if (!this.stage) return 0;
return this.stage.viewRect.height;
}
/**
* 舞台可见宽度
*/
get stageWidth() {
if (!this.stage) return 0;
return this.stage.viewRect.width;
}
/**
* 适配方式x两边偏移的量,固定宽度x为0
*/
get stageOffsetX() {
if (!this.stage) return 0;
return this.stage.viewRect.x;
}
get stageOffsetY() {
if (!this.stage) return 0;
return this.stage.viewRect.y;
}
/**
* 舞台中心点位置x
*/
// get stageCenterX(): number {
// return this.stage.viewRect.x + this.stage.viewRect.width >> 1;
// }
/**
* 舞台中心点位置y,layer位置做过偏移的就不对了,所以还是自行算吧
*/
// get stageCenterY(): number {
// return this.stage.viewRect.y + this.stage.viewRect.height >> 1;
// }
}
export const layers = new Layers();
//先执行,在淘宝小程序中重新进入会再次初始化
export function destroyLayers() {
//所有层级移除,init会重新建
layers.removeChildren();
//从父级stage移除自己,init会重新加
if (layers.parent) layers.parent.removeChild(layers)
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "game_template",
"version": "1.0.0",
"description": "game_template",
"main": "index.html",
"scripts": {
"dev": "node rollup.dev.mjs -p 8080",
"build": "npm run handleRes && node scripts/mergeJson && node scripts/upload && npm run buildTS",
"buildTS": "rollup -c rollup.prod.mjs && node scripts/uploadSingleJs",
"handleLotS": "node scripts/handleLotS",
"handleRes": "node scripts/delRel && node scripts/copyRes && node scripts/createTm && node scripts/textureMerge && node scripts/delTm && node scripts/imageMin",
"copyJs": "node scripts/copyJs",
"flushRes": "node scripts/flushRes",
"psd": "node scripts/psdH && node scripts/flushRes",
"psdSin": "node scripts/psdHSin",
"clearSameImg": "node scripts/clearSameImg && node scripts/flushRes",
"createModule": "node scripts/createModule",
"createAllModule": "node scripts/createAllModule"
},
"devDependencies": {
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.1.1",
"@rollup/plugin-typescript": "^8.3.0",
"ali-oss": "^4.11.4",
"chalk": "^2.3.0",
"co": "^4.6.0",
"del": "^2.2.1",
"fs": "0.0.2",
"glslify": "^7.1.1",
"imagemin": "^7.0.1",
"imagemin-mozjpeg": "^8.0.0",
"imagemin-pngquant": "^8.0.0",
"pack_textures": "^1.1.9",
"path": "^0.12.7",
"progress": "^2.0.0",
"psd": "^3.2.0",
"readline": "^1.3.0",
"rollup": "^2.61.1",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-glsl-loader": "^1.0.13",
"rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-progress": "^1.1.2",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-serve": "^1.1.0",
"rollup-plugin-terser": "^7.0.2",
"tslint": "^5.9.1",
"typescript": "^4.5.4"
},
"dependencies": {
"colors": "^1.4.0",
"duiba-utils": "^1.0.9",
"md5": "^2.3.0"
},
"author": "MrKwon",
"license": "ISC"
}
{
"type": "activity",
"name": "template"
}
\ No newline at end of file
{
"groups": [
{
"keys": "helpBg.png,helpBtn.png",
"name": "HelpPanel"
},
{
"keys": "5cab5037-81fc-4246-96e5-b1353f339275.png,7458bc9a-d07d-4a7c-972b-4de7ed7c040d.png,7e4500a1-83be-4686-a46b-67147ed44ddd.png,845ae874-998e-4f68-8e79-641eb77466f3.png,a122de8a-beed-4442-9252-8c047986f371.png,ad9681a6-9eb2-40ad-8c2c-0b3ad121a00d.png,b48ee079-b3d7-4371-b294-944200eccba9.png,cd1a775d-36c9-4c8e-9c67-8191070068e9.png",
"name": "LoadingEffect"
},
{
"keys": "noTimeBg.png,noTimeBtn.png",
"name": "NoTimePanel"
},
{
"keys": "overBtn.png,overNoPrizeBg.png,overPrizeBg.png",
"name": "OverPanel"
},
{
"keys": "rankBg.png,rankIcon.png",
"name": "RankPanel"
},
{
"keys": "rankNoPrizeBg.png,rankNoPrizeBtn.png,rankPrizeBg.png,rankPrizeBtn.png",
"name": "RankPrizePanel"
},
{
"keys": "reviveBg.png,reviveCancel.png,reviveOk.png",
"name": "RevivePanel"
},
{
"keys": "rulePanelBg.png,rulePanelBtn.png",
"name": "RulePanel"
},
{
"keys": "comCloseBtn.png,com_bg.jpg,toastBg.png,waitingBg.png,waitingRot.png",
"name": "common"
},
{
"keys": "gameMusicOff.png,gameMusicOn.png,gameScore+.png,gameScore0.png,gameScore1.png,gameScore2.png,gameScore3.png,gameScore4.png,gameScore5.png,gameScore6.png,gameScore7.png,gameScore8.png,gameScore9.png,guide.png",
"name": "game"
},
{
"keys": "btnTipBg.png,prizeBtn.png,progressBg.png,progressFill.png,progressLabel.png,rankBtn.png,ruleBtn.png,startBtn.png,taskBtn.png",
"name": "index"
},
{
"keys": "loading_effect.png,loading_title.png",
"name": "loading"
}
],
"path": "./resource/"
}
\ No newline at end of file
{
"x": 0,
"y": 0,
"type": "container",
"children": [
{
"name": "LoadingScene",
"x": 0,
"y": 0,
"type": "container",
"children": [
{
"name": "LoadingSceneBg",
"x": 0,
"y": 0,
"type": "sprite",
"props": {
"source": "LoadingSceneBg.png"
}
},
{
"name": "LoadingSceneProBg",
"x": 193,
"y": 1064,
"type": "sprite",
"props": {
"source": "LoadingSceneProBg.png"
}
},
{
"name": "LoadingScenePro",
"x": 199,
"y": 1072,
"type": "sprite",
"props": {
"source": "LoadingScenePro.png"
}
},
{
"name": "LoadingSceneBean",
"x": 273,
"y": 572,
"type": "sprite",
"props": {
"source": "LoadingSceneBean.png"
}
},
{
"name": "LoadingSceneText",
"x": 218,
"y": 477,
"type": "text",
"props": {
"text": "最高可得1000小豆奖励",
"size": 30.000002081447345,
"fillColor": "#ffffff",
"textAlpha": 1
}
},
{
"name": "LoadingSceneTitle",
"x": 55,
"y": 265,
"type": "sprite",
"props": {
"source": "LoadingSceneTitle.png"
}
}
]
},
{
"name": "RulePanel",
"x": 0,
"y": 0,
"type": "container",
"children": [
{
"name": "RulePanelBg",
"x": 51,
"y": 330,
"type": "sprite",
"props": {
"source": "RulePanelBg.png"
}
},
{
"name": "RulePanelBtn",
"x": 235,
"y": 929,
"type": "sprite",
"props": {
"source": "RulePanelBtn.png"
}
},
{
"name": "RulePanelText",
"x": 138,
"y": 592,
"type": "text",
"props": {
"text": "1.本次活动的规则是\n2.本次活动的规则是这样的,那样的,开心就好\r3.本次活动的规则是这样的,那样的,开心就好。本次活动的规则是这样的,那样的,开心就好",
"size": 24.00000598698421,
"fillColor": "#b06852",
"textAlpha": 1
}
},
{
"name": "RulePanelTitle",
"x": 260,
"y": 498,
"type": "sprite",
"props": {
"source": "RulePanelTitle.png"
}
}
]
}
]
}
\ No newline at end of file
/*
* rollup.dev.mjs
* Created by 还有醋v on 2022/5/24.
* Copyright © 2021 haiyoucuv. All rights reserved.
*/
import json from "@rollup/plugin-json";
import typescript from "@rollup/plugin-typescript";
import childProcess from "child_process";
import * as fs from "fs";
import * as path from "path";
import * as rollup from "rollup";
import livereload from "rollup-plugin-livereload";
import progress from "rollup-plugin-progress";
import replace from "rollup-plugin-replace";
import serve from "rollup-plugin-serve";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import glslLoader from "rollup-plugin-glsl-loader";
import colors from "colors";
const argv = process.argv;
const port = +argv[argv.indexOf("-p") + 1] || 8080;
const open = +argv[argv.indexOf("-open") + 1] || false;
watchResChange();
const options = {
input: "src/Main.ts",
cache: true,
output: [
{
file: "build/output.js",
format: "umd",
name: "output",
sourcemap: true,
},
{
file: 'build/output.module.js',
format: 'esm',
sourcemap: true,
}
],
onwarn(warning) {
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
console.log(colors.red(`\n(!) ${warning.message}`));
}
},
plugins: [
progress(),
replace({
ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
}),
resolve(),
typescript({ tsconfig: "./tsconfig.json" }),
commonjs(),
json(),
glslLoader({
glslify: true,
}),
serve({
port,
open,
headers: {
'Access-Control-Allow-Origin': '*',
},
}),
livereload(),
],
};
rollup.watch(options);
/**
* 资源变化自动刷新
*/
function watchResChange() {
const skinUrl = "./resource/skin.json";
fs.watchFile(skinUrl, { persistent: true, interval: 2000 }, (curr, prev) => {
const skinDataAll = fs.readFileSync(skinUrl)
const endFile = `export const SkinJson = ${skinDataAll}`;
fs.writeFileSync("./src/SkinJson.ts", endFile);
console.log("SkinJson.ts文件已更新");
});
// 修改resource文件夹任意内容自动刷新资源
const flushScript = path.resolve('./scripts/flushRes.js');
fs.watch('./resource/', { recursive: true }, _debounce((event, filename) => {
if (
filename === ".DS_Store"
|| filename === "res.json"
|| filename === "skin.json"
) return;
runScript(flushScript, (err) => err && console.log(err));
}));
runScript(flushScript, (err) => err && console.log(err));
}
function runScript(scriptPath, callback) {
let invoked = false;
const process = childProcess.fork(scriptPath);
process.on('error', (err) => {
if (invoked) return;
invoked = true;
callback(err);
});
process.on('exit', (code) => {
if (invoked) return;
invoked = true;
const err = code === 0 ? null : new Error('exit code ' + code);
callback(err);
});
}
function _debounce(fn, delay = 1000) {
let timer = null;
return function (...args) {
timer && clearTimeout(timer);
timer = setTimeout(fn, delay, ...args);
};
}
/*
* rollup.prod.mjs
* Created by 还有醋v on 2022/5/24.
* Copyright © 2021 haiyoucuv. All rights reserved.
*/
import json from "@rollup/plugin-json";
import typescript from "@rollup/plugin-typescript";
import glslLoader from "rollup-plugin-glsl-loader";
import progress from "rollup-plugin-progress";
import replace from "rollup-plugin-replace";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import { terser } from "rollup-plugin-terser";
export default {
input: "src/Main.ts",
output: [
{
file: "released/output.js",
format: "umd",
name: "output",
sourcemap: true,
},
{
file: 'released/output.module.js',
format: 'esm',
sourcemap: true,
}
],
plugins: [
progress(),
replace({
ENV: JSON.stringify(process.env.NODE_ENV || 'prod'),
}),
resolve({ preferBuiltins: true }),
typescript({ sourceMap: true, watch: false, }),
commonjs(),
json(),
glslLoader({
glslify: true,
}),
terser(),
]
};
var fs = require("fs");
var path = require('path');
var del = require('del');
var pathName = "./resource";
var inPath = "./resource/common/";
{
key: ["aa", "bb"]
}
var hash = {};//记录名字和所在文件夹
var files = fs.readdirSync(pathName);
files.forEach(function (file) {
//文件common,不处理
if (file == "common") return
//路径
let fPath = path.join(pathName, file);
//只处理文件夹
if (fs.statSync(fPath).isDirectory()) {
var sonFiles = fs.readdirSync(fPath);
//没有文件
if (!sonFiles.length) return;
sonFiles.forEach(function (s) {
if (!hash[s]) hash[s] = [];
hash[s + ""].push(file);
})
}
})
//遍历
for (var key in hash) {
//有重复的,拷贝到common,删除原文件夹里的文件,
if (hash[key].length > 1) {
// 拷贝到common
fs.writeFileSync(inPath + key, fs.readFileSync(pathName + "/" + hash[key][0] + "/" + key));
console.log("重复资源:" + key)
//删除原文件夹里的文件,
hash[key].forEach(function (s) {
del(pathName + "/" + s + "/" + key)
})
}
}
console.log("重复资源处理完成")
\ No newline at end of file
var fs = require("fs");
// fs.writeFileSync(
// "./released/output.js",
// fs.readFileSync("./output.js")
// )
// var endPath = 'D:/duibaGame/测试项目0527/taobaominiTest/client/pages/index1/';
var endPath = 'D:/duibaGame/淘宝项目/taobao_mini/babycare_xiaoxiaole/babycare_c_client/client/pages/index/';
var version = Math.round(new Date().getTime() / 1000);
// fs.writeFileSync(endPath + "output." + version + ".js", fs.readFileSync("./released/output.js"));
fs.writeFileSync(endPath + "output.js", fs.readFileSync("./released/output.js"));
// console.log("js覆盖完成")
console.log(`版本号:
${version}`)
// cp infile outfile 拷贝文件直接放指令里
\ No newline at end of file
var fs = require('fs');
var path = require("path");
function writeFile(p, text) {
fs.writeFile(p, text, function (err) {
// if (!err)
// console.log("写入成功!")
})
}
//递归创建目录 同步方法
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true;
} else {
if (mkdirsSync(path.dirname(dirname))) {
// console.log("mkdirsSync = " + dirname);
fs.mkdirSync(dirname);
return true;
}
}
}
function _copy(src, dist) {
var paths = fs.readdirSync(src)
paths.forEach(function (p) {
var _src = src + '/' + p;
var _dist = dist + '/' + p;
var stat = fs.statSync(_src)
if (stat.isFile()) {// 判断是文件还是目录
fs.writeFileSync(_dist, fs.readFileSync(_src));
} else if (stat.isDirectory()) {
copyDir(_src, _dist)// 当是目录是,递归复制
}
})
}
/*
* 复制目录、子目录,及其中的文件
* @param src {String} 要复制的目录
* @param dist {String} 复制到目标目录
*/
function copyDir(src, dist) {
var b = fs.existsSync(dist)
// console.log("dist = " + dist)
if (!b) {
// console.log("mk dist = ",dist)
mkdirsSync(dist);//创建目录
}
// console.log("_copy start")
_copy(src, dist);
}
function createDocs(src, dist, callback) {
// console.log("createDocs...")
copyDir(src, dist);
// console.log("copyDir finish exec callback")
if (callback) {
callback();
}
}
createDocs("./resource", "./released/resource/", function () {
console.log("资源拷贝成功")
})
\ No newline at end of file
var exec = require('child_process').exec;
var fs = require("fs");
//用这个生成所有的,最好把createModule里的warn去掉,否则子进程的打不到
const skinDataAll = JSON.parse(fs.readFileSync("./resource/skin.json"));
skinDataAll.children.forEach(c => {
const cmd = "node ./scripts/createModule.js " + c.name;
exec(cmd, { encoding: 'utf8' }, (e) => {
console.log("生成模块:" + c.name)
})
});
var fs = require("fs");
function createHtml(url) {
var js = `//yun.duiba.com.cn/db_games/${url}/output.js`;
var template = fs.readFileSync("./index.html").toString();
//写入released
fs.writeFileSync("./released/index.html", template.replace("./build/output.js", js))
}
module.exports = createHtml
const fs = require("fs");
const warn = require("./warn");
//类型对应
const DISRES = {
'container': "Container",
'text': "TextField",
'button': "Button",
'sprite': "Sprite",
'rect': "Graphics",
// 'skin'
}
const skinDataAll = JSON.parse(fs.readFileSync("./resource/skin.json"))
//取指令后的参数
let arg = process.argv.splice(2);
//类名
var className = arg[0];
//皮肤名字
var skinName = arg[0]; //arg[1];
//是否弹框,存在参数就是场景
var moduleType = className.indexOf("Scene") > -1 ? "Scene" : "Panel";
// console.log('类名:',className)
// console.log('皮肤名字:',skinName)
var skinData = getSkinDataByName(skinName, skinDataAll);
if (!skinData) {
console.log(skinName + "皮肤不存在");
return
}
var groupName = skinData.name;
var endPath = moduleType == "Panel" ? "./src/panels/" : "./src/scenes/";
// var template =
// (moduleType == "Panel" ?
// 'import { Panel } from "../../module/views/Panel";\n' :
// 'import { Scene } from "../../module/views/Scene";\n') +
// 'export class ' + className + ' extends ' + moduleType + ' {\n' +
// '\tget groupNames() { return ["' + groupName + '"] }\n' +
// '\tget skinName() { return "' + skinName + '" }\n' +
// '\t' + getIds(skinData) + "\n" +
// '\tinitUi() {\n' +
// ' \n' +
// '\t}\n' +
// '\tstart(data) {\n' +
// '\t\tsuper.start();\n' +
// '\t}\n' +
// '\tinitEvents() {\n' +
// '\t\tsuper.initEvents();' +
// ' \n' +
// '\t}\n' +
// '\tremoveEvents() {\n' +
// '\t\tsuper.removeEvents();' +
// ' \n' +
// '\t}\n' +
// '}\n'
var template =
(moduleType == "Panel" ?
'import { Panel } from "../../module/views/Panel";\n' :
'import { Scene } from "../../module/views/Scene";\n') +
`export class ${className} extends ${moduleType} {
get groupNames() { return ["${groupName}"] };
get skinName() { return "${skinName}" };
${getIds(skinData)}
initUi() {
}
start(data) {
super.start();
}
initEvents() {
super.initEvents();
}
removeEvents() {
super.removeEvents();
}
}\n\n`
//取出skinName里的Item
var skins = getItemSkins(skinData)
if (skins.length) template = 'import { Item } from "../../module/views/Item";\n' + template;
for (var i = 0; i < skins.length; i++) {
var skin = skins[i];
// template +=
// 'class ' + upperCaseFirstChar(skin.name) + ' extends Item {\n' +
// '\tget skinName() { return "' + skin.name + '" }\n' +
// '\t' + getIds(skin) + "\n" +
// '\tinitUi(data?) {\n' +
// ' \n' +
// '\t}\n' +
// '\tupdateData(data?) {\n' +
// ' \n' +
// '\t}\n' +
// '\tinitData(id: number, data: any): void {\n' +
// '\t\tsuper.initData(id,data);\n' +
// ' \n' +
// '\t}\n' +
// '\tresetData() {\n' +
// ' \n' +
// '\t}\n' +
// '}\n'
template +=
`class ${upperCaseFirstChar(skin.name)} extends Item {
get skinName() { return "${skin.name}" }
${getIds(skin)}
initUi(data?) {
}
updateData(data?) {
}
initData(id: number, data: any): void {
if (id < 0 || !data) return;
super.initData(id,data);
}
resetData() {
}
}\n\n`;
}
//不存在时建一个
if (!fs.existsSync(endPath)) fs.mkdirSync(endPath);
//判断ts文件是否已存在
if (fs.existsSync(endPath + className + ".ts")) {
warn(
className + ".ts已存在,是否覆盖",
() => {
fs.writeFileSync(endPath + className + ".ts", template)
},
() => { }
)
} else {
fs.writeFileSync(endPath + className + ".ts", template)
}
// function cutIds(ids) {
// var str = ''
// var arr = ids.split(";")
// // console.log(arr)
// arr.forEach(element => {
// if (element) str += element + ";\n\t"
// });
// return str
// }
/**
* 获取皮肤数据
* @param {*} skinName
* @param {*} skinNode
*/
function getSkinDataByName(skinName, skinNode) {
if (!skinNode || !skinNode.children || !skinNode.children.length) return null;
for (var i = 0; i < skinNode.children.length; i++) {
var child = skinNode.children[i];
//皮肤数据得是容器
if (child.name == skinName && (child.type == "container" || child.type == "item")) return child;
var gson = getSkinDataByName(skinName, child);
if (gson) return gson
}
return null;
}
//取出所有的Item的皮肤,标记为item的
function getItemSkins(skinNode) {
var arr = []
for (var i = 0; i < skinNode.children.length; i++) {
var c = skinNode.children[i];
if (c.type == 'item') arr.push(c);
if (c.children) getItemSkins(c).forEach((cc) => {
arr.push(cc);
})
}
return arr
}
function getIds(skinNode, str) {
str = str || ''
for (var i = 0; i < skinNode.children.length; i++) {
var c = skinNode.children[i];
if (c.id) str += c.id + ": FYGE." + DISRES[c.type] + ";\n\t";
//作为item的不进
if (c.type == "container" && c.type != "item") str = getIds(c, str);
}
return str
}
function upperCaseFirstChar(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
var fs = require("fs");
var iconv = require('iconv-lite');
var del = require('del');
var readPath = "./released/resource/";
//读取json文件
var data = iconv.decode(fs.readFileSync(readPath + "res.json"), "utf-8");//GBK
//反序列化
data = JSON.parse(data); //eval(data)
//取出里面的图片,暂存到tm文件夹中,同时删除文件夹里的,和本身json里的
if (!fs.existsSync("./released/tm"))
fs.mkdirSync("./released/tm");
for (var i = 0; i < data.groups.length; i++) {
var name = data.groups[i].name;
var path = readPath + name + "/";
var arr = data.groups[i].keys.split(",");
//取出图片的,注意已排除jpg
var images = arr.filter((f) => { return (f.substr(-4) == ".png" /*|| f.substr(-4) == ".jpg"*/) })
//没有图片,
if (!images.length) continue;
//去掉原先数据里的
// data.groups[i].keys = arr.filter((f) => { return (f.substr(-4) != ".png" && f.substr(-4) != ".jpg") }).join(",");
//添加新的json,加到atlas里
// if (data.groups[i].keys) data.groups[i].keys += ","
data.groups[i].atlas = name + ".json"
//读取原先路径里的图片,写到tm的文件夹里,并删除原文件夹里的图片
fs.mkdirSync("./released/tm/" + name);
for (var m = 0; m < images.length; m++) {
fs.writeFileSync(
"./released/tm/" + name + "/" + images[m],
fs.readFileSync(path + images[m])
)
del(path + images[m])
}
}
//序列化
fs.writeFileSync(readPath + "res.json", JSON.stringify(data, "", "\t"));
var fs = require("fs");
var del = require('del');
function delDir(path, isSelf) {
let files = [];
if (fs.existsSync(path)) {
files = fs.readdirSync(path);
files.forEach((file, index) => {
let curPath = path + "/" + file;
if (fs.statSync(curPath).isDirectory()) {
delDir(curPath); //递归删除文件夹
} else {
fs.unlinkSync(curPath); //删除文件
}
});
if (!isSelf) fs.rmdirSync(path);
}
}
var paths = './released/';//设置删除路径
// delDir(paths, true);//删除文件夹
del(paths).then(() => {
fs.mkdirSync(paths);
}).catch(()=>{
fs.mkdirSync(paths);
})
// var tasks = [];
// function addTask(task) {
// tasks.push(task);
// }
// function next() {
// if (tasks.length > 0) {
// tasks.shift()();
// } else {
// return;
// }
// }
// var delRel = function () {
// del(paths).then(() => {
// // console.log("del")
// next();
// })
// }
// var createRel = function () {
// fs.mkdirSync(paths);
// // console.log("create")
// next();
// }
// addTask(delRel)
// addTask(createRel)
// next();
\ No newline at end of file
var del = require('del');
del("./released/tm")
\ No newline at end of file
//生成res.json
//遍历资源文件夹,生成
const fs = require('fs');
const path = require("path");
const readPath = "./resource/"
const files = fs.readdirSync(readPath);
const obj = { groups: [] };//每项包括keys合name
files.forEach(function (file) {
//路径
let fPath = path.join(readPath, file);
//只处理文件夹
if (fs.statSync(fPath).isDirectory()) {
//继续读每个子文件夹,json和png名字有相同的,只留json,
let sonFiles = fs.readdirSync(fPath);
//没有文件
if (!sonFiles.length) return
//取出所有json
const jsons = sonFiles.filter((f) => {
return f.substr(-5) === ".json"
});
//去掉json所带png的图片
sonFiles = sonFiles.filter((f) => { return jsons.indexOf(f.substring(0, f.length - 4) + ".json") === -1 })
//去掉mac上的缓存文件
sonFiles = sonFiles.filter((f) => { return f !== '.DS_Store' })
const group = {
keys: "",
name: file
};
for (let i = 0; i < sonFiles.length; i++) {
if (i !== 0) group.keys += ",";
group.keys += sonFiles[i]
}
obj.groups.push(group)
}
})
obj.path="./resource/"
console.log("资源更新完成")
//生成json
fs.writeFileSync(readPath + "res.json", JSON.stringify(obj, "", "\t"));
//TS也更新
const endPath = './src/';
const endFile = `export const ResJson = ${JSON.stringify(obj, "", "\t")}`;
fs.writeFileSync(endPath + "ResJson.ts", endFile);
/*
* aaaa.js
* Created by 还有醋v on 2022/5/25.
* Copyright © 2022 haiyoucuv. All rights reserved.
*/
const polyfillLibrary = require('polyfill-library');
const fs = require("fs");
polyfillLibrary.getPolyfillString({
uaString: 'Mozilla/5.0 (Linux; Android 4.1.0;) Chrome/29.0.3202.84 Mobile',
minify: true,
features: {
'es5': { },
'Number.isNaN': { },
'Number.isFinite': { },
'Number.isInteger': { },
'Number.parseInt': { },
'Number.parseFloat': { },
'Array.from': { },
'Array.isArray': { },
'Array.prototype.map': { },
'Array.prototype.sort': { },
'Array.prototype.reduce': { },
'Array.prototype.indexOf': { },
'Array.prototype.entries': { },
'Array.prototype.filter': { },
'Array.prototype.forEach': { },
'Object.keys': { },
'Object.values': { },
'Object.assign': { },
'Object.entries': { },
'Promise': { },
'Promise.prototype.finally': { },
'Set': { },
'String.prototype.repeat': { },
'String.prototype.matchAll': { },
'String.prototype.replaceAll': { },
'String.prototype.trim': { },
'String.prototype.trimEnd': { },
'String.prototype.trimStart': { },
'Symbol': { },
}
}).then(function(bundleString) {
fs.writeFileSync("polyfill.js", bundleString);
});
const fs = require("fs");
const iconv = require('iconv-lite');
const path = require('path');
const trans = require("./trans");
const md5 = require('md5');
//用于处理带base64图片的lottie文件,取出图片,同名lottie文件夹,写入代码"./src/lotties/"中;
//别再执行,会覆盖
// return
const pathName = "./lotties";
const outPath = "./resource";
//读文件夹
const files = fs.readdirSync(pathName);
//对每个json文件作处理
files.forEach(function (lottiesFileName) {
// console.log(lottiesFileName)
//后缀不是json的,不处理
if (path.extname(lottiesFileName).indexOf(".json") < 0) return;
//用文件名作为类名和资源文件夹名
const cusName = lottiesFileName.substring(0, lottiesFileName.lastIndexOf(".json"));
//读数据
let data = iconv.decode(fs.readFileSync(pathName + "/" + lottiesFileName), "utf-8");//GBK
//反序列化
data = JSON.parse(data);
//存图片
const assets = data.assets;
if (!assets || !assets.length) return;
//删除属性
delete data.assets;
const copyAssets = [];
const imgOutPath = outPath + "/" + cusName;//data.nm
//建文件夹data.nm
if (!fs.existsSync(imgOutPath)) fs.mkdirSync(imgOutPath);
assets.forEach((e) => {
//没有base64数据,可能是嵌套的
if (!e.p) {
copyAssets.push(e);
return
}
let id = e.id;
// let uuid = guid();
// //存图片
const base64 = e.p.replace(/^data:image\/\w+;base64,/, "");//去掉图片base64码前面部分data:image/png;base64
const dataBuffer = /*new Buffer*/Buffer.from(base64, 'base64'); //把base64码转成buffer对象,
//用用到该图片的图层的名字当作图片名,必须是.png结尾,为了图片去重
let name = data.layers.find((l) => l.refId === id);
//没找到图层,
if (!name) {//再往嵌套图层里的找
for (let ii = 0; ii < assets.length; ii++) {
if (!assets[ii].p) {
name = assets[ii].layers.find((l) => l.refId === id);
if (name) break;
}
}
}
//还没找到图层,不处理
if (!name) return
//不用缓存了,直接用md5;
name = md5(base64);
//修改所有的refId
data.layers.forEach((l) => {
l.refId === id && (l.refId = name)
})
//还有嵌套的
assets.forEach((a) => {
if (!a.p) a.layers.forEach((l) => l.refId === id && (l.refId = name));
})
fs.writeFile(imgOutPath + "/" + name + ".png", dataBuffer, () => 0);
});
//如果存在嵌套图层的,assets加回
if (copyAssets.length) data.assets = copyAssets;
//开始删东西
//是否3d
delete data.ddd;
//版本号,版本必须5.6.10,否则可能有问题
delete data.v;
//遍历删除图层东西
for (let i = 0; i < data.layers.length; i++) {
const l = data.layers[i];
//是否3d,后缀,sr,ao,开始时间,混合模式,特效
["ddd", "cl", "sr", "ao", "st", "bm", "ef"].forEach((e) => delete l[e]);
//ks删除
["o", "r", "p", "a", "s"].forEach((e) => {
const d = l.ks[e];
//ix不知道干嘛用,删了
delete d.ix;
//貌似标记0是没有关键帧的,1是有关键帧的
delete d.a;
//删除k里数据,都要用了,不能删,看情况用吧,如果不需要补间的,用Tween拼的,就删掉,不删只是文件大点
// if (d.k.length && typeof d.k[0] == "object") {
// d.k.forEach((ee) => {
// ["i", "o", "ti", "to"/*, "h"*/].forEach((eee) => { delete ee[eee]; })//h需要判断是否是缓动
// })
// }
})
}
//导出代码到src的lotties文件夹,名字就是lottie动画名字,资源名字临时处理了,首页加载动画用图层的nm,bonustime用refid
const endPath = './src/lotties';
if (!fs.existsSync(endPath)) fs.mkdirSync(endPath);
//文件名字修改,中划线变成下划线,中文变拼音
const fileName = trans(cusName/*data.nm*/).replace(/-/g, "_");
//导出对象直接用lottie动画名字
const endFile = `export const ${fileName} = ${JSON.stringify(data, "", "\t")}`;
//文件名字用lottie动画名字
fs.writeFileSync(endPath + "/" + fileName + ".ts", endFile);
console.log("生成文件:" + fileName + ".ts");
});
const imagemin = require('imagemin');
// const imageminJpegtran = require('imagemin-jpegtran');imagemin-mozjpeg
const imageminJpegtran = require('imagemin-mozjpeg');
const imageminPngquant = require('imagemin-pngquant');
var fs = require('fs');
var path = require('path');
// 要处理的图片文件夹路径
var altasPath = "./released/resource/"
var folders = getFolders(altasPath);
folders.map(async function (folder) {
const files = await imagemin([altasPath + folder + '/*.{png,jpg}'], {
destination: altasPath + folder,
plugins: [
imageminJpegtran(),
imageminPngquant({
quality: [0.6, 0.8]
})
]
});
if (files && files.length) {
files.forEach((v) => {
console.log("压缩图片成功:", v.sourcePath.substring(v.sourcePath.lastIndexOf("/") + 1, v.sourcePath.length))
})
}
});
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function (file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
\ No newline at end of file
var fs = require("fs");
var path = require('path');
var del = require('del');
var iconv = require('iconv-lite');
const join = require('path').join;
//写入图集的文件夹,将文件夹内所有的json合并,并删除原先json
var readPath = "./released/resource/";
//读取json文件
var data = iconv.decode(fs.readFileSync(readPath + "res.json"), "utf-8");//GBK
//反序列化
data = JSON.parse(data);
var files = fs.readdirSync(readPath);
// let obj = {};
let count = 0;
let countAll = files.length
files.forEach(function (file) {
//路径
let fPath = join(readPath, file);
//只处理文件夹
if (fs.statSync(fPath).isDirectory()) {
//读文件夹fPath里的json文件
fs.readdir(fPath, function (err, files) {
if (err) {
console.warn(err)
} else {
var hasJson
//遍历
for (var i = 0; i < files.length; i++) {
let filename = files[i];
if (filename.indexOf(".json") == -1) continue
hasJson = true;
//获取当前文件的绝对路径
let filedir = path.join(fPath, filename);
let content = fs.readFileSync(filedir, 'utf-8');
let group = getGroupByName(filename.replace(".json", ""), data.groups)
group.atlas = JSON.parse(content);
//删除原先json
del(filedir)
if (++count == countAll) endFun();
}
if(!hasJson)if (++count == countAll) endFun();
//序列化,不格式化,节省内存
}
})
} else {
if (++count == countAll) endFun();
}
})
function endFun() {
console.log("资源配置js生成完毕")
// del(join(readPath, "res.json"))
fs.writeFileSync(readPath + "res.json", JSON.stringify(data, "", "\t"));
}
function getGroupByName(name, groups) {
var group;
for (var i = 0; i < groups.length; i++) {
if (groups[i].name === name) {
group = groups[i];
break;
}
}
return group
}
var fs = require("fs");
var PSD = require('psd');
var path = require('path');
// const mkdirp = require('mkdirp');
//千万别再执行,否则覆盖
// return
var options = {
//导出图片的目录,没有就导在psd所在目录
outImgDir: "./resource/",
//导出Json的目录,没有就不导出
outJsonDir: "./resource/",
}
//psd文件所在文件夹目录
var pathName = "./psd";
var files = fs.readdirSync(pathName);
//只输出一个数据,就算多个psd,也按照每个psd的第一级进入root的children
var rootStructure = {
'x': 0,
'y': 0,
'type': "container",
'children': []
}
files.forEach(async function (psdFileName) {
//获取当前文件的后缀名
var extname = path.extname(psdFileName);
//后缀psd的,进行切图
if (extname.indexOf(".psd") >= 0) {
const psdFile = pathName + "/" + psdFileName
const psdFilePath = path.resolve(psdFile);
var pathInfo = path.parse(psdFile);
const psdData = PSD.fromFile(psdFilePath);//open(异步),fromDroppedFile(异步,拖入文件),fromFile
psdData.parse();
const rootNode = psdData.tree();
//按照第一层的进行分组导出
for (let i = 0; i < rootNode._children.length; i++) {
//一个组,比如开始页面,游戏页面等
const group111 = rootNode._children[i]
const queueNodes = [];
const queueNodesIndex = [];
const queueNodesName = [];
const queueNodesStructure = [];
//如果不是组,直接导common文件夹
if (!group111._children || !group111._children.length) {
saveAsPng("common", group111.name, group111)
} else {
const groupName = rootNode._children[i].name;
//颠倒一下
group111._children.reverse()
queueNodes.push(group111._children);
queueNodesIndex.push(0);
queueNodesName.push(undefined);
//首层的容器默认都是0,0,所以他的left和top修改下
group111.left = group111.top = 0;
const psdStructure = {
// 'ids': "",
"name": groupName,
'x': 0,
'y': 0,
'type': "container",
'children': []
};
queueNodesStructure.push(psdStructure);
queueLoop: while (0 < queueNodes.length) {
const queueIndex = queueNodes.length - 1;
const nodes = queueNodes[queueIndex];
const nodesStructure = queueNodesStructure[queueIndex];
let nodesIndex = queueNodesIndex[queueIndex];
let nodesName = queueNodesName[queueIndex];
if (nodesName === undefined) {
nodesName = '';
} else {
nodesName += path.sep;
}
while (nodesIndex < nodes.length) {
const node = nodes[nodesIndex];
nodesIndex++;
// if (node.layer.visible === false) continue;
//分割一下
const splitArr = node.name.split("_");
if (node.type === 'group') {
//如果是按钮的组,就单纯按钮的三种贴图,第一个是正常,第二个是无法点击,第三个down
if (splitArr[1] == "btn") {
const structure = {
'name': splitArr[0],
'x': node.left - (node.parent ? node.parent.left : 0),
'y': node.top - (node.parent ? node.parent.top : 0),
'type': "button",
};
structure.props = {}
// structure.source = splitArr[0] + ".png"
if (splitArr[2]) {
structure.id = splitArr[2];
// psdStructure.ids += splitArr[2] + ":FYGE.Button;"
}
saveAsPng(groupName, node._children[0].name, node._children[0]);
structure.props.tUp = node._children[0].name + ".png";
if (node._children[1]) {
saveAsPng(groupName, node._children[1].name, node._children[1]);
structure.props.tDisable = node._children[1].name + ".png";
}
if (node._children[2]) {
saveAsPng(groupName, node._children[2].name, node._children[2]);
structure.props.tDown = node._children[2].name + ".png";
}
nodesStructure.children.push(structure);
}
//单纯的组
else {
//颠倒一下
node._children.reverse()
queueNodes.push(node._children);
queueNodesIndex[queueIndex] = nodesIndex;
queueNodesIndex.push(0);
queueNodesName.push(nodesName + node.name);
const structure = {
'name': splitArr[0],
'x': node.left - (node.parent ? node.parent.left : 0),
'y': node.top - (node.parent ? node.parent.top : 0),
// 'id': splitArr[2]||,//对于group
'type': "container",
'children': [],
};
if (splitArr[1] == "skin" || splitArr[1] == "item") {//这种情况不该有id
structure.type = "item"
} else if (splitArr[1]) {
structure.id = splitArr[1];
// psdStructure.ids += splitArr[1] + ":FYGE.Container;"
}
nodesStructure.children.push(structure);
queueNodesStructure.push(structure);
continue queueLoop;
}
} else {
//如果单纯作为贴图,只保存,不进入节点
if (splitArr[1] == "tex") {
saveAsPng(groupName, splitArr[0], node)
continue;
}
const structure = {
'name': splitArr[0],
'x': node/*.layer*/.left - (node.parent ? node.parent.left : 0),
'y': node/*.layer*/.top - (node.parent ? node.parent.top : 0),
// 'width': node.layer.width,
// 'height': node.layer.height
// 'alpha': node.layer.opacity / 255,
};
//只有不为1才记录alpha
if (node.layer.opacity < 255) structure.alpha = node.layer.opacity / 255;
//如果是文本
if (node.layer.typeTool) {
structure.type = "text";
const text = node.layer.typeTool();
const sizes = text.sizes();
// if (splitArr[0] == "20%") console.log(sizes)
// var size = sizes && sizes.length > 1 ? sizes[0] || 12 :
// sizes ? (sizes[0] || 24) / 2 : 12
var size = (() => {
if (!sizes || !sizes[0]) return 12;
return sizes[0] * text.transform.yy;
})();
// var size = sizes ? sizes[0] || 12 : 12 //这个psd又是正常的
const colors = text.colors()[0];
structure.props = {
text: text.textValue.replace("\r", "\n"),
size,
fillColor: rgb2String(colors),
textAlpha: colors[3] / 255 || 1,
}
if (splitArr[1]) {
//加入全局,方便复制
// psdStructure.ids += splitArr[1] + ":FYGE.TextField;";
structure.id = splitArr[1];
}
}
//如果是矢量图,考虑是否需要,简单点判断吧
else if (node.layer.solidColor &&
node.layer.vectorMask().paths[2].numPoints == 4 &&
(!node.layer.vectorMask().paths[3] || node.layer.vectorMask().paths[3].recordType == 2)
) {
const { r, g, b } = node.layer.solidColor();
let fillColor = rgb2String([r, g, b]);
structure.type = 'rect';
structure.props = {
width: node.width,
height: node.height,
fillColor
}
if (splitArr[1]) {
structure.id = splitArr[1];
// psdStructure.ids += splitArr[1] + ":FYGE.Graphics;"
}
}
//标记过按钮的
else if (splitArr[1] == "btn") {
structure.type = "button";
structure.props = {
tUp: splitArr[0] + ".png"
}
// structure.source = splitArr[0] + ".png"
if (splitArr[2]) {
structure.id = splitArr[2];
// psdStructure.ids += splitArr[2] + ":FYGE.Button;"
}
saveAsPng(groupName, splitArr[0], node)
}
//保存图片
else {
structure.type = "sprite";
//如果标记过jpg的
if (splitArr[1] == "jpg") {
structure.props = {
source: splitArr[0] + ".jpg"
}
// structure.source = splitArr[0] + ".jpg"
saveAsPng(groupName, splitArr[0], node, "jpg");
if (splitArr[2]) {
structure.id = splitArr[2];
// psdStructure.ids += splitArr[2] + ":FYGE.Sprite;"
}
} else {
structure.props = {
source: splitArr[0] + ".png"
}
// structure.source = splitArr[0] + ".png"
saveAsPng(groupName, splitArr[0], node);
if (splitArr[1]) {
structure.id = splitArr[1];
// psdStructure.ids += splitArr[1] + ":FYGE.Sprite;"
}
}
}
nodesStructure.children.push(structure);
}
}
queueNodes.pop();
queueNodesIndex.pop();
queueNodesName.pop();
queueNodesStructure.pop();
}
//存入root
rootStructure.children.push(psdStructure)
// const outJsonData = JSON.stringify(psdStructure/*.group*/, "", "\t");
//如果需要导出ui数据
// if (options.outJsonDir) {
// const outJsonDirPath = path.resolve(options.outJsonDir + groupName);
// const outJsonPath = path.join(outJsonDirPath, groupName + '.json');
// // make output directory.
// if (!fs.existsSync(outJsonDirPath)) {
// fs.mkdirSync(outJsonDirPath);
// }
// // output file.
// fs.writeFileSync(outJsonPath, outJsonData);
// }
}
}
}
})
//导出所有的数据
if (options.outJsonDir) {
//倒转一下所有children的层级
const outJsonData = JSON.stringify(rootStructure/*.group*/, "", "\t");
const outJsonDirPath = path.resolve(options.outJsonDir);
const outJsonPath = path.join(outJsonDirPath, 'skin.json');
if (!fs.existsSync(outJsonDirPath)) {
fs.mkdirSync(outJsonDirPath);
}
fs.writeFileSync(outJsonPath, outJsonData);
//代码也保存
var endPath = './src/';
var endFile = `export const SkinJson = ${outJsonData}`
fs.writeFileSync(endPath + "SkinJson.ts", endFile);
}
function rgb2String(rgb) {
var hex = ((rgb[0] << 16) + (rgb[1] << 8) + (rgb[2] | 0));
hex = hex.toString(16);
hex = '000000'.substr(0, 6 - hex.length) + hex;
return `#${hex}`;
}
/**
*
* @param {string} dirName 文件夹名字
* @param {string} name 图片名称
* @param {*} node
* @param {*} format 保存图片格式,默认png
*/
function saveAsPng(dirName, name, node, format = "png") {
const outImgDirPath = options.outImgDir + dirName;
// mkdirp.sync(outImgDirPath);
if (!fs.existsSync(outImgDirPath)) fs.mkdirSync(outImgDirPath);
console.log('保存图片:' + name + '.' + format);
//保存成图片
node.layer.image.saveAsPng(path.join(outImgDirPath, name + '.' + format));
}
var fs = require("fs");
var PSD = require('psd');
var path = require('path');
// const mkdirp = require('mkdirp');
//千万别再执行,否则覆盖
// return
//取指令后的参数
let arg = process.argv.splice(2);
//psd文件名字
var psdName = arg[0];
var options = {
//导出图片的目录,没有就导在psd所在目录,单视图处理都先进psd,
outImgDir: "./psd/",
//导出Json的目录,没有就不导出,单视图处理都先进psd,剩下的自己复制,为了不影响原皮肤数据
outJsonDir: "./psd/",
}
//psd文件所在文件夹目录
var pathName = "./psd";
//只输出一个数据,就算多个psd,也按照每个psd的第一级进入root的children
var rootStructure = {
'x': 0,
'y': 0,
'type': "container",
'children': []
}
const psdFile = pathName + "/" + psdName + ".psd";
const psdFilePath = path.resolve(psdFile);
// var pathInfo = path.parse(psdFile);
const psdData = PSD.fromFile(psdFilePath);//open(异步),fromDroppedFile(异步,拖入文件),fromFile
psdData.parse();
const rootNode = psdData.tree();
//按照第一层的进行分组导出
for (let i = 0; i < rootNode._children.length; i++) {
//一个组,比如开始页面,游戏页面等
const group111 = rootNode._children[i]
const queueNodes = [];
const queueNodesIndex = [];
const queueNodesName = [];
const queueNodesStructure = [];
//如果不是组,直接导common文件夹
if (!group111._children || !group111._children.length) {
saveAsPng("common", group111.name, group111)
} else {
const groupName = rootNode._children[i].name;
//颠倒一下
group111._children.reverse()
queueNodes.push(group111._children);
queueNodesIndex.push(0);
queueNodesName.push(undefined);
//首层的容器默认都是0,0,所以他的left和top修改下
group111.left = group111.top = 0;
const psdStructure = {
// 'ids': "",
"name": groupName,
'x': 0,
'y': 0,
'type': "container",
'children': []
};
queueNodesStructure.push(psdStructure);
queueLoop: while (0 < queueNodes.length) {
const queueIndex = queueNodes.length - 1;
const nodes = queueNodes[queueIndex];
const nodesStructure = queueNodesStructure[queueIndex];
let nodesIndex = queueNodesIndex[queueIndex];
let nodesName = queueNodesName[queueIndex];
if (nodesName === undefined) {
nodesName = '';
} else {
nodesName += path.sep;
}
while (nodesIndex < nodes.length) {
const node = nodes[nodesIndex];
nodesIndex++;
// if (node.layer.visible === false) continue;
//分割一下
const splitArr = node.name.split("_");
if (node.type === 'group') {
//如果是按钮的组,就单纯按钮的三种贴图,第一个是正常,第二个是无法点击,第三个down
if (splitArr[1] == "btn") {
const structure = {
'name': splitArr[0],
'x': node.left - (node.parent ? node.parent.left : 0),
'y': node.top - (node.parent ? node.parent.top : 0),
'type': "button",
};
structure.props = {}
// structure.source = splitArr[0] + ".png"
if (splitArr[2]) {
structure.id = splitArr[2];
// psdStructure.ids += splitArr[2] + ":FYGE.Button;"
}
saveAsPng(groupName, node._children[0].name, node._children[0]);
structure.props.tUp = node._children[0].name + ".png";
if (node._children[1]) {
saveAsPng(groupName, node._children[1].name, node._children[1]);
structure.props.tDisable = node._children[1].name + ".png";
}
if (node._children[2]) {
saveAsPng(groupName, node._children[2].name, node._children[2]);
structure.props.tDown = node._children[2].name + ".png";
}
nodesStructure.children.push(structure);
}
//单纯的组
else {
//颠倒一下
node._children.reverse()
queueNodes.push(node._children);
queueNodesIndex[queueIndex] = nodesIndex;
queueNodesIndex.push(0);
queueNodesName.push(nodesName + node.name);
const structure = {
'name': splitArr[0],
'x': node.left - (node.parent ? node.parent.left : 0),
'y': node.top - (node.parent ? node.parent.top : 0),
// 'id': splitArr[2]||,//对于group
'type': "container",
'children': [],
};
if (splitArr[1] == "skin" || splitArr[1] == "item") {//这种情况不该有id,但是貌似没法集合id了
structure.type = "item"
} else if (splitArr[1]) {
structure.id = splitArr[1];
// psdStructure.ids += splitArr[1] + ":FYGE.Container;"
}
nodesStructure.children.push(structure);
queueNodesStructure.push(structure);
continue queueLoop;
}
} else {
//如果单纯作为贴图,只保存,不进入节点
if (splitArr[1] == "tex") {
saveAsPng(groupName, splitArr[0], node)
continue;
}
const structure = {
'name': splitArr[0],
'x': node/*.layer*/.left - (node.parent ? node.parent.left : 0),
'y': node/*.layer*/.top - (node.parent ? node.parent.top : 0),
// 'width': node.layer.width,
// 'height': node.layer.height
// 'alpha': node.layer.opacity / 255,
};
//只有不为1才记录alpha
if (node.layer.opacity < 255) structure.alpha = node.layer.opacity / 255;
//如果是文本
if (node.layer.typeTool) {
structure.type = "text";
const text = node.layer.typeTool();
const sizes = text.sizes();
// if (splitArr[0] == "20%") console.log(sizes)
// var size = sizes && sizes.length > 1 ? sizes[0] || 12 :
// sizes ? (sizes[0] || 24) / 2 : 12
var size = (() => {
if (!sizes || !sizes[0]) return 12;
return sizes[0] * text.transform.yy;
})();
// var size = sizes ? sizes[0] || 12 : 12 //这个psd又是正常的
const colors = text.colors()[0];
structure.props = {
text: text.textValue.replace("\r", "\n"),
size,
fillColor: rgb2String(colors),
textAlpha: colors[3] / 255 || 1,
}
if (splitArr[1]) {
//加入全局,方便复制
// psdStructure.ids += splitArr[1] + ":FYGE.TextField;";
structure.id = splitArr[1];
}
}
//如果是矢量图,考虑是否需要,简单点判断吧
else if (node.layer.solidColor &&
node.layer.vectorMask().paths[2].numPoints == 4 &&
(!node.layer.vectorMask().paths[3] || node.layer.vectorMask().paths[3].recordType == 2)
) {
const { r, g, b } = node.layer.solidColor();
let fillColor = rgb2String([r, g, b]);
structure.type = 'rect';
structure.props = {
width: node.width,
height: node.height,
fillColor
}
if (splitArr[1]) {
structure.id = splitArr[1];
// psdStructure.ids += splitArr[1] + ":FYGE.Graphics;"
}
}
//标记过按钮的
else if (splitArr[1] == "btn") {
structure.type = "button";
structure.props = {
tUp: splitArr[0] + ".png"
}
// structure.source = splitArr[0] + ".png"
if (splitArr[2]) {
structure.id = splitArr[2];
// psdStructure.ids += splitArr[2] + ":FYGE.Button;"
}
saveAsPng(groupName, splitArr[0], node)
}
//保存图片
else {
structure.type = "sprite";
//如果标记过jpg的
if (splitArr[1] == "jpg") {
structure.props = {
source: splitArr[0] + ".jpg"
}
// structure.source = splitArr[0] + ".jpg"
saveAsPng(groupName, splitArr[0], node, "jpg");
if (splitArr[2]) {
structure.id = splitArr[2];
// psdStructure.ids += splitArr[2] + ":FYGE.Sprite;"
}
} else {
structure.props = {
source: splitArr[0] + ".png"
}
// structure.source = splitArr[0] + ".png"
saveAsPng(groupName, splitArr[0], node);
if (splitArr[1]) {
structure.id = splitArr[1];
// psdStructure.ids += splitArr[1] + ":FYGE.Sprite;"
}
}
}
nodesStructure.children.push(structure);
}
}
queueNodes.pop();
queueNodesIndex.pop();
queueNodesName.pop();
queueNodesStructure.pop();
}
//存入root
rootStructure.children.push(psdStructure)
// const outJsonData = JSON.stringify(psdStructure/*.group*/, "", "\t");
//如果需要导出ui数据
// if (options.outJsonDir) {
// const outJsonDirPath = path.resolve(options.outJsonDir + groupName);
// const outJsonPath = path.join(outJsonDirPath, groupName + '.json');
// // make output directory.
// if (!fs.existsSync(outJsonDirPath)) {
// fs.mkdirSync(outJsonDirPath);
// }
// // output file.
// fs.writeFileSync(outJsonPath, outJsonData);
// }
}
}
//导出所有的数据
if (options.outJsonDir) {
//倒转一下所有children的层级
const outJsonData = JSON.stringify(rootStructure/*.group*/, "", "\t");
const outJsonDirPath = path.resolve(options.outJsonDir);
const outJsonPath = path.join(outJsonDirPath, 'skin.json');
if (!fs.existsSync(outJsonDirPath)) {
fs.mkdirSync(outJsonDirPath);
}
fs.writeFileSync(outJsonPath, outJsonData);
//代码也保存
// var endPath = './src/';
// var endFile = `export const SkinJson = ${outJsonData}`
// fs.writeFileSync(endPath + "SkinJson.ts", endFile);
}
function rgb2String(rgb) {
var hex = ((rgb[0] << 16) + (rgb[1] << 8) + (rgb[2] | 0));
hex = hex.toString(16);
hex = '000000'.substr(0, 6 - hex.length) + hex;
return `#${hex}`;
}
/**
*
* @param {string} dirName 文件夹名字
* @param {string} name 图片名称
* @param {*} node
* @param {*} format 保存图片格式,默认png
*/
function saveAsPng(dirName, name, node, format = "png") {
const outImgDirPath = options.outImgDir + dirName;
// mkdirp.sync(outImgDirPath);
if (!fs.existsSync(outImgDirPath)) fs.mkdirSync(outImgDirPath);
console.log('保存图片:' + name + '.' + format);
//保存成图片
node.layer.image.saveAsPng(path.join(outImgDirPath, name + '.' + format));
}
const fs = require("fs");
const exec = require('child_process').exec;
const del = require('del');
const join = require('path').join;
// const packTextures = require("pack_textures");
//写入图集的文件夹
const outPath = "./released/resource/";
//读取散图的文件夹
const readPath = "./released/tm/";
const files = fs.readdirSync(readPath);
files.forEach(function (file) {
//路径
let fPath = join(readPath, file);
//只处理文件夹
if (fs.statSync(fPath).isDirectory()) {
//判断文件夹内是否有图片
if (!judgeHasImage(fPath)) return;
//如果文件夹不存在
if (!fs.existsSync(outPath + file)) {
fs.mkdirSync(outPath + file);
} else {
//图集文件存在就删除
if (fs.existsSync(outPath + file + "/" + file + ".json")) {
del(outPath + file + "/" + file + ".json")
}
if (fs.existsSync(outPath + file + "/" + file + ".png")) {
del(outPath + file + "/" + file + ".png")
}
}
// packTextures(
// fPath,
// outPath + file + "/" + file,
// 4096,
// 4096,
// false,
// 2,
// 2,
// true,
// true
// )
//全局命令装过,就直接用命令行
exec(
'packTextures' + //基础指令
' -i ' + fPath + //要合图集的文件夹路径
' -o ' + outPath + file + "/" + file + //输出路径及名字
' --mw ' + 4096 + //最大宽度
' --mh ' + 4096 +//最大高度
' -p ' + false + //长宽是否2的指数,canvas下没必要,false
' --sp ' + 2 + //图片间隔
' --bp ' + 2 + //边界间隔
' -r ' + true + //是否允许图片旋转
' -t ' + true //是否允许裁切图片边缘透明像素
,
{ encoding: 'utf8' },
(e) => {
if (e) return console.log(e);
console.log("生成图集:" + file);
}
)
}
})
/**
* 判断文件夹内是否有图片
* @param {*} path
*/
function judgeHasImage(path) {
const files = fs.readdirSync(path);
for (let i = 0; i < files.length; i++) {
const itm = files[i];
const stat = fs.statSync(path + "/" + itm);
if (stat.isDirectory()) {
//递归读取文件
if (judgeHasImage(path + "/" + itm + "/")) return true;
} else {
if (itm.substr(-4) === ".jpg" || itm.substr(-4) === ".png") return true;
}
}
return false;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
const fs = require('fs');
const path = require('path');
const co = require('co');
const OSS = require('ali-oss');
const chalk = require('chalk');
const ProgressBar = require('progress');
const iconv = require('iconv-lite');
const colors = require("colors");
const config = require("../project.json");
class TuiaAutoUpload {
constructor(props, type) {
this.type = type;
const defaultOptions = {
dir: undefined,
originDir: undefined
}
this.options = Object.assign({}, defaultOptions, props);
if (!this.options.dir || !this.options.originDir) {
console.log(chalk.red('缺少参数,初始化失败'))
return;
}
this.init();
}
init() {
const _this = this;
this.client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: 'LTAI5tLEo6SbjfmNPmH7Mz3o',
accessKeySecret: '8yZ6nVMg56DEupEEMRl6rz1DcpG2R7',
bucket: _this.type === 'prod' ? 'duiba' : 'daily-duiba'
});
this.bar = new ProgressBar(chalk.yellow(` 文件上传中 [:bar] :current/${this.files().length} :percent :elapseds`), {
complete: '●',
incomplete: '○',
width: 20,
total: this.files().length,
callback: () => {
console.log(chalk.green('\n All complete.'));
console.log(chalk.blue(`\n 本次队列文件共${this.files().length}个,已存在文件${this.existFiles}个,上传文件${this.uploadFiles}个,上传失败文件${this.errorFiles}个\n`));
}
})
return this;
}
files() {
const _this = this;
if (this._files) return this._files;
this._files = [];
/**
* 文件遍历方法
* @param filePath 需要遍历的文件路径
*/
function fileDisplay(filePath) {
//根据文件路径读取文件,返回文件列表
const files = fs.readdirSync(filePath);
files.forEach(function (filename) {
//获取当前文件的绝对路径
const filedir = path.join(filePath, filename);
//根据文件路径获取文件信息,返回一个fs.Stats对象
const stats = fs.statSync(filedir);
const isFile = stats.isFile();//是文件
const isDir = stats.isDirectory();//是文件夹
if (isFile) {
let sep = '/';
if ('win32' === process.platform)
sep = '\\';
const newDirArr = filedir.split(sep);
newDirArr.shift();
_this._files.push(newDirArr.join('/'));
}
if (isDir) {
fileDisplay(filedir);//递归,如果是文件夹,就继续遍历该文件夹下面的文件
}
});
}
//调用文件遍历方法
fileDisplay(this.options.dir);
return this._files;
}
start() {
this.files().map((file) => {
let _this = this;
const path1 = path.join(path.resolve(__dirname, '..'), 'released', file);
let originFile;
this.existFiles = 0;
this.uploadFiles = 0;
this.errorFiles = 0;
co(function* () {
const originPath = `${_this.options.originDir}${file}`;
try {
originFile = yield _this.client.head(originPath);
} catch (error) {
originFile = error;
}
if (_this.type === 'prod') {
if (originFile.status === 404) {
yield _this.client.put(originPath, path1);
_this.uploadFiles += 1;
} else {
_this.existFiles += 1;
}
} else if (_this.type === 'dev') {
if (originFile.status === 404 || originFile.status === 200) {
_this.existFiles += 1;
}
yield _this.client.put(originPath, path1, {
headers: {
'Cache-Control': 'no-cache'
}
})
_this.uploadFiles += 1;
}
_this.bar.tick();
}).catch(function (err) {
_this.errorFiles += 1;
console.log(err);
});
});
}
}
if (!config.type) {
throw new Error(`project.json 的type不存在.`);
}
if (!config.name) {
throw new Error(`project.json 的name不存在.`);
}
const now = new Date();
const version = Math.round(now.getTime() / 1000);
console.log(colors.bgMagenta(`资源版本号:\n${version}`));
const autoupload = new TuiaAutoUpload({
dir: './released/',
originDir: `/db_games/${config.type}/${config.name}/${version}/`
}, "prod");
autoupload.start();
const readPath = "./released/resource/";
// 读取json文件
let data = iconv.decode(fs.readFileSync(readPath + "res.json"), "utf-8");// GBK
// 反序列化
data = JSON.parse(data);
data.path = `https://yun.duiba.com.cn/db_games/${config.type}/${config.name}/${version}/resource/`;
// 写入目标文件夹,可配置,每个项目必须修改,或者直接和project的保持一致(淘宝项目文件固定后)
const endPath = './src/';
const endFile = `export const ResJson = ${JSON.stringify(data, "", "\t")}`;
fs.writeFileSync(endPath + "ResJson.ts", endFile);
const co = require('co');
const OSS = require('ali-oss');
const config = require("../project.json");
const colors = require("colors");
//只打包js时,自执行上传
uploadSingleJs();
function uploadSingleJs(url) {
if (!url) {//不传的时候
if (!config.type) {
throw new Error(`project.json 的type不存在.`)
}
if (!config.name) {
throw new Error(`project.json 的name不存在.`)
}
const now = new Date();
const version = Math.round(now.getTime() / 1000);
url = `${config.type}/${config.name}/${version}`;
require("./createHtml")(`${config.type}/${config.name}/${version}`);
console.log(colors.bgGreen(`版本号:\n${version}`));
}
const client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: 'LTAI4Fw25WcfcGv7FvcHoiHK',
accessKeySecret: 'NZk1NtT9J5HFaAolNbtQdzTzLLvLYm',
bucket: 'duiba'
});
//单js文件上传
co(function* () {
const originPath = `/db_games/${url}/output.js`;
let originFile;
try {
originFile = yield client.head(originPath);
} catch (error) {
originFile = error;
}
if (originFile.status === 404)
yield client.put(originPath, "./released/output.js");
});
//js.map
co(function* () {
const originPath = `/db_games/${url}/map_123_map/output.js.map`;
var originFile;
try {
originFile = yield client.head(originPath);
} catch (error) {
originFile = error;
}
if (originFile.status === 404)
yield client.put(originPath, "./released/output.js.map");
});
}
module.exports = uploadSingleJs
var readline = require('readline');//node上有,不为了锁版本,可以不用安装
/**
* 提醒脚本
* @param {string} msg 提示信息
* @param {Function} resolve yes回调
* @param {Function} reject no回调
*/
function warn(msg, resolve, reject) {
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(msg + "[y/n]", function (answer) {
switch (answer) {
case 'y':
case 'Y':
case 'yes':
case 'YES':
resolve && resolve();
// 不加close,则不会结束
rl.close();
break;
case 'n':
case 'N':
case 'no':
case 'NO':
default:
reject && reject();
rl.close();
break;
}
});
}
module.exports = warn
export default class Clock {
startTime = 0;
oldTime = 0;
elapsedTime = 0;
running = false;
constructor(
public autoStart = true
) {
}
start() {
this.startTime = (typeof performance === 'undefined' ? Date : performance).now();
this.oldTime = this.startTime;
this.elapsedTime = 0;
this.running = true;
}
stop() {
this.getElapsedTime();
this.running = false;
this.autoStart = false;
}
getElapsedTime() {
this.getDelta();
return this.elapsedTime;
}
getDelta() {
let diff = 0;
if (this.autoStart && !this.running) {
this.start();
return 0;
}
if (this.running) {
const newTime = (typeof performance === 'undefined' ? Date : performance).now();
diff = (newTime - this.oldTime) / 1000;
this.oldTime = newTime;
this.elapsedTime += diff;
}
return diff;
}
}
import { ajax, jsonp } from "../module/ajax"
import { showToast } from "../module/ctrls"
import { duiba_md5 } from "../module/tools/security"
//////////补给站用到的接口集成
//部分情况需要,比如duiba_md5,需跳转下载的
// <script crossorigin="anonymous" src="//yun.duiba.com.cn/db_games/libs/zepto_security_downloadApp.min.js"></script>
/**
* 获取基本信息
*/
export function ajaxElement(): Promise<{ success: boolean, data?: any }> {
return new Promise((r) => {
ajax({
url: "/hdtool/recon/ajaxElement", //请求地址
type: "GET",//"POST", //请求方式
data: {
duibaId: window['CFG'].hdToolId,
activityId: window['CFG'].actId,
}, //请求参数
dataType: "json", // 返回值类型的设定,暂时只有json
async: true, //是否异步
// headers: headers,
success: function (res) {
if (!res.success) showToast(res.desc || "网络异常,请稍后再试")
r(res)
},
error: function (status) {
showToast("网络异常,请稍后再试")
r({ success: false })
},
})
})
}
/**
* 参与游戏
*/
export function doJoin(): Promise<{ success: boolean, data?: any }> {
return new Promise(async (r) => {
//获取token
var token = await getTokenHdtool();
if (!token) {//如果没有token
showToast("token获取失败")
r({ success: false })
return
}
ajax({
url: "/hdtool/recon/doJoin",
type: "GET",//"POST", //请求方式
data: {
token,
activityId: window['CFG'].actId,
activityType: "hdtool",
consumerId: window['CFG'].consumerId
}, //请求参数
dataType: "json", // 返回值类型的设定,暂时只有json
async: true, //是否异步
// headers: headers,
success: function (res) {
if (!res.success) showToast(res.desc || "网络异常,请稍后再试")
r(res)
},
error: function (status) {
showToast("网络异常,请稍后再试")
r({ success: false })
},
})
})
}
/**
* 开始游戏轮询
* @param orderId doJoin返回的数据中的data字段
*/
export function getNgameStartStatus(orderId): Promise<any> {
let count = 0;
return new Promise((resolve) => {
(async function ask(r) {
const data = await getN(orderId);
if (data.code == "0000000000") {
r(data);
} else {
//超过10次的话,提示下
if (++count >= 10) {
showToast("获取开始游戏信息失败\n请稍后重试")
r({ success: false })
return
}
setTimeout(() => { ask(r) }, 500)
}
})(resolve)
})
}
function getN(orderId): Promise<{ success: boolean, data?: any, code?: string }> {
return new Promise((r) => {
ajax({
url: "/hdtool/recon/ngame/getNgameStartStatus",
type: "GET",//"POST", //请求方式
data: {
orderId,
}, //请求参数
dataType: "json", // 返回值类型的设定,暂时只有json
async: true, //是否异步
// headers: headers,
success: function (res) {
r(res)
},
error: function (status) {
r({ success: false })
},
})
})
}
/**
*
* @param orderId doJoin里的数据data字段
* @param score 分数可能传1
* @param submitToken 轮询数据里的data.submitToken
*/
export function submit(orderId: string, score: number, submitToken: string): Promise<{ success: boolean, data?: any }> {
let gameData = "[]";
// let sgin = window['duiba_md5'](orderId + '' + score + '' + gameData + '' + submitToken);
let sgin = duiba_md5(orderId + '' + score + '' + gameData + '' + submitToken);
let dynamicData = JSON.stringify(`{t2:${new Date().getTime()}}`);
const param: any = {
orderId,
score,
gameData,
sgin,
dynamicData
};
return new Promise((r) => {
ajax({
url: "/hdtool/recon/ngame/ngameSubmit",
type: "POST", //请求方式
data: param, //请求参数
dataType: "json", // 返回值类型的设定,暂时只有json
async: true, //是否异步
// headers: headers,
success: function (res) {
if (!res.success) showToast(res.desc || "网络异常,请稍后再试")
r(res)
},
error: function (status) {
showToast("网络异常,正在重试中")
r({ success: false })
},
})
})
}
/**
* 获取奖品信息,这里面的data.element用于更新ajaxElement,要轮询
* @param orderId doJoin里的数据data字段
*/
export function getOrderStatus(orderId): Promise<{ success: boolean, data?: any }> {
let count = 0;
return new Promise((resolve) => {
(async function ask(r) {
const data = await getO(orderId);
if (data.code == "0000000000") {
r(data);
} else {
//超过10次的话,提示下
if (++count >= 10) {
showToast("获取开始游戏信息失败\n请稍后重试")
r({ success: false })
return
}
setTimeout(() => { ask(r) }, 500)
}
})(resolve)
})
}
function getO(orderId): Promise<{ success: boolean, data?: any, code?: string }> {
return new Promise((r) => {
ajax({
url: "/hdtool/recon/getOrderStatus", //请求地址
type: "GET",//"POST", //请求方式
data: {
orderId
}, //请求参数
dataType: "json", // 返回值类型的设定,暂时只有json
async: true, //是否异步
// headers: headers,
success: function (res) {
r(res)
},
error: function (status) {
r({ success: false })
},
})
})
}
/**
* 补给站获取token
*/
function getTokenHdtool(): Promise<string> {
return new Promise((r) => {
if (window.location.port == "8080") {//本地开发
r("token")
} else {
if (!window['getDuibaToken']) {
r(null);
} else {
window['getDuibaToken']((tokenObj) => {
r(tokenObj.token);
}, (key, messageObj) => {
r(null);
});
}
}
})
}
/**
* 获取我的奖品链接,老活动工具 window.location.href = getRecordUrl('00');
* @param type
* @param ids
*/
export function getRecordUrl(type: '00', ids?) {
let recordUrl;
let oaId;
oaId = window["CFG"].oaId;
recordUrl = window["CFG"].recordUrl;
if (!ids) {
ids = [oaId];
}
let i = 0;
const len = ids.length;
for (i; i < len; i++) {
if (window.location.href.indexOf("?") == -1) {
recordUrl += '?origins=' + ids[i] + type;
} else {
recordUrl += '&origins=' + ids[i] + type;
}
}
return recordUrl;
}
/**
* 补给站埋点
* @param type
* @param area
*/
export function sendLogBuji(type: 'exposure' | 'click', area: number) {
var appId = window["CFG"].appId;
var oaId = window["CFG"].oaId;
var dpm = appId + '.' + 263 + '.' + area + '.' + 1;//怎么拼按具体需求
var dcm = 202 + '.' + oaId + '.0.0';//怎么拼按具体需求
let params: any = {
dpm,
dcm,
appId,
consumerId: window["CFG"].consumerId,
domain: '//embedlog.duiba.com.cn'
};
let isExposure = (type == "exposure");
if (isExposure) {
jsonp('//embedlog.duiba.com.cn/exposure/standard', params);
} else {
jsonp('/log/click', params);
}
}
//补给站老活动会用到
window["CFG"] = {
actId: '143212468677481',
oaId: '143212468677481',
unitName: '猫币',
btnUnitName: '猫币',
doJoin: '/hdtool/doJoin?dpm=1.3.1.0&activityId=143212468677481',
quireOrder: '/hdtool/getOrderStatus',
styleConfig: '/hdtool/getHdtoolConfig',
getElement: '/hdtool/ajaxElement',
getPrizeDetail: '/hdtool/prizeDetail',
ajaxThroughInfo: '/hdtool/ajaxThroughInfo',
throughSubmit: '/hdtool/throughSubmit',
gameGetOrder: '/hdtool/getOrderInfo',//游戏获取订单信息接口
gameSubmit: '/hdtool/gameSubmit',//游戏结果提交接口
doSubmit: '/hdtool/submit',
adslotId: '',
consumerId: '1',
isNotLoginUser: false,
uid: '1',
hdType: 'duiba',
hdToolId: '43743',
appType: 'credits',
subType: 'lotteryMachine',
directSendCoupon: 'false',
ajaxAction: '',
recommendQueue: '/recommend/getRecommend',
recommendSkin: '/recommend/getRecommendSkin',
isShowDetail: true,
preview: false,
from: '',
login: '//activity.m.duiba.com.cn/hdtool/login?dpm=1.3.3.0',
flowRedirectUrl: '',
flowRedirectTuiaUrl: '',
isOpenRecommend: false,
getCreditsLink: 'mxsa://magicshop/cointask?uid=1&dbnewopen',
appId: '1',
recordUrl: '//activity.m.duiba.com.cn/crecord/record?dbnewopen&dpm=1.3.2.0',
shareDesc: '分享分享文案文案',
entranceDesc: '测试领奖,也可到我的奖品领奖哦!!!',
isSHowMeat: true,
needCouponModal: true, // 给前端用,判断是否需要使用配置的优惠券弹窗
needRecommendModal: true, // 给前端用,判断是否需要公用推荐位弹窗
asyncFiles: [], // 给前端用,异步加载的文件
shareAndroidLinkActivity: 'http://www.baidu.com',
shareIosLinkActivity: 'http://www.iqiyi.com'
};
import { layers, destroyLayers } from "../module/views/layers";
import { RES } from "../module/RES";
import { changeScene, destroyAllCtrls, showToast } from "../module/ctrls";
import { G_EVENT } from "./common/G_EVENT";
import { IndexScene } from "./scenes/IndexScene";
import MusicBtn from "./scenes/Jump3D/MusicBtn";
import { ResJson } from "./ResJson";
import { SkinJson } from "./SkinJson";
import { destroyTbNetData } from "./TaoBaoNet";
import { Tools } from "./Tools";
import { destroyWebNetData } from "./WebNet";
import Tween = FYGE.Tween;
import EventDispatcher = FYGE.EventDispatcher;
import Stage = FYGE.Stage;
import RENDERER_TYPE = FYGE.RENDERER_TYPE;
import Event = FYGE.Event;
import getEnv = FYGE.getEnv;
import Texture = FYGE.Texture;
/**
* 全局事件,为了和小程序交互
* 有可能多处页面用到,所以单开
*/
export const GDispatcher = new EventDispatcher();
export class Main {
//主舞台
stage: Stage;
private requestID;
private _pause: boolean;
private canvas: HTMLCanvasElement;
constructor(canvas: HTMLCanvasElement) {
let sysInfo;
//淘宝小程序环境就用canvas初始化
if (!window) {//自行处理吧,这么判断也不保险,万一淘宝小程序加进了window
FYGE.initedByCanvas(canvas)//里面会设置env为tb,这个很重要
//@ts-ignore 存在my就初始化
sysInfo = my.getSystemInfoSync()
}
//建舞台
const stage = this.stage = new FYGE.Stage(
canvas,//canvas标签
750,//设计宽度,按设计搞给的就行
1624,//设计高度
sysInfo && sysInfo.windowWidth || document.body.clientWidth, //显示宽度,全屏就是屏幕宽度
sysInfo && sysInfo.windowHeight || document.body.clientHeight,//显示高度,全屏就是屏幕高度
RENDERER_TYPE.WEBGL,//渲染模式canvas
true, //视窗居中裁切
false,//不定高,定宽适配
sysInfo && sysInfo.pixelRatio || window.devicePixelRatio || 1,//分辨率
{ antialias: true }
);
this.canvas = canvas; // 赋值下,为了下面的destroy的cancelAnimationFrame
//stage初始化
stage.addEventListener(Event.INIT_STAGE, this.onAddToStage, this);
//循环
this.loop();
}
private loop = () => {
if (!this._pause) {
Tween.flush();
this.stage.flush();
}
// @ts-ignore
getEnv() == "tb" ? this.requestID = this.canvas.requestAnimationFrame(this.loop) :
this.requestID = window.requestAnimationFrame(this.loop);
}
private async onAddToStage() {
//初始化层级
layers.init(this.stage);
console.log("初始化层级完成");
//初始化资源配置
RES.loadConfig(ResJson);
console.log("初始化资源配置完成");
//皮肤配置加载
RES.loadSkinConfig(SkinJson);
console.log("初始化皮肤配置完成");
//加载通用资源
await RES.loadGroup("common");
console.log("通用资源加载完成");
// h5环境时,隐藏加载中
if (getEnv() == "web" && document.getElementById("__loading__")) {
document.getElementById("__loading__").style.display = "none";
}
await Tools.getGlobalData();
const baseSuccess = await Tools.getActivityBaseInfo();
const defaultImage = "https://yun.duiba.com.cn/aurora/assets/79e467e771f01e98fb1b6b7daa3cfeecb8584617.png";
await RES.getResAsync(Tools.activityBaseInfo.showImage || defaultImage);
if (!baseSuccess) {
showToast("获取活动信息失败");
return;
}
const gameSuccess = await Tools.getGameInfo();
if (!gameSuccess) {
showToast("获取游戏信息失败");
return;
}
Tools.checkPermission();
await Promise.all([
Texture.fromUrl("https://yun.duiba.com.cn/aurora/assets/923bcdee2d54f39797fb1cc5a79ab84da1bbe972.jpg"),
Texture.fromUrl("https://yun.duiba.com.cn/aurora/assets/92856abbb6293e863708fa2c0ea3556cf9b2afaa.jpg"),
Texture.fromUrl("https://yun.duiba.com.cn/aurora/assets/d660b9e12c66ad2c42fca23c57bf33db5009fedf.jpg"),
Texture.fromUrl("https://yun.duiba.com.cn/aurora/assets/a6903842083d8015e2e81d2dc652370574be6774.jpg"),
]);
MusicBtn.changeMusicStatus(true); /// TODO 进游戏打开音乐先
changeScene(IndexScene, { from: "main" });
}
run() {
this._pause = false;
// @ts-ignore Tween计时清零
Tween._lastTime = null;
// 触发onShow
GDispatcher.dispatchEvent({ type: G_EVENT.ON_SHOW });
}
/**
* 在小程序隐藏时调用onHide
*/
pause() {
// this._pause = true;//先不暂停了
// 触发onHide
GDispatcher.dispatchEvent({ type: G_EVENT.ON_HIDE });
}
/**
* 添加全局事件,用于小程序的交互调用
* 一直很犹豫要不要放在main的实例里,还是和Main同级导出,还有上面的pause,run,下面的事件等
* @param name
* @param fun
* @param thisObj
* @param once
*/
addGlobalEvent(name: string, fun: Function, thisObj?: any, once: boolean = false) {
if (once) {
GDispatcher.once(name, fun, thisObj)
} else {
GDispatcher.addEventListener(name, fun, thisObj)
}
}
/**
* 派发全局事件,用于小程序的交互调用
* @param name 可以是事件名,也可以是事件
* @param data
*/
dispatchGlobalEvent(name: string | any, data?: any) {
GDispatcher.dispatchEvent(name, data)
}
/**
* 移除全局事件,用于小程序交互调用
* @param name
* @param fun
* @param thisObj
*/
removeGlobalEvent(name: string, fun: Function, thisObj?: any) {
GDispatcher.removeEventListener(name, fun, thisObj)
}
//在小程序页面卸载时调用onUnload,多次销毁后会有问题,再检查
destroy() {
// Tween都移除,注意吧,可能原先的也被移除,对于多page时注意,会把其他页面的也去掉
Tween.removeAllTweens();
// 停掉计时器
// @ts-ignore 为了兼容多page的canvas
FYGE.getEnv() == "tb" ? this.canvas.cancelAnimationFrame(this.requestID) :
window.cancelAnimationFrame(this.requestID);
// 层级销毁
destroyLayers();
// 销毁控制器
destroyAllCtrls();
// 舞台销毁
this.stage.destroy();
// 全局事件置空
GDispatcher.removeAllEventListener();
// //淘宝环境网络数据记录清
// destroyTbNetData();
//
// // 网络数据记录清空
// destroyWebNetData();
}
}
export const ResJson = {
"groups": [
{
"keys": "helpBg.png,helpBtn.png",
"name": "HelpPanel",
"atlas": {
"helpBg.png": {
"x": 2,
"y": 2,
"w": 581,
"h": 547,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 547,
"ro": false
},
"helpBtn.png": {
"x": 2,
"y": 551,
"w": 418,
"h": 102,
"ox": 0,
"oy": 0,
"sw": 418,
"sh": 102,
"ro": false
}
}
},
{
"keys": "5cab5037-81fc-4246-96e5-b1353f339275.png,7458bc9a-d07d-4a7c-972b-4de7ed7c040d.png,7e4500a1-83be-4686-a46b-67147ed44ddd.png,845ae874-998e-4f68-8e79-641eb77466f3.png,a122de8a-beed-4442-9252-8c047986f371.png,ad9681a6-9eb2-40ad-8c2c-0b3ad121a00d.png,b48ee079-b3d7-4371-b294-944200eccba9.png,cd1a775d-36c9-4c8e-9c67-8191070068e9.png",
"name": "LoadingEffect",
"atlas": {
"5cab5037-81fc-4246-96e5-b1353f339275.png": {
"x": 2,
"y": 2,
"w": 516,
"h": 108,
"ox": 0,
"oy": 0,
"sw": 516,
"sh": 108,
"ro": false
},
"b48ee079-b3d7-4371-b294-944200eccba9.png": {
"x": 2,
"y": 112,
"w": 137,
"h": 74,
"ox": 0,
"oy": 0,
"sw": 137,
"sh": 74,
"ro": false
},
"a122de8a-beed-4442-9252-8c047986f371.png": {
"x": 141,
"y": 112,
"w": 134,
"h": 24,
"ox": 0,
"oy": 0,
"sw": 134,
"sh": 24,
"ro": false
},
"cd1a775d-36c9-4c8e-9c67-8191070068e9.png": {
"x": 2,
"y": 188,
"w": 123,
"h": 104,
"ox": 0,
"oy": 0,
"sw": 123,
"sh": 104,
"ro": false
},
"7458bc9a-d07d-4a7c-972b-4de7ed7c040d.png": {
"x": 127,
"y": 188,
"w": 48,
"h": 30,
"ox": 0,
"oy": 0,
"sw": 48,
"sh": 30,
"ro": true
},
"ad9681a6-9eb2-40ad-8c2c-0b3ad121a00d.png": {
"x": 141,
"y": 138,
"w": 23,
"h": 36,
"ox": 0,
"oy": 0,
"sw": 23,
"sh": 36,
"ro": false
},
"845ae874-998e-4f68-8e79-641eb77466f3.png": {
"x": 127,
"y": 238,
"w": 24,
"h": 25,
"ox": 0,
"oy": 0,
"sw": 24,
"sh": 25,
"ro": false
},
"7e4500a1-83be-4686-a46b-67147ed44ddd.png": {
"x": 141,
"y": 176,
"w": 5,
"h": 6,
"ox": 0,
"oy": 0,
"sw": 5,
"sh": 6,
"ro": false
}
}
},
{
"keys": "noTimeBg.png,noTimeBtn.png",
"name": "NoTimePanel",
"atlas": {
"noTimeBg.png": {
"x": 2,
"y": 2,
"w": 581,
"h": 547,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 547,
"ro": false
},
"noTimeBtn.png": {
"x": 2,
"y": 551,
"w": 418,
"h": 102,
"ox": 0,
"oy": 0,
"sw": 418,
"sh": 102,
"ro": false
}
}
},
{
"keys": "overBtn.png,overNoPrizeBg.png,overPrizeBg.png",
"name": "OverPanel",
"atlas": {
"overPrizeBg.png": {
"x": 2,
"y": 2,
"w": 581,
"h": 843,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 843,
"ro": false
},
"overNoPrizeBg.png": {
"x": 585,
"y": 2,
"w": 581,
"h": 577,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 577,
"ro": true
},
"overBtn.png": {
"x": 585,
"y": 585,
"w": 418,
"h": 102,
"ox": 0,
"oy": 0,
"sw": 418,
"sh": 102,
"ro": false
}
}
},
{
"keys": "rankBg.png,rankIcon.png",
"name": "RankPanel",
"atlas": {
"rankBg.png": {
"x": 2,
"y": 2,
"w": 581,
"h": 944,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 944,
"ro": false
},
"rankIcon.png": {
"x": 585,
"y": 2,
"w": 34,
"h": 42,
"ox": 0,
"oy": 0,
"sw": 34,
"sh": 42,
"ro": false
}
}
},
{
"keys": "rankNoPrizeBg.png,rankNoPrizeBtn.png,rankPrizeBg.png,rankPrizeBtn.png",
"name": "RankPrizePanel",
"atlas": {
"rankPrizeBg.png": {
"x": 2,
"y": 2,
"w": 581,
"h": 717,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 717,
"ro": false
},
"rankNoPrizeBg.png": {
"x": 585,
"y": 2,
"w": 581,
"h": 546,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 546,
"ro": true
},
"rankNoPrizeBtn.png": {
"x": 585,
"y": 585,
"w": 418,
"h": 102,
"ox": 0,
"oy": 0,
"sw": 418,
"sh": 102,
"ro": false
},
"rankPrizeBtn.png": {
"x": 2,
"y": 721,
"w": 418,
"h": 102,
"ox": 0,
"oy": 0,
"sw": 418,
"sh": 102,
"ro": false
}
}
},
{
"keys": "reviveBg.png,reviveCancel.png,reviveOk.png",
"name": "RevivePanel",
"atlas": {
"reviveBg.png": {
"x": 2,
"y": 2,
"w": 581,
"h": 508,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 508,
"ro": false
},
"reviveOk.png": {
"x": 2,
"y": 512,
"w": 233,
"h": 89,
"ox": 0,
"oy": 0,
"sw": 233,
"sh": 89,
"ro": false
},
"reviveCancel.png": {
"x": 237,
"y": 512,
"w": 224,
"h": 85,
"ox": 0,
"oy": 0,
"sw": 224,
"sh": 85,
"ro": false
}
}
},
{
"keys": "rulePanelBg.png,rulePanelBtn.png",
"name": "RulePanel",
"atlas": {
"rulePanelBg.png": {
"x": 2,
"y": 2,
"w": 581,
"h": 717,
"ox": 0,
"oy": 0,
"sw": 581,
"sh": 717,
"ro": false
},
"rulePanelBtn.png": {
"x": 585,
"y": 2,
"w": 418,
"h": 102,
"ox": 0,
"oy": 0,
"sw": 418,
"sh": 102,
"ro": true
}
}
},
{
"keys": "comCloseBtn.png,com_bg.jpg,toastBg.png,waitingBg.png,waitingRot.png",
"name": "common",
"atlas": {
"toastBg.png": {
"x": 2,
"y": 2,
"w": 460,
"h": 130,
"ox": 0,
"oy": 0,
"sw": 460,
"sh": 130,
"ro": false
},
"waitingBg.png": {
"x": 2,
"y": 134,
"w": 160,
"h": 180,
"ox": 0,
"oy": 0,
"sw": 160,
"sh": 180,
"ro": true
},
"comCloseBtn.png": {
"x": 184,
"y": 134,
"w": 58,
"h": 58,
"ox": 0,
"oy": 0,
"sw": 58,
"sh": 58,
"ro": false
},
"waitingRot.png": {
"x": 184,
"y": 194,
"w": 56,
"h": 56,
"ox": 0,
"oy": 0,
"sw": 56,
"sh": 56,
"ro": false
}
}
},
{
"keys": "gameMusicOff.png,gameMusicOn.png,gameScore+.png,gameScore0.png,gameScore1.png,gameScore2.png,gameScore3.png,gameScore4.png,gameScore5.png,gameScore6.png,gameScore7.png,gameScore8.png,gameScore9.png,guide.png",
"name": "game",
"atlas": {
"guide.png": {
"x": 2,
"y": 2,
"w": 320,
"h": 416,
"ox": 0,
"oy": 0,
"sw": 320,
"sh": 416,
"ro": false
},
"gameMusicOff.png": {
"x": 324,
"y": 2,
"w": 82,
"h": 82,
"ox": 0,
"oy": 0,
"sw": 82,
"sh": 82,
"ro": false
},
"gameMusicOn.png": {
"x": 324,
"y": 86,
"w": 82,
"h": 82,
"ox": 0,
"oy": 0,
"sw": 82,
"sh": 82,
"ro": false
},
"gameScore0.png": {
"x": 324,
"y": 170,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": true
},
"gameScore1.png": {
"x": 324,
"y": 216,
"w": 28,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 32,
"sh": 56,
"ro": true
},
"gameScore2.png": {
"x": 324,
"y": 246,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": true
},
"gameScore3.png": {
"x": 324,
"y": 292,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": true
},
"gameScore4.png": {
"x": 324,
"y": 338,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 48,
"sh": 56,
"ro": false
},
"gameScore5.png": {
"x": 408,
"y": 2,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": false
},
"gameScore6.png": {
"x": 408,
"y": 60,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": false
},
"gameScore7.png": {
"x": 408,
"y": 118,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": false
},
"gameScore8.png": {
"x": 382,
"y": 176,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": true
},
"gameScore9.png": {
"x": 382,
"y": 222,
"w": 44,
"h": 56,
"ox": 2,
"oy": 0,
"sw": 47,
"sh": 56,
"ro": true
},
"gameScore+.png": {
"x": 382,
"y": 268,
"w": 42,
"h": 40,
"ox": 2,
"oy": 8,
"sw": 46,
"sh": 56,
"ro": false
}
}
},
{
"keys": "btnTipBg.png,prizeBtn.png,progressBg.png,progressFill.png,progressLabel.png,rankBtn.png,ruleBtn.png,startBtn.png,taskBtn.png",
"name": "index",
"atlas": {
"progressBg.png": {
"x": 2,
"y": 2,
"w": 750,
"h": 188,
"ox": 0,
"oy": 0,
"sw": 750,
"sh": 188,
"ro": false
},
"progressFill.png": {
"x": 2,
"y": 192,
"w": 615,
"h": 20,
"ox": 0,
"oy": 0,
"sw": 615,
"sh": 20,
"ro": false
},
"startBtn.png": {
"x": 2,
"y": 214,
"w": 490,
"h": 111,
"ox": 0,
"oy": 0,
"sw": 490,
"sh": 111,
"ro": false
},
"prizeBtn.png": {
"x": 494,
"y": 214,
"w": 153,
"h": 51,
"ox": 0,
"oy": 0,
"sw": 153,
"sh": 51,
"ro": false
},
"taskBtn.png": {
"x": 494,
"y": 267,
"w": 151,
"h": 51,
"ox": 0,
"oy": 0,
"sw": 151,
"sh": 51,
"ro": false
},
"btnTipBg.png": {
"x": 2,
"y": 327,
"w": 147,
"h": 36,
"ox": 0,
"oy": 0,
"sw": 147,
"sh": 36,
"ro": false
},
"ruleBtn.png": {
"x": 649,
"y": 192,
"w": 102,
"h": 42,
"ox": 0,
"oy": 0,
"sw": 102,
"sh": 42,
"ro": false
},
"rankBtn.png": {
"x": 494,
"y": 320,
"w": 98,
"h": 43,
"ox": 0,
"oy": 0,
"sw": 98,
"sh": 43,
"ro": false
},
"progressLabel.png": {
"x": 151,
"y": 327,
"w": 87,
"h": 31,
"ox": 0,
"oy": 0,
"sw": 87,
"sh": 31,
"ro": false
}
}
},
{
"keys": "loading_effect.png,loading_title.png",
"name": "loading",
"atlas": {
"loading_effect.png": {
"x": 2,
"y": 2,
"w": 665,
"h": 121,
"ox": 0,
"oy": 0,
"sw": 665,
"sh": 121,
"ro": false
},
"loading_title.png": {
"x": 2,
"y": 125,
"w": 531,
"h": 146,
"ox": 0,
"oy": 0,
"sw": 531,
"sh": 146,
"ro": false
}
}
}
],
"path": "https://yun.duiba.com.cn/db_games/activity/template/1653467733/resource/"
}
\ No newline at end of file
export const SkinJson = {
"x": 0,
"y": 0,
"type": "container",
"children": []
}
import { showToast } from "../module/ctrls";
import { GDispatcher } from "./Main";
//接口枚举,包括需要调用淘宝的api,用是否含有兑吧区分,或者单独区分
export enum TbNetName {
/**
* 埋点统计
* activityId type
*/
addData = "surge.addStat",
/**
* 活动基本信息
* activityId
*/
getActivityBaseInfoById = "feileJump.getActivityBaseInfoById",
getGameInfo = "feileJump.getGameInfo",
startGame = "feileJump.startGame",
doHelp = "feileJump.doHelp",
getVipInfo = "feileJump.getVipInfo",
submitGame = "feileJump.submitGame",
continueGame = "feileJump.continueGame",
getRankList = "feileJump.getRankList",
getPrizeList = "feileJump.getPrizeList",
getRankRewards = "feileJump.getRankRewards",
getMyRankPrize = "feileJump.getMyRankPrize",
receiveEnamePrize = "feileJump.receiveEnamePrize",
openMember = "mine.openMember",
openTask = "mine.openTask",
///////////////////前端调用接口都加个mine,下面这些基本固定的不修改,对应小程序那边的逻辑抽空整理下
////带用户操作,和index.js特殊操作的
/**
* 用户授权
*/
authorize = 'mine.authorize',
/**
* 关注店铺
*/
favorShop = "mine.favorShop",
/**
* 获取用户地址及确认
* prizeId
*/
getUserAddress = "mine.getUserAddress",
/**
* 获取名字
* type
*/
getAdoptName = "mine.getAdoptName",
///////////////////////////基本都是前端同步方法
/**
* 获取参数
*/
getAppData = "mine.getAppData",
/**
* 小程序内跳到其他页面
* url
*/
navigateToOutside = "mine.navigateToOutside",
/**
* 跳转到小程序的其他页面
* url
*/
navigateTo = "mine.navigateTo",
/**
* 返回上一页或多页
* delta,页面数,不传默认1
*/
navigateBack = "mine.navigateBack",
/**
* 分享面板
* openId
*/
showSharePanel = "mine.showSharePanel",
/**
* 打开详情页
* itemId
*/
openDetail = "mine.openDetail",
/**
* 自定义埋点
* logkey
*/
reportAnalytics = "mine.reportAnalytics",
/**
* 打开音频
* isOn
*/
openMusic = "mine.openMusic",
}
//返回数据类型
interface dataOut {
success: boolean,
data?: any
code?: string,
message?: string
}
//记录数据
let dataRecord: {
[name: string]: any
} = {};
/**
* 发送接口
* @param netName
* @param parameter
* @param callback
* @param hideMsg
*/
export function sendTbNet(
netName: TbNetName,
parameter?: any,
callback?: (success: boolean, res?: dataOut) => void,
hideMsg: boolean = false
): Promise<dataOut> {
return new Promise((resolve, reject) => {
//网络超时
// let waitObj;
//@ts-ignore 本地开发,直接取数据
if (!my) {
const netInfo = netName.split(".");
const url = `../../mock/miniTb/${netInfo[0]}/${netInfo[1]}.json`;
fetchAsync(url)
.then((data) => {
//清除超时
// clearWait(waitObj)
//记录数据
dataRecord[netName] = data;
//统一错误信息提示
if (!hideMsg && !data.success) showToast(data.message || "网络异常")
//回调
callback && callback(data.success, data);
resolve(data)
console.log(
`\n%c[ mock ]\n`
+ `NAME : ${netName} \n`
+ `STATE : %o \n`
+ `PARAM : %o \n`
+ `%cDATA : %o \n`
, `${data.success ? 'color:green' : 'color:red'}`
, data.success
, parameter
, `${data.success ? 'color:green' : 'color:red'}`
, data
);
}, () => {
resolve({ success: false, data: null });
})
return
}
let fun = function (e: { type: string, data: dataOut }) {
//清除超时记录
// clearWait(waitObj)
//移除事件
GDispatcher.removeEventListener(netName, fun);
var d = e.data;
//记录数据
dataRecord[netName] = d;
//统一错误信息提示,d.data为了区分网络超时
if (!hideMsg && !d.success) showToast(d.message || "网络超时")
//执行回调
callback && callback(d.success, d);
resolve(d)
console.log(
`\n%c[ request ]\n`
+ `NAME : ${netName} \n`
+ `STATE : %o \n`
+ `PARAM : %o \n`
+ `%cDATA : %o \n`
, `${d.success ? 'color:green' : 'color:red'}`
, d.success
, parameter
, `${d.success ? 'color:green' : 'color:red'}`
, d
);
}
//添加事件接收接口返回信息
GDispatcher.addEventListener(netName, fun);
//用事件方式吧,派发事件发接口,,,,注意很多独有的事件名别重了,onHide,onShow,onMessage等 放到最后,因为有同步的情况
GDispatcher.dispatchEvent({ type: "onMessage" }, { netName, parameter })
})
}
export function addData(type) {
sendTbNet(
TbNetName.addData,
{ type },
null,
true,
);
}
/**
* 获取数据
* @param netName
*/
export function getTbData(netName: TbNetName): dataOut {
return dataRecord[netName] || null;
}
//销毁数据
export function destroyTbNetData() {
dataRecord = {}
}
async function fetchAsync(url: string) {
// await response of fetch call
let response = await fetch(url);
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
return data;
}
/**
* 曝光埋点枚举
* 自定义,注意淘宝控制台也需要相应配置
*/
export enum LogTbEnum {
AD = "ad",
TASK_ICON = 'taskIcon',
FOLLOW_SHOP = 'followShop',
INVITE_FRIEND = 'inviteFriend',
BROWSE_PRODUCT = 'browseProduct',
COLLECTION_PRODUCT = 'collectionProduct',
BUY_PRODUCT = 'buyProduct',
IMPROVE_INFORMATION = 'improveInformation',
SECRET_ORDER = 'secretOrder',
SIGN_ICON = 'signIcon',
BAG_ICON = 'bagIcon',
}
/**
* 淘宝小程序点击埋点,自定义字段,
* @param elemType
*/
export function clickLogTb(elemType: LogTbEnum) {
//TODO确定参数
sendTbNet(TbNetName.addData, { params: { elemType }, type: "click" }, () => {
}, true)
//淘宝自定义埋点
sendTbNet(TbNetName.reportAnalytics, { logkey: elemType }, () => {
}, true)
}
//上面的可以也可以搞曝光的,反正都是手动
// export function showLog(elemType: string) {
// sendTbNet(TbNetName.trackingReport, { params: { elemType }, type: "exposure" }, () => { }, true)
// //淘宝自定义埋点
// sendTbNet(TbNetName.reportAnalytics, { logkey: elemType }, () => { }, true)
// }
/**
* 询问安卓淘宝加载权限,
* @param tryCloudUrl
*/
export async function checkTbDownloadPermission(tryCloudUrl: string) {
var tbMy;
try {//判断my是否有声明,万一引擎里去掉了my的声明,其他地方就要改成try的方式,或者用getEnv判断
//@ts-ignore
tbMy = my;
} catch (err) {
}
if (!tbMy) return;
//@ts-ignore
const { cloud } = getApp();
//测试地址//到时云存储传一个小json,,改路径
var url = tryCloudUrl//"cloud://B4F0300E5148F478B506DEDC26EA4C6C//butterfly0.svga";
//获取临时地址
var urls = await cloud.file.getTempFileURL({ fileId: [url] })
url = urls[0].url.replace('-internal', '');
tbMy.downloadFile({
url: url,
success(res) {
var i = res.apFilePath;
tbMy.getFileSystemManager().readFile({
filePath: i,
// encoding: "utf8",
success: function (r) {
},
fail: function (res) {
}
})
},
fail(res) {
},
});
}
/**
* 获取淘宝服务器时间,获取失败会直接用Date.now()
* @returns {number} 服务器时间戳
*/
export const getTbServerTime = (): Promise<number> => {
return new Promise((resolve, reject) => {
if (FYGE.getEnv() == "tb") {
// @ts-ignore
my.getServerTime({
success: (res) => {
resolve(+res.time);
},
fail: err => {
resolve(Date.now());//失败就返回当前时间
}
});
} else {
resolve(Date.now());
}
});
};
//淘宝奖品类型,可能会变
export enum TBPRIZE_TYPE {
ENAME = 1,
CREDITS = 2,
OBJECT = 3,
THANKS = 5
}
import { sendTbNet, TbNetName } from "./TaoBaoNet";
// @ts-ignore
const app = getApp();
export default class TbFunc {
/**
* 赠送卡给好友
* @param {{type: "invite", openId: string} | {type: "gift", cardId: string}} data
* @return {Promise<void>}
*/
static async showSharePanel(data: { type: "invite", openId: string, } | { type: "gift", cardId: string, cardType: 1 | 2 | 3 | 4 }) {
await sendTbNet(TbNetName.showSharePanel, data);
}
/**
* 打开入会插件
* @return {Promise<void>}
*/
static async openMember() {
return await sendTbNet(TbNetName.openMember);
}
/**
* 关注店铺
* @return {Promise<void>}
*/
static async favorShop() {
return await sendTbNet(TbNetName.favorShop, null, null, true);
}
/**
* 检查会员,要在app上挂checkMember方法
* @return {Promise<boolean>}
*/
static async checkMember() {
// @ts-ignore
return app.checkMember();
}
/**
* 打开任务
* @return {Promise<void>}
*/
static async showTask() {
await sendTbNet(TbNetName.openTask);
}
/**
* 去我的奖品
*/
static goMyPrize() {
// @ts-ignore
my && my.navigateTo({
url: '/pages/myPrize/myPrize'
});
}
/******************* 转接my方法 *******************/
static navigateBack() {
// @ts-ignore
my && my.navigateBack();
}
static navigateTo(url) {
// @ts-ignore
my && my.navigateTo({ url });
}
static alert(title, content) {
// @ts-ignore
my && my.alert({
title,
content
});
}
static navigateToOutside(url) {
// @ts-ignore
my && my.navigateToOutside({ url });
}
static saveImg(url: string) {
//@ts-ignore
if (my) {
//@ts-ignore
my.saveImage({
url: url,
showActionSheet: true,
success: () => {
//@ts-ignore
my.alert({
title: '保存成功',
});
},
});
}
}
}
import { RES } from "../module/RES";
import { layers } from "../module/views/layers";
import { sendTbNet, TbNetName } from "./TaoBaoNet";
import Container = FYGE.Container;
import TEXT_ALIGN = FYGE.TEXT_ALIGN;
import TextField = FYGE.TextField;
import Texture = FYGE.Texture;
import Tween = FYGE.Tween;
export function goMyPrize() {
sendTbNet(
TbNetName.navigateTo,
{ url: '/pages/myprize/myprize' },
null,
true
);
}
export function goTask() {
sendTbNet(TbNetName.openTask);
}
/**
* 定制,记录一些全局量和通用方法
*/
export class Tools {
/**
* 缓存key
*/
static cacheKey: string = "cow_xiaobujian"
/**
* 全局数据,重要数据
*/
public static globalData: {
"avatar": string,
"nickName": string,
"activityId": string,
"openId": string,
"inviteId": string,
"isFollow": boolean
"newUser": boolean
}
public static async getGlobalData() {
const { data } = await sendTbNet(TbNetName.getAppData);
Tools.globalData = data;
}
static indexMask = {}
/**
* activityBaseInfo
* @member openId openId
* @member rule 规则
* @member startTime 开始时间
* @member endTime 结束时间
* @member activityStatus 1 活动未开始 2 活动进行 3 活动结束
* @member totalScore 活动当前总分数
* @member showImage 展示图片地址
*/
public static activityBaseInfo: {
openId: string,
rule: string,
startTime: number,
endTime: number,
activityStatus: 1 | 2 | 3,
openPrizeStatus: 1 | 2 | 3,
totalScore: number,
showImage: string,
} = {
openId: "",
rule: "",
startTime: 0,
endTime: 0,
activityStatus: 1,
openPrizeStatus: 1,
totalScore: 0,
showImage: "https://yun.duiba.com.cn/aurora/assets/a2f9da458cc425df5b4428a1fe902606ea5dc4fd.jpg",
}
public static async getActivityBaseInfo() {
const { success, data } = await sendTbNet(TbNetName.getActivityBaseInfoById);
if (data) {
Tools.activityBaseInfo = data;
}
return success;
}
public static gameInfo: {
score: number,
gameTimes: number,
isFirstEnterGame: boolean
} = {
score: 0,
gameTimes: 0,
isFirstEnterGame: false
}
public static async getGameInfo() {
const { success, data } = await sendTbNet(TbNetName.getGameInfo);
if (data) {
Tools.gameInfo = data;
}
return success;
}
public static async queryVip() {
const { success, data } = await sendTbNet(TbNetName.getVipInfo);
return success && data.isVip;
}
/**
* 询问权限用
*/
public static async checkPermission() {
//@ts-ignore
var tbMy = my
if (!tbMy) return;
if (FYGE.osType == "ios") return;
//@ts-ignore
const { cloud } = getApp();
//测试地址//到时云存储传一个小json,,改路径
var url = "cloud://8105858AA48FED3F15CB94186ED0D5E7//feileJump.doHelp.json";
//获取临时地址
var urls = await cloud.file.getTempFileURL({ fileId: [url] })
url = urls[0].url.replace('-internal', '');
tbMy.downloadFile({
url: url,
success(res) {
var i = res.apFilePath;
tbMy.getFileSystemManager().readFile({
filePath: i,
// encoding: "utf8",
success: function (r) {
},
fail: function (res) {
}
})
},
fail(res) {
},
});
}
/************ 其他 ************/
/**
* 修改皮肤上的文本对齐方式,原先默认是左的,多汗行的时候计算有误,待查
* @param text
* @param align
* @param textWidth
*/
static changeTextAlign(text: TextField, align: TEXT_ALIGN, textWidth?: number) {
if (align == TEXT_ALIGN.LEFT) return;
text.textAlign = align;
//没有就原先的
textWidth = textWidth || text.textWidth;
//修改位置
if (align == TEXT_ALIGN.CENTER) text.x -= (textWidth - text.textWidth) / 2;
if (align == TEXT_ALIGN.RIGHT) text.x -= textWidth - text.textWidth
text.textWidth = textWidth;
}
/**
* 延时防连点
* @param target
* @param {number} delay 默认2000毫秒
*/
static btnDelay(target: Container, delay: number = 2000) {
target.mouseEnable = false;
target.mouseChildren = false;
setTimeout(() => {
target.mouseEnable = true;
target.mouseChildren = true;
}, delay);
}
/**
* 根据名字获取0到9的贴图
* 位图字每次都写太烦了
* @param name
*/
static getNumTextures(name: string): { [key: number]: Texture } {
const arr = {};
for (let i = 0; i <= 9; i++) arr[i] = RES.getRes(name + i + ".png")
return arr
}
/**
* 获得距离底部的百分比高度,还要减个自身的高度,自行处理
* @param {number} percent 百分比
* @returns {number}
*/
static getAdjustBottomHeight(percent: number): number {
return layers.stageHeight - layers.stageHeight * percent + layers.stageOffsetY;//stageOffsetY加不加取决于页面适配类型
}
/**
* 获得距离顶部的百分比高度
* @param {number} percent 百分比
* @returns {number}
*/
static getAdjustTopHeight(percent: number): number {
return layers.stageHeight * percent + layers.stageOffsetY;//stageOffsetY加不加取决于页面适配类型
}
}
/**
* 从数组里随机取元素
* @param arr
* @param count
*/
export function getRandomArrayElements(arr, count) {
if (arr.length <= count) return arr;
let shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
while (i-- > min) {
index = (i + 1) * Math.random() >> 0;
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
return shuffled.slice(min);
}
/**
* 数字补0
* @param num 数字
* @param length 位数
*/
export function prefixInteger(num: number, length: number) {
return (Array(length).join('0') + num).slice(-length);
}
export function numLimit(num: number, min: number, max: number): number {
if (num > max) return max;
else if (num < min) return min;
return num;
}
export async function sleep(time: number): Promise<void> {
return new Promise((resolve) => {
Tween.get(FYGE)
.wait(time)
.call(resolve)
});
}
/*
* UI.ts
* Created by 还有醋v on 2021/5/12.
* Copyright © 2021 haiyoucuv. All rights reserved.
*/
import { RES } from "../module/RES";
import Container = FYGE.Container;
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
import Sprite = FYGE.Sprite;
import TEXT_ALIGN = FYGE.TEXT_ALIGN;
import TextField = FYGE.TextField;
import Shape = FYGE.Shape;
import Lottie = FYGE.Lottie;
import Texture = FYGE.Texture;
import Graphics = FYGE.Graphics;
import BitmapText = FYGE.BitmapText;
export default class UI {
/**
* 按钮
* @param {FYGE.Container} parent
* @param {string} enImg
* @param {Function} func
* @param that
* @param {number} x
* @param {number} y
* @param {number} anchorX
* @param {number} anchorY
* @param {string} tImg
* @param {string} disImg
* @returns {FYGE.Button}
* @constructor
*/
static Btn(
parent: Container,
enImg: string,
func: Function,
that,
x: number = 0, y: number = 0,
anchorX?: number, anchorY?: number,
tImg: string = enImg, disImg: string = enImg
): Button {
const btn = new Button(RES.getRes(enImg), RES.getRes(tImg), RES.getRes(disImg));
btn.addEventListener(MouseEvent.CLICK, func, that);
btn.position.set(x, y);
anchorX !== undefined && (btn.anchorX = anchorX);
anchorY !== undefined && (btn.anchorY = anchorY);
parent && parent.addChild(btn);
return btn;
}
/**
* 图片
* @param {FYGE.Container} parent
* @param {string} imageName
* @param {number} x
* @param {number} y
* @returns {FYGE.Sprite}
* @constructor
*/
public static Sp(
parent: Container,
imageName: string | Texture,
x: number = 0, y: number = 0
): Sprite {
let sprite;
if (imageName instanceof Texture) {
sprite = new Sprite(imageName);
} else {
const texture = RES.getRes(imageName);
if (texture) {
sprite = new Sprite(texture);
} else {
sprite = Sprite.fromUrl(imageName);
}
}
sprite.position.set(x, y);
parent && parent.addChild(sprite);
return sprite;
}
/**
* Container
* @param {Container} parent
* @param {number} x
* @param {number} y
* @returns {Container}
* @constructor
*/
public static Ctn(
parent: Container,
x: number = 0, y: number = 0
): Container {
const ctn = new Container();
ctn.position.set(x, y);
ctn && parent.addChild(ctn);
return ctn;
}
/**
* 文本
* @param {FYGE.Container} parent
* @param {string} txt
* @param {number} size
* @param {string} color
* @param {FYGE.TEXT_ALIGN} align
* @param {number} textWidth
* @param {number} x
* @param {number} y
* @param bold
* @returns {FYGE.TextField}
*/
public static Txt(
parent: Container,
txt: string,
size: number,
color: string = "#000000",
align: TEXT_ALIGN = TEXT_ALIGN.LEFT,
textWidth: number = 0,
x: number = 0,
y: number = 0,
bold: boolean = false
): TextField {
const text = new TextField();
text.fillColor = color;
text.size = size;
textWidth && (text.textWidth = textWidth);
text.textAlign = align;
text.position.set(x, y);
text.text = txt;
text.bold = bold
parent && parent.addChild(text);
return text;
}
public static Rect(
parent: Container,
width: number,
height: number,
color: number = 0xff0000,
radius: number = 0,
x: number = 0,
y: number = 0,
alpha: number = 1,
): Shape {
const shape = new Shape();
// shape.clear();
shape.beginFill(color);
if (!radius) {
shape.drawRect(0, 0, width, height);
} else {
shape.drawRoundedRect(0, 0, width, height, radius);
}
shape.endFill();
shape.alpha = alpha;
shape.position.set(x, y);
parent && parent.addChild(shape);
return shape;
}
public static Lottie(parent: Container, data: any, x: number = 0, y: number = 0) {
const lottie = new Lottie(data);
lottie.x = x
lottie.y = y
parent && parent.addChild(lottie);
return lottie;
}
public static Shape(
parent: Container,
x: number = 0, y: number = 0
): Shape {
const shape = new Shape();
shape.position.set(x, y);
parent && parent.addChild(shape);
return shape;
}
public static Graphics(
parent: Container,
x: number = 0, y: number = 0
): Graphics {
const graphics = new Graphics();
graphics.position.set(x, y);
parent && parent.addChild(graphics);
return graphics;
}
public static BitTxt(
parent: Container,
texture: { [key: string]: Texture },
text: string = "",
x: number = 0,
y: number = 0,
scaleX: number = 1,
scaleY: number = 1,
gap = 0
): BitmapText {
const bitTxt = new BitmapText(texture);
bitTxt.position.set(x, y);
bitTxt.scale.set(scaleX, scaleY);
bitTxt.text = text;
bitTxt.gap = gap;
parent && parent.addChild(bitTxt);
return bitTxt;
}
}
import { showToast } from "../module/ctrls";
import { ajax, jsonp } from "../module/ajax";
import { GDispatcher } from "./Main";
import { getUrlParams } from "../module/tools/WebTool";
//////////////星速台接口方法集成
/**
* web接口枚举,mock 文件名类似aaa/homeInfo.do
*/
export enum WebNetName {
/**
* 首页
* 参数a 参数b
*/
index = "/projectx/{projectId}/game/index.do",
/**
* 参与
*/
join = "/projectx/{projectId}/game/join.do",
/**
* 获取结果
*/
queryResult = "/projectx/{projectId}/game/queryResult.do",
/**
* 获取规则
*/
projectRule = "/projectx/{projectId}/projectRule.query"
}
//返回数据类型
interface dataOut {
success: boolean,
data?: any
code?: string,
message?: string
}
//记录数据
let dataRecord: {
[name: string]: any
} = {};
/**
* 发送接口
* @param netName
* @param parameter
* @param callback
* @param hideMsg
* @param isGet
* @param headers
*/
export function sendWebNet(
netName: WebNetName,
parameter?: any,
callback?: (success: boolean, res?: dataOut) => void,
hideMsg: boolean = false,
isGet: boolean = true,//这两个参数基本不设置,放后面吧
headers?: any,
): Promise<dataOut> {
return new Promise((resolve, reject) => {
if (window.location.port == "8080") { // window.location.port == "8080";考虑按端口判断 TODO
let path = netName.split('{projectId}/')[1];//后缀名字之前的是文件夹,mock里结构
if (path.indexOf('/') <= -1) path = `projectX/${path}`;
const url = "../../mock/webNet/" + path + ".json";
fetchAsync(url)
.then((data) => {
//清除超时
// clearWait(waitObj)
//记录数据
dataRecord[netName] = data;
//统一错误信息提示
if (!hideMsg && !data.success) showToast(data.message || "网络异常")
//回调
callback && callback(data.success, data);
resolve(data)
console.log(
`\n%c[ mock ]\n`
+ `NAME : ${netName} \n`
+ `STATE : %o \n`
+ `PARAM : %o \n`
+ `%cDATA : %o \n`
, `${data.success ? 'color:green' : 'color:red'}`
, data.success
, parameter
, `${data.success ? 'color:green' : 'color:red'}`
, data
);
}, () => {
})
return
}
//网络请求
ajax({
url: netName.replace("{projectId}", getProjectId()), //请求地址
type: isGet ? 'GET' : "POST", //请求方式
data: parameter || {}, //请求参数
dataType: "json", // 返回值类型的设定,暂时只有json
async: true, //是否异步
headers: headers,
success: function (response) {
//发现有些接口成功了,但是response为空
response = response || {}
//记录数据
dataRecord[netName] = response;
//统一错误信息提示,
if (!hideMsg && !response.success) {
showToast(response.message || "网络异常")
}
callback && callback(response.success, response)
resolve(response)
console.log(
`\n%c[ request ]\n`
+ `NAME : ${netName} \n`
+ `STATE : %o \n`
+ `PARAM : %o \n`
+ `%cDATA : %o \n`
, `${response.success ? 'color:green' : 'color:red'}`
, response.success
, parameter
, `${response.success ? 'color:green' : 'color:red'}`
, response
);
},
error: function (status) {
if (!hideMsg) showToast("网络超时");
callback && callback(false)
resolve({ success: false });
console.log("接口" + netName + ":网络超时");
},
})
})
}
/**
* 获取数据
* @param netName
*/
export function getWebData(netName: WebNetName): dataOut {
return dataRecord[netName] || null;
}
//销毁数据
export function destroyWebNetData() {
dataRecord = {}
}
async function fetchAsync(url: string) {
// await response of fetch call
let response = await fetch(url);
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
return data;
}
const projectxString = "projectx/";
let projectId: string;
/**
* 获取链接上的projectId
*/
export function getProjectId(): string {
if (projectId) return projectId;
let windowUrl = window.location.href;
let splitArr = windowUrl.split(projectxString);
if (splitArr.length != 2) {
return projectId = "projectId"
}
let start = windowUrl.indexOf(projectxString) + projectxString.length;
let end = splitArr[1].indexOf("/");
return projectId = windowUrl.substr(start, end);
}
//这个临时,如星速台链接有变,注意
var isProd = location.href.indexOf(".com.cn/projectx") >= 0;
/**
* 刷新星速台tokenkey,注意多活动跳转手动执行一边
* @param callback
*/
export function refreshPxTokenKey(callback?: (success: boolean) => void) {
if (isProd) {//线上
var head = document.getElementsByTagName("head")[0];
const scriptEl = document.createElement('script');
scriptEl.src = "getTokenKey?_=" + Date.now();
scriptEl.onload = function () {
head.removeChild(scriptEl);
callback && callback(true)
};
scriptEl.onerror = function () {
head.removeChild(scriptEl);
callback && callback(false)
};
head.appendChild(scriptEl);
} else {//本地环境
callback && callback(true)
}
}
//执行一次
refreshPxTokenKey();
/**
* 获取星速台token
* @param callback
*/
export function getPxToken(callback: (msg: string, token?: string) => void) {
if (!isProd) {//本地环境
callback(null, "token")
return
}
if (!window["ohjaiohdf"]) {
callback("need reload")
return
}
var xml = new XMLHttpRequest;
xml.open("get", "getToken?_t=" + Date.now(), !0);
xml.onreadystatechange = function () {
if (xml.readyState === 4 && xml.status === 200) {
var e = JSON.parse(xml.response);
if (e.success) {
window.eval(e.data);
callback(null, window["ohjaiohdf"]());
} else {
var msg = (() => {
switch (e.code) {
case "100001":
return "need login"
case "100024":
return "state invalid"
default:
return e.code
}
})();
callback(msg);
}
}
}
xml.onerror = function () {
callback("net error")
};
xml.onloadend = function () {
xml.status === 404 && callback("net error")
};
xml.send()
}
export enum LOG_TYPE {
EXPOSURE = 'exposure',
CLICK = 'click',
}
/**
* 埋点 sendLog(LOG_TYPE.EXPOSURE,"4")
* 注意点击埋点前必有曝光埋点
* @param type
* @param data
*/
export function sendLog(type: LOG_TYPE | 'exposure' | 'click', area: number) {
const projectID = getProjectId();
const appID = getUrlParams("appID");
//给个提示
if (!appID) console.error("appID不存在,检查链接")
var dpm = `${appID || 'appID'}.110.${area}.1`;// TODO appID注意默认写死一个,已防链接没有
var dcm = `202.${projectID || 'projectID'}.0.0`;
//看需求
// var dom = `${isWxClient() ? '2' : '1'}.0.0.0`;
let params: any = {
dpm,
dcm,
appId: appID
};
//看需求
// if (dom) params.dom = dom;
let isExposure = (type == LOG_TYPE.EXPOSURE);
if (isExposure) {
//曝光
jsonp('//embedlog.duiba.com.cn/exposure/standard', params);
} else {
//点击
jsonp('/log/click', params);
}
// console.log('try log', {type, ...params});
}
/**
* 根据规则id获取奖品列表
* @param strategyId 规则id
* @param optionId 不传表示返回所有奖品
*/
export function queryPrizeList(strategyId: string, optionId?: string): Promise<dataOut> {
let url = `/projectx/${getProjectId()}/${strategyId}.query`;
return new Promise((resolve) => {
if (window.location.port == "8080") {//本地环境
resolve({//自定义数据。暂时这样
"success": true,
"message": "consequat ea",
"data": [
{
"prizeType": "dolore culpa in tempor",
"name": "ka3",
"refType": "Excepteur adipisicing sint",
"icon": "//yun.duiba.com.cn/spark/assets/58184d8d965c556b412026acf7a5d5d9e7a975f5.png",
"index": "Ut in pariatur",
"id": "et",
"refId": "minim culpa veniam aliqua ut",
"prizeId": "aa",
"icon2": "aliquip consectetur laborum Duis"
}
],
"code": "fugiat velit in esse aute"
})
} else {
ajax({
url,
type: 'GET',
data: optionId ? { optionId } : {},
dataType: "json",
async: true,
success: function (response) {
resolve(response)
},
error: function () {
resolve({ success: false })
}
})
}
})
}
////////////webview通信的范例,小程序端的是天猫精灵的例子
//天猫的webview数据请求方式 webview和小程序通讯方式,别忘了html上加sdk
//<script type="text/javascript" src="https://appx/web-view.min.js"></script>
export enum TmallNetName {
getAppData = "mine.getAppData",
/**
* 监听声音类型
*/
getVoiceType = "mine.getVoiceType",
}
//淘宝小程序全局
const my = window["my"];
if (FYGE.getEnv() == "web" && my) {//小程序webview时
//接收数据
my.onMessage = function (e) {
console.log("返回数据", e.netName, e.data)
//记录数据
// data[e.netName] = e.data;
//触发事件,会考虑单独发过来的事件
GDispatcher.dispatchEvent(e.netName, e.data)
}
}
export function sendTmallNet(
netName: TmallNetName,
parameter?: any,
callback?: (success: boolean, res?: dataOut) => void,
): Promise<dataOut> {
console.log("发送数据", netName, parameter)
return new Promise((resolve, reject) => {
if (window["development"]) {
var url = "../../mock/miniTb/" + netName + ".json"
fetchAsync(url)
.then((data) => {
//回调
callback && callback(data.success, data);
resolve(data);
}, () => {
callback(false);
})
return
}
if (FYGE.getEnv() == "web" && !my) {//临时处理
if (netName == TmallNetName.getAppData) {
var d = {
success: true,
data: {
avatar: "https://source.unsplash.com/user/erondu/76x76",
userNick: "驱蚊器委屈委"
}
}
callback && callback(true, d);
resolve(d);
}
return
}
//向小程序发信息
my.postMessage({
netName: netName,
parameter: parameter
});
//事件回调
let fun = function (e: { type: string, data: dataOut }) {
var d = e.data;
GDispatcher.removeEventListener(netName, fun);
callback && callback(d.success, d);
resolve(d);
}
//加事件
GDispatcher.addEventListener(netName, fun);
})
}
export enum G_EVENT {
ON_SHOW = 'onShow', // 页面显示
ON_HIDE = 'onHide', // 页面隐藏
UPDATE_TASK = 'onUpdateTask', // 更新任务
UPDATE_SCENE= "onUpdateScene",//更新场景
}
import { Panel } from "../../module/views/Panel";
// interface IConfirmPanel {
//
// resolve: Function;
// reject: Function;
// promise: Promise<any>;
//
// make(): Promise<any>;
//
// }
export default class ConfirmPanel extends Panel {
resolve: Function = null;
reject: Function = null;
promise: Promise<any> = null;
public makePromise(): Promise<any> {
this.promise = new Promise<any>((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
return this.promise;
}
}
import { RES } from "../../module/RES";
import { getLightBgTexture } from "./getLightBgTexture";
/**
* 旋转光
*/
export class Light extends FYGE.Sprite {
constructor() {
super();
this.texture = RES.getRes("light.png");
this.anchorTexture.set(0.5, 0.5);
this.addEventListener(FYGE.Event.ENTER_FRAME, () => {
this.rotation += 1;
}, this)
}
}
/**
* 自行生成的光
*/
export class RotateLight extends FYGE.Sprite {
constructor(
lightColor: string = "#fffbb0",
lightRadius: number = 425,
lightNum: number = 18,
bgColor: string = lightColor,
bgRadius: number = lightRadius - 25
) {
super();
this.texture = getLightBgTexture(
lightColor,
lightRadius,
lightNum,
bgColor,
bgRadius
);
this.anchorTexture.set(0.5, 0.5);
this.addEventListener(FYGE.Event.ENTER_FRAME, () => {
this.rotation += 1;
}, this)
}
}
\ No newline at end of file
import UI from "../UI";
import TEXT_ALIGN = FYGE.TEXT_ALIGN;
import Container = FYGE.Container;
/**
* 纯色进度条
*/
export class ProgressBar extends Container {
/**
* 0到1的进度
*/
private _value = 0;
private upImage: FYGE.Graphics;
private progressTxt: FYGE.TextField;
private readonly maxLength: number;
constructor() {
super()
this.maxLength = 377//最大长度
this._value = 0;
this.upImage = UI.Graphics(this)
.beginFill(0xf8c862)
.drawRoundedRect(0, 0, this.value * this.maxLength, 19, 10)
.endFill();
this.progressTxt = UI.Txt(
this, "0%", 22, "#f8c862",
TEXT_ALIGN.CENTER, 80, (this.maxLength - 80) / 2, 36
);
}
get value() {
return this._value;
}
set value(v) {
if (v < 0) v = 0;
if (v > 1) v = 1;
this._value = v;
this.progressTxt.text = ((v * 100) >> 0) + "%";
const length = this._value * this.maxLength;
this.upImage.clear()
.beginFill(0xf8c862)
.drawRoundedRect(0, 0, length, 19, 10)
.endFill();
}
}
/**
* 传入文案和进度条图片
* 进度条图片位移,固定遮罩
* 貌似这样就不需要继承显示类了
*/
import Sprite = FYGE.Sprite;
import TextField = FYGE.TextField;
import Graphics = FYGE.Graphics;
import FrameAni = FYGE.FrameAni;
export class ProgressBarS {
/**
* 0到1的进度
*/
private _value = 0;
private upImage: Sprite;
private progressTxt: TextField;
private maxLength: number;
private oriX: number
constructor(upImage: Sprite, txt?: TextField) {
this.maxLength = upImage.width;//最大长度,直接取图片宽度
this.upImage = upImage;
this.progressTxt = txt;
this.oriX = upImage.x;
var delta = 0
//传入的也可能是帧动画,这样原点就有问题了
if (upImage instanceof FrameAni) delta = 0.5
//给图片加个矩形遮罩
this.upImage.mask = this.upImage.parent.addChild(new Graphics())
.beginFill(0xf8c862)
.drawRoundedRect(
upImage.x - upImage.width * delta,
upImage.y - upImage.height * delta,
upImage.width,
upImage.height,
111
)
.endFill();
this.value = 0;
}
get value() {
return this._value;
}
set value(v) {
if (v < 0) v = 0;
if (v > 1) v = 1;
this._value = v;
if (this.progressTxt) this.progressTxt.text = ((v * 100) >> 0) + "%";
this.upImage.x = this.oriX - (1 - this._value) * this.maxLength
}
}
// var aa = this.addChild(new RichText(
// [
// { text: "啊请问请问", style: { color: "#000000", size: 30 } },
// { text: "=2134324234啊请问请问", style: { color: "#ff0000", size: 30 } },
// { text: "驱蚊器问问", style: { color: "#000000", size: 30 } }
// ]
// ))
// aa.text = [
// { text: "啊请问请问", style: { color: "#000000", size: 30 } },
// { text: "=2134", style: { color: "#ff0000", size: 30 } },
// { text: "驱蚊器问问", style: { color: "#000000", size: 30 } }
// ]
// aa.position.set(375, 800);
// [{text: "测试",style:{color: ""}},{},{}]
import TextField = FYGE.TextField;
import Container = FYGE.Container;
interface IRichTextEle {
text: string,
style: { color: string, size: number }
}
export class RichText extends Container {
declare children : TextField[];
private static cache: FYGE.TextField[] = []
/**
*
* @param text
*/
constructor(text?: IRichTextEle[]) {
super()
if (text) this.text = text;
}
/**
* 水平对齐方式,默认居中
*/
get textAlign() {
return this._textAlign
}
set textAlign(value: FYGE.TEXT_ALIGN) {
if (this._textAlign !== value) {
this._textAlign = value;
this.adaptate();
}
}
private _textAlign: FYGE.TEXT_ALIGN = FYGE.TEXT_ALIGN.CENTER;
/**
* 垂直居中方式,默认居中
*/
get verticalAlign() {
return this._verticalAlign
}
set verticalAlign(value: FYGE.VERTICAL_ALIGN) {
if (this._verticalAlign !== value) {
this._verticalAlign = value;
this.adaptate();
}
}
private _verticalAlign: FYGE.VERTICAL_ALIGN = FYGE.VERTICAL_ALIGN.MIDDLE;
/**
* 文字间隙
*/
get gap(): number {
return this._gap;
};
set gap(value: number) {
if (this._gap != value) {
this._gap = value;
this.adaptate();
}
};
private _gap: number = 0;
/**
* 文本
*/
private _text: IRichTextEle[];
/**
* 按顺序
*/
get text(): IRichTextEle[] {
return this._text
}
/**
*
*/
set text(value: IRichTextEle[]) {
let i;
this._text = value;
const arr = value || [];
for (i = 0; i < arr.length; i++) {
const a = arr[i];
const c: TextField = this.children[i] || this.addChild(RichText.cache.shift() || new TextField());
c.text = a.text;
c.fillColor = a.style.color;
c.size = a.style.size;
}
//如果多了,去掉后面的,回收
if (this.children.length > arr.length) {
//移除后序
for (i = this.children.length - 1; i >= arr.length; i--) {
const c = this.children[i];
this.removeChild(c);
RichText.cache.push(c);
}
}
//适配
this.adaptate()
}
/**
* 适配,
*/
private adaptate() {
let i;
if (!this.children.length) return
var len = this.children.length;
//算总长度
var sum = 0;
for (var m = 0; m < len; m++) {
sum += this.children[m].textWidth;
}
sum += (len - 1) * this._gap;
//算出左边第一个元素的位置
var left: number;
if (this._textAlign == FYGE.TEXT_ALIGN.LEFT) {
left = 0
}
else if (this._textAlign == FYGE.TEXT_ALIGN.RIGHT) {
left = -sum
} else {
left = -sum / 2
}
var temSum = 0;
for (i = 0; i < this.children.length; i++) {
this.children[i].x = left + temSum
temSum += this.children[i].textWidth + this._gap;
}
var up: number;
if (this._verticalAlign == FYGE.VERTICAL_ALIGN.UP) {
up = 0
}
else if (this._verticalAlign == FYGE.VERTICAL_ALIGN.DOWN) {
up = -1
} else {
up = -1 / 2
}
for (i = 0; i < this.children.length; i++) {
this.children[i].y = this.children[i].textHeight * up;
}
}
}
//sdk
// <script src="//yun.duiba.com.cn/db_games/libs0924/howler.min.js"></script>
var resPath = "https://yun.duiba.com.cn/db_games/qx/hyundaiXXL/sound/";
var gameMusicBg = "https://yun.duiba.com.cn/aurora/assets/1f591de154f744a65f16fc2b86ae7cd069ac4421.mp3";
var boom = 'https://yun.duiba.com.cn/spark/assets/0cebbed9233d99ac4fb8a78d875f5efca9bad444.mp3';
var props = "https://yun.duiba.com.cn/spark/assets/34666d18dcc6c5054257c6914268f67c67bae49d.mp3";
var gold = "https://yun.duiba.com.cn/spark/assets/729a54f12f529cfef03db43715e0985d1f0d4f72.mp3";
export enum SoundType {
gameMusicBg = "gameMusicBg",
}
let isMuteStatus = false
let isPlayBg = false
export function cusPlaySound(soundType: number, loop: boolean = false, isMute: boolean = false) {
switch (soundType) {
case 1:
if (!isPlayBg) {
isPlayBg = true
playSound(gameMusicBg, loop, isMuteStatus)
}
break
case 2:
playSound(boom, loop, isMuteStatus)
break
case 3:
playSound(props, loop, isMuteStatus)
break
case 4:
playSound(gold, loop, isMuteStatus)
break
default:
break
}
// playSound(unionPath, loop);
}
/**
* 提前加载音频
* @param type
*/
export function preloadSound(type: SoundType) {
let src = resPath + type + ".mp3";
soundHash[src] = new Howl({
src: src,
preload: true,
});
}
/**
* 根据路径记录
*/
const soundHash: { [key: string]: Howl } = {};
export function playSound(src: string, loop: boolean = false, isMute: boolean = false) {
console.log('测试音效isMute', isMute);
let sound: Howl;
//循环的,且有缓存,取缓存的
if (soundHash[src] && loop) sound = soundHash[src]
//没有就新建
if (!sound) sound = new Howl({ src: [src], autoplay: false, loop });
//记录下,方便停止
soundHash[src] = sound;
//不循环删除缓存
if (!loop) sound.on('stop', function () { delete soundHash[src] });
if (isMute) {
// 静音
sound.stop()
} else {
//播放
console.log("播放")
sound.mute(false)
sound.play();
}
// console.log(sound)
//console.log('测试是否播放音效',src);
//返回一个,可以自行控制
return sound;
}
export function stopSound(src: string) {
if (soundHash[src]) soundHash[src].stop();
}
export function muteAllSound() {
isMuteStatus = false
console.log(isMuteStatus)
for (let key in soundHash) soundHash[key].mute(false);
}
export function resumeAllSound() {
isMuteStatus = true
console.log(isMuteStatus)
for (let key in soundHash) soundHash[key].mute(true);
}
export function stopAllSound() {
for (let key in soundHash) soundHash[key].stop();
}
export function playAllSound() {
for (let key in soundHash) soundHash[key].play();
}
//设置隐藏属性和改变可见属性的事件的名称
let hidden: string, visibilityChange: string;
if (typeof document.hidden !== 'undefined') {
hidden = 'hidden';
visibilityChange = 'visibilitychange';
} else if (typeof document['msHidden'] !== 'undefined') {
hidden = 'msHidden';
visibilityChange = 'msvisibilitychange';
} else if (typeof document['webkitHidden'] !== 'undefined') {
hidden = 'webkitHidden';
visibilityChange = 'webkitvisibilitychange';
}
const handleVisibilityChange = () => {
if (document.visibilityState == "visible") {
playAllSound();
console.log("网页显示")
}
else if (document.visibilityState == "hidden") {
stopAllSound()
console.log("网页隐藏")
}
};
document.addEventListener(
visibilityChange,
handleVisibilityChange,
false
);
window.onbeforeunload = function () {
//发接口
}
// window.addEventListener('beforeunload', ()=>{
// //发接口出去,
// })
// document.body['onbeforeunload'] = () => {
// }
/**
*
* @param dis
* @param zoomCenter 是否设定中心缩放,默认true,为了自行确定锚点的对象
*/
export function addBreathing(dis: FYGE.DisplayObject, zoomCenter: boolean = true) {
if (zoomCenter) {
dis.anchorX = dis.width / 2;
dis.anchorY = dis.height / 2;
}
FYGE.Tween.get(dis, { loop: true })
.to({ scaleX: 1.1, scaleY: 1.1 }, 1000)
.to({ scaleX: 1, scaleY: 1 }, 1000)
}
/**
*
* @param dis
* @param zoomCenter 是否设定中心缩放,默认true,为了自行确定锚点的对象
*/
import DisplayObject = FYGE.DisplayObject;
import MouseEvent = FYGE.MouseEvent;
import Tween = FYGE.Tween;
export function addClickZoom(dis: DisplayObject, zoomCenter: boolean = true) {
if (zoomCenter) {
dis.anchorX = dis.width / 2;
dis.anchorY = dis.height / 2;
}
dis.addEventListener("onMouseDown", _mouseEvent, dis)
.addEventListener("onMouseUp", _mouseEvent, dis)
.addEventListener("onMouseOut", _mouseEvent, dis);
let s = dis;
function _mouseEvent(e: MouseEvent) {
if (e.type == MouseEvent.MOUSE_DOWN) {
Tween.removeTweens(s);
Tween.get(s).to({ scaleX: 0.9, scaleY: 0.9 }, 50);
} else {
Tween.removeTweens(s);
Tween.get(s).to({ scaleX: 1, scaleY: 1 }, 50);
}
}
return dis;
}
/**
* 倒计时
* @param time 毫秒计算
* @param onChange 根据时间倒计时的执行函数
*/
export function countDown(time: number, onChange: (t: number) => void) {
const timeObj = { a: time };
FYGE.Tween.get(timeObj, {
onChange: () => {
onChange(timeObj.a)
// this.timeTxt.text = "" + Math.round(timeObj.a / 1000) + "s"
// if (timeObj.a < 100) {
// FYGE.Tween.removeTweens(timeObj)
// callback()
// }
}
})
.to({ a: 0 }, time)
//返回一个,可以中途取消
return timeObj
}
/**
* 中断倒计时
* @param timeObj
*/
export function clearCountDown(timeObj) {
if (!timeObj) return
FYGE.Tween.removeTweens(timeObj)
}
const cache: {
[key: string]: FYGE.Texture
} = {}
/**
*
* @param lightColor 颜色
* @param lightRadius 光环半径
* @param lightNum 光环扇形数量
* @param bgColor 背光颜色
* @param bgRadius 背光半径
*/
export function getLightBgTexture(
lightColor: string = "#fffbb0",
lightRadius: number = 425,
lightNum: number = 18,
bgColor: string = lightColor,
bgRadius: number = lightRadius - 25
) {
const cacheKey = `${lightColor}_${lightRadius}_${lightNum}_${bgColor}_${bgRadius}`;
//缓存过就返回
if (cache[cacheKey]) return cache[cacheKey];
const canvas = FYGE.createCanvas()// document.createElement("canvas");
canvas.width = canvas.height = lightRadius * 2;
const x = lightRadius, y = x;
const ctx = canvas.getContext("2d");
//最大值18,否则开放每个灯光角度
lightNum = Math.floor(Math.min(18, lightNum));
//背景的光晕
var colorObj = ctx.createRadialGradient(x, y, 0, x, y, bgRadius);
colorObj.addColorStop(0, bgColor);
colorObj.addColorStop(1, bgColor + "00");
ctx.fillStyle = colorObj;
ctx.beginPath();
ctx.arc(x, y, lightRadius, 0, 2 * Math.PI)
ctx.fill()
//径向的光
var colorObj = ctx.createRadialGradient(x, y, 0, x, y, lightRadius);
colorObj.addColorStop(0, lightColor);
colorObj.addColorStop(1, lightColor + "00");
ctx.fillStyle = colorObj;
ctx.beginPath();
var anglePer = Math.PI / 12;
var delta = Math.PI * 2 / lightNum;
for (var i = 0; i < lightNum; i++) {
ctx.moveTo(x, y)
ctx.arc(x, y, lightRadius, Math.PI * 1.5 - anglePer / 2 + delta * i, Math.PI * 1.5 + anglePer / 2 + delta * i)
}
ctx.fill();
//缓存
cache[cacheKey] = FYGE.Texture.fromCanvas(canvas);
return cache[cacheKey];
}
\ No newline at end of file
export const LoadingEffect = {
"fr": 30,
"ip": 0,
"op": 147,
"w": 750,
"h": 245,
"nm": "LoadingEffect",
"layers": [
{
"ind": 1,
"ty": 2,
"nm": "点11",
"refId": "7e4500a1-83be-4686-a46b-67147ed44ddd",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 10,
"s": [
472.5,
242,
0
]
},
{
"t": 16,
"s": [
472.5,
238.75,
0
]
},
{
"t": 22,
"s": [
472.5,
242,
0
]
},
{
"t": 41,
"s": [
472.5,
242,
0
]
},
{
"t": 47,
"s": [
472.5,
238.75,
0
]
},
{
"t": 53,
"s": [
472.5,
242,
0
]
},
{
"t": 72,
"s": [
472.5,
242,
0
]
},
{
"t": 78,
"s": [
472.5,
238.75,
0
]
},
{
"t": 84,
"s": [
472.5,
242,
0
]
},
{
"t": 103,
"s": [
472.5,
242,
0
]
},
{
"t": 109,
"s": [
472.5,
238.75,
0
]
},
{
"t": 115,
"s": [
472.5,
242,
0
]
},
{
"t": 133,
"s": [
472.5,
242,
0
]
},
{
"t": 139,
"s": [
472.5,
238.75,
0
]
},
{
"t": 145,
"s": [
472.5,
242,
0
]
},
{
"t": 164,
"s": [
472.5,
242,
0
]
},
{
"t": 170,
"s": [
472.5,
238.75,
0
]
},
{
"t": 176,
"s": [
472.5,
242,
0
]
},
{
"t": 195,
"s": [
472.5,
242,
0
]
},
{
"t": 201,
"s": [
472.5,
238.75,
0
]
},
{
"t": 207,
"s": [
472.5,
242,
0
]
}
]
},
"a": {
"k": [
2.5,
3,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 2,
"ty": 2,
"nm": "点10",
"refId": "7e4500a1-83be-4686-a46b-67147ed44ddd",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 8,
"s": [
461.5,
242,
0
]
},
{
"t": 14,
"s": [
461.5,
238.75,
0
]
},
{
"t": 20,
"s": [
461.5,
242,
0
]
},
{
"t": 39,
"s": [
461.5,
242,
0
]
},
{
"t": 45,
"s": [
461.5,
238.75,
0
]
},
{
"t": 51,
"s": [
461.5,
242,
0
]
},
{
"t": 70,
"s": [
461.5,
242,
0
]
},
{
"t": 76,
"s": [
461.5,
238.75,
0
]
},
{
"t": 82,
"s": [
461.5,
242,
0
]
},
{
"t": 101,
"s": [
461.5,
242,
0
]
},
{
"t": 107,
"s": [
461.5,
238.75,
0
]
},
{
"t": 113,
"s": [
461.5,
242,
0
]
},
{
"t": 131,
"s": [
461.5,
242,
0
]
},
{
"t": 137,
"s": [
461.5,
238.75,
0
]
},
{
"t": 143,
"s": [
461.5,
242,
0
]
},
{
"t": 162,
"s": [
461.5,
242,
0
]
},
{
"t": 168,
"s": [
461.5,
238.75,
0
]
},
{
"t": 174,
"s": [
461.5,
242,
0
]
},
{
"t": 193,
"s": [
461.5,
242,
0
]
},
{
"t": 199,
"s": [
461.5,
238.75,
0
]
},
{
"t": 205,
"s": [
461.5,
242,
0
]
}
]
},
"a": {
"k": [
2.5,
3,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 3,
"ty": 2,
"nm": "点9",
"refId": "7e4500a1-83be-4686-a46b-67147ed44ddd",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 6,
"s": [
450.625,
242,
0
]
},
{
"t": 12,
"s": [
450.625,
238.75,
0
]
},
{
"t": 18,
"s": [
450.625,
242,
0
]
},
{
"t": 37,
"s": [
450.625,
242,
0
]
},
{
"t": 43,
"s": [
450.625,
238.75,
0
]
},
{
"t": 49,
"s": [
450.625,
242,
0
]
},
{
"t": 68,
"s": [
450.625,
242,
0
]
},
{
"t": 74,
"s": [
450.625,
238.75,
0
]
},
{
"t": 80,
"s": [
450.625,
242,
0
]
},
{
"t": 99,
"s": [
450.625,
242,
0
]
},
{
"t": 105,
"s": [
450.625,
238.75,
0
]
},
{
"t": 111,
"s": [
450.625,
242,
0
]
},
{
"t": 129,
"s": [
450.625,
242,
0
]
},
{
"t": 135,
"s": [
450.625,
238.75,
0
]
},
{
"t": 141,
"s": [
450.625,
242,
0
]
},
{
"t": 160,
"s": [
450.625,
242,
0
]
},
{
"t": 166,
"s": [
450.625,
238.75,
0
]
},
{
"t": 172,
"s": [
450.625,
242,
0
]
},
{
"t": 191,
"s": [
450.625,
242,
0
]
},
{
"t": 197,
"s": [
450.625,
238.75,
0
]
},
{
"t": 203,
"s": [
450.625,
242,
0
]
}
]
},
"a": {
"k": [
2.5,
3,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 4,
"ty": 2,
"nm": "点8",
"refId": "7e4500a1-83be-4686-a46b-67147ed44ddd",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 4,
"s": [
439.25,
242,
0
]
},
{
"t": 10,
"s": [
439.25,
238.75,
0
]
},
{
"t": 16,
"s": [
439.25,
242,
0
]
},
{
"t": 35,
"s": [
439.25,
242,
0
]
},
{
"t": 41,
"s": [
439.25,
238.75,
0
]
},
{
"t": 47,
"s": [
439.25,
242,
0
]
},
{
"t": 66,
"s": [
439.25,
242,
0
]
},
{
"t": 72,
"s": [
439.25,
238.75,
0
]
},
{
"t": 78,
"s": [
439.25,
242,
0
]
},
{
"t": 97,
"s": [
439.25,
242,
0
]
},
{
"t": 103,
"s": [
439.25,
238.75,
0
]
},
{
"t": 109,
"s": [
439.25,
242,
0
]
},
{
"t": 127,
"s": [
439.25,
242,
0
]
},
{
"t": 133,
"s": [
439.25,
238.75,
0
]
},
{
"t": 139,
"s": [
439.25,
242,
0
]
},
{
"t": 158,
"s": [
439.25,
242,
0
]
},
{
"t": 164,
"s": [
439.25,
238.75,
0
]
},
{
"t": 170,
"s": [
439.25,
242,
0
]
},
{
"t": 189,
"s": [
439.25,
242,
0
]
},
{
"t": 195,
"s": [
439.25,
238.75,
0
]
},
{
"t": 201,
"s": [
439.25,
242,
0
]
}
]
},
"a": {
"k": [
2.5,
3,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 5,
"ty": 2,
"nm": "点7",
"refId": "7e4500a1-83be-4686-a46b-67147ed44ddd",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 2,
"s": [
428.125,
242,
0
]
},
{
"t": 8,
"s": [
428.125,
238.75,
0
]
},
{
"t": 14,
"s": [
428.125,
242,
0
]
},
{
"t": 33,
"s": [
428.125,
242,
0
]
},
{
"t": 39,
"s": [
428.125,
238.75,
0
]
},
{
"t": 45,
"s": [
428.125,
242,
0
]
},
{
"t": 64,
"s": [
428.125,
242,
0
]
},
{
"t": 70,
"s": [
428.125,
238.75,
0
]
},
{
"t": 76,
"s": [
428.125,
242,
0
]
},
{
"t": 95,
"s": [
428.125,
242,
0
]
},
{
"t": 101,
"s": [
428.125,
238.75,
0
]
},
{
"t": 107,
"s": [
428.125,
242,
0
]
},
{
"t": 125,
"s": [
428.125,
242,
0
]
},
{
"t": 131,
"s": [
428.125,
238.75,
0
]
},
{
"t": 137,
"s": [
428.125,
242,
0
]
},
{
"t": 156,
"s": [
428.125,
242,
0
]
},
{
"t": 162,
"s": [
428.125,
238.75,
0
]
},
{
"t": 168,
"s": [
428.125,
242,
0
]
},
{
"t": 187,
"s": [
428.125,
242,
0
]
},
{
"t": 193,
"s": [
428.125,
238.75,
0
]
},
{
"t": 199,
"s": [
428.125,
242,
0
]
}
]
},
"a": {
"k": [
2.5,
3,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 6,
"ty": 2,
"nm": "点1",
"refId": "7e4500a1-83be-4686-a46b-67147ed44ddd",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 0,
"s": [
416.5,
242,
0
]
},
{
"t": 6,
"s": [
416.5,
238.75,
0
]
},
{
"t": 12,
"s": [
416.5,
242,
0
]
},
{
"t": 31,
"s": [
416.5,
242,
0
]
},
{
"t": 37,
"s": [
416.5,
238.75,
0
]
},
{
"t": 43,
"s": [
416.5,
242,
0
]
},
{
"t": 62,
"s": [
416.5,
242,
0
]
},
{
"t": 68,
"s": [
416.5,
238.75,
0
]
},
{
"t": 74,
"s": [
416.5,
242,
0
]
},
{
"t": 93,
"s": [
416.5,
242,
0
]
},
{
"t": 99,
"s": [
416.5,
238.75,
0
]
},
{
"t": 105,
"s": [
416.5,
242,
0
]
},
{
"t": 123,
"s": [
416.5,
242,
0
]
},
{
"t": 129,
"s": [
416.5,
238.75,
0
]
},
{
"t": 135,
"s": [
416.5,
242,
0
]
},
{
"t": 154,
"s": [
416.5,
242,
0
]
},
{
"t": 160,
"s": [
416.5,
238.75,
0
]
},
{
"t": 166,
"s": [
416.5,
242,
0
]
},
{
"t": 185,
"s": [
416.5,
242,
0
]
},
{
"t": 191,
"s": [
416.5,
238.75,
0
]
},
{
"t": 197,
"s": [
416.5,
242,
0
]
}
]
},
"a": {
"k": [
2.5,
3,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 7,
"ty": 2,
"nm": "Loading",
"refId": "a122de8a-beed-4442-9252-8c047986f371",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
342,
233,
0
]
},
"a": {
"k": [
67,
12,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 8,
"ty": 3,
"nm": "空 5",
"ks": {
"o": {
"k": 0
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 0,
"s": [
-43.375,
93.125,
0
]
},
{
"t": 18,
"s": [
125.625,
93.125,
0
]
},
{
"t": 28,
"s": [
125.625,
93.125,
0
]
},
{
"t": 43,
"s": [
271.625,
93.125,
0
]
},
{
"t": 54,
"s": [
271.625,
93.125,
0
]
},
{
"t": 69,
"s": [
421.625,
93.125,
0
]
},
{
"t": 80,
"s": [
421.625,
93.125,
0
]
},
{
"t": 95,
"s": [
539.625,
81.125,
0
]
},
{
"t": 106,
"s": [
539.625,
81.125,
0
]
},
{
"t": 121,
"s": [
653.625,
84.625,
0
]
},
{
"t": 132,
"s": [
653.625,
84.625,
0
]
},
{
"t": 147,
"s": [
797.625,
84.625,
0
]
}
]
},
"a": {
"k": [
0,
0,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 9,
"ty": 3,
"nm": "空 1",
"parent": 8,
"ks": {
"o": {
"k": 0
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 0,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 9.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 18,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 26,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 35.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 44,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 52,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 61.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 70,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 78,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 87.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 96,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 104,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 113.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 122,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 130,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 139.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 148,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 156,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 165.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 174,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 182,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 191.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 200,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 208,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 217.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 226,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 234,
"s": [
-0.25,
-10.25,
0
]
},
{
"t": 243.212,
"s": [
-0.25,
-36.25,
0
]
},
{
"t": 252,
"s": [
-0.25,
-10.25,
0
]
}
]
},
"a": {
"k": [
0,
0,
0
]
},
"s": {
"k": [
21.25,
21.25,
100
]
}
},
"ip": -8,
"op": 199
},
{
"ind": 10,
"ty": 2,
"nm": "棋子头",
"parent": 9,
"refId": "845ae874-998e-4f68-8e79-641eb77466f3",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": -8,
"s": [
-2.353,
-160,
0
]
},
{
"t": 0,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 7.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 18,
"s": [
-2.353,
-160,
0
]
},
{
"t": 26,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 33.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 44,
"s": [
-2.353,
-160,
0
]
},
{
"t": 52,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 59.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 70,
"s": [
-2.353,
-160,
0
]
},
{
"t": 78,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 85.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 96,
"s": [
-2.353,
-160,
0
]
},
{
"t": 104,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 111.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 122,
"s": [
-2.353,
-160,
0
]
},
{
"t": 130,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 137.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 148,
"s": [
-2.353,
-160,
0
]
},
{
"t": 156,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 163.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 174,
"s": [
-2.353,
-160,
0
]
},
{
"t": 182,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 189.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 200,
"s": [
-2.353,
-160,
0
]
},
{
"t": 208,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 215.242,
"s": [
-2.353,
-160,
0
]
},
{
"t": 226,
"s": [
-2.353,
-160,
0
]
},
{
"t": 234,
"s": [
-2.353,
-128.941,
0
]
},
{
"t": 241.2421875,
"s": [
-2.353,
-160,
0
]
}
]
},
"a": {
"k": [
12,
12.5,
0
]
},
"s": {
"k": [
470.588,
470.588,
100
]
}
},
"ip": -8,
"op": 199
},
{
"ind": 11,
"ty": 2,
"nm": "棋子2",
"parent": 9,
"refId": "ad9681a6-9eb2-40ad-8c2c-0b3ad121a00d",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
0,
63.529,
0
]
},
"a": {
"k": [
11.5,
36,
0
]
},
"s": {
"k": [
{
"t": -8,
"s": [
470.588,
470.588,
100
]
},
{
"t": 0,
"s": [
470.588,
377.588,
100
]
},
{
"t": 7.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 18,
"s": [
470.588,
470.588,
100
]
},
{
"t": 26,
"s": [
470.588,
377.588,
100
]
},
{
"t": 33.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 44,
"s": [
470.588,
470.588,
100
]
},
{
"t": 52,
"s": [
470.588,
377.588,
100
]
},
{
"t": 59.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 70,
"s": [
470.588,
470.588,
100
]
},
{
"t": 78,
"s": [
470.588,
377.588,
100
]
},
{
"t": 85.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 96,
"s": [
470.588,
470.588,
100
]
},
{
"t": 104,
"s": [
470.588,
377.588,
100
]
},
{
"t": 111.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 122,
"s": [
470.588,
470.588,
100
]
},
{
"t": 130,
"s": [
470.588,
377.588,
100
]
},
{
"t": 137.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 148,
"s": [
470.588,
470.588,
100
]
},
{
"t": 156,
"s": [
470.588,
377.588,
100
]
},
{
"t": 163.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 174,
"s": [
470.588,
470.588,
100
]
},
{
"t": 182,
"s": [
470.588,
377.588,
100
]
},
{
"t": 189.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 200,
"s": [
470.588,
470.588,
100
]
},
{
"t": 208,
"s": [
470.588,
377.588,
100
]
},
{
"t": 215.242,
"s": [
470.588,
470.588,
100
]
},
{
"t": 226,
"s": [
470.588,
470.588,
100
]
},
{
"t": 234,
"s": [
470.588,
377.588,
100
]
},
{
"t": 241.2421875,
"s": [
470.588,
470.588,
100
]
}
]
}
},
"ip": -8,
"op": 199
},
{
"ind": 12,
"ty": 2,
"nm": "棋子投影",
"parent": 9,
"refId": "7458bc9a-d07d-4a7c-972b-4de7ed7c040d",
"ks": {
"o": {
"k": 30.196
},
"r": {
"k": 0
},
"p": {
"k": [
{
"t": 0,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 9.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 18,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 26,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 35.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 44,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 52,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 61.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 70,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 78,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 87.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 96,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 104,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 113.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 122,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 130,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 139.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 148,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 156,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 165.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 174,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 182,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 191.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 200,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 208,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 217.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 226,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 234,
"s": [
-67.059,
-3.529,
0
]
},
{
"t": 243.053,
"s": [
-183.529,
-60,
0
]
},
{
"t": 252,
"s": [
-67.059,
-3.529,
0
]
}
]
},
"a": {
"k": [
24,
15,
0
]
},
"s": {
"k": [
470.588,
470.588,
100
]
}
},
"ip": -8,
"op": 199
},
{
"ind": 13,
"ty": 2,
"nm": "电影院",
"refId": "cd1a775d-36c9-4c8e-9c67-8191070068e9",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
127.5,
111,
0
]
},
"a": {
"k": [
61.5,
52,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 14,
"ty": 2,
"nm": "形状 762",
"refId": "b48ee079-b3d7-4371-b294-944200eccba9",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
111.5,
118,
0
]
},
"a": {
"k": [
68.5,
37,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
},
{
"ind": 15,
"ty": 2,
"nm": "格子",
"refId": "5cab5037-81fc-4246-96e5-b1353f339275",
"ks": {
"o": {
"k": 100
},
"r": {
"k": 0
},
"p": {
"k": [
450,
108,
0
]
},
"a": {
"k": [
258,
54,
0
]
},
"s": {
"k": [
100,
100,
100
]
}
},
"ip": 0,
"op": 147
}
],
"markers": [
{
"tm": 147,
"cm": "1",
"dr": 0
}
]
}
import { Panel } from "../../module/views/Panel";
import { RES } from "../../module/RES";
import { Tools } from "../Tools";
import { sendTbNet, TbNetName } from "../TaoBaoNet";
import { showToast } from "../../module/ctrls";
import UI from "../UI";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
export class HelpPanel extends Panel {
get groupNames() {
return ["HelpPanel"]
}
vip: false;
async initUi() {
super.start();
this.vip = await Tools.queryVip();
UI.Sp(this, "helpBg.png", 84, 435);
this.addChild(new Button(RES.getRes('helpBtn.png')))
.addEventListener(MouseEvent.CLICK, this.doHelp, this)
.position.set(167, 789);
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, () => this.hidePanel())
.position.set(598, 369);
}
start(data) {
}
hidePanel() {
super.hidePanel();
Tools.globalData.inviteId = ''; // 必须到后面在删除inviteId,不然我这个助力到时候没地方取
this.data.call();
}
async doHelp(e) {
this.btnDelay(e.target);
sendTbNet(TbNetName.addData, { type: 4 }, null, true);
if (Tools.globalData.inviteId == Tools.globalData.openId) {
showToast('自己不能给自己助力');
this.hidePanel();
return;
}
// 必为非会员才会到这个弹窗,所以是会员了就可以干掉了
if (this.vip) {
this.hidePanel();
return;
}
if (await Tools.queryVip()) {
sendTbNet(TbNetName.doHelp, { inviteId: Tools.globalData.inviteId },
(success, res) => {
if (!success) { // 失败唤起入会插件
if (res.code != "430009") {
showToast(res.message);
}
this.hidePanel();
return;
}
showToast('接受邀请成功');
this.hidePanel();
}, true
);
} else {
showToast('请先加入会员');
setTimeout(() => {
sendTbNet(TbNetName.openMember);
}, 1500);
}
}
}
import { changeScene } from "../../module/ctrls";
import { Panel } from "../../module/views/Panel";
import { IndexScene } from "../scenes/IndexScene";
import { goTask } from "../Tools";
import { RES } from "../../module/RES";
import UI from "../UI";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
export class NoTimePanel extends Panel {
get groupNames() {
return ["NoTimePanel"]
}
async initUi() {
UI.Sp(this, "noTimeBg.png", 84, 435);
this.addChild(new Button(RES.getRes('noTimeBtn.png')))
.addEventListener(MouseEvent.CLICK, () => {
this.hidePanel();
goTask();
}, this)
.position.set(167, 789);
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 369);
}
hidePanel() {
super.hidePanel();
if (!this.data || this.data.from != "index") { // 如果不是从主场景来的,则还要切到主场景
changeScene(IndexScene);
}
}
}
import { changeScene, showPanel } from "../../module/ctrls";
import { Panel } from "../../module/views/Panel";
import { IndexScene } from "../scenes/IndexScene";
import { LoadingScene } from "../scenes/LoadingScene";
import { sendTbNet, TbNetName } from "../TaoBaoNet";
import { RES } from "../../module/RES";
import UI from "../UI";
import { NoTimePanel } from "./NoTimePanel";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
export class OverNoPrizePanel extends Panel {
get groupNames() {
return ["OverPanel"]
}
async initUi() {
this.addChild(new FYGE.Sprite(RES.getRes("overNoPrizeBg.png")))
.position.set(84, 421);
this.addChild(new Button(RES.getRes('overBtn.png')))
.addEventListener(MouseEvent.CLICK, this.again, this)
.position.set(167, 849);
UI.Txt(
this, this.data.score + "", 60, '#704a5b',
FYGE.TEXT_ALIGN.CENTER, 750, 0, 661
);
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 369);
}
// 再来一次
async again(e) {
this.btnDelay(e.target);
if (this.data.gameTimes <= 0) {
showPanel(NoTimePanel);
} else {
const { success, data: startData } = await sendTbNet(TbNetName.startGame);
if (!success) return;
changeScene(LoadingScene, { startData });
}
super.hidePanel();
}
hidePanel() {
super.hidePanel();
changeScene(IndexScene);
}
}
import { changeScene, showPanel, showToast } from "../../module/ctrls";
import { Panel } from "../../module/views/Panel";
import { IndexScene } from "../scenes/IndexScene";
import { LoadingScene } from "../scenes/LoadingScene";
import { sendTbNet, TbNetName } from "../TaoBaoNet";
import { RES } from "../../module/RES";
import UI from "../UI";
import { NoTimePanel } from "./NoTimePanel";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
import Sprite = FYGE.Sprite;
export class OverPrizePanel extends Panel {
get groupNames() {
return ["OverPanel"]
}
async initUi() {
this.addChild(new FYGE.Sprite(RES.getRes("overPrizeBg.png")))
.position.set(84, 309);
this.addChild(new Button(RES.getRes('overBtn.png')))
.addEventListener(MouseEvent.CLICK, this.again, this)
.position.set(167, 979);
UI.Txt(
this, this.data.score + "", 60, '#704a5b',
FYGE.TEXT_ALIGN.CENTER, 750, 0, 593
);
UI.Txt(
this, "请前往「我的奖品」页领取", 24, '#a35e7a',
FYGE.TEXT_ALIGN.CENTER, 750, 0, 924
);
const img = this.addChild(Sprite.fromUrl(this.data.prizeInfo.image));
img.anchorTexture.set(0.5, 0.5);
img.position.set(375, 790);
img.width = img.height = 214;
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 369);
}
// 再来一次
async again(e) {
this.btnDelay(e.target);
if (this.data.gameTimes <= 0) {
showPanel(NoTimePanel);
} else {
const { success, data: startData } = await sendTbNet(TbNetName.startGame);
if (!success) return;
changeScene(LoadingScene, { startData });
}
super.hidePanel();
}
private clickPrizeBtn(e) {
this.btnDelay(e.target);
switch (this.data.prizeInfo.type) {
case 1: // 权益
sendTbNet(TbNetName.receiveEnamePrize, {
_id: this.data.prizeInfo._id,
id: this.data.prizeInfo._id
},
(success, res) => {
if (!success || !res) {
showToast('奖品发放失败\n请前往我的奖品处进行处理');
this.hidePanel();
return;
}
if (res.data && res.data.drawStatus == 3) {
showToast('奖品发放成功\n请前往我的奖品处查看');
} else {
showToast('奖品发放失败\n请前往我的奖品处进行处理');
}
this.hidePanel();
}, true
);
break;
case 3: // 实物
sendTbNet(TbNetName.getUserAddress, {
prizeId: this.data.prizeInfo._id,
},
(success, res) => {
if (!success) {
// showToast('奖品发放失败\n请前往我的奖品处进行处理');
return;
}
showToast('奖品发放成功\n请前往我的奖品处查看');
this.hidePanel();
}, true
);
break;
case 2: // 积分
case 5: // 谢谢参与
this.hidePanel();
break;
}
}
hidePanel() {
super.hidePanel();
changeScene(IndexScene);
}
}
import { Panel } from "../../module/views/Panel";
import { RES } from "../../module/RES";
import UI from "../UI";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
export class RankNoPrizePanel extends Panel {
get groupNames() {
return ["RankPrizePanel"]
}
async initUi() {
this.addChild(new FYGE.Sprite(RES.getRes("rankNoPrizeBg.png")))
.position.set(84, 434);
this.addChild(new Button(RES.getRes('rankNoPrizeBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(166, 789);
const { rank, score } = this.data.rank;
const rankTxt = score == 0 ? "-" : rank;
UI.Txt(
this, rankTxt + "", 60, '#704a5b',
FYGE.TEXT_ALIGN.CENTER, 750, 0, 623
);
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 368);
}
}
import { RES } from "../../module/RES";
import { Item } from "../../module/views/Item";
import { Panel } from "../../module/views/Panel";
import { sendTbNet, TbNetName } from "../TaoBaoNet";
import { Tools } from "../Tools";
import UI from "../UI";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
import ScrollList = FYGE.ScrollList;
import Shape = FYGE.Shape;
import Sprite = FYGE.Sprite;
import TEXT_ALIGN = FYGE.TEXT_ALIGN;
import TextField = FYGE.TextField;
import Texture = FYGE.Texture;
export class RankPanel extends Panel {
get groupNames() {
return ["RankPanel"]
}
timeLabel: TextField;
mRank: TextField;
mNick: TextField;
mScore: TextField;
rankList: ScrollList;
prizeList: ScrollList;
async initUi() {
this.addChild(new Sprite(RES.getRes("rankBg.png")))
.position.set(84, 360);
const endDate = new Date(Tools.activityBaseInfo.endTime);
this.timeLabel = UI.Txt(
this, `排行榜奖励${endDate.getMonth() + 1}${endDate.getDate()}${endDate.getHours()}时开奖`,
24, '#704a5b', TEXT_ALIGN.CENTER, 750, 0, 1006
);
this.timeLabel.bold = true;
// 我的排行
this.mRank = UI.Txt(
this, "未入榜", 24, '#704a5b',
TEXT_ALIGN.CENTER, 113, 122, 563
);
this.mNick = UI.Txt(
this, "", 24, '#704a5b',
TEXT_ALIGN.CENTER, 200, 231, 563
);
this.mScore = UI.Txt(
this, "0分", 24, '#704a5b',
TEXT_ALIGN.CENTER, 167, 458, 563
);
// 排行榜列表
this.rankList = this.addChild(new ScrollList(
RankItem, 500, 69, 500, 360
));
this.rankList.position.set(122, 615);
// 奖品列表
this.prizeList = this.addChild(new ScrollList(
PrizeItem, 149, 69, 500, 178, false
));
this.prizeList.position.set(122, 1059);
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 294);
}
async start() {
super.start();
const { success, data, message } = await sendTbNet(TbNetName.getRankList);
if (success) {
const { rank, score, userNick } = data;
this.mRank.text = score == 0 ? "未入榜" : rank;
/// TODO 淘宝昵称不可能是空的吧,也不会在4位以下吧
this.mNick.text = userNick[0] + "**" + userNick[userNick.length - 1];
this.mScore.text = (score || 0) + "分";
this.rankList.updateData(data.list || []);
this.rankList.maxDistance += 30;
}
const prizeData = await sendTbNet(TbNetName.getPrizeList);
if (prizeData.success) {
this.prizeList.updateData(prizeData.data.list || []);
this.prizeList.maxDistance += 30;
}
}
}
/**
* 排行榜Item
*/
class RankItem extends Item {
rank: TextField;
nick: TextField;
score: TextField;
icon: Sprite;
initUi(data?) {
super.initUi(data);
this.rank = UI.Txt(
this, "1", 24, '#704a5b',
TEXT_ALIGN.CENTER, 113, 0, 28
);
this.nick = UI.Txt(
this, "", 24, '#704a5b',
TEXT_ALIGN.CENTER, 200, 109, 28
);
this.score = UI.Txt(
this, "0分", 24, '#704a5b',
TEXT_ALIGN.CENTER, 167, 336, 28
);
this.icon = UI.Sp(this,"rankIcon.png");
this.icon.position.set(39, 14);
const shape = this.addChild(new Shape());
shape.beginFill(0xf6bad9);
shape.drawRect(0, 69, 500, 2);
shape.endFill();
}
initData(id: number, data: any) {
super.initData(id, data);
if (id == -1) return;
const { rank, userNick, score } = this.data;
this.rank.text = rank;
/// TODO 淘宝昵称不可能是空的吧,也不会在4位以下吧
this.nick.text = userNick[0] + "**" + userNick[userNick.length - 1];
this.score.text = (score || 0) + "分";
this.icon.visible = (+rank <= 3);
}
}
/**
* 奖品Item
*/
class PrizeItem extends Item {
prizeImg: Sprite;
nameLabel: TextField;
initUi(data?) {
super.initUi(data);
this.prizeImg = this.addChild(new Sprite());
this.prizeImg.anchorTexture.set(0.5, 0.5);
this.prizeImg.width = this.prizeImg.height = 130;
this.prizeImg.position.set(65, 65);
this.nameLabel = UI.Txt(
this, "0分", 22, '#704a5b',
TEXT_ALIGN.CENTER, 130, 0, 150
);
}
initData(id: number, data: any) {
super.initData(id, data);
if (id == -1) return;
this.prizeImg.texture = Texture.fromUrl(data.image);
const rankArr = data.rank.split("-");
if (rankArr[0] == rankArr[1]) {
this.nameLabel.text = `第${rankArr[0]}名`;
} else {
this.nameLabel.text = `第${data.rank}名`;
}
}
}
import { showToast } from "../../module/ctrls";
import { Panel } from "../../module/views/Panel";
import { sendTbNet, TbNetName } from "../TaoBaoNet";
import { RES } from "../../module/RES";
import UI from "../UI";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
import Sprite = FYGE.Sprite;
export class RankPrizePanel extends Panel {
get groupNames() {
return ["RankPrizePanel"]
}
async initUi() {
this.addChild(new FYGE.Sprite(RES.getRes("rankPrizeBg.png")))
.position.set(84, 434);
this.addChild(new Button(RES.getRes('rankPrizeBtn.png')))
.addEventListener(MouseEvent.CLICK, this.clickPrizeBtn, this)
.position.set(166, 979);
const { rank, score } = this.data.rank;
const rankTxt = score == 0 ? "-" : rank;
UI.Txt(
this, rankTxt + "", 60, '#704a5b',
FYGE.TEXT_ALIGN.CENTER, 750, 0, 623
);
const img = this.addChild(Sprite.fromUrl(this.data.prize.image));
img.anchorTexture.set(0.5, 0.5);
img.position.set(375, 790);
img.width = img.height = 214;
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 368);
}
private clickPrizeBtn(e) {
this.btnDelay(e.target);
switch (this.data.prize.type) {
case 1: // 权益
this.hidePanel();
// sendTbNet(TbNetName.receiveEnamePrize, {
// _id: this.data.prize._id,
// id: this.data.prize._id
// },
// (success, res) => {
// if (!success || !res) {
// showToast('奖品发放失败\n请前往我的奖品处进行处理');
// this.hidePanel();
// return;
// }
// if (res.data && res.data.drawStatus == 3) {
// showToast('奖品发放成功\n请前往我的奖品处查看');
// } else {
// showToast('奖品发放失败\n请前往我的奖品处进行处理');
// }
// this.hidePanel();
// }, true
// );
break;
case 3: // 实物
sendTbNet(TbNetName.getUserAddress, {
prizeId: this.data.prize._id,
},
(success, res) => {
if (!success) {
// showToast('奖品发放失败\n请前往我的奖品处进行处理');
return;
}
showToast('奖品发放成功\n请前往我的奖品处查看');
this.hidePanel();
}, true
);
break;
case 2: // 积分
case 5: // 谢谢参与
this.hidePanel();
break;
}
}
}
import { showToast } from "../../module/ctrls";
import { Panel } from "../../module/views/Panel";
import { GDispatcher } from "../Main";
import { sendTbNet, TbNetName } from "../TaoBaoNet";
import { Tools } from "../Tools";
import { RES } from "../../module/RES";
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
export class RevivePanel extends Panel {
get groupNames() {
return ["RevivePanel"]
}
vip: false;
async initUi() {
this.vip = await Tools.queryVip();
if (this.vip) { // 必为非会员才会到这个弹窗,所以是会员了就可以干掉了
this.hidePanel();
return;
}
this.addChild(new FYGE.Sprite(RES.getRes("reviveBg.png")))
.position.set(84, 474);
this.addChild(new Button(RES.getRes('reviveCancel.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(131, 782);
this.addChild(new Button(RES.getRes('reviveOk.png')))
.addEventListener(MouseEvent.CLICK, this.doRevive, this)
.position.set(385, 778);
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 369);
}
async doRevive(e) {
this.btnDelay(e.target);
// 必为非会员才会到这个弹窗,所以是会员了就可以干掉了
if (this.vip) {
this.hidePanel();
return;
}
const revive = async () => {
const {
success,
data,
message
} = await sendTbNet(TbNetName.continueGame, { gameId: this.data.gameId });
if (!success || !data.isContinue) {
showToast(message);
this.hidePanel();
return;
}
// 复活
this.data.revive();
super.hidePanel();
}
if (await Tools.queryVip()) {
revive();
} else {
showToast('请先加入会员');
GDispatcher.once("JoinMember", revive);
setTimeout(() => {
sendTbNet(TbNetName.openMember);
}, 1500);
}
}
hidePanel() {
super.hidePanel();
this.data.submit();
}
}
import { Panel } from "../../module/views/Panel";
import { Tools } from "../Tools";
import { RES } from "../../module/RES";
import UI from "../UI";
import TextField = FYGE.TextField;
import TEXT_lINETYPE = FYGE.TEXT_lINETYPE;
import ScrollPage = FYGE.ScrollPage;
import Button = FYGE.Button;
import MouseEvent = FYGE.MouseEvent;
export class RulePanel extends Panel {
get groupNames() {
return ["RulePanel"]
}
ruleTex: TextField;
scroll: ScrollPage;
initUi() {
this.addChild(new FYGE.Sprite(RES.getRes("rulePanelBg.png")))
.position.set(84, 435);
const rule = Tools.activityBaseInfo.rule;
UI.Txt(
this, rule, 26, '#704a5b',
FYGE.TEXT_ALIGN.LEFT, 444
);
this.ruleTex.lineType = TEXT_lINETYPE.MULTI;
this.scroll = this.addChild(new ScrollPage(
444, 370, this.ruleTex.textHeight + 30
));
this.scroll.position.set(158, 590);
this.scroll.view.addChild(this.ruleTex);
this.addChild(new Button(RES.getRes('rulePanelBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(167, 989);
this.addChild(new Button(RES.getRes('comCloseBtn.png')))
.addEventListener(MouseEvent.CLICK, this.hidePanel, this)
.position.set(598, 369);
}
start(data) {
super.start();
}
initEvents() {
super.initEvents();
}
removeEvents() {
super.removeEvents();
}
}
import { changeScene, showPanel, showToast } from "../../module/ctrls";
import { RES } from "../../module/RES";
import { Scene } from "../../module/views/Scene";
import { GDispatcher } from "../Main";
import { HelpPanel } from "../panels/HelpPanel";
import { NoTimePanel } from "../panels/NoTimePanel";
import { RankNoPrizePanel } from "../panels/RankNoPrizePanel";
import { RankPanel } from "../panels/RankPanel";
import { RankPrizePanel } from "../panels/RankPrizePanel";
import { RulePanel } from "../panels/RulePanel";
import { sendTbNet, TbNetName } from "../TaoBaoNet";
import { goMyPrize, goTask, Tools } from "../Tools";
import UI from "../UI";
import { LoadingScene } from "./LoadingScene";
import Button = FYGE.Button;
import Container = FYGE.Container;
import MouseEvent = FYGE.MouseEvent;
import Shape = FYGE.Shape;
import Sprite = FYGE.Sprite;
import TEXT_ALIGN = FYGE.TEXT_ALIGN;
import TextField = FYGE.TextField;
import VERTICAL_ALIGN = FYGE.VERTICAL_ALIGN;
import Texture = FYGE.Texture;
export class IndexScene extends Scene {
prizeBtn: Button;
taskBtn: Button;
ruleBtn: Button;
rankBtn: Button;
startBtn: Button;
paper: Sprite;
timeLabel: TextField;
progress: IndexProgress;
get groupNames(): string[] {
return [
'index',
]
}
async initUi() {
const { totalScore } = Tools.activityBaseInfo;
this.paper = this.addChild(Sprite.fromUrl("https://yun.duiba.com.cn/aurora/assets/70c7fdc45ed8139bdc0a23ac004facc07abf3cfd.jpg"));
this.progress = this.addChild(new IndexProgress({
value: totalScore
}));
this.progress.y = 1050;
// 排行榜
this.rankBtn = this.addChild(new Button(RES.getRes("rankBtn.png")))
.addEventListener(MouseEvent.CLICK, this.clickBtn, this);
this.rankBtn.position.set(652, 450);
this.rankBtn.anchorX = 98;
// 任务
this.taskBtn = this.addChild(new Button(RES.getRes("taskBtn.png")))
.addEventListener(MouseEvent.CLICK, this.clickBtn, this);
this.taskBtn.position.set(599, 388);
this.taskBtn.anchorX = 151;
// 我的奖品
this.prizeBtn = this.addChild(new Button(RES.getRes("prizeBtn.png")))
.addEventListener(MouseEvent.CLICK, this.clickBtn, this);
this.prizeBtn.y = 392;
this.prizeBtn.anchorX = 0;
// 规则
this.ruleBtn = this.addChild(new Button(RES.getRes("ruleBtn.png")))
.addEventListener(MouseEvent.CLICK, this.clickBtn, this);
this.ruleBtn.y = 453;
this.ruleBtn.anchorX = 0;
// 开始游戏
this.startBtn = this.addChild(new Button(RES.getRes("startBtn.png")))
.addEventListener(MouseEvent.CLICK, this.startGame, this);
this.startBtn.position.set(128, 1244);
UI.Sp(this.startBtn, "btnTipBg.png", 426, -13);
this.timeLabel = UI.Txt(
this.startBtn, `剩余次数:${Tools.gameInfo.gameTimes}`, 20, "#ffffff",
TEXT_ALIGN.CENTER, 147, 426, -13
);
this.timeLabel.textHeight = 36;
this.timeLabel.verticalAlign = VERTICAL_ALIGN.MIDDLE;
UI.Txt(
this, `单局奇迹值达520分\t\t必得「甜蜜福利」\t发完即止`, 22,
"#ffa8d0", TEXT_ALIGN.CENTER, 750, 0, 1376
);
}
destroy() {
super.destroy();
GDispatcher.removeEventListener("UpdateScene", this.updateIndex, this);
}
async updateIndex() {
await Tools.getActivityBaseInfo();
await Tools.getGameInfo();
const { showImage, totalScore } = Tools.activityBaseInfo;
this.paper.texture = Texture.fromUrl(showImage);
this.progress.value = totalScore;
this.timeLabel.text = `剩余次数:${Tools.gameInfo.gameTimes}`;
}
async start() {
super.start();
GDispatcher.addEventListener("UpdateScene", this.updateIndex, this);
if (!this.data || this.data.from != "main") {
await Tools.getActivityBaseInfo();
await Tools.getGameInfo();
}
const { showImage, totalScore } = Tools.activityBaseInfo;
this.paper.texture = Texture.fromUrl(showImage);
this.progress.value = totalScore;
this.timeLabel.text = `剩余次数:${Tools.gameInfo.gameTimes}`;
// 排行榜奖励
if (Tools.activityBaseInfo.activityStatus == 3 && Tools.activityBaseInfo.openPrizeStatus == 3) {
// await sendTbNet(TbNetName.getRankRewards); /// TODO 手动补发,不需要了
const { success, data } = await sendTbNet(TbNetName.getMyRankPrize);
if (success && data.showAwardDialog) {
if (!data.prize || data.prize.type == 5) {
showPanel(RankNoPrizePanel, data);
} else {
showPanel(RankPrizePanel, data);
}
}
}
const judgeRule = () => {
if (Tools.globalData.newUser) {
Tools.globalData.newUser = false;
showPanel(RulePanel);
}
}
// 有邀请码,唤起弹窗
if (Tools.globalData.inviteId && Tools.activityBaseInfo.activityStatus != 3) {
showPanel(HelpPanel, { call: judgeRule });
} else {
judgeRule();
}
}
async startGame(e) {
this.btnDelay(e.target);
if (Tools.activityBaseInfo.activityStatus == 1) {
return showToast("活动未开始");
} else if (Tools.activityBaseInfo.activityStatus == 3) {
return showToast("活动已结束");
}
if (Tools.gameInfo.gameTimes <= 0) {
showPanel(NoTimePanel, { from: "index" });
return;
}
const { success, data: startData } = await sendTbNet(TbNetName.startGame);
if (!success) return;
changeScene(LoadingScene, { startData });
}
private async clickBtn(e) {
this.btnDelay(e.target);
switch (e.target) {
case this.ruleBtn:
showPanel(RulePanel);
break;
case this.prizeBtn:
goMyPrize();
break;
case this.taskBtn:
if (Tools.activityBaseInfo.activityStatus == 1) {
showToast("活动未开始");
} else if (Tools.activityBaseInfo.activityStatus == 3) {
showToast("活动已结束");
} else {
goTask();
}
break;
case this.rankBtn:
showPanel(RankPanel);
break;
}
}
}
class IndexProgress extends Container {
constructor(data: { value: number }) {
super();
this.init();
this.value = data.value;
}
private _value: number = 0;
public get value(): number {
return this._value;
}
public set value(value: number) {
this._value = value;
this.miracleTxt.text = `当前总奇迹值:${value}`;
switch (true) {
case (value <= 5.2 * 10000): // 5.2万以下
this.fill.mask.x = 80 * value / 52000 + 72 - 608;
break;
case (value <= 52 * 10000): // 5.2万 - 52万
this.fill.mask.x = 160 * value / 520000 + 72 - 608 + 80;
break;
case (value <= 520 * 10000): // 52万 - 520万
this.fill.mask.x = 304 * value / 5200000 + 72 - 608 + 80 + 160;
break;
case (value > 520 * 10000): // 520万以上
this.fill.mask.x = 72;
break;
}
}
miracleTxt: TextField;
fill: Sprite;
init() {
UI.Sp(this, "progressBg.png");
this.fill = UI.Sp(this, "progressFill.png");
this.fill.position.set(69, 79);
const mask = this.addChild(new Shape());
mask.beginFill(0xff0000);
mask.drawRoundedRect(0, 0, 608, 25, 10, 10, 10, 10);
mask.endFill();
mask.position.set(73, 74);
this.fill.mask = mask;
this.addChild(new ProgressLabel("5.2万")).position.set(102, 72);
this.addChild(new ProgressLabel("52万")).position.set(264, 72);
this.addChild(new ProgressLabel("520万")).position.set(564, 72);
this.miracleTxt = UI.Txt(
this, `当前总奇迹值:0`, 24, "#ffffff",
TEXT_ALIGN.CENTER, 750, 0, 39
);
UI.Txt(
this, `当奇迹值达到520万时,将于519当天揭秘时尚运动代言人`, 22,
"#ffffff", TEXT_ALIGN.CENTER, 750, 0, 119
);
}
}
class ProgressLabel extends Container {
constructor(label: string) {
super();
UI.Sp(this, "progressLabel.png");
const text = UI.Txt(
this, label, 22, "#000000",
TEXT_ALIGN.CENTER, 87, 0, 1.45
);
text.textHeight = 31;
text.verticalAlign = VERTICAL_ALIGN.MIDDLE;
}
}
/*
* Box.ts
* Created by 还有醋v on 2021/4/13.
* Copyright © 2021 haiyoucuv. All rights reserved.
*/
import BaseMaterial = FYGE.BaseMaterial;
import CircleGeometry = FYGE.CircleGeometry;
import Mesh3D = FYGE.Mesh3D;
import Object3D = FYGE.Object3D;
import PlaneGeometry = FYGE.PlaneGeometry;
import Vector2 = FYGE.Vector2;
import { BoxType, getBoxConfig, M_loadGLB, TestFun, typeArr } from "./MT";
/**
* IOutAreaData
* @param out 0 在外 1 在内 2 加分
* @param verFall? 是否直接垂直掉落,超过边界一定值则为true,则需是直接垂直掉落
* @param fallDir? 掉落方向:-1 向负方向 1 向正方形
* @param fallAxis? 掉落轴:"x" | "z"
*/
export interface IOutAreaData {
out: 0 | 1 | 2,
verFall?: boolean,
fallDir?: -1 | 1,
fallAxis?: "x" | "z"
}
/**
* Box
*/
export default class Box extends Object3D {
mesh: Object3D;
point: Object3D;
constructor(public type?: BoxType) {
super();
if (!type) {
this.type = typeArr[Math.random() * typeArr.length >> 0];
// this.type = BoxType.TennisBarrel;
}
// this.type = BoxType.ChocolateShop;
this.init();
}
async init() {
const { ow, oz, ir, dx, dz, src, testFun } = getBoxConfig(this.type);
this.point = this.addChild(new Mesh3D(
new CircleGeometry(ir, 25, 25),
new BaseMaterial({ color: 0xaaaaaa, alpha: 0.8 })
));
this.point.y = 0.65;
this.point.rotationX = -90;
this.point.visible = false;
this.mesh = await M_loadGLB(src);
this.addChild(this.mesh);
this.mesh.children[0].position.set(0, 0, 0);
if(this.type == BoxType.ChocolateShop){
this.mesh.children[0].position.set(53.5, 80, 59);
}else if(this.type == BoxType.TennisBarrel){
this.mesh.children[0].position.set(6.5, 36, 16);
}
// this.useShadow(this.mesh);
this.mesh.x += dx;
this.mesh.z += dz;
/// TODO Test
if (false) {
// this.addChild(new AxesHelper(1000));
const geoP = new PlaneGeometry(ow, oz);
const geoC = new CircleGeometry(ow, 25, 25);
// 落地范围
const meshOut = this.addChild(new Mesh3D(
testFun == "rect" ? geoP : geoC,
new BaseMaterial({ color: 0xff0000, alpha: 0.8 })
));
meshOut.y = 0.66;
meshOut.rotationX = -90;
// 加分点
const meshIn = this.addChild(new Mesh3D(
new CircleGeometry(ir, 25, 25),
new BaseMaterial({ color: 0x00ff00, alpha: 0.8 })
));
meshIn.y = 0.66;
meshIn.rotationX = -90;
}
}
useShadow(v: Object3D) {
this.mesh.castShadow = true;
this.mesh.receiveShadow = true;
v.children.forEach(v => {
v.castShadow = true;
v.receiveShadow = true;
v.children && this.useShadow(v);
});
}
outArea(px: number, pz: number): IOutAreaData {
// px, pz 别人的x和z
const { x: tx, z: tz } = this; // 自己的x,z
// ow oz 外圈,超过即掉出
// ir 内圈半径,在里面则双倍得分
// testFun 检测函数
const { ow, oz, ir, testFun } = getBoxConfig(this.type);
const p = new Vector2(px, pz);
const t = new Vector2(tx, tz);
// 检查外圈 直接不管多余的参数了,js管个p
let testOut = TestFun[testFun](p, t, ow, oz);
// 外圈外返回0
if (!testOut) {
// 圈外计算超出范围是多少,负的是超过,正的是没到
const dv = new Vector2().copy(p).sub(t);
const pd = 0.1; // 超出这个距离为直落地,否则为摔落
let d: number, fallAxis: "x" | "z";
// 其中有一个值必为0
if (dv.x != 0) {
d = Math.abs(dv.x) - ow / 2;
fallAxis = "x";
} else {
d = Math.abs(dv.y) - oz / 2;
fallAxis = "z";
}
return {
out: 0,
verFall: d >= pd,
fallDir: (dv.x + dv.y) > 0 ? 1 : -1,
fallAxis
};
}
// 检查内圈
// 内圈内返回2
const testIn = TestFun.circle(p, t, ir);
return { out: testIn ? 2 : 1 };
}
}
import { GTool } from "../../../module/tools/GTool";
import Box, { IOutAreaData } from "./Box";
import { BoxType, getBoxConfig, getBoxType, typeArr } from "./MT";
import ParticleEmitter from "./Particle";
import Player, { Direction } from "./Player";
import { GameEvent } from "./PlayScene";
import AmbientLight = FYGE.AmbientLight;
import Ease = FYGE.Ease;
import Event = FYGE.Event;
import MouseEvent = FYGE.MouseEvent;
import Scene3D = FYGE.Scene3D;
import Tween = FYGE.Tween;
import Vector3 = FYGE.Vector3;
const cameraPos = new Vector3(5.5, 3.6, 5.2);
export class Jump3d extends Scene3D {
public player: Player;
private cacheBox = {
[BoxType.Cinema]: [],
[BoxType.Cube1]: [],
[BoxType.Cube2]: [],
[BoxType.ChocolateShop]: [],
[BoxType.TennisCourt]: [],
[BoxType.TennisBarrel]: [],
[BoxType.FlowerShop]: [],
[BoxType.FILAShop]: [],
[BoxType.Logo1]: [],
[BoxType.Logo2]: [],
}; // 盒子对象池
private curBox: Box; // 当前盒子
private nextBox: Box; // 下一个盒子
private canMove: boolean = false; // 是否可移动
/**
* 跳跃方向
*/
private direction: Direction = Direction.right;
/**
* 可能要被移除的物体,待回收的物体
*/
private outBox = [];
private pushParticle: ParticleEmitter;
private pushObj: { c: number } = { c: 0 }; // 蓄力
private bonusScore: number = 0; // 连续加分计数
// 停留加分的Tween
private specialBonusTween: Tween = Tween.get({});
// private dirLight: DirectionalLight;
// private plane: Mesh3D;
constructor() {
super();
this.initScene();
this.addEvents();
this.reset();
}
setView(x, y, w, h) {
this.viewX = x;
this.viewY = y;
this.viewWidth = w; //视窗宽度
this.viewHeight = h; //视窗高度
//@ts-ignore
this.camera.set(undefined, w / h, 0.1, 1000.00);
}
async reset() {
// 回收所有的方块
for (let i = this.outBox.length - 1; i >= 0; i--) {
let r = this.outBox[i];
this.removeChild(r);
this.cacheBox[r.type].push(r);
}
this.outBox.length = 0;
// 回收当前方块
if (this.curBox) {
this.removeChild(this.curBox);
this.cacheBox[this.curBox.type].push(this.curBox);
}
if (this.nextBox) {
this.removeChild(this.nextBox);
this.cacheBox[this.nextBox.type].push(this.nextBox);
}
this.pushObj = { c: 0 }; // 蓄力
this.bonusScore = 0; // 连续加分计数
// 初始化Box
this.curBox = this.addChild(new Box(BoxType.Logo2));
this.curBox.position.set(0, 0, 0);
this.nextBox = this.addChild(new Box(BoxType.Cinema));
this.nextBox.position.set(0, 0, -1.7);
this.direction = Direction.right;
// 相机
this.camera.position.copy(cameraPos);
this.moveCamera(0 / 2, -1.7 / 2);
// this.camera.lookAt(this.camera.x - cameraPos.x, 0, this.camera.z - cameraPos.z)
// this.camera.rotation.set(-0.76, 0.77, 0.59, 0);
await this.player.reset();
this.canMove = true; // 可以继续移动了
// 重制粒子位置和lookAt
this.pushParticle.position.copy(this.player.position);
const { x, y, z } = this.camera.position;
this.pushParticle.lookAt(x, y, z);
}
createBox() {
const type = getBoxType();
if (this.cacheBox[type].length) {
return this.cacheBox[type].splice(0, 1)[0];
// return this.cacheBox.shift();
}
return new Box(type);
}
private initScene() {
// 每种盒子加一个
typeArr.forEach((type: BoxType) => {
this.cacheBox[type].push(new Box(type));
});
/// TODO 测试
// 手势移动相机,暂时只有旋转
// this.setOrbitControl({ enablePitch: false, autoRotate: false, userZoom: false, userRotateSpeed: 0.5 });//俯仰不可用
// this.setOrbitControl();
this.addChild(new AmbientLight(0xffffff, 1.0));
// 坐标轴
// this.addChild(new AxesHelper(10000));
// 网格
// this.addChild(new GridHelper(20, 20, 0xffffff, 0x00000));
this.player = this.addChild(new Player());
this.pushParticle = this.addChild(new ParticleEmitter());
}
private onUp = async () => {
this.pushParticle.stop(); // 停止释放聚力粒子
this.nextBox.point.visible = false; // 隐藏加分点
Tween.removeTweens(this.pushObj);
// console.log("jump:", this.pushObj.c);
// 计算起跳参数,位置,方向,距离
const dis = 7 * this.pushObj.c;
let x = this.curBox.x, z = this.curBox.z;
if (this.direction == Direction.left) {
x -= dis;
} else {
z -= dis;
}
await this.jump(x, z, this.direction);
// 跳完设置粒子位置
this.pushParticle.position.copy(this.player.position);
const { x: px, z: pz } = this.player;
// 落在自己内
if (this.curBox.outArea(px, pz).out > 0) {
this.canMove = true; // 可以继续移动了
return;
}
//检查目标方块
const outAreaNext: IOutAreaData = this.nextBox.outArea(px, pz);
if (outAreaNext.out == 0) { // 在外, 死了
await this.die(outAreaNext);
} else { // 在内
// 停留加分
const score = getBoxConfig(this.nextBox.type).score;
if (score != 0) {
this.specialBonusTween = Tween.get({})
.wait(2000)
.call(() => {
this.player.particleEmitter.startLanding();
this.dispatchEvent(GameEvent.AddScore, { add: score });
});
}
// 释放玩家落到方块上到粒子
this.player.particleEmitter.startLanding();
this.outBox.push(this.curBox);
this.curBox = this.nextBox;
let x = this.curBox.x, z = this.curBox.z;
let cx = x, cz = z;
const dis = GTool.randomT(1.72, 3.3);
// const dis = 3.2//GTool.randomT(1.66, 2.6);
if (Math.random() > 0.5) {
this.direction = Direction.left;
x -= dis;
cx -= dis / 2;
} else {
this.direction = Direction.right;
z -= dis;
cz -= dis / 2;
}
this.nextBox = this.addRect(x, z);
this.moveCamera(cx, cz);
// TODO 加分范围内
if (outAreaNext.out == 2) {
this.player.doubleEffect(++this.bonusScore);
this.dispatchEvent(GameEvent.AddScore, { add: this.bonusScore + 4 });
} else {
this.bonusScore = 0;
this.dispatchEvent(GameEvent.AddScore, { add: 1 });
}
this.canMove = true; // 可以继续移动了
}
}
onDown = () => {
if (!this.canMove) return;
this.canMove = false; // 先禁止移动
Tween.removeTweenSelf(this.specialBonusTween);
this.pushParticle.startPush(); // 释放聚力粒子
this.nextBox.point.visible = true; // 显示加分点
this.pushObj = { c: 0 };
Tween.get(this.pushObj, {
onChange: () => {
this.curBox.scaleY = 1 - this.pushObj.c;
this.player.push(this.pushObj.c);
}
})
.to({ c: 0.65 }, 1600, Ease.quadInOut)
.call(() => {
console.log("最大蓄力了");
});
/// TODO 测试
// document.addEventListener("keyup", this.onUp, { once: true });
this.once(MouseEvent.MOUSE_UP, this.onUp);
}
private addEvents() {
/// TODO 测试
// document.addEventListener("keydown", (e) => {
// if (e.code != "Space") return;
// this.onDown();
// });
this.addEventListener(MouseEvent.MOUSE_DOWN, this.onDown);
//循环
this.addEventListener(Event.ENTER_FRAME, this.onUpdate, this);
}
/**
* 根据lookAt位置,移动相机,就是两个物体中间点就行
*/
private moveCamera(x: number, z: number) {
const camX: number = x + cameraPos.x;
const camZ: number = z + cameraPos.z;
this.camera.y = cameraPos.y;
Tween.get(this.camera, {
onChange: () => {
const { x, y, z } = this.camera;
this.camera.lookAt(x - cameraPos.x, 0, z - cameraPos.z)
// this.plane.position.set(x - cameraPos.x, 0, z - cameraPos.z);
// this.dirLight.position.set(x - cameraPos.x + 20, 20, z - 10);
}
}).to({ x: camX, z: camZ }, 500, Ease.sineInOut);
}
private addRect(x: number, z: number) {
const box = this.createBox();
box.position.set(x, 1, z);
this.addChild(box);
Tween.get(box).to({ y: 0 }, 320, Ease.bounceOut);
return box;
}
/**
* 跳
* @param x
* @param z
* @param d
* @private
*/
private jump(x: number, z: number, d: Direction) {
return new Promise((resolve) => {
//恢复吧,或者缓动恢复
this.player.scaleY = 1;
//当前rect的恢复动画
Tween.get(this.curBox).to({ scaleY: 1 }, 300, Ease.getBackOut(2.2));
this.player.jump(x, z).then(resolve); //jump
this.player.rot(d); //旋转
});
}
/**
* 死
* @param oad
* @private
*/
private async die(oad: IOutAreaData) {
console.log(oad, "die");
await this.player.fall(oad, 800);
this.dispatchEvent(GameEvent.GameOver);
}
async revive(): Promise<void> {
await this.player.revive(this.curBox);
this.canMove = true; // 复活后可以继续移动了
}
onUpdate() {
// 移除Rect
for (let i = this.outBox.length - 1; i >= 0; i--) {
let r = this.outBox[i];
let x = this.curBox.x, z = this.curBox.z;
if (r.x > x + 8 || r.z > z + 8) {
this.outBox.splice(i, 1);
this.removeChild(r);
this.cacheBox[r.type].push(r);
}
}
}
}
/*
* MT.ts
* Created by 还有醋v on 2021/4/13.
* Copyright © 2021 haiyoucuv. All rights reserved.
*/
import loadGltf = FYGE.loadGltf;
import { showToast } from "../../../module/ctrls";
import Scene3D = FYGE.Scene3D;
import Vector2 = FYGE.Vector2;
/**
* glb缓存
*/
const glbCache: { [key: string]: Scene3D } = {};
function getGlbFromCache(src) {
const newScene = new Scene3D().copy(glbCache[src]);
newScene.scale.set(0.005, 0.005, 0.005);
return newScene;
}
/**
* 加载glb模型,缓存里有会从缓存里取
* @param src
* @constructor
*/
export async function M_loadGLB(src): Promise<Scene3D> {
return new Promise((resolve) => {
if (glbCache[src]) { // 缓存里有就从缓存里取
return resolve(getGlbFromCache(src));
}
loadGltf(src, (r) => {
glbCache[src] = r.scene; // 保存在Cache里
resolve(getGlbFromCache(src));
}, (e) => {
console.error(e);
resolve(new Scene3D()); // 模型加载失败就返回个空场景,防止外面报错
showToast("加载模型资源失败");
});
});
}
export enum BoxType {
Cinema = "Cinema",
Cube1 = "Cube1",
Cube2 = "Cube2",
ChocolateShop = "ChocolateShop",
TennisCourt = "TennisCourt",
TennisBarrel = "TennisBarrel",
FlowerShop = "FlowerShop",
FILAShop = "FILAShop",
Logo1 = "Logo1",
Logo2 = "Logo2",
}
export const typeArr: BoxType[] = [
BoxType.Cinema,
BoxType.Cube1,
BoxType.Cube2,
BoxType.ChocolateShop,
BoxType.TennisCourt,
BoxType.TennisBarrel,
BoxType.FlowerShop,
BoxType.FILAShop,
BoxType.Logo1,
BoxType.Logo2,
];
// 加分点范围
const ir = 0.06;
export const GlobalConfig: {
playerConfig: { src: string, tbsrc: string },
boxConfig: {
[key in BoxType]: {
src: string,
tbsrc: string,
ow: number, oz: number,
dx: number, dz: number,
ir: number,
testFun: string,
score: number,
}
}
} = {
playerConfig: {
src: "https://yun.duiba.com.cn/aurora/assets/80244821c29db4c619fe3f0c90d57132d149d9bf.glb",
tbsrc: "cloud://CEAE1CD8B6B8EAF842FD9754CF064639//棋子.glb",
},
boxConfig: {
[BoxType.Cinema]: {
src: "https://yun.duiba.com.cn/aurora/assets/ca66f10db4bb98c483a612c2196a2baccf68f9ba.glb",
tbsrc: "cloud://9C90F5DA62F3DD1FC7C8EB0657CB867D//电影院.glb",
ow: 0.96, oz: 0.94,
dx: 0.07, dz: 0.02,
ir: ir, testFun: "rect",
score: 0,
},
[BoxType.Cube1]: {
src: "https://yun.duiba.com.cn/aurora/assets/660b0f9479686ee3efdbefea233d9cfec66573b1.glb",
tbsrc: "cloud://F672EE52A61F3CFEA2CD455EC3AC3920//立方体1.glb",
ow: 0.83, oz: 0.83,
dx: 0, dz: 0,
ir: ir, testFun: "rect",
score: 0,
},
[BoxType.Cube2]: {
src: "https://yun.duiba.com.cn/aurora/assets/cc85f0cd4f030874e60966c891d30f79ef0be927.glb",
tbsrc: "cloud://78804605CF45221AD835915687B35908//立方体2.glb",
ow: 0.87, oz: 0.88,
dx: 0, dz: 0,
ir: ir, testFun: "rect",
score: 0,
},
[BoxType.ChocolateShop]: {
src: "https://yun.duiba.com.cn/aurora/assets/f9fec8a8bcce73e23eb17b824eda33202daecf2f.glb",
tbsrc: "cloud://D60F1E52845A434408A338CE2037D53F//巧克力店.glb",
ow: 0.65, oz: 0.65,
dx: 0.01, dz: 0.01,
ir: ir, testFun: "circle",
score: 0,
},
[BoxType.FlowerShop]: {
src: "https://yun.duiba.com.cn/aurora/assets/0fcff8d4762f24f468d07f1671a5a8482b88ff41.glb",
tbsrc: "cloud://5F122FEF16478E0BBEBE63D7B0B71539//花店.glb",
ow: 0.8, oz: 0.91,
dx: 0.024, dz: -0.031,
ir: ir, testFun: "rect",
score: 0,
},
[BoxType.FILAShop]: {
src: "https://yun.duiba.com.cn/aurora/assets/d4da10c0518b98a58c6bee9f720a6680fd726925.glb",
tbsrc: "cloud://4153569ADBB267C5C29A60A2076AF812//file店铺.glb",
ow: 0.92, oz: 1.18,
dx: 0, dz: 0.02,
ir: ir, testFun: "rect",
score: 15,
},
[BoxType.TennisCourt]: {
src: "https://yun.duiba.com.cn/aurora/assets/1e556dbdb1e60a31f87d5e386f2a0a027fd90397.glb",
tbsrc: "cloud://73E2BDD33A55C202BBE979A93954E0F5//网球场.glb",
ow: 1.2, oz: 1.665,
dx: 0, dz: 0,
ir: ir, testFun: "rect",
score: 0,
},
[BoxType.TennisBarrel]: {
src: "https://yun.duiba.com.cn/aurora/assets/a454a74ba50bc1d6801e510e9355be1de8ac8cda.glb",
tbsrc: "cloud://CDD8F47A6945FE70A0D15ABF36875356//网球桶.glb",
ow: 0.35, oz: 0.35,
dx: 0, dz: 0,
ir: ir, testFun: "circle",
score: 0,
},
[BoxType.Logo1]: {
src: "https://yun.duiba.com.cn/aurora/assets/74d4d08652acd570d5013226e80f22d0929c596c.glb",
tbsrc: "cloud://7920741060B24380DBE357505D146877//LOGO1.glb",
ow: 0.84, oz: 0.884,
dx: -0.09, dz: 0.005,
ir: ir, testFun: "rect",
score: 10,
},
[BoxType.Logo2]: {
src: "https://yun.duiba.com.cn/aurora/assets/00e19f936170dbe9b09eb5dcd2c47e476a9c271b.glb",
tbsrc: "cloud://92D7323E60199169EF79C8762BEC112A//logo2.glb",
ow: 0.92, oz: 0.92,
dx: 0, dz: 0,
ir: ir, testFun: "rect",
score: 0,
},
},
}
export function getBoxConfig(type: BoxType) {
const config = GlobalConfig.boxConfig[type];
if (FYGE.getEnv() == 'tb') {
config.src = config.tbsrc;
}
return config;
}
export function getPlayerConfig() {
const config = GlobalConfig.playerConfig;
if (FYGE.getEnv() == 'tb') {
config.src = config.tbsrc;
}
return config;
}
/**
* 检测点是否在内
*/
export const TestFun = {
/**
* 检测矩形
* @param p 点
* @param c 中心点
* @param w 宽度
* @param h 高度
*/
rect: function (p: Vector2, c: Vector2, w: number, h: number): boolean {
const pc = new Vector2().copy(p).sub(c);
return !(Math.abs(pc.x) > w / 2 || Math.abs(pc.y) > h / 2);
},
/**
* 检测圆形
* @param p 点
* @param c 圆点
* @param r 半径
*/
circle: function (p: Vector2, c: Vector2, r: number): boolean {
return p.distanceTo(c) <= r;
}
}
const probabilityConfig: { key: BoxType, probability: number }[] = [
{
key: BoxType.Cinema,
probability: 12,
},
{
key: BoxType.Cube1,
probability: 13,
},
{
key: BoxType.Cube2,
probability: 13,
},
{
key: BoxType.ChocolateShop,
probability: 8,
},
{
key: BoxType.FlowerShop,
probability: 12,
},
{
key: BoxType.TennisCourt,
probability: 8,
},
{
key: BoxType.TennisBarrel,
probability: 19,
},
{
key: BoxType.FILAShop,
probability: 1,
},
{
key: BoxType.Logo1,
probability: 2,
},
{
key: BoxType.Logo2,
probability: 12,
},
];
probabilityConfig.sort((a, b) => {
return a.probability - b.probability;
});
let pTotal = 0;
probabilityConfig.forEach((v) => {
pTotal = (v.probability += pTotal);
});
export const getBoxType = (): BoxType => {
const p = Math.random() * pTotal;
for (let last = 0, now = 1; now < probabilityConfig.length; last++, now++) {
const l = probabilityConfig[last];
const n = probabilityConfig[now];
if (p > l.probability && p <= n.probability) {
return n.key;
}
}
return BoxType.Cinema;
}
/*
* MusicBtn.ts
* Created by 还有醋v on 2021/4/27.
* Copyright © 2021 haiyoucuv. All rights reserved.
*/
import Button = FYGE.Button;
import Container = FYGE.Container;
import Texture = FYGE.Texture;
import MouseEvent = FYGE.MouseEvent;
import { sendTbNet, TbNetName } from "../../TaoBaoNet";
export default class MusicBtn extends Container {
private static status = true;
private static btns: MusicBtn[] = [];
public static changeMusicStatus(status: boolean) {
MusicBtn.status = status;
MusicBtn.btns.forEach((v) => {
v.btn.changeTexture(status ? v.on : v.off);
});
sendTbNet(TbNetName.openMusic, { isOn: status });
}
private btn: Button;
constructor(private on: Texture, private off: Texture) {
super();
this.btn = this.addChild(new Button(MusicBtn.status ? this.on : this.off));
this.btn.addEventListener(MouseEvent.CLICK, MusicBtn.onClick, this);
MusicBtn.btns.push(this);
}
private static onClick() {
MusicBtn.changeMusicStatus(!MusicBtn.status);
}
destroy() {
super.destroy();
MusicBtn.btns.splice(MusicBtn.btns.indexOf(this), 1);
this.btn.removeEventListener(MouseEvent.CLICK, MusicBtn.onClick, this);
}
}
/*
* Particle.ts
* Created by 还有醋v on 2021/4/9.
* Copyright © 2021 haiyoucuv. All rights reserved.
*/
import { GTool } from "../../../module/tools/GTool";
import Object3D = FYGE.Object3D;
import Mesh3D = FYGE.Mesh3D;
import CircleGeometry = FYGE.CircleGeometry;
import BaseMaterial = FYGE.BaseMaterial;
import Tween = FYGE.Tween;
const particleGeo = new CircleGeometry(0.015, 25, 25);
const particleMatGreen = new BaseMaterial({ color: 0x00ff00 });
const particleMatWhite = new BaseMaterial({ color: 0xffffff });
/**
* 粒子
*/
class Particle extends Mesh3D {
constructor() {
super(particleGeo, particleMatWhite);
}
}
/**
* 粒子发射器
*/
export default class ParticleEmitter extends Object3D {
particles: Particle[] = [];
cacheParticles: Particle[] = [];
constructor() {
super();
}
private startTween;
startLanding() {
for (let i = 0; i < 20; i++) {
const p = this.createParticle();
p.position.set(
GTool.randomT(-0.3, 0.3),
GTool.randomT(-1.5, 0.5),
GTool.randomT(-0.3, 0.3)
);
p.material = particleMatWhite;
this.particles.push(p);
this.addChild(p);
Tween.get(p.position)
.to({ x: p.position.x, y: 0.8, z: p.position.z }, GTool.randomT(300, 1000))
.call(() => {
this.removeChild(p);
this.cacheParticles.push(p);
});
}
setTimeout(() => {
this.stop();
}, 1800);
}
startPush() {
this.startTween = Tween.get(this, { loop: true })
.call(() => {
for (let i = 0; i < 20; i++) {
const p = this.createParticle();
const rang = 0.7;
p.position.set(
GTool.randomT(-rang, rang),
GTool.randomT(-rang, rang),
GTool.randomT(-rang, rang)
);
p.material = Math.random() < 0.3 ? particleMatGreen : particleMatWhite;
this.particles.push(p);
this.addChild(p);
Tween.get(p.position)
.to({ x: 0, y: 0, z: 0 }, GTool.randomT(300, 1800))
.call(() => {
this.removeChild(p);
this.cacheParticles.push(p);
});
}
})
.wait(600);
}
stop() {
Tween.removeTweens(this);
this.particles.forEach((p) => {
this.removeChild(p);
this.cacheParticles.push(p);
Tween.removeTweens(p.position);
});
this.particles.length = 0;
}
createParticle(): Particle {
if (this.cacheParticles.length) return this.cacheParticles.shift();
return new Particle();
}
}
import { changeScene, showPanel, showToast } from "../../../module/ctrls";
import { RES } from "../../../module/RES";
import { layers } from "../../../module/views/layers";
import { Scene } from "../../../module/views/Scene";
import { OverNoPrizePanel } from "../../panels/OverNoPrizePanel";
import { OverPrizePanel } from "../../panels/OverPrizePanel";
import { RevivePanel } from "../../panels/RevivePanel";
import { sendTbNet, TbNetName } from "../../TaoBaoNet";
import { sleep, Tools } from "../../Tools";
import UI from "../../UI";
import { IndexScene } from "../IndexScene";
import { Jump3d } from "./Jump3d";
import MusicBtn from "./MusicBtn";
import BitmapText = FYGE.BitmapText;
import TEXT_ALIGN = FYGE.TEXT_ALIGN;
import Tween = FYGE.Tween;
import Event = FYGE.Event;
import Ease = FYGE.Ease;
import Shape = FYGE.Shape;
import Container = FYGE.Container;
import MouseEvent = FYGE.MouseEvent;
export enum GameEvent {
AddScore = "AddScore",
GameOver = "GameOver",
}
export class PlayScene extends Scene {
get groupNames(): string[] {
return ["game"];
}
scoreTxt: BitmapText;
musicButton: MusicBtn;
jump3d: Jump3d;
addScoreLabel: BitmapText;
private _score: number = 0;
public get score(): number {
return this._score;
}
public set score(score: number) {
this._score = score;
this.scoreTxt.text = score + '';
}
async initUi() {
UI.Sp(this, "com_bg.jpg");
// 第一次游戏新手引导
if (this.data.startData.isFirstEnterGame) {
await this.showGuide();
}
// @ts-ignore
const jump3d: Jump3d = this.jump3d = this.addChild(new Jump3d());
jump3d.setView(0, layers.stageOffsetY, layers.stageWidth, layers.stageHeight);
jump3d.addEventListener(GameEvent.AddScore, this.addScore, this);
jump3d.addEventListener(GameEvent.GameOver, this.gameOver, this);
// 音乐按钮
this.musicButton = this.addChild(
// new Button(RES.getRes("gameMusicOn.png"))
new MusicBtn(RES.getRes("gameMusicOn.png"), RES.getRes("gameMusicOff.png"))
);
this.musicButton.position.set(636, layers.stageOffsetY + 265 * layers.stageOffsetY / 422);
this.musicButton.position.set(636, 265);
// 分数
const txtObj = Tools.getNumTextures('gameScore');
txtObj["+"] = RES.getRes("gameScore+.png");
this.scoreTxt = this.addChild(new BitmapText(txtObj));
this.scoreTxt.text = "0";
this.scoreTxt.textAlign = TEXT_ALIGN.LEFT;
this.scoreTxt.position.set(65, layers.stageOffsetY + 305 * layers.stageOffsetY / 422);
this.scoreTxt.position.set(65, 305);
// 加分
this.addScoreLabel = this.addChild(new BitmapText(txtObj));
this.addScoreLabel.position.set(100, 1000);
this.addScoreLabel.scale.set(0.5, 0.5);
this.addEventListener(Event.ENTER_FRAME, () => {
this.addScoreLabel.position.x = this.jump3d.player.stagePos.x;
});
}
/**
* 展示新手引导
*/
async showGuide() {
return new Promise<void>((resolve) => {
const group = this.addChild(new Container());
const bg = group.addChild(new Shape());
bg.beginFill(0x000000, 0.8);
bg.drawRect(0, 0, 750, 1624);
bg.endFill();
UI.Sp(group, "guide.png", 100, 700);
group.once(MouseEvent.CLICK, () => {
this.removeChild(group);
resolve();
});
});
}
destroy() {
super.destroy();
}
/**
* 加分
* @param e
*/
addScore(e) {
console.log("加分", e.data);
this.score += e.data.add;
this.addScoreLabel.text = `+${e.data.add}`;
const _y = this.jump3d.player.stagePos.y;
Tween.get(this.addScoreLabel)
.set({ visible: true, alpha: 2, y: _y })
.to({ y: _y - 100, alpha: 0 }, 1500, Ease.quadOut)
.set({ visible: false });
}
/**
* 游戏结束
* @param e
*/
async gameOver(e) {
const { gameId, beMember, isFirstEnterGame } = this.data.startData;
if (!beMember && isFirstEnterGame) { // 非店铺会员且首次游戏
// 引导入会 复活
showPanel(RevivePanel, {
gameId: this.data.startData.gameId,
submit: this.submitGame,
revive: this.reviveGame
});
return;
}
this.submitGame();
}
/**
* 复活
*/
reviveGame = async () => {
this.data.startData.beMember = true;
await sleep(500);
this.jump3d.revive();
}
/**
* 提交
*/
submitGame = async () => {
const { success, data, message } = await sendTbNet(TbNetName.submitGame, {
gameId: this.data.startData.gameId,
score: this.score,
isGetPrize: this.score >= 520
});
if (!success) {
showToast(message);
await sleep(1000);
changeScene(IndexScene);
return;
}
const { prizeInfo, score, getScore, maxScore, gameTimes, avatar, userNick, rank } = data;
Tools.gameInfo.gameTimes = gameTimes;
if (
!prizeInfo
|| JSON.stringify(prizeInfo) == JSON.stringify({})
|| prizeInfo.type == 5
) { // 没奖励或者谢谢参与
showPanel(OverNoPrizePanel, { score: this.score, gameTimes });
} else {
showPanel(OverPrizePanel, { score: this.score, prizeInfo, gameTimes });
}
}
}
import { IOutAreaData } from "./Box";
import { getPlayerConfig, M_loadGLB } from "./MT";
import ParticleEmitter from "./Particle";
import Object3D = FYGE.Object3D;
import Tween = FYGE.Tween;
import Ease = FYGE.Ease;
import Mesh3D = FYGE.Mesh3D;
import BaseMaterial = FYGE.BaseMaterial;
import RingGeometry = FYGE.RingGeometry;
export enum Direction {
/**
* -x方向
*/
left = 0,
/**
* -z方向
*/
right
}
const playY = 0.77;
const ringGeo = new RingGeometry(0.14, 0.21, 30, 1);
/**
* 玩家
*/
export default class Player extends Object3D {
particleEmitter: ParticleEmitter;
mesh: Object3D;
constructor() {
super();
this.init();
}
async init() {
const config = getPlayerConfig();
const mesh = this.mesh = await M_loadGLB(config.src);
// this.mesh.scale.set(0.0025, 0.0025, 0.0025);
this.mesh.scale.set(0.004, 0.004, 0.004);
this.mesh.children[0].y = -35;
// this.mesh.children[0].castShadow = true;
// this.mesh.children[0].receiveShadow = true;
this.addChild(mesh);
this.particleEmitter = this.addChild(new ParticleEmitter());
const { x, y, z } = this.scene.camera.position;
this.particleEmitter.lookAt(x, y, z);
}
async reset(): Promise<void> {
return new Promise((resolve) => {
this.rotation.set(0, 0, 0, 0);
this.position.set(0, playY + 1, 0);
Tween.get(this)
.to({ y: playY }, 1000, Ease.bounceOut)
.call(resolve);
});
}
async jump(x, z) {
return new Promise((resolve) => {
//y向上跳;
Tween.get(this)
.to({ y: 1.5 }, 250, Ease.quadOut)
.to({ y: playY }, 250, Ease.quadIn);
//位移
Tween.get(this)
.to({ x, z }, 500)
.call(resolve);
});
}
/**
* 蓄力
*/
push(s: number) {
this.scaleY = 1 - s;
//位置也要往下
this.y = playY - s / 2 - 0.13 * s / 0.5;
}
rot(d: Direction) {
let k = "rotationX", c = this.mesh;
if (d == Direction.left) k = "rotationZ";
Tween.get(c)
.to({ [k]: k == "rotationX" ? -360 : 360 }, 500)
.call(() => {
c[k] = 0;
});
}
/**
* 落到加分范围内的动画
* @param count 连续几次
*/
doubleEffect(count: number = 1): void {
for (let i = 0; i < count; i++) {
Tween.get({})
.wait(180 * i)
.call(() => {
const ring = this.scene.addChild(new Mesh3D(
ringGeo,
new BaseMaterial({ color: 0xffffff, alpha: 1 })
));
ring.position.copy(this.position);
ring.y += 0.01 * i; // 防止面重叠渲染出错
ring.rotationX = -90;
Tween.get(ring.material)
.to({ alpha: 0 }, 1000, Ease.quartOut);
Tween.get(ring)
.to({ scaleX: 5, scaleY: 5 }, 800, Ease.quartOut)
.call(() => {
this.scene.removeChild(ring);
});
});
}
}
/**
* 跌落
* @param oad IOutAreaData
* @param wait 动画完成后等待时间
*/
async fall(oad: IOutAreaData, wait): Promise<void> {
/**
* IOutAreaData
* @param out 0 在外 1 在内 2 加分
* @param fall? 是否掉落,超过边界一定值则为true,则需要掉落
* @param fallDir? 掉落方向:-1 向负方向 1 向正方形
* @param fallAxis? 掉落轴:"x" | "z"
*/
// fall: true
// fallAxis: "z"
// fallDir: 1
// out: 0
return new Promise((resolve) => {
if (oad.verFall) { // 垂直落地
Tween.get(this)
.to({ y: 0.15 }, 130)
.wait(wait)
.call(resolve);
} else { // 摔落
const { fallDir: fd, fallAxis: fa } = oad;
const r = 90 * fd * (fa == "x" ? -1 : 1);
Tween.get(this)
.wait(50)
.to({
y: 0.08,
[fa]: this[fa] + 0.2 * fd,
[`rotation${fa == "x" ? "Z" : "X"}`]: r
}, 230, Ease.quadIn)
.wait(wait)
.call(resolve);
}
});
}
/**
* 复活
* @param box 要停在哪个盒子上
*/
async revive(box): Promise<void> {
return new Promise((resolve) => {
Tween.get(this)
.to({
y: playY,
rotationX: 0,
rotationY: 0,
rotationZ: 0,
}, 750, Ease.quartOut);
Tween.get(this)
.to({
x: box.x,
z: box.z
}, 750, Ease.quadIn)
.call(resolve);
});
}
}
/**
* @author oosmoxiecode
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
import Geometry = FYGE.Geometry;
import Vector3 = FYGE.Vector3;
export class TorusGeometry extends Geometry {
constructor(
radius = 1,
tube = 0.4,
radialSegments = 8,
tubularSegments = 6,
arc = Math.PI * 2
) {
radialSegments = Math.floor(radialSegments);
tubularSegments = Math.floor(tubularSegments);
// buffers
const indices = [];
const vertices = [];
const normals = [];
const uvs = [];
// helper variables
const center = new Vector3();
const vertex = new Vector3();
const normal = new Vector3();
let j, i;
// generate vertices, normals and uvs
for (j = 0; j <= radialSegments; j++) {
for (i = 0; i <= tubularSegments; i++) {
var u = i / tubularSegments * arc;
var v = j / radialSegments * Math.PI * 2;
// vertex
vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u);
vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u);
vertex.z = tube * Math.sin(v);
vertices.push(vertex.x, vertex.y, vertex.z);
// normal
center.x = radius * Math.cos(u);
center.y = radius * Math.sin(u);
normal.subVectors(vertex, center).normalize();
normals.push(normal.x, normal.y, normal.z);
// uv
uvs.push(i / tubularSegments);
uvs.push(j / radialSegments);
}
}
// generate indices
for (j = 1; j <= radialSegments; j++) {
for (i = 1; i <= tubularSegments; i++) {
// indices
const a = (tubularSegments + 1) * j + i - 1;
const b = (tubularSegments + 1) * (j - 1) + i - 1;
const c = (tubularSegments + 1) * (j - 1) + i;
const d = (tubularSegments + 1) * j + i;
// faces
indices.push(a, b, d);
indices.push(b, c, d);
}
}
super(vertices, indices, normals, null, uvs);
}
}
import { RES } from "../../module/RES";
import { Scene } from "../../module/views/Scene";
import { LoadingEffect } from "../lotties/LoadingEffect";
import { changeScene } from "../../module/ctrls";
import UI from "../UI";
import { getBoxConfig, M_loadGLB, typeArr } from "./Jump3D/MT";
import { PlayScene } from "./Jump3D/PlayScene";
import Lottie = FYGE.Lottie;
import Tween = FYGE.Tween;
import Event = FYGE.Event;
export class LoadingScene extends Scene {
get groupNames(): string[] {
return [
'loading',
'LoadingEffect',
]
}
initUi() {
UI.Sp(this, "com_bg.jpg");
UI.Sp(this, "loading_title.png", 115, 356);
const ani = this.addChild(new Lottie(LoadingEffect));
ani.y = 710;
ani.play();
}
async start() {
super.start()
this.addEventListener(Event.PROGRESS, this.progressEvent, this);
const loadPromise = [];
let pro = 0.0;
for (let k of typeArr) {
const config = getBoxConfig(k);
loadPromise.push((async () => {
await M_loadGLB(config.src);
this.dispatchEvent(Event.PROGRESS, pro += 0.8 / typeArr.length);
})());
// await M_loadGLB(config.src);
// this.dispatchEvent(Event.PROGRESS, pro += 0.8 / typeArr.length);
}
await Promise.all(loadPromise);
await RES.loadGroup("game");
this.dispatchEvent(Event.PROGRESS, 0.9);
this.dispatchEvent(Event.PROGRESS, 1);
}
progressEvent(e: Event) {
let pro = e.data;
Tween.get({}, null, null, true)
.to({ value: pro }, 0)
.call(() => {
if (pro >= 1) {
this.removeEventListener(Event.PROGRESS, this.progressEvent, this);
changeScene(PlayScene, { startData: this.data.startData });
// sendTbNet(TbNetName.openMusic, { isOn: true });
}
});
}
destroy() {
//动效要去掉
// Tween.removeTweens()
super.destroy()
//到时如果内存炸了,考虑销毁用过的贴图缓存,待测试,在RES里写个根据销毁组内贴图的方法
}
}
{
"compilerOptions": {
"module": "ESNext",
"target": "ESNext",
"noImplicitAny": false,
"sourceMap": true,
"allowJs": true,
"noUnusedLocals": false,
"moduleResolution": "Node",
"removeComments": true,
"outDir": "dist",
/*"outFile": "./index.js",*/
"lib": [
"es5",
"dom",
"es2015.promise"
]
},
"exclude": [
"node_modules"
]
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment