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