Files

672 lines
22 KiB
JavaScript
Raw Permalink Normal View History

2026-05-24 10:21:26 +08:00
"use strict";
cc._RF.push(module, '90e57Vs5XVNlZ3t2axjkG2E', 'cmp.battle.scene');
// Scripts/mod/battle/act/cmp.battle.scene.js
"use strict";
/******************************************************************
*
* 新版战斗场景
*
******************************************************************/
//16 X 8格子地图,角色层 从左到右,从上到下,cellsize 80*80
//角色层只跟随场景销毁,角色死亡只隐藏
var BridgeWindow = require("bridge.window");
var PathTool = require("pathtool");
var BTC = require("battle_controller");
var BCT = require("battle_const");
var BET = require("battle_event");
var _require = require("define"),
SCENE_TAG = _require.SCENE_TAG,
SCREEN_WIDTH = _require.SCREEN_WIDTH,
SCREEN_HEIGHT = _require.SCREEN_HEIGHT,
PlayerAction = _require.PlayerAction;
var NxSpine = require("nx.fx.spine");
cc.Class({
"extends": BridgeWindow,
properties: {
//主要节点
main_layer: {
"default": null,
type: cc.Node
},
battle_layer: {
"default": null,
type: cc.Node
},
black_layer: {
"default": null,
type: cc.Node
},
pk_layer: {
"default": null,
type: cc.Node
},
//挂机和剧情战斗地图
map_lLayer: {
"default": null,
type: cc.Node,
displayName: "超远景"
},
map_fLayer: {
"default": null,
type: cc.Node,
displayName: "远景"
},
map_sLayer: {
"default": null,
type: cc.Node,
displayName: "近景"
},
//其他地图
map_oLayer: {
"default": null,
type: cc.Node,
displayName: "单场景"
},
//角色层和特效层
role_layer: {
"default": null,
type: cc.Node
},
effect_layer_2: {
"default": null,
type: cc.Node,
displayName: "下层特效"
},
effect_layer_1: {
"default": null,
type: cc.Node,
displayName: "上层特效"
},
elfin_layer: {
"default": null,
type: cc.Node,
displayName: "精灵(僚机)层特效"
},
//地图图片
maps: {
"default": [],
type: [cc.Node]
},
mapf: {
"default": [],
type: [cc.Node]
},
mapl: {
"default": [],
type: [cc.Node]
},
talk: {
"default": null,
type: cc.Node
},
talkTxt: {
"default": null,
type: cc.Node
},
startSp: {
"default": null,
type: NxSpine
}
},
onLoad: function onLoad() {
this.battle_model = BTC.getInstance().getModel();
this.battle_hook_model = BTC.getInstance().getHookModel();
this.battle_drama_model = require("battle_drama_controller").getInstance().getModel();
this.battle_res_id = 0; //当前战斗背景资源
this.is_real_fight = false;
this.need_run_map = true; //是否需要移动地图
this.l_speed = 60; //超远景移动速率
this.f_speed = 150; //地图移动速率
this.bg_speed = 100; // 背景层移动速率
this.combat_type = BCT.Fight_Type.Nil; // 当前战斗类型
this.real_role_list = {}; // 当前真实战斗的单位列表
this.resources_list = {}; // 下载资源
this.is_pre_updatescene = false;
this.bindGEvent(BET.INIT_BATTLE_RESBG, this.initSceneResId.bind(this));
this.bindGEvent(BET.HIDE_BAT_UI_IN_SETTLE, this.hideSceneUI.bind(this));
},
hideSceneUI: function hideSceneUI() {
if (this.node && this.node.isValid) {
this.node.active = false;
}
},
start: function start() {},
initSceneResId: function initSceneResId() {
this.battle_res_id = 0;
this.init_drama_finish = false;
},
// 重载:参数打开
onOpenConfigs: function onOpenConfigs(params) {
this.buildUILayer();
if (params.finish_cb) {
//在model設置主場景
params.finish_cb(this);
}
},
onPreClosed: function onPreClosed() {
nx.bridge.camBattle.reset(0.1, null);
this.need_run_map = false;
if (this.black_layer) {
this.black_layer.stopAllActions();
}
if (this.elfin_skill_container) {
this.elfin_skill_container.destroy();
}
if (this.battle_model.isInRealBattle()) {
this.battle_model.clearBattleNd();
// 只要不是剧情副本,都切出战斗
BTC.getInstance().requestCutOutBattle();
}
},
// 改变状态
changeVisible: function changeVisible(status) {
if (!status) {
this.node.active = false;
} else {
this.node.active = true;
}
},
/**
* 更新或者创建战斗场景
* @param {*} is_real
*/
updateBattleScene: function updateBattleScene(is_real) {
this.is_real_fight = is_real;
this.is_pre_updatescene = false;
this.node.active = true;
// 更新战斗地图 1
this.changeBattleScene(is_real);
// 初始化战斗单位 2
if (is_real) {
this.battle_res_id = 0;
// 创建真战斗的角色
var need_enter = this.battle_model.needPlayEnterAction();
if (need_enter) {
// 如果是初始化战斗的话,需要播放进场动画
this.floorTips();
} else {
this.battle_model.createRoleList();
}
this.update_drama_battle = false;
this.init_drama_finish = false;
} else {
this.update_drama_battle = true;
// 创建假战斗的角色
if (this.is_pre_updatescene) this.battle_hook_model.prepareStarBattle(this.initDramaFinish.bind(this));
}
},
// 判断是否需要播放进出场的boss来袭或者是pk的VS动画
floorTips: function floorTips() {
var _this = this;
var battle_data = this.battle_model.getCurBattleData();
if (nx.dt.objEmpty(battle_data)) return;
var combat_config = game.configs.combat_type_data.data_fight_list[battle_data.combat_type];
if (combat_config) {
var start_effect = "E80038";
var eft_name = start_effect;
if (battle_data.combat_type == 44) {
start_effect = "E80052";
eft_name = "action";
}
var res_path = cc.js.formatStr("resDB/effects/%s/%s", start_effect, eft_name);
this.startSp.load(res_path, function (_e) {
if (!_e) {
_this.startSp.action(PlayerAction.action, false, function (_key, _name) {
if (_key == "complete") {
_this.battle_model.createRoleList();
return;
}
});
} else {
_this.startSp.stop();
_this.battle_model.createRoleList();
}
});
// Utils.playEffectOnce( start_effect, eft_name, 0, 0, this.pk_layer, ()=> {
// this.battle_model.createRoleList();
// }, PlayerAction.action, 1 )
} else {
this.battle_model.createRoleList();
}
},
// 获取当前战斗的资源
curBattleResId: function curBattleResId(combat_type) {
var battle_res_id = 10001;
if (combat_type == BCT.Fight_Type.Darma) {
var drama_data = this.battle_drama_model.getDramaData();
if (drama_data && drama_data.chapter_id) {
var base_config = game.configs.battle_bg_data.data_info2[combat_type][drama_data.chapter_id];
if (base_config == null) {
base_config = game.configs.battle_bg_data.data_info[BCT.Fight_Type.Default];
}
if (base_config == null) {
battle_res_id = 10001;
} else {
battle_res_id = base_config.bid;
}
}
} else {
var _base_config = game.configs.battle_bg_data.data_info[combat_type];
if (_base_config == null) {
_base_config = game.configs.battle_bg_data.data_info[BCT.Fight_Type.Default];
}
if (_base_config == null) {
battle_res_id = 10001;
} else {
battle_res_id = _base_config.bid;
}
// // 冒险战斗后面加
// if( combat_type == BCT.Fight_Type.Adventrue ) {
// var base_data = AdventureController.getInstance().getModel().getAdventureBaseData();
// if( base_data ) {
// var config = game.configs.adventure_data.data_battle_res[ base_data.id ];
// if( config && config.battle_res_id ) {
// battle_res_id = config.battle_res_id;
// }
// }
// }
}
return battle_res_id;
},
// 更新战斗背景
changeBattleScene: function changeBattleScene(is_real) {
var battle_data = this.battle_model ? this.battle_model.getCurBattleData() : null;
var unreal_battle_data = this.battle_hook_model.getUnrealBattleData();
if (battle_data == null && unreal_battle_data == null) return;
var combat_type = BCT.Fight_Type.Nil;
if (is_real == true) {
combat_type = battle_data.combat_type; // 如果是真实战斗,并且是剧情战斗的话,就要去当前剧情id然后获取资源
} else {
combat_type = BCT.Fight_Type.Darma;
}
this.combat_type = combat_type; // 整场战斗唯一,也是判断的依据
this.need_run_map = !is_real; // 非真实战斗才需要移动地图
var battle_res_id = this.curBattleResId(combat_type);
this.loaderBattleScene(battle_res_id); // 切换战斗背景资源
},
// 创建战斗背景,也用于更新下一章节的时候切换假战斗资源
loaderBattleScene: function loaderBattleScene(battle_res_id) {
if (battle_res_id == 0) return;
if (this.battle_res_id != battle_res_id) {
this.battle_res_id = battle_res_id;
if (this.combat_type == BCT.Fight_Type.Darma) {
if (battle_res_id) {
this.createSingleScene(battle_res_id);
this.is_pre_updatescene = true;
if (this.update_drama_battle && !this.init_drama_finish) {
this.battle_hook_model.prepareStarBattle(this.initDramaFinish.bind(this));
}
// this.createDramaScene( battle_res_id );
}
} else {
this.createSingleScene(battle_res_id);
}
} else {
this.is_pre_updatescene = true;
}
},
// 创建剧情副本的背景资源
// s_parh:string 背景资源 f_path:string 前景资源
createDramaScene: function createDramaScene(battle_res_id) {
// var bg_1_f = false;
// var bg_2_f = false;
// var drama_paths = PathTool.getBattleDrameBg( battle_res_id );
// this.map_oLayer.active = false;
// //需要计算实际屏幕宽度下的所需地图块的数量
// let self = this;
// cc.loader.loadRes(drama_paths.s,cc.SpriteFrame,(err,obj)=>{
// if(err){
// return;
// }
// let sps = nx.gui.getComponent(self.maps[0],"",cc.Sprite);
// sps.spriteFrame = obj;
// self.maps[0].x = 0;
// let num = Math.ceil(self.main_layer.width / self.maps[0].width);
// for(let i=1;i<=num;i++){
// let spsc = cc.instantiate(self.maps[0]);
// spsc.parent = this.maps[0].parent;
// spsc.x = self.maps[i-1].x + i * self.maps[0].width;
// self.maps.push(spsc);
// }
// // let sps2 = nx.gui.getComponent(this.maps[1],"",cc.Sprite);
// // sps2.spriteFrame = obj;
// // this.maps[1].x = this.maps[0].x + this.maps[0].width;
// bg_1_f = true;
// if( bg_2_f ) {
// self.is_pre_updatescene = true;
// if( self.update_drama_battle && !self.init_drama_finish ) {
// self.battle_hook_model.prepareStarBattle( self.initDramaFinish.bind( self ) )
// }
// }
// });
// cc.loader.loadRes(drama_paths.f,cc.SpriteFrame,(err,obj)=>{
// if(err){
// return;
// }
// let spf = nx.gui.getComponent(self.mapf[0],"",cc.Sprite);
// spf.spriteFrame = obj;
// self.mapf[0].x = 0;
// let numf = Math.ceil(self.main_layer.width / self.mapf[0].width);
// for(let l=1;l<=numf;l++){
// let spsf = cc.instantiate(self.mapf[0]);
// spsf.parent = this.mapf[0].parent;
// spsf.x = self.mapf[l-1].x + l * self.mapf[0].width;
// self.mapf.push(spsf);
// }
// // let spf2 = nx.gui.getComponent(this.mapf[1],"",cc.Sprite);
// // spf2.spriteFrame = obj;
// // this.mapf[1].x = this.mapf[0].x + this.mapf[0].width;
// bg_2_f = true;
// if( bg_1_f ) {
// self.is_pre_updatescene = true;
// if( self.update_drama_battle && !self.init_drama_finish ) {
// self.battle_hook_model.prepareStarBattle( self.initDramaFinish.bind( self ) )
// }
// }
// });
// cc.loader.loadRes(drama_paths.l,cc.SpriteFrame,(err,obj)=>{
// if(err){
// return;
// }
// let spl = nx.gui.getComponent(self.mapl[0],"",cc.Sprite);
// spl.spriteFrame = obj;
// self.mapl[0].x = 0;
// let numl = Math.ceil(self.main_layer.width / self.mapl[0].width);
// for(let a=1;a<=numl;a++){
// let spsl = cc.instantiate(self.mapl[0]);
// spsl.parent = this.mapl[0].parent;
// spsl.x = self.mapl[a-1].x + a * self.mapl[0].width;
// self.mapl.push(spsl);
// }
// // let spl2 = nx.gui.getComponent(this.mapl[1],"",cc.Sprite);
// // spl2.spriteFrame = obj;
// // this.mapl[1].x = this.mapl[0].x + this.mapl[0].width;
// });
},
initDramaFinish: function initDramaFinish() {
this.init_drama_finish = true;
},
// 创建单张战斗背景的
createSingleScene: function createSingleScene(res_id) {
this.map_oLayer.active = true;
var res_path = PathTool.getBattleSingleBg(res_id);
var spf = nx.gui.getComponent(this.map_oLayer, "", cc.Sprite);
nx.gui.setSpriteFrame(spf, "", res_path);
// cc.loader.loadRes( res_path,cc.SpriteFrame,( err,res_object )=> {
// if(err){
// return this.createSingleScene( 10001 );
// }
// spf.spriteFrame = res_object;
// } )
},
update: function update(dt) {
//只有准备场景完毕后才能执行地图更新
// if( this.need_run_map && this.init_drama_finish ) {
// this.moveMap(dt)
// }
},
// 设置是否移动地图,只有剧情战斗才需要做这个处理
changeMoveMapStatus: function changeMoveMapStatus(status) {
if (this.combat_type == BCT.Fight_Type.Darma) {
this.need_run_map = status;
}
},
// 移动地图
moveMap: function moveMap(dt) {
if (!this.maps[0] || !this.mapf[0] || !this.mapl[0]) return;
for (var a = 0; a < this.maps.length; a++) {
this.changeBgPosition2(a, this.maps[a], this.maps[0].width);
this.maps[a].x = this.maps[a].x - this.bg_speed * dt;
}
for (var b = 0; b < this.mapf.length; b++) {
this.changeBgPosition3(b, this.mapf[b], this.mapf[0].width);
this.mapf[b].x = this.mapf[b].x - this.f_speed * dt;
}
for (var c = 0; c < this.mapl.length; c++) {
this.changeBgPosition4(c, this.mapl[c], this.mapl[0].width);
this.mapl[c].x = this.mapl[c].x - this.l_speed * dt;
}
},
changeBgPosition2: function changeBgPosition2(index, cur_bg, width) {
if (cur_bg == null) return;
if (cur_bg.x <= -width) {
if (this.maps[index - 1] != null) {
cur_bg.x = this.maps[index - 1].x + width;
} else {
cur_bg.x = this.maps[this.maps.length - 1].x + width;
}
}
},
changeBgPosition3: function changeBgPosition3(index, cur_bg, width) {
if (cur_bg == null) return;
if (cur_bg.x <= -width) {
if (this.mapf[index - 1] != null) {
cur_bg.x = this.mapf[index - 1].x + width;
} else {
cur_bg.x = this.mapf[this.mapf.length - 1].x + width;
}
}
},
changeBgPosition4: function changeBgPosition4(index, cur_bg, width) {
if (cur_bg == null) return;
if (cur_bg.x <= -width) {
if (this.mapl[index - 1] != null) {
cur_bg.x = this.mapl[index - 1].x + width;
} else {
cur_bg.x = this.mapl[this.mapl.length - 1].x + width;
}
}
},
// 设置地图位置可能移动越界了
changeBgPosition: function changeBgPosition(cur_bg, target_bg, width) {
if (cur_bg == null || target_bg == null) {
return;
}
if (cur_bg.x <= -width) {
cur_bg.x = target_bg.x + width;
}
},
// 获取战斗的特效层
getBattleEffectLayer: function getBattleEffectLayer(index) {
if (index == 1) {
return this.effect_layer_1;
} else {
return this.effect_layer_2;
}
},
// 返回角色层
getBattleRoleLayer: function getBattleRoleLayer() {
return this.role_layer;
},
// 设置黑屏,战斗效果播放
setBlack: function setBlack(status, alpha) {
if (!status) {
if (this.black_layer) {
this.black_layer.runAction(cc.fadeOut(0.2));
// this.black_layer.stopAllActions();
this.black_layer.active = false;
this.black_on_show = false;
}
} else {
if (this.black_on_show) return;
this.black_on_show = true;
this.black_layer.active = true;
this.black_layer.opacity = 0;
this.black_layer.runAction(cc.fadeIn(0.2));
}
},
// 震屏,战斗效果播放
shakeScreen: function shakeScreen(shake_id) {
var _this2 = this;
if (this.is_shake) return;
if (shake_id == null) return;
var data_config = game.configs.skill_data.data_get_shake_data[shake_id];
if (data_config == null) return;
this.is_shake = true;
this.main_layer.stopAllActions();
this.main_layer.setPosition(0, 0);
// 重置位置
var returnPos = function () {
this.is_shake = false;
this.main_layer.setPosition(0, 0);
}.bind(this);
var order = [0, 3, 6, 4, 7, 8, 5, 2, 1];
var str = data_config.shake_strength; // 振幅,单位像素
var step = data_config.shake_rate * 0.003; // 振幅间隔,单位秒
var shakeTime = data_config.shake_time; // 振动次数
var shakeXTime = 0.35; // 横向加倍
var shakeYTime = 0.35; // 纵向加倍
var xy_list = [[-0.7, 0.7], [0, 1], [0.7, 0.7], [-1, 0], [0, 0], [1, 0], [-0.7, -0.7], [0, -1], [0.7, -0.7]];
// 随机设置坐标
var setRandomPos = function (index) {
var pos_x = str * shakeYTime * xy_list[order[index]][0];
var pos_y = -str * shakeXTime * xy_list[order[index]][1];
this.main_layer.setPosition(pos_x, pos_y);
}.bind(this);
var base_call = null;
for (var times = 0; times < shakeTime; times++) {
var _loop = function _loop(index) {
delay = cc.delayTime(step);
if (base_call == null) {
base_call = cc.sequence(cc.callFunc(function () {
setRandomPos(index);
}.bind(_this2)), delay);
} else {
base_call = cc.sequence(base_call, cc.callFunc(function () {
setRandomPos(index);
}.bind(_this2), delay));
}
};
for (var index = 0; index < order.length; index++) {
var delay;
_loop(index);
}
str = str - 3;
}
if (base_call) {
base_call = cc.sequence(base_call, cc.callFunc(returnPos));
this.main_layer.runAction(base_call);
}
},
showElfinSkillAni: function showElfinSkillAni(attacker, call_back, is_act) {
//精灵的效果
if (attacker == null || !attacker.isValid || attacker.skill_data == null) {
if (call_back) {
call_back();
}
return;
}
if (!is_act && attacker.temp_skill_bid != attacker.attacker_info.skill_bid) {
attacker.temp_skill_bid = attacker.attacker_info.skill_bid;
var is_left = this.battle_model.isLeft(attacker.group);
var object_type = attacker.object_type;
if (object_type != BCT.BattleObjectType.Elfin) {
return;
}
//精靈喊招特效
// if( this.elfin_skill_container == null ) {
// this.elfin_skill_container = new cc.Node( "elfin_skill_container" )
// this.elfin_skill_container.setContentSize( cc.size( this.main_layer.width, this.main_layer.height ) )
// this.elfin_skill_container.setAnchorPoint( cc.v2( 0, 0 ) )
// this.elfin_skill_container.setPosition( 0, 0 )
// this.elfin_skill_container.setParent( this.effect_layer_1 );
// }
this.elfin_layer.setContentSize(cc.size(this.main_layer.width, this.main_layer.height));
if (object_type == null) {
if (call_back) {
call_back();
}
} else {
this.elfin_layer.active = true;
this.elfin_layer.stopAllActions();
var call_back_fun = cc.callFunc(function () {
call_back();
}.bind(this));
var call_back_fun_1 = cc.callFunc(function () {
attacker.addSpriteRole(attacker.attacker_info.skill_bid, is_left);
attacker.spriteAction();
}.bind(this));
var head_delay = cc.delayTime(0.5);
var head_over = cc.callFunc(function () {
this.elfin_layer.active = false;
this.elfin_layer.scaleX = 1;
}.bind(this));
this.elfin_layer.runAction(cc.sequence(call_back_fun_1, call_back_fun, head_delay, head_over));
}
} else {
if (call_back) {
call_back();
}
}
},
talkOne: function talkOne(msg, scene_pos, is_friend, _cb) {
var _this3 = this;
nx.gui.setString(this.talkTxt, "", msg);
this.talk.y = scene_pos.y + 170;
if (is_friend) {
this.talk.scaleX = 1;
this.talkTxt.scaleX *= 1;
this.talk.x = scene_pos.x - 60;
} else {
if (this.talkTxt.scaleX > 0) {
this.talkTxt.scaleX *= -1;
}
this.talk.scaleX = -1;
this.talk.x = scene_pos.x + 60;
}
this.talk.active = true;
this.scheduleOnce(function () {
nx.dt.fnInvoke(_cb, true);
_this3.talk.active = false;
}, 1.5);
},
// 创建UI层
buildUILayer: function buildUILayer() {
var layer = nx.gui.find(this.node, "battleUI");
if (layer) {
return;
}
layer = new cc.Node();
layer.name = "battleUI";
layer.setContentSize(this.node.getContentSize());
layer.setAnchorPoint(0.5, 0.5);
layer.setPosition(0, 0);
layer.zIndex = cc.macro.MAX_ZINDEX - 1;
this.node.addChild(layer);
var widget = layer.addComponent(cc.Widget);
widget.isAlignTop = true;
widget.isAlignBottom = true;
widget.isAlignLeft = true;
widget.isAlignRight = true;
widget.alignMode = cc.Widget.AlignMode.ON_WINDOW_RESIZE;
widget.updateAlignment();
nx.bridge.ui.addSceneNode(SCENE_TAG.battleUI, layer);
}
});
cc._RF.pop();