123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922 |
- import PlatUtils from "../../common-plugin/Scripts/PlatUtils";
- import { cocosz } from "../Framework/CocosZ";
- import Constant, { ZindexLayer } from "../Framework/Constant";
- import GameDate from "../Game/gameDate";
- import { gameMgr } from "../Game/gameMgr";
- import Person from "../Game/person";
- import { upgradeMgr } from "../Game/UpgradeMgr";
- import Bullet from "./bullet";
- const { ccclass, property } = cc._decorator;
- enum AtkType {
- front = 0,// 前方
- area,// 区域
- charge,// 冲锋
- range,// 远程
- }
- @ccclass
- export default class ZombieBase extends Person {
- @property({ tooltip: "僵尸id" })
- zombieId: number = 0;
- @property({ type: cc.Prefab, tooltip: "子弹预制体", visible() { return [5, 6, 20].includes(this.zombieId) } })
- bullet_prefab: cc.Prefab = null;
- @property({ type: sp.Skeleton, tooltip: "警告圈", visible() { return [5, 6, 20].includes(this.zombieId) } })
- sp_hongzhaquan: sp.Skeleton = null;
- @property({ type: cc.AudioClip, tooltip: "攻击音效1" })
- audio_attack1: cc.AudioClip = null;
- @property({ type: cc.AudioClip, tooltip: "攻击音效2" })
- audio_attack2: cc.AudioClip = null;
- @property({ type: cc.AudioClip, tooltip: "受伤音效" })
- audio_hart: cc.AudioClip = null;
- @property({ type: cc.AudioClip, tooltip: "死亡音效" })
- audio_die: cc.AudioClip = null;
- isBoss: boolean = false;
- protected _aniLayer: cc.Node = null;
- protected _spAni: sp.Skeleton = null;
- protected onLoad(): void {
- this.id = 94;
- // 初始化配置表属性
- if (GameDate.ZombieMess[this.zombieId]) {
- this.totleHp = GameDate.ZombieMess[this.zombieId].hp;
- this.atkNum = GameDate.ZombieMess[this.zombieId].atk;
- this.atkRange = GameDate.ZombieMess[this.zombieId].atkRange;
- this.MoveSpeed = GameDate.ZombieMess[this.zombieId].speed;
- if (PlatUtils.IsOPPO) { this.MoveSpeed /= 2; }
- }
- // 大小缩放
- if (this.isBoss) {
- this.node.scale = 1;
- } else {
- this.node.scale = 0.8;
- }
- // 刚体
- this.rig = this.node.getComponent(cc.RigidBody);
- if (this.rig) { this.rig.linearDamping = 0.2; }
- // spine动画
- this._aniLayer = this.node.getChildByName("aniLayer");
- if (this._aniLayer) {
- this._spAni = this._aniLayer.getChildByName("ani").getComponent(sp.Skeleton);
- }
- // 监听动画
- if (this._spAni) {
- this._spAni.setStartListener(() => { this.startListenerCall() });
- this._spAni.setCompleteListener(() => { this.endListenerCall() });
- }
- }
- protected onDestroy() {
- // 取消监听
- cc.game.targetOff(this);
- }
- protected start(): void { }
- initNode() {
- gameMgr && gameMgr.setMapTs.checkNode(this.node, true);
- // 消息监听
- cc.game.on(Constant.E_GAME_LOGIC, this._onGameMessageHandler, this);
- gameMgr.zombieCurNum++;
- this.node.stopAllActions();
- this.node.zIndex = ZindexLayer.zindex_zombie + this.zombieId;
- this.node.opacity = 255;
- this.atkDir = cc.Vec2.ZERO;
- this.curHp = this.totleHp;
- this.isDeath = false;
- this.isAtk = false;
- this._canAtk = true;
- this.canMoveDir = true;
- this.canMove = true;
- // 播放出场动画
- if (this._spAni && this._spAni.isValid) {
- this._spAni.node.scaleX = Math.abs(this._spAni.node.scaleX);
- this._spAni.node.opacity = 255;
- this._spAni.node.color = cc.Color.WHITE;
- if (this.isBoss) {
- this._spAni.setAnimation(0, "spawn", false);
- this.scheduleOnce(() => {
- // 碰撞体
- let boxCollider = this.node.getComponent(cc.BoxCollider);
- if (boxCollider) boxCollider.enabled = true;
- }, 2)
- } else {
- this._spAni.setAnimation(0, "idle", true);
- // 碰撞体
- let boxCollider = this.node.getComponent(cc.BoxCollider);
- if (boxCollider) boxCollider.enabled = true;
- }
- }
- // 轰炸圈
- if (this.sp_hongzhaquan) {
- this.sp_hongzhaquan.node.setParent(this.node.parent);
- this.sp_hongzhaquan.node.zIndex = ZindexLayer.zinedx_floorTip;
- this.sp_hongzhaquan.setCompleteListener(() => {
- if (this.sp_hongzhaquan && this.sp_hongzhaquan.isValid) {
- this.sp_hongzhaquan.node.active = false;
- }
- })
- }
- // boss
- if (this.isBoss) {
- cc.game.emit(Constant.E_GAME_LOGIC, { type: Constant.E_Commonzombie_Destory });
- gameMgr && gameMgr.showBossHp(1);
- if (this.node.getChildByName("boos")) this.node.getChildByName("boos").active = true;
- }
- }
- putNodePool() {
- // 取消监听
- cc.game.targetOff(this);
- // boss
- if (this.isBoss) {
- // boss光影
- if (this.node.getChildByName("boos")) this.node.getChildByName("boos").active = false;
- // boss边界
- if (gameMgr) {
- gameMgr && gameMgr.showBossHp(0);
- if (gameMgr.boss_border && cc.isValid(gameMgr.boss_border)) {
- gameMgr.boss_border.destroy();
- gameMgr.boss_border = null;
- }
- }
- this.isBoss = false;
- }
- // 轰炸圈
- if (this.sp_hongzhaquan && this.sp_hongzhaquan.isValid) {
- this.sp_hongzhaquan.node.setParent(this.node);
- this.sp_hongzhaquan.node.active = false;
- }
- gameMgr.zombieCurNum--;
- gameMgr && gameMgr.isValid && gameMgr.nodePut(this.node.name, this.node);
- }
- startListenerCall() {
- if (this._spAni.animation.includes("spawn")) {
- this._spAni.timeScale = 0.4;
- this.scheduleOnce(() => { this._spAni.timeScale = 1; }, 1)
- this.canMoveDir = false;
- // 出场方向
- let fromPos = this.node.getPosition();
- let toPos = gameMgr.playerTs.node.getPosition();
- let div = toPos.subSelf(fromPos);
- this._spAni.node.scaleX = (div.x > 0 ? 1 : -1) * Math.abs(this._spAni.node.scaleX);
- }
- else if (this._spAni.animation.includes("attack")) {
- this.isAtk = true;
- this.canMoveDir = false;
- if ([8, 9, 18].includes(this.zombieId) && this._spAni.animation == "attack2") {
- this.speedRate *= 2.5;
- this.udpateRBody(this.moveDir);
- this.scheduleOnce(() => {
- this.speedRate /= 2.5;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }, 0.2)
- } else if ([10, 11, 12, 13].includes(this.zombieId) && this._spAni.animation == "attack2") {
- this.speedRate *= 3;
- this.udpateRBody(this.moveDir);
- this.scheduleOnce(() => {
- this.speedRate /= 3;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }, 0.2)
- } else if ([14, 19].includes(this.zombieId) && this._spAni.animation.includes("attack")) {
- this.speedRate *= 3;
- this.udpateRBody(this.moveDir);
- this.scheduleOnce(() => {
- this.speedRate /= 3;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }, 0.2)
- } else if (this.zombieId == 15 && this._spAni.animation == "attack") {
- this.speedRate *= 3;
- this.udpateRBody(this.moveDir);
- this.scheduleOnce(() => {
- this.speedRate /= 3;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }, 0.4)
- } else if (this.zombieId == 16 && this._spAni.animation == "attack") {
- this.speedRate *= 2;
- this.udpateRBody(this.moveDir);
- this.scheduleOnce(() => {
- this.speedRate /= 2;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }, 0.3)
- } else if (this.zombieId == 17 && this._spAni.animation.includes("attack")) {
- this.speedRate *= 2;
- this.udpateRBody(this.moveDir);
- this.scheduleOnce(() => {
- this.speedRate /= 2;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }, 0.3)
- } else {
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }
- }
- else if (this._spAni.animation.includes("jump_up")) {
- this.canMoveDir = false;
- }
- }
- endListenerCall() {
- if (this._spAni.animation.includes("spawn")) {
- this._spAni.setAnimation(0, "idle", true);
- this.canMoveDir = true;
- this.updateMove();
- this.updatePerson();
- this.udpateRBody(this.moveDir);
- } else if (this._spAni.animation.includes("attack")) {
- this._spAni.setAnimation(0, "idle", true);
- this.isAtk = false;
- this.canMoveDir = true;
- this.updateMove();
- this.updatePerson();
- this.udpateRBody(this.moveDir);
- this.atkDir = cc.Vec2.ZERO;
- } else if (this._spAni.animation.includes("jump_down")) {
- this._spAni.setAnimation(0, "idle", true);
- this.canMoveDir = true;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir);
- }
- }
- /** 消息 */
- private _onGameMessageHandler(event: any) {
- switch (event.type) {
- // 清除所有僵尸
- case Constant.E_Allzombie_Destory: {
- this.hart(9999999, null, null, true, true, cc.Color.WHITE, true);
- break;
- }
- // boss出现清除普通僵尸
- case Constant.E_Commonzombie_Destory: {
- if (!this.isBoss) {
- cc.tween(this.node).to(0.3, { opacity: 1 }, { easing: "fade" }).call(() => { this.putNodePool(); }).start();
- }
- break;
- }
- }
- }
- private _divToPlayer: cc.Vec2 = cc.Vec2.ZERO;
- protected _time: number = -1;
- lateUpdate(dt: number): void {
- if (this.isDeath || cocosz.isPause || !gameMgr.isGameStart || gameMgr.isWin || gameMgr.isFail) {
- this.udpateRBody(cc.Vec2.ZERO);
- return;
- }
- this._time++;
- if (this._time % 15 == 0) {
- if (this._time % 30 == 0) {
- this.updateDiv();
- this.updateMove();
- }
- this.updateAtk();
- this.updateAni();
- this.updatePerson();
- this.udpateRBody(this.moveDir);
- }
- }
- updateDiv() {
- let fromPos = this.node.getPosition();
- let toPos = gameMgr.playerTs.node.getPosition();
- this._divToPlayer = toPos.subSelf(fromPos);
- // 超出屏幕距离删除
- if (!this.isBoss && this._divToPlayer.mag() > cc.winSize.height / 2 / gameMgr.mainCamera.zoomRatio) {
- this.putNodePool();
- }
- }
- /** 更新移动 */
- updateMove() {
- if (this.rig.type == cc.RigidBodyType.Dynamic) {
- if (this.canMove && this.canMoveDir) {
- // 有目标
- if (gameMgr.playerTs) {
- // 玩家存活
- if (!gameMgr.playerTs.isDeath) {
- // 跳跃
- if (this.zombieId == 3 && Math.random() < 0.2) {
- if (!this._spAni.animation.includes("jump")) {
- this._spAni.setAnimation(0, "jump_up", false);
- this._spAni.addAnimation(0, "jump_down", false);
- this.moveDir = this._divToPlayer.normalize();
- }
- }
- // 朝着玩家移动
- else if (this._divToPlayer.mag() >= this.atkRange * 0.8) {
- this.moveDir = cc.v2(this._divToPlayer.normalize()).rotateSelf(Math.PI / 2 * (0.5 - Math.random()));
- }
- // 距离玩家很近,停止移动
- else {
- this.moveDir = cc.Vec2.ZERO;
- }
- }
- // 玩家死亡
- else {
- // 距离很近则远离玩家
- if (this._divToPlayer.mag() < (this.isBoss ? 800 : 1500)) {
- this.moveDir = this._divToPlayer.normalize().negSelf();
- }
- // 随机移动
- else {
- this.moveDir = cc.v2(this._divToPlayer.normalize()).rotateSelf(2 * Math.PI * Math.random());
- }
- }
- }
- }
- }
- }
- /** 更新攻击 */
- updateAtk() {
- // 能否攻击攻击
- if (!this.canAtk()) {
- // ...
- }
- // 新的攻击
- else if (gameMgr.playerTs && !gameMgr.playerTs.isDeath) {
- // 普通距离攻击
- if (this._divToPlayer.mag() < this.atkRange) {
- this.atkDir = this._divToPlayer.normalize();
- this.atk();
- }
- // 远距离攻击
- else {
- switch (this.zombieId) {
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 18: {
- if (this._divToPlayer.mag() < 600 && Math.random() < 0.1 * (this.isBoss ? 2 : 1)) {
- this.atkDir = this._divToPlayer.normalize();
- this.moveDir = this._divToPlayer.normalize()
- this.atk("attack2");
- }
- break;
- }
- case 14:
- case 16:
- case 19: {
- if (this._divToPlayer.mag() < 800 && Math.random() < 0.1 * (this.isBoss ? 2 : 1)) {
- this.atkDir = this._divToPlayer.normalize();
- this.moveDir = this._divToPlayer.normalize()
- this.atk("attack");
- }
- break;
- }
- case 15: {
- if (this._divToPlayer.mag() < 800 && Math.random() < 0.1 * (this.isBoss ? 2 : 1)) {
- this.atkDir = this._divToPlayer.normalize();
- this.moveDir = this._divToPlayer.normalize()
- this.atk("attack");
- }
- break;
- }
- case 16: {
- if (this._divToPlayer.mag() < 600 && Math.random() < 0.1 * (this.isBoss ? 2 : 1)) {
- this.atkDir = this._divToPlayer.normalize();
- this.moveDir = this._divToPlayer.normalize()
- this.atk("attack");
- }
- break;
- }
- case 17: {
- if (this._divToPlayer.mag() < 600 && Math.random() < 0.15 * (this.isBoss ? 2 : 1)) {
- this.atkDir = this._divToPlayer.normalize();
- this.moveDir = this._divToPlayer.normalize()
- this.atk();
- }
- break;
- }
- case 20: {
- if (this._divToPlayer.mag() < 600) {
- if (Math.random() < 0.15 * (this.isBoss ? 2 : 1)) {
- this.atkDir = this._divToPlayer.normalize();
- this.moveDir = this._divToPlayer.normalize()
- this.atk("attack");
- }
- } else if (this.sp_hongzhaquan.isValid && !this.sp_hongzhaquan.node.active && this._divToPlayer.mag() > 800) {
- this.atk("bullet_chui");
- }
- break;
- }
- }
- }
- }
- else {
- this.atkDir = cc.Vec2.ZERO;
- }
- }
- /** 更新动画 */
- updateAni() {
- if (this.isDeath == false) {
- // 暂停
- if (this._spAni.timeScale == 0) {
- // ...a
- }
- // 出场
- else if (this._spAni.animation.includes("spawn")) { }
- // 攻击
- else if (this._spAni.animation.includes("attack")) { }
- // 跳跃
- else if (this._spAni.animation.includes("jump")) { }
- // 其它
- else {
- // 移动
- if (this.moveDir && this.moveDir.mag()) {
- if (this.zombieId == 17) {
- !this._spAni.animation.includes("wing") && this._spAni.setAnimation(0, "wing", true);
- } else {
- !this._spAni.animation.includes("run") && this._spAni.setAnimation(0, "run", true);
- }
- }
- // 待机
- else {
- !this._spAni.animation.includes("idle") && this._spAni.setAnimation(0, "idle", true);
- }
- }
- }
- // 死亡
- else if (this._spAni && this._spAni.skeletonData && this._spAni.skeletonData.skeletonJson.animations["die"]) {
- !this._spAni.animation.includes("die") && this._spAni.setAnimation(0, "die", false);
- }
- }
- updatePerson() {
- let dir = null;
- if (this.atkDir && this.atkDir.mag()) {
- dir = this.atkDir;
- } else if (this.moveDir && this.moveDir.mag()) {
- dir = this.moveDir;
- }
- // 动画方向
- if (dir) {
- this._spAni.node.scaleX = Math.abs(this._spAni.node.scaleX) * (dir.x > 0 ? 1 : -1);
- }
- }
- /** 刚体移动 */
- udpateRBody(dir: cc.Vec2, isMust: boolean = false) {
- if (this.rig.type == cc.RigidBodyType.Dynamic) {
- if (this.canMove || isMust) {
- if (dir && !dir.equals(cc.Vec2.ZERO)) {
- this.rig.linearVelocity = dir.mul(Math.floor(this.MoveSpeed * this.speedRate * (1 - 0.2 * Math.random())));
- } else {
- this.rig.linearVelocity = cc.Vec2.ZERO;
- }
- }
- }
- }
- /** 攻击 */
- atk(aniName: string = "") {
- let atkType: AtkType = AtkType.front;
- let atkRange: number = this.atkRange;
- let atkTime: number = 0;
- let bulletTime: number = 2;
- let clip: cc.AudioClip = this.audio_attack1;
- switch (this.zombieId) {
- case 0:
- case 1: {
- if (Math.random() < 0.5) {
- aniName = "attack";
- } else {
- aniName = "attack2";
- clip = this.audio_attack2;
- }
- atkTime = 0.3;
- break;
- }
- case 2:
- case 3: {
- aniName = "attack1";
- atkTime = 0.3;
- break;
- }
- case 4: {
- aniName = "attack";
- atkTime = 0.3;
- break;
- }
- case 5: {
- aniName = "attack";
- atkTime = 4;
- atkType = AtkType.range;
- bulletTime = 2;
- this._canAtk = false;
- break;
- }
- case 6: {
- aniName = "attack";
- atkTime = 4;
- atkType = AtkType.range;
- bulletTime = 2;
- this._canAtk = false;
- break;
- }
- case 7: {
- break;
- }
- case 8:
- case 18: {
- if (aniName == "attack2") {
- aniName = "attack2";
- atkRange = 300;
- atkTime = 0.3;
- atkType = AtkType.area;
- clip = this.audio_attack2;
- }
- else {
- aniName = "attack";
- atkRange = 350;
- atkTime = 0.3;
- }
- break;
- }
- case 9: {
- if (aniName == "attack2") {
- aniName = "attack2";
- atkRange = 450;
- atkTime = 0.3;
- clip = this.audio_attack2;
- }
- else {
- aniName = "attack";
- atkRange = 350;
- atkTime = 0.3;
- }
- break;
- }
- case 10: {
- if (aniName == "attack2") {
- aniName = "attack2";
- atkRange = 200;
- atkTime = 0.3;
- clip = this.audio_attack2;
- }
- else {
- aniName = "attack";
- atkRange = 200;
- atkTime = 0.3;
- }
- break;
- }
- case 11:
- case 12:
- case 13: {
- if (aniName == "attack2") {
- aniName = "attack2";
- atkRange = 250;
- atkTime = 0.3;
- clip = this.audio_attack2;
- }
- else {
- aniName = "attack";
- atkRange = 250;
- atkTime = 0.3;
- }
- break;
- }
- case 14:
- case 19: {
- if (Math.random() < 0.6) {//冲盾
- aniName = "attack";
- atkRange = 350;
- atkTime = 0.3;
- atkType = AtkType.charge;
- clip = this.audio_attack1;
- }
- else {
- aniName = "attack2";//挥棍
- atkRange = 350;
- atkTime = 0.3;
- clip = this.audio_attack2;
- }
- break;
- }
- case 15: {
- if (aniName == "attack") {//冲锋
- aniName = "attack";
- atkRange = 250;
- atkTime = 0.3;
- atkType = AtkType.charge;
- }
- else {
- aniName = "attack2";//喷火
- atkRange = 400;
- atkTime = 0.3;
- }
- break;
- }
- case 16: {
- if (aniName == "attack" || Math.random() < 0.4) {
- aniName = "attack";
- atkRange = 450;
- atkTime = 0.3;
- atkType = AtkType.area;
- }
- else {
- aniName = "attack2";
- atkRange = 300;
- atkTime = 0.3;
- }
- break;
- }
- case 17: {
- if (Math.random() < 0.5) {
- aniName = "attack";
- atkRange = 200;
- atkTime = 0.3;
- }
- else {
- aniName = "attack2";
- atkRange = 200;
- atkTime = 0.3;
- atkType = AtkType.charge;
- }
- break;
- }
- case 20: {
- if (aniName == "bullet_chui") {
- atkType = AtkType.range;
- aniName = "attack2";
- bulletTime = 1.5;
- }
- else if (aniName == "attack") {
- aniName = "attack";
- atkRange = 500;
- atkTime = 0.3;
- }
- else {
- aniName = "attack2";
- atkRange = 300;
- atkTime = 0.3;
- }
- break;
- }
- }
- // 执行动画
- if (aniName) this._spAni.setAnimation(0, aniName, false);
- if (clip && clip.isValid) gameMgr.playClip(clip, this.node, 0.5);
- // 攻击伤害
- let call = () => {
- if (gameMgr.playerTs && !gameMgr.playerTs.isDeath) {
- let fromPos = this.node.getPosition();
- let toPos = gameMgr.playerTs.node.getPosition();
- let div = toPos.subSelf(fromPos);
- // 判断是否在攻击范围和攻击方向
- if (div.mag() < atkRange) {
- if (atkType == AtkType.front) {
- if (div.mag() < 200 || (div.x * this._spAni.node.scale > 0 && Math.abs(div.y / div.x) < 1.4)) {
- gameMgr.playerTs.hart(1, this.node, div.normalizeSelf(), true);
- }
- } else if (atkType === AtkType.charge) {
- gameMgr.playerTs.hart(1, this.node, div.normalizeSelf(), true);
- this.unschedule(call);
- } else {
- gameMgr.playerTs.hart(1, this.node, div.normalizeSelf(), true);
- }
- }
- };
- }
- if (atkType == AtkType.front || atkType == AtkType.area) {
- this.scheduleOnce(call, atkTime);
- } else if (atkType == AtkType.charge) {
- this.schedule(call, 0, 15);
- } else if (atkType == AtkType.range) {
- let pos_from = this.node.getPosition();
- let pos_to = gameMgr.playerTs.node.getPosition();
- let p2 = cc.v2((pos_from.x + pos_to.x) / 2, pos_from.y + 1500);
- // 生成子弹
- if (this.bullet_prefab) {
- let bullet = cc.instantiate(this.bullet_prefab);
- // 子弹脚本
- let ts = bullet.getComponent(Bullet);
- ts.id = this.id;
- ts.atker = this.node;
- ts.atk = this.atkNum;
- ts.isAngle = true;
- // 子弹属性
- bullet.setPosition(pos_from);
- bullet.zIndex = ZindexLayer.zindex_bullet_sky;
- bullet.parent = this.node.parent;
- // 子弹移动
- cc.tween(bullet)
- .call(() => {
- // 轰炸预警
- if (this.sp_hongzhaquan && this.sp_hongzhaquan.isValid) {
- this.sp_hongzhaquan.node.active = true;
- this.sp_hongzhaquan.node.setPosition(pos_to);
- this.sp_hongzhaquan.setAnimation(0, "animation", false);
- }
- })
- .bezierTo(bulletTime, pos_from, p2, pos_to)
- .call(() => {
- // 生成爆炸子弹
- if (ts.boomEffect) {
- let boom = cc.instantiate(ts.boomEffect)
- boom.parent = ts.node.parent;
- boom.setPosition(ts.node.getPosition());
- let curBullet = boom.getComponent(Bullet);
- curBullet.atk = ts.atk;
- curBullet.atker = ts.atker;
- curBullet.id = ts.id;
- gameMgr.playEffect("explo", boom);
- if (ts.hitEffect) {
- let pos = bullet.getPosition();
- let node = cc.instantiate(ts.hitEffect);
- node.parent = bullet.parent;
- node.setPosition(pos);
- node.zIndex = ZindexLayer.zindex_effect_hit;
- }
- }
- bullet.destroy();
- })
- .start();
- this.scheduleOnce(() => { this._canAtk = true; }, atkTime);
- }
- }
- }
- /** 受伤 */
- hart(atkNum: number, from: cc.Node, dir?: cc.Vec2, isAudio: boolean = true, isEmit: boolean = true, labelColor?: cc.Color, isMust: boolean = false): void {
- if (this.isDeath) return;
- if (isMust == false && cocosz.isPause) return;
- // 防止dir过大
- if (dir && dir.mag() > 3) dir.normalizeSelf().mulSelf(3);
- // 减伤
- atkNum = (1 - this.damageReduction) * atkNum;
- // 数字
- gameMgr.showRoleTip(this.node, Math.min(this.HP, atkNum).toFixed(0), labelColor);
- // 设置血量
- this.HP -= atkNum;
- if (this.isBoss) {
- gameMgr && gameMgr.showBossHp(this.HP / this.totleHp);
- }
- // 受伤效果
- if (!this.isAttackedEffect && this._spAni && this._spAni.node && this._spAni.node.isValid) {
- this.isAttackedEffect = true;
- // 受伤音效
- if (isAudio) {
- // 受伤音效
- if (this.audio_hart) {
- gameMgr.playClip(this.audio_hart, this.node, 0.5);
- }
- }
- // 缩放
- cc.tween(this._aniLayer)
- .to(0.1, { scale: 0.7 }, { easing: "sineIn" })
- .to(0.1, { scale: 1 }, { easing: "sineOut" })
- .call(() => { this.isAttackedEffect = false; })
- .start();
- // 变色
- if (this._canColor) {
- cc.tween(this._spAni.node)
- .to(0.1, { color: new cc.Color(0, 0, 0, 255) })
- .to(0.1, { color: cc.Color.WHITE })
- .start();
- }
- // 后退
- if (this.rig.type == cc.RigidBodyType.Dynamic && dir && this.canMove && this.canMoveDir) {
- // 控制
- this.canMove = false;
- this.scheduleOnce(() => { this.canMove = true; }, 0.1);
- // 后退
- let div = dir.mulSelf(400 * dir.mag()).addSelf(this.rig.linearVelocity);
- let maxDiv: number = this.isBoss ? 100 : 300;
- if (div.mag() > maxDiv) {
- div.normalizeSelf().mulSelf(maxDiv);
- }
- this.rig.linearVelocity = div;
- }
- }
- if (this.HP <= 0) {
- this.death();
- // 死亡事件
- cc.game.emit(Constant.E_GAME_LOGIC, { type: Constant.E_Zombie_Death, node: this.node, from: from })
- } else {
- // 受伤事件
- if (from && isEmit) {
- cc.game.emit(Constant.E_GAME_LOGIC, { type: Constant.E_Zombie_Hart, node: this.node })
- }
- }
- }
-
- /** 死亡 */
- death() {
- this.isAtk = false;
- this.isDeath = true;
- this._spAni.timeScale = 1;
- // 碰撞体
- this.node.getComponents(cc.Collider).forEach(v => v.enabled = false);
- // 隐藏销毁
- cc.tween(this._spAni.node).to(1, { opacity: 0 }).start();
- // 死亡音效
- if (this.audio_die) gameMgr.playClip(this.audio_die, null, 0.2);
- // 死亡效果
- this.updateAni();
- if (this.zombieId < 8) {
- let pre = cocosz.resMgr.getRes("effect_death", cc.Prefab);
- if (pre) {
- let effect_death: cc.Node = cc.instantiate(pre);
- effect_death.zIndex = ZindexLayer.zinedx_floorSkill;
- effect_death.setPosition(this.node.position);
- effect_death.setParent(this.node.parent);
- }
- }
- // 死亡掉落道具
- this.creatItem();
- this.scheduleOnce(() => { this.putNodePool(); }, 2);
- }
- creatItem() {
- if (gameMgr.isWin || gameMgr.isFail) return;
- if (upgradeMgr && upgradeMgr.isValid) {
- let count = (this.zombieId < 8 ? 1 : 10);
- for (let i = 0; i < count; i++) {
- let pos = this.node.getPosition();
- if (i > 0) {
- pos.addSelf(cc.v2(20 * i, 0).rotateSelf(2 * Math.PI * Math.random()));
- }
- upgradeMgr.createJingyan(pos);
- }
- }
- }
- private _canColor: boolean = true;
- frozenStart() {
- this._canColor = false;
- // 停止受伤变色
- this._spAni.node.stopAllActions();
- // 启动变色
- this._spAni.node.color = cc.Color.BLUE;
- if (this._spAni) {
- this._spAni.timeScale = 0;
- }
- // 移动暂停
- this.isAtk = false;
- this.canMoveDir = false;
- this.moveDir = cc.Vec2.ZERO;
- this.udpateRBody(this.moveDir, true);
- }
- frozenEnd() {
- if (!this.isDeath) {
- this._canColor = true;
- // 恢复颜色
- this._spAni.node.color = cc.Color.WHITE;
- if (this._spAni) {
- this._spAni.timeScale = 1;
- this._spAni.setAnimation(0, "idle", true);
- }
- // 移动恢复
- this.canMoveDir = true;
- this.isAtk = false;
- this.atkDir = cc.Vec2.ZERO;
- this.updateMove();
- this.updatePerson();
- this.udpateRBody(this.moveDir);
- }
- }
- fire_start() {
- this._canColor = false;
- // 停止受伤变色
- this._spAni.node.stopAllActions();
- // 启动变色
- this._spAni.node.color = cc.Color.RED;
- }
- fire_end() {
- this._canColor = true;
- // 恢复颜色
- this._spAni.node.color = cc.Color.WHITE;
- }
- private _canAtk: boolean = true;
- canAtk() {
- if (!this._canAtk || this.isAtk || this._spAni.timeScale == 0 || this._spAni.animation.includes("spawn") || this._spAni.animation.includes("jump")) {
- return false;
- }
- return true;
- }
- }
|