Commit 43990b1d authored by 张世斌's avatar 张世斌

1.修复bug

parent 39292dd9
This diff is collapsed.
...@@ -130,10 +130,12 @@ cc.Class({ ...@@ -130,10 +130,12 @@ cc.Class({
this.bindColorButton(item); this.bindColorButton(item);
} }
this._alligator = this.bindAlligator(this.paint); // this._alligator = this.bindAlligator(this.paint);
this._alligator2 = this.bindAlligator(this.paint2); // this._alligator2 = this.bindAlligator(this.paint2);
this._alligator = this.paint.getChildByName("alligator");//children[0];//this.bindAlligator(this.paint);
this._alligator2 = this.paint2.getChildByName("alligator");;//children[0];//this.bindAlligator(this.paint2);
this.bindAlligatorButton(this._alligator); // this.bindAlligatorButton(this._alligator);
this.btn_submit.node.on('click', () => { this.btn_submit.node.on('click', () => {
...@@ -217,28 +219,59 @@ cc.Class({ ...@@ -217,28 +219,59 @@ cc.Class({
this.btn_submit.node.active = false; this.btn_submit.node.active = false;
}, },
// copyColor() {
// let a1 = this._alligator;
// let a2 = this._alligator2;
// let len = a1.teeth.length;
// for (let i = 0; i < len; i++) {
// a2.teeth[i].color = a1.teeth[i].color;
// a2.teeth[i].word.node.color = a1.teeth[i].word.node.color;
// a2.teeth[i].word.string = a1.teeth[i].word.string;
// }
// },
copyColor() { copyColor() {
let a1 = this._alligator; let a1 = this._alligator;
let a2 = this._alligator2; let a2 = this._alligator2;
let len = a1.teeth.length; let len = a1.teeth.length;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
a2.teeth[i].color = a1.teeth[i].color; let node=cc.instantiate(a1.teeth[i]);
a2.teeth[i].word.node.color = a1.teeth[i].word.node.color; a2.addChild(node);
a2.teeth[i].word.string = a1.teeth[i].word.string; // a2.teeth[i].color = a1.teeth[i].color;
// a2.teeth[i].word.node.color = a1.teeth[i].word.node.color;
// a2.teeth[i].word.string = a1.teeth[i].word.string;
} }
}, },
initAlligator(node, words) { async initAlligator(parent) {
let tooth, len = node.teeth.length; for(let i=0;i<this.data.images.length;i++){
for (let i = 0; i < len; i++) { let image=this.data.images[i];
tooth = node.teeth[i]; let tooth=await this.getSprNodeByUrl(image.img);
tooth.color = cc.Color.WHITE; parent.addChild(tooth);
tooth.word.node.color = cc.Color.BLACK; // tooth.color = cc.Color.WHITE;
tooth.painted = null; tooth.painted = null;
tooth.word.string = words[i];
} }
// let tooth, len = node.teeth.length;
// for (let i = 0; i < len; i++) {
// tooth = node.teeth[i];
// tooth.color = cc.Color.WHITE;
// tooth.word.node.color = cc.Color.BLACK;
// tooth.painted = null;
// tooth.word.string = words[i];
// }
}, },
// async initAlligator(parent) {
// for(let i=0;i<this.data.images.length;i++){
// let image=this.data.images[i];
// let tooth=await this.getSprNodeByUrl(image.img);
// parent.addChild(tooth);
// // tooth.color = cc.Color.WHITE;
// tooth.painted = null;
// }
// },
bindAlligator(parent) { bindAlligator(parent) {
let node = parent.children[0]; let node = parent.children[0];
...@@ -246,7 +279,7 @@ cc.Class({ ...@@ -246,7 +279,7 @@ cc.Class({
let len = node.children.length; let len = node.children.length;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
teeth[i] = node.children[i]; teeth[i] = node.children[i];
teeth[i].word = teeth[i].children[0].getComponent(cc.Label); // teeth[i].word = teeth[i].children[0].getComponent(cc.Label);
} }
node.teeth = teeth; node.teeth = teeth;
...@@ -354,7 +387,7 @@ cc.Class({ ...@@ -354,7 +387,7 @@ cc.Class({
const btn = cc.find('Canvas/bg/btnReplay'); const btn = cc.find('Canvas/bg/btnReplay');
if (btn.active) { if (btn.active) {
playDragonBoneAnimation(this.coolcat, 'finish', -1); playDragonBoneAnimation(this.coolcat, 'finish', -1);
this.playAudioByUrl(this.data.endAudio, () => { this.playAudioByUrl(this.data.finishAudio, () => {
playDragonBoneAnimation(this.coolcat, 'normal', -1); playDragonBoneAnimation(this.coolcat, 'normal', -1);
}); });
} else { } else {
...@@ -366,24 +399,37 @@ cc.Class({ ...@@ -366,24 +399,37 @@ cc.Class({
}); });
}, },
updateItem() { async updateItem() {
this._submitted = false; this._submitted = false;
this.cleanColor(); this.cleanColor();
this.coolcat.active = true; this.coolcat.active = true;
// let info = this.data.items[this._index]; let spriteFrame=await this.getSpriteFrimeByUrl(this.data.bg);
// let words = info.words.split(''); let bg1=this.paint.getChildByName("bg_img");
// let answers = info.answers.split(''); // this.log("bg:"+bg1.name);
let words = 'aAcBaCbA'.split(''); bg1.getComponent(cc.Sprite).spriteFrame=spriteFrame;
let answers = '0147'.split('');
this._timeoutIds.push(setTimeout(() => { let bg2=this.paint2.getChildByName("bg_img");
this.initAlligator(this._alligator, words); bg2.getComponent(cc.Sprite).spriteFrame=spriteFrame;
}, 1));
console.log(words, answers); this._alligator.destroyAllChildren();
this._ids = answers; this._alligator2.destroyAllChildren();
this._id_count = answers.length; // this._timeoutIds.push(setTimeout(() => {
await this.initAlligator(this._alligator);
// }, 1));
this._alligator = this.bindAlligator(this.paint);
this._alligator2 = this.bindAlligator(this.paint2);
this.bindAlligatorButton(this._alligator);
// console.log(words, answers);
this._ids=[];
for(let i=0;i<this.data.images.length;i++){
this._ids[i]=i;
}
// this._ids = answers;
this._id_count = this._ids.length;
console.log(' coolcat play ') console.log(' coolcat play ')
...@@ -440,26 +486,45 @@ cc.Class({ ...@@ -440,26 +486,45 @@ cc.Class({
}, },
getSpriteFrimeByUrl(url, cb) { async getSpriteFrimeByUrl(url, cb) {
return new Promise((resolve)=>{
cc.loader.load({ url }, (err, img) => { cc.loader.load({ url }, (err, img) => {
const spriteFrame = new cc.SpriteFrame(img) const spriteFrame = new cc.SpriteFrame(img)
if (cb) { resolve(spriteFrame);
cb(spriteFrame); // if (cb) {
} // cb(spriteFrame);
// }
}) })
});
}, },
getSprNodeByUrl(url, cb) { async getSprNodeByUrl(url) {
const node = new cc.Node(); const node = new cc.Node();
const spr = node.addComponent(cc.Sprite); const spr = node.addComponent(cc.Sprite);
this.getSpriteFrimeByUrl(url, (sf) => { spr.spriteFrame=await this.getSpriteFrimeByUrl(url);
spr.spriteFrame = sf; return node;
if (cb) {
cb(node);
}
})
}, },
// getSpriteFrimeByUrl(url, cb) {
// cc.loader.load({ url }, (err, img) => {
// const spriteFrame = new cc.SpriteFrame(img)
// if (cb) {
// cb(spriteFrame);
// }
// })
// },
// getSprNodeByUrl(url, cb) {
// const node = new cc.Node();
// const spr = node.addComponent(cc.Sprite);
// this.getSpriteFrimeByUrl(url, (sf) => {
// spr.spriteFrame = sf;
// if (cb) {
// cb(node);
// }
// })
// },
playAudioByUrl(audio_url, cb = null) { playAudioByUrl(audio_url, cb = null) {
if (!audio_url) { if (!audio_url) {
cb && cb(); cb && cb();
...@@ -488,6 +553,7 @@ cc.Class({ ...@@ -488,6 +553,7 @@ cc.Class({
console.log('isCanFinish:', isCanFinish); console.log('isCanFinish:', isCanFinish);
if (isCanFinish) { if (isCanFinish) {
this.playAudioByUrl(this.data.finishAudio);
this.submitBtnClick(); this.submitBtnClick();
} }
}, },
...@@ -541,38 +607,61 @@ cc.Class({ ...@@ -541,38 +607,61 @@ cc.Class({
if (this.color_selector.active == false) if (this.color_selector.active == false)
return; return;
// console.log('area:' + sprite.t_idx);
let find_id = this._ids.indexOf(sprite.t_idx + '');
if (find_id >= 0) {
this._ids[find_id] = -1;
// if (this.btn_submit.node.active == false) {
// this.btn_submit.node.active = true;
// }
//correct //correct
playDragonBoneAnimation(this.coolcat, 'right', -1); playDragonBoneAnimation(this.coolcat, 'right', -1);
this.playAudioByName('correct', () => { this.playAudioByUrl(this.data.rightAudio,()=>{
playDragonBoneAnimation(this.coolcat, 'normal', -1); playDragonBoneAnimation(this.coolcat, 'normal', -1);
this._can_tap = true; this._can_tap = true;
});
this.playAudioByName('painted');
}
else {
//incorrect
this._can_tap = false;
playDragonBoneAnimation(this.coolcat, 'wrong', -1);
this.playAudioByName('incorrect', () => {
playDragonBoneAnimation(this.coolcat, 'normal', -1);
this._can_tap = true;
});
return;
}
this._ids[tooth.t_idx]=-1;
sprite.painted = true; sprite.painted = true;
sprite.color = this._color; sprite.color = this._color;
sprite.word.node.color = cc.Color.WHITE; // sprite.word.node.color = cc.Color.WHITE;
this.tryFinish(); this.tryFinish();
})
// this.playAudioByName('correct', () => {
// playDragonBoneAnimation(this.coolcat, 'normal', -1);
// this._can_tap = true;
// });
this.playAudioByName('painted');
// // console.log('area:' + sprite.t_idx);
// let find_id = this._ids.indexOf(sprite.t_idx + '');
// if (find_id >= 0) {
// this._ids[find_id] = -1;
// // if (this.btn_submit.node.active == false) {
// // this.btn_submit.node.active = true;
// // }
// //correct
// playDragonBoneAnimation(this.coolcat, 'right', -1);
// this.playAudioByName('correct', () => {
// playDragonBoneAnimation(this.coolcat, 'normal', -1);
// this._can_tap = true;
// });
// this.playAudioByName('painted');
// }
// else {
// //incorrect
// this._can_tap = false;
// playDragonBoneAnimation(this.coolcat, 'wrong', -1);
// this.playAudioByName('incorrect', () => {
// playDragonBoneAnimation(this.coolcat, 'normal', -1);
// this._can_tap = true;
// });
// return;
// }
// this._ids[tooth.t_idx]=-1;
// sprite.painted = true;
// sprite.color = this._color;
// // sprite.word.node.color = cc.Color.WHITE;
// this.tryFinish();
}); });
sprite._hitTest = this._hitTest.bind(this); sprite._hitTest = this._hitTest.bind(this);
......
{
"ver": "1.1.2",
"uuid": "41970e8e-5322-4f22-9782-9531f4e45289",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}
\ No newline at end of file
import Manager from "./Manager/Manager"
import SoundMgr from "./Manager/SoundMgr"
import AssetMgr from "./Manager/AssetMgr"
import ViewMgr from "./Manager/ViewMgr"
import LayerMgr from "./Manager/LayerMgr"
import ModuleMgr from "./Manager/ModuleMgr"
import LoopMgr from "./Manager/LoopMgr"
import { EventConst } from "./ConstDefine/EventConst"
import GameUpdateMgr from "./Manager/GameUpdateMgr"
let Managers=[
LoopMgr,
AssetMgr,
LayerMgr,
SoundMgr,
ViewMgr,
ModuleMgr,
GameUpdateMgr
]
export default class AppFacade{
private static mgrDic:Map<string,Manager>=new Map()
private static mgrProgress:number=null //模块进度
private static progress:number=null //总进度
public static get Progress(){return this.progress}
private static isInitFinish:boolean=null
private static isDestroy:boolean=false
private constructor(){}
private static hideFun:any
private static showFun:any
public static onLoad(){
console.log("onLoad")
this.mgrProgress=0
this.progress=0
this.isInitFinish=false
this.isDestroy=false
this.hideFun=this.onHideGame.bind(this)
this.showFun=this.onShow.bind(this)
cc.game.on(cc.game.EVENT_SHOW, this.onShow, this)
cc.game.on(cc.game.EVENT_HIDE, this.onHideGame, this)
}
public static async onStart(){
console.log("onStart")
let counter=0
for(let mgr of Managers){
await this.addMgr(mgr as any)
this.mgrProgress=(++counter/Managers.length)
}
this.getMgr(AssetMgr).startPreLoad()
this.mgrProgress=1
}
public static onUpdate(){
if(this.isInitFinish==false){
let assetMgr=this.getMgr(AssetMgr)
let updateMgr=this.getMgr(GameUpdateMgr)
if(assetMgr){
//总进度=更新进度+模块加载进度+资源预加载进度
this.progress=(updateMgr&&updateMgr.Progress||0)*0.5+(this.mgrProgress*0.2)+(assetMgr&&assetMgr.PreProgress*0.3||0)
this.progress>=1&&(this.isInitFinish=true)
}
}else{
for(let v of this.mgrDic.values()){
v.update()
}
}
}
public static onLateUpdate(){
if(this.isDestroy) return
for(let v of this.mgrDic.values()){
v.lateUpdate()
}
}
/**
* bug:loopMgr清理了事件,最好先释放
*/
public static async onDestroy(){
cc.game.off(cc.game.EVENT_SHOW, this.onShow, this)
cc.game.off(cc.game.EVENT_HIDE, this.onHideGame, this)
this.onHideGame()
this.isDestroy=true
for(let i=0;i<this.mgrDic.size;++i){
console.log(Managers[i].TypeName)
this.mgrDic.get(Managers[i].TypeName).release()
}
this.mgrDic.clear()
}
public static getMgr<T extends Manager>(type:{new():T;TypeName:string}):T{
let res:T=<T>this.mgrDic.get(type.TypeName)
return res
}
//IManager 要求对象继承于IManager ,用Manager要求对象有一堆属性实现
//T 是最终存入的对象
private static async addMgr<T extends Manager>(type:{new():T;TypeName:string}){
let res:T=<T>this.mgrDic.get(type.TypeName)
if(!res){
res=new type()
await res.start()
this.mgrDic.set(type.TypeName,res)
}
return res
}
private static onHideGame(){
console.log("隐藏到后退或者退出")
cc.systemEvent.emit(EventConst.HideGame)
}
private static onShow(res){
cc.systemEvent.emit(EventConst.ShowGame,res)
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "635c923c-a3a5-4520-8111-9a88754b8a87",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.1.2",
"uuid": "01a9d787-2186-4fe7-b00b-8ac6f65d5e02",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}
\ No newline at end of file
import AppFacade from "../AppFacade";
import LayerMgr from "../Manager/LayerMgr";
import UIUtil from "../Util/UIUtil";
import View from "./View";
/**
* @param 全屏界面
* 1.需要有Bottom Top Left Right 四个二级节点对齐
* 2.最高级父节点Size=0,0
* 3.【应该只有一级界面是Fullview,内曾是Fullview没意义,middle等节点并不会展开】
*/
export default abstract class FullView extends View{
public widget:cc.Widget=null
public top:cc.Node=null
public bottom:cc.Node=null
public left:cc.Node
public leftTop:cc.Node
public leftBottom:cc.Node
public right:cc.Node
public rightBottom:cc.Node
public rightTop:cc.Node
public middle:cc.Node
public topWidget:cc.Widget=null
public bottomWidget:cc.Widget=null
public leftWidget:cc.Widget=null
public leftTopWidget:cc.Widget
public leftBottomWidget:cc.Widget
public rightWidget:cc.Widget=null
public rightTopWidget:cc.Widget
public rightBottomWidget:cc.Widget
public middleWidth:cc.Widget=null
public abstract getTypeName():string
protected setLayer(){
let layer=AppFacade.getMgr(LayerMgr)
// widget 安装上后,left的值等没有根据父亲更新
this.widget=UIUtil.autoFitCanvas(this.node,layer.bangScreenTopOffset())
this.top=this.getChildNode("Top")
if(this.top){
this.top.setContentSize(cc.view.getDesignResolutionSize())
this.topWidget=this.addCCComp<cc.Widget>(this.top,cc.Widget)
this.topWidget.isAlignTop=true
}
this.bottom=this.getChildNode("Bottom")
if(this.bottom){
this.bottom.setContentSize(cc.view.getDesignResolutionSize())
this.bottomWidget=this.addCCComp<cc.Widget>(this.bottom,cc.Widget)
this.bottomWidget.isAlignBottom=true
}
this.left=this.getChildNode("Left")
if(this.left){
this.left.setContentSize(cc.view.getDesignResolutionSize())
this.leftWidget=this.addCCComp<cc.Widget>(this.left,cc.Widget)
this.leftWidget.isAlignLeft=true
}
this.leftTop=this.getChildNode("LeftTop")
if(this.leftTop){
this.leftTop.setContentSize(cc.view.getDesignResolutionSize())
this.leftTopWidget=this.addCCComp<cc.Widget>(this.leftTop,cc.Widget)
this.leftTopWidget.isAlignLeft=true
this.leftTopWidget.isAlignTop=true
}
this.leftBottom=this.getChildNode("LeftBottom")
if(this.leftBottom){
this.leftBottom.setContentSize(cc.view.getDesignResolutionSize())
this.leftBottomWidget=this.addCCComp<cc.Widget>(this.leftBottom,cc.Widget)
this.leftBottomWidget.isAlignLeft=true
this.leftBottomWidget.isAlignBottom=true
this.leftBottomWidget.updateAlignment()
}
this.right=this.getChildNode("Right")
if(this.right){
this.right.setContentSize(cc.view.getDesignResolutionSize())
this.rightWidget=this.addCCComp<cc.Widget>(this.right,cc.Widget)
this.rightWidget.isAlignRight=true
}
this.rightTop=this.getChildNode("RightTop")
if(this.rightTop){
this.rightTop.setContentSize(cc.view.getDesignResolutionSize())
this.rightTopWidget=this.addCCComp<cc.Widget>(this.rightTop,cc.Widget)
this.rightTopWidget.isAlignRight=true
this.rightTopWidget.isAlignTop=true
}
this.rightBottom=this.getChildNode("RightBottom")
if(this.rightBottom){
this.rightBottom.setContentSize(cc.view.getDesignResolutionSize())
this.rightBottomWidget=this.addCCComp<cc.Widget>(this.rightBottom,cc.Widget)
this.rightBottomWidget.isAlignRight=true
this.rightBottomWidget.isAlignBottom=true
}
this.middle=this.getChildNode("Middle")
if(this.middle){
this.middleWidth=UIUtil.autoFitCanvas(this.middle)
}
}
protected updateAligment(){
this.topWidget&&this.topWidget.updateAlignment()
this.bottomWidget&&this.bottomWidget.updateAlignment()
this.leftWidget&&this.leftWidget.updateAlignment()
this.leftTopWidget&&this.leftTopWidget.updateAlignment()
this.leftBottomWidget&&this.leftBottomWidget.updateAlignment()
this.rightTopWidget&&this.rightTopWidget.updateAlignment()
this.rightBottomWidget&&this.rightBottomWidget.updateAlignment()
this.rightWidget&&this.rightWidget.updateAlignment()
this.middleWidth&&this.middleWidth.updateAlignment()
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "8b8f4199-a46f-42d9-807a-87bf0d003d43",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import { ViewConst } from "../ConstDefine/ViewConst";
import AppFacade from "../AppFacade";
import LayerMgr from "../Manager/LayerMgr";
import UIWindowView from "./UIWindowView";
import View from "./View";
export default class MaskView extends View{
//栈
private viewStack:Array<UIWindowView>=new Array()
//退出队列
private exitQueue:Array<UIWindowView>=new Array()
private newTarget:cc.Node=null
public getTypeName(): string {
return ViewConst.PauseView
}
protected setLayer(){
this.newTarget&&this.setParentData(this.newTarget)
}
protected async getChilds(){
this.node.on(cc.Node.EventType.TOUCH_END,this.onClickMask,this)
this.node.active=true
this.isOpen=true
}
/**
* @param target
* @returns 是否可以显示出来
*/
public bindTarget(target:UIWindowView){
if(!target) return
let init=this.viewStack.length<=0
this.pushStack(target)
if(init){
this.node&&(this.isOpen=true)
}
}
public unBindTarget(target:UIWindowView){
this.popStack(target)
this.tryResycle()
}
/**
* 返回是否已经存入
* @param target
*/
private pushStack(target:UIWindowView){
let lastView=this.viewStack[this.viewStack.length-1]
if(lastView==target) return
let index=this.viewStack.lastIndexOf(target)
if(index>=0){
this.viewStack.splice(index,1)
}
let preView=this.viewStack[this.viewStack.length-1]
this.viewStack.push(target)
this.setParentData(target?.node)
this.popExitQueue(target)
this.popExitQueue(preView)
if(preView){
this.exitQueue.push(preView)
preView.hide()
}
}
private popStack(target:UIWindowView) {
//只是临时退出
if(this.exitQueue.includes(target)){
return
}
let index=this.viewStack.lastIndexOf(target)
if(index>=0){
this.viewStack.splice(index,1)
}
let preView=this.exitQueue.shift()
if(preView){
preView.open()
this.setParentData(preView.node)
}
}
private popExitQueue(target:UIWindowView){
let index=this.exitQueue.lastIndexOf(target)
if(index>=0){
this.exitQueue.splice(index,1)
}
}
private setParentData(node:cc.Node){
if(!node) return
if(this.node){
this.setParent(node.parent)
this.setPosition(cc.Vec2.ZERO_R)
let sibling=node.parent?.childrenCount??0
this.node.setSiblingIndex(sibling+1)
node.setSiblingIndex(sibling)
}else{
this.newTarget=node
}
}
private onClickMask(){
// if(this.viewStack.length>0){
// let view=this.viewStack[0]
// if(view?.IsCanClickMaskClose){
// view.close()
// }
// }
// this.tryResycle()
}
public closeAll(){
let tmpStack=this.viewStack.splice(0)
this.viewStack.length=0
this.exitQueue.length=0
for(let view of tmpStack){
view?.close()
}
this.tryResycle()
}
public isInStack(view:UIWindowView):boolean{
return this.viewStack.includes(view)
}
private tryResycle(){
if(this.viewStack.length<=0){
this.exitQueue.length=0
AppFacade.getMgr(LayerMgr).pushPool(this.node)
this.isOpen=false
}
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "afa23280-0ecb-4d13-9b0a-cdbf0391714b",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import { ViewConst, ViewType } from "../ConstDefine/ViewConst"
import AppFacade from "../AppFacade"
import LayerMgr from "..//Manager/LayerMgr"
import ViewMgr from "..//Manager/ViewMgr"
import FullView from "./FullView"
/**
* UI全屏界面
*/
export default abstract class UIFullView extends FullView{
public abstract getTypeName():string
public getViewType():ViewType{return ViewType.UIFullView}
protected setLayer(){
super.setLayer()
this.changeLayer()
}
protected changeLayer(){
let layer=AppFacade.getMgr(LayerMgr)
layer.setLayer(this.node,layer.UiLayer)
}
public close(){
super.close()
AppFacade.getMgr(ViewMgr).releaseView(this.getTypeName(),ViewConst.ReleaseTime.UI)
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "0b4c5b38-fdae-4880-ac59-d6c7ea228412",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import View from "./View";
import AppFacade from "../AppFacade";
import LayerMgr from "../Manager/LayerMgr";
import MaskView from "./MaskView";
import LoopMgr from "../Manager/LoopMgr";
import ViewMgr from "../Manager/ViewMgr";
import { ResConst } from "../ConstDefine/ResConst";
import { ViewConst, ViewType } from "../ConstDefine/ViewConst";
/**
@param UI窗体
*/
const TWEEN_TIME=0.3
export default abstract class UIWindowView extends View{
//静态变量只有加载模块的时候调用
public static maskView:MaskView=null
private enterTween:cc.Tween=null
private exitTween:cc.Tween=null
private enterPos:cc.Vec3=cc.Vec3.ZERO
private exitPos:cc.Vec3=cc.v3(0,cc.view.getDesignResolutionSize().height)
protected btnClose:cc.Button=null
//允许点击mask关闭
public get IsCanClickMaskClose():boolean{return this.isCanClickMaskClose}
protected isCanClickMaskClose:boolean=true
private closeTimeoutId:number=-1
public abstract getTypeName():string
public getViewType():ViewType{return ViewType.UIWindow}
protected setLayer():void{
let layer=AppFacade.getMgr(LayerMgr)
layer.setLayer(this.node,layer.WindowLayer)
this.enterTween=cc.tween(this.node).to(0,{position:this.exitPos}).to(TWEEN_TIME,{position:this.enterPos},{easing:cc.easing.circInOut})
this.exitTween=cc.tween(this.node).to(0,{position:this.enterPos}).to(TWEEN_TIME,{position:this.exitPos},{easing:cc.easing.expoIn})
}
protected async getChilds(){
if(!UIWindowView.maskView){
UIWindowView.maskView=new MaskView()
UIWindowView.maskView.loadViewAsync(ResConst.UiABName,"Common/MaskView")
}
this.btnClose=this.getChildComp("BtnClose",cc.Button)
this.btnClose?.node.on("click",this.close,this)
await this.getWindowChilds()
}
/** 子类重写这个方法
* 会忘记调用 await this.getChilds()
*/
protected abstract getWindowChilds()
protected onOpenEnter(){}
/** window不能限制,影响窗口再弹 */
public open(){
super.open()
this.clearCloseTimeout()
UIWindowView.maskView?.bindTarget(this)
this.playAnimal(true)
}
public close():void{
if(this.isOpen==false) return
this.clearCloseTimeout()
UIWindowView.maskView?.unBindTarget(this)
this.playAnimal(false)
AppFacade.getMgr(ViewMgr).releaseView(this.getTypeName(),ViewConst.ReleaseTime.UI)
super.close()
// this.closeTimeoutId=AppFacade.getMgr(LoopMgr).setTimeout(()=>{
// AppFacade.getMgr(ViewMgr).releaseView(this.getTypeName(),ViewConst.ReleaseTime.UI)
// super.close()
// },TWEEN_TIME)
}
public hide(){
this.playAnimal(false)
}
public playAnimal(isEnter:boolean){
if(isEnter){
// this.exitTween?.stop()
// this.enterTween?.start()
// AppFacade.getMgr(LoopMgr).setTimeout(this.onOpenEnter.bind(this),TWEEN_TIME)
this.onOpenEnter()
}else{
// this.enterTween?.stop()
// this.exitTween?.start()
}
// AppFacade.getMgr(SoundMgr).playEffect(SoundConst.Window)
}
private clearCloseTimeout(){
AppFacade.getMgr(LoopMgr).clearTimeout(this.closeTimeoutId)
this.closeTimeoutId=-1
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "cda9cb01-2ec6-44fb-95ec-03acf7ec70bd",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import AppFacade from "../AppFacade";
import { EventConst } from "../ConstDefine/EventConst";
import ViewComp from "../ViewComp/ViewComp";
import { ViewType } from "../ConstDefine/ViewConst";
import IView from "../Interface/IView";
import AssetMgr from "../Manager/AssetMgr";
/**
* @param 所有对象的父类
*/
export default class View implements IView {
//【禁止使用】类名会因为编译修改
private getClsName(): string {
return this.constructor.name
}
private static gIndex=0
private instanceId:number=0
public get InstanceId():number{
if(!this.instanceId){
this.instanceId=++View.gIndex
}
return this.instanceId
}
public getTypeName(): string { return "View" }
public getViewType():ViewType{ return ViewType.None}
public get node(): cc.Node { return this.rootNode }
private rootNode: cc.Node
protected isOpen: boolean
public get IsOpen(): boolean { return this.isOpen }
protected resName: string = ""
public get ResName(): string { return this.resName }
protected abPath: string = ""
protected isStarLoad:boolean=false
public get IsStartLoad():boolean{return this.isStarLoad}
protected isLoadFinish: boolean = false //用来判断是否加载完
public get IsLoadFinish():boolean{return this.isLoadFinish}
private viewComps:Map<typeof ViewComp,ViewComp>
//子类写以下方法
protected setLayer(): void { }
protected async getChilds() { }
protected async onUpdateData(data?: Object) { }
protected onOpen(): void { }
protected onClose(): void { }
/**是否可以设置active */
public isCanActiveClose:boolean=true
public isCanActiveOpen:boolean=true
public async loadViewAsync(abPath: string, resName: string) {
this.isStarLoad=true
return new Promise(async (resolve)=>{
this.resName = resName
this.abPath = abPath
try{
let prefab = await AppFacade.getMgr(AssetMgr).loadAssetAsync<cc.Prefab>(abPath, resName, cc.Prefab)
this.rootNode = cc.instantiate(prefab)
await this.loadViewFinish()
resolve(this)
}catch(err){
console.log(err)
}
})
}
public async loadViewClone(prefab: cc.Node, instantiate: boolean)
public async loadViewClone(prefab: cc.Prefab)
public async loadViewClone(prefab: any, instantiate: boolean = true) {
this.isStarLoad=true
return new Promise(async (resolve)=>{
if (!prefab) {
console.error("loadViewClone prefab is null")
return
}
this.rootNode = instantiate && cc.instantiate(prefab) || prefab
await this.loadViewFinish()
resolve(this)
})
}
protected async loadViewFinish(){
this.setLayer()
await this.getChilds()
this.viewComps?.forEach((comp)=>comp.getChilds())
this.isLoadFinish = true
}
public isRootView(): boolean { return cc.isValid(this.node) }
public isParentView(): boolean { return this.isRootView() && cc.isValid(this.node.parent) }
//防止没加载完成的时候多次调用
public async updateData(data?: Object) {
if (this.isLoadFinish == false)
return
await this.onUpdateData(data)
this.viewComps?.forEach((comp)=>comp.updateData(data))
}
public open(): void {
if (this.isLoadFinish==false||this.isOpen==true) return
this.isOpen = true
this.viewComps?.forEach((comp)=>comp.open())
if(this.isCanActiveOpen&&this.isRootView()){
this.node.active=true
}
this.isParentView() && this.node.setSiblingIndex(this.node.parent.childrenCount)
this.emitEvent(EventConst.OpenView)
this.onOpen()
}
protected emitEvent(event:string){
cc.systemEvent.emit(event,this.getTypeName(),this.getViewType())
}
public close(): void {
if (this.isOpen==false) return
this.isOpen = false
this.viewComps?.forEach((comp)=>comp.close())
if(this.isCanActiveClose&&this.isRootView()){
this.node.active=false
}
this.onClose()
this.emitEvent(EventConst.CloseView)
}
/**
* 事件在loop中释放了
*/
public release(): void {
this.onRelsese()
this.isLoadFinish = false
this.node?.destroy()
this.viewComps?.forEach((comp)=>comp.release())
AppFacade.getMgr(AssetMgr).releaseAsset(this.abPath,this.resName)
}
protected onRelsese(){}
public setActive(active:boolean){
this.isRootView()&&(this.node.active=active)
}
public setParent(parent: cc.Node) {
this.isRootView() && (this.node.parent = parent)
}
public setPosition(newPosOrX: cc.Vec2 | cc.Vec3) {
this.isRootView() && (this.node.setPosition(newPosOrX))
}
public setRotation(rotation: number) {
this.isRootView() && (this.node.angle = -rotation)
}
public getWorldPos(): cc.Vec3 {
let res = cc.Vec3.ZERO
if (this.isParentView()) {
res = this.node.parent.convertToWorldSpaceAR(this.node.position)
}
return res
}
public setWorldPos(worldPos: cc.Vec3) {
if (this.isParentView()) {
this.node.position = this.node.parent.convertToNodeSpaceAR(worldPos)
}
}
protected addViewComp(type:typeof ViewComp):ViewComp{
if(!this.viewComps){
this.viewComps=new Map()
}
let c=this.viewComps.get(type)
if(!c){
c=new type(this)
this.viewComps.set(type,c)
}
return c
}
public getViewComp<T extends ViewComp>(type:typeof ViewComp):T{
if(!this.viewComps) return
let comp=this.viewComps.get(type)
return <T>comp
}
protected getChildNode(url: string): cc.Node {
if (!this.isRootView()) return null
if (url === "") return this.node
return cc.find(url, this.node)
}
protected getChildComp<T extends cc.Component>(url: string, type: { prototype: T }): T {
if (!this.isRootView()) return null
let node = this.getChildNode(url)
!node && (cc.error(this.resName, url, "not exit", "getChildComp"))
return node && node.getComponent(type)
}
protected getChildComps<T extends cc.Component>(url: string, type: { prototype: T }): T[] {
if (!this.isRootView()) return null
let node = this.getChildNode(url)
!node && (cc.error(this.resName, url, "not exit", "getChildComp"))
return node && node.getComponentsInChildren(type)
}
protected addCCComp<T extends cc.Component>(node: cc.Node, type: new () => cc.Component): T {
if (!node) return null
let res = node.getComponent(type)
if (!res) {
res = node.addComponent(type) as T
}
return res
}
protected setName(name: string) {
this.isRootView() && (this.node.name = name)
}
public getPathInLayer():string{
if(!this.isRootView()) return ""
let p=this.node.parent
let res=this.node.name
while(cc.isValid(p)){
res=p.name+"/"+res
p=p.parent
}
return res
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "803110d8-07ce-4d32-b11e-61b7c7efee33",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.1.2",
"uuid": "db5f0937-64e8-4998-83b6-ddd2e1cd2869",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}
\ No newline at end of file
export namespace AppConst{
//语言定义 Zn中文 Fan繁体 En英文
export let LangZn="CN"
export let LangFan="TC"
export let LangEn="EN"
export let Lang=LangZn
export let IsDebug=true;//false
export let IsAuto=true;//false
export let GameOptimize=false //启动优化
export let GameFrameRate=60//60帧
export let GameFrameInterval=1/GameFrameRate //减少update调用次数
export let Width=2176
export let Height=1600
export let Ip="127.0.0.1"
export let Port="8081"
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "8b93a4cd-8f62-4a53-b362-a5292ae4bc34",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
/**
* @param 事件
*/
export const EventConst = {
//输入系统
TouchStart: "TouchStart",
TouchStay: "TouchStay",
TouchEnd: "TouchEnd",
TouchCancle: "TouchCancle",
TouchMove: "TouchMove",
ChangeTouchState:"ChangeTouchState",//修改操作状态
//全局
BtnForceClickOpen: "BtnForceClickOpen",//ForceClick脚本附加事件
BtnForceClickClose: "BtnForceClickClose",//ForceClick脚本附加事件
TBCLRState: "TBCLRState",//tbclr方位界面动画状态
OpenView: "OpenView", //打开界面
CloseView: "CloseView", //关闭界面
CloseAllWindow: "CloseAllWindow",//关闭所有窗口界面
SaveDataPre: "SaveDataPre", //存档前
//游戏相关
MainMenu:"MainMenu", //进入主菜单
EnterGame: "EnterGame",//进入游戏
ShowGame:"ShowGame", //展开游戏
HideGame: "HideGame", //退出游戏
LoadingFinish: "LoadingFinish", //更新完成
LoadingShow: "LoadingShow",//进度页面
LoadingHide: "LoadingHide",//隐藏进度页面
RoleMove:"RoleMove",
//广告
TemplateViewAdStatus:"TemplateViewAdStatus0", //模板【界面】广告的状态
JumpToStartView:"JumpToStartView",//跳到开始界面
JumpToGameView:"JumpToGameView",//跳到游戏
JumpToOverView:"JumpToOverView",//跳到结算
JumpToTalentSelectView:"JumpToTalentSelectView",//跳到天赋
JumoToAttrView:"JumoToAttrView",//跳到属性
JumpToStatisticsView:"JumpToStatisticsView",//跳到总结
//debug
StartAuto:"StartAuto", //开始自动跑
SelectTalentDebug:"SelectTalentDebug",//点击天赋十连
SetAttrValueDebug:"SetAttrValueDebug",
PlayGameDebug:"PlayGameDebug",
OverViewDebug:"OverViewDebug",
//属性
AttrUpdate:"UpdateAttr",//更新属性
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "308804b0-7159-435e-91f5-6e7ed528fdd8",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
export enum SubContextEvent{
InitData="InitData",
Open="Open",
Close="Close",
SetValue="SetValue",
ReciveInvite="ReciveInvite",
}
export enum ChannelType
{
//小游戏
None,Weixin,ByteDance,Kuaishou,OPPO,VIVO,_4399,
//Android
Android,Android_Ohayoo,_233,Android_MOMOYU,
//IOS
IOS,IOS_Ohayoo,
}
export namespace PlatformConst{
//微信 start
//web可以有多个渠道,没办法区分只能赋给id
// export let Channel=ChannelType.Weixin
// export let Channel=ChannelType.ByteDance
export let Channel=ChannelType.None
//分享query数字
export let ShareQuery={
None:"0",
inviteFriend:"1", //邀请好友 给 shareMessageToFriend 用
inviteNum:"2", //邀请数量
sendDiamond:"3", //送钻石
}
export let InviteFriendDiamond=20 //邀请好友奖励
export let GiveFriendDiamond=5 //赠送好友钻石
export function getWXShareData(openId){
return {
title: '皇帝模拟器',
// imageUrlId:getPlatformShareId(),
// imageUrl: getPlatfomShareImg(),
query: "inviteOpenId=" + openId,
}
}
function getPlatformShareId():string{
if(PlatformConst.Channel==ChannelType.Weixin){
return "gkkrxQYURhaacqjt7nkPdg=="
}
}
function getPlatfomShareImg():string{
if(PlatformConst.Channel==ChannelType.Weixin){
// return "https://mmocgame.qpic.cn/wechatgame/w0jhXlUMxvQnf3I2WMFnzfetNbBgVIRTG5UVrlOFBjKRsqkpZHzCR2dDocU8GLD5/0"
return ""
}
}
/** appId */
export function getAppKey():string{
if(PlatformConst.Channel==ChannelType.OPPO){
return "24em7kOC6t40k4Cs040ScgWWK"
}else if(PlatformConst.Channel==ChannelType.VIVO){
return "61506548aa5cab5f8803ed3f8d422a9a"
}
}
export function getAppSecrete():string{
if(PlatformConst.Channel==ChannelType.OPPO){
return "E2cdf7a3773b646EbcD77Bd6eec2A947"
}else if(PlatformConst.Channel==ChannelType.VIVO){
return "d1f2afc75fc0b36ff22af3159744edf6"
}
}
export function getPkgName():string{
if(PlatformConst.Channel==ChannelType.OPPO){
return "gzyy.msyx.nearme.gamecenter"
}else if(PlatformConst.Channel==ChannelType.VIVO){
return "com.gzyy.msyx.vivominigame"
}
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "bd4cfa23-db06-4478-bb95-f34967f16c0d",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
//资源相关常量
export namespace ResConst{
export let emptyABName="";
export let AudioABName="res/audio"
export let PrefabsABName="prefabs"
export let JsonABName="json"
export let Role1ABName="role1"
export let UiABName="UI"
export let AiABName="Ai"
export let ConfigABName="config"
export let ResourcesABName="resources"
export let ParticleABName="Particle"
export let SpineABName="Spine"
export let SkillSVGName="skill"
export let snd={
button:"button",
click:"click",
right:"correct",
wrong:"incorrect",
lack:"lack",
finish:"finish",
painted:"painted"
}
//必须加载完
export const AwaitLoadAssets=[
]
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "a523a2f0-b168-4822-a6b9-69a4c7fea0c3",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
export enum ViewType{
None=0,
UI=1<<0,
UIWindow=(1<<1)|UI,
UIFullView=(1<<2)|UI,
UITabView=(1<<3)|UIWindow,
SceneView=(1<<4),
}
export namespace ViewType{
export function isUI(viewType:ViewType){
let res=viewType&ViewType.UI
return res==ViewType.UI
}
export function isUIWindow(viewType:ViewType){
let res=viewType&ViewType.UIWindow
return res==ViewType.UIWindow
}
export function isScene(viewType:ViewType){
let res=viewType&ViewType.SceneView
return res==ViewType.SceneView
}
}
export namespace ViewConst{
//释放时间
export const ReleaseTime={
UI:5,
Particle:8,
SceneObj:10,
}
//View
export const TipsView="TipsView"
//SceneView
export const MenuView="bg"
//UIWindow
export const CardView="CardView"
export const PauseView="PauseView"
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "37363f43-0b03-46fb-9a8c-bb40d7df82c6",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import AppFacade from "./AppFacade";
import ViewMgr from "./Manager/ViewMgr";
import View from "./BaseView/View";
import IController from "./Interface/IController";
//controller操作数据model和view
export default class Controller implements IController{
protected constructor(){}
protected static _inst=null
public static get Inst():Controller{
if(this._inst==null){
this._inst=new Controller()
}
return this._inst
}
public async init() {}
public release() {}
// public async getView(viewName:string,type:typeof View){
// let view=AppFacade.getMgr(ViewMgr).openView(viewName,type)
// if(!view.IsStartLoad){
// await view.loadViewClone(cc.find("Canvas/"+viewName),false);
// }
// }
public async getView(viewName:string,type:typeof View){
let view=AppFacade.getMgr(ViewMgr).openView(viewName,type)
if(!view.IsStartLoad){
await view.loadViewClone(cc.find("Canvas/"+viewName),false);
}
// await view.updateData()
// view.open()
return view;
}
// public async getView(viewName:string,type:typeof View,resName:string){
// let view=AppFacade.getMgr(ViewMgr).openView(viewName,type)
// if(!view.IsStartLoad){
// await view.loadViewAsync(ResConst.PrefabsABName,resName)
// }
// // await view.updateData()
// // view.open()
// return view;
// }
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "4fa632b5-6def-4037-836c-32d36b5e46d0",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.1.2",
"uuid": "9846b613-68a1-44c2-b47a-bb94057036f7",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}
\ No newline at end of file
/**
* @param 函数接口
*/
export interface ICreateFunc<T>{
():T
}
export interface IPredicate<T>{
(t:T):boolean
}
export interface IParamter<T>{
(t:T,i?:number):void
}
export interface ILimitFunc{
(arr:any,i:number):void
}
{
"ver": "1.0.8",
"uuid": "f5debb73-a049-43ff-bd2f-32bb61c2c649",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
export default interface IController{
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "28e09d98-3a46-47f8-a4d3-946ed3c4f5f2",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "a9a8a69e-85a0-44f6-a377-b46717032148",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
export default interface IModel{
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "4e08a9fd-23e6-4de8-966e-14be66928679",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
export default interface IView{
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "53428666-7299-4b1a-94c2-a1b5ebf9481a",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import { MyCocosSceneComponent } from "../MyCocosSceneComponent";
import AppFacade from "./AppFacade";
const {ccclass, property} = cc._decorator;
//启动动态图集 必须放这里
cc.macro.CLEANUP_IMAGE_CACHE = false
cc.dynamicAtlasManager.enabled = true
@ccclass
export default class Main extends MyCocosSceneComponent {
addPreloadImage() {
AppFacade.onLoad()
}
onLoadEnd(){
try {
AppFacade.onStart()
} catch (err) {
cc.error("运行出错", err)
}
}
// onLoad(): void {
// AppFacade.onLoad()
// }
// start () {
// try{
// AppFacade.onStart()
// }catch(err){
// cc.error("运行出错",err)
// }
// }
update(){
try{
AppFacade.onUpdate()
}catch(err){
cc.error("运行错误",err)
}
}
lateUpdate(){
AppFacade.onLateUpdate()
}
onDestroy(){
AppFacade.onDestroy()
}
}
{
"ver": "1.0.8",
"uuid": "bf6d8a0d-d989-49fe-a23d-19ec171e58fe",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.1.2",
"uuid": "b06e0643-fca0-4540-ad36-176d2cee4e94",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}
\ No newline at end of file
import { ResConst } from "../ConstDefine/ResConst"
import Manager from "./Manager"
export default class AssetMgr extends Manager {
static get TypeName(): string { return "AssetMgr" }
private preProgress: number = 0
public get PreProgress(): number { return this.preProgress }
public async start() {
console.log("AssetMgr onStart")
}
public release() {
console.log("AssetMgr onRelease")
}
public async startPreLoad() {
let promises = []
for (let v of ResConst.AwaitLoadAssets) {
promises.push(this.preLoadAsset(v[0], v[1]))
}
await Promise.all(promises)
this.preProgress = 1
// this.startNoAwaitLoad()
}
// private startNoAwaitLoad() {
// this.preLoadAsset(ResConst.UiABName, "Scene/SceneObj/Player", cc.Prefab)
// this.preLoadAsset(ResConst.UiABName, "Menu/MenuView", cc.Prefab)
// this.preLoadAsset(ResConst.UiABName, "Bg/BgView", cc.Prefab)
// }
// private allProgress() {
// return ResConst.AwaitLoadAssets.length
// }
/**
* 预加载不需要等待
*/
public async preLoadAsset(abName: string, resName: string, type?: typeof cc.Asset) {
return new Promise<void>((resolve, reject) => {
cc.assetManager.loadBundle(abName, (err, bundle: cc.AssetManager.Bundle) => {
if (!err) {
bundle.preload(resName, type, (err, items) => {
resolve()
})
} else {
reject()
}
})
})
}
/**
* 预加载不需要等待
* ""表示整个目录
*/
public preLoadAssetDir(abName: string, dir: string = "", type: typeof cc.Asset) {
cc.assetManager.loadBundle(abName, (err, bundle: cc.AssetManager.Bundle) => {
if (!err) {
bundle.preloadDir(dir, type, (err, items) => { })
}
})
}
//读取目录下所有类型文件
public loadAssetDirAsync<T extends cc.Asset>(abName: string, type: typeof cc.Asset = cc.Asset): Promise<T[]> {
return new Promise((resolve, reject) => {
cc.assetManager.loadBundle(abName, (err, bundle) => {
if (err) {
cc.error("loadBundleAsync error", abName, err)
reject(err)
} else {
bundle.loadDir("./",type,(err,assets)=>{
if (err) {
cc.error("loadAssetAsync error")
reject(err)
}
else {
// assets?.addRef()
resolve(<T[]>assets)
}
})
}
})
})
}
public loadAssetAsync<T extends cc.Asset>(abName: string, resName: string, type: typeof cc.Asset = cc.Asset): Promise<T> {
return new Promise((resolve, reject) => {
cc.assetManager.loadBundle(abName, (err, bundle) => {
if (err) {
cc.error("loadBundleAsync error", abName, resName, err)
reject(err)
} else {
bundle.load(resName, type,
//complete
(err, assets) => {
if (err) {
cc.error("loadAssetAsync error", resName)
reject(err)
}
else {
// assets?.addRef()
resolve(<T>assets)
}
})
}
})
})
}
public releaseAsset(asset: cc.Asset, _?)
public releaseAsset(abName: string, resName: string)
public releaseAsset(a1: any, a2: any) {
if (a1 instanceof cc.Asset) {
if (cc.isValid(a1)) {
a1?.decRef()
}
} else {
if (!a1 || !a2) return
let ab = cc.assetManager.getBundle(a1)
let info: Record<string, any> = ab.getInfoWithPath(a2)
let uuid = info?.uuid
let asset = cc.assetManager.assets?.get(uuid)
asset?.decRef()
if (asset?.refCount <= 0) {
// console.log("释放",asset?.name,cc.assetManager.assets?.count)
}
}
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "6c69587a-b010-4680-921e-1822c7b70123",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
class EventInfo{
public constructor(public callback:Function,public target?:any){}
}
export default class EventMgr{
private static _infoMap:Map<string,Array<EventInfo>>=new Map()
public static on(key:string,cb:Function,target?:any){
let arr=this._infoMap.get(key)
if(!arr){
arr=new Array()
this._infoMap.set(key,arr)
}
arr.push(new EventInfo(cb,target))
}
public static off(key:string,cb:Function,target?:any){
let arr=this._infoMap.get(key)
if(!arr) return
for(let i=arr.length-1;i>=0;i--){
let info=arr[i]
if(target){
if(info.callback==cb&&info.target==target){
arr.splice(i)
}
}else{
if(info.callback==cb){
arr.splice(i)
}
}
}
}
public static emit(key:string,arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any){
let arr=this._infoMap.get(key)
if(!arr||arr.length<=0) return
for(let info of arr){
info?.callback?.call(info?.target,arg1,arg2,arg3,arg4,arg5)
}
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "bf77ba53-2ee7-4988-8735-7267f3435cd0",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import Manager from "./Manager";
import { EventConst } from "../ConstDefine/EventConst";
import { ChannelType, PlatformConst } from "../ConstDefine/PlatformConst"
//负责游戏更新
export default class GameUpdateMgr extends Manager {
static get TypeName(): string { return "GameUpdateMgr" }
private progress: number = null
public get Progress(): number { return this.progress }
public async start() {
console.log("开始更新...")
this.progress = 0
this.startUpdate()
this.onUpdateFinish()
console.log("更新完成...")
}
public release() {
}
//检测资源
private async startUpdate() {
return new Promise<void>((resovle)=>{
if (PlatformConst.Channel==ChannelType.Weixin||PlatformConst.Channel==ChannelType.ByteDance) {
const mgr = wx.getUpdateManager()
console.log("onCheckForUpdate",mgr)
if (mgr) {
mgr.onCheckForUpdate((res) => {
// 请求完新版本信息的回调
if (res.hasUpdate) {
//如果内存卡有存储游戏相关的离线文件,在更新版本的时候需要清除,避免废文件越来越多
wx.showToast({ icon: "none", title: "有新版本了,正在下载中..", duration: 600000 });//10分钟
}else{
resovle()
}
})
mgr.onUpdateFailed(function () {
wx.hideToast()
wx.showModal({
content: '新版本下载失败了,点击确定重启游戏',
title: '更新提示',
showCancel: false,
success: function (res) {
wx.exitMiniProgram()
resovle()
}
})
console.log("onUpdateFailed")
})
mgr.onUpdateReady(function () {
wx.hideToast();
wx.showModal({
content: '新版本已经准备好了,点击确定重启应用',
title: '更新提示',
showCancel: false,
success: function (res) {
// if (res.confirm) {
// // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
// mgr.applyUpdate()
// }else{
// }
mgr.applyUpdate()
resovle()
}
})
console.log("onUpdateReady")
})
}else{
resovle()
}
}
else{
resovle()
}
})
}
private onUpdateFinish(): void {
this.progress = 1
cc.systemEvent.emit(EventConst.LoadingFinish)
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "30c38aed-87fd-4038-acae-d198e771fbcf",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import { AppConst } from "../ConstDefine/AppConst"
import UIUtil from "../Util/UIUtil"
import Manager from "./Manager"
/**
* @params 管理分辨率 层级
*/
const PoolLayer = "PoolLayer"
const WindowLayer="WindowLayer"
const BangScreenOffSet = 70
const FAR_POS = cc.v3(-10000, -10000)
export default class LayerMgr extends Manager {
static get TypeName(): string { return "LayerMgr" }
private uiRoot: cc.Node = null
public get UIRoot(): cc.Node { return this.uiRoot }
private root: cc.Node
public get Root(): cc.Node { return this.root }
//对象池池层级
private poolLayer: cc.Node = null
public get PoolLayer() { return this.poolLayer }
//场景层start
//背景图
private sceneBackLayer: cc.Node = null
public get SceneBackLayer() { return this.sceneBackLayer }
//场景层
private sceneLayer: cc.Node = null
public get SceneLayer() { return this.sceneLayer }
//场景底层
private sceneTopLayer: cc.Node
public get SceneTopLayer() { return this.sceneTopLayer }
//场景层end
//ui层start
//飘血
private flybllodLayer: cc.Node = null
public get FlybllodLayer() { return this.flybllodLayer }
private uiLayer: cc.Node = null
//ui图标层
public get UiLayer() { return this.uiLayer }
//窗口
private windowLayer: cc.Node = null
public get WindowLayer() { return this.windowLayer }
private windowTopLayer: cc.Node = null
public get WindowTopLayer() { return this.windowTopLayer }
//广播
private broadcastLayer: cc.Node = null
public get BroadcastLayer() { return this.broadcastLayer }
//弹窗
private tipViewLayer: cc.Node = null
public get TipViewLayer() { return this.tipViewLayer }
//引导
private guideLayer: cc.Node = null
public get GuideLayer() { return this.guideLayer }
//顶层
private topLayer: cc.Node = null
public get TopLayer() { return this.topLayer }
//ui层end
private layers: cc.Node[] = null
private index: number = 1
private uiViews: Array<cc.Node> = null
public async start() {
// cc.view.enableAutoFullScreen(false)
this.uiRoot = cc.find("Canvas")
cc.game.addPersistRootNode(this.uiRoot)
this.root = cc.find("Root")
if(this.root){
cc.game.addPersistRootNode(this.root)
}
else
{
this.root=this.uiRoot;
}
// 小程序设置无效
// let screen=cc.view.getFrameSize()
// cc.view.setFrameSize(screen.width*0.5,screen.height*0.5)
//手机设备和pc返回的不一样【神经病,pc返回width/height,应该是height/widg】
//let cRatio=cc.view.getDevicePixelRatio()
// let policy = this.isFitWidth() && cc.ResolutionPolicy.FIXED_WIDTH || cc.ResolutionPolicy.FIXED_HEIGHT
// // cc.view.setDesignResolutionSize(720, 1280, policy)
// cc.view.setDesignResolutionSize(AppConst.Width, AppConst.Height, policy)
this.initSize();
this.layers = new Array()
this.createLayers()
this.uiViews = [this.flybllodLayer, this.uiLayer, this.windowLayer, this.windowTopLayer, this.tipViewLayer, this.guideLayer, this.topLayer]
console.log("LayerMgr onStart")
}
_designSize = null; // 设计分辨率
_frameSize = null; // 屏幕分辨率
_mapScaleMin = null; // 场景中常用缩放(取大值)
_mapScaleMax = null; // 场景中常用缩放(取小值)
_cocosScale = null; // cocos 自缩放 (较少用到)
initSize() {
// 注意cc.winSize只有在适配后(修改fitHeight/fitWidth后)才能获取到正确的值,因此使用cc.getFrameSize()来获取初始的屏幕大小
let screen_size = cc.view.getFrameSize().width / cc.view.getFrameSize().height
let design_size = cc.Canvas.instance.designResolution.width / cc.Canvas.instance.designResolution.height
let f = screen_size >= design_size
cc.Canvas.instance.fitHeight = f
cc.Canvas.instance.fitWidth = !f
const frameSize = cc.view.getFrameSize();
this._frameSize = frameSize;
this._designSize = cc.view.getDesignResolutionSize();
let sx = cc.winSize.width / frameSize.width;
let sy = cc.winSize.height / frameSize.height;
this._cocosScale = Math.min(sx, sy);
sx = frameSize.width / this._designSize.width;
sy = frameSize.height / this._designSize.height;
this._mapScaleMin = Math.min(sx, sy) * this._cocosScale;
this._mapScaleMax = Math.max(sx, sy) * this._cocosScale;
cc.director['_scene'].width = frameSize.width;
cc.director['_scene'].height = frameSize.height;
}
public release() {
console.log("LayerMgr onRelease")
this.uiViews.length = 0
if (cc.isValid(this.uiRoot)) {
this.uiRoot.destroyAllChildren()
}
this.uiRoot = null
this.layers.length = 0
this.index = 1
}
private createLayers(): void {
this.poolLayer = this.createLayer(PoolLayer, cc.v2(-100000, -100000))
//场景层
this.sceneBackLayer = this.createLayer("SceneBackLayer")
this.sceneLayer = this.createLayer("SceneLayer")
this.sceneTopLayer = this.createLayer("SceneTopLayer")
//ui层
this.flybllodLayer = this.createLayer("FlybllodLayer")
this.uiLayer = this.createLayer("UiLayer")
this.windowLayer = this.createLayer(WindowLayer)
this.windowTopLayer = this.createLayer("WindowTopLayer")
this.broadcastLayer = this.createLayer("BroadcastLayer")
this.tipViewLayer = this.createLayer("TipViewLayer")
this.guideLayer = this.createLayer("GuideLayer")
this.topLayer = this.createLayer("TopLayer")
}
private createLayer(layerName: string, pos: cc.Vec2 = cc.Vec2.ZERO): cc.Node {
let node = new cc.Node(layerName)
this.layers.push(node)
node.setParent(this.uiRoot)
if (layerName != PoolLayer) {
UIUtil.autoFitCanvas(node)
}
node.setSiblingIndex(this.index++)
node.setPosition(pos)
return node
}
/**
* setSiblingIndex 设置同节点层级排序
* zIndex和zOrder是同一个东西。设置渲染顺序,只能影响同一级节点
* 节点渲染都是先渲染自己再渲染子节点
*/
public setLayer(node: cc.Node, layer: cc.Node, offset: number = -1) {
if (!cc.isValid(node)) return
node.parent = layer
node.setSiblingIndex(layer.childrenCount + offset)
}
public pushPool(node: cc.Node) {
if (!cc.isValid(node)) return
node.setParent(this.poolLayer)
node.setPosition(FAR_POS)
}
/**
* @param 是否是刘海屏幕
*/
public isHasBangScreen() {
return this.getDeviceRatio() >= 2
}
/**
* @param 刘海屏偏移
*/
public bangScreenTopOffset(): number {
if (this.isHasBangScreen()) {
return BangScreenOffSet
}
return 0
}
/**
* //手机设备和pc返回的不一样【神经病,pc返回width/height,应该是height/widg】
//let cRatio=cc.view.getDevicePixelRatio()
*/
public getDeviceRatio(): number {
let size = cc.view.getFrameSize()
let ratio = Math.max(size.height, size.width) / Math.min(size.height, size.width)
return ratio
}
public findNode(path: string): cc.Node {
return cc.find(path, this.uiRoot)
}
/**
* uiViews 中的是ui界面,永远显示在屏幕上
*/
public foreverShowUiView(cameraLocPos: cc.Vec3) {
for (let view of this.uiViews) {
view.position = cameraLocPos
}
}
//适配后的分辨率 用cc.winSize就可以了
public getFitedSceneResolution(): cc.Size {
return this.sceneLayer.getContentSize()
}
/** 是否是宽度适配 */
public isFitWidth(): boolean {
let cRatio = this.getDeviceRatio()
let dsize = cc.view.getDesignResolutionSize()
let dRatio = dsize.height / dsize.width
let isFitWidth = cRatio > dRatio
return isFitWidth
}
//全屏特效需要适配屏幕
public fitScreen(node: cc.Node) {
if (!node?.isValid) return
let cRatio = this.getDeviceRatio()
let dsize = cc.view.getDesignResolutionSize()
let dRatio = dsize.height / dsize.width
let paramScale = node.scale || 1
if (this.isFitWidth()) {
node.scale = paramScale * (cRatio / dRatio)
} else {
node.scale = paramScale * (dRatio / cRatio)
}
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "04d4d6d3-121e-4d8b-8a7a-f0f720fc5958",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import { AppConst } from "../ConstDefine/AppConst";
import { EventConst } from "../ConstDefine/EventConst";
import { ILimitFunc } from "../Interface/FuncInterface";
import Manager from "./Manager";
/**
* @param js自带的interval和timeout不好管理容易造成内存泄露尽量不要使用
*/
class TimeoutInfo {
constructor(public func: Function, public timer: number, public id: number = -1) { }
}
class InterInfo {
constructor(public func: Function, public interval: number, public id: number = -1, public timer = 0) { }
}
class DelayInfo {
constructor(public func: Function, public couter: number = 0) { }
}
class LimitInfo {
constructor(public iterator: ILimitFunc, public arr: Array<any>, public limit: number, public resolve: any, public reject: any, public running: number = 0) { }
}
export default class LoopMgr extends Manager {
static get TypeName(): string { return "LoopMgr" }
private updateDic: Map<number, Function> = new Map()
private fixedDic: Map<number, Function> = new Map()
private lateUpdateDic: Map<number, Function> = new Map()
private timeoutDic: Map<number, TimeoutInfo> = new Map()
private intervalDic: Map<number, InterInfo> = new Map()
private delayOneFrames: Array<DelayInfo> = new Array()
private updateFramer: number = 0
private fixedNowTime: number = 0
private limitDic: Map<number, LimitInfo> = new Map()
private deleteLimits: Array<number> = new Array()
private framer: number = 0
public get Frame(): number { return this.framer }
private static LoopIndex: number = 0
async start() {
console.log("LoopMgr onStart")
}
public release() {
console.log("LoopMgr onRelease")
this.updateDic.clear()
this.lateUpdateDic.clear()
this.fixedDic.clear()
this.limitDic.clear()
for (let v of this.intervalDic) {
if (v[1].id != -1) {
clearInterval(v[1].id)
}
}
for (let v of this.timeoutDic) {
if (v[1].id != -1) {
clearTimeout(v[1].id)
}
}
this.intervalDic.clear()
this.timeoutDic.clear()
LoopMgr.LoopIndex = 0
this.clearEvents()
cc.Tween.stopAll()
this.updateFramer = 0
this.fixedNowTime = 0
}
public update(): void {
this.framer = (++this.framer) % Number.MIN_SAFE_INTEGER
//fixedupdate
this.fixedNowTime += cc.director.getDeltaTime()
let delta = AppConst.GameFrameRate
while (this.fixedNowTime > delta) {
this.fixedDic.forEach((v) => { v && v() })
this.fixedNowTime -= delta
}
//update
if (this.isCanUpdate()) {
this.updateDic.forEach((v, key) => { v && v() })
this.runLimit()
}
}
public lateUpdate(): void {
//lateupdate不优化,一定每帧执行的才放这里
this.lateUpdateDic.forEach((v) => { v() })
let v: DelayInfo = null
for (let i = this.delayOneFrames.length - 1; i >= 0; --i) {
v = this.delayOneFrames[i]
if (v.couter >= 1) {
v.func && v.func()
this.delayOneFrames.splice(i, 1)
}
}
this.delayOneFrames.forEach((v) => { v.couter++ })
}
//-----------------------------公开外部方法start--------------------------------
/**
* 分帧执行await async第一次会等待回调返回,之后就直接执行
* @param arr
* @param iterator 每帧如何迭代arr
* @param limit 每帧最多执行多少次
*/
public async eachLimit(arr: Array<any>, iterator: ILimitFunc, limit: number) {
return new Promise((resolve, reject) => {
let info = new LimitInfo(iterator, arr, limit, resolve, reject)
this.limitDic.set(LoopMgr.LoopIndex++, info)
})
}
public addUpdate(func: Function): number {
let id = LoopMgr.LoopIndex++
this.add(id, func, this.updateDic)
return id
}
public remvoeUpdate(id: number) {
this.remove(id, this.updateDic)
}
public addFixedUpdate(func: Function): number {
let id = LoopMgr.LoopIndex++
this.add(id, func, this.fixedDic)
return id
}
public removeFixed(id: number) {
this.remove(id, this.fixedDic)
}
public addLateUpdate(func: Function): number {
let id = LoopMgr.LoopIndex++
this.add(id, func, this.lateUpdateDic)
return id
}
public removeLateUpdate(id: number) {
this.remove(id, this.lateUpdateDic)
}
public setTimeout(func: Function, second: number): number {
let tinfo = new TimeoutInfo(func, second)
tinfo.id = setTimeout(func, second * 1000)
this.timeoutDic.set(tinfo.id, tinfo)
return tinfo.id
}
/**
* 等待多少秒,0会间隔一帧
* 用于协程
*/
public async waitForTime(second: number) {
return new Promise<number>((resolve) => {
let id=this.setTimeout(() => {
resolve(id)
}, second)
})
}
public clearTimeout(id: number) {
if (id < 0) return
clearTimeout(id)
if(this.timeoutDic.has(id)){
this.timeoutDic.delete(id)
}
}
public clearInterval(id: number) {
if (id <0) return
if(this.intervalDic.has(id)){
this.intervalDic.delete(id)
}else{
console.error("clearInterval 不存在的id")
}
clearInterval(id)
}
public setInterval(func: Function, second: number) {
let tinfo = new InterInfo(func, second)
tinfo.id = setInterval(func, second * 1000)
this.intervalDic.set(tinfo.id, tinfo)
return tinfo.id
}
public delayOneFrame(func: Function) {
this.delayOneFrames.push(new DelayInfo(func))
}
//-----------------------------公开外部方法start--------------------------------
private add(id: number, func: Function, map: Map<number, Function>) {
if (map.has(id)) return
map.set(id, func)
}
private remove(id: number, map: Map<number, Function>) {
map.delete(id)
}
private clearEvents() {
for (let v in EventConst) {
cc.systemEvent.removeAll(v)
}
}
/**
* 隔帧执行
*/
private isCanUpdate(): boolean {
if (AppConst.GameFrameInterval <= 0) return true
this.updateFramer--
if (this.updateFramer <= 0) {
this.updateFramer = AppConst.GameFrameInterval
return true
}
return false
}
/**
* await async在分帧没意义,await卡几十帧,之后一帧就被执行完了
*/
private runLimit() {
this.deleteLimits.length = 0
for (const [key, info] of this.limitDic.entries()) {
let i = 0
while (info.running < info.arr.length && i < info.limit) {
info.iterator(info.arr[info.running], info.running)
info.running++
i++
}
if (info.running >= info.arr.length) {
this.deleteLimits.push(key)
info.resolve()
}
}
this.deleteLimits.forEach((key) => {
this.limitDic.delete(key)
})
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "6f857b7e-6dec-4234-aba5-6bac9c9184fc",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import IManager from "../Interface/IManager";
export default abstract class Manager implements IManager{
//注释父类的的TypeName让编译器自动检查子类提示
//static get TypeName(): string{return "Manager"}
async start(){}
update():void{}
lateUpdate():void{}
release(){}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "d98090ce-fe3a-4842-9124-fc68f61dfdbe",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import MenuController from "../../Game/MenuController";
import Controller from "../Controller";
import Manager from "./Manager";
export let InitModules=[
MenuController
]
export default class ModuleMgr extends Manager{
static get TypeName():string{return "ModuleMgr"}
private modules:Array<Controller>=null
public async start(){
console.log("开始初始化模块")
this.modules=new Array()
let modules=InitModules
let promises=[]
for(let mod of modules){
this.modules.push(mod.Inst)
promises.push(mod.Inst.init())
}
await Promise.all(promises)
console.log("ModuleMgr")
}
public release(){
console.log("ModuleMgr onRelease")
for(let mod of this.modules.reverse()){
mod.release()
}
this.modules.length=0
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "8e11150f-b79e-41e3-b05f-05edc4192642",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import Manager from "./Manager";
import AppFacade from "../AppFacade";
import AssetMgr from "./AssetMgr";
import { ResConst } from "../ConstDefine/ResConst";
import LoopMgr from "./LoopMgr";
import MathUtil from "../Util/MathUtil";
import GameUtil from "../Util/GameUtil";
import { EventConst } from "../ConstDefine/EventConst";
const ValidID=-1
class Info{
constructor(public res: string, public Id: number = ValidID, public loop: boolean = true, public volume: number = 1) { }
}
export default class SoundMgr extends Manager{
static get TypeName(): string{return "SoundMgr"}
private musicDic:Map<string,Info>=new Map()
private effectDic:Map<string,Info>=new Map()
private tmpMusic:Info
private effectResDic:Map<string,cc.AudioClip>=new Map()
async start(){
this.initSoundDB()
this.playStartMusic()
console.log("SoundMgr")
cc.systemEvent.on(EventConst.ShowGame,this.onShowGame,this)
cc.systemEvent.on(EventConst.HideGame,this.onHideGame,this)
}
public release(){
console.log("SoundMgr onRelease")
this.stopAllMusic()
this.stopTmpMusic()
this.musicDic.clear()
this.effectResDic.clear()
this.tmpMusic=undefined
cc.systemEvent.off(EventConst.ShowGame,this.onShowGame,this)
cc.systemEvent.off(EventConst.HideGame,this.onHideGame,this)
}
private onHideGame(){
cc.log("cocos隐藏游戏")
// cc.audioEngine.pauseAll()
}
private onShowGame(){
cc.log("cocos显示游戏")
// cc.audioEngine.resumeAll()
}
private initSoundDB() {
}
private playStartMusic(){
}
public tryChangeMusic(isOpen:boolean){
cc.log("改变声音状态",isOpen)
if(isOpen){
// this.IsMusicOpen&&this.resumAllMusic()
cc.audioEngine.resumeAll()
}else{
cc.audioEngine.pauseAll()
}
}
//播放URL的音乐
public async playMusicByUrl(resName: string, volume: number = 1, loop: boolean = true) {
let info: Info = this.musicDic.get(resName)
if (!info) {
info = new Info(resName)
//不循环的没必要加如缓存
loop && this.musicDic.set(resName, info)
info.loop = loop
info.volume = volume
}
let audio = await this.loadResByUrl(resName) as cc.AudioClip;
if (audio) {
info.Id = cc.audioEngine.play(audio, loop, volume)
cc.log("播放音乐", resName)
}
}
//播放场景中的音乐
public async playResMusic(resName:string,volume:number=1,loop:boolean=true){
let info:Info=this.musicDic.get(resName)
if(!info){
info=new Info(resName)
//不循环的没必要加如缓存
loop&&this.musicDic.set(resName,info)
info.loop=loop
info.volume=volume
}
let audio = this.loadResClone(resName);
if (audio) {
info.Id = cc.audioEngine.play(audio, loop, volume)
cc.log("播放音乐", resName)
}
}
/**
* 播放音乐,可以同时播放多个音乐
* @param resName
* @param volume
* @param loop
*/
public async playMusic(resName:string,volume:number=1,loop:boolean=true){
let info:Info=this.musicDic.get(resName)
if(!info){
info=new Info(resName)
//不循环的没必要加如缓存
loop&&this.musicDic.set(resName,info)
info.loop=loop
info.volume=volume
}
let audio = await this.loadResAsync(ResConst.AudioABName, resName)
if (audio) {
info.Id = cc.audioEngine.play(audio, loop, volume)
cc.log("播放音乐", resName)
}
}
/**
* 播放临时音乐,不会被记录下来musicDic
* @param resName
* @param volume
* @param loop
* @param resume 播放结束自动切回背景音乐吗
*/
public async playTmpMusic(resName:string,volume:number=1,loop:boolean=true,resume:boolean=false){
if(this.tmpMusic){
this.stopTmpMusic()
}
this.tmpMusic=new Info(resName)
let audio=await this.loadResAsync(ResConst.AudioABName,"Bgm/"+resName)
let musicTime=0
if(audio){
this.tmpMusic.loop=loop
this.tmpMusic.volume=volume
this.tmpMusic.Id=cc.audioEngine.play(audio,loop,volume)
musicTime=audio.duration
}
if(resume&&musicTime>0){
AppFacade.getMgr(LoopMgr).setTimeout(()=>{
this.resumAllMusic()
},musicTime)
}
}
public stopTmpMusic(){
if(!this.tmpMusic) return
if(this.tmpMusic.Id!=ValidID){
cc.audioEngine.stop(this.tmpMusic.Id)
}
this.tmpMusic=null
}
public async resumAllMusic(){
for(let v of this.musicDic){
let info=v[1]
await this.playMusic(info.res,info.volume,info.loop)
}
}
public stopAllMusic(){
cc.audioEngine.stopAll()
}
public stopMusic(resName:string){
let info = this.musicDic.get(resName)
this.musicDic.delete(resName)
if(info&&info.Id!=ValidID){
cc.audioEngine.stop(info.Id)
}
}
//一套音效随机播放一个
public playEffectR(resName:string[],volume:number=1){
let i=MathUtil.randInt(resName.length)
this.playEffect(resName[i],0,volume)
}
public playEffect(resName:string,delay:number=0,volume:number=1,isLoop:boolean=false){
if(GameUtil.isStringEmpty(resName)) return
if (delay > 0) {
AppFacade.getMgr(LoopMgr).setTimeout(this._playEffect.bind(this, resName, volume), delay)
} else {
this._playEffect(resName, volume, isLoop)
}
}
public stopEffect(resName:string){
if(GameUtil.isStringEmpty(resName)) return
let info=this.effectDic.get(resName)
if(info){
cc.audioEngine.stopEffect(info.Id)
this.effectDic.delete(resName)
}
}
//播放URL的音效
public async playEffectByUrl(resName: string, delay: number = 0, volume: number = 1, isLoop: boolean = false) {
this.stopAllMusic();
let audio = await this.loadResEffectByUrl(resName)
if (audio) {
let id = cc.audioEngine.play(audio, isLoop, volume)
//长期循环播放才保存
if (isLoop) {
let info = new Info(resName, id, isLoop, volume)
this.effectDic.set(resName, info)
}
}
}
//播放场景中的音效
public playResEffect(resName:string,delay:number=0,volume:number=1,isLoop:boolean=false){
this.stopAllMusic();
let audio=this.loadResEffectClone(resName)
if(audio){
let id=cc.audioEngine.play(audio,isLoop,volume)
//长期循环播放才保存
if(isLoop){
let info=new Info(resName,id,isLoop,volume)
this.effectDic.set(resName,info)
}
}
}
private async _playEffect(resName:string,volume:number=1,isLoop:boolean=false){
let audio=await this.loadEffectAsync(resName)
if(audio){
let id=cc.audioEngine.play(audio,isLoop,volume)
//长期循环播放才保存
if(isLoop){
let info=new Info(resName,id,isLoop,volume)
this.effectDic.set(resName,info)
}
}
}
private async loadResEffectByUrl(resName:string){
let effect=this.effectResDic.get(resName)
if(!effect){
effect=await this.loadResByUrl(resName) as cc.AudioClip;
effect&&this.effectResDic.set(resName,effect)
}
return effect
}
private loadResEffectClone(resName:string){
let effect=this.effectResDic.get(resName)
if(!effect){
effect=this.loadResClone(resName)
effect&&this.effectResDic.set(resName,effect)
}
return effect
}
private async loadEffectAsync(resName:string){
let effect=this.effectResDic.get(resName)
if(!effect){
effect=await this.loadResAsync(ResConst.AudioABName,resName)
effect&&this.effectResDic.set(resName,effect)
}
return effect
}
private async loadResAsync(abName:string,resName:string):Promise<cc.AudioClip>{
let asMgr=AppFacade.getMgr(AssetMgr)
return await asMgr.loadAssetAsync<cc.AudioClip>(abName,resName,cc.AudioClip)
}
private loadResClone(resName:string,instantiate:boolean=false){
let prefab=cc.find(ResConst.AudioABName+"/"+resName);
if (!prefab) {
console.error("loadViewClone prefab is null")
return
}
let clone = instantiate && cc.instantiate(prefab) || prefab
return clone.getComponent(cc.AudioSource).clip;
}
private async loadResByUrl(resName:string){
return new Promise((resolve,reject)=>{
if(!resName){
reject("文件名错误!");
}
cc.assetManager.loadRemote(resName, (err, audioClip) => {
resolve(audioClip);
});
});
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "164a6421-a6f8-45ea-87cd-cccd702a1787",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import UIWindowView from "../BaseView/UIWindowView";
import { EventConst } from "../ConstDefine/EventConst";
import AppFacade from "../AppFacade";
import LoopMgr from "./LoopMgr";
import Manager from "./Manager";
import View from "../BaseView/View";
/*
管理窗口类型的view
*/
class ViewInfo{
public view:View
public timer:number=0
public isRecycle:boolean=false
}
export default class ViewMgr extends Manager{
static get TypeName(): string{return "ViewMgr"}
private intervalId:number=-1
private viewDic:Map<string,ViewInfo>
private allVies:Array<View>
async start(){
this.allVies=new Array()
this.viewDic=new Map()
cc.systemEvent.on(EventConst.CloseAllWindow,this.closeAllWindowView,this)
this.intervalId=AppFacade.getMgr(LoopMgr).setInterval(this.onInterVal.bind(this),1)
console.log("ViewMgr onStart")
}
public release(){
console.log("ViewMgr onRelease")
AppFacade.getMgr(LoopMgr).clearInterval(this.intervalId)
this.intervalId=-1
cc.systemEvent.off(EventConst.CloseAllWindow,this.closeAllWindowView,this)
this.releaseViews()
}
private onInterVal(){
for(let [name,info] of this.viewDic.entries()){
if(!info.isRecycle) continue
info.timer-=1
if(info.timer<=0){
let view=info?.view
if(view&&!view.IsOpen){
info.view=null
this.viewDic.delete(name)
view.release()
}
}
}
}
/**
@param 释放所有windows 释放
*/
public releaseViews():void{
for(let i=this.allVies.length-1;i>=0;--i){
let view=this.allVies[i] as View
view?.release()
}
this.allVies.length=0
UIWindowView.maskView?.release()
UIWindowView.maskView=null
}
private closeAllWindowView():void{
UIWindowView.maskView?.closeAll()
}
/**
* 界面是否开启
* @param viewNames TODO
*/
public isViewOpen(...viewNames:string[]):boolean{
if(!viewNames) return false
let res=false
for(let name of viewNames){
let view=this.allVies?.find((view)=>view.getTypeName()==name)
if(view instanceof UIWindowView){
res=UIWindowView?.maskView.isInStack(view)
}else if(view instanceof View){
res=view.IsOpen
}
if(!res) break
}
return res
}
public openView<T extends View>(viewName:string,type:typeof View):T{
let info=this.viewDic.get(viewName)
if(!info){
info=new ViewInfo()
}
let view=info?.view
if(!view){
view=new type()
info.view=view
this.viewDic.set(viewName,info)
}
info.isRecycle=false
return <T>view
}
public async updateView(viewName:string,data?:Object){
let info=this.viewDic.get(viewName)
await info?.view?.updateData(data)
}
public async closeView(viewName:string){
let info=this.viewDic.get(viewName)
info?.view?.close()
}
public releaseView(viewName:string,releaseTime:number){
let info=this.viewDic.get(viewName)
if(!info) return
info.isRecycle=true
info.timer=releaseTime
}
public getView<T extends View>(viewName:string):T{
let info=this.viewDic.get(viewName)
return info?.view as T
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "e468010d-20eb-415a-8658-5eaaf667af78",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import IModel from "./Interface/IModel";
import IController from "./Interface/IController";
//model用于存放模块数据
export default abstract class Model implements IModel{
constructor(protected control:IController){}
abstract init()
abstract release()
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "2090ba29-8cec-41fa-88f2-c28b671f8fe7",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.1.2",
"uuid": "32033f68-fd6e-4d4f-a042-04d9e37c0624",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}
\ No newline at end of file
import View from "../BaseView/View";
export default class UI extends View{
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "f507b183-fc83-448c-b9f8-d0d24b5b8236",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
This diff is collapsed.
{
"ver": "1.0.8",
"uuid": "8a813e48-2e16-46a8-80b6-5252ea6ffe4d",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
export class UIAnimationParams{
type:UIAnimation=UIAnimation.None
time:number=0.3
}
//UI动画
export enum UIAnimation{
None,
Circle, //转圈
Scale, //缩放
}
{
"ver": "1.0.8",
"uuid": "0bc440f3-16d1-4ae4-825e-aba660fccdc6",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
import UIRenderView from "./UIRenderView";
import UI from "./UI";
/**
* @param UI容器 有子对象的界面
*/
export default class UIContainer extends UI{
protected data:Array<Object>
protected renders: Array<UIRenderView>=new Array()
protected sendDataFromRenderCb:Function
protected isCommonData:boolean=false //相同的数据更新,只能判断引用
public async updateData(data?:Array<Object>){
this.isCommonData=this.data==data&&this.data!=undefined
this.data=data?.slice()||this.data||new Array()
await this.onUpdateData(this.data)
}
public release(){
this.renders?.forEach((r)=>r.release())
super.release()
}
//render回调回来
public addSendDataFromRender(cb:Function){
this.sendDataFromRenderCb=cb
}
//render回调数据
protected onSendDataFromRender(data?:Object){
this.sendDataFromRenderCb&&this.sendDataFromRenderCb(data)
}
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "6d1a9710-6292-4eab-a565-383fd229b0b3",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.1.2",
"uuid": "ccb1192c-9514-4eda-ac17-b9dac1e561b9",
"isBundle": false,
"bundleName": "",
"priority": 1,
"compressionType": {},
"optimizeHotUpdate": {},
"inlineSpriteFrames": {},
"isRemoteBundle": {},
"subMetas": {}
}
\ No newline at end of file
This diff is collapsed.
{
"ver": "1.0.8",
"uuid": "0b0c53d9-36ad-431b-ad28-7eba0c016202",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
This diff is collapsed.
{
"ver": "1.0.8",
"uuid": "d85e826c-3025-469a-a152-f7efbf9b5139",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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