123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624 |
- import { AnimationComponent, CameraComponent, director, find, GraphicsComponent, instantiate, loader, Node, Prefab, Vec3, _decorator } from 'cc';
- import { EventDispatcher } from '../../../engines/events/EventDispatcher';
- import { GUIManager } from '../../../engines/gui/GUIManager';
- import { CameraUtils } from '../../../engines/utils/CameraUtils';
- import GameConfigManager from '../../models/GameConfigManager';
- import { GameModel } from '../../models/GameModel';
- import { FightingScene } from '../../scenes/FightingScene';
- import { UIConst } from '../UIConst';
- import { FenceBase } from './fences/FenceBase';
- import { FightingMediator } from './FightingMediator';
- import { MonsterBase } from './monsters/MonsterBase';
- import { MonsterHPUIPool } from './monsters/MonsterHPUIPool';
- import { SkillBase } from './skills/SkillBase';
- import SkillManager from './skills/SkillManager';
- import AutomaticFifleWeapon from './weapons/AutomaticFifleWeapon';
- import { SingleShotWeapon } from './weapons/SingleShotWeapon';
- import { WeaponBase } from './weapons/WeaponBase';
- const { ccclass, property } = _decorator;
- export class GameController extends EventDispatcher{
- public weapon:WeaponBase;
- public fence:FenceBase;
- public camera:CameraComponent;
- public leftEndNode:Node;
- public middleEndNode:Node;
- public rightEndNode:Node;
- public leftStartNode:Node;
- public middleStartNode:Node;
- public rightStartNode:Node;
- /**
- * 当前正在运行的技能
- */
- public currentSkill:SkillBase;
- /**
- * 游戏结束
- */
- public GameOver:boolean=true;
- public leftMonsterList:MonsterBase[];
- public middleMonsterList:MonsterBase[];
- public rightMonsterList:MonsterBase[];
- /**
- * 怪物弹痕预制体
- */
- public monsterZhouDanPrefab:Prefab;
- /**
- * 怪物血条层
- */
- public monsterHPUILayer:Node;
- /**
- * 关卡配置
- */
- public levelConfig:any;
- private monstersConfig:any[];
- /**
- * 这一关怪物数量
- */
- public monsterTotalCount:number;
- /**
- * 本局游戏时间
- */
- private runTime:number=0;
- private fightingMediator:FightingMediator;
- constructor()
- {
- super();
- this.leftMonsterList=[];
- this.middleMonsterList=[];
- this.rightMonsterList=[];
- }
- /**
- * 初始化
- * @param leftHand
- * @param rightHand
- */
- Init(uiMediator:FightingMediator):void{
- this.fightingMediator=uiMediator;
- let sceneNode:Node=find("FightingScene");
- if(sceneNode==null){
- throw new Error("找不到战斗场景节点!");
- }
- let sceneScript:FightingScene=sceneNode.getComponent(FightingScene);
- if(sceneNode==null){
- throw new Error("战斗场景上没有挂载FightingScene脚本!");
- }
- this.camera=sceneScript.camrea;
- this.leftStartNode=sceneScript.LeftStartPos;
- this.middleStartNode=sceneScript.MiddleStartPos;
- this.rightStartNode=sceneScript.RightStartPos;
- this.leftEndNode=sceneScript.LeftEndPos;
- this.middleEndNode=sceneScript.MiddleEndPos;
- this.rightEndNode=sceneScript.RightEndPos;
- this.monsterZhouDanPrefab=sceneScript.monsterZhouDanPrefab;
- this.weapon=this.CreateWeapon(sceneScript.leftHand,sceneScript.rightHand);
- this.StartGame();
- }
- /**
- * 改变栅栏
- */
- ChangeFence():void{
- this.GameOver=true;
- this.paused=true;
- let config:any=GameConfigManager.GetFenceConfig(GameModel.single.fenceId);
- // let prefab:Prefab=loader.getRes(config.prefab);
- // if(prefab==null){
- // throw new Error("栅栏资源未加载!");
- // }
- loader.loadRes(config.prefab,Prefab,(err,prefab:Prefab)=>{
- if(err!=null){
- throw new Error("栅栏加载出错!");
- }
- //如果老的存在,先清理
- if(this.fence&&this.fence.node!=null){
- this.fence.node.destroy();
- this.fence=null;
- }
- let fenceNode:Node=instantiate(prefab);
- this.fence=fenceNode.getComponent(FenceBase);
- this.fence.config=config;
- this.fence.node.setPosition(new Vec3(0,0,-2));
- this.scene.addChild(fenceNode);
- this.GameOver=false;
- this.paused=false;
- });
- }
- /**
- * 开始游戏
- */
- StartGame():void{
- GameModel.single.killCount=0;
- GameModel.single.angerCount=0;
- GameModel.single.integral=0;
- //重置技能
- this.SkillReset();
- this.levelConfig=GameConfigManager.GetLevelConfig(GameModel.single.currentLevel);
- this.runTime=0;
- //复制一份配置
- this.monstersConfig=GameConfigManager.CreateMonsterByList(this.levelConfig.monsters,this.runTime);
- this.monsterTotalCount=this.monstersConfig.length;
- //直接重置子弹数量
- this.weapon.bulletCount=GameConfigManager.GetWeaponConfig(GameModel.single.currentWeaponId).clip;
- //初始化栅栏
- this.ChangeFence();
- }
- /**
- * 游戏结束
- * @param state 0 胜利 1 失败 2正常退出
- */
- OnGameOver(state:number):void{
- //清理怪物
- this.ClearMonsters();
- //清理武器
- this.weapon.Destroy();
- //销毁栅栏
- if(this.fence.node){
- this.fence.node.destroy();
- }
- if(state==0){
- GUIManager.single.Show(UIConst.GAME_OVER_UI,true);
- }else if(state==1)
- {
- GUIManager.single.Show(UIConst.GAME_OVER_UI,false);
- }
- GUIManager.single.Hide(UIConst.FIGHTING_UI);
- this.GameOver=true;
- }
- paused:boolean;
- /**
- * 暂停游戏
- */
- PauseGame():void{
- this.paused=true;
- }
- /**
- * 继续游戏
- */
- PlayGame():void{
- this.paused=false;
- }
- /**
- * 重玩
- */
- Replay():void{
- this.StartGame();
- GUIManager.single.Show(UIConst.FIGHTING_UI);
- }
- /**
- * 开始下一关
- */
- PlayNextLevel():void{
- //清空试用栅栏
- GameModel.single.trialFenceId=-1;
- console.log(GameModel.single.currentLevel);
- this.StartGame();
- GUIManager.single.Show(UIConst.FIGHTING_UI);
- }
- /**
- * 清理怪物
- */
- ClearMonsters():void{
- this.clearMonsterList(this.leftMonsterList);
- this.clearMonsterList(this.middleMonsterList);
- this.clearMonsterList(this.rightMonsterList);
- }
- private clearMonsterList(list:MonsterBase[]):void{
- if(list.length>0){
- list.forEach(element => {
- if(element.node!=null&&element.node.isValid){
- element.node.destroy();
- }
- });
- }
- list.length=0;
- }
- TryFire(fireKey:number):void{
- if(this.currentSkill!=null&&this.currentSkill.unController){
- return;
- }
- if(fireKey==0){
- this.weapon.StopFire();
- }else{
- this.weapon.StartFire(fireKey);
- }
- }
- /**
- * 使用技能
- */
- UseSkill():void{
- if(this.currentSkill!=null){
- return;
- }
- //重置子弹数量
- this.weapon.bulletCount=this.weapon.maxBulletCount;
-
- this.currentSkill=SkillManager.single.Create(this.weapon.weaponConfig.skill);
- this.currentSkill.config=GameConfigManager.GetSkillConfig(this.weapon.weaponConfig.skill);
- this.currentSkill.AddEvent(SkillBase.SKILL_COMPLETE,this,this.SkillReset,0);
- this.currentSkill.UseSkill(this.weapon,this);
- GameModel.single.angerCount=0;
- }
- /**
- * 清除技能
- */
- private SkillReset():void{
- if(this.currentSkill!=null){
- this.currentSkill.RemoveEvent(SkillBase.SKILL_COMPLETE,this,this.SkillReset);
- this.currentSkill.Dispose();
- this.currentSkill=null;
- }
- }
- Update(dt:number):void{
- if(this.paused){
- return;
- }
- if(this.GameOver){
- return;
- }
- if(this.currentSkill!=null){
- this.currentSkill.Update(dt);
- }
- this.runTime+=dt*1000;
- this.weapon.Update(dt);
- this.CheckMonster();
- }
- get drawingBoard():GraphicsComponent{
- return this.fightingMediator.DrawingBoard;
- }
-
- /**
- * 检测怪物
- */
- CheckMonster():void{
- if(this.monstersConfig.length>0){
- let config:any;
- let monster:Node;
- for (let index = 0; index < this.monstersConfig.length; index++) {
- config = this.monstersConfig[index];
- if(this.runTime>=config.createTime){
- //根据配置创建怪物
- monster=this.CreateMonster(config);
- this.scene.addChild(monster);
- this.monstersConfig.splice(index,1);
- index--;
- }
- }
- }
- if(this.monstersConfig.length==0&&this.leftMonsterList.length==0&&this.middleMonsterList.length==0&&this.rightMonsterList.length==0){
- //全部怪物死亡
- console.log("通关");
- GameModel.single.currentLevel++;
- if(GameModel.single.currentLevel>=GameConfigManager.MaxLevel){
- GameModel.single.currentLevel=GameConfigManager.MaxLevel;
- }
- this.OnGameOver(0);
- }
- }
-
- /**
- * 怪物攻击
- * @param damage 伤害
- */
- MonsterAttack(attackType:number,damage:number):void{
- if(this.GameOver){
- return;
- }
- if(attackType==0){
- if(this.fence.IsDie==false){
- this.fence.Damage(damage);
- let cameraUtils:CameraUtils=this.camera.getComponent(CameraUtils);
- if(cameraUtils!=null){
- cameraUtils.shake(500,new Vec3(-0.01,-0.01,0),new Vec3(0.01,0.01,0));
- }
- }
- }else{
- this.OnGameOver(1);
- }
- }
- /**
- * 是否有怪物可攻击 -1没有可攻击怪 0 左边 1中间 2右边
- */
- public get FindAttackMonsterPosType():number{
- let leftDis:number=this.NearestDistance(this.leftMonsterList);
- let middleDis:number=this.NearestDistance(this.middleMonsterList);
- let rightDis:number=this.NearestDistance(this.rightMonsterList);
- if(leftDis<middleDis&&leftDis<rightDis){
- return 0;
- }
- if(middleDis<leftDis&&middleDis<rightDis){
- return 1;
- }
- if(rightDis<leftDis&&rightDis<middleDis){
- return 2;
- }
- return -1;
- }
- /**
- * 就算这一路中可攻击怪的最近距离
- * @param monsterList
- */
- private NearestDistance(monsterList:MonsterBase[]):number{
- let monster:MonsterBase;
- let endNode:Node;
- let minDis:number=Number.MAX_VALUE;
- let dis:number;
- for (let index = 0; index < monsterList.length; index++) {
- monster = monsterList[index];
- if(monster.config.startPos==0){
- endNode=this.leftEndNode;
- }else if(monster.config.startPos==1){
- endNode=this.middleEndNode;
- }else{
- endNode=this.rightEndNode;
- }
- dis=Vec3.distance(monster.node.worldPosition,endNode.worldPosition);
- if(dis<=this.weapon.weaponConfig.attackDistance){
- if(dis<minDis){
- minDis=dis;
- }
- }
- }
- return minDis;
- }
- /**
- * 武器攻击
- */
- WeaponAttack():void{
- //只要开了第一枪就不算新玩家了
- GameModel.single.isNewPlayer=false;
-
- let monsterList:MonsterBase[];
- let monsterLists:Array<Array<MonsterBase>>=[];
- //攻击1条路
- if(this.weapon.weaponConfig.attackRange==1){
- if(this.weapon.fireKey==1){
- monsterList=this.leftMonsterList;
- }else if(this.weapon.fireKey==2){
- monsterList=this.middleMonsterList;
- }else{
- monsterList=this.rightMonsterList;
- }
- if(monsterList.length==0){
- return;
- }
- monsterList.sort(this.monsterSortFunc);
- monsterLists.push(monsterList);
- }else if(this.weapon.weaponConfig.attackRange==2){//攻击2条路
- //左
- if(this.weapon.fireKey==1){
- if(this.leftMonsterList.length>0){
- this.leftMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.leftMonsterList);
- }
- if(this.middleMonsterList.length>0){
- this.middleMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.middleMonsterList);
- }
- }else if(this.weapon.fireKey==2){//中
- if(this.middleMonsterList.length>0){
- this.middleMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.middleMonsterList);
- }
- //随机左边/右边
- let random:number=Math.random();
- if(random>0.5){
- if(this.rightMonsterList.length>0){
- this.rightMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.rightMonsterList);
- }
- }else{
- if(this.leftMonsterList.length>0){
- this.leftMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.leftMonsterList);
- }
- }
- }else{//右
- if(this.rightMonsterList.length>0){
- this.rightMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.rightMonsterList);
- }
- if(this.middleMonsterList.length>0){
- this.middleMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.middleMonsterList);
- }
- }
- }else{//攻击3条路
- if(this.leftMonsterList.length>0){
- this.leftMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.leftMonsterList);
- }
- if(this.middleMonsterList.length>0){
- this.middleMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.middleMonsterList);
- }
- if(this.middleMonsterList.length>0){
- this.middleMonsterList.sort(this.monsterSortFunc);
- monsterLists.push(this.middleMonsterList);
- }
- }
- //没有任何怪物可以攻击
- if(monsterLists.length==0){
- return;
- }
- //攻击怪物
- let monster:MonsterBase;
- let endNode:Node;
- let index:number=0;
- let total:number=0;
- let dis:number=0;
- monsterLists.forEach(monsterList => {
- //攻击怪物
- index=0;
- total=Math.min(this.weapon.weaponConfig.attackCount,monsterList.length);
- while(index<total){
- monster=monsterList[index];
- if(monster.config.startPos==0){
- endNode=this.leftEndNode;
- }else if(monster.config.startPos==1){
- endNode=this.middleEndNode;
- }else{
- endNode=this.rightEndNode;
- }
- if(Vec3.distance(monster.node.worldPosition,endNode.worldPosition)<=this.weapon.weaponConfig.attackDistance){
- if(this.currentSkill!=null){
- monster.Damage(this.weapon.weaponConfig.damage*this.currentSkill.damage);
- }else{
- monster.Damage(this.weapon.weaponConfig.damage);
- }
- }else{
- console.log("超出枪械攻击距离Miss");
- }
- index++;
- total=Math.min(this.weapon.weaponConfig.attackCount,monsterList.length);
- }
- for (let index = 0; index < monsterList.length; index++) {
- monster = monsterList[index];
- //怪物死亡
- if(monster.isDie){
- //增加怒气
- GameModel.single.angerCount+=monster.config.anger;
- //增加击杀量
- GameModel.single.killCount++;
- //增加积分
- if(monster.config.integral>0){
- GameModel.single.integral+=monster.config.integral;
- }
- //从列表中删除
- monsterList.splice(index,1);
- index--;
- }
- }
- });
- }
- private monsterSortFunc(a:MonsterBase,b:MonsterBase):number{
- if(a.node.position.z>b.node.position.z){
- return -1;
- }else if(a.node.position.z<b.node.position.z){
- return 1;
- }
- return 0;
- }
- /**
- * 根据配置生成怪物
- * @param config
- */
- private CreateMonster(config:any):Node{
- let monsterConfig:any=GameConfigManager.GetMonsterConfig(config.monsterId);
- if(monsterConfig==null){
- throw new Error("找不到怪物配置:"+config.monsterId);
- }
- let prefab:Prefab=loader.getRes(monsterConfig.prefab);
- let monster:Node=instantiate(prefab);
- monster.name="Monster"+config.mId;
- let monsterScript=monster.addComponent(MonsterBase);
- monsterScript.config=config;
- //左
- if(config.startPos==0){
- monster.setPosition(this.leftStartNode.worldPosition);
- this.leftMonsterList.push(monsterScript);
- }else if(config.startPos==1){//中
- monster.setPosition(this.middleStartNode.worldPosition);
- this.middleMonsterList.push(monsterScript);
- }else{//右
- monster.setPosition(this.rightStartNode.worldPosition);
- this.rightMonsterList.push(monsterScript);
- }
- //创建血条
- monsterScript.hpView=MonsterHPUIPool.Create();
- monsterScript.hpView.monster=monsterScript;
- return monster;
- }
- private CreateWeapon(leftHand:AnimationComponent,rightHand:AnimationComponent):any{
- let config:any=GameConfigManager.GetWeaponConfig(GameModel.single.currentWeaponId);
- if(config.fireType==0){
- return new SingleShotWeapon(leftHand,rightHand);
- }else if(config.fireType==1){
- return new AutomaticFifleWeapon(leftHand,rightHand);
- }
- return new SingleShotWeapon(leftHand,rightHand);;
- }
- /**
- * 判断是否需要提示射击
- */
- FireTip(type:number):boolean{
- switch (type) {
- case 1:
- this.leftMonsterList.forEach(element => {
- if(element.monsterConfig.fireTip>0){
- return true;
- }
- });
- break;
- case 2:
- this.middleMonsterList.forEach(element => {
- if(element.monsterConfig.fireTip>0){
- return true;
- }
- });
- break;
- case 3:
- this.rightMonsterList.forEach(element => {
- if(element.monsterConfig.fireTip>0){
- return true;
- }
- });
- break;
- }
- return false;
- }
- get scene(){
- return director.getScene();
- }
- private static instance:GameController;
- public static get single(){
- if(this.instance==null){
- this.instance=new GameController();
- }
- return this.instance;
- }
- }
|