FSprite.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. import FObject, { GroupType } from "./FObject";
  2. import CMath from "../../../util/CMath";
  3. import BObject from "../../fight/bullet/BObject";
  4. import FPanel from "./FPanel";
  5. import { FFAttr } from "../../data/FFCalAttr";
  6. import AIBase from "./AI/AIBase";
  7. import FPanelIcon from "./FPanelIcon";
  8. import Equip from "../../home/equip/Equip";
  9. import { __SkillData } from "../../data/sdata/SManage";
  10. const { ccclass, property } = cc._decorator;
  11. /**
  12. * 精灵状态
  13. */
  14. export const SpriteType = cc.Enum({
  15. NONE: 0,//站立
  16. MOVE: 1,//移动
  17. // ATK: 2, //攻击
  18. });
  19. /**
  20. * 动画类型
  21. */
  22. export const SpriteActionType = cc.Enum({
  23. stand: 'idle',//站立
  24. move: 'move',//移动
  25. run: 'run',//跑步
  26. atk: 'atk',//行走攻击
  27. atk1: 'atk1',//站立攻击
  28. dead: 'dead',//死亡
  29. yun: 'yun',//倒地晕
  30. yun2: 'yun2',//晕倒地上
  31. dang: 'dang',//惊吓
  32. chuizi: 'chuizi',//锤子
  33. shiqu: 'shiqu'//捡起
  34. });
  35. /**
  36. * 碰撞精灵
  37. */
  38. export interface ColliderSprite {
  39. sprite: FSprite,
  40. dis: number,
  41. }
  42. /**
  43. * 精灵
  44. */
  45. @ccclass
  46. export default class FSprite extends FObject {
  47. /**
  48. * 当前调用的动画
  49. */
  50. public spine: sp.Skeleton = null;
  51. // public hurtSpine: sp.Skeleton = null;
  52. // public hurtParticle: cc.ParticleSystem = null;
  53. mBullet: cc.Prefab = null;//攻击效果
  54. // @property(cc.Node)
  55. // mWeapon: cc.Node = null;//武器
  56. public mAtkSite: sp.spine.Bone = null;//子弹发射插槽
  57. public mWeapon1: sp.spine.Bone = null;//武器
  58. mPanels: Array<FPanel> = [];//显示面板
  59. public mRigidBody: cc.RigidBody;//刚体
  60. public status = SpriteType.NONE;//当前状态
  61. /**
  62. * 当前剩余血量
  63. */
  64. public hp: number = -1;
  65. /**
  66. * 属性
  67. */
  68. public attrData: FFAttr = null;
  69. /**
  70. * 是否被激活
  71. */
  72. public isActive = true;
  73. public SPEED_WALK = 300;//行走速度
  74. // public SPEED_RUN = 350;//跑步速度
  75. public SPEED_SHOOT = 100;//攻击时候的移动速度
  76. /**
  77. * 当前移动的方向
  78. */
  79. private dir = { x: 0, y: 0 };
  80. public moveV2: cc.Vec2 = cc.v2(1, 0);
  81. public isWalk = false;//是否行走
  82. public isRuning = false;//是否跑
  83. public isShooting = false;//是否按住攻击按钮
  84. public wAngle = 0;//当前操作武器旋转角度
  85. /**
  86. * 当前是否暂停状态
  87. */
  88. public gamePause: boolean = false;
  89. public hitCount = 0;
  90. private yanwu: cc.Node = null;
  91. /**
  92. * 当前是否有盾,有盾的时候减少50%伤害
  93. */
  94. public hasDun = false;
  95. /**
  96. * 当前是否处于无敌状态
  97. */
  98. public hasWudi = false;
  99. onLoad() {
  100. let spriteNode = this.node.getChildByName('juese01');
  101. let spineNode0 = spriteNode.getChildByName('spineRight');
  102. if (this.node.name == "s1") {
  103. this.yanwu = spriteNode.getChildByName("yanwu_gs");
  104. }
  105. // this.hurtSpine = spriteNode.getChildByName("hurt").getComponent(sp.Skeleton);
  106. // this.hurtParticle = spriteNode.getChildByName("particle").getComponent(cc.ParticleSystem);
  107. this.mRigidBody = this.node.getComponent(cc.RigidBody);
  108. this.mRigidBody.allowSleep = false;
  109. this.spine = spineNode0.getComponent(sp.Skeleton);
  110. this.mAtkSite = this.spine.findBone('zidan');
  111. this.mWeapon1 = this.spine.findBone('control');
  112. }
  113. start() {
  114. if (this.id > 0) {//载入预设怪物数据
  115. let main = this.map.ff.main;
  116. let attrData = main.sManage.getMonsterData(this.id);
  117. this.setAttrData(attrData);
  118. this.hp = this.attrData.hp;
  119. for (let i = 0; i < this.mPanels.length; i++) {
  120. const element = this.mPanels[i];
  121. element.updatePanel()
  122. }
  123. }
  124. this.setYanwu(false);
  125. this.updateSkin()
  126. }
  127. /**
  128. * 使用锤子
  129. */
  130. public useHammer() {
  131. Equip.chaneWeapon(this.spine, '1000')
  132. }
  133. public updateSkin() {
  134. // if (this.hp <= 0) {
  135. // return
  136. // }
  137. // if (this.attrData.skin) {
  138. // this.spine.setSkin(this.attrData.skin)
  139. // }
  140. // if (this.attrData.weapon) {
  141. // Equip.chaneWeapon(this.spine, this.attrData.weapon)
  142. // }
  143. }
  144. update(dt) {
  145. if (this.gamePause) {
  146. return;
  147. }
  148. this.updateMove(dt)
  149. }
  150. public setPause(pause: boolean) {
  151. this.gamePause = pause
  152. if (this.gamePause) {
  153. this.setDir({ x: 0, y: 0 });
  154. this.setWalk(false);
  155. }
  156. }
  157. /**
  158. * 设置坐标和方向
  159. */
  160. public setPosition(pos) {
  161. this.node.setPosition(pos);
  162. }
  163. /**
  164. * 设置子弹
  165. * @param mBullet
  166. */
  167. public setBullet(mBullet) {
  168. this.mBullet = mBullet;
  169. }
  170. /**
  171. * 设置属性
  172. * @param attrData
  173. */
  174. public setAttrData(attrData: FFAttr) {
  175. this.attrData = attrData;
  176. //mBullet
  177. if (this.mBullet) {
  178. let node = cc.instantiate(this.mBullet);
  179. node.destroy();
  180. } else {
  181. if (!attrData.bullet) {
  182. attrData.bullet = '1001'
  183. }
  184. attrData.bullet = '1101'
  185. cc.resources.load('prefab/bullet/' + attrData.bullet, cc.Prefab, (err, prefab: cc.Prefab) => {
  186. if (err) {
  187. cc.error(err);
  188. } else {
  189. //加载结束
  190. this.mBullet = prefab;
  191. let node = cc.instantiate(this.mBullet);
  192. node.destroy();
  193. }
  194. });
  195. }
  196. let asset = 'prefab/common/hp_monter';
  197. if (this.node.group == 'B') {
  198. asset = 'prefab/common/hp_monter_red'
  199. }
  200. cc.resources.load(asset, cc.Prefab, (err, prefab: cc.Prefab) => {
  201. if (err) {
  202. cc.error(err);
  203. } else {
  204. //加载结束
  205. let node = cc.instantiate(prefab);
  206. let panel = node.getComponent(FPanel);
  207. panel.sprite = this;
  208. this.mPanels.push(panel);
  209. node.y = -10;
  210. node.parent = this.node;
  211. panel.updatePanel();
  212. }
  213. });
  214. }
  215. public flushAttrData(attrData: FFAttr) {
  216. this.attrData = attrData;
  217. this.updateSkin()
  218. if (!attrData.bullet) {
  219. attrData.bullet = '1001'
  220. }
  221. cc.resources.load('prefab/bullet/' + attrData.bullet, cc.Prefab, (err, prefab: cc.Prefab) => {
  222. if (err) {
  223. cc.error(err);
  224. } else {
  225. //加载结束
  226. this.mBullet = prefab;
  227. let node = cc.instantiate(this.mBullet);
  228. node.destroy();
  229. }
  230. });
  231. }
  232. /**
  233. * 添加面板显示
  234. */
  235. public addPanelHUD() {
  236. let res = this.ff.fres;
  237. let node = cc.instantiate(res.mHudPrefab)
  238. node.parent = res.mHudNode;
  239. let panelIcon = node.getComponent(FPanelIcon)
  240. panelIcon.sprite = this
  241. panelIcon.setIcon()
  242. this.mPanels.push(panelIcon)
  243. }
  244. protected setWeaponAngle(angle: number) {
  245. if (this.mWeapon1) {
  246. this.wAngle = angle * 180 / Math.PI;
  247. // console.log("=====wAngle===", this.wAngle);
  248. this.mWeapon1.rotation = this.wAngle + 180;//this.spine.node.scaleX > 0 ? this.wAngle - 90 : -(this.wAngle - 90);
  249. }
  250. }
  251. /**
  252. * 更新武器旋转角度
  253. */
  254. protected updateWeaponAngle(angle: number) {
  255. if (this.mWeapon1) {
  256. // this.mWeapon1.data.rotation = (angle - 90) * this.spine.node.scaleX + 90
  257. this.mWeapon1.rotation = (angle - 90) * this.spine.node.scaleX
  258. // console.log("======武器角度=====", this.mWeapon1.rotation)
  259. }
  260. }
  261. /**
  262. * 角色状态改变后更新角色动作
  263. */
  264. public updateAction() {
  265. if (this.isWalk) {
  266. if (this.isShooting) {
  267. this.createBullet();
  268. this.playAction(SpriteActionType.atk, false, () => {
  269. this.updateSpine();
  270. // this.tmpDir.x = this.dir.x;
  271. // this.tmpDir.y = this.dir.y;
  272. this.updateAction();
  273. });
  274. } else {
  275. this.playAction(SpriteActionType.move, true);
  276. }
  277. } else {
  278. if (this.isShooting) {
  279. this.createBullet();
  280. this.playAction(SpriteActionType.atk1, false, () => {
  281. this.updateSpine();
  282. // this.tmpDir.x = this.dir.x;
  283. // this.tmpDir.y = this.dir.y;
  284. this.updateAction();
  285. });
  286. } else {
  287. this.playAction(SpriteActionType.stand, true);
  288. }
  289. }
  290. }
  291. /**
  292. * 更新动画朝向
  293. */
  294. public updateSpine(): boolean {
  295. let csprite: FSprite = this.findEnemy(1300).sprite;
  296. let p1 = this.node.getPosition();
  297. if (csprite && csprite.isValid) {
  298. let p2 = csprite.node.getPosition();
  299. if (p1.x == p2.x) {
  300. } else if (p1.x - p2.x > 3) {
  301. this.setLR(-1);
  302. } else {
  303. this.setLR(1);
  304. }
  305. //计算弧度
  306. // let angle = Math.floor(CMath.getAngle(p1, p2) * (180 / Math.PI));
  307. //this.wAngle = angle
  308. // this.updateWeaponAngle(angle);
  309. } else {
  310. // this.updateSpineByDir();
  311. // this.updateWeaponAngle(this.wAngle);
  312. }
  313. return false;
  314. }
  315. private updateSpineByDir() {
  316. if (this.dir.x >= 0) {
  317. this.setLR(1);
  318. } else {
  319. this.setLR(-1);
  320. }
  321. }
  322. /**
  323. * 设置精灵方向
  324. */
  325. public setDir(dir): boolean {
  326. if (this.gamePause) {
  327. return;
  328. }
  329. if (dir.x == 0 && dir.y == 0) {
  330. this.setWalk(false);
  331. return false;
  332. }
  333. if (this.isWalk && this.dir.x == dir.x && this.dir.y == dir.y) {
  334. return true;
  335. }
  336. this.dir.x = dir.x;
  337. this.dir.y = dir.y;
  338. this.setWalk(true);
  339. return true;
  340. }
  341. /**
  342. * 设置是否移动
  343. * @param isWalk
  344. */
  345. public setWalk(isWalk: boolean) {
  346. this.isWalk = isWalk;
  347. // this.updateSpine()
  348. // this.updateAction();
  349. if(!isWalk){
  350. this.spine.setAnimation(0, SpriteActionType.stand, true)
  351. }
  352. }
  353. /**
  354. * 设置是否跑
  355. * @param isRuning
  356. */
  357. // public setRuning(isRuning: boolean) {
  358. // this.isRuning = isRuning;
  359. // this.updateAction();
  360. // }
  361. /**
  362. * 攻击时候的方向
  363. */
  364. /**
  365. * 设置攻击
  366. * @param isShooting
  367. */
  368. public setShooting(isShooting: boolean) {
  369. this.isShooting = isShooting;
  370. if (isShooting && this.status == SpriteType.NONE) {
  371. // this.tmpDir.x = this.dir.x;
  372. // this.tmpDir.y = this.dir.y;
  373. this.updateAction();
  374. }
  375. }
  376. public updateMove(dt) {
  377. if (this.isWalk) {
  378. // this.mRigidBody.allowSleep = false;
  379. let speed = 0;
  380. if (this.isShooting) {
  381. speed = this.SPEED_SHOOT;
  382. } else {
  383. speed = this.SPEED_WALK;
  384. }
  385. this.node.x += this.dir.x * dt * speed;
  386. this.node.y += this.dir.y * dt * speed;
  387. this.setYanwu(true);
  388. } else {
  389. // this.mRigidBody.allowSleep = true;
  390. this.setYanwu(false);
  391. }
  392. }
  393. /**
  394. * 移动到某个点
  395. * @param x
  396. * @param y
  397. */
  398. public moveTo(pos: cc.Vec2, dt): boolean {
  399. // this.node.x = pos.x;
  400. // this.node.y = pos.y;
  401. let speed = 1200;
  402. let px = this.node.x > pos.x ? -speed : speed;
  403. let py = this.node.y > pos.y ? -speed : speed;
  404. this.node.x += dt * px;
  405. this.node.y += dt * py;
  406. if (px > 0) {
  407. if (this.node.x > pos.x) {
  408. this.node.x = pos.x;
  409. }
  410. } else {
  411. if (this.node.x < pos.x) {
  412. this.node.x = pos.x;
  413. }
  414. }
  415. if (py > 0) {
  416. if (this.node.y > pos.y) {
  417. this.node.y = pos.y;
  418. }
  419. } else {
  420. if (this.node.y < pos.y) {
  421. this.node.y = pos.y;
  422. }
  423. }
  424. return false;
  425. }
  426. // public playAction(nActionType, loop?: boolean, finishBack?: () => void) {
  427. // if (finishBack) {
  428. // this.spine.setCompleteListener(() => {
  429. // this.spine.setCompleteListener(null);
  430. // finishBack();
  431. // });
  432. // }
  433. // if (!this.isActive) {
  434. // return;
  435. // }
  436. // this.spine.setAnimation(0, nActionType, loop);
  437. // }
  438. public setLR(lr: number) {
  439. let scaleX = Math.abs(this.spine.node.scaleX);
  440. if (lr == -1) {
  441. this.spine.node.scaleX = -scaleX;
  442. } else {
  443. this.spine.node.scaleX = scaleX;
  444. }
  445. }
  446. public getLR(): number {
  447. if (this.spine.node.scaleX > 0) {
  448. return 1
  449. } else {
  450. return -1;
  451. }
  452. }
  453. /**
  454. * hit事件回调
  455. */
  456. public fireCallback: () => void;
  457. public setFireCallback(fireCallback: () => void) {
  458. this.fireCallback = fireCallback;
  459. }
  460. /**
  461. *
  462. * @param prefab 添加攻击特效
  463. */
  464. public addSendEffect(prefab: cc.Prefab, target: cc.Node) {
  465. if (prefab) {
  466. let node = cc.instantiate(prefab);
  467. let x = this.mAtkSite.worldX * this.spine.node.scaleX
  468. let y = this.mAtkSite.worldY
  469. let pos = cc.v2(x, y);
  470. node.setPosition(pos);
  471. node.parent = this.node;
  472. // if(this.mWeapon1){
  473. // node.angle = this.mWeapon1.data.rotation*this.spine.node.scaleX
  474. // node.scaleX = this.spine.node.scaleX
  475. // }
  476. if (target) {
  477. let p1 = this.node.getPosition();
  478. let p2 = target.getPosition();
  479. //计算弧度
  480. let angle = Math.floor(CMath.getAngle(p1, p2) * (180 / Math.PI));
  481. node.angle = angle
  482. } else {
  483. node.angle = this.wAngle
  484. }
  485. let spine = node.getComponent(sp.Skeleton)
  486. spine.setCompleteListener(() => {
  487. node.destroy()
  488. });
  489. spine.setAnimation(0, 'atk', false)
  490. }
  491. }
  492. createBullet() {
  493. if (this.isValid && !this.gamePause) {
  494. let node = cc.instantiate(this.mBullet);
  495. node.group = 'bullet';
  496. let x = this.node.x + this.mAtkSite.worldX * this.spine.node.scaleX
  497. let y = this.node.y + this.mAtkSite.worldY
  498. let pos = cc.v2(x, y);
  499. node.setPosition(pos);
  500. let bObject = node.getComponent(BObject);
  501. bObject.setSprite(this);
  502. let csprite: FSprite = this.findEnemy(2000).sprite;
  503. node.parent = this.map.mSprites;
  504. if (csprite && csprite.isValid) {
  505. bObject.fire(csprite.node);
  506. this.addSendEffect(bObject.mStartEffect, csprite.node);
  507. } else {//没有目标的时候,向朝向开火
  508. bObject.fireAngle1(this.wAngle);
  509. this.addSendEffect(bObject.mStartEffect, null);
  510. }
  511. if (this.fireCallback) {
  512. this.fireCallback();
  513. }
  514. if (this.node == this.ff.mainSprite.node) {
  515. if (this.hitCount > 4) {
  516. this.ff.shockMap();
  517. this.hitCount = 0;
  518. } else {
  519. this.hitCount++;
  520. }
  521. }
  522. this.ff.main.playerEffectByPath('music/magic_1001_fs');
  523. }
  524. }
  525. public tmpActionType = null;
  526. public playAction(nActionType, loop?: boolean, finishBack?: () => void): boolean {
  527. if (!this.isActive) {
  528. return false;
  529. }
  530. if (!this.spine) {
  531. return false;
  532. }
  533. // cc.log('nActionType : ',this.tmpActionType,nActionType);
  534. if (nActionType == this.tmpActionType) {
  535. return false;
  536. }
  537. if (finishBack) {
  538. this.spine.setCompleteListener(() => {
  539. this.spine.setCompleteListener(null);
  540. this.tmpActionType = null;
  541. finishBack();
  542. });
  543. }
  544. //this.spine.setEventListener(null);
  545. // cc.log('nActionType : ',this.tmpActionType,nActionType);
  546. this.tmpActionType = nActionType;
  547. this.spine.setAnimation(0, nActionType, loop);
  548. return true
  549. }
  550. public playAction2(nActionType, loop?: boolean, finishBack?: () => void) {
  551. this.status = SpriteType.NONE
  552. if (finishBack) {
  553. this.spine.setCompleteListener(() => {
  554. this.spine.setCompleteListener(null);
  555. this.tmpActionType = null;
  556. finishBack();
  557. });
  558. }
  559. this.spine.setEventListener(null);
  560. this.spine.setAnimation(0, nActionType, loop);
  561. }
  562. /**
  563. * 攻击对手进行结算
  564. * @param target
  565. */
  566. public atkjs(target: FSprite, _skillData?: __SkillData) {
  567. let reslut = this.calculate(this.attrData, target.attrData, _skillData);
  568. target.reduce(reslut);
  569. if (this == this.ff.mainSprite as FSprite) {
  570. this.ff.flushHP(target);
  571. } else {
  572. this.ff.updateHP(target);
  573. }
  574. // this.ff.main.playSound2('music/magic_1001_sj');
  575. //对方存在AI,设置仇恨
  576. if (target.hp > 0) {
  577. let baseAI = target.node.getComponent(AIBase);
  578. if (baseAI) {
  579. baseAI.setTarget(this);
  580. }
  581. // 播放受击动画和粒子特效
  582. // if (target.node.group == "B") {
  583. // target.hurtParticle.enabled = true;
  584. // target.hurtSpine.enabled = true;
  585. // target.hurtSpine.setAnimation(0, "hurt", false);
  586. // target.hurtSpine.setCompleteListener(() => {
  587. // target.hurtParticle.enabled = false;
  588. // })
  589. // }
  590. }
  591. }
  592. /**
  593. * 被攻击
  594. * @param attrData
  595. */
  596. public bAtkjs(attrData: FFAttr) {
  597. let reslut = this.calculate(attrData, this.attrData);
  598. this.reduce(reslut);
  599. }
  600. /**
  601. * 计算攻击
  602. * @param fd
  603. */
  604. private calculate(A: FFAttr, B: FFAttr, _skillData?: __SkillData): any {
  605. let xx = A.atk - B.def;
  606. if (_skillData) {
  607. // 1 水
  608. // 2 火
  609. // 3 土
  610. // 4 风
  611. // 5 雷
  612. // 6 光
  613. // 7 暗
  614. if (_skillData.value4 == 1) {
  615. xx += A.water
  616. } else if (_skillData.value4 == 2) {
  617. xx += A.fire
  618. } else if (_skillData.value4 == 3) {
  619. xx += A.earth
  620. } else if (_skillData.value4 == 4) {
  621. xx += A.wind
  622. } else if (_skillData.value4 == 5) {
  623. xx += A.thunder
  624. }
  625. }
  626. if (xx <= 0) {
  627. xx = 1;
  628. }
  629. let hp = xx * 500 / (B.def + 300);
  630. if (hp < 1) {
  631. hp = 1;
  632. }
  633. let bj = false
  634. let sk = false
  635. let rand = CMath.getRandom(1, 100)
  636. if (rand < 30) {
  637. bj = true
  638. hp += hp * 3 / 10
  639. }
  640. if (_skillData) {
  641. hp = hp * _skillData.value1 / 100
  642. sk = true
  643. }
  644. let xd = hp / 10;
  645. let xxd = CMath.getRandom(-xd, xd);
  646. hp += xxd;
  647. if (hp < 10) {
  648. hp = CMath.getRandom(1, 10);
  649. }
  650. hp = Math.floor(hp)
  651. return {
  652. hp: Math.floor(hp),
  653. bj: bj,
  654. sk: sk
  655. }
  656. }
  657. /**
  658. * 返回敌人的分组
  659. */
  660. public getEnemyGroup() {
  661. return this.node.group == 'A' ? 'B' : 'A';
  662. }
  663. /**
  664. * 查找周边可攻击对象
  665. */
  666. public findEnemy(radius: number): ColliderSprite {
  667. let mGroup = this.getEnemyGroup();
  668. let minDis = 0
  669. let targetSprite = null;
  670. if (this.map) {
  671. let nodes = this.map.getSprites();
  672. for (let i = 0; i < nodes.length; i++) {
  673. const node = nodes[i];
  674. let sobj = node.getComponent(FSprite);
  675. if (sobj && node.active && sobj.isActive && sobj.hp > 0 && sobj.node.group == mGroup) {
  676. let dis = cc.Vec2.distance(this.node.getPosition(), node.getPosition());
  677. if (dis < radius) {
  678. if (targetSprite == null) {
  679. targetSprite = sobj;
  680. minDis = dis;
  681. } else if (dis < minDis) {
  682. targetSprite = sobj;
  683. minDis = dis;
  684. }
  685. }
  686. }
  687. }
  688. }
  689. return {
  690. sprite: targetSprite,
  691. dis: minDis
  692. };
  693. }
  694. public wudi(time) {
  695. this.hasWudi = true
  696. cc.tween(this.node).sequence(
  697. cc.delayTime(time),
  698. cc.callFunc(() => {
  699. this.hasWudi = false
  700. })
  701. ).start()
  702. }
  703. public reduce(result: any) {
  704. let hp = result.hp
  705. if (hp <= 0) {
  706. return
  707. }
  708. if (this.hasWudi) {
  709. return
  710. }
  711. if (this.hp <= 0) {//已经死了
  712. return
  713. }
  714. if (!this.ff.lockCamera) {
  715. return
  716. }
  717. let bj = result.bj
  718. let sk = result.sk
  719. this.playHit();
  720. if (this.hasDun) {
  721. hp = Math.floor(hp / 2);
  722. }
  723. if (sk) {
  724. this.showNumber('/' + hp, this.ff.mSkillFont);
  725. } else if (bj) {
  726. this.showNumber('/' + hp, this.ff.mBjFont, null, true);
  727. } else {
  728. this.showNumber('/' + hp, this.ff.mRed);
  729. }
  730. this.hp -= hp;
  731. if (this.hp <= 0) {
  732. this.hp = 0;
  733. this.isActive = false;
  734. if (this.ff.clearCallback) {
  735. this.ff.clearCallback(this);
  736. }
  737. if (this.ff.removeCallback) {
  738. this.ff.removeCallback(this);
  739. }
  740. if (this == this.ff.mainSprite as FSprite) {
  741. // this.ff.mainSprite = null;
  742. } else {
  743. this.removeSelf();
  744. }
  745. }
  746. this.updatePanel();
  747. }
  748. public updatePanel() {
  749. for (let i = 0; i < this.mPanels.length; i++) {
  750. const element = this.mPanels[i];
  751. element.updatePanel();
  752. }
  753. }
  754. public removeSelf() {
  755. this.gamePause = true;
  756. this.playAction2(SpriteActionType.dead, false, () => {
  757. this.node.destroy();
  758. });
  759. }
  760. /**
  761. * 显示字符
  762. * ; +
  763. * : -
  764. * @param hp
  765. * @param font
  766. */
  767. private showNumber(str: string, font: cc.Font, color?: cc.Color, bs?: boolean) {
  768. let node: cc.Node = new cc.Node('hp');
  769. node.group = 'map';
  770. let lable: cc.Label = node.addComponent(cc.Label);
  771. lable.fontSize = 30;
  772. if (font) {
  773. lable.font = font;
  774. }
  775. if (color) {
  776. node.color = color;
  777. }
  778. lable.string = str;
  779. node.x = this.node.x;
  780. node.y = this.node.y + this.node.height * 3 / 4;
  781. this.map.node.addChild(node);
  782. let moveBy = cc.moveBy(2, cc.v2(0, 150)).easing(cc.easeSineOut());
  783. let fadeout = cc.fadeOut(2);
  784. let spawn = null
  785. if (bs) {
  786. let seq = cc.sequence(cc.scaleTo(0.05, 1.5), cc.scaleTo(0.2, 1.2));
  787. spawn = cc.spawn(moveBy, fadeout, seq);
  788. } else {
  789. spawn = cc.spawn(moveBy, fadeout);
  790. }
  791. let seq = cc.sequence(cc.delayTime(0.1), spawn, cc.callFunc(() => {
  792. node.removeFromParent(true);
  793. node.destroy();
  794. }));
  795. node.runAction(seq);
  796. }
  797. /**
  798. * 播放受击动作
  799. */
  800. public playHit() {
  801. let spriteNode = this.node.getChildByName('juese01');
  802. if (spriteNode) {
  803. cc.tween(spriteNode).sequence(
  804. cc.scaleTo(0.06, 1.1, 0.95),
  805. cc.scaleTo(0.06, 1, 1.1),
  806. cc.scaleTo(0.06, 1, 1),
  807. ).start();
  808. // cc.tween(spriteNode).sequence(
  809. // cc.moveTo(0.1,cc.v2(0,-9)),
  810. // cc.moveTo(0.16,cc.v2(0,6)),
  811. // cc.moveTo(0.23,cc.v2(0,-6)),
  812. // cc.moveTo(0.3,cc.v2(0,0)),
  813. // ).start();
  814. }
  815. }
  816. public addActiveIcon(): cc.Node {
  817. let node = new cc.Node('activeIcon');
  818. let sprite = node.addComponent(cc.Sprite);
  819. sprite.spriteFrame = this.ff.mActiveIcon;
  820. node.parent = this.node;
  821. node.y = this.node.height + 20
  822. return node;
  823. }
  824. public removeActiveIcon() {
  825. let node = this.node.getChildByName('activeIcon');
  826. if (node) {
  827. node.destroy();
  828. }
  829. }
  830. /**
  831. * 后面的
  832. */
  833. public nextSprite: FSprite;
  834. public setNext(sprite: FSprite) {
  835. this.nextSprite = sprite;
  836. }
  837. /**
  838. * 目标位置的切线方向移动
  839. * @param target
  840. */
  841. public tangentMove(target: cc.Node) {
  842. }
  843. public setYanwu(status: boolean) {
  844. if (this.yanwu) {
  845. if (this.yanwu.active == status) return
  846. this.yanwu.active = status;
  847. }
  848. }
  849. public dead(){
  850. }
  851. }