import SpineMgr from "../core/mgrs/SpineMgr"; import LightShader from "../core/shader/2d/LightShader"; import AIPlayer from "../d2Obj/AIPlayer"; import D2BallSrc from "../d2Obj/D2BallSrc"; import D2World from "../d2Obj/D2World"; import D3World from "../d3Obj/D3World"; import DataMgr from "../data/DataMgr"; import { AwardType, FIRST_BALL_HOLE, GameMode, Prop, SkillType } from "../data/Define"; import ui_UIMoney from "../fgui/res/game/ui_UIMoney"; import GameMgr from "../game/GameMgr"; import SkillMgr from "../game/SkillMgr"; import TalkMgr from "../game/TalkMgr"; import WordsMgr from "../game/WordsMgr"; import UIDraw from "../ui/UIDraw"; import UIFlyEft from "../ui/UIFlyEft"; import { UIGame } from "../UI/UIGame"; import UIGameEnd from "../ui/UIGameEnd"; import UIGetAward from "../ui/UIGetAward"; import UIMain from "../ui/UIMain"; import UIRodMethod from "../UI/UIRodMethod"; import UISign from "../ui/UISign"; import UISkill from "../ui/UISkill"; import { xGame } from "../xGame"; export default class Common { // 单例对象 private static _instance: Common = null; public static getInstance(): Common { if (!this._instance) { this._instance = new Common(); } return this._instance; } constructor() { Common._instance = this; window["common"] = this; } gameMgr: GameMgr; //3d场景 d3Scene: Laya.Scene3D; d2World: D2World; d3World: D3World; gameUI: UIGame; uiRodMethod: UIRodMethod; aiPlayer: AIPlayer; /**标准分辨率下,固定相机下2d3d转换关系 */ convertNum: number = 0.025; //gameUI: UIGame; VectorUp = new Laya.Vector3(0, 1, 0); scaleV3One = new Laya.Vector3(); scaleV3Two = new Laya.Vector3(); // posV4 = new Laya.Vector4(); showDebug: boolean = false; openGuide: boolean = true; // screenImg: Laya.Texture; //高低杆偏移值 rodOffest = new Laya.Vector2(0, 0); //高低杆偏移角度 rodAngle: number = 0; //游戏模式 gameMode: GameMode = GameMode.classic; //秘书spine secretary: SpineMgr; //经典模式表情spine classicEmotionSpine: SpineMgr; //挑战模式的奖励模式 awardSpine: SpineMgr; //大招技能管理 skillMgr: SkillMgr; wordsMgr: WordsMgr; talkMgr: TalkMgr; //大招关卡当前得索引 bigMoveLevelIndex: number = 1; //进入大招模式需要的金币数目 bigMoveNeedCoin: number = 1000; //进入巅峰赛需要的金币数目 classicNiceNeddCoin: number = 1000; //通过后奖励的金币数目 passAwardCoin: number = 2000; //经典模式的房间类型 classicRoomType: number = 1; /**最大体力值 */ maxPower: number = 20; /**自然恢复最大值 */ natureMaxPower: number = 5; /**看视频增加的体力数 */ videoPower: number = 2; /**自然恢复量 */ powerRecoverNum: number = 900; //当前玩家所选择的技能类型 curPlayerSkillType: number = 0; //是否是新的一天 isNewDay: boolean = false; //玩家的回合点击了球球 clickedBall: boolean = false; //摆球达人当前选择的关卡 placeBallCurLevel: number = 0; //通关摆球达人时的星星数目 placeBallStarNum: number = 0; //是否已经延长了辅助线 longHelpLine: boolean = false; /**每日分享钻石的最大次数 */ maxShareDiamondTimes: number = 3; //uigame界面中guide步骤 guideStep: number = 0; temSelfLevel = 0;//新手引导下玩家的技能等级 extraMoveNum = 0;//大招模式额外移动量, /// curRankID: number = 0; rankID = { normalStar: 12000, wxStar: 12001 } // // skillNameList = ["Fall from the sky", "Unstoppable Force", "Freeze Shot","Coming Soon"]; skillNameList = ["Fall from the sky", "Unstoppable Force", "Freeze Shot"]; //skillIconList = ["gf_jn1", "gf_jn2", "gf_jn4", "gf_jn4"]; skillIconList = ["gf_jn1", "gf_jn2", "gf_jn4"]; btnClickStr: string = "buttonclick"; //大招可升级到的最大等级 maxSkillLevel: number = 10; //当前看广告提升了大招技能等级 upSkillLevel: boolean = false; //游戏开始时间 gameStartTime: number = 0; //////////////////// _sysOffestNum: number = 0; public get sysOffestNum(): number { if (this._sysOffestNum == 0) { this._sysOffestNum = (Laya.stage.width - 1334) / 2; } return this._sysOffestNum; } testShader() { let test = new LightShader(); test.texture = "res/d3Res/ballTexture/ball1.png"; Laya.stage.addChild(test); } playScale(node) { Laya.Tween.to(node, { scaleX: 1.1, scaleY: 1.1 }, 100, null, Laya.Handler.create(this, () => { Laya.Tween.to(node, { scaleX: 1, scaleY: 1 }, 100, null, Laya.Handler.create(this, () => { // })) })) } setGroup(colli: Laya.PhysicsCollider | Laya.Rigidbody3D, ...group) { let out = 0; for (let index = 0; index < group.length; index++) { if (index == 0) { out = Laya.Physics3DUtils[`COLLISIONFILTERGROUP_CUSTOMFILTER${group[index]}`]; } else { out = out | Laya.Physics3DUtils[`COLLISIONFILTERGROUP_CUSTOMFILTER${group[index]}`]; } } colli.collisionGroup = out; } setCanGroupWith(colli: Laya.PhysicsCollider | Laya.Rigidbody3D, ...group) { let out = 0; for (let index = 0; index < group.length; index++) { if (index == 0) { out = Laya.Physics3DUtils[`COLLISIONFILTERGROUP_CUSTOMFILTER${group[index]}`]; } else { out = out | Laya.Physics3DUtils[`COLLISIONFILTERGROUP_CUSTOMFILTER${group[index]}`]; } } colli.canCollideWith = out; } loadPrefab(name, callback) { Laya.loader.create(`prefab/${name}.json`, Laya.Handler.create(this, (obj) => { let prefab = new Laya.Prefab(); prefab.json = obj; let img: Laya.Image = Laya.Pool.getItemByCreateFun(name, prefab.create, prefab); callback && callback(img); })) } pos2to3Convert(x, y, d3Pos: Laya.Vector3) { //转换2D屏幕坐标系统到3D正交投影下的坐标系统 x = x + this.sysOffestNum; d3Pos.setValue(x, y, 0); let success = this.d3World.camera.convertScreenCoordToOrthographicCoord(d3Pos, d3Pos); if (success) { //success } else { console.error("转换出错了。。。。。。。。"); } } scale2to3Convert(num) { this.scaleV3One.setValue(0, 0, 0); this.d3World.camera.convertScreenCoordToOrthographicCoord(this.scaleV3One, this.scaleV3One); this.scaleV3Two.setValue(0, num, 0); this.d3World.camera.convertScreenCoordToOrthographicCoord(this.scaleV3Two, this.scaleV3Two); let outNum = Math.abs(this.scaleV3One.x - this.scaleV3Two.x); return outNum; } pos3to2Convert(d3Pos) { this.d3World.camera.viewport.project(d3Pos, this.d3World.camera.projectionViewMatrix, this.posV4); d3Pos.x = this.posV4.x / Laya.stage.clientScaleX; d3Pos.y = this.posV4.y / Laya.stage.clientScaleY; // d3Pos.x -= this.sysOffestNum; } scale3to2Convert(num) { let scale = this.scale2to3Convert(1); //2d的一个单位对应的3d值 let d2Out = num / scale; return d2Out; } //type=box,circle getCollider(type, restitution = 0.9, density = 10) { let colli; // if (type == "box") colli = new Laya.BoxCollider(); else colli = new Laya.CircleCollider(); // colli.friction = 0; colli.restitution = restitution; colli.density = density; return colli; } getRigbody() { let rigy = new Laya.RigidBody(); rigy.bullet = true; rigy.allowRotation = false; rigy.allowSleep = false; rigy.gravityScale = 0; return rigy; } angleV2 = new Laya.Vector2(); rootV = new Laya.Vector2(0, 1); getfguiRotation(x, y) { this.angleV2.setValue(x, y); Laya.Vector2.normalize(this.angleV2, this.angleV2); let angle = Math.acos(Laya.Vector2.dot(this.rootV, this.angleV2)) * 180 / Math.PI; if ((this.angleV2.x >= 0 && this.angleV2.y >= 0) || (this.angleV2.x >= 0 && this.angleV2.y < 0)) { angle = -angle; } return 180 + angle; } getAngle(x, y) { this.angleV2.setValue(x, y); Laya.Vector2.normalize(this.angleV2, this.angleV2); let angle = Math.acos(Laya.Vector2.dot(this.rootV, this.angleV2)) * 180 / Math.PI; return angle; } randomNum(a, b) { return a + Math.floor((b - a + 1) * Math.random()); } getRandArrEle(arr: Array) { return arr[Math.floor(arr.length * Math.random())]; } getSign(val) { return val >= 0 ? 1 : -1; } botherArr(arr: Array) { let times = arr.length + 2; let length = arr.length; let a; let b; let temp; for (let index = 0; index < times; index++) { a = Math.floor(Math.random() * length); b = Math.floor(Math.random() * length); // temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } } getGameIconUrl(id: string): string { return "ui://game/" + id; } getComponentUrl(id: string): string { return "ui://game/" + id; } getAnimation() { } // judgeSkillType(type: SkillType = SkillType.highSpace) { if (this.gameMode == GameMode.classic) return; let gameMgr = this.gameMgr; if (gameMgr.selfTurn) { if (gameMgr.selfCurSkill == type) { return true; } } else { if (gameMgr.aiCurSkill == type) { return true; } } } //球碰到6个桌球洞口了 ballColliHole(collider) { //首次进球,确定阵营,白球进入无效 if (xGame.common.gameMgr.isFirstInGame && collider.owner["mySrc"].number != 0) { xGame.common.gameMgr.isFirstInGame = false; xGame.eventMgr.event(FIRST_BALL_HOLE, collider.owner["mySrc"].number); } collider.owner.mySrc.checkWrongBall(); } // getArrMaxEle(arr) { let max = -Infinity; for (let index = 0; index < arr.length; index++) { max = Math.max(arr[index], max); } return max; } getArrMinEle(arr) { let min = Infinity; for (let index = 0; index < arr.length; index++) { min = Math.min(arr[index], min); } return min; } playRandomMutiBallBigSkillSound() { if (Math.random() <= 0.5) return; let rand = this.randomNum(1, 6); let str = "ganfa0" + rand; xGame.soundMgr.playSound(str); } showOneCamera(type) { let object = xGame.common.d3World.cameraObj; for (const key in object) { if (Object.prototype.hasOwnProperty.call(object, key)) { object[key].init(); object[key].owner.active = key == type; } } } //检测球是否已经超出了边境 checkBallOverBorder(x, y) { let radius = 17; let condition = this._checkBorder(x + radius, y) || this._checkBorder(x - radius, y) || this._checkBorder(x, y + radius) || this._checkBorder(x, y - radius); // if (condition) { //超出边境了 return true; } } private _checkBorder(x, y) { let borderRect = this.d2World.borderRect; let xOffest = 20; let yOffest = 20; //上边界 if (y <= borderRect.y - yOffest) { return true; } //下边界 if (y >= borderRect.y + borderRect.height + yOffest) { return true; } //左边界 if (x <= borderRect.x - xOffest) { return true; } //右边界 if (x >= borderRect.x + borderRect.width + xOffest) { return true; } } //权重// cfg只有id和weight两个参数 initWeight(cfg) { let allCfgData = { data: {}, allWeightNum: 0 }; let weightCfg = allCfgData.data; // let weight = 0; for (const key in cfg) { weightCfg[key] = {}; weightCfg[key].id = cfg[key].id; weightCfg[key].minWeight = weight; // weight += cfg[key].weight; // weightCfg[key].maxWeight = weight } allCfgData.allWeightNum = weight; return allCfgData; } getRandomWeightData(cfg) { let weightCfg = cfg.data; let allWeightNum = cfg.allWeightNum; let rand = Math.floor(Math.random() * allWeightNum); for (const key in weightCfg) { if (rand > weightCfg[key].minWeight && rand <= weightCfg[key].maxWeight) { return weightCfg[key]; } } return weightCfg[1]; } //显示小秘书对话框 showGirlTalkPop(wordsIndex, node, msgNode) { node.visible = true; msgNode.text = cfgTable.secretaryData[wordsIndex].msg; node.t0.play(Laya.Handler.create(this, () => { node.visible = false; })); } stopGirlPop(node) { node.t0.stop(); node.visible = false; } createHead(loader: fgui.GLoader, url, size = 107) { if (Laya.Browser.name == "Browser") { //console.log("处于浏览器中", Laya.Browser.name); loader.url = url; return; } if (Moyu.isTT) { let localImage = new Image(); localImage.src = url; localImage.onload = () => { let t2d = new Laya.Texture2D(); t2d.width = size; t2d.height = size; loader.displayObject.graphics.drawImage(new Laya.Texture(t2d), 0, 0); t2d.loadImageSource(localImage); } } else { console.log('zh:url=',url); loader.url = url; } } addTestCoin(num) { DataMgr.setCoin(num); } addTestDiamond(num) { DataMgr.setDiamond(num); } addTestSkill() { DataMgr.setBigSkill(0, 99); DataMgr.setBigSkill(1, 99); DataMgr.setBigSkill(2, 99); } playClassicEmotion(number, x, y) { if (this.gameMode == GameMode.bigMove) return; // let randIndex = this.randomNum(0, 2); let data = { x: x, y: y, scaleX: 1, scaleY: 1 }; let parent = this.gameUI.ui.classicEmotionSpineNode.displayObject; if (this.gameMgr.selfTurn) { if (this.gameMgr.selfBallArr.indexOf(number) > -1) { //进了己方阵营的球 this.classicEmotionSpine.play(data, randIndex, false, parent); } else { if (this.gameMgr.aiBallArr.indexOf(number) > -1) { //进了别人的球 } else { if (number == this.gameMgr.blackNum) { //黑8 if (this.gameMgr.selfBallArr.length == 0) { //胜利进球 this.classicEmotionSpine.play(data, randIndex, false, parent); } else { //失败 } } else { //不是黑8,首次进球 this.classicEmotionSpine.play(data, randIndex, false, parent); } } } } else { if (this.gameMgr.aiBallArr.indexOf(number) > -1) { //进了ai阵营的球 this.classicEmotionSpine.play(data, randIndex, false, parent); } else { if (this.gameMgr.selfBallArr.indexOf(number) > -1) { //进了玩家的球 } else { if (number == this.gameMgr.blackNum) { //黑8 if (this.gameMgr.aiBallArr.length == 0) { //胜利进球 this.classicEmotionSpine.play(data, randIndex, false, parent); } else { //失败 } } else { //不是黑8,首次进球 this.classicEmotionSpine.play(data, randIndex, false, parent); } } } } } playHappySound(number) { if (this.gameMode != GameMode.classic) return; if (number == 8) return; // let play = false; // if (this.gameMgr.selfTurn) { if (this.gameMgr.ensureBallType) { //已经确定阵营,且进球了 if (this.gameMgr.selfBallArr.indexOf(number) > -1) { //进了己方阵营的球 play = true; } } else { play = true; } } else { if (this.gameMgr.ensureBallType) { //已经确定阵营,且进球了 if (this.gameMgr.aiBallArr.indexOf(number) > -1) { //进了己方阵营的球 play = true; } } else { play = true; } } // if (play) xGame.soundMgr.playSound("applause"); } destroyClassicEmotion() { if (this.gameMode == GameMode.bigMove) return; let parent = this.gameUI.ui.classicEmotionSpineNode.displayObject; parent.destroyChildren(); } playAwardSpine(x, y) { let data = { x: x, y: y, scaleX: 1, scaleY: 1 }; let parent = this.gameUI.ui.awardSpineNode.displayObject; this.awardSpine.play(data, 0, false, parent); } destroyAwardSpine() { let parent = this.gameUI.ui.awardSpineNode.displayObject; parent.destroyChildren(); } tempDir1 = new Laya.Vector2(); tempDir2 = new Laya.Vector2(); ballSize = 33; isBlock(bx, by, hx, hy, except: D2BallSrc = null) { this.tempDir1 = xGame.tools.getV2Dir(bx, by, hx, hy, this.tempDir1); let balls = xGame.common.d2World.ballArr; let outArr = []; for (let index = 0; index < balls.length; index++) { let obj = balls[index]; if (obj.number == 0) continue; if (obj == except) continue; //其他球与该球的方向距离 let dis = xGame.tools.getDistance(obj.gameObj.x, obj.gameObj.y, bx, by); this.tempDir2 = xGame.tools.getV2Dir(bx, by, obj.gameObj.x, obj.gameObj.y, this.tempDir2); let num = Laya.Vector2.dot(this.tempDir1, this.tempDir2); if (num >= 1) num = 1; if (num < 0) //大于90 continue; let gap = Math.sin(Math.acos(num)) * dis; if (gap < this.ballSize) { outArr.push({ dis: xGame.tools.getDis(bx, by, obj.gameObj.x, obj.gameObj.y), disHon: Math.cos(Math.acos(num)) * dis, disVer: Math.sin(Math.acos(num)) * dis, src: balls[index], dir: this.tempDir1 }) } } // if (outArr.length > 0) { outArr.sort((a, b) => { return a.dis - b.dis }); return outArr[0]; } } public AngleBetween(vector1, vector2) { let rad = Math.acos(Laya.Vector2.dot(vector1, vector2)); return rad * (180 / Math.PI); } public getSecretaryScale() { if (this.secretary.spineName == "mishu") { return 1.28; } else { return 1.024; } } //签到奖励中是否包含球杆 public signAwardContainsRod(arr) { let temp; for (let index = 0; index < arr.length; index++) { temp = arr[index].split('-')[0]; if (parseInt(temp) > 2) { return true; } } } judgeSameDay() { let lastTime = DataMgr.getSignTime(); let curTime = new Date().getTime(); if (new Date(lastTime).toDateString() === new Date(curTime).toDateString()) { return true; } return false; } getAward(arr: Array, callback?) { let showTriple = arr[0].type <= 2; xGame.uiMgr.Show(UIGetAward, arr, showTriple, (watchVideo) => { let temp: AwardType; for (let index = 0; index < arr.length; index++) { temp = arr[index]; switch (temp.type) { case 1: //钻石 this.playObjFlyAnim(temp.num, temp.type); break; case 2: //金币 this.playObjFlyAnim(temp.num, temp.type); break; case 3: case 4: case 5: case 6: DataMgr.setBallRod(temp.type - 2, 1); DataMgr.setCurBallRod(temp.type - 2); break; default: break; } } // callback && callback(watchVideo); }) } //飞金币或飞钱钱特效 stPos = new Laya.Point(); edPos = new Laya.Point(); getMoneyNode() { let moneyNode: ui_UIMoney; let sign = xGame.uiMgr.getUI(UISign); let draw = xGame.uiMgr.getUI(UIDraw); let end = xGame.uiMgr.getUI(UIGameEnd); let skill = xGame.uiMgr.getUI(UISkill); if (sign && !sign.isHide) moneyNode = sign.ui.moneyNode; if (draw && !draw.isHide) moneyNode = draw.ui.moneyNode; if (end && !end.isHide) moneyNode = end.ui.moneyNode; if (skill && !skill.isHide) moneyNode = skill.ui.moneyNode; let condition1 = (!sign || sign.isHide) && (!draw || draw.isHide) && (!skill || skill.isHide); let main = xGame.uiMgr.getUI(UIMain); if (condition1 && main && !main.isHide) { moneyNode = main.ui.moneyNode; } return moneyNode; } playObjFlyAnim(num, type, callback = null) { this.stPos.x = Laya.stage.width / 2; this.stPos.y = Laya.stage.height / 2; // let moneyNode = this.getMoneyNode(); // switch (type) { case Prop.diamond: this.edPos.x = moneyNode.x + moneyNode.diamondImg.x this.edPos.y = moneyNode.y + moneyNode.diamondImg.y moneyNode.diamondImg.displayObject.localToGlobal(this.edPos); this.edPos.x /= 2; this.edPos.y /= 2; break; case Prop.coin: this.edPos.x = moneyNode.x + moneyNode.coinImg.x this.edPos.y = moneyNode.y + moneyNode.coinImg.y moneyNode.coinImg.displayObject.localToGlobal(this.edPos); this.edPos.x /= 2; this.edPos.y /= 2; break; default: break; } // this.edPos.x += this.sysOffestNum; xGame.soundMgr.playSound("coinbag"); // xGame.uiMgr.Show(UIFlyEft, this.stPos, this.edPos, num, type, () => { //完成后的回调用 switch (type) { case Prop.diamond: DataMgr.setDiamond(num); break; case Prop.coin: DataMgr.setCoin(num); break; default: break; } callback && callback(); }) } // autoPopUIView() { let arr = []; let sign = this.judgeSameDay() ? false : true; if (sign) arr.push("sign"); let draw = DataMgr.getDailyfreeDrawTimes() > 0; if (draw) arr.push("draw"); if (arr.length <= 0) return; let str = this.getRandArrEle(arr); switch (str) { case "sign": xGame.uiMgr.Show(UISign); break; case "draw": xGame.uiMgr.Show(UIDraw); break; default: break; } } // getMSTime(time) { let min: any = Math.floor(time / 60); let sec: any = Math.floor((time - min * 60)) if (sec < 10) sec = "0" + sec; if (min < 10) min = "0" + min; return `${min}:${sec}` } testPower() { DataMgr.setPower(0, false); } getAllStarNum() { let data = DataMgr.getPlaceBallLevelList(); let out = 0; for (let index = 0; index < data.length; index++) { out += data[index].star; } return out; } recoverCameraView() { Laya.timer.once(900, this, () => { xGame.common.showOneCamera("mainCamera"); if (xGame.common.gameUI.ui.d2Node.alpha == 0) { xGame.common.gameUI.ui.d2Node.alpha = 1; xGame.common.gameUI.ui.border.alpha = 0; // if (Laya.physicsTimer.scale < 1) { Laya.physicsTimer.scale = 1; } } }) } //获取经典模式的段位 getClassicLevel() { let successTimes = DataMgr.getClassicTimes(); let needKey = ""; let lastKey = ""; let cfg = cfgTable.classictimesData; let data: cfgTable.classictimes; for (const key in cfg) { data = cfg[key]; if (successTimes <= data.times) { needKey = key; } lastKey = key; } if (needKey == "") needKey = lastKey; // return cfg[needKey]; } }