123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- import { _decorator, Component, Node, log, AnimationComponent, RigidBodyComponent, Vec3, find, ParticleSystemComponent, instantiate, Prefab, loader } from 'cc';
- import { SoundManager } from '../../../../engines/sounds/SoundManager';
- import CCSAnimationUtils from '../../../../engines/utils/CCSAnimationUtils';
- import { MathUtils } from '../../../../engines/utils/MathUtils';
- import GameConfigManager from '../../../models/GameConfigManager';
- import { GameController } from '../GameController';
- import { MonsterHP } from './MonsterHP';
- import { MonsterHPUIPool } from './MonsterHPUIPool';
- const { ccclass, property } = _decorator;
- @ccclass('MonsterBase')
- export class MonsterBase extends Component {
- config:any;
- monsterConfig:any;
-
- hpView:MonsterHP;
- /**
- * 血量
- */
- hp:number=0;
- /**
- * 最大血量
- */
- maxHP:number=0;
- /**
- * 伤害
- */
- damage:number;
- private speedVec3:Vec3=new Vec3();
- private speedVec3N:Vec3=new Vec3();
- private endNode:Node;
-
- private animation:AnimationComponent;
- /**
- * 0 移动 1攻击 2 被攻击 3死亡
- */
- private state:number=0;
- /**
- * 攻击类型 0攻击栅栏 1攻击玩家
- */
- private attackType:number=0;
- /**
- * 弹痕粒子
- */
- private danHen:ParticleSystemComponent;
-
- start () {
- this.monsterConfig=GameConfigManager.GetMonsterConfig(this.config.monsterId);
- this.hp=this.maxHP=this.config.hp;
- this.damage=this.config.damage;
- this.animation=this.getComponent(AnimationComponent);
- if(this.animation==null){
- throw new Error("动画组件为空!");
- }
- this.InitAnimations();
- this.InitPostitionAndEndPos();
- this.InitScale();
- }
- /**
- * 子节点收集
- * @param root
- * @param list
- */
- private getChildren(root:Node,list:Node[]):void{
- root.children.forEach(element => {
- list.push(element);
- if(element.children.length>0){
- this.getChildren(element,list);
- }
- });
- }
- /**
- * 动画数据初始化
- */
- private InitAnimations():void{
- CCSAnimationUtils.SetAnimationSpeed(this.animation,this.monsterConfig.moveAnimation,this.monsterConfig.moveAnimationSpeed);
- CCSAnimationUtils.SetAnimationSpeed(this.animation,this.monsterConfig.attackAnimation,this.monsterConfig.attackAnimationSpeed);
- // CCSAnimationUtils.SetAnimationEvent(this.animation,this.monsterConfig.attackAnimation,this.monsterConfig.attackAnimationEvents);
- CCSAnimationUtils.SetAnimationSpeed(this.animation,this.monsterConfig.dieAnimation,this.monsterConfig.dieAnimationSpeed);
- }
- /**
- * 初始化开始位置及结束位置
- */
- private InitPostitionAndEndPos():void{
- //左
- if(this.config.startPos==0){
- this.endNode=GameController.single.leftEndNode;
- }else if(this.config.startPos==1){//中
- this.endNode=GameController.single.middleEndNode;
- }else{//右
- this.endNode=GameController.single.rightEndNode;
- }
- Vec3.subtract(this.speedVec3N,this.endNode.worldPosition,this.node.worldPosition);
- this.speedVec3N.normalize();
- this.Move();
- }
- /**
- * 初始化Scale
- */
- private InitScale():void{
- let scale:Vec3=this.node.scale;
- scale.x*=this.monsterConfig.scale.x;
- scale.y*=this.monsterConfig.scale.y;
- scale.z*=this.monsterConfig.scale.z;
- this.node.setScale(scale);
- }
-
- update (deltaTime: number) {
- if(GameController.single.GameOver){
- return;
- }
- if(GameController.single.paused){
- this.animation.pause();
- return;
- }else{
- this.animation.resume();
- }
- if(this.isDie){
- return;
- }
- let dis:number;
- if(GameController.single.fence.IsDie==false){
- dis=Vec3.distance(GameController.single.fence.node.worldPosition,this.node.worldPosition);
- if(dis<2){
- this.Attack(0);
- }else{
- this.Move();
- }
- }else{
- dis=Vec3.distance(this.endNode.worldPosition,this.node.worldPosition);
- //到达终点
- if(dis<0.5){
- //攻击
- this.Attack(1);
- return;
- }else{
- this.Move();
- }
- }
- if(this.state==0){
- this.MoveUpdate(deltaTime);
- }
- }
- /**
- * 开始移动
- */
- Move():void{
- if(this.state>0){
- return;
- }
- this.removeAllAnimationEvent();
- this.state=0;
- }
- private MoveUpdate(deltaTime:number):void{
- this.animation.crossFade(this.monsterConfig.moveAnimation);
- let currentPos:Vec3=this.node.position;
- Vec3.multiplyScalar(this.speedVec3,this.speedVec3N,this.monsterConfig.moveSpeed*deltaTime);
- Vec3.add(currentPos,currentPos,this.speedVec3);
- this.node.setPosition(currentPos);
- }
- /**
- * 攻击
- */
- private Attack(attackType:number):void{
- this.attackType=attackType;
- if(this.state==1||this.state==2){
- return;
- }
- this.state=1;
- this.removeAllAnimationEvent();
- this.animation.on(AnimationComponent.EventType.FINISHED,this.AttackComplete,this,true);
- this.animation.play(this.monsterConfig.attackAnimation);
- }
- // /**
- // * 攻击生效帧回调
- // */
- // AttackDamageFrame():void{
- // console.log(this.config.mId+"攻击"+this.attackType);
- // GameController.single.MonsterAttack(this.attackType,this.config.damage);
- // }
- private AttackComplete():void{
- console.log(this.config.mId+"攻击"+this.attackType);
- GameController.single.MonsterAttack(this.attackType,this.config.damage);
- this.state=0;
- this.Move();
- }
- /**
- * 受伤
- * @param value
- */
- Damage(value:number):void{
- if(this.hp==0){
- return;
- }
- this.hp-=value;
- if(this.hp<=0){
- this.hp=0;
- this.Die();
- }else{
- if(this.state==3){
- return;
- }
- this.state=2;
- this.removeAllAnimationEvent();
- if(this.animation==null){
- return;
- }
- this.animation.on(AnimationComponent.EventType.FINISHED,this.DamageComplete,this,true);
- this.animation.play(this.monsterConfig.damageAnimation);
- }
- //音效
- let v:number=Math.random()*10;
- let url:string;
- if(v<5){
- url="sounds/zombieDamage";
- }else{
- url="sounds/zombieDamage1";
- }
- if(SoundManager.single.ChannelIsPlaying(this.config.id)){
- SoundManager.single.PlaySound(this.config.id,url);
- }
- //弹痕
- if(this.danHen==null){
- let prefab:Prefab=loader.getRes(this.monsterConfig.damageParticle);
- let danhenNode:Node=instantiate(prefab);
- this.danHen=danhenNode.getComponent(ParticleSystemComponent);
- this.node.addChild(danhenNode);
- }
- this.danHen.node.active=true;
- let pos:Vec3=this.danHen.node.position;
- pos.x=MathUtils.RandomRange(-0.08,0.08);
- pos.y=MathUtils.RandomRange(0.5,0.8);
- this.danHen.node.position=pos;
- this.danHen.stop();
- this.danHen.play();
- }
-
- private DamageComplete():void{
- this.state=0;
- this.Move();
- }
- Die():void{
- if(this.state==3){
- return;
- }
- this.state=3;
- SoundManager.single.PlaySound(this.config.id,"sounds/zombieDie");
- this.removeAllAnimationEvent();
- this.animation.on(AnimationComponent.EventType.FINISHED,this.DieComplete,this,true);
- this.animation.play(this.monsterConfig.dieAnimation);
- }
- private DieComplete():void{
- this.node.active=false;
- this.node.destroy();
- }
- onDestroy():void{
- SoundManager.single.ClearSound(this.config.id);
- this.danHen=null;
- MonsterHPUIPool.Recycle(this.hpView);
- this.hpView=null;
- }
- private removeAllAnimationEvent():void{
- if(this.animation==null){
- return;
- }
- if(this.animation.hasEventListener(AnimationComponent.EventType.FINISHED,this.DamageComplete,this)){
- this.animation.off(AnimationComponent.EventType.FINISHED,this.DamageComplete,this);
- }
- if(this.animation.hasEventListener(AnimationComponent.EventType.FINISHED,this.AttackComplete,this)){
- this.animation.off(AnimationComponent.EventType.FINISHED,this.AttackComplete,this);
- }
- if(this.animation.hasEventListener(AnimationComponent.EventType.FINISHED,this.DieComplete,this)){
- this.animation.off(AnimationComponent.EventType.FINISHED,this.DieComplete,this);
- }
- }
- get isDie():boolean{
- if(this.hp<=0){
- return true;
- }
- return false;
- }
- /**
- * 血条显示位置
- */
- get hpSocket():Node{
- let socket:Node=find("RootNode/Root/HpSocket",this.node);
- return socket?socket:this.node;
- }
- }
|