import Armature from "./Armature"; const {ccclass, property} = cc._decorator; /**角色类 */ @ccclass export default class Role extends cc.Component { //动画名称 public static AnimationName_Idle:string = 'idle'; public static AnimationName_Attack:string = 'attack'; public static AnimationName_Defense:string = 'defense'; public static AnimationName_Dodge:string = 'dodge'; public static AnimationName_Hurt:string = 'hurt'; public static FrameEvent_Hit:string = 'hit'; //角色事件 public static EventType_HpChange:string = 'hpChange'; public static EventType_EnduranceChange:string = 'enduranceChange'; public static EventType_Die:string = 'die'; public static EventType_DefenseSuccess:string = 'defenseSuccess'; public static EventType_DodgeSuccess:string = 'dodgeSuccess'; public static EventType_BeHit:string = 'beHit'; public static EventType_NoAction:string = 'noAction'; public static EventType_DoAttack:string = 'doAttack'; public static EventType_DoDodge:string = 'doDodge'; public static EventType_DoDefense:string = 'doDefense'; public static EventType_GetTarget:string = 'getTarget'; //自定义骨架 public armature:Armature; //攻击目标 public target:Role; //角色状态 public attacking:boolean; public defensing:boolean; public dodging:boolean; public hurting:boolean; public direction:number = 1; public pausing:boolean = true; //角色属性 public property_hp:number = 100; public property_maxHp:number = 100; public property_endurance:number = 100; public property_maxEndurance:number = 100; public property_damage:number = 5; public property_enduranceResumeSpeed:number = 3; public onLoad():void{ //动画播放完成时,对应角色状态取消 this.node.on(Armature.EventType_Finish,(animationName:string)=>{ if(animationName==Role.AnimationName_Attack){ this.attacking = false; this.node.emit(Role.EventType_NoAction); return; } if(animationName==Role.AnimationName_Defense){ this.defensing = false; this.node.emit(Role.EventType_NoAction); return; } if(animationName==Role.AnimationName_Dodge){ this.dodging = false; this.node.emit(Role.EventType_NoAction); return; } if(animationName==Role.AnimationName_Hurt){ this.hurting = false; this.node.emit(Role.EventType_NoAction); return; } },this); //监听攻击时的击中帧事件 this.node.on(Armature.EventType_Frame,(animationName:string,processName:string)=>{ if(animationName==Role.AnimationName_Attack&&processName==Role.FrameEvent_Hit){ this.target.hurt(this.property_damage); } },this); } public update(dt:number):void{ //待机条件满足时,自动执行动画 if(!this.attacking&&!this.dodging&&!this.defensing&&!this.hurting){ if(this.armature.getAnimationName()!=Role.AnimationName_Idle){ this.armature.playAnimation(Role.AnimationName_Idle,0); } } if(!this.pausing){ this.resumeEndurance(dt*this.property_enduranceResumeSpeed); } } public setTarget(target:Role):void{ this.target = target; this.node.emit(Role.EventType_GetTarget); } public leftJay():void{ if(this.pausing||this.attacking||this.dodging||this.defensing||this.hurting||!this.isEnduranceEnough(5))return; this.consumeEndurance(5); this.attacking = true; this.direction = 1; this.node.scaleX = this.direction*Math.abs(this.node.scaleX); this.armature.playAnimation(Role.AnimationName_Attack,1); this.node.emit(Role.EventType_DoAttack); } public rightJay():void{ if(this.pausing||this.attacking||this.dodging||this.defensing||this.hurting||!this.isEnduranceEnough(5))return; this.consumeEndurance(5); this.attacking = true; this.direction = -1; this.node.scaleX = this.direction*Math.abs(this.node.scaleX); this.armature.playAnimation(Role.AnimationName_Attack,1); this.node.emit(Role.EventType_DoAttack); } public leftDodge():boolean{ if(this.pausing||this.attacking||this.dodging||this.defensing||this.hurting||!this.isEnduranceEnough(5))return false; this.consumeEndurance(5); this.dodging = true; this.direction = -1; this.node.scaleX = this.direction*Math.abs(this.node.scaleX); this.armature.playAnimation(Role.AnimationName_Dodge,1); this.node.emit(Role.EventType_DoDodge); return true; } public rightDodge():boolean{ if(this.pausing||this.attacking||this.dodging||this.defensing||this.hurting||!this.isEnduranceEnough(5))return false; this.consumeEndurance(5); this.dodging = true; this.direction = 1; this.node.scaleX = this.direction*Math.abs(this.node.scaleX); this.armature.playAnimation(Role.AnimationName_Dodge,1); this.node.emit(Role.EventType_DoDodge); return true; } public defense():void{ if(this.pausing||this.attacking||this.dodging||this.defensing||this.hurting||!this.isEnduranceEnough(20))return; this.consumeEndurance(20); this.defensing = true; this.armature.playAnimation(Role.AnimationName_Defense,1); this.node.emit(Role.EventType_DoDefense); } public hurt(damage:number):boolean{ //检测受伤条件是否满足 if(this.property_hp<=0)return false; if(this.dodging&&this.direction==this.target.direction){ //躲避成功恢复10耐力 this.resumeEndurance(20); this.node.emit(Role.EventType_DodgeSuccess); return; } if(this.defensing){ //防守成功恢复10hp this.resumeHp(10); cc.audioEngine.playEffect(cc.loader.getRes('audio/defense',cc.AudioClip),false); this.node.emit(Role.EventType_DefenseSuccess); return; } //状态纠正 this.hurting = true; this.attacking = false; this.dodging = false; //方向纠正 this.direction = this.target.direction; this.node.scaleX = this.direction*Math.abs(this.node.scaleX); //动画音效 this.armature.playAnimation(Role.AnimationName_Hurt,1); cc.audioEngine.playEffect(cc.loader.getRes('audio/hit',cc.AudioClip),false); this.node.emit(Role.EventType_BeHit); this.consumeHp(damage); return true; } /** * 消耗hp * @param value 消耗值 */ public consumeHp(value:number):void{ if(this.property_hp>0){ let nextHp = this.property_hp - value; if(nextHp>0){ this.property_hp = nextHp; }else{ this.property_hp = 0; } this.node.emit(Role.EventType_HpChange,this.property_hp,this.property_maxHp); //死亡检测 if(this.property_hp==0){ this.node.emit(Role.EventType_Die); } } } /** * 恢复hp * @param value 消耗值 */ public resumeHp(value:number):void{ if(this.property_hpthis.property_maxHp){ this.property_hp = this.property_maxHp; }else{ this.property_hp = nextHp; } this.node.emit(Role.EventType_HpChange,this.property_hp,this.property_maxHp); } } /**判断耐力是否足够 * @param value 对比值 */ public isEnduranceEnough(value:number):boolean{ return this.property_endurance>=value; } /** * 消耗耐力 * @param value 消耗值 */ public consumeEndurance(value:number):void{ this.property_endurance -= value; this.node.emit(Role.EventType_EnduranceChange,this.property_endurance,this.property_maxEndurance); } /** * 恢复耐力 * @param value 恢复值 */ public resumeEndurance(value:number):void{ if(this.property_endurancethis.property_maxEndurance){ this.property_endurance = this.property_maxEndurance; }else{ this.property_endurance = nextEndurance; } this.node.emit(Role.EventType_EnduranceChange,this.property_endurance,this.property_maxEndurance); } } }