var Config = require('config'); var Global = require('global'); var Res = require('res'); var Util = require('util'); let cakeUtil = require('cakeUtil'); const newerLines = [ [{pos: 0, length: 2}, {pos: 2, length: 2}, {pos: 4, length: 2}, {pos: 6, length: 1}], [{pos: 0, length: 1}, {pos: 1, length: 1}, {pos: 2, length: 2}, {pos: 4, length: 2}, {pos: 6, length: 1}], [{pos: 0, length: 1}, {pos: 3, length: 2}, {pos: 6, length: 1}], ]; cc.Class({ extends: cc.Component, properties: { cookiePrefab: { default: null, type: cc.Prefab }, linePrefab: { type: cc.Prefab, default: null }, nodeLine: { type: cc.Node, default: null }, pnlCombo: { type: require('comboPanel'), default: null }, nodeScene: { type: cc.Node, default: null }, nodeLevelup: { type: cc.Node, default: null }, lblLevel: { type: cc.Label, default: null }, nodeShader: { type: cc.Node, default: null }, content: { type: cc.Node, default: null }, length_probability: { type: Array, default: [] }, empty_probability: { type: Array, default: [] }, newLine: 99, sliderHelpNd: cc.Node, cakeHouseBtn: cc.Node, }, onLoad() { this.empty_probability = []; this.length_probability = []; this.bomb_probability = 0; this.next_grids = []; this.container = [];//每行 每块方块的js句柄 this.next_line_container = []; this.combo = 0;//连击数 this.level = 1; this.score = 0; this.step_eliminate = false;//本次操作是否有消除 this.isCanTouch = false;//是否可以操作 this.useItemIndex = -1; this.non_eliminate_times = 0; this.eliminate_times = 0; // this.nodeCombo.opacity = 0; this.gameScene = this.nodeScene.getComponent('gameScene'); this.nodeLevelup.active = false; this.nodeShader.active = false; let total = 0; for (let i = 0; i < Config.empty_weigh.length; ++i) { total += Config.empty_weigh[i]; } let total2 = 0; for (let i = 0; i < Config.empty_weigh.length; ++i) { total2 += Config.empty_weigh[i]; this.empty_probability[i] = total2 / total; } if (CC_DEBUG) { this.content.on(cc.Node.EventType.MOUSE_DOWN, this.onMouseDown, this); } // cc.EffectMgr.showScoreCollectEffect(cc.v2(0,0), cc.v2(0,0), 0); }, onDestroy() { this.unschedule(this.set_face_twitchmouth); this.unschedule(this.set_face_wait) }, start() { this.showLineCube = cc.jc.maincfg.info['line_cube']; }, startGame() { Global.isGaming = true; this.gameOver = false; this.lvlTarget = this.gameScene.lvlTarget; this.targetArr = []; this.cookieMap = new Map(); for (let key in this.lvlTarget) { if (this.lvlTarget.hasOwnProperty(key)) { this.targetArr.push({id: key, val: this.lvlTarget[key]}); this.cookieMap.set(parseInt(key), this.lvlTarget[key]); } } for (let i = 0; i < Config.cookies.length; i++) { let cookie = Config.cookies[i]; if ((!this.cookieMap.has(cookie.id)) && this.cookieMap.size < 3) { let count = Global.getItemCount(this.level); this.cookieMap.set(cookie.id, count); } } this.levelRedpack = false; let self = this; this.step_eliminate = false; this.isCanEvent = true; this.crazyMode = false; this.unschedule(this.set_face_twitchmouth); this.schedule(this.set_face_twitchmouth, Config.twitchmouth_time); this.unschedule(this.set_face_wait) this.scheduleOnce(this.set_face_wait, Config.blank_wait_time); this.set_probability(this.level); // if (Global.saveData.grids.length > 0) { // this.loadGame(); // } else { if (!Global.getHelpStatus(6) && !this.gameScene.slideHelp) { this.newLine = 0; } this.next_grids = this.generate_grids(); this.generate_row(); // } this.step(function () { if (self) { self.combo = 0; self.isCanTouch = true; self.operationCallback(); } }) }, // 得到随机从小到大排列的数字 get_sorted_random_integers(min, range, amount) { amount = range < amount ? range : amount; let ret = []; while (--amount >= 0) { let r = Util.getRandom(range, min); let i = 0; for (; i < ret.length; ++i) { if (r < ret[i]) { break; } else { ++r; } } ret.splice(i, 0, r); --range; } return ret; }, //获取随机砖块 get_random_wafers(num) { let all = []; for (let i = 0; i < this.container.length; ++i) { let units = this.container[i]; for (let j = 0; j < units.length; ++j) { all.push(units[j]); } } let indexes = this.get_sorted_random_integers(0, all.length, num); let wafers = []; for (let i = 0; i < indexes.length; ++i) { wafers.push(all[indexes[i]]); } return wafers; }, //撇嘴表情 set_face_twitchmouth() { let wafers = this.get_random_wafers(Config.random_twitchmouth_num); for (let i = 0; i < wafers.length; ++i) { wafers[i].playAct('twitchmouth'); } }, //10秒不操作播放等待表情 set_face_wait() { let wafers = this.get_random_wafers(Config.random_face_num); for (let i = 0; i < wafers.length; ++i) { wafers[i].playAct('asquint'); } }, // 播放哭泣表情 set_face_weep() { let wafers = this.get_random_wafers(Config.random_face_num); for (let i = 0; i < wafers.length; ++i) { wafers[i].playAct('weep'); } }, //设置掉落属性 set_probability(level) { let weigh = Config.length_weigh[level - 1] || Config.length_weigh[Config.length_weigh.length - 1]; let total = 0; for (let i = 0; i < weigh.length; ++i) { total += weigh[i]; } let total2 = 0; for (let i = 0; i < weigh.length; ++i) { total2 += weigh[i]; this.length_probability[i] = total2 / total; } this.bomb_probability = Config.bomb_probability[level - 1] || Config.bomb_probability[Config.bomb_probability.length - 1]; this.flash_probability = Config.flash_probability[level - 1] || Config.flash_probability[Config.flash_probability.length - 1]; this.cookie_probability = Config.cookie_probability[level - 1] || Config.cookie_probability[Config.cookie_probability.length - 1]; this.redpack_probability = Global.redpackProbability(); }, //生成一行 generate_grids() { if (this.newLine < 3) { this.isGuide = true; return newerLines[this.newLine++]; } else { this.isGuide = false; } // 随出新行的最大空格数 let r = 0; r = Util.rand01(); if (isNaN(r)) { r = 0; if (CC_DEBUG) console.log(`isNaN netIndex${this.netIndex} netTimeSeed=${Util.netTimeSeed.length}`); } let empty_num; for (let i = 0; i < this.empty_probability.length; ++i) { if (r < this.empty_probability[i]) { empty_num = i + 1; break; } } // 算出方块长度组合 let lengths = []; let total = 0; while (total < Config.hCount - empty_num) { let r = 0; r = Util.rand01(); if (isNaN(r)) { r = 0; if (CC_DEBUG) console.log(`isNaN netIndex${this.netIndex}`); } for (let i = 0; i < this.length_probability.length; ++i) { if (r < this.length_probability[i]) { let length = i + 1; if (length >= Config.hCount - total) { length = Config.hCount - total - 1; } total += length; lengths.push(length); break; } } } // 插入空格 empty_num = Config.hCount - total; while (--empty_num >= 0) { let r = 0; r = Util.getRandom(lengths.length + 1); if (isNaN(r)) { r = 0; if (CC_DEBUG) console.log(`isNaN netIndex${this.netIndex} netTimeSeed=${Util.netTimeSeed.length}`); } lengths.splice(r, 0, 0); } // 算出方块的位置和长度信息 let grids = []; let pos = 0; for (let i = 0; i < lengths.length; ++i) { if (!lengths[i]) { ++pos; } else { grids.push({pos: pos, length: lengths[i]}); pos += lengths[i]; } } return grids; }, //生成一个威化饼 newBrick({gridNum, typeNum, column, eventData, hasRedPack, hasCube}) { eventData = eventData || {}; let brick = cc.instantiate(this.cookiePrefab); this.content.addChild(brick); let code = brick.getComponent('gameCookie'); if (!this.hummerBrick) { code.hasHelpTag = true; this.hummerBrick = brick; } if (this.newLine === 1) { code.hasHelpTag = true; if (this.hummerBrick && !this.breadBrick && this.hummerBrick !== brick) { this.breadBrick = brick; } } code.initUI(); code.initData({gridNum, typeNum, column, eventData, hasRedPack, hasCube}); return brick; }, //生成当前行+下一行 generate_row() { let units = []; let lineHasCookie = false; for (let i = 0; i < this.next_grids.length; ++i) { let showCube = false; let grid = this.next_grids[i]; let typeNum = 0; let hasRedpack = false; if (this.isGuide || !Global.getHelpStatus(6)) { // 如果当前是新手引导状态, 则根据预先设置好的样式显示材料方块 if (grid.typeNum) { typeNum = grid.typeNum; } else { typeNum = 0; } } else if (Util.rand01() < this.bomb_probability) { typeNum = 1; } // else if (Util.rand01() < this.cookie_probability && !lineHasCookie) { // lineHasCookie = true; // let cookieArr = []; // for (let key of this.cookieMap.keys()) { // if (this.cookieMap.get(key) > 0) { // cookieArr.push(key); // } // } // if (cookieArr.length > 0 ) { // let randomNum = Util.getRandom(cookieArr.length, 0); // let key = cookieArr[randomNum]; // this.cookieMap.set(key, this.cookieMap.get(key) - 1); // typeNum = key; // } else { // typeNum = 0; // } // } if (Util.rand01() < this.redpack_probability && !this.levelRedpack && Config.redpack_open) { hasRedpack = true; this.levelRedpack = true; } let randomVal = Util.getRandom(10); if (Global.levelData.lines >= Config.cube_line && typeNum === 0 && randomVal >= 5 && this.showLineCube) { Global.levelData.lines = 0; showCube = true; } let brick = this.newBrick({gridNum: grid.length, typeNum: typeNum, column: grid.pos, hasRedPack: hasRedpack, hasCube: showCube}); units.push(brick.getComponent('gameCookie')); } this.container.push(units); this.next_grids = this.generate_grids(); this.generate_nextline(); }, //生成预览 new_line(length, pos, typeNum) { let line = cc.instantiate(this.linePrefab); line.x = pos * Config.singleSize; line.width = length * Config.singleSize; line.typeNum = typeNum; this.nodeLine.addChild(line); return line; }, //预览下一行 generate_nextline() { for (let i = 0; i < this.next_line_container.length; ++i) { this.next_line_container[i].destroy(); } this.next_line_container.length = 0; for (let i = 0; i < this.next_grids.length; ++i) { let grid = this.next_grids[i]; let line = this.new_line(grid.length, grid.pos, grid.typeNum); this.next_line_container.push(line); } }, // 一步操作完成(检查下落/播放下落动画/计算分数/生成新行/整体提升/检查下落) step(cb, initial_row_index) { let self = this; if (!cb) { cb = function () { self.combo = 0; self.isCanTouch = true; } } this.check_descend(function () { if (Global.isGaming === false) { return; } self.generate_row(); self.rise_upper_units(function () { if (Global.isGaming === false) { return; } self.check_emotion(); self.settle(cb); }); }, initial_row_index); }, check_emotion() { if (this.container.length >= Config.idle_row_limit) { if (this.isMyPanel) { cc.SoundMgr.playSound(cc.SoundMgr['nervous']); } this.set_face_weep(); } this.gameScene.switchShakeItem(this.container.length >= Config.vCount - 1); }, get_min_row() { return Config.min_rows[this.level - 1] || Config.min_rows[Config.min_rows.length - 1]; }, // 检测是否有方块下降以及保证最小行数 settle(cb) { let self = this; if (!cb) { cb = function () { self.combo = 0; self.isCanTouch = true; } } this.check_descend(function () { if (Global.isGaming === false) { return; } if (self.container.length < self.get_min_row()) { self.next_grids = self.generate_grids(); self.generate_row(); self.rise_upper_units(function () { if (Global.isGaming === false) { return; } self.settle(cb); }); } else { self.check_emotion(); cb(); } }); }, //整体方块上移 rise_upper_units(cb) { let bricks = []; for (let i = this.container.length - 2; i >= 0; --i) { let units = this.container[i]; for (let j = 0; j < units.length; ++j) { bricks.push(units[j]); } } let length = bricks.length; if (length === 0) { this.remove_empty_row(this.container.length - 1); if (cb) { cb(); } return; } for (let i = 0; i < length; i++) { bricks[i].upper(); } this.scheduleOnce(cb, Config.rise_time); }, descend_pos(unit, bottom_row) { let unit_right = unit.column + unit.gridNum; let pos = 0; while (pos < bottom_row.length) { let bottom_unit = bottom_row[pos]; let bottom_right = bottom_unit.column + bottom_unit.gridNum; if (unit_right <= bottom_unit.column) { return pos; } else if (unit.column >= bottom_right) { ++pos; } else { return -1; } } return pos; }, //获取下落参数 get_descend_length_pos(unit, row_index) { let length = 0; let pos; for (let i = row_index; i < this.container.length; ++i) { let p = this.descend_pos(unit, this.container[i]); if (p >= 0) { pos = p; ++length; } else { break; } } return {length: length, pos: pos}; }, //删除空行 remove_empty_row(initial_row_index) { for (let i = initial_row_index; i >= 0; --i) { if (!this.container[i].length) { this.container.splice(i, 1); } } }, //下落动作 //TODO: 这里可能有问题 descend_units(units, cb) { for (let i = 0; i < units.length; i++) { units[i].descend(); } this.scheduleOnce(cb, Config.descend_time); }, //检查下落 check_descend(cb, initial_row_index) { let self = this; initial_row_index = initial_row_index || this.container.length - 2; if (initial_row_index > this.container.length - 2) { initial_row_index = this.container.length - 2; } /* if(initial_row_index&&initial_row_index < this.container.length - 2){ initial_row_index = initial_row_index; }else{ initial_row_index = this.container.length - 2; }*/ let objs = []; for (let i = initial_row_index; i >= 0; --i) { let top_row = this.container[i]; let bottom_row = this.container[i + 1]; let top_pos = 0; let bottom_pos = 0; while (top_pos < top_row.length && bottom_pos < bottom_row.length) { let top_unit = top_row[top_pos]; let bottom_unit = bottom_row[bottom_pos]; let top_right = top_unit.column + top_unit.gridNum; let bottom_right = bottom_unit.column + bottom_unit.gridNum; if (top_right <= bottom_unit.column) { let t = this.get_descend_length_pos(top_unit, i + 2); if (t.length > 0) { this.container[i + t.length + 1].splice(t.pos, 0, top_unit); } else { bottom_row.splice(bottom_pos, 0, top_unit); ++bottom_pos; } objs.push(top_unit); top_row.splice(top_pos, 1); } else if (top_right < bottom_right) { ++top_pos; } else if (top_unit.column < bottom_right) { ++top_pos; ++bottom_pos; } else { ++bottom_pos; } } let remaining_units = top_row.splice(top_pos, top_row.length - top_pos); for (let j = 0; j < remaining_units.length; ++j) { let top_unit = remaining_units[j]; let t = this.get_descend_length_pos(top_unit, i + 2); if (t.length > 0) { this.container[i + t.length + 1].splice(t.pos, 0, top_unit); } else { bottom_row.splice(bottom_pos, 0, top_unit); ++bottom_pos; } objs.push(top_unit); } } this.remove_empty_row(initial_row_index); if (!objs.length) { if (cb) { cb(); } return; } this.descend_units(objs, function () { self.check_score(cb); }); }, get_score_rate(combo) { // if (combo > 30) { // return 1 << 30; // } // return 1 << combo - 1; return combo; }, /** * @param {object} row_dict 从上到下第几行上有爆炸方块 * @param {number} row_index 爆炸方块在第几行(从上到下) * @param {object} exploded 爆炸方块 * @param {[object]} exploded_objs 待爆炸的方块数组 * @param {} is_exploded * @param {object} exploded_stack * */ count_row_exploded(row_dict, row_index, exploded, exploded_objs, is_exploded, exploded_stack) { let square_num = 0; let units = this.container[row_index]; let exploded_right = exploded.column + exploded.gridNum; for (let i = units.length - 1; i >= 0; --i) { let unit = units[i]; if (exploded_right > unit.column) { if (unit.column + unit.gridNum > exploded.column) { if (!is_exploded[row_index][unit.column]) { is_exploded[row_index][unit.column] = true; if (unit.typeNum === 1) { exploded_stack.push([row_index, unit]); } exploded_objs.push(unit); if (!row_dict[row_index]) { square_num += unit.gridNum; units.splice(i, 1); } } } else { break; } } } return square_num; }, //获取爆炸分数, 并将爆炸方块旁边的方块放入 exploded_objs count_exploded(rows, exploded_objs, is_exploded, extra_unit, extra_unit_row) { let self = this; let square_num = 0; let row_dict = {}; for (let i = 0; i < rows.length; ++i) { row_dict[rows[i]] = true; } let exploded_stack = []; let score_rate = this.get_score_rate(this.combo + rows.length); if (extra_unit) { is_exploded[extra_unit_row][extra_unit.column] = true; exploded_stack.push([extra_unit_row, extra_unit]); exploded_objs.push(extra_unit); } else { for (let k = 0; k < rows.length; k++) { let units = this.container[rows[k]]; for (let i = units.length - 1; i >= 0; --i) { if (units[i].typeNum === 1) { let unit = units[i]; is_exploded[k][unit.column] = true; exploded_stack.push([rows[k], unit]); exploded_objs.push(unit); } } } } while (exploded_stack.length > 0) { let e = exploded_stack.pop(); let row_index = e[0]; let exploded = e[1]; if (row_index > 0) { square_num += this.count_row_exploded(row_dict, row_index - 1, exploded, exploded_objs, is_exploded, exploded_stack); } if (row_index < this.container.length - 1) { square_num += this.count_row_exploded(row_dict, row_index + 1, exploded, exploded_objs, is_exploded, exploded_stack); } let units = this.container[row_index]; let exploded_right = exploded.column + exploded.gridNum; for (let i = units.length - 1; i >= 0; --i) { let unit = units[i]; if (exploded_right === unit.column) { if (!is_exploded[row_index][unit.column]) { is_exploded[row_index][unit.column] = true; if (unit.typeNum === 1) { exploded_stack.push([row_index, unit]); } exploded_objs.push(unit); if (!row_dict[row_index]) { square_num += unit.gridNum; units.splice(i, 1); } } } else if (exploded_right > unit.column) { if (unit.column + unit.gridNum === exploded.column) { if (!is_exploded[row_index][unit.column]) { is_exploded[row_index][unit.column] = true; if (unit.typeNum === 1) { exploded_stack.push([row_index, unit]); } exploded_objs.push(unit); if (!row_dict[row_index]) { square_num += unit.gridNum; units.splice(i, 1); } } } else if (unit.column + unit.gridNum < exploded.column) { break; } } } } return square_num * this.level * score_rate; }, //连击提示 combo_box(combo) { // 测试 // let cnt = combo; // let sec = 1; // for(let i = 0; i < 3; i++){ // this.scheduleOnce(()=>{ // this.pnlCombo.combo(cnt); // cnt++; // }, sec); // sec++; // } this.pnlCombo.combo(combo); // if (combo > 1) { // cc.EffectMgr.showFireworkEffect(this.pnlCombo.node); // } }, //加分 score_process(objs, score, cb) { if (this.isMyPanel) { cc.SoundMgr.playSound(cc.SoundMgr['score']); } let hasRedpack = false; let hasCube = false; for (let i = 0; i < objs.length; i++) { objs[i].addScore(score); if (objs[i].hasRedPack) { hasRedpack = true; } if (objs[i].hasCube) { hasCube = true; } } if (hasRedpack) { this.gameScene.showRedpackPanel(); } if (hasCube) { this.gameScene.showCubeReward(); } if (cb) { this.scheduleOnce(cb, Config.remove_time); } }, //消除动画 ani_eliminate(objs, rows, score, cb) { if (this.isMyPanel) { cc.SoundMgr.playSound(cc.SoundMgr['eliminate']); } let start_tween = () => { if (Global.isGaming === false) return; this.score_process(objs, score, cb); } let waiting = rows.length; if (!waiting) { start_tween(); return; } let scale = Config.eliminate_scale; let combo = this.combo - rows.length; for (let i = 0; i < rows.length; ++i) { let ani_name = ''; if (++combo > 1) { ani_name = 'comboeliminate'; } else { ani_name = 'normaleliminate'; } let node = new cc.Node(); node.anchorX = 0; node.anchorY = 0; node.width = this.node.width; node.height = Config.singleSize; this.content.addChild(node); let spr = node.addComponent(cc.Sprite); let ani = node.addComponent(cc.Animation); let clip = cc.AnimationClip.createWithSpriteFrames(Res.extra[ani_name], Config.ani_default_fps); ani.addClip(clip, ani_name); ani.play(ani_name); node.scaleY = scale; node.scaleX = 1.2; node.x = 0; node.y = (this.container.length - 1 - rows[i]) * Config.singleSize; cc.EffectMgr.showLineEffect(node); ani.on('stop', function () { node.destroy(); if (--waiting === 0) { start_tween(); } }); } }, //消除动画 exploded_ani_eliminate(objs, cb) { let splst = []; let exploded_length = objs.length; for (let i = 0; i < exploded_length; ++i) { let obj = objs[i]; let aniName = ''; if (obj.typeNum === 1) { splst.push(obj); continue; //aniName = "specialBubble"; } else { aniName = 'bubble'; } obj.playBubble(aniName); } splst.forEach(element => { element.playBubble('specialBubble'); }); this.scheduleOnce(cb, 1.25 + 0.24); }, /** * 非爆炸方块消除 * @param {[Object]} normal_objs 待消除方块数组 * @param {} rows ? * @param {number} score 消除后的得分 * @param {} cb * */ normal_eliminate(normal_objs, rows, score, cb) { let self = this; //this.gameScene.checkShowCakeLight(); let normal_length = normal_objs.length; if (!normal_length) { if (cb) { cb(); } return; } let bricks = {1: 0, 2: 0, 3: 0, 4: 0}; for (let i = 0; i < normal_length; ++i) { normal_objs[i].playAct('blank'); if (normal_objs[i].typeNum === 0) { bricks[normal_objs[i].colorType] += 1; } else { if (normal_objs[i].typeNum >= 100) { if (bricks[normal_objs[i].typeNum]) { bricks[normal_objs[i].typeNum] += 1; } else { bricks[normal_objs[i].typeNum] = 1; } let itemId = normal_objs[i].typeNum; if (this.gameScene.topLevelComp.lvlTarget[itemId]) { cc.EffectMgr.showCookieCollectEffect(normal_objs[i].node, this.gameScene.topLevelNode.getChildByName('targetContainer'), itemId); } } } } Global.updateLevelData(bricks, rows.length); this.scheduleOnce(function () { self.ani_eliminate(normal_objs, rows, score, cb); }, Config.weep_time) }, // 爆炸方块消除 exploded_eliminate(exploded_objs, cb) { let self = this; let exploded_length = exploded_objs.length; if (!exploded_length) { if (cb) { cb(); } return; } let bricks = {1: 0, 2: 0, 3: 0, 4: 0}; for (let i = 0; i < exploded_length; ++i) { exploded_objs[i].chocolate = true; exploded_objs[i].playAct('blank'); if (exploded_objs[i].typeNum === 0) { bricks[exploded_objs[i].colorType] += 1; } else { if (exploded_objs[i].typeNum >= 100) { if (bricks[exploded_objs[i].typeNum]) { bricks[exploded_objs[i].typeNum] += 1; } else { bricks[exploded_objs[i].typeNum] = 1; } let itemId = exploded_objs[i].typeNum; if (this.gameScene.topLevelComp.lvlTarget[itemId]) { cc.EffectMgr.showCookieCollectEffect(exploded_objs[i].node, this.gameScene.topLevelNode.getChildByName('targetContainer'), itemId); } } } } Global.updateLevelData(bricks); this.gameScene.updateLevelInfo(); this.scheduleOnce(function () { self.exploded_ani_eliminate(exploded_objs, cb); }, Config.weep_time) }, // 得分以及移除得分方块 removeUnit(rows, has_bomb, checkCombo, cb) { if (checkCombo) { this.combo = this.gameScene.updateComboProgress(rows.length); } else { this.combo = 1; } if (this.crazyMode) { this.gameScene.shakeSelf(); cc.jc.gameVibrateLong(); } else { cc.jc.gameVibrate(); } Global.updateCombo(this.combo); this.gameScene.updateSkillProgress(Config.one_line_score * this.combo); let normal_objs = []; let exploded_objs = []; let is_exploded = []; for (let i = 0; i < this.container.length; ++i) { is_exploded.push({}); } let score = 0; let exploded_score = 0; let remaining_count = 1; if (has_bomb) { ++remaining_count; exploded_score += this.count_exploded(rows, exploded_objs, is_exploded); } for (let i = 0; i < rows.length; ++i) { let units = this.container[rows[i]]; if (units.length === 0) { continue; } let rate = 1; if (checkCombo) { rate = this.get_score_rate(this.combo); } let sameColor = true; let preColor = units[0].colorType; for (let j = 0; j < units.length; ++j) { if (preColor !== units[j].colorType) { sameColor = false; break; } } if (sameColor) { rate *= Config.same_color_rate; } rate = rate * (this.baseRate || 1) let pos = units[Util.getRandom(units.length, 0)].node.position; let sourcePos = units[0].node.parent.convertToWorldSpaceAR(pos); let rowScore = 0; for (let j = 0; j < units.length; ++j) { let unit = units[j]; if (!is_exploded[rows[i]][unit.column]) { normal_objs.push(unit); unit.score = unit.gridNum * rate; score += unit.score; } else { unit.score = unit.gridNum * rate; exploded_score += unit.score; } rowScore += unit.score; } units.length = 0; // let targetNode = this.gameScene.topLevelNode.getChildByName('targetContainer'); // let targetPos = targetNode.parent.convertToWorldSpaceAR(targetNode.position); // cc.EffectMgr.showScoreCollectEffect(sourcePos, targetPos, rowScore); } let check_finish = function () { if (--remaining_count === 0) { if (cb) { cb(); } } } if (checkCombo) { this.combo_box(this.combo); if (this.combo >= Config.happy_combo) { if (this.isMyPanel) { cc.SoundMgr.playSound(cc.SoundMgr['happy']); } this.gameScene.playExtra('combo'); } if (this.combo >= 2 && this.isMyPanel) { cc.SoundMgr.playSound(cc.SoundMgr['combo']); } } this.step_eliminate = true; this.normal_eliminate(normal_objs, rows, score, check_finish); if (has_bomb) { this.exploded_eliminate(exploded_objs, () => { this.score_process(exploded_objs, exploded_score, () => { check_finish(); }); }); } ; }, check_score(cb) { let self = this; let rows = []; let has_bomb; for (let i = this.container.length - 1; i >= 0; --i) { let units = this.container[i]; if (units.length > 0 && units[0].column === 0) { let length = units[0].gridNum; has_bomb = units[0].typeNum === 1; for (let j = 1; j < units.length; ++j) { if (length !== units[j].column) { break; } length += units[j].gridNum; has_bomb = has_bomb || units[j].typeNum === 1; } if (length === Config.hCount) { rows.push(i); if (has_bomb) { break; } } } } if (!rows.length) { if (cb) { cb(); } return; } this.removeUnit(rows, has_bomb, true, function () { self.check_descend(cb); }); }, addScore(score) { this.score += score; // if (Config.levels[this.level - 1] != undefined && this.score >= Config.levels[this.level - 1]) { // this.level++; // this.set_probability(this.level); // } }, // 点击道具使用弹窗的使用按钮后执行的方法 onTouchUseItem() { this.useItemIndex = this.gameScene.selectItemIndex; cc.jc.gamelog.logButtonClick('useitembtn', {}, this.useItemIndex); }, //吃砖块效果 game_over_process(cb) { if (this.isMyPanel) { cc.SoundMgr.playSound(cc.SoundMgr['eat']); } let self = this; let row_length = this.container.length; let middle = Config.hCount / 2; for (let i = 0; i < row_length; i++) { let units = this.container[i]; for (let j = 0; j < units.length; j++) { let unit = units[j]; let x = unit.node.x; let y = this.node.height + Config.singleSize; let delay = (i + 1) * (Config.game_over_time / (row_length * 2)); if (unit.column + 1 === middle) { //nothing } else if (unit.column + 1 < middle) { x += Config.singleSize; } else if (unit.column + 1 > middle) { x -= Config.singleSize; } unit.node.runAction(cc.sequence(cc.delayTime(delay), cc.moveTo(delay, cc.v2(x, y)))); } } this.scheduleOnce(function () { if (cb) { cb(); } }, Config.game_over_time); }, getRandomRow() { // 随出新行的最大空格数 let r = Util.rand01(); let empty_num; for (let i = 0; i < this.empty_probability.length; ++i) { if (r < this.empty_probability[i]) { empty_num = i + 1; break; } } // 算出方块长度组合 let lengths = []; let total = 0; while (total < Config.hCount - empty_num) { let r = Util.rand01(); for (let i = 0; i < this.length_probability.length; ++i) { if (r < this.length_probability[i]) { let length = i + 1; if (length >= Config.hCount - total) { length = Config.hCount - total - 1; } total += length; lengths.push(length); break; } } } // 插入空格 empty_num = Config.hCount - total; while (--empty_num >= 0) { let r = Util.getRandom(lengths.length + 1); lengths.splice(r, 0, 0); } // 算出方块的位置和长度信息 let grids = []; let pos = 0; for (let i = 0; i < lengths.length; ++i) { let length = lengths[i]; if (length === 0) { ++pos; } else { grids.push({pos: pos, length: lengths[i]}); pos += length; } } for (let i = 0; i < grids.length; i++) { let bomb = false; if (Util.rand01() < this.bomb_probability) { bomb = true; } let colorType = Util.getRandom(Config.color_num + 1, 1); grids[i].typeNum = bomb ? 1 : 0; grids[i].color = colorType; } return grids; }, loadGame() { let grids = Global.saveData.grids; Global.levelData.cookie = Global.saveData.cookie; this.gameScene.topLevelComp.showAllItems(); for (let i = 0; i < grids.length; ++i) { let units = []; for (let j = 0; j < grids[i].length; j++) { let data = grids[i][j]; let brick = this.newBrick({gridNum: data.length, typeNum: data.typeNum, column: data.pos, eventData: data}); units.push(brick.getComponent('gameCookie')); } this.container.push(units); } }, //一步操作之后的回调 operationCallback() { let self = this; this.combo = 0; //更新表情 if (this.step_eliminate) {//有消除 this.step_eliminate = false; this.non_eliminate_times = 0; if (++this.eliminate_times >= Config.tsundere_step_times) { let wafers = this.get_random_wafers(Config.random_face_num); for (let i = 0; i < wafers.length; ++i) { wafers[i].playAct('tsundere'); } } } else { this.eliminate_times = 0; if (++this.non_eliminate_times >= Config.asquint_step_times) {//连续无消除 let wafers = this.get_random_wafers(Config.random_face_num); for (let i = 0; i < wafers.length; ++i) { wafers[i].playAct('weep'); } } } if (this.container.length >= Config.vCount && this.isMyPanel) {//游戏结束 this.game_over_process(e => { self.gameScene.gameOver(); }); } else { this.isCanTouch = true; Global.saveData.grids.length = 0; for (let i = 0; i < this.container.length; i++) { let rows = []; for (let j = 0; j < this.container[i].length; j++) { let unit = this.container[i][j] rows.push({ length: unit.gridNum, pos: unit.column, color: unit.colorType, typeNum: unit.typeNum, y: unit.row }); } Global.saveData.grids.push(rows); } Global.save(); this.checkHelp(); //this.gameScene.updateSkillProgress(Config.one_line_score * this.combo); } }, //升级处理 checkLevelUp() { if (!this.crazyMode) { if (this.gameScene.checkLevelUp()) { if (!this.gameOver) { this.gameOver = true; this.stageOver(); } } } }, stageOver() { for (let i = 0; i < this.container.length; i++) { for (let j = 0; j < this.container[i].length; j++) { this.container[i][j].destroy(); } this.container[i].length = 0; } Global.saveData.grids.length = 0; this.gameScene.stageOver(); }, update(dt) { }, /** * 消除场景上所有的方块 * @param {boolean} ignoreSpecial 消除的时候是否无视巧克力方块, 该值为true的话,会将巧克力方块当作普通方块消除 * @param {function} cb 消除后的回调 * */ eliminateAll(ignoreSpecial, cb) { let self = this; let rows = []; let has_bomb = false; for (let i = this.container.length - 1; i >= 0; --i) { if (ignoreSpecial) { for (let obj of this.container[i]) { obj.typeNum = obj.typeNum === 1 ? 0 : obj.typeNum; } } rows.push(i); } if (!rows.length) { cb && cb(); return; } this.removeUnit(rows, has_bomb, false, function () { self.check_descend(function () { self.generate_row(); self.rise_upper_units(function () { if (Global.isGaming === false) { return; } self.check_emotion(); self.checkLevelUp(); self.settle(cb); }); }); }); }, showGuide(type, obj) { if (!Global.getHelpStatus(type)) { // this.gameScene.showGuide(type, obj); } }, // 检查是否要显示游戏内引导效果 checkHelp() { //if (!Global.getHelpStatus(6) && this.gameScene.slideHelp) { // this.gameScene.showCakeMakeTip(); //} if (this.container.length >= Config.idle_row_limit) { cc.EffectMgr.showAlertPanel(); if (!Global.getHelpStatus(13)) { let brickNd; for (let i = 0; i < this.container.length; i++) { for (let j = 0; j < this.container[i].length; j++) { if (this.container[i][j].gridNum > 1) { (brickNd) || (brickNd = this.container[i][j]); } } } // 大方块数量大于等于8的时候,显示锤子的闪光和手指效果 if (brickNd) { this.gameScene.toggleNoAct(true); let nd = this.gameScene.btnItemArr[1].node.getChildByName('spr_icon'); this.gameScene.showTipLight(nd); this.scheduleOnce(function () { this.gameScene.showItemHelp(nd, brickNd, 1); }, 1); this.scheduleOnce(function () { this.gameScene.removeTipLight(); }, 5); } } else if (!Global.getHelpStatus(14) && Global.getHelpStatus(13)) { this.gameScene.toggleNoAct(true); let nd = this.gameScene.btnItemArr[0].node.getChildByName('spr_icon'); this.gameScene.showTipLight(nd); let brickNd; for (let i = 0; i < this.container.length; i++) { for (let j = 0; j < this.container[i].length; j++) { if (this.container[i][j].typeNum === 0) { brickNd = this.container[i][j]; break; } } if (brickNd) { break; } } this.scheduleOnce(function () { this.gameScene.showItemHelp(nd, brickNd, 0); }, 1); this.scheduleOnce(function () { this.gameScene.removeTipLight(); }, 5); } else { } } else { cc.EffectMgr.hideAlertPanel(); } }, // // 显示砖块上手指点击效果 // showFingerOnBrick() { // let nd ; // if (!Global.getHelpAllStatus(5)) { // nd = this.container[0][0]; // } else if(Global.getHelpAllStatus(5) && (!Global.getHelpAllStatus(6))){ // for (let i = 0; i < this.container.length; i++) { // for (let j = 0; j < this.container[i].length; j++) { // if (this.container[i][j].gridNum > 1) { // nd = this.container[i][j]; // break; // } // } // if (nd) { // break; // } // } // } // if (nd) { // cc.EffectMgr.showFingerClick(nd.node); // } // }, showCakeHelp() { if (!Global.getHelpStatus(6) && !this.gameScene.slideHelp) { cc.UIManage.hideGuide(); this.gameScene.showNextLineHelp(); //cc.UIManage.hideGuide(5); //cc.UIManage.showGuide({type: 6, target: this.cakeHouseBtn, autoShow: false}); } }, // 晃动一个方块 shockOneBrick() { if (Global.isGaming) { this.shockNd = this.container[0][0]; (this.shockNd && this.shockNd.parent) && (this.shockNd.getComponent(cc.Animation).play('cubeShock')); } }, // 移除方块晃动效果 removeBrickShock() { if (this.shockNd && this.shockNd.parent && Global.isGaming) { this.shockNd.getComponent(cc.Animation).stop('cubeShock') this.shockNd.node.rotation = 0; } }, // 用于测试时右键添加方块 onMouseDown(event) { let mouseType = event.getButton(); if (mouseType === cc.Event.EventMouse.BUTTON_RIGHT){ let loc = this.content.convertToNodeSpaceAR(event.getLocation()); let xNum = Math.floor(loc.x / Config.singleSize); let yNum = Math.floor(loc.y / Config.singleSize); this.addOneBrick(xNum, yNum); } }, // 随机添加一个方块 addRandomBrick() { let brickMap = this.getBricksMap(); let noneArr = []; for (let j = 0; j < brickMap.length; j ++) { let arr = brickMap[j]; for (let i = 0; i < arr.length; i++) { if (arr[i] === 0) { noneArr.push([i, j]); } } } if (noneArr.length > 0) { let target = noneArr[Util.getRandom(noneArr.length, 0)]; this.addOneBrick(target[0], target[1]); } }, getBricksMap() { let brickArr = []; for (let i = 0; i < Config.vCount; i ++) { brickArr.push([0,0,0,0,0,0,0,0]); } for (let i = 0; i < this.container.length; i ++) { let bricks = this.container[i]; if (bricks.length > 0) { let idx = bricks[0].row; let cols = brickArr[idx]; for (let k = 0; k < bricks.length; k++) { let obj = bricks[k]; for (let j = 0; j < obj.gridNum; j++) { cols[obj.column + j] = j ? 1 : obj; } } } } return brickArr; }, addOneBrick(xNum, yNum) { let brickMap = this.getBricksMap(); let bricks = brickMap[yNum]; if (bricks[xNum] === 0) { let brick = this.newBrick({gridNum: 1, typeNum: 0, column: xNum, hasRedPack: false, eventData: {y: yNum}, }); bricks[xNum] = brick.getComponent('gameCookie'); } let brickArr = []; for (let i = brickMap.length - 1; i >=0 ; i --) { let brickRow = brickMap[i]; if (brickRow.length > 0) { let subArr = []; for (let obj of brickRow) { if (obj !== 0 && obj !== 1) { subArr.push(obj); } } brickArr.push(subArr); } } this.container = brickArr; }, checkHasBomb(units) { let hasBomb = false; if (units.length > 0) { for (let j = 0; j < units.length; ++j) { hasBomb = hasBomb || units[j].typeNum === 1; } } return hasBomb; }, // 使用消除一行的道具消除三行 removeOneRow(comp) { let self = this; let rows = []; let has_bomb; for (let i = this.container.length - 1; i >= 0; --i) { let units = this.container[i]; if (units.length > 0) { has_bomb = units[0].typeNum === 1; for (let j = 0; j < units.length; ++j) { if (comp === units[j]) { rows.push(i); } has_bomb = has_bomb || units[j].typeNum === 1; } if (rows.length > 0) { break; } } } if (!rows.length) { return; } let currentIdx = rows[0]; if (currentIdx > 0) { has_bomb = has_bomb || this.checkHasBomb(this.container[currentIdx - 1]); rows.unshift(currentIdx - 1); } if (currentIdx < this.container.length - 1) { rows.push(currentIdx + 1); has_bomb = has_bomb || this.checkHasBomb(this.container[currentIdx + 1]); } this.removeUnit(rows, has_bomb, true, function () { self.check_descend(function () { self.settle(); }); }); }, // 敲碎所有大方块 breakAllBrick() { this.isCanTouch = false; for (let i = 0; i < this.container.length; i ++) { let units = this.container[i]; for (let j = 0; j < units.length; j++) { if (units[j].gridNum > 1) { units[j].playItemAni('hammer'); } } } let self = this; this.scheduleOnce(function () { let containers = []; for (let i = 0; i < self.container.length; i ++) { let units = self.container[i]; let newUnits = []; for (let j = 0; j < units.length; j ++) { if (units[j].gridNum > 1) { let unit = units[j]; for (let k = 0; k < unit.gridNum; ++k) { let new_unit = self.newBrick({ gridNum: 1, newBrick: unit.typeNum, column: unit.column + k, typeNum: unit.typeNum, eventData: { color: unit.colorType, y: unit.row } }).getComponent('gameCookie'); newUnits.push(new_unit); } unit.node.active = false; unit.node.parent = null; } else { newUnits.push(units[j]); } } newUnits.sort(function (a, b) { return a.column - b.column; }); containers.push(newUnits); } self.container = containers; self.settle(function () { self.checkLevelUp(); }); self.isCanTouch = true; self.useItemIndex = -1; }, 1) }, fetchCrazyRows() { let self = this; if (self.container.length < Config.crazy_min_rows) { for (let i = self.container.length; i < Config.crazy_min_rows; i ++) { self.next_grids = self.generate_grids(); self.generate_row(); self.rise_upper_units(function () { }); } } }, });