import { GameEvent } from "../constant/constant-game"; import { USER } from "../constant/constant-user"; import AccountModel from "../data/Account/AccountModel"; import buffDtManager from "../dataManager/buffDtManager"; import itemDtManager from "../dataManager/itemDtManager"; import modelDtlManager from "../dataManager/modelDtlManager"; import npcHelper from "../dataManager/npcHelper"; import { AssetsHelper } from "../framework/asset/AssetsHelper"; import { BenzAssetManager } from "../framework/asset/BenzAssetManager"; import EventManager from "../framework/event/EventManager"; import { Log, LOG_TAG } from "../framework/log/Log"; import AudioManager from "../framework/music/AudioManager"; import UIBase from "../framework/ui/UIBase"; import UIHelp from "../framework/ui/UIHelp"; import Utils from "../framework/utils/utils"; import bundleManager from "../manager/bundleManager"; import dungeonManager from "../manager/dungeonManager"; import effectManager from "../manager/effectManager"; import levelManager from "../manager/levelManager"; import playerActionMgr from "../manager/playerActionMgr"; import dungeonNode from "../ui/dungeonNode"; import UIFailView from "../ui/uiview/Interface/UIFailView"; import UIReliveView from "../ui/uiview/Interface/UIReliveView"; import UITopMenu from "../ui/uiview/Interface/UITopMenu"; import UIWinView from "../ui/uiview/Interface/UIWinView"; import UIFallitem from "../ui/uiview/map/UIFallitem"; import BulletObject from "./gameObject/bullet/bulletObject"; import zomBiebullet from "./gameObject/bullet/zomBiebullet"; import GameObject from "./gameObject/gameObject"; import NodeMove from "./gameObject/player/nodeMove"; import PlayerObject from "./gameObject/player/playerObject"; import PlayerProp from "./gameObject/player/playerProp"; import PlayerView from "./gameObject/player/playerView"; import NpcObject from "./gameObject/tool/npcObject"; import WeaponProp from "./gameObject/tool/weaponProp"; import ZomBieObject from "./gameObject/zombie/zombieObject"; import ZombieProp from "./gameObject/zombie/zombieProp"; import zombieView from "./gameObject/zombie/zombieView"; import gameData from "./utrl/gameData"; import { ANI_STATE, ATTACK_MODE, EVENT_TYPE, FALLITEM_TYPE, GAME_OBJECT_TYPE, HERO_TYPE, HeroId, ITEM_TYPE, JOY_STATE, ROLE_STATE, WEAPON_TYPE } from "./utrl/gameEnum"; import gameEventManager from "./utrl/gameEventManager"; import UICrazyAwardView from "../ui/uiview/Interface/UICrazyAwardView"; import UIMng from "../framework/ui/UIMng"; const { ccclass, property } = cc._decorator; /**关卡逻辑类 */ @ccclass export default class LevelLogic extends cc.Component { @property(cc.Node) /**地图父节点 */ map_parent: cc.Node = null; @property(cc.Node) /**实体父节点 */ object_parent: cc.Node = null; /**道具父节点 */ @property(cc.Node) prop_parent: cc.Node = null; /**道具预制体 */ @property(cc.Prefab) prop_pre: cc.Prefab = null; /**未解锁npc父节点 */ @property(cc.Node) npc_parent: cc.Node = null; @property() playerNum: Number = 6; /**摄像机节点 */ private camera: cc.Node = null; /**玩家预制体 */ private player_pre: cc.Prefab = null; /**僵尸预制体 */ private zombie_pre: cc.Prefab = null; /**子弹预制体 */ private bullet_pre: cc.Prefab = null; game_over: boolean = false; //是否失败 isGoDungeon: boolean = false; isWin: boolean = false; //是否通关成功 playerDiePos: cc.Vec3 = null; //玩家死亡位置 playerIsMove: boolean = false; /**buff间隔时间 */ private buff_dur = 10; /**buff间隔计时器 */ private buff_timer = 0; /**buff回复子弹血量体力值组 */ private buffs: number[][] = []; /**地图包围框节点 */ private map_frame: cc.Node = null; /**迷你地图 */ private mini_map: cc.Node = null; zombieBornNodeArr: cc.Node[]; /**玩家组 */ /**角色组,0玩家组,1僵尸组 */ roles: cc.Node[][] = [null, null]; _isInit: boolean = false; _initPlayer: boolean = false; dtCount: number = 0; isPause = false; //对象池 playerBulletPool: cc.NodePool; zombieNodePool: cc.NodePool; playerNodePool: cc.NodePool; propsNodePool: cc.NodePool; start() { // gameData.curPeopleNum = this.getPlayerArr().length; gameEventManager.emit(EVENT_TYPE.CANT_JOY, true); Utils.tipsSprite('main/jiangshilaixi', cc.director.getScene().getChildByName('Canvas')); gameEventManager.emit(EVENT_TYPE.attack_mode); if (AccountModel.getInstance().curLevel == 1) { zjSdk?.sendEvent('进入新手引导') }; this.initBulletPool(); this.initZombiePool(); this.initPlayerPool(); this.initPropPool(); } initPlayerPool() { this.playerNodePool = Utils.initNodePool(this.player_pre, 20); } initZombiePool() { this.zombieNodePool = Utils.initNodePool(this.zombie_pre, 15); } initBulletPool() { this.playerBulletPool = Utils.initNodePool(this.bullet_pre, 10); } initPropPool() { this.propsNodePool = new cc.NodePool(); } clearPropPool() { let poolLen = this.propsNodePool.size(); if (poolLen > 0 && poolLen > 20) { this.propsNodePool.clear(); Log.log(LOG_TAG.DEBUG, 'clearpropsNodePool'); } } onEnable() { this._isInit = false; this._initPlayer = false; gameEventManager.on(EVENT_TYPE.GAME_RELIVE, this.gameRelive, this); gameEventManager.on(EVENT_TYPE.GAME_OVER, this.gameOver, this); gameEventManager.on(EVENT_TYPE.joy_stick, this.playerMove, this); gameEventManager.on(EVENT_TYPE.random_leader, this.randomLeader, this); gameEventManager.on(EVENT_TYPE.add_zombie, this.addZombie, this); gameEventManager.on(EVENT_TYPE.bullet0, this.playerRemoteAttack0, this); gameEventManager.on(EVENT_TYPE.bullet1, this.playerRemoteAttack1, this); gameEventManager.on(EVENT_TYPE.zombie_boom, this.zombieRemoteBoom, this); gameEventManager.on(EVENT_TYPE.player_die, this.diePlayerCbk, this); gameEventManager.on(EVENT_TYPE.zombie_die, this.dieZombieCbk, this); gameEventManager.on(EVENT_TYPE.RESET_ZOMBIE, this.reSetZombie, this); gameEventManager.on(EVENT_TYPE.zombieDieForCrazy, this.zombieDie, this); gameEventManager.on(EVENT_TYPE.ADD_HERO, this.addHero, this) gameEventManager.on(EVENT_TYPE.ADD_HERO_BY_ID, this.addHeroById, this) gameEventManager.on(EVENT_TYPE.ADD_WEAPONS, this.addWeapons, this) gameEventManager.on(EVENT_TYPE.VIOLENT_ZOMBIE, this.zombieViolent, this); gameEventManager.on(EVENT_TYPE.BOSS_SKIN_ADDZOMBIE, this.bossAddZombie, this) gameEventManager.on(EVENT_TYPE.ADD_BOSS, this.addBoss, this) gameEventManager.on(EVENT_TYPE.CHANGE_STATUS, this.changeStatue, this) gameEventManager.on(EVENT_TYPE.RECOVER_ZOMBIE, this.recoverZombie, this) gameEventManager.on(EVENT_TYPE.RECOVER_PLAYER, this.recoverPlayer, this) gameEventManager.on(EVENT_TYPE.RECOVER_PLAYER_BULLET, this.recoverPlayerBullet, this) this.isGoDungeon = false; if (this.mini_map) { this.mini_map.active = true; } this.scheduleOnce(() => { this.iniPlayer(); }, 0.04) gameEventManager.emit(EVENT_TYPE.INIT_SWITCH_BTN); } isAddBoos() { if (gameData.bAddBoss) { let bossList = this.getBossList(); if (bossList.length <= 0) { this.addBoss(); } } } onDisable() { gameEventManager.off(EVENT_TYPE.GAME_RELIVE, this.gameRelive, this); gameEventManager.off(EVENT_TYPE.ADD_BOSS, this.addBoss, this) gameEventManager.off(EVENT_TYPE.BOSS_SKIN_ADDZOMBIE, this.bossAddZombie, this) gameEventManager.off(EVENT_TYPE.ADD_HERO, this.addHero, this) gameEventManager.off(EVENT_TYPE.ADD_HERO_BY_ID, this.addHeroById, this) gameEventManager.off(EVENT_TYPE.ADD_WEAPONS, this.addWeapons, this) gameEventManager.off(EVENT_TYPE.VIOLENT_ZOMBIE, this.zombieViolent, this); gameEventManager.off(EVENT_TYPE.RESET_ZOMBIE, this.reSetZombie, this); gameEventManager.off(EVENT_TYPE.joy_stick, this.playerMove, this); gameEventManager.off(EVENT_TYPE.random_leader, this.randomLeader, this); gameEventManager.off(EVENT_TYPE.GAME_OVER, this.gameOver, this); gameEventManager.off(EVENT_TYPE.add_zombie, this.addZombie, this); gameEventManager.off(EVENT_TYPE.bullet0, this.playerRemoteAttack0, this); gameEventManager.off(EVENT_TYPE.bullet1, this.playerRemoteAttack1, this); gameEventManager.off(EVENT_TYPE.zombie_boom, this.zombieRemoteBoom, this); gameEventManager.off(EVENT_TYPE.player_die, this.diePlayerCbk, this); gameEventManager.off(EVENT_TYPE.zombie_die, this.dieZombieCbk, this); gameEventManager.off(EVENT_TYPE.CHANGE_STATUS, this.changeStatue, this) gameEventManager.off(EVENT_TYPE.zombieDieForCrazy, this.zombieDie, this); gameEventManager.off(EVENT_TYPE.RECOVER_ZOMBIE, this.recoverZombie, this); gameEventManager.off(EVENT_TYPE.RECOVER_PLAYER, this.recoverPlayer, this) gameEventManager.off(EVENT_TYPE.RECOVER_PLAYER_BULLET, this.recoverPlayerBullet, this) } changeStatue(flag) { this.isPause = flag; } update(dt: number) { if (this.isPause) { return; } if (!this.playerIsMove || !this._isInit) { return; } if (this.isWin || this.game_over) { return; } // this.runBullets(dt); this.checkPlayerWithProp(); this.checkPlayerBulletCrashZombie(); this.checkBulletCrashPlayer(); this.playerRunBuff(dt); this.isCloseDungeon(); this.checkPlayerWithNpc(); this.isCloseWinNode(); this.createZombie(); this.fast(); this.updateRoleDt(); } lateUpdate(dt) { this.cameraTrack(dt); } updateRoleDt() { if (this.game_over) { return } this.dtCount++; if (this.dtCount >= 15) { this.dtCount = 0; this.layInPlayerDt(); AccountModel.getInstance().playerDtList = gameData.playerDtList; } } bossAddZombie(addNum: number, targetNode: cc.Node) { let randomID = npcHelper.getRandomZombieId(); this.schedule(() => { if (!targetNode || !cc.isValid(targetNode)) { return; } let randomX = 0//Utils.random(-100, 100); let randomY = Utils.random(-50, -20) let pos = cc.v3(targetNode.position.x + randomX, targetNode.position.y + randomY); this.addZombie(randomID, pos); }, 0.5, addNum) } //回收僵尸节点 recoverZombie(nd) { let zombiePool = this.zombieNodePool; if (zombiePool) { zombiePool.put(nd); Log.log(LOG_TAG.DEBUG, zombiePool); } else { nd.destroy(); } } recoverPlayer(nd) { let playerPool = this.playerNodePool; if (playerPool) { playerPool.put(nd); Log.log(LOG_TAG.DEBUG, playerPool); } else { nd.destroy(); } } recoverPlayerBullet(nd) { let playerBulletPool = this.playerBulletPool; if (playerBulletPool) { playerBulletPool.put(nd); Log.log(LOG_TAG.DEBUG, playerBulletPool); } else { nd.destroy(); } } //僵尸狂暴状态 zombieViolent() { // console.log('僵尸狂暴') let zombieList = this.getZombies(); if (zombieList.length > 0) { for (let i = 0; i < zombieList.length; ++i) { if (cc.isValid(zombieList[i]) && zombieList[i].active == true) { zombieList[i].getComponent(zombieView).zombieViolent(); } } } } //僵尸重生 reSetZombie(pos) { gameData.isSetZomBie = true; this.scheduleOnce(() => { if (gameData.isSetZomBie == false) { return; } let offsetX = Utils.random(-150, 150); let offsetY = Utils.random(-150, 150); let newPos = cc.v3(pos.x + offsetX, pos.y + offsetY); if (!gameData.isDayTime) { this.addZombie(npcHelper.getRandomZombieId(), newPos); } this.addZombie(npcHelper.getRandomZombieId(), newPos); }, 10) } zombieDie() { if (!GameEvent.isShowInnerCrazyAward) { return; } if (GameEvent.crazyAwardPopMaxTimes - AccountModel.getInstance().show_crazy_in_level <= 0) { return; } //第一滴血 if (gameData.curKillZomNum == GameEvent.firstCrazyByZombieNum) { this.isPause = true; gameEventManager.emit(EVENT_TYPE.CHANGE_STATUS, true) UIHelp.ShowUI(UICrazyAwardView); } if (gameData.curKillZomNum != 0 && gameData.curKillZomNum % GameEvent.crazyByZombieNumTimes == 0) { //濒临状态不弹 if (this.checkVerge()) { return; } gameEventManager.emit(EVENT_TYPE.CHANGE_STATUS, true) this.isPause = true; UIHelp.ShowUI(UICrazyAwardView) } } checkVerge() { let result = 0; const threshold = 20; const player = this.roles[0]; for (let node of player) { if (!cc.isValid(node)) { continue; } result += node.getComponent(PlayerObject).player_prop.cur_hp if (result >= threshold) { return false; } } return true; } playerMove(state) { if (state = JOY_STATE.move) { this.playerIsMove = true } else { this.playerIsMove = false; } } /**初始化 * @param camera 摄像机 * @param player_pre * @param zombie_pre * @param bullet_pre * @param isNew 是否新开局 */ init(camera: cc.Node, player_pre: cc.Prefab, zombie_pre: cc.Prefab, bullet_pre: cc.Prefab, isNew = false) { this.camera = camera; this.player_pre = player_pre; this.zombie_pre = zombie_pre; this.bullet_pre = bullet_pre; this.zombieBornNodeArr = this.node.$zombieBorn_parent.children; isNew = this.iniPlayer() //新开局 if (isNew) { this.initUIData(); this.tryLoadPermanentHero(); } this.initZomBie(); this.map_frame = this.map_parent.getChildByName('frame'); gameEventManager.emit(EVENT_TYPE.refresh_mini_map, levelManager.getCurOpenId() - 1, this.map_frame); gameEventManager.emit(EVENT_TYPE.refresh_mini_map_pos, cc.v2()); this.buffs = []; for (let i = 1; i <= 9; i++) { let d = buffDtManager.getDataByID(i); let b = [d.att, d.hp, d.food]; this.buffs.push(b); } } private initUIData() { AccountModel.getInstance().first_dec_power = false; AccountModel.getInstance().first_dec_bullet = false; } private tryLoadPermanentHero() { const ids = AccountModel.singleInstance.fixed_role_ids; //微信平台加载不出来的临时解决方案 if (!ids.indexOf(HERO_TYPE.wuliuqi) && AccountModel.singleInstance.sign_times >= 7) { ids.push(HERO_TYPE.wuliuqi); } Log.log(LOG_TAG.DEBUG, "加载英雄:", ids); if (ids.length != 0) { ids.forEach((value, index) => { this.scheduleOnce(() => { const playerObject = this.addHeroById(value); //护士写死算了, if (value == 14) { const data = itemDtManager.getDataByID(FALLITEM_TYPE.futou); const gunData = itemDtManager.getDataByID(FALLITEM_TYPE.chongfengqiang); this.addWeapons(data.id, data.value, data.type == 4, playerObject); this.addWeapons(gunData.id, gunData.value, data.gunData == 4, playerObject); } // 保证有players对象 }, (index + 3) * 0.2); }) } } //初始化僵尸 initZomBie() { this.createZombie(); this.addZombieCbk(); } createZombie() { for (let j = this.zombieBornNodeArr.length - 1; j >= 0; --j) { let dis = this.getDis(this.camera, this.zombieBornNodeArr[j]); let limit = (cc.winSize.width / 2) + 150; if (this.zombieBornNodeArr[j].active == true && dis <= limit) { let name: string = this.zombieBornNodeArr[j].name; let bornDt = this.getZombieBornDtByName(name); let bornNum: number = bornDt.num; this.schedule(() => { let randomId = bornDt.type == "s" ? npcHelper.getRandomSeniorZombieId() : npcHelper.getRandomZombieId(); let offsetX = Utils.random(-150, 150); let offsetY = Utils.random(-150, 150); let pos = cc.v3(this.zombieBornNodeArr[j].x + offsetX, this.zombieBornNodeArr[j].y + offsetY); this.addZombie(randomId, pos); }, 0.04, bornNum - 1) this.zombieBornNodeArr[j].active = false; } } } addBoss() { if (gameData.bAddBoss) { gameData.bAddBoss = false; } let bossId = npcHelper.getRandomBossId(); let cb = () => { let randomX = Utils.random(150, 200); let randomY = Utils.random(-10, 80); let pos = cc.v3(this.roles[0][0].position.x + randomX, this.roles[0][0].position.y + randomY, 0) this.addZombie(bossId, pos); } this.addBossTips(bossId, cb) } //添加BOSS警告 addBossTips(bossId, cb) { let framesName = modelDtlManager.getDataByID(bossId).modelname; let winSize = cc.winSize; let node = new cc.Node(); let bossNode = new cc.Node(); node.addComponent(cc.Sprite); bossNode.addComponent(cc.Sprite) bundleManager.setBundleFrame('UI', 'main/' + framesName, bossNode); bundleManager.setBundleFrame('UI', 'main/jinggao', node); node.parent = cc.director.getScene().getChildByName('Canvas'); bossNode.parent = node bossNode.x += 150; node.x = -winSize.width / 2 - 400; node.y += 80; cc.tween(node) .delay(1) .to(1, { x: 0 }, { easing: 'smooth' }) .delay(2) .by(1, { x: winSize.width / 2 + 350 }, { easing: 'smooth' }) .call(() => { node.destroy(); cb() }) .start() } getBossList() { let bossList: cc.Node[] = []; let zombieList = this.getZombies(); for (let nd of zombieList) { if (npcHelper.isBoss(nd.getComponent(ZomBieObject).zombie_prop.zombie_ID)) { bossList.push(nd); } } return bossList; } private getZombieBornDtByName(name: string): { num: number, type: string } { if (name.indexOf('s') >= 0) { let nameArr = name.split(''); return { num: +nameArr[1], type: 's' }; } else { return { num: +name, type: 'c' }; } } //是否已经初始化过玩家 isInitedPlayer() { if (this.getPlayerArr().length > 0) { return true; } return false; } //初始化玩家 iniPlayer() { if (this._initPlayer) { return; } this._initPlayer = true; let isNew = false; let playerDt = AccountModel.getInstance().playerDtList; // 为零就是初始化 if (playerDt.length == 0) { isNew = true; } let playerNum = playerDt.length > 0 ? playerDt.length : this.playerNum; gameData.curPeopleNum = playerNum; EventManager.emit(EVENT_TYPE.UPDATE_PEOPLE_NUM); var initCameraPos = cc.v2(); let playerBornNode = this.node.$playerBornNode; if (this.mini_map) { this.mini_map.active = true; } let idx = 0; this.schedule(() => { let nd = this.playerNodePool.size() > 0 ? this.playerNodePool.get() : cc.instantiate(this.player_pre); let playerViewCom = nd.getChildByName('view').getComponent(PlayerView); let playerObjCom = nd.getComponent(PlayerObject); let randomID = null; if (playerDt.length > 0) { randomID = playerDt[idx].player_ID; let offset = 50; if (playerDt[idx].pos) { nd.setPosition(playerDt[idx].pos.x, playerDt[idx].pos.y - offset); } else { if (playerDt[0].pos) { nd.setPosition(playerDt[0].pos.x, playerDt[0].pos.y - offset); } else { let random = Math.random(); nd.setPosition(playerBornNode.x + random, playerBornNode.y + random); } } } else { randomID = npcHelper.getRandomComPlayerId(); let offset = cc.v2(Math.random(), Math.random()); nd.setPosition(playerBornNode.x + offset.x, playerBornNode.y + offset.y); } if (idx == 0) { initCameraPos = nd.getPosition(); this.camera.setPosition(initCameraPos); } this.addBuffItem(randomID, nd); this.object_parent.addChild(nd); playerObjCom.init(randomID, this.roles); playerViewCom.init(randomID); if (idx >= (playerNum - 1)) { this.addPlayerCbk(); this.randomLeader(); //随机一个领导 this.resetIsCover(); this._isInit = true this.isAddBoos(); return; } idx++; }, 0.02, playerNum - 1); return isNew; } resetIsCover() { let dt = AccountModel.getInstance().playerDtList; if (dt.length > 0) { dt.forEach(element => { element.isCover = false; }); } } gameOver() { if (AccountModel.getInstance().curLevel == 1) { zjSdk?.sendEvent('新手引导-失败') }; this.removeNode(); this.setPlayerDiePos(); this.game_over = true; UITopMenu.getInstance().node.active = false; gameEventManager.emit(EVENT_TYPE.CANT_JOY, false); gameData.isSetZomBie = false; AccountModel.getInstance().curPower = USER.init_powerNum; AccountModel.getInstance().curBullet = USER.init_bulletNum; AccountModel.getInstance().curDay = USER.init_day; AccountModel.getInstance().playerDtList = []; AccountModel.getInstance().curWelfare = []; gameData.init(); if (AccountModel.getInstance().reliveNum <= 0) { zjSdk?.gameEnd(() => { UIHelp.ShowUI(UIFailView); }) } else { UIHelp.ShowUI(UIReliveView); } } /*复活*/ gameRelive(reLiveType) { if (reLiveType == 'restart') { zjSdk?.gameEnd(() => { UIHelp.ShowUI(UIFailView); }) } else { Log.log(LOG_TAG.DEBUG, '复活'); AccountModel.getInstance().reliveNum -= 1; this.relivePlayer(); } } //玩家复活 relivePlayer() { let playerNum = 5; for (let i = 0; i < playerNum; ++i) { let randomId = npcHelper.getRandomComPlayerId(); let randomPos = cc.v3(this.playerDiePos.x + Utils.random(-20, 20), this.playerDiePos.y + Utils.random(-20, 20)); this.addPlayer(randomId, randomPos) } for (let j = 0; j < this.roles[0].length; ++j) { let closeWeaponID = 21; let romoteWeaponID = 39; let remoteValue = itemDtManager.getDataByID(romoteWeaponID).value; let closeValue = itemDtManager.getDataByID(closeWeaponID).value; let playerObj = this.roles[0][j].getComponent(PlayerObject); this.getWeapon(closeWeaponID, closeValue, playerObj, true); this.getWeapon(romoteWeaponID, remoteValue, playerObj, false); } this.randomLeader(); this.game_over = false; UITopMenu.getInstance().node.active = true; gameData.isSetZomBie = true; gameEventManager.emit(EVENT_TYPE.CANT_JOY, true); gameData.curBulletNum += 200; //奖励定死 gameData.curPowerNum = 200 let bs = this.roles[0]; let zs = this.getZombies(); for (let i = bs.length - 1; i >= 0; i--) { for (let j = zs.length - 1; j >= 0; j--) { let dis = this.getDis(bs[i], zs[j]); if (dis < 100) { zs[j].destroy(); } } } } //记录玩家死亡位置 方便复活用 setPlayerDiePos() { let playerDt = AccountModel.getInstance().playerDtList; if (playerDt && playerDt.length > 0) { for (let i = 0; i < playerDt.length; ++i) { if (playerDt[i].is_leader) { this.playerDiePos = playerDt[i].pos; return; } } } } /**切换攻击模式 */ switchAttackMode() { if (gameData.cur_attack_mode == ATTACK_MODE.close) { gameData.cur_attack_mode = ATTACK_MODE.remote; } else { gameData.cur_attack_mode = ATTACK_MODE.close; } gameEventManager.emit(EVENT_TYPE.attack_mode); } /**设置迷你地图 */ setMiniMap(map: cc.Node) { this.mini_map = map; } /**玩家生成回调 */ private addPlayerCbk() { this.roles[0] = this.getPlayerArr(); } /**玩家死亡回调 */ private diePlayerCbk() { this.roles[0] = this.getPlayerArr(); } /**僵尸生成回调 */ private addZombieCbk() { this.roles[1] = this.getZombies(); } /**僵尸死亡回调 */ private dieZombieCbk() { this.roles[1] = this.getZombies(); } /**生成玩家 * @param id 视图id * @param pos 生成位置 */ private addPlayer(id: number, pos: cc.Vec3) { // cc.log('增加npc', id, pos); let nd = cc.instantiate(this.player_pre); let playerViewCom = nd.getChildByName('view').getComponent(PlayerView); let playerObjCom = nd.getComponent(PlayerObject); nd.setPosition(pos); this.addBuffItem(id, nd); this.object_parent.addChild(nd); playerObjCom.init(id, this.roles); playerObjCom.setLeader(false); playerViewCom.init(id); gameData.curPeopleNum++; EventManager.emit(EVENT_TYPE.UPDATE_PEOPLE_NUM); this.addPlayerCbk(); return playerObjCom; } addBuffItem(playerID, parent) { var path = null; if (playerID == 13) { path = 'main/egg'; } else if (playerID == 19) { path = 'main/cake'; } if (path) { let effNode = BenzAssetManager.getInstance().getAsset(AssetsHelper.EFF_obtain); let Prefb = cc.instantiate(effNode) as unknown as cc.Node; Prefb.parent = parent; Prefb.y = 100; let node = new cc.Node node.parent = Prefb; node.addComponent(cc.Sprite); bundleManager.setBundleFrame('UI', path, node); } } /**生成僵尸 * @param id 视图id * @param pos 生成位置 */ private addZombie(id: number, pos: cc.Vec3) { let nd = null; if (this.zombieNodePool.size() > 0) { nd = this.zombieNodePool.get(); } else { nd = cc.instantiate(this.zombie_pre); } let comp = nd.getComponent(ZomBieObject); this.object_parent.addChild(nd); comp.init(id, pos, this.roles, this.isPause); this.addZombieCbk(); } /**随机从解锁人员里选出领队 */ private randomLeader() { let newArr: cc.Node[] = []; let playerList = this.getPlayerArr(); if (playerList.length == 0) { console.log('所有玩家已死亡'); return; } for (let i = 0; i < playerList.length; i++) { if (playerList[i].getComponent(PlayerObject).isDie == false) { newArr.push(playerList[i]); } } let index = Math.round(Math.random() * newArr.length) - 1; index = index < 0 ? 0 : index; for (let i = 0; i < newArr.length; i++) { let comp = newArr[i].getComponent(PlayerObject); if (i == index) { comp.setLeader(true); } else { comp.setLeader(false); } } console.log('随机生成领队'); } /**检测玩家子弹与僵尸碰撞 */ checkPlayerBulletCrashZombie() { if (gameData.cur_attack_mode == ATTACK_MODE.close) { return; }; let bs = this.getBullets(); let zs = this.getZombies(); for (let i = bs.length - 1; i >= 0; i--) { for (let j = zs.length - 1; j >= 0; j--) { let dis = this.getDis(bs[i], zs[j]); if (dis < 40) { if (!zs[j] || !cc.isValid(zs[j])) { break; } let bc = bs[i].getComponent(BulletObject); let zc = zs[j].getComponent(ZomBieObject); let zv = zc.zombie_view; zv.hitEff(); let hp = zc.zombie_prop.beHurt(bc.damage); if (hp == 0) { //玩家加经验 if (bc.from_p && bc.from_p.isValid) { let curExp = zc.zombie_prop.exp bc.from_p.addExp(curExp); } var curLevel = AccountModel.getInstance().curLevel; if (curLevel > 1) { let x = zs[j].x; let y = zs[j].y; let pos = cc.v3(x, y); gameEventManager.emit(EVENT_TYPE.RESET_ZOMBIE, pos); } this.recoverZombie(zs[j]); zs.splice(j, 1); gameData.curKillZomNum += 1; gameEventManager.emit(EVENT_TYPE.zombie_die); } this.recoverPlayerBullet(bs[i]); bs.splice(i, 1); break; } } } } /** 检测玩家跟僵尸子弹的碰撞 */ checkBulletCrashPlayer() { let bs = this.getZombieBullets(); if (bs.length <= 0) { return; } let wj = this.roles[0]; for (let i = bs.length - 1; i >= 0; i--) { for (let j = wj.length - 1; j >= 0; j--) { let dis = this.getBulletToplayerDis(bs[i], wj[j]); if (dis < 30) { let bc = bs[i].getComponent(zomBiebullet); let zc = wj[j].getComponent(PlayerObject); let zv = zc.player_view; zv.playBeHurt(); let hp = zc.player_prop.beHurt(bc.damage); if (hp == 0) { zc.die(); } bs[i].destroy(); bs.splice(i, 1); break; } } } } /*获取玩家与僵尸子弹的距离**/ getBulletToplayerDis(zombieBullet: cc.Node, player: cc.Node): number { let bulletView = zombieBullet.getComponent(zomBiebullet).view; let wp = bulletView.parent.convertToWorldSpaceAR(cc.v3(bulletView.x, bulletView.y)); let np = zombieBullet.parent.convertToNodeSpaceAR(wp); return np.sub(player.position).mag(); } //检测玩家与道具作用 checkPlayerWithProp() { let len = 100; let players = this.roles[0]; let props = this.prop_parent.children; if (!players || !props || players.length <= 0 || props.length <= 0) { return; } for (let i = players.length - 1; i >= 0; i--) { if (!cc.isValid(players[i])) { continue; } let p_comp = players[i].getComponent(PlayerObject); for (let j = props.length - 1; j >= 0; j--) { if (!cc.isValid(props[j])) { continue } let dis = this.getDis(players[i], props[j]); if (dis < len) { let comp = props[j].getComponent(UIFallitem); switch (comp.getType()) { case 2: { this.getHeal(comp.getValue(), props[j]); AudioManager.play('pickup'); break; } case 3: { this.getBullet(comp.getValue(), props[j]); AudioManager.play('pickup'); break; } case 1: { this.getFood(comp.getValue(), props[j]); AudioManager.play('pickup'); break; } case 4: { if (p_comp.player_prop.player_ID > 10) { continue; } if (this.getWeapon(comp.getID(), comp.getValue(), p_comp, true, props[j])) { AudioManager.play('pickup'); } break; } case 5: { if (p_comp.player_prop.player_ID > 10) { continue; } //获得枪引导 if (AccountModel.getInstance().is_new == 1) { if (AccountModel.getInstance().curLevel == 1 && gameData.cur_attack_mode == ATTACK_MODE.close) { gameEventManager.emit(EVENT_TYPE.getGun_guide); } } if (this.getWeapon(comp.getID(), comp.getValue(), p_comp, false, props[j])) { AudioManager.play('pickup'); } break; } } } } } } propAction(props) { let itemID = props.getComponent(UIFallitem).getID(); let node = new cc.Node; node.addComponent(cc.Sprite); node.parent = this.node; node.setPosition(props.x, props.y); let ResName = itemDtManager.getItemResName(itemID); this.propsNodePool.put(props); bundleManager.setBundleFrame('UI', ResName, node); cc.tween(node) .to(0.2, { scale: 2, position: cc.v3(node.x, node.y + 50) }) .to(0.2, { scale: 0 }) .call(() => { this.propsNodePool.put(node); this.clearPropPool(); }) .start(); } /**检测玩解锁npc */ checkPlayerWithNpc() { let dis = 200; let ps = this.getPlayerArr(); let ns = this.npc_parent.children; for (let j = ns.length - 1; j >= 0; j--) { if (!ps[0]) { return } if (this.getDis(ps[0], ns[j]) < dis) { let npc_id = ns[j].getComponent(NpcObject).view_id; this.addPlayer(npc_id, ns[j].position); ns[j].destroy(); AudioManager.play('getrole'); } } } addHero() { let randomID = Utils.random(49, 52); let players = this.roles[0]; if (players[0]) { this.addPlayer(randomID, players[0].position); } } addHeroById(roleId: number) { let players = this.roles[0]; const randomX = Utils.random(-0.5, 0.5); const randomY = Utils.random(-0.5, 0.5); if (players[0]) { const position = players[0].position; return this.addPlayer(roleId, new cc.Vec3(position.x + randomX, position.y + randomY, 0)); } } /** * 给英雄增加装备 */ addWeapons(id: number, damage: number, is_close: boolean, player?: PlayerObject) { if (player) { this.getWeapon(id, damage, player, is_close); return; } let players = this.roles[0]; let props = this.prop_parent.children; if (!players || !props || players.length <= 0 || props.length <= 0) { return; } // 直到有人拿起武器 for (let i = players.length - 1; i >= 0; i--) { if (!cc.isValid(players[i])) { continue; } let p_comp = players[i].getComponent(PlayerObject); const isEquip = this.getWeapon(id, damage, p_comp, is_close); if (isEquip) { return; } } } /**获取僵尸组 */ getZombies(): cc.Node[] { let zs: cc.Node[] = []; let ch = this.object_parent.children; ch.forEach(function (z: cc.Node) { let comp = z.getComponent(GameObject); if (comp.type == GAME_OBJECT_TYPE.zombie) { zs.push(z); } }); return zs; } /**获取两实体间的距离 */ getDis(obj0: cc.Node, obj1: cc.Node): number { let dis = obj0.position.sub(obj1.position).mag(); return dis; } /**获取食物道具事件回调 */ getFood(food: number, props: cc.Node) { this.propAction(props); gameData.curPowerNum += food; } /** * 进入副本 储存玩家数据 */ layInPlayerDt() { gameData.playerDtList = []; this.roles[0].forEach((node) => { if (!node || !cc.isValid(node)) { return; } let propCom = node.getComponent(PlayerObject).player_prop; let playerDt = propCom.getPlayerDt(); if (playerDt) { gameData.playerDtList.push(propCom.getPlayerDt()); } }) } /** * * @param name 房间名 * @param type 房间类型 */ goDungeon(name: string, type: number) { if (this.mini_map) { this.mini_map.active = false; } // this.layInPlayerDt(type); dungeonManager.open(name, type); levelManager.remove(); } //是否靠近房间 isCloseDungeon() { let playerArr = this.getPlayerArr(); let dungeonList = this.node.$dungeon_parent.children; if (!dungeonList) return; let leave = true; for (let i = 0; i < dungeonList.length; ++i) { for (let j = 0; j < playerArr.length; ++j) { if (playerArr[j].group == 'leader') { let offset = 100; let min = playerArr[j].x >= (dungeonList[i].x - offset); let max = playerArr[j].x <= (dungeonList[i].x + offset); let minY = dungeonList[i].y + 50 >= playerArr[j].y && playerArr[j].y >= dungeonList[i].y - 50 if (minY && min && max) { this.isGoDungeon = true; let name = dungeonList[i].getComponent(dungeonNode).getName(); let type = dungeonList[i].getComponent(dungeonNode).getType(); this.goDungeon(name, type); this.removeNode(); } } } } return false; } removeNode() { let playerList = this.getPlayerArr(); let dogList = this.dogNode() if (playerList.length <= 0) { return; } for (let i = playerList.length - 1; i >= 0; i--) { playerList[i].destroy(); } for (let i = dogList.length - 1; i >= 0; i--) { dogList[i].destroy(); } } dogNode() { let nds: cc.Node[] = []; for (let nd of this.object_parent.children) { if (nd.name == 'dog_obj') { nds.push(nd); } } return nds; } //是否靠近拯救点 isCloseWinNode() { let playerArr = this.getPlayerArr(); let dungeonList = this.node.$winNode; if (!dungeonList) return; for (let j = 0; j < playerArr.length; ++j) { let dis = this.getDis(dungeonList, playerArr[j]); if (dis > 600) { return; } if (dis < 50 && !this.isWin) { this.isWin = true; UITopMenu.getInstance().node.active = false; gameEventManager.emit(EVENT_TYPE.CANT_JOY, false); zjSdk?.gameEnd(() => { UIHelp.ShowUI(UIWinView); }) gameData.playerDtList = []; playerArr.forEach((node) => { let propCom = node.getComponent(PlayerObject).player_prop; let playerDt = propCom.getPlayerDt(); if (playerDt) { gameData.playerDtList.push(propCom.getPlayerDt()); } }) } } return false; } /**获取子弹道具事件回调 */ getBullet(bullet: number, props: cc.Node) { this.propAction(props); gameData.curBulletNum += bullet; this.roles[0].forEach(function (player: cc.Node) { if (player && cc.isValid(player)) { let isleader = player.getComponent(PlayerObject).player_prop.is_leader; if (isleader) { let bulletCom = player.getChildByName('addbulletNum'); bulletCom.active = true; bulletCom.getComponent(cc.Label).string = '+' + bullet setTimeout(() => { bulletCom.active = false; }, 500) return; } } }); } /**获得药箱事件回调 */ getHeal(heal: number, props: cc.Node) { this.propAction(props); let players = this.getPlayerArr(); players.forEach(function (player: cc.Node) { let comp = player.getComponent(PlayerObject); comp.player_prop.healHp(heal, player.getChildByName('view')); }); } /** * 获取武器事件回调 * * props 可能为空 * */ getWeapon(id: number, damage: number, player: PlayerObject, is_close: boolean, props?: cc.Node) { let del = false; let drop: WeaponProp = null; if (is_close) { if (player.player_prop.close_weapon != null) { if (player.player_prop.close_weapon.damage < damage) { //更改近战武器 drop = player.player_prop.close_weapon; player.player_prop.setWeapon(id, true); props && this.propAction(props); del = true; } } else { //更改近战武器 player.player_prop.setWeapon(id, true); props && this.propAction(props); del = true; } } else { if (player.player_prop.remote_weapon != null) { if (player.player_prop.remote_weapon.damage < damage) { //更改远程武器 drop = player.player_prop.remote_weapon; player.player_prop.setWeapon(id, false); props && this.propAction(props); del = true; } } else { //更改远程武器 player.player_prop.setWeapon(id, false); props && this.propAction(props); del = true; } } if (drop != null) { //生成对应id武器道具 let nd = cc.instantiate(this.prop_pre); this.prop_parent.addChild(nd); nd.setPosition(player.node.position); let comp = nd.getComponent(UIFallitem); comp.initItem(drop.id); } return del; } /**玩家远程步枪手枪子弹攻击回调 * @param rad 发射角度 * @param damage 子弹伤害 * @param player 发射者 */ private playerRemoteAttack0(rad: number, damage: number, player: PlayerObject) { if (gameData.curBulletNum == 0) { return; } player.player_view.fireEff(); gameData.curBulletNum--; let b = null; if (this.playerBulletPool.size() > 0) { b = this.playerBulletPool.get(); } else { b = cc.instantiate(this.bullet_pre); } this.object_parent.addChild(b); let com = b.getComponent(BulletObject); let pos = playerActionMgr.getGunHeadPos(); com.init(cc.v3(pos.x, pos.y), rad, damage, player); } /**玩家远程霰弹枪子弹攻击回调 * @param rad 发射角度 * @param damage 子弹伤害 * @param player 发射者 */ private playerRemoteAttack1(rad: number, damage: number, player: PlayerObject) { if (gameData.curBulletNum == 0) { return; } gameData.curBulletNum--; damage *= 4;//单发合成一发,攻击*4 let b = cc.instantiate(this.bullet_pre); this.object_parent.addChild(b); let com = b.getComponent(BulletObject); let pos = playerActionMgr.getGunHeadPos(); com.init(cc.v3(pos.x, pos.y), rad, damage, player); } /**远程肉弹攻击回调 * @param start_pos 开始位置 * @param target_pos 目标位置 */ private zombieRemoteBoom(start_pos: cc.Vec3, target_pos: cc.Vec3, addNum: number, damage: number) { this.schedule(() => { let bullet = BenzAssetManager.getInstance().getAsset(AssetsHelper.PREFAB_ZOMBIE_BULLET); let b = cc.instantiate(bullet) as unknown as cc.Node; this.object_parent.addChild(b); let com = b.getComponent(zomBiebullet); com.init(start_pos, target_pos, damage); }, 0.3, addNum) } //获取玩家列表 getPlayerArr() { let nds: cc.Node[] = []; for (let nd of this.object_parent.children) { if (nd.getComponent(GameObject).type == GAME_OBJECT_TYPE.player) { if (nd.getComponent(PlayerObject).player_prop.cur_state != ROLE_STATE.die) { nds.push(nd); } } } return nds; } /**获取子弹组 */ getBullets(): cc.Node[] { let bs: cc.Node[] = []; let ch = this.object_parent.children; ch.forEach(function (b: cc.Node) { let comp = b.getComponent(GameObject); if (comp.type == GAME_OBJECT_TYPE.bullet) { bs.push(b); } }); return bs; } /** 僵尸子弹组 */ getZombieBullets(): cc.Node[] { let bs: cc.Node[] = []; let ch = this.object_parent.children; ch.forEach(function (b: cc.Node) { let comp = b.getComponent(GameObject); if (comp.type == GAME_OBJECT_TYPE.zombieBullet) { bs.push(b); } }); return bs; } /**摄像机跟随 */ private cameraTrack(dt: number) { // setTimeout(() => { let multiple = 1; let dis = 500 * multiple; let target: cc.Node = null; for (let p of this.object_parent.children) { let comp = p.getComponent(NodeMove); if (comp != null && comp.enabled) { target = p; break; } } if (target != null) { let v_sub = target.position.sub(this.camera.position); // if (v_sub.mag() > dis) { // v_sub = v_sub.normalize().mul(dis); // } this.camera.setPosition(this.camera.position.add(v_sub.mul(0.02 * 2.5))); } // }, 0.1) } /**运行玩家buff */ playerRunBuff(dt: number) { this.buff_timer += dt; if (this.buff_timer > this.buff_dur) { this.buff_timer = 0; let self = this; let players: PlayerObject[] = []; this.getPlayerArr().forEach(function (nd: cc.Node) { players.push(nd.getComponent(PlayerObject)); }); players.forEach(function (player: PlayerObject) { let b_id = player.player_prop.buff_id; if (b_id == 0) { return; } let buff = self.buffs[b_id - 1]; players.forEach(function (i_player, idx, players) { i_player.player_prop.healHp(buff[1], players[idx].node.getChildByName('view')); }); if (buff[0] > 0) { gameData.curBulletNum += buff[0]; } if (buff[2] > 0) { gameData.curPowerNum += buff[2]; } }); } } /**性能优化 */ fast() { let zs = this.getZombies(); let mapBg = this.node.$map_parent.$map.$bg.children; let mapCar = this.node.$map_parent.$map.$car.children; let mapUi = this.node.$map_parent.$map.$ui.children; let mapBuild = this.node.$map_parent.$map.$buildding.children; this.zombieActive(zs); this.nodeIsActive(mapBg); this.nodeIsActive(mapCar); this.nodeIsActive(mapUi); this.nodeIsActive(mapBuild); } zombieActive(zs) { if (!zs) { return }; let self = this; let winSize = cc.winSize.width; zs.forEach(function (nd: cc.Node) { let dis = self.getDis(nd, self.camera); if (dis > winSize) { if (nd.active == false) { return } nd.active = false; } else { if (nd.active == true) { return } nd.active = true; } }) } nodeIsActive(nodeArr: cc.Node[]) { if (!nodeArr) { return }; let self = this; let sw = (cc.winSize.width / 2) + 120; nodeArr.forEach(function (nd: cc.Node) { let rl = Math.sqrt(Math.pow(nd.width, 2) + Math.pow(nd.height, 2)) / 2; if (self.getDis(nd, self.camera) > rl + sw) { if (nd.active == true) { nd.active = false; } } else { if (nd.active == false) { nd.active = true; } } }); } }