import { _decorator, Component, Label, Node, tween, UIOpacity, v3, Vec3, Sprite, UITransform, instantiate } from 'cc'; import { AudioManager } from '../AudioManager'; import LocalizedLabel from '../i18n/LocalizedLabel'; import PoolManager from '../PoolManager'; import { Popup } from '../src/ui/page/popup'; import { Url } from '../Url'; import { BlockConfig, BlockState, GridBoardData } from './Block/BlockData'; import GlobalData from './GlobalData'; import { GridBlockMgr } from './GridBlockMgr'; import { Guide } from './Guide'; import { LocalStorageMgr } from './LocalStorageMgr'; import { TouchMgr } from './TouchMgr'; import { BlockController } from './Block/BlockController'; const { ccclass, property } = _decorator; @ccclass('MainGameLogic') export class MainGameLogic extends Component { /** 单例模式 */ private static _ins: MainGameLogic; constructor() { super(); MainGameLogic._ins = this; } public static get ins(): MainGameLogic { if (!MainGameLogic._ins) { MainGameLogic._ins = new MainGameLogic(); } return MainGameLogic._ins; } @property(Node) background: Node = null; @property(Node) guide: Node = null; @property(Label) curScoreLabel: Label = null; @property(Label) historyScoreLabel: Label = null; @property(Label) todayScoreLabel: Label = null; /** 当前得分 */ public curScore: number = 0; /** 特殊处理总钱数 */ spaciCashTotal: number = 0; sssspaciCashTotal: number = 0; @property(Label) refrashPropLabel: Label = null; @property(Label) hummerPropLabel: Label = null; lotteryData: any = null; private lastReturnedIndex: number = 0; @property(Node) tarPropRefrashIcon: Node = null; @property(Node) tarPropHummerIcon: Node = null; //特效展示节点 @property(Node) effectsContainer: Node = null; propInUse: boolean = false; @property(Node) autoPlayBtn: Node = null; // 自动放置按钮 isAutoPlaying: boolean = false; // 自动播放状态 autoPlayTimer: any = null; // 自动播放计时器 start() { AudioManager.ins.play(Url.AUDIO.BGM); this.gameStart(); } //游戏开始 gameStart() { if (!GlobalData.isCommer || GlobalData.guideRecord >= 5) { GlobalData.isCommer = false; LocalStorageMgr.setItem(LocalStorageMgr.isCommer_key, GlobalData.isCommer); GridBlockMgr.ins.generateBoard_effect(GlobalData.lastGameBoard); this.scheduleOnce(() => { GridBlockMgr.ins.generateSpecificSelectionBlock(false) }, 2); this.guide.active = false; } else { console.log("开启新手引导"); this.guide.active = true; } mtec.cc.adaptBackgroundNode(this.background); //不需要 // this.checkAndUpdateDailyHighScore(GlobalData.lastLoginDate); //更新道具数量,不需要 // this.updatePropNum(); } //游戏结束 gameOver() { this.scheduleOnce(async () => { await Popup.Gameoverpage(); }, 3) } //重新开始游戏 reStartGame() { this.curScore = 0; GlobalData.curScore = 0; LocalStorageMgr.setItem(LocalStorageMgr.curScore_key, GlobalData.curScore); this.updateScores(GlobalData.curScore) GridBlockMgr.ins.generateBoard_effect(GridBoardData.customizeBoardData5); this.scheduleOnce(() => { GridBlockMgr.ins.generateSpecificSelectionBlock(false) }, 2) } // 生成一个分数特效 async createEleAddScoreEff(effPos: Vec3, scoreNum: number) { let addsecore = await PoolManager.getObject('labelTip'); addsecore.setParent(this.effectsContainer); addsecore.setPosition(effPos); addsecore.angle = 0; addsecore.getComponent(Label).string = '+' + scoreNum.toString(); // addsecore.qtJumpDistance(new Vec3(this.randInt(-400, 400), -this.randInt(1000, 1500), 0), this.randInt(1000, 1300), 1, 1) // .call(() => { // PoolManager.putObject('labelTip', addsecore) // }) // .start(); tween(addsecore) .to(0.3, { scale: v3(6, 6, 1) }) .delay(0.5) .to(0.5, { scale: v3(0, 0, 1) }, { easing: 'backIn' }) .call(() => { this.updateScores(scoreNum); PoolManager.putObject('labelTip', addsecore) }) .start(); } // 生成连续消除特效 async createConsecutiveEffect(effPos: Vec3, totalClearedLines: number) { if (!effPos) { return } let consecutiveEff; let name; if (totalClearedLines < 2) { return; } if (totalClearedLines == 2) { //good consecutiveEff = await PoolManager.getObject('good'); AudioManager.ins.playOneShot(Url.AUDIO.SFX17, 1); name = 'good' } else if (totalClearedLines == 3) { //great consecutiveEff = await PoolManager.getObject('great'); AudioManager.ins.playOneShot(Url.AUDIO.SFX18, 1); name = 'great' } else if (totalClearedLines == 4) { //excellent consecutiveEff = await PoolManager.getObject('excellent'); AudioManager.ins.playOneShot(Url.AUDIO.SFX19, 1); name = 'excellent' } else if (totalClearedLines == 5) { //amazing consecutiveEff = await PoolManager.getObject('amazing'); AudioManager.ins.playOneShot(Url.AUDIO.SFX20, 1); name = 'amazing' } else if (totalClearedLines >= 6) { //unbelievable consecutiveEff = await PoolManager.getObject('unbelievable'); AudioManager.ins.playOneShot(Url.AUDIO.SFX21, 1); name = 'unbelievable' } consecutiveEff.setParent(this.effectsContainer); consecutiveEff.setPosition(effPos); consecutiveEff.angle = 0; consecutiveEff.setScale(v3(0, 0, 1)) // consecutiveEff.qtJumpDistance(new Vec3(this.randInt(-400, 400), -this.randInt(1000, 1500), 0), this.randInt(1000, 1200), 1, 1) // .call(() => { // PoolManager.putObject(name, consecutiveEff) // }) // .start(); tween(consecutiveEff) .to(0.3, { scale: v3(1, 1, 1) }) .delay(0.5) .to(0.5, { scale: v3(0, 0, 1) }, { easing: 'backIn' }) .call(() => { PoolManager.putObject(name, consecutiveEff) }) .start(); } // 生成一个tip吐司、 async createOneTipTpast(str: string, insert: string = null) { let tip: Node = await PoolManager.getObject('tip'); tip.setParent(this.effectsContainer); tip.setPosition(v3(0, 0, 0)); tip.getComponent(UIOpacity).opacity = 255; let tiplabel = tip.children[0].getComponent(Label) let localizedLabel = tiplabel.node.getComponent(LocalizedLabel); localizedLabel.setTextKeyAndOption(str, insert); tween(tip) .delay(0.5) .to(0.5, { position: v3(0, 50, 0) }) .call(() => { PoolManager.putObject('tip', tip) }) .start() tween(tip.getComponent(UIOpacity)) .delay(0.5) .to(0.5, { opacity: 0 }) .start() } colorMap = { BLUE: '#00B8FF', // 蓝色 DEEPBLUE: '#00008B', // 深蓝色 GREEN: '#008000', // 绿色 ORANGE: '#FFA500', // 橘色 PURPLE: '#800080', // 紫色 RED: '#FF0000', // 红色 YELLOW: '#FFFF00' // 黄色 }; /// 根据 Url.BLOCK 对象的值获取对应的颜色值 getColorHexFromUrl(blockUrl) { // 遍历 Url.BLOCK 对象,找到匹配的键名 for (let key in Url.BLOCK) { if (Url.BLOCK[key] === blockUrl) { return this.colorMap[key]; // 返回对应的颜色值 } } return 'Invalid block URL'; // 如果未找到匹配项,返回错误信息 } async createOneBlockEfEffect(blocknode: Node, block_color: string) { let colorHEX = this.getColorHexFromUrl(block_color); for (let i = 0; i < 2; i++) { let tarEfPos = TouchMgr.ins.getNodeAToNodeBPoint(blocknode, this.effectsContainer); let blockef = await PoolManager.getObject('ef'); blockef.setParent(this.effectsContainer); blockef.setPosition(tarEfPos.add(v3(this.randInt(-20, 20), this.randInt(-20, 20), 0))); blockef.active = true; blockef.getComponent(UIOpacity).opacity = 255; // blockef.getComponent(Sprite).color = new Color().fromHEX(colorHEX); blockef.setScale(v3(0, 0, 0)); let s = this.randFloat(0.5, 1.2); tween(blockef) .parallel( tween().to(0.3, { scale: v3(s, s, 0) }), tween().to(0.3, { angle: this.randInt(0, 360) }) ) .start() tween(blockef.getComponent(UIOpacity)) .delay(0.3) .to(0.3, { opacity: 0 }) .call(() => { PoolManager.putObject('ef', blockef); // 回收到对象池 }) .start() } } // 随机生成一个力的值 getRandomForce(min1, max1, min2, max2) { // 50% 的概率选择第一个区间 [-5000, -2000],或第二个区间 [2000, 5000] if (Math.random() < 0.5) { return Math.random() * (max1 - min1) + min1; // [-5000, -2000] } else { return Math.random() * (max2 - min2) + min2; // [2000, 5000] } } randInt(min: number, max: number = undefined): number { if (max === undefined) { max = min; min = 0; } min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min)) + min; } randFloat(min: number, max: number = undefined): number { if (max === undefined) { max = min; min = 0; } return Math.random() * (max - min) + min; } /** * 使用锤子道具特效 * @param targetPos 飞向目标位置 */ // async usePropHummerEffect(targetPos: Vec3, call) { // let hummer = await PoolManager.getObject('hummer'); // hummer.setParent(this.effectsContainer); // hummer.setPosition(v3(0, 0, 0)); // hummer.setScale(2, 2, 1); // hummer.angle = 0; // tween(hummer) // .delay(0.2) // .parallel( // tween().to(0.3, { position: targetPos }), // tween().to(0.3, { angle: -30 }) // ) // .call(() => { // AudioManager.ins.playOneShot(Url.AUDIO.SFX8, 1); // }) // .to(0.2, { angle: 70 }) // .call(() => { // call(); // PoolManager.putObject('hummer', hummer); // }) // .start() // } // updatePropNum() { // this.refrashPropLabel.string = 'x' + GlobalData.refrashPropNum.toString(); // this.hummerPropLabel.string = 'x' + GlobalData.hummerPropNum.toString(); // let refrashadicon = this.refrashPropLabel.node.parent.getChildByName('adicon'); // let hummeradicon = this.hummerPropLabel.node.parent.getChildByName('adicon'); // if (GlobalData.refrashPropNum == 0) { // this.refrashPropLabel.node.active = false; // refrashadicon.active = true; // } else { // this.refrashPropLabel.node.active = true; // refrashadicon.active = false; // } // if (GlobalData.hummerPropNum == 0) { // this.hummerPropLabel.node.active = false; // hummeradicon.active = true; // } else { // this.hummerPropLabel.node.active = true; // hummeradicon.active = false; // } // } // async useRefrashProp(event, _gameOverUse = false) { // if (_gameOverUse) { // AudioManager.ins.playOneShot(Url.AUDIO.SFX7, 1); // GridBlockMgr.ins.generateSpecificSelectionBlock(true); // return // } // if (this.propInUse) { // return // } // if (GlobalData.refrashPropNum > 0) { // this.propInUse = true; // AudioManager.ins.playOneShot(Url.AUDIO.SFX7, 1); // GridBlockMgr.ins.generateSpecificSelectionBlock(true); // GlobalData.refrashPropNum--; // this.updatePropNum(); // } else { // AudioManager.ins.pauseBgm(); // // 触发广告 // let isCom = await true; // if (isCom) { // GlobalData.refrashPropNum++; // this.updatePropNum(); // AudioManager.ins.resumeBgm(); // } // } // LocalStorageMgr.setItem(LocalStorageMgr.refrashPropNum_key, GlobalData.refrashPropNum) // } // async useHummerProp(event, _gameOverUse = false) { // // console.log(_gameOverUse); // if (_gameOverUse) { // GridBlockMgr.ins.chechAndEliminateRandomArea(); // return // } // if (this.propInUse) { // return // } // if (GlobalData.hummerPropNum > 0) { // this.propInUse = true; // let isUse = GridBlockMgr.ins.chechAndEliminateRandomArea(); // // console.log(isUse); // if (isUse) { // GlobalData.hummerPropNum--; // this.updatePropNum(); // } // } else { // AudioManager.ins.pauseBgm(); // // 触发广告 // let isCom = await true; // if (isCom) { // GlobalData.hummerPropNum++; // this.updatePropNum(); // AudioManager.ins.resumeBgm(); // } // } // LocalStorageMgr.setItem(LocalStorageMgr.hummerPropNum_key, GlobalData.hummerPropNum) // } /** 检测引导和合成次数 */ public async detectGuideAndElimiTimes(add_tempel_lotNum: number) { GlobalData.elimiTimes++; LocalStorageMgr.setItem(LocalStorageMgr.elimiTimes_key, GlobalData.elimiTimes); if (GlobalData.isCommer) { Guide.ins.completeCurGuide(GlobalData.elimiTimes + 1); } } /** 检查是否是新的一天并更新今日最高分 */ // public checkAndUpdateDailyHighScore(lastLoginDate: string): void { // // 更新当前得分 // this.curScore = GlobalData.curScore; // // 获取当前日期 // const currentDate = new Date().toDateString(); // // 检查是否是同一天 // console.log('是否是同一天:', lastLoginDate == currentDate); // if (lastLoginDate !== currentDate) {//不是同一天 // GlobalData.todayHighScore = 0; // LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore); // } else { // if (GlobalData.curScore >= GlobalData.todayHighScore) { // GlobalData.todayHighScore = GlobalData.curScore; // LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore); // } // } // // 更新最后登录日期 // LocalStorageMgr.setItem(LocalStorageMgr.lastLoginDate_key, currentDate); // this.updateScoreLabel(this.historyScoreLabel, GlobalData.historyHighScore); // this.updateScoreLabel(this.todayScoreLabel, GlobalData.todayHighScore); // this.updateScoreLabel(this.curScoreLabel, GlobalData.curScore); // } /** 更新分数 */ public updateScores(addScore: number): void { // 更新当前得分 this.curScore += addScore; GlobalData.curScore = this.curScore; // 更新今日最高分 if (this.curScore > GlobalData.todayHighScore) { GlobalData.todayHighScore = this.curScore; this.updateScoreLabel(this.todayScoreLabel, this.curScore) } // 更新历史最高分 if (this.curScore > GlobalData.historyHighScore) { GlobalData.historyHighScore = this.curScore; this.updateScoreLabel(this.historyScoreLabel, this.curScore) } this.updateScoreLabel(this.curScoreLabel, this.curScore); // 保存分数的方法 LocalStorageMgr.setItem(LocalStorageMgr.historyHighScore_key, GlobalData.historyHighScore); LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore); LocalStorageMgr.setItem(LocalStorageMgr.curScore_key, GlobalData.curScore); } /** * 更新分数标签,使其逐渐增长到新分数 * @param tarLabel 目标标签 * @param newScore 新分数 * @param duration 动画持续时间 */ updateScoreLabel(tarLabel: Label, newScore: number, duration: number = 1): void { const currentScore = parseInt(tarLabel.string) || 0; const delta = newScore - currentScore; if (delta === 0) { return; } tween({ value: currentScore }) .to(duration, { value: newScore }, { onUpdate: (target: { value: number }) => { tarLabel.string = Math.floor(target.value).toString(); } }) .start(); //当前分数超过关分数就通关 if ((newScore >= 100)) { console.log("通关了"); } } }