sweet/assets/scriptes/gamePanel.js
2020-08-07 09:55:56 +08:00

1625 lines
46 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 () {
});
}
}
},
});