12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571 |
- /**
- * 代码描述
- */
- import { Audio } from "../../common/src/Audio";
- import { GameDataCenter } from "../../common/src/GameDataCenter";
- import { LevelConfig } from "../../common/src/LevelConfig";
- import { UIManager } from "../../common/src/UIManager";
- import { Utils } from "../../common/src/Utils";
- const { ccclass, property } = cc._decorator;
- @ccclass
- export class BobbleGamePanel extends cc.Component {
- @property({ type: cc.Node, tooltip: '反弹界面节点' })
- walls: cc.Node = null;
- @property({ type: cc.Graphics, tooltip: '射线节点' })
- ray: cc.Graphics = null;
- @property({ type: cc.Node, tooltip: '地图节点' })
- map: cc.Node = null;
- @property({ type: cc.Node, tooltip: '角色节点' })
- player: cc.Node = null;
- @property({ type: cc.Node, tooltip: 'ui节点' })
- ui: cc.Node = null;
- @property({ type: cc.Prefab, tooltip: '泡泡预制体' })
- bubble: cc.Prefab = null;
- @property({ type: cc.Prefab, tooltip: '射线预制体' })
- rayPrefab: cc.Prefab = null;
- @property({ type: cc.Prefab, tooltip: '激励预制体' })
- appraisePrefab: cc.Prefab = null;
- @property({ type: cc.Prefab, tooltip: '发射小球预制体' })
- shootBubblePre: cc.Prefab = null;
- @property({ type: cc.Prefab, tooltip: '激光预制体' })
- laser_gj: cc.Prefab = null;
- @property({ type: cc.Prefab, tooltip: '闪电预制体' })
- thunder_gj: cc.Prefab = null;
- @property({ type: cc.Prefab, tooltip: '总分预制体' })
- scorePrefab: cc.Prefab = null;
- @property({ type: cc.Prefab, tooltip: '箭头预制体' })
- arrows: cc.Prefab = null;
- @property({ type: [cc.SpriteFrame], tooltip: '普通泡泡纹理集合\n0.紫色\n1.绿色\n2.蓝色\n3.黄色\n4.红色' })
- bubbleSpriteFrame: cc.SpriteFrame[] = [];
- @property({ type: [cc.SpriteFrame], tooltip: '特殊泡泡纹理集合\n0.炸弹\n1.激光\n2.七色\n3.闪电' })
- specialBubbleSpriteFrame: cc.SpriteFrame[] = [];
- @property({ type: [cc.SpriteFrame], tooltip: '图标集合\n0.广告\n1.无限\n2.金币\n3.暗星\n4.亮星' })
- iconSpriteFrame: cc.SpriteFrame[] = [];
- @property({ type: [cc.Prefab], tooltip: '特殊球待机动画预制体\n0.炸弹\n1.激光\n2.七色\n3.闪电' })
- specialBubbleEffect: cc.Prefab[] = [];
- //线段颜色
- private rayColor: cc.Color[] = [cc.color('#a600e6' as any), cc.color('#0ca600' as any), cc.color('#10c8e3' as any), cc.color('#f77916' as any), cc.color('#cd1904' as any)];
- /**特殊球颜色 */
- private specialColor: cc.Color[][] = [[cc.color('#fdce25' as any), cc.color('#f48118' as any), cc.color('#f48118' as any), cc.color('#fdce25' as any)], [cc.color('#f0e288' as any), cc.color('#d999d1' as any), cc.color('#92e7fc' as any)], [cc.color('#48adf7' as any), cc.color('#fdde52' as any), cc.color('#f77923' as any), cc.color('#d7008e' as any)], [cc.color('#073dd3' as any), cc.color('#ffffff' as any), cc.color('#073dd3' as any)]];
- /**总分评价 */
- private appraise: string[] = ['bksy', 'tbl', 'bc'];
- //发射坐标
- private startPos: cc.Vec2 = cc.v2();
- //射线节点坐标
- private rayPos: cc.Vec2[] = [];
- private pathPos: cc.Vec2[] = [];
- //射线节点半径
- private r: number = 0;
- //放大缩小方向
- private op: number = 1;
- //是否隐藏
- private isHide: boolean = true;
- //泡泡半径
- private bubbleR: number = 30;
- //地图高度
- private screenH: number = 0;
- //地图宽度
- private screenW: number = 0;
- /** 当前发射小球 */
- public shootBubble: cc.Node;
- /** 预发射小球 */
- public preBubble: cc.Node;
- /** 特殊小球 */
- public specialBubble: cc.Node;
- /**校正之后泡泡的位置 */
- private bubbleIndex: cc.Vec2 = null;
- /**小球数量 */
- private bubbleCount: number = 0;
- /**连击数 */
- private combo: number = 0;
- /**是否在准备泡泡 */
- private isReady: boolean = false;
- /**场上小球的颜色数量 */
- private colorCount: number[] = [0, 0, 0, 0, 0, 0];
- /**特殊球类型 */
- private specialBubbleType: number = 0;
- /**特殊球消除位置 */
- private specialBubbleIndex: cc.Vec2[] = [];
- /**激光终点向量 */
- private laserVec: cc.Vec2 = null;
- /**闪电爆炸位置 */
- private thunderIndex: cc.Vec2 = null;
- /**游戏是否结束 */
- private isWin: boolean = false;
- /**得分 */
- private score: number = 0;
- /**三星分数 */
- private perfectScore: number = 0;
- /**星星数 */
- private star: number = 0;
- /**首次出现冰球的关卡 */
- private iceTips: number = 31;
- /**在线时间 */
- private onlineTime: number = 0;
- /*要显示的排数*/
- private showCount: number = 10;
- private callBack: Function = null;
- private isPress: boolean = false;
- onLoad() {
- Audio.playMusicByPath('game:res/snd/bgm');
- cc.director.getPhysicsManager().enabled = true;
- }
- onEnable() {
- this.scheduleOnce(() => {
- this.init();
- }, 0.5);
- let specialBubble = this.ui.getChildByName('specialBubble');
- for (let i = 0; i < specialBubble.childrenCount; i++) {
- specialBubble.children[i].on('click', this.onSpecialBubble, this);
- }
- this.player.getChildByName('icon').on('click', this.onSwitchBubble, this)
- this.ui.getChildByName('cancel').on('click', this.onCancel, this);
- this.ui.getChildByName('topPanel').getChildByName('pauseButton').on('click', this.onPause, this);
- this.ui.getChildByName('topPanel').getChildByName('coin').getChildByName('addButton').on('click', this.onCoinStore, this);
- this.ui.getChildByName('online').on('click', this.onOnline, this);
- this.ui.getChildByName('ten').on('click', () => {
- cc.systemEvent.emit('updateBubble', 10);
- }, this);
- cc.systemEvent.on('restart', this.onRestart, this);
- cc.systemEvent.on('updateBubble', this.onUpdateBubble, this);
- cc.systemEvent.on('updateUI', this.onUpdateUI, this);
- cc.systemEvent.on('startTimer', this.onStartTimer, this);
- cc.systemEvent.on('showTenButton', (isShow: boolean) => { this.ui.getChildByName('ten').active = isShow }, this);
- this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
- this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMoved, this);
- this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnded, this);
- this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancelled, this);
- }
- onDisable() {
- this.node.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
- this.node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMoved, this);
- this.node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnded, this);
- this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancelled, this);
- }
- /**点击特殊球 */
- private onSpecialBubble(button): void {
- if (GameDataCenter.gameLevel == 12) {
- this.ui.getChildByName('colorTip').active = false;
- GameDataCenter.tipType = 2;
- UIManager.open('tip:TipPanel');
- }
- if (!this.isReady || this.isWin) return;
- this.isPress = true;
- Audio.playSoundByPath('game:res/snd/click');
- if (button.node.getChildByName('null').active == true && GameDataCenter.coin < 100) {
- switch (button.node.name) {
- case 'bombBubble': this.specialBubbleCallback(1); break;
- case 'laserBubble': this.specialBubbleCallback(2); break;
- case 'omnipotentBubble': this.specialBubbleCallback(3); break;
- case 'lightningBubble': this.specialBubbleCallback(4); break;
- }
- return;
- }
- switch (button.node.name) {
- case 'bombBubble': this.specialBubbleType = 1; break;
- case 'laserBubble': this.specialBubbleType = 2; break;
- case 'omnipotentBubble': this.specialBubbleType = 3; break;
- case 'lightningBubble': this.specialBubbleType = 4; break;
- }
- this.player.getChildByName('icon').active = false;
- let specialBubble = this.ui.getChildByName('specialBubble');
- for (let i = 0; i < specialBubble.childrenCount; i++) {
- specialBubble.children[i].getComponent(cc.Button).interactable = false;
- }
- this.switchSpecialBubble(1);
- }
- /**点击取消 */
- private onCancel(): void {
- Audio.playSoundByPath('game:res/snd/click');
- this.specialBubbleType = 0;
- this.switchSpecialBubble(-1);
- this.isPress = false;
- }
- /**暂停界面 */
- private onPause(): void {
- Audio.playSoundByPath('game:res/snd/click');
- UIManager.open('pause:PausePanel');
- }
- /**金币商店 */
- private onCoinStore(): void {
- Audio.playSoundByPath('game:res/snd/click');
- UIManager.open('coinStore:CoinStorePanel');
- }
- /**点击切换小球 */
- private onSwitchBubble(button): void {
- if (!this.isReady || this.isWin) return;
- Audio.playSoundByPath('game:res/snd/click');
- this.isReady = false;
- button.node.getComponent(cc.Button).interactable = false;
- if (button.node.children[0].name == '0') {
- this.callBack = () => {
- button.node.children[0].getComponent(cc.Sprite).spriteFrame = this.iconSpriteFrame[1];
- button.node.children[0].name = '1';
- let pos = this.player.convertToNodeSpaceAR(this.startPos);
- cc.tween(this.shootBubble).to(0.2, { position: cc.v3(pos.x + 60, pos.y - 60), scale: 0.75 }).start();
- cc.tween(this.preBubble).to(0.2, { position: cc.v3(pos.x, pos.y), scale: 1 }).call(() => {
- let node: cc.Node = null;
- node = this.shootBubble;
- this.shootBubble = this.preBubble;
- this.preBubble = node;
- this.scheduleOnce(() => {
- this.isReady = true;
- }, 0);
- this.ray.fillColor = this.rayColor[this.shootBubble.getComponent('Bubble').color - 1];
- button.node.getComponent(cc.Button).interactable = true;
- }).start();
- }
- this.scheduleOnce(() => {
- button.node.getComponent(cc.Button).interactable = true;
- this.isReady = true;
- this.callBack();
- }, 1);
- return;
- }
- let pos = this.player.convertToNodeSpaceAR(this.startPos);
- cc.tween(this.shootBubble).to(0.2, { position: cc.v3(pos.x + 60, pos.y - 60), scale: 0.75 }).start();
- cc.tween(this.preBubble).to(0.2, { position: cc.v3(pos.x, pos.y), scale: 1 }).call(() => {
- let node: cc.Node = null;
- node = this.shootBubble;
- this.shootBubble = this.preBubble;
- this.preBubble = node;
- this.scheduleOnce(() => {
- this.isReady = true;
- }, 0);
- this.ray.fillColor = this.rayColor[this.shootBubble.getComponent('Bubble').color - 1];
- button.node.getComponent(cc.Button).interactable = true;
- }).start();
- }
- /**在线奖励面板 */
- private onOnline(): void {
- Audio.playSoundByPath('game:res/snd/click');
- if (this.onlineTime > 0) {
- this.creatLabel(`再多玩一会吧,在线时间还不够哦~`);
- return;
- }
- else {
- GameDataCenter.rewarded = [`${Math.floor(Math.random() * 4)}:1`, '4:80'];
- UIManager.open('rewarded:RewardedPanel');
- cc.systemEvent.emit('startTimer');
- }
- }
- /**再来一次 */
- private onRestart(): void {
- this.isReady = false;
- this.initMap(true);
- }
- /**更新泡泡数量 */
- private onUpdateBubble(num: number): void {
- this.isReady = false;
- let count: number = this.bubbleCount;
- this.bubbleCount += num;
- for (let i = 0; i < num; i++) {
- this.scheduleOnce(() => {
- count++;
- this.player.getChildByName('bubbleCount').getComponent(cc.Label).string = `${count}`
- }, i * 0.1);
- }
- this.scheduleOnce(() => {
- this.isReady = true;
- }, 0.5);
- }
- /**更新UI数量 */
- private onUpdateUI(type: string, num: number) {
- this.changeUi(type, num);
- }
- /**开始在线奖励倒计时 */
- private onStartTimer(): void {
- let node = this.ui.getChildByName('online').getChildByName('gift');
- cc.Tween.stopAllByTarget(node);
- node.scale = 1;
- node.angle = 0;
- this.onlineTime = 120;
- this.ui.getChildByName('online').getChildByName('time').getComponent(cc.Label).string = '02;00';
- this.ui.getChildByName('online').getChildByName('time').active = true;
- this.ui.getChildByName('online').getChildByName('name').getChildByName('label').getComponent(cc.Label).string = `在线奖励`;
- this.ui.getChildByName('online').getChildByName('name').getChildByName('label').x -= 14;
- this.ui.getChildByName('online').getChildByName('name').getChildByName('videoIcon').active = false;
- // this.ui.getChildByName('online').getComponent(cc.Button).interactable = false;
- this.schedule(this.online, 1);
- }
- private specialBubbleCallback(type) {
- this.specialBubbleType = type;
- this.player.getChildByName('icon').active = false;
- let specialBubble = this.ui.getChildByName('specialBubble');
- for (let i = 0; i < specialBubble.childrenCount; i++) {
- specialBubble.children[i].getComponent(cc.Button).interactable = false;
- }
- this.switchSpecialBubble(1);
- this.changeUi(`special${this.specialBubbleType}`, 1);
- }
- /**
- * 场景动画更新前回调
- * @param dt 游戏帧时长
- */
- update(dt: number) {
- if (!this.isHide) {
- this.updateRay(dt);
- }
- }
- /** touch事件回调 */
- onTouchStart(event: cc.Event.EventTouch) {
- this.isPress = true;
- if (GameDataCenter.gameLevel == 1) {
- if (this.ui.getChildByName('tip').getChildByName('tip1').activeInHierarchy == true) {
- cc.Tween.stopAllByTarget(this.ui.getChildByName('tip').getChildByName('tip1').getChildByName('finger'));
- this.ui.getChildByName('tip').getChildByName('tip1').active = false;
- }
- }
- if (GameDataCenter.gameLevel == 2) {
- if (this.ui.getChildByName('tip').getChildByName('tip3').activeInHierarchy == true) {
- this.ui.getChildByName('tip').getChildByName('tip3').active = false;
- this.node.getChildByName('effect').removeAllChildren();
- }
- }
- // if (GameDataCenter.gameLevel == 11) {
- // if (this.ui.getChildByName('tip').getChildByName('tip4').activeInHierarchy == true) {
- // this.ui.getChildByName('tip').getChildByName('tip4').active = false;
- // }
- // }
- if (!this.isReadyRay(event)) { return; }
- this.topTween(0);
- this.rayPos = [];
- this.pathPos = [this.ray.node.convertToNodeSpaceAR(this.startPos)];
- const pos = event.getLocation();
- this.drawRayCast(this.startPos, pos.subSelf(this.startPos).normalizeSelf(), this.ray);
- }
- onTouchMoved(event: cc.Event.EventTouch) {
- if (!this.isReadyRay(event)) { return; }
- this.topTween(0);
- this.rayPos = [];
- this.pathPos = [this.ray.node.convertToNodeSpaceAR(this.startPos)];
- const pos = event.getLocation();
- this.drawRayCast(this.startPos, pos.subSelf(this.startPos).normalizeSelf(), this.ray);
- }
- onTouchEnded(event: cc.Event.EventTouch) {
- this.isPress = false;
- if (this.isHide) { return; }
- this.topTween(1);
- this.ray.clear();
- for (let i = 0; i < this.ray.node.childrenCount; i++) {
- this.ray.node.children[i].getComponent(cc.Graphics).clear();
- }
- this.isReady = false;
- this.laserVec = event.getLocation();
- this.shootBubble.getChildByName('trailing_normal').active = true;
- switch (this.specialBubbleType) {
- case 0:
- Audio.playSoundByPath('game:res/snd/shoot');
- break;
- case 1:
- Audio.playSoundByPath('game:res/snd/bomb');
- break;
- case 2:
- Audio.playSoundByPath('game:res/snd/laser');
- break;
- case 3:
- Audio.playSoundByPath('game:res/snd/omnipotent');
- break;
- case 4:
- Audio.playSoundByPath('game:res/snd/lightning');
- break;
- }
- this.ui.getChildByName('cancel').active = false;
- this.bubbleMove(1);
- this.isHide = true;
- }
- onTouchCancelled(event: cc.Event.EventTouch) {
- this.isPress = false;
- this.ray.clear();
- for (let i = 0; i < this.ray.node.childrenCount; i++) {
- this.ray.node.children[i].getComponent(cc.Graphics).clear();
- }
- this.isHide = true;
- }
- /**初始化 */
- private init(): void {
- if (!GameDataCenter.isInitSpecial) {
- GameDataCenter.isInitSpecial = true;
- cc.systemEvent.emit('updateUI', 'special1', 1);
- cc.systemEvent.emit('updateUI', 'special2', 1);
- cc.systemEvent.emit('updateUI', 'special3', 1);
- cc.systemEvent.emit('updateUI', 'special4', 1);
- }
- if (GameDataCenter.gameLevel >= 8) {
- //签到
- if (!GameDataCenter.isSignIn) {
- this.scheduleOnce(() => {
- UIManager.open('attendance:AttendancePanel');
- }, 0.1)
- }
- }
- //初始化ui
- this.onStartTimer();
- this.changeUi('coin');
- this.changeUi('special0');
- this.changeUi('ingot');
- //初始化初始发射点
- this.startPos = this.node.convertToWorldSpaceAR(cc.v2(this.player.position.x, this.player.position.y));
- //初始化泡泡半径
- this.bubbleR = Math.floor(this.node.getContentSize().width / 11 / 2);
- //初始化地图宽度
- this.screenW = this.node.getContentSize().width;
- //设置地图大小
- // this.map.setContentSize(this.screenW, this.node.getContentSize().height * 3 / 7);
- //初始化地图高度
- this.screenH = this.map.getContentSize().height;
- //初始化地图
- this.scheduleOnce(() => {
- this.createShootBubble(true);
- this.createShootBubble();
- this.initMap(true);
- }, 0.5);
- }
- /**初始化地图 */
- private initMap(isInit: boolean = false): void {
- this.ui.getChildByName('ten').active = false;
- GameDataCenter.bubbles = [];
- this.map.removeAllChildren();
- //初始化广告图片
- let icon = this.player.getChildByName('icon');
- icon.zIndex = 100;
- icon.children[0].getComponent(cc.Sprite).spriteFrame = this.iconSpriteFrame[0];
- icon.children[0].name = '0';
- this.colorCount = [0, 0, 0, 0, 0, 0];
- this.specialBubbleType = 0;
- this.combo = 0;
- this.star = 0;
- this.isWin = false;
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('levelLabel').getComponent(cc.Label).string = `第${GameDataCenter.gameLevel}关`
- this.map.position = cc.v3(0, -this.node.getContentSize().height);
- this.walls.getChildByName('top').position = this.walls.convertToNodeSpaceAR(this.map.convertToWorldSpaceAR(cc.v3(this.map.position.x, this.map.getContentSize().height + this.walls.getChildByName('top').getContentSize().height / 2)));
- let length = Object.keys(LevelConfig.level).length;
- let gameLevel = LevelConfig.level[GameDataCenter.gameLevel > length ? Math.floor(Math.random() * length) + 1 : GameDataCenter.gameLevel]
- let bubbleCount = this.bubbleCount;
- let count = 0;
- this.bubbleCount = isInit ? gameLevel.bubbleCount : gameLevel.bubbleCount + 1;
- for (let i = 0; i < Math.max(gameLevel.bubbleCount - bubbleCount, 0); i++) {
- this.scheduleOnce(() => {
- bubbleCount++;
- this.player.getChildByName('bubbleCount').getComponent(cc.Label).string = `${bubbleCount}`
- }, i * 0.05);
- }
- let data = gameLevel.map;
- let time: number = 0;
- for (let i = 0; i < data.length; i++) {
- GameDataCenter.bubbles[i] = [];
- for (let j = 0; j < data[i].length; j++) {
- let type = data[i][j];
- if (type == 0) continue;
- this.scheduleOnce(() => {
- this.creatBubble(i, j, type);
- count++;
- }, time * 0.01);
- time = (time++) / 5;
- }
- }
- this.scheduleOnce(() => {
- this.changeUi('score', 0);
- this.perfectScore = count * 40;
- GameDataCenter.bubbles[data.length] = [];
- let t = ((1.5 * this.node.getContentSize().height - 210) / (this.bubbleR * Math.sqrt(3))) + Math.max(GameDataCenter.bubbles.length - 10, 0)
- this.setMapPosition(t);
- this.scheduleOnce(() => {
- if (GameDataCenter.gameLevel == 2) {
- this.ui.getChildByName('tip').getChildByName('tip3').active = true;
- Utils.openPanel(this.ui.getChildByName('tip').getChildByName('tip3'));
- this.rayPos = [];
- this.drawRayCast(this.startPos, cc.v2(this.startPos.x - 100, this.startPos.y + 140).subSelf(this.startPos).normalizeSelf(), this.ray);
- let rayPos = this.rayPos;
- for (let i = 0; i < rayPos.length - 2; i++) {
- let node = cc.instantiate(this.arrows);
- let angle = this.vectorsToDegree(rayPos[i], rayPos[i + 1]);
- if (angle != this.vectorsToDegree(rayPos[i + 1], rayPos[i + 2])) {
- cc.tween(node)
- .to(0.5, { opacity: 0 })
- .call(() => {
- node.opacity = 255;
- })
- .union()
- .repeatForever()
- .start();
- }
- if (i == rayPos.length - 3) {
- cc.tween(node)
- .to(0.5, { opacity: 0 })
- .call(() => {
- node.opacity = 255;
- })
- .union()
- .repeatForever()
- .start();
- }
- node.parent = this.node.getChildByName('effect');
- node.position = cc.v3(rayPos[i].x, rayPos[i].y);
- node.angle += angle;
- cc.tween(node)
- .to(0.5, { position: cc.v3(rayPos[i + 1].x, rayPos[i + 1].y) })
- .call(() => {
- node.position = cc.v3(rayPos[i].x, rayPos[i].y);
- })
- .union()
- .repeatForever()
- .start();
- }
- }
- this.switchShootBubble();
- }, 0.03 * t + 0.1);
- if (GameDataCenter.gameLevel == 1) {
- this.ui.getChildByName('tip').getChildByName('tip1').active = true;
- cc.tween(this.ui.getChildByName('tip').getChildByName('tip1').getChildByName('finger'))
- .by(0.3, { x: -100 })
- .by(0.6, { x: 200 })
- .by(0.3, { x: -100 })
- .union()
- .repeatForever()
- .start();
- }
- if (GameDataCenter.gameLevel >= 3) {
- this.ui.getChildByName('specialBubble').active = true;
- }
- if (GameDataCenter.gameLevel >= 8) {
- //签到
- if (!GameDataCenter.isSignIn && GameDataCenter.gameLevel < 16) {
- this.scheduleOnce(() => {
- UIManager.open('attendance:AttendancePanel');
- }, 0.1);
- }
- }
- // if (GameDataCenter.gameLevel == 11) {
- // this.ui.getChildByName('tip').getChildByName('tip4').active = true;
- // }
- if (GameDataCenter.gameLevel == 12) {
- this.ui.getChildByName('colorTip').active = true;
- cc.systemEvent.emit('updateUI', `special3`, 1);
- }
- if (GameDataCenter.gameLevel == 13) {
- if (this.onlineTime == 0) {
- this.onOnline();
- }
- }
- if (GameDataCenter.gameLevel == this.iceTips || GameDataCenter.gameLevel == 11) {
- GameDataCenter.tipType = 2;
- UIManager.open('tip:TipPanel');
- }
- }, time * 0.01 + 1);
- }
- /**判断射线出现 */
- private isReadyRay(event): boolean {
- let pos = this.player.parent.convertToNodeSpaceAR(event.getLocation());
- if (pos.y < Math.tan(cc.misc.degreesToRadians(20)) * (Math.abs(pos.x)) + this.player.position.y || !this.isReady) {
- this.ray.clear();
- this.topTween(1);
- for (let i = 0; i < this.ray.node.childrenCount; i++) {
- this.ray.node.children[i].getComponent(cc.Graphics).clear();
- }
- this.node.getChildByName('tipRay').getComponent(cc.Graphics).clear();
- this.isHide = true;
- return false;
- }
- this.isHide = false;
- return true;
- }
- /**
- * @description 计算射线
- * @param startLocation 起始位置 世界坐标系
- * @param vector_dir 单位方向向量
- */
- private drawRayCast(startLocation: cc.Vec2, vector_dir: cc.Vec2, graphic: cc.Graphics): void {
- if (this.specialBubbleType == 2) {
- this.specialBubbleIndex = [];
- const endLocation = startLocation.add(vector_dir.mul(1500));
- const results = cc.director.getPhysicsManager().rayCast(startLocation, endLocation, cc.RayCastType.AllClosest);
- this.drawAimLine(startLocation, results[results.length - 1].point, graphic);
- //计算激光经过的泡泡
- let result1 = cc.director.getPhysicsManager().rayCast(startLocation.sub(cc.v2(this.bubbleR - 1)), endLocation.sub(cc.v2(this.bubbleR - 1)), cc.RayCastType.AllClosest);
- for (let i in result1) {
- if (result1[i].collider.node.name == 'bubble') {
- let hitBubble = result1[i].collider.node.parent.getComponent('Bubble');
- this.specialBubbleIndex.push(cc.v2(hitBubble.i, hitBubble.j));
- }
- }
- let result2 = cc.director.getPhysicsManager().rayCast(startLocation.sub(cc.v2(-this.bubbleR + 1)), endLocation.sub(cc.v2(-this.bubbleR + 1)), cc.RayCastType.AllClosest);
- for (let i in result2) {
- if (result2[i].collider.node.name == 'bubble') {
- let hitBubble = result2[i].collider.node.parent.getComponent('Bubble');
- this.specialBubbleIndex.push(cc.v2(hitBubble.i, hitBubble.j));
- }
- }
- if (result1[result1.length - 1].collider.node.name != 'bubble' && result2[result2.length - 1].collider.node.name != 'bubble') {
- this.node.getChildByName('tipRay').getComponent(cc.Graphics).clear();
- }
- //加入点位
- if (this.specialBubbleIndex.length > 0) {
- let tipRay = this.node.getChildByName('tipRay').getComponent(cc.Graphics);
- tipRay.clear();
- this.unique();
- for (let i = 0; i < this.specialBubbleIndex.length; i++) {
- let pos = this.convertRowColToPos(this.specialBubbleIndex[i].x, this.specialBubbleIndex[i].y);
- pos = this.node.convertToNodeSpaceAR(this.map.convertToWorldSpaceAR(pos))
- tipRay.circle(pos.x, pos.y, this.bubbleR);
- }
- tipRay.stroke();
- }
- }
- else {
- const endLocation = startLocation.add(vector_dir.mul(10000));
- const results = cc.director.getPhysicsManager().rayCast(startLocation, endLocation, cc.RayCastType.Closest);
- const result = results[0];
- // 指定射线与穿过的碰撞体在哪一点相交。
- const point = result.point;
- this.drawAimLine(startLocation, point, graphic);
- //碰撞体
- const collider = result.collider.node.name;
- // 画入射线段
- if (collider == 'left' || collider == 'right') {
- // 指定碰撞体在相交点的表面的法线单位向量。
- const vector_n = result.normal;
- const vector_r = vector_dir.sub(vector_n.mul(2 * vector_dir.dot(vector_n)));
- this.drawRayCast(point, vector_r, graphic);
- }
- else {
- let hitBubble = result.collider.node.parent;
- if (collider == 'bubble') {
- this.bubbleIndex = this.setBubble(hitBubble.getComponent('Bubble').i, hitBubble.getComponent('Bubble').j, this.map.convertToNodeSpaceAR(point));
- }
- if (collider == 'top') {
- this.bubbleIndex = this.setBubble(-1, -1, this.map.convertToNodeSpaceAR(point));
- }
- this.specialBubbleIndex = [];
- switch (this.specialBubbleType) {
- case 1:
- this.bombBubble();
- break;
- case 3:
- this.omnipotentBubble();
- break;
- case 4:
- this.lightningBubble(hitBubble, collider == 'top' ? true : false);
- break;
- }
- let tipRay = this.node.getChildByName('tipRay').getComponent(cc.Graphics);
- tipRay.clear();
- // this.specialBubbleIndex.push(cc.v2(this.bubbleIndex.x, this.bubbleIndex.y));
- this.unique();
- for (let i = 0; i < this.specialBubbleIndex.length; i++) {
- let pos = this.convertRowColToPos(this.specialBubbleIndex[i].x, this.specialBubbleIndex[i].y);
- pos = this.node.convertToNodeSpaceAR(this.map.convertToWorldSpaceAR(pos))
- tipRay.circle(pos.x, pos.y, this.bubbleR);
- }
- tipRay.stroke();
- }
- }
- }
- /**
- * @description 画瞄准线
- * @param startLocation 起始位置 世界坐标系
- * @param endLocation 结束位置 世界坐标系
- */
- private drawAimLine(startLocation: cc.Vec2, endLocation: cc.Vec2, graphic: cc.Graphics): void {
- const graphic_startLocation = graphic.node.convertToNodeSpaceAR(startLocation);
- const graphic_endLocation = graphic.node.convertToNodeSpaceAR(endLocation);
- graphic.moveTo(graphic_startLocation.x, graphic_startLocation.y);
- /*画间隔圆线*/
- //圆与圆之间的间隔
- let delta = 60;
- //直线方向
- const vector_dir = endLocation.sub(startLocation);
- //圆的数量
- const total_count = Math.floor(vector_dir.mag() / delta);
- //每次间隔向量
- vector_dir.normalizeSelf().mulSelf(delta);
- for (let index = 0; index < total_count; index++) {
- graphic_startLocation.addSelf(vector_dir);
- this.rayPos.push(cc.v2(graphic_startLocation.x, graphic_startLocation.y));
- }
- this.rayPos.push(cc.v2(graphic_endLocation.x, graphic_endLocation.y));
- this.pathPos.push(cc.v2(graphic_endLocation.x, graphic_endLocation.y));
- }
- /**更新射线 */
- private updateRay(dt): void {
- this.ray.clear();
- for (let i = 0; i < this.ray.node.childrenCount; i++) {
- this.ray.node.children[i].getComponent(cc.Graphics).clear();
- }
- // (0.4:min+5:max)/2
- let offset: number = 10;
- for (let i = 0; i < this.rayPos.length; i++) {
- if (i % 2 == 0) {
- this.ray.circle(this.rayPos[i].x, this.rayPos[i].y, offset + this.r);
- for (let j = 0; j < this.ray.node.childrenCount; j++) {
- this.ray.node.children[j].getComponent(cc.Graphics).circle(this.rayPos[i].x, this.rayPos[i].y, offset + this.r - (j + 1) * 3);
- }
- }
- else {
- this.ray.circle(this.rayPos[i].x, this.rayPos[i].y, offset - this.r);
- for (let j = 0; j < this.ray.node.childrenCount; j++) {
- this.ray.node.children[j].getComponent(cc.Graphics).circle(this.rayPos[i].x, this.rayPos[i].y, offset - this.r - (j + 1) * 3);
- }
- }
- }
- this.r += this.op * 10 * dt;
- if (Math.abs(this.r) > 3) {
- this.op = -this.op;
- }
- this.ray.fill();
- for (let i = 0; i < this.ray.node.childrenCount; i++) {
- this.ray.node.children[i].getComponent(cc.Graphics).fill();
- }
- }
- /**创建小球 */
- private creatBubble(i: number, j: number, color: number): void {
- let node = cc.instantiate(this.bubble);
- node.position = this.convertRowColToPos(i, j);
- if (this.specialBubbleType == 0) {
- node.getComponent(cc.Sprite).spriteFrame = this.bubbleSpriteFrame[color - 1];
- }
- else {
- node.getComponent(cc.Sprite).spriteFrame = this.specialBubbleSpriteFrame[color - 1];
- }
- node.parent = this.map;
- node.getComponent('Bubble').init(i, j, color);
- node.setContentSize(this.bubbleR * 2, this.bubbleR * 2);
- node.children[0].getComponent(cc.PhysicsCircleCollider).radius = this.bubbleR;
- node.children[0].getComponent(cc.PhysicsCircleCollider).apply();
- GameDataCenter.bubbles[i][j] = node;
- if (color >= 1 && color <= 6) { this.colorCount[color - 1]++; }
- }
- /**创建预发射小球 */
- private createShootBubble(isInit: boolean = false): void {
- if (!isInit) {
- this.shootBubble = this.preBubble;
- this.ray.fillColor = this.rayColor[this.shootBubble.getComponent('Bubble').color - 1];
- this.bubbleCount--;
- if (this.bubbleCount == 0) {
- GameDataCenter.tipType = 0;
- UIManager.open('tip:TipPanel');
- }
- if (this.bubbleCount == 3) {
- GameDataCenter.tipType = 3;
- UIManager.open('tip:TipPanel');
- }
- if (this.bubbleCount == 10) {
- GameDataCenter.tipType = 1;
- UIManager.open('tip:TipPanel');
- }
- }
- let node = cc.instantiate(this.shootBubblePre);
- let pos = this.player.convertToNodeSpaceAR(this.startPos);
- let color = this.randNum();
- node.position = cc.v3(pos.x + 60, pos.y - 60);
- node.parent = this.player;
- node.getChildByName('sprite').getComponent(cc.Sprite).spriteFrame = this.bubbleSpriteFrame[color - 1];
- node.setContentSize(this.bubbleR * 2, this.bubbleR * 2);
- node.getComponent('Bubble').color = color;
- node.scale = 0;
- this.preBubble = node;
- }
- /**发射小球切换动画 */
- private switchShootBubble(): void {
- this.scheduleOnce(() => {
- this.specialBubbleType = 0;
- let pos = this.player.convertToNodeSpaceAR(this.startPos);
- if (this.colorCount[this.shootBubble.getComponent('Bubble').color - 1] == 0) {
- let color = this.randNum();
- this.shootBubble.getComponent('Bubble').color = color;
- this.shootBubble.getChildByName('sprite').getComponent(cc.Sprite).spriteFrame = this.bubbleSpriteFrame[color - 1];
- }
- cc.tween(this.shootBubble).to(0.5, { position: cc.v3(pos.x, pos.y), scale: 1 }).start();
- cc.tween(this.preBubble).to(0.5, { scale: 0.75 }).start();
- this.ray.fillColor = this.rayColor[this.shootBubble.getComponent('Bubble').color - 1];
- this.player.getChildByName('bubbleCount').getComponent(cc.Label).string = `${this.bubbleCount}`
- this.scheduleOnce(() => {
- this.isReady = true;
- }, 0.5);
- this.player.getChildByName('icon').active = true;
- }, 0.1);
- }
- /**特殊球切换 */
- private switchSpecialBubble(op: number): void {
- let specialBubble = this.ui.getChildByName('specialBubble');
- for (let i = 0; i < specialBubble.childrenCount; i++) {
- cc.tween(specialBubble.children[i])
- .by(0.5, { y: op * -200, opacity: op * -255 })
- .call(() => {
- if (op == 1) {
- this.ui.getChildByName('cancel').active = true;
- specialBubble.children[i].getComponent(cc.Button).interactable = true;
- }
- })
- .start();
- }
- if (op == 1) {
- this.setspecialColor();
- let node = cc.instantiate(this.shootBubblePre);
- let pos = this.player.convertToNodeSpaceAR(this.startPos);
- node.position = cc.v3(pos.x, pos.y);
- node.parent = this.player;
- node.getChildByName('sprite').getComponent(cc.Sprite).spriteFrame = this.specialBubbleSpriteFrame[this.specialBubbleType - 1];
- node.setContentSize(this.bubbleR * 2, this.bubbleR * 2);
- node.scale = 0;
- let effect = cc.instantiate(this.specialBubbleEffect[this.specialBubbleType - 1]);
- effect.parent = node;
- this.specialBubble = node;
- cc.tween(this.specialBubble)
- .to(0.3, { scale: 1 })
- .start();
- cc.tween(this.shootBubble)
- .to(0.3, { scale: 0, opacity: 0 })
- .call(() => {
- this.shootBubble.active = false;
- this.shootBubble.opacity = 255;
- this.shootBubble.scale = 0;
- this.shootBubble.position = cc.v3(pos.x + 60, pos.y - 60);
- })
- .start();
- cc.tween(this.preBubble)
- .to(0.3, { scale: 0 })
- .start();
- }
- else {
- this.ray.node.removeAllChildren();
- this.specialBubble.destroy();
- this.shootBubble.active = true;
- cc.tween(this.shootBubble).to(0.3, { scale: 0.75 }).start();
- if (!this.isWin) { this.switchShootBubble(); }
- this.ui.getChildByName('cancel').active = false;
- }
- }
- /**小球运动 */
- private bubbleMove(i): void {
- // let pos: cc.Vec2 = this.player.convertToNodeSpaceAR(this.ray.node.convertToWorldSpaceAR(this.rayPos[i]));
- // let end: cc.Vec2 = this.player.convertToNodeSpaceAR(this.ray.node.convertToWorldSpaceAR(this.rayPos[i - 1]));
- let pos: cc.Vec2 = this.player.convertToNodeSpaceAR(this.ray.node.convertToWorldSpaceAR(this.pathPos[i]));
- let end: cc.Vec2 = this.player.convertToNodeSpaceAR(this.ray.node.convertToWorldSpaceAR(this.pathPos[i - 1]));
- if (this.specialBubbleType == 2) {
- this.combo++;
- this.node.getChildByName('tipRay').getComponent(cc.Graphics).clear();
- let node = cc.instantiate(this.laser_gj);
- node.parent = this.specialBubble;
- node.angle = this.vectorsToDegree(this.startPos, this.laserVec);
- for (let i in this.specialBubbleIndex) {
- let color = GameDataCenter.bubbles[this.specialBubbleIndex[i].x][this.specialBubbleIndex[i].y].getComponent('Bubble').color;
- if (color >= 1 && color <= 6) { this.colorCount[color - 1]--; }
- GameDataCenter.bubbles[this.specialBubbleIndex[i].x][this.specialBubbleIndex[i].y].getComponent('Bubble').playDeathAnimation(this.combo, this.specialBubbleType);
- this.changeUi('score', this.combo * 10);
- }
- this.isSuspension();
- return;
- }
- cc.tween(this.specialBubbleType == 0 ? this.shootBubble : this.specialBubble)
- .to(Math.floor(pos.sub(end).mag()) / (1000 * 2), { position: cc.v3(pos.x, pos.y, 0) })
- .call(() => {
- if (i < this.pathPos.length - 1) {
- this.bubbleMove(i + 1);
- }
- else {
- if (this.specialBubbleType == 0) {
- this.creatBubble(this.bubbleIndex.x, this.bubbleIndex.y, this.shootBubble.getComponent('Bubble').color);
- this.crashTween(this.bubbleIndex.x, this.bubbleIndex.y);
- this.shootBubble.destroy();
- this.isElimination();
- }
- else {
- this.combo++;
- this.node.getChildByName('tipRay').getComponent(cc.Graphics).clear();
- if (this.specialBubbleType == 4) {
- if (!GameDataCenter.bubbles[this.thunderIndex.x][this.thunderIndex.y]) {
- this.creatBubble(this.thunderIndex.x, this.thunderIndex.y, this.specialBubbleType);
- this.specialBubbleIndex.push(cc.v2(this.thunderIndex.x, this.thunderIndex.y));
- }
- let node = cc.instantiate(this.thunder_gj);
- node.parent = GameDataCenter.bubbles[this.thunderIndex.x][this.thunderIndex.y];
- node.position = node.parent.convertToNodeSpaceAR(this.map.convertToWorldSpaceAR(cc.v3(0, this.convertRowColToPos(this.thunderIndex.x, this.thunderIndex.y).y)));
- let children = node.getChildByName('qiu')
- children.position = node.convertToNodeSpaceAR(this.map.convertToWorldSpaceAR(this.convertRowColToPos(this.thunderIndex.x, this.thunderIndex.y)));
- }
- else {
- this.creatBubble(this.bubbleIndex.x, this.bubbleIndex.y, this.specialBubbleType);
- this.specialBubbleIndex.push(cc.v2(this.bubbleIndex.x, this.bubbleIndex.y));
- }
- for (let i in this.specialBubbleIndex) {
- let color = GameDataCenter.bubbles[this.specialBubbleIndex[i].x][this.specialBubbleIndex[i].y].getComponent('Bubble').color;
- if (color >= 1 && color <= 6) { this.colorCount[color - 1]--; }
- GameDataCenter.bubbles[this.specialBubbleIndex[i].x][this.specialBubbleIndex[i].y].getComponent('Bubble').playDeathAnimation(this.combo, this.specialBubbleType);
- this.changeUi('score', this.combo * 10);
- }
- this.isSuspension();
- this.specialBubble.destroy();
- }
- }
- })
- .start();
- }
- /**更新地图大小及位置 */
- private setMapPosition(op: number = 1): void {
- let offset: number = this.bubbleR * Math.sqrt(3);
- cc.tween(this.map)
- .by(Math.max(0.03 * op, 0.3), { y: op * offset })
- .call(() => {
- for (let i = 0; i < this.map.childrenCount; i++) {
- this.map.children[i].children[0].position = cc.v3(0, 0, 0);
- this.map.children[i].children[0].getComponent(cc.RigidBody).syncPosition(false);
- }
- })
- .start();
- cc.tween(this.walls.getChildByName('top'))
- .by(Math.max(0.03 * op, 0.3), { y: op * offset })
- .start();
- // this.schedule(() => {
- // this.showBubble();
- // }, 0.1, Math.ceil(Math.max(0.02 * op, 0.3) / 0.1) + 1);
- }
- /**泡泡位置校正 */
- private setBubble(i: number, j: number, position: cc.Vec2): cc.Vec2 {
- let mag: number = 99999;
- let index: cc.Vec2 = cc.v2();
- if (i == -1 && j == -1) {
- index.x = 0;
- for (let k = 0; k < 11; k++) {
- if (GameDataCenter.bubbles[0][k]) { continue; }
- let t: cc.Vec3 = this.convertRowColToPos(0, k);
- let p: cc.Vec2 = cc.v2(t.x, t.y);
- if (p.sub(position).mag() < mag) {
- mag = p.sub(position).mag();
- index.y = k;
- }
- }
- }
- else {
- this.traversal(i, j, (row: number, col: number) => {
- if (GameDataCenter.bubbles[row][col]) return true;
- let t: cc.Vec3 = this.convertRowColToPos(row, col);
- let p: cc.Vec2 = cc.v2(t.x, t.y);
- if (p.sub(position).mag() < mag) {
- mag = p.sub(position).mag();
- index.x = row;
- index.y = col;
- }
- })
- }
- return index;
- }
- /**检测泡泡是否消除 */
- private isElimination(): void {
- // 记录消除行列值
- let record: cc.Vec2[] = [];
- let color = this.shootBubble.getComponent('Bubble').color;
- GameDataCenter.bubbles[this.bubbleIndex.x][this.bubbleIndex.y].getComponent('Bubble').isVisited = true;
- record.push(cc.v2(this.bubbleIndex.x, this.bubbleIndex.y));
- this.traversalAll(this.bubbleIndex.x, this.bubbleIndex.y, (row: number, col: number) => {
- // if (row < GameDataCenter.bubbles.length - this.showCount - 1) return true;
- let nodeData = GameDataCenter.bubbles[row][col].getComponent('Bubble');
- // 如果被访问过
- if (nodeData.isVisited) return true;
- // 如果颜色不同
- if (nodeData.color !== color) return true;
- // 符合条件
- nodeData.isVisited = true;
- record.push(cc.v2(row, col));
- })
- let count: number = 0;
- for (let row = 0; row < GameDataCenter.bubbles.length; row++) {
- for (let col = 0; col < GameDataCenter.bubbles[row].length; col++) {
- if (!GameDataCenter.bubbles[row][col]) continue;
- if (GameDataCenter.bubbles[row][col].getComponent('Bubble').isVisited) {
- GameDataCenter.bubbles[row][col].getComponent('Bubble').isVisited = false;
- count++;
- }
- }
- }
- if (count >= 3) {
- this.combo++;
- // 执行消除
- for (let i in record) {
- this.scheduleOnce(() => {
- this.isIceBubble(record[i].x, record[i].y, GameDataCenter.bubbles[record[i].x][record[i].y].getComponent('Bubble').color);
- this.colorCount[GameDataCenter.bubbles[record[i].x][record[i].y].getComponent('Bubble').color - 1]--;
- GameDataCenter.bubbles[record[i].x][record[i].y].getComponent('Bubble').playDeathAnimation(this.combo);
- }, +i * (0.04 - record.length * 0.001));
- }
- this.scheduleOnce(() => {
- this.changeUi('score', 10 * this.combo * count);
- // this.scheduleOnce(() => {
- // Audio.playSoundByPath('game:res/snd/score');
- // }, 0.5);
- //分数激励
- let node = cc.instantiate(this.scorePrefab);
- node.parent = this.node;
- let pos = this.convertRowColToPos(this.bubbleIndex.x, this.bubbleIndex.y);
- pos = this.node.convertToNodeSpaceAR(this.map.convertToWorldSpaceAR(pos));
- node.position = cc.v3(pos.x, pos.y - 100);
- node.children[0].getComponent(cc.Label).string = `${count * this.combo * 10}`;
- node.getChildByName(this.appraise[Math.floor(Math.random() * 3)]).active = true;
- cc.tween(node)
- .by(0.5, { y: 100 })
- .removeSelf()
- .start();
- if (count > 10) {
- node = cc.instantiate(this.appraisePrefab);
- node.parent = this.node;
- node.scale = 0;
- node.children[Math.floor(Math.random() * 3)].active = true;
- }
- cc.tween(node)
- .to(0.2, { scale: 1 })
- .delay(1)
- .to(0.2, { scale: 0 })
- .removeSelf()
- .start();
- this.isSuspension();
- }, record.length * (0.04 - record.length * 0.001));
- } else {
- this.combo = 0;
- //数组变化及地图移动
- if (this.bubbleIndex.x >= GameDataCenter.bubbles.length - 1) {
- GameDataCenter.bubbles[GameDataCenter.bubbles.length] = []
- if (GameDataCenter.bubbles.length > 10) {
- this.setMapPosition();
- }
- }
- //创建下一个小球
- this.scheduleOnce(() => {
- this.createShootBubble();
- this.switchShootBubble();
- }, 0);
- }
- }
- /**悬空检测 */
- private isSuspension(): void {
- this.scheduleOnce(() => {
- for (let i = 0; i < GameDataCenter.bubbles[0].length; i++) {
- // 执行最上的一排泡泡
- if (!GameDataCenter.bubbles[0][i]) continue;
- this.traversalAll(0, i, (row: number, col: number) => {
- let nodeData = GameDataCenter.bubbles[row][col].getComponent('Bubble');
- if (nodeData.isVisited) return true;
- // 符合条件
- nodeData.isVisited = true;
- nodeData.isLinked = true;
- }, true);
- }
- let count: number = 0;
- for (let row = 0; row < GameDataCenter.bubbles.length; row++) {
- for (let col = 0; col < GameDataCenter.bubbles[row].length; col++) {
- if (!GameDataCenter.bubbles[row][col]) continue;
- if (!GameDataCenter.bubbles[row][col].getComponent('Bubble').isLinked) {
- this.scheduleOnce(() => {
- let color = GameDataCenter.bubbles[row][col].getComponent('Bubble').color;
- if (color >= 1 && color <= 6) { this.colorCount[color - 1]--; }
- GameDataCenter.bubbles[row][col].getComponent('Bubble').playDownAnimation(this.combo * 2, this.map.convertToNodeSpaceAR(this.startPos));
- }, count * 0.02);
- count++;
- } else {
- GameDataCenter.bubbles[row][col].getComponent('Bubble').isVisited = false;
- GameDataCenter.bubbles[row][col].getComponent('Bubble').isLinked = false;
- }
- }
- }
- this.scheduleOnce(() => {
- if (count > 0) { this.changeUi('score', 10 * this.combo * count * 2); }
- this.removeEmpty();
- }, count * 0.02 + count > 0 ? 1.5 : 0);
- }, 0);
- }
- /**冰球检测*/
- private isIceBubble(i: number, j: number, color: number): void {
- this.traversal(i, j, (row: number, col: number) => {
- if (!GameDataCenter.bubbles[row] || !GameDataCenter.bubbles[row][col]) return true;
- if (GameDataCenter.bubbles[row][col].getComponent('Bubble').color == 6) {
- GameDataCenter.bubbles[row][col].destroy();
- Audio.playSoundByPath('game:res/snd/ice');
- this.colorCount[5]--;
- this.creatBubble(row, col, color);
- }
- })
- }
- /**碰撞动画 */
- private crashTween(i: number, j: number): void {
- this.traversal(i, j, (row: number, col: number) => {
- if (!GameDataCenter.bubbles[row] || !GameDataCenter.bubbles[row][col]) return true;
- let start = this.convertRowColToPos(i, j);
- let end = this.convertRowColToPos(row, col);
- let dir = end.sub(start);
- cc.tween(GameDataCenter.bubbles[row][col])
- .by(0.1, { position: dir.normalize().mul(10) })
- .by(0.1, { position: dir.normalize().mul(-10) })
- .start();
- })
- }
- /**炸弹 */
- private bombBubble(): void {
- this.traversal(this.bubbleIndex.x, this.bubbleIndex.y, (row: number, col: number) => {
- this.traversal(row, col, (i, j) => {
- if (!GameDataCenter.bubbles[i] || !GameDataCenter.bubbles[i][j]) return true;
- this.specialBubbleIndex.push(cc.v2(i, j));
- })
- })
- }
- /**七色 */
- private omnipotentBubble(): void {
- this.traversal(this.bubbleIndex.x, this.bubbleIndex.y, (row: number, col: number) => {
- if (!GameDataCenter.bubbles[row] || !GameDataCenter.bubbles[row][col]) return true;
- let color = GameDataCenter.bubbles[row][col].getComponent('Bubble').color;
- this.traversalAll(row, col, (i: number, j: number) => {
- let nodeData = GameDataCenter.bubbles[i][j].getComponent('Bubble');
- // 如果被访问过
- if (nodeData.isVisited) return true;
- // 如果颜色不同
- if (nodeData.color !== color) return true;
- // 符合条件
- nodeData.isVisited = true;
- })
- });
- for (let row = 0; row < GameDataCenter.bubbles.length; row++) {
- for (let col = 0; col < GameDataCenter.bubbles[row].length; col++) {
- if (!GameDataCenter.bubbles[row][col]) continue;
- if (GameDataCenter.bubbles[row][col].getComponent('Bubble').isVisited) {
- GameDataCenter.bubbles[row][col].getComponent('Bubble').isVisited = false;
- this.specialBubbleIndex.push(cc.v2(row, col));
- }
- }
- }
- }
- /**闪电 */
- private lightningBubble(hitBubble: cc.Node, isTop: boolean): void {
- if (isTop) {
- this.thunderIndex = cc.v2(this.bubbleIndex.x, this.bubbleIndex.y);
- }
- else {
- this.thunderIndex = cc.v2(hitBubble.getComponent('Bubble').i, hitBubble.getComponent('Bubble').j);
- }
- for (let i = 0; i < GameDataCenter.bubbles[this.thunderIndex.x].length; i++) {
- let node = GameDataCenter.bubbles[this.thunderIndex.x][i]
- if (!node) { continue; }
- this.specialBubbleIndex.push(cc.v2(node.getComponent('Bubble').i, node.getComponent('Bubble').j));
- }
- }
- /**清空空数组 */
- private removeEmpty(): void {
- let removeCount: number = 0;
- for (let i = GameDataCenter.bubbles.length - 2; i >= 0; i--) {
- let count = 0;
- for (let j = 0; j < GameDataCenter.bubbles[i].length; j++) {
- if (GameDataCenter.bubbles[i][j]) {
- count++;
- }
- }
- if (count == 0) {
- GameDataCenter.bubbles.length--;
- if (GameDataCenter.bubbles.length >= 10) { removeCount++; }
- }
- }
- this.setMapPosition(-removeCount);
- let sum: number = 0;
- for (let i = 0; i < this.colorCount.length; i++) {
- sum += this.colorCount[i];
- }
- let count = 0;
- if (sum == 0) {
- this.isWin = true;
- Audio.playSoundByPath('game:res/snd/victory');
- GameDataCenter.gameLevel++;
- for (let i = 0; i < GameDataCenter.bubbles.length; i++) {
- for (let j = 0; j < GameDataCenter.bubbles[i].length; j++) {
- if (!GameDataCenter.bubbles[i][j]) { continue; }
- this.scheduleOnce(() => {
- GameDataCenter.bubbles[i][j].getComponent('Bubble').playDownAnimation(this.combo * 2, this.map.convertToNodeSpaceAR(this.startPos));
- }, count * 0.01);
- count++;
- }
- }
- if (count > 0) {
- this.scheduleOnce(() => {
- this.changeUi('score', this.combo * 2 * count * 10);
- }, count * 0.01);
- }
- this.scheduleOnce(() => {
- this.initMap();
- }, 2 + count * 0.01);
- }
- this.scheduleOnce(() => {
- if (this.specialBubbleType == 0) {
- this.scheduleOnce(() => {
- this.createShootBubble();
- this.switchShootBubble();
- }, this.isWin ? 3 : 0);
- }
- else {
- if (GameDataCenter.specialBubbles[this.specialBubbleType - 1] > 0) {
- this.changeUi(`special${this.specialBubbleType}`, -1);
- }
- else if (GameDataCenter.coin >= 100) {
- this.changeUi('coin', -100);
- }
- this.scheduleOnce(() => {
- this.switchSpecialBubble(-1);
- }, this.specialBubbleType == 2 ? 1 : 0);
- }
- }, count * 0.01);
- }
- /**传入二维数组行列, 返回对应位置坐标 */
- private convertRowColToPos(row: number, col: number): cc.Vec3 {
- let posX: number = this.bubbleR * ((row % 2) + 1) + col * this.bubbleR * 2 - this.screenW / 2;
- let posY: number = this.screenH - (this.bubbleR + this.bubbleR * row * Math.sqrt(3));
- return cc.v3(posX, posY);
- }
- /**计算向量与y轴之间的夹角 */
- private vectorsToDegree(comVec, dirVec) {
- // 求方向向量与对比向量间的弧度
- let dir = comVec.sub(dirVec);
- let radian = dir.signAngle(cc.v2(1, 0));
- // 将弧度转换为角度
- let degree = cc.misc.radiansToDegrees(radian);
- return Math.round(-(degree - 90));
- }
- /**随机颜色函数 */
- private randNum(): number {
- if (GameDataCenter.gameLevel == 1) {
- if (LevelConfig.level[1].index < 4) { return LevelConfig.level[1].bubble[LevelConfig.level[1].index++]; }
- }
- let color: number[] = [];
- for (let i = 0; i < this.colorCount.length - 1; i++) {
- if (this.colorCount[i] != 0) {
- color.push(i + 1);
- }
- }
- let min: number = 0;
- let max: number = color.length - 1;
- // random 0 - 1 不包括 1
- let random = min + Math.floor((max - min + 1) * Math.random())
- if (color.length == 0) {
- min = 1;
- max = this.colorCount.length - 1
- random = min + Math.floor((max - min + 1) * Math.random())
- return random;
- }
- return color[random];
- }
- /**特殊消除球向量数组去重 */
- private unique(): void {
- let array: cc.Vec2[] = []
- for (let i in this.specialBubbleIndex) {
- let isExit = false;
- for (let j in array) {
- if (this.specialBubbleIndex[i].x == array[j].x && this.specialBubbleIndex[i].y == array[j].y) {
- isExit = true;
- break;
- }
- }
- if (!isExit) {
- array.push(cc.v2(this.specialBubbleIndex[i].x, this.specialBubbleIndex[i].y))
- }
- }
- this.specialBubbleIndex = array;
- }
- /**设置特殊球瞄准线线段颜色 */
- private setspecialColor(): void {
- let specialColor = this.specialColor[this.specialBubbleType - 1];
- this.ray.fillColor = specialColor[0];
- for (let i = 1; i < specialColor.length; i++) {
- let node = cc.instantiate(this.rayPrefab);
- node.parent = this.ray.node;
- let graphic = node.getComponent(cc.Graphics);
- graphic.fillColor = specialColor[i];
- }
- }
- /**ui变化 */
- private changeUi(type: string, num: number = 0): void {
- if (type == 'coin') {
- this.ui.getChildByName('topPanel').getChildByName('coin').getChildByName('num').children[0].getComponent(cc.Label).string = `${GameDataCenter.coin}`;
- if (num == 0) { return; }
- let t: number = GameDataCenter.coin;
- GameDataCenter.coin += num;
- for (let i = 0; i < Math.abs(GameDataCenter.coin - t); i++) {
- this.scheduleOnce(() => {
- num > 0 ? t++ : t--;
- this.ui.getChildByName('topPanel').getChildByName('coin').getChildByName('num').children[0].getComponent(cc.Label).string = `${t}`;
- }, 0.002 * i);
- }
- let specialBubble = this.ui.getChildByName('specialBubble');
- for (let i = 0; i < specialBubble.childrenCount; i++) {
- specialBubble.children[i].getChildByName('null').getChildByName('icon').getComponent(cc.Sprite).spriteFrame = GameDataCenter.coin >= 100 ? this.iconSpriteFrame[2] : this.iconSpriteFrame[0];
- specialBubble.children[i].getChildByName('null').getChildByName('label').getComponent(cc.Label).string = GameDataCenter.coin >= 100 ? '100' : ':1';
- }
- }
- else if (type == 'score') {
- if (num == 0) {
- this.score = 0;
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('scoreLabel').getComponent(cc.Label).string = `得分:${this.score}`;
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('progressBar').getComponent(cc.ProgressBar).progress = 0;
- for (let i = 1; i <= 3; i++) {
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName(`star${i}`).getComponent(cc.Sprite).spriteFrame = this.iconSpriteFrame[3];
- }
- return;
- }
- let t = this.score;
- this.score += num;
- for (let i = 0; i < Math.abs(this.score - t); i++) {
- this.scheduleOnce(() => {
- num > 0 ? t++ : t--;
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('scoreLabel').getComponent(cc.Label).string = `得分:${t}`;
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('progressBar').getComponent(cc.ProgressBar).progress = t / this.perfectScore;
- }, 0.5 * i / num);
- }
- this.scheduleOnce(() => {
- if (this.score >= this.perfectScore && this.star == 2) {
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('star3').getComponent(cc.Sprite).spriteFrame = this.iconSpriteFrame[4];
- this.star++;
- }
- if (this.score >= this.perfectScore * 0.7 && this.star == 1) {
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('star2').getComponent(cc.Sprite).spriteFrame = this.iconSpriteFrame[4];
- this.star++;
- }
- if (this.score >= this.perfectScore * 0.2 && this.star == 0) {
- this.ui.getChildByName('topPanel').getChildByName('score').getChildByName('star1').getComponent(cc.Sprite).spriteFrame = this.iconSpriteFrame[4];
- this.star++;
- }
- }, 0.5);
- }
- else if (type.substring(0, type.length - 1) == 'special') {
- let specialBubble = this.ui.getChildByName('specialBubble');
- let enableSwitch: Function = (i) => {
- specialBubble.children[i].getChildByName('num').active = GameDataCenter.specialBubbles[i] <= 0 ? false : true;
- specialBubble.children[i].getChildByName('null').active = GameDataCenter.specialBubbles[i] <= 0 ? true : false;
- specialBubble.children[i].getChildByName('null').getChildByName('icon').getComponent(cc.Sprite).spriteFrame = GameDataCenter.coin >= 100 ? this.iconSpriteFrame[2] : this.iconSpriteFrame[0];
- specialBubble.children[i].getChildByName('null').getChildByName('label').getComponent(cc.Label).string = GameDataCenter.coin >= 100 ? '100' : ':1';
- specialBubble.children[i].getChildByName('null').getChildByName('icon').setContentSize(GameDataCenter.coin >= 100 ? cc.size(40, 40) : cc.size(40, 30));
- }
- for (let i = 0; i < specialBubble.childrenCount; i++) {
- specialBubble.children[i].getChildByName('num').getChildByName('label').getComponent(cc.Label).string = `${GameDataCenter.specialBubbles[i]}`;
- enableSwitch(i);
- }
- let specialBubbleType = (+type[type.length - 1]) - 1;
- if (specialBubbleType < 0 || num == 0) { return; }
- let t: number = GameDataCenter.specialBubbles[specialBubbleType];
- let array = GameDataCenter.specialBubbles;
- array[specialBubbleType] += num;
- GameDataCenter.specialBubbles = array;
- for (let i = 0; i < Math.abs(GameDataCenter.specialBubbles[specialBubbleType] - t); i++) {
- this.scheduleOnce(() => {
- num > 0 ? t++ : t--;
- specialBubble.children[specialBubbleType].getChildByName('num').getChildByName('label').getComponent(cc.Label).string = `${t}`;
- }, 0.1 * i);
- }
- enableSwitch(specialBubbleType);
- }
- else if (type == 'ingot') {
- }
- }
- /**遍历小球一周 */
- private traversal(i: number, j: number, callback: Function): void {
- let judge: Function = (row: number, col: number) => {
- let leftTop = col;
- // 根据不同的行做偏移
- if (row % 2 === 0) {
- leftTop = col - 1;
- }
- // 每个泡泡周围有6个,依次检测
- // 左上
- test(row - 1, leftTop);
- //右上
- test(row - 1, leftTop + 1);
- //左
- test(row, col - 1);
- //右
- test(row, col + 1);
- //左下
- test(row + 1, leftTop);
- //右下
- test(row + 1, leftTop + 1);
- }
- let test: Function = (row: number, col: number) => {
- if (row < 0) return;
- if (col < 0 || col >= 11) return;
- if (row % 2 == 1 && (col < 0 || col >= 10)) { return; }
- if (callback(row, col)) return;
- }
- judge(i, j);
- }
- /**遍历所有小球 */
- private traversalAll(i: number, j: number, callback: Function, isDFS: boolean = false): void {
- if (isDFS) {
- //深搜
- let test: Function = (row: number, col: number) => {
- if (!GameDataCenter.bubbles[row] || !GameDataCenter.bubbles[row][col]) return;
- if (row < 0) return;
- if (col < 0 || col >= 11) return;
- if (row % 2 == 1 && (col < 0 || col >= 10)) { return; }
- if (callback(row, col)) return;
- let leftTop = col;
- if (row % 2 === 0) {
- leftTop = col - 1;
- }
- // 每个泡泡周围有6个,依次检测
- // 左上
- test(row - 1, leftTop);
- //右上
- test(row - 1, leftTop + 1);
- //左
- test(row, col - 1);
- //右
- test(row, col + 1);
- //左下
- test(row + 1, leftTop);
- //右下
- test(row + 1, leftTop + 1);
- }
- test(i, j);
- }
- else {
- //广搜
- let indexs: cc.Vec2[] = [];
- indexs.push(cc.v2(i, j));
- while (indexs.length != 0) {
- let index = indexs[0];
- indexs.shift();
- this.traversal(index.x, index.y, (row: number, col: number) => {
- if (!GameDataCenter.bubbles[row] || !GameDataCenter.bubbles[row][col]) return;
- if (row < 0) return;
- if (col < 0 || col >= 11) return;
- if (row % 2 == 1 && (col < 0 || col >= 10)) { return; }
- if (callback(row, col)) return;
- indexs.push(cc.v2(row, col));
- })
- }
- }
- }
- /**倒计时回调 */
- private online(): void {
- this.onlineTime--;
- let mm = Math.floor(this.onlineTime / 60);
- let ss = this.onlineTime % 60;
- this.ui.getChildByName('online').getChildByName('time').getComponent(cc.Label).string = `${Utils.formatLen(mm, 2)};${Utils.formatLen(ss, 2)}`;
- let fun: Function = () => {
- this.scheduleOnce(() => {
- if (this.isPress) {
- fun();
- }
- else {
- GameDataCenter.tipType = 4;
- UIManager.open('tip:TipPanel');
- // this.onOnline();
- }
- }, 1)
- }
- if (this.onlineTime <= 0) {
- this.ui.getChildByName('online').getChildByName('time').active = false;
- this.ui.getChildByName('online').getChildByName('name').getChildByName('label').getComponent(cc.Label).string = `领取`;
- this.ui.getChildByName('online').getChildByName('name').getChildByName('label').x += 14;
- this.ui.getChildByName('online').getChildByName('name').getChildByName('videoIcon').active = true;
- // this.ui.getChildByName('online').getComponent(cc.Button).interactable = true;
- this.unschedule(this.online);
- Utils.shake(this.ui.getChildByName('online').getChildByName('gift'));
- if (GameDataCenter.gameLevel >= 13) {
- fun();
- }
- }
- }
- /**顶板透明 */
- private topTween(op: number) {
- if (op) {
- this.ui.getChildByName('topPanel').opacity = 255;
- }
- else {
- this.ui.getChildByName('topPanel').opacity = 100;
- }
- }
- //创建数字
- private creatLabel(s: string) {
- let node = new cc.Node();
- node.parent = this.node;
- node.color = cc.color('#f5bf61' as any);
- let label = node.addComponent(cc.Label);
- label.string = s;
- label.fontSize = 34;
- label.lineHeight = 34;
- label.enableBold = true;
- this.scheduleOnce(() => { node.destroy() }, 1);
- }
- }
|