UpgradeMgr.ts 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. import { cocosz } from "../Framework/CocosZ";
  2. import Constant, { PanelName, ZindexLayer } from "../Framework/Constant";
  3. import Bullet from "./bullet";
  4. import { gameMgr } from "./gameMgr";
  5. import Jingyan from "./jingyan";
  6. import ZombieBase from "./ZombieBase";
  7. const { ccclass, property } = cc._decorator;
  8. export enum SkillType {
  9. 整装待发 = 0,
  10. 瞄准,
  11. 强化,
  12. 瞬斩,
  13. 强力射击,
  14. 窃魂弹夹,
  15. 科技子弹,
  16. 站姿射击,
  17. 子弹碎片,
  18. 双发,
  19. 谢幕,
  20. 枪林弹雨,
  21. 疾走,
  22. 跑动射击,
  23. 意气风发,
  24. 护甲靴子,
  25. 磁场,
  26. 灵能补给,
  27. 容光焕发,
  28. 鹰眼,
  29. 生命力,
  30. 再生,
  31. 进化,
  32. 萃取,
  33. 火焰精通,
  34. 雷电精通,
  35. 冰霜精通,
  36. 双重附魔,
  37. 龙卵,
  38. 通灵匕首,
  39. 通灵镰刀,
  40. 神圣守护,
  41. 飞轮,
  42. 闪电,
  43. 燃烧瓶,
  44. }
  45. export let upgradeMgr: UpgradeMgr = null;
  46. @ccclass
  47. export default class UpgradeMgr extends cc.Component {
  48. @property(cc.Prefab)
  49. bulletPrefab: cc.Prefab = null;
  50. zombieKillNum: number = 0;
  51. bossKillId: number[] = [];
  52. // 经验层
  53. jingyanLayer: cc.Node = null;
  54. // 经验预制体
  55. jingyanPre: cc.Prefab = null;
  56. // 经验触碰距离
  57. jingyanRange: number = 200;
  58. // 升级经验
  59. private _jingyanArr: number[] = [5, 10, 20, 25, 30, 40, 50, 60, 60, 70, 80, 90, 100, 110, 120, 130, 150, 170, 200, 220, 250, 280, 300, 350, 400, 500, 1000];// 经验数组
  60. // private _jingyanArr: number[] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];// 经验数组
  61. // 已拥有技能
  62. upgradeSkillArr: number[] = [
  63. 0, 0, 0, 0, 0,
  64. 0, 0, 0, 0, 0,
  65. 0, 0, 0, 0, 0,
  66. 0, 0, 0, 0, 0,
  67. 0, 0, 0, 0, 0,
  68. 0, 0, 0, 0, 0,
  69. 0, 0, 0, 0, 0
  70. ];
  71. upgradeSkillMaxLevelArr: number[] = [
  72. 1, 1, 1, 1, 1,
  73. 1, 1, 1, 1, 1,
  74. 1, 1, 1, 1, 1,
  75. 1, 1, 1, 1, 1,
  76. 1, 1, 1, 1, 1,
  77. 1, 1, 1, 1, 1,
  78. 1, 1, 3, 3, 3,
  79. ];
  80. // 技能属性
  81. skill_14: number = 1;//增强倍率(伤害和移动速度)
  82. skill_18: number = 0;//加速时间
  83. skill_magic: number = 0;//附魔技能的数量
  84. private _maxLevel: number = 25;// 最大等级
  85. private _curLevel: number = 0;// 当前等级
  86. public get curLevel(): number { return this._curLevel; }
  87. public set curLevel(v: number) {
  88. if (v < 0) v = 0;
  89. else if (v > this._maxLevel) v = this._maxLevel;
  90. // 升级
  91. if (v >= this._curLevel) {
  92. this._curLevel = v;
  93. gameMgr.model6_levelLabel.string = "" + this._curLevel;
  94. // 升级效果
  95. this.upgradeEffect();
  96. // 弹窗
  97. cocosz.pauseCount++;
  98. cocosz.uiMgr.openPanel(PanelName.UIUpgradePanel);
  99. this._curJingyan -= this._curMaxJingyan;
  100. this._curMaxJingyan = this._jingyanArr[this.curLevel];
  101. }
  102. }
  103. private _curMaxJingyan: number = this._jingyanArr[this.curLevel];
  104. private _curJingyan: number = 0;// 当前经验
  105. public get curJingyan(): number { return this._curJingyan; }
  106. public set curJingyan(v: number) {
  107. if (v < 0) v = 0;
  108. this._curJingyan = v;
  109. }
  110. /** 初始化监听 */
  111. onLoad() {
  112. upgradeMgr = this;
  113. cc.game.on(Constant.E_GAME_LOGIC, this._onGameMessageHandler, this);
  114. // 经验预制体
  115. this.jingyanPre = cocosz.resMgr.getRes("jingyan", cc.Prefab);
  116. // 添加经验层
  117. this.jingyanLayer = new cc.Node();
  118. this.jingyanLayer.name = "jingyanLayer";
  119. this.jingyanLayer.zIndex = ZindexLayer.zinedx_jingyan;
  120. this.jingyanLayer.setPosition(cc.Vec2.ZERO);
  121. this.jingyanLayer.setParent(this.node);
  122. }
  123. protected start(): void { }
  124. protected onDestroy(): void {
  125. upgradeMgr = null;
  126. cc.game.targetOff(this);
  127. }
  128. canUpgrade: boolean = true;
  129. protected update(dt: number): void {
  130. if (gameMgr && gameMgr.model6_jingyanBar) {
  131. let from = gameMgr.model6_jingyanBar.progress;
  132. let to = this.curJingyan / this._curMaxJingyan;
  133. if (to == 0) { to = 0.001 }
  134. gameMgr.model6_jingyanBar.progress = cc.misc.lerp(from, to, 0.2);
  135. }
  136. // 经验值满足,且可以升级
  137. if (this.canUpgrade && !cocosz.isPause && this.curLevel < this._maxLevel && this._curJingyan >= this._curMaxJingyan) {
  138. this.curLevel += 1;
  139. }
  140. }
  141. /** 是否拥有技能 */
  142. isHaveSkill(id) {
  143. return this.upgradeSkillArr[id] > 0 ? true : false;
  144. }
  145. skillImgArr: cc.Node[] = [];
  146. /** 设置技能UI */
  147. setSkillImg(id: number) {
  148. let str = "zombieSkill_icon_" + id + (this.upgradeSkillMaxLevelArr[id] > 1 ? ("_" + this.upgradeSkillArr[id]) : "");
  149. let icon = cocosz.resMgr.getRes(str, cc.SpriteFrame);
  150. if (icon && gameMgr.model6_skillScrollView_content && gameMgr.model6_skillScrollView_content.isValid) {
  151. if (!this.skillImgArr[id] && gameMgr.model6_skillScrollView_item) {
  152. this.skillImgArr[id] = cc.instantiate(gameMgr.model6_skillScrollView_item);
  153. this.skillImgArr[id].active = true;
  154. this.skillImgArr[id].setParent(gameMgr.model6_skillScrollView_content);
  155. // 滑动到最右边
  156. if (gameMgr.model6_skillScrollView_content.width > gameMgr.model6_skillScrollView.node.width) {
  157. gameMgr.model6_skillScrollView.scrollToRight();
  158. }
  159. }
  160. if (this.skillImgArr[id]) {
  161. let sprite = this.skillImgArr[id].getComponent(cc.Sprite);
  162. if (sprite) sprite.spriteFrame = icon;
  163. }
  164. }
  165. }
  166. /** 设置技能cd */
  167. setSkillCD(id: number, time: number) {
  168. if (this.skillImgArr[id]) {
  169. let skillCD = this.skillImgArr[id].getChildByName("skillCD");
  170. if (skillCD) {
  171. skillCD.active = true;
  172. skillCD.opacity = 255;
  173. cc.tween(skillCD.children[0].getComponent(cc.Sprite))
  174. .set({ fillRange: 1 })
  175. .to(time, { fillRange: 0 })
  176. .call(() => { skillCD.opacity = 0; })
  177. .start();
  178. let num = time;
  179. let timeLabel = skillCD.children[1].getComponent(cc.Label);
  180. cc.tween(skillCD)
  181. .call(() => { timeLabel.string = num.toString(); num--; })
  182. .delay(1)
  183. .union()
  184. .repeat(time)
  185. .start();
  186. }
  187. }
  188. }
  189. /** 获得技能 */
  190. getSkill(id) {
  191. this.upgradeSkillArr[id]++;
  192. this.setSkillImg(id);
  193. switch (id) {
  194. case SkillType.整装待发: {
  195. if (gameMgr.playerTs && gameMgr.playerTs.curWeapon) {
  196. gameMgr.playerTs.curWeapon.bulletNum += 4;
  197. }
  198. break;
  199. }
  200. case SkillType.瞄准: {
  201. if (gameMgr.playerTs) {
  202. gameMgr.playerTs.atkRate *= 1.25;
  203. }
  204. break;
  205. }
  206. case SkillType.强化: {
  207. if (gameMgr.playerTs && gameMgr.playerTs.curWeapon) {
  208. gameMgr.playerTs.curWeapon.bulletNum += 2;
  209. gameMgr.playerTs.atkRate *= 1.1;
  210. }
  211. break;
  212. }
  213. case SkillType.瞬斩: {
  214. break;
  215. }
  216. case SkillType.强力射击: {
  217. if (gameMgr.playerTs) {
  218. gameMgr.playerTs.atkRate *= 1.2;
  219. }
  220. break;
  221. }
  222. case SkillType.窃魂弹夹: {
  223. break;
  224. }
  225. case SkillType.科技子弹: {
  226. if (gameMgr.playerTs) {
  227. gameMgr.playerTs.atkSpeedRate -= 0.1;
  228. }
  229. break;
  230. }
  231. case SkillType.站姿射击: {
  232. let can = true;
  233. this.schedule(() => {
  234. if (can && gameMgr.playerTs.moveDir.mag() == 0) {
  235. can = false;
  236. gameMgr.playerTs.atkRate *= 1.3;
  237. } else if (!can && gameMgr.playerTs.moveDir.mag() > 0) {
  238. can = true;
  239. gameMgr.playerTs.atkRate /= 1.3;
  240. }
  241. }, 0.1);
  242. break;
  243. }
  244. case SkillType.子弹碎片: {
  245. break;
  246. }
  247. case SkillType.双发: {
  248. if (gameMgr.playerTs) {
  249. gameMgr.playerTs.atkBulletNum += 1;
  250. }
  251. break;
  252. }
  253. case SkillType.谢幕: {
  254. break;
  255. }
  256. case SkillType.枪林弹雨: {
  257. if (gameMgr.playerTs) {
  258. gameMgr.playerTs.atkBulletNum *= 2;
  259. }
  260. break;
  261. }
  262. case SkillType.疾走: {
  263. if (gameMgr.playerTs) {
  264. gameMgr.playerTs.speedRate *= 1.1;
  265. }
  266. break;
  267. }
  268. case SkillType.跑动射击: {
  269. let can = true;
  270. this.schedule(() => {
  271. if (can && gameMgr.playerTs.isAtk) {
  272. can = false;
  273. gameMgr.playerTs.speedRate *= 1.2;
  274. } else if (!can && !gameMgr.playerTs.isAtk) {
  275. can = true;
  276. gameMgr.playerTs.speedRate /= 1.2;
  277. }
  278. }, 0.1);
  279. break;
  280. }
  281. case SkillType.意气风发: {
  282. // 每10秒增加10%的伤害和移动速度
  283. this.schedule(() => {
  284. if (gameMgr.playerTs) {
  285. let k = this.skill_14 + 0.1;
  286. if (k > 1.4) k = 1.4;
  287. else if (k < 1) k = 1;
  288. gameMgr.playerTs.atkRate *= (k / this.skill_14);
  289. gameMgr.playerTs.speedRate *= (k / this.skill_14);
  290. this.skill_14 = k;
  291. }
  292. }, 10);
  293. break;
  294. }
  295. case SkillType.护甲靴子: {
  296. break;
  297. }
  298. case SkillType.磁场: {
  299. this.jingyanRange += 200;
  300. break;
  301. }
  302. case SkillType.灵能补给: {
  303. this.jingyanRange += 50;
  304. break;
  305. }
  306. case SkillType.容光焕发: {
  307. this.jingyanRange += 50;
  308. break;
  309. }
  310. case SkillType.鹰眼: {
  311. this.jingyanRange += 50;
  312. cc.tween(gameMgr.mainCamera).to(1, { zoomRatio: 0.6 }).start();
  313. break;
  314. }
  315. case SkillType.生命力: {
  316. if (gameMgr.playerTs) {
  317. gameMgr.playerTs.totleHp += 1;
  318. gameMgr.playerTs.HP = gameMgr.playerTs.totleHp;
  319. this.scheduleOnce(() => { gameMgr.playerTs.recoverEffect(); }, 1)
  320. }
  321. break;
  322. }
  323. case SkillType.再生: {
  324. this.schedule(() => { this._updateZaisheng(); }, 1);
  325. break;
  326. }
  327. case SkillType.进化: {
  328. if (gameMgr.playerTs) {
  329. gameMgr.playerTs.atkRate *= 1.1;
  330. gameMgr.playerTs.totleHp += 1;
  331. gameMgr.playerTs.HP += 1;
  332. this.scheduleOnce(() => { gameMgr.playerTs.recoverEffect(); }, 1)
  333. }
  334. break;
  335. }
  336. case SkillType.萃取: {
  337. break;
  338. }
  339. case SkillType.火焰精通: {
  340. break;
  341. }
  342. case SkillType.冰霜精通: {
  343. break;
  344. }
  345. case SkillType.双重附魔: {
  346. break;
  347. }
  348. case SkillType.通灵匕首: {
  349. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_bishou", cc.Prefab);
  350. if (pre && gameMgr && gameMgr.playerTs) {
  351. this._bishou = cc.instantiate(pre);
  352. this._bishou.setParent(this.node);
  353. this._bishou.zIndex = cc.macro.MAX_ZINDEX;
  354. this._bishou.active = false;
  355. this.updateBishou();
  356. }
  357. break;
  358. }
  359. case SkillType.神圣守护: {
  360. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_hudun", cc.Prefab);
  361. if (pre && gameMgr && gameMgr.playerTs) {
  362. this.hudun = cc.instantiate(pre);
  363. this.hudun.setParent(gameMgr.playerTs.node);
  364. this.hudun.setPosition(0, 0);
  365. this.hudun.zIndex = cc.macro.MAX_ZINDEX - 1;
  366. break;
  367. }
  368. }
  369. case SkillType.飞轮: {
  370. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_feilun", cc.Prefab);
  371. if (pre) {
  372. if (gameMgr && gameMgr.playerTs) {
  373. this._feilun && this._feilun.isValid && this._feilun.destroy();
  374. this._feilun = cc.instantiate(pre);
  375. this._feilun.setParent(gameMgr.playerTs.node);
  376. this._feilun.setPosition(cc.Vec2.ZERO);
  377. this._feilun.active = true;
  378. this._feilun.zIndex = cc.macro.MAX_ZINDEX;
  379. this.updateFeilun(this.upgradeSkillArr[SkillType.飞轮]);
  380. }
  381. }
  382. break;
  383. }
  384. case SkillType.闪电: {
  385. if (this.upgradeSkillArr[SkillType.闪电] == 1) {
  386. this.schedule(this.updateShandian, 1)
  387. }
  388. break;
  389. }
  390. case SkillType.燃烧瓶: {
  391. if (this.upgradeSkillArr[SkillType.燃烧瓶] == 1) {
  392. this.schedule(this.updateFire, 1)
  393. }
  394. break;
  395. }
  396. }
  397. }
  398. /** 消息 */
  399. private _onGameMessageHandler(event: any) {
  400. switch (event.type) {
  401. case Constant.E_Jingyan_Finish: {
  402. if (this.isHaveSkill(SkillType.灵能补给)) {
  403. if (gameMgr && gameMgr.playerTs && Math.random() < 0.01) {
  404. gameMgr.playerTs.curWeapon.curBullet += 1;
  405. }
  406. }
  407. else if (this.isHaveSkill(SkillType.容光焕发)) {
  408. if (this.skill_18 < 3) {
  409. if (this.skill_18 == 0) {
  410. this.accelerate();
  411. }
  412. this.skill_18++;
  413. }
  414. }
  415. break;
  416. }
  417. case Constant.E_Zombie_Hart: {
  418. if (event.node && event.node.isValid) {
  419. if (this.isHaveSkill(SkillType.瞬斩) && this.canAddMagic(event.node, SkillType.瞬斩)) {
  420. this.skill_effect_3(event.node);
  421. } else {
  422. let skillArr: number[] = [];
  423. if (this.isHaveSkill(SkillType.火焰精通) && this.canAddMagic(event.node, SkillType.火焰精通)) {
  424. skillArr.push(SkillType.火焰精通);
  425. }
  426. /* if (this.isHaveSkill(SkillType.雷电精通) && this.canAddMagic(event.node, SkillType.雷电精通)) {
  427. skillArr.push(SkillType.雷电精通);
  428. } */
  429. if (this.isHaveSkill(SkillType.冰霜精通) && this.canAddMagic(event.node, SkillType.冰霜精通)) {
  430. skillArr.push(SkillType.冰霜精通);
  431. }
  432. // 随机技能
  433. if (skillArr.length) {
  434. let skillIndex = Math.floor(Math.random() * skillArr.length);
  435. let skillId = skillArr[skillIndex];
  436. switch (skillId) {
  437. case SkillType.火焰精通: {
  438. this.skill_effect_24(event.node);
  439. break;
  440. }
  441. /* case SkillType.雷电精通: {
  442. this.skill_effect_25(event.node);
  443. break;
  444. } */
  445. case SkillType.冰霜精通: {
  446. this.skill_effect_26(event.node);
  447. break;
  448. }
  449. }
  450. }
  451. }
  452. }
  453. break;
  454. }
  455. case Constant.E_Zombie_Death: {
  456. if (event.node) {
  457. if (this.isHaveSkill(SkillType.子弹碎片) && event.from) {
  458. let angle = 30 * Math.random();
  459. this.createBullet(event.node, 30 + angle, 40);
  460. this.createBullet(event.node, 150 + angle, 40);
  461. this.createBullet(event.node, 270 + angle, 40);
  462. }
  463. else if (this.isHaveSkill(SkillType.萃取)) {
  464. if (gameMgr && gameMgr.playerTs && gameMgr.playerTs.HP < gameMgr.playerTs.totleHp && Math.random() < 0.05) {
  465. gameMgr.playerTs.HP += 1;
  466. gameMgr.playerTs.recoverEffect();
  467. }
  468. }
  469. // 统计击杀
  470. let ts: ZombieBase = event.node.getComponent(ZombieBase);
  471. if (ts) {
  472. this.zombieKillNum++;
  473. if (ts.isBoss) {
  474. this.bossKillId.push(ts.zombieId);
  475. if (gameMgr.bossArr.length == 0) {
  476. gameMgr.win();
  477. }
  478. }
  479. }
  480. }
  481. break;
  482. }
  483. case Constant.E_Bullet_Last: {
  484. if (this.isHaveSkill(SkillType.谢幕)) {
  485. if (gameMgr.playerTs) {
  486. this.createBullet(event.node, 36 * 1, 40);
  487. this.createBullet(event.node, 36 * 3, 40);
  488. this.createBullet(event.node, 36 * 5, 40);
  489. this.createBullet(event.node, 36 * 7, 40);
  490. this.createBullet(event.node, 36 * 9, 40);
  491. this.scheduleOnce(() => {
  492. this.createBullet(event.node, 36 * 2, 40);
  493. this.createBullet(event.node, 36 * 4, 40);
  494. this.createBullet(event.node, 36 * 6, 40);
  495. this.createBullet(event.node, 36 * 8, 40);
  496. this.createBullet(event.node, 36 * 10, 40);
  497. }, 0);
  498. }
  499. }
  500. break;
  501. }
  502. case Constant.E_Bullet_Reload: {
  503. if (this.isHaveSkill(SkillType.窃魂弹夹)) {
  504. if (gameMgr.playerTs) {
  505. gameMgr.playerTs.atkRate *= 1.3;
  506. this.scheduleOnce(() => {
  507. gameMgr.playerTs.atkRate /= 1.3;
  508. }, 1);
  509. }
  510. }
  511. break;
  512. }
  513. case Constant.E_Player_Hart: {
  514. if (this.isHaveSkill(SkillType.意气风发)) {
  515. this.skill_14 = 1;
  516. }
  517. break;
  518. }
  519. case Constant.E_Player_Death: {
  520. if (this.hudun) {
  521. this.hudun.opacity = 0;
  522. }
  523. break;
  524. }
  525. }
  526. }
  527. /** 经验 */
  528. createJingyan(pos: cc.Vec2) {
  529. if (this.jingyanPre && this.jingyanLayer) {
  530. let jingyan = gameMgr.nodeGet("jingyan", this.jingyanPre);
  531. let ts = jingyan.getComponent(Jingyan);
  532. if (ts) { ts.init(); }
  533. jingyan.setPosition(pos);
  534. jingyan.setParent(this.jingyanLayer);
  535. }
  536. }
  537. /** 升级效果 */
  538. upgradeEffect() {
  539. if (gameMgr.playerTs && gameMgr.playerTs.isValid) {
  540. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_sjgx", cc.Prefab);
  541. if (pre) {
  542. let node = cc.instantiate(pre);
  543. node.setPosition(cc.Vec2.ZERO);
  544. node.setParent(gameMgr.playerTs.node);
  545. // node.zIndex = -1;
  546. // 升级音效
  547. gameMgr.playEffect("LevelUp");
  548. }
  549. }
  550. }
  551. /** 子弹 */
  552. createBullet(node: cc.Node, angle: number, atkNum: number) {
  553. if (this.bulletPrefab) {
  554. let dir = cc.v2(1, 0).rotateSelf(cc.misc.degreesToRadians(angle));
  555. let bullet = cc.instantiate(this.bulletPrefab);
  556. bullet.parent = this.node;
  557. bullet.setPosition(node.getPosition())
  558. bullet.angle = angle;
  559. let pos1 = bullet.getPosition();
  560. let pos2 = pos1.add(dir.mul(1000));
  561. cc.tween(bullet)
  562. .to(pos2.sub(pos1).mag() / 2500, { position: cc.v3(pos2) })
  563. .call(() => {
  564. let ts = bullet.getComponent(Bullet);
  565. if (ts.boomEffect) {
  566. let boom = cc.instantiate(ts.boomEffect)
  567. boom.parent = ts.node.parent;
  568. boom.setPosition(ts.node.getPosition());
  569. boom.zIndex = ZindexLayer.zindex_bomb;
  570. let curBullet = boom.getComponent(Bullet);
  571. curBullet.atk = ts.atk;
  572. curBullet.atker = ts.atker;
  573. curBullet.id = ts.id;
  574. gameMgr.playEffect("explo", boom);
  575. if (ts.hitEffect) {
  576. let pos = bullet.getPosition();
  577. let node = cc.instantiate(ts.hitEffect);
  578. node.parent = bullet.parent;
  579. node.setPosition(pos);
  580. node.zIndex = ZindexLayer.zindex_effect_hit;
  581. }
  582. }
  583. bullet.destroy()
  584. })
  585. .start();
  586. let ts = bullet.getComponent(Bullet);
  587. ts.id = 1;
  588. ts.atker = null;
  589. ts.atk = atkNum;
  590. ts.dir = dir;
  591. }
  592. }
  593. private _canAccelerate: boolean = true;
  594. /** 获得经验加速1秒(可累计) */
  595. accelerate() {
  596. if (this.skill_18 == 0) {
  597. if (this._canAccelerate) {
  598. this._canAccelerate = false;
  599. // 开始加速
  600. if (gameMgr.playerTs) gameMgr.playerTs.speedRate *= 1.5;
  601. } else {
  602. this._canAccelerate = true;
  603. // 结束加速
  604. if (gameMgr.playerTs) gameMgr.playerTs.speedRate /= 1.5;
  605. return;
  606. }
  607. }
  608. this.scheduleOnce(() => {
  609. this.skill_18--;
  610. this.accelerate();
  611. }, 1);
  612. }
  613. /** 魔法伤害倍率 */
  614. magic_hart_rate() {
  615. if (this.isHaveSkill(SkillType.双重附魔) && this.skill_magic > 1) {
  616. return 1.5;
  617. } else {
  618. return 1;
  619. }
  620. }
  621. /** 能否添加魔法(审判,火焰,雷电,冰冻) */
  622. canAddMagic(enemy: cc.Node, id?: number) {
  623. if (enemy && enemy.isValid) {
  624. let zombieTs: ZombieBase = enemy.getComponent(ZombieBase);
  625. if (zombieTs) {
  626. // 血量小于0
  627. if (zombieTs.HP <= 0) {
  628. return false;
  629. }
  630. // 已存在瞬斩
  631. for (let i = 0; i < enemy.childrenCount; i++) {
  632. if (enemy.children[i].name == `zombieSkill_${SkillType.瞬斩}`) {
  633. return false;
  634. }
  635. }
  636. if (id >= 0) {
  637. if (id == SkillType.瞬斩) {
  638. // 是否达到试用条件
  639. if (zombieTs.isBoss || (zombieTs.totleHp > 0 && zombieTs.HP / zombieTs.totleHp > 0.4)) {
  640. return false;
  641. }
  642. }
  643. else {
  644. // 已存在火焰和冰霜
  645. for (let i = 0; i < enemy.childrenCount; i++) {
  646. if (enemy.children[i].name.includes("zombieSkill"))
  647. return false;
  648. }
  649. if (zombieTs.isBoss) {
  650. if (id == SkillType.火焰精通) {
  651. return Math.random() < 0.2 ? true : false;
  652. } else if (id == SkillType.冰霜精通) {
  653. return Math.random() < 0.2 ? true : false;
  654. }
  655. }
  656. }
  657. }
  658. else { return false; }
  659. }
  660. else { return false; }
  661. }
  662. else { return false; }
  663. return true;
  664. }
  665. /** 瞬斩 */
  666. skill_effect_3(enemy: cc.Node) {
  667. if (enemy && enemy.isValid) {
  668. let zombieTs: ZombieBase = enemy.getComponent(ZombieBase);
  669. if (zombieTs) {
  670. // 技能效果
  671. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_3", cc.Prefab);
  672. if (pre) {
  673. let node: cc.Node = cc.instantiate(pre);
  674. node.setPosition(0, 0);
  675. node.setParent(enemy);
  676. // 销毁
  677. zombieTs.moveDir = cc.Vec2.ZERO;
  678. zombieTs.canMoveDir = false;
  679. zombieTs.updateMove();
  680. cc.tween(zombieTs)
  681. .delay(0.5)
  682. .call(() => {
  683. if (zombieTs && zombieTs.isValid) {
  684. zombieTs.hart(zombieTs.HP, null, null, false, false, cc.Color.RED);
  685. }
  686. })
  687. .delay(0.5)
  688. .call(() => {
  689. if (node && node.isValid) {
  690. node.destroy();
  691. }
  692. })
  693. .start();
  694. }
  695. }
  696. }
  697. }
  698. /** 火焰精通 */
  699. skill_effect_24(enemy: cc.Node) {
  700. if (enemy && enemy.isValid) {
  701. let zombieTs: ZombieBase = enemy.getComponent(ZombieBase);
  702. if (zombieTs) {
  703. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_24", cc.Prefab);
  704. if (pre) {
  705. // 添加火焰动画
  706. let node = cc.instantiate(pre);
  707. node.setPosition(0, 0/* -enemy.height / 2 * enemy.scaleY */);
  708. node.setParent(enemy);
  709. node.zIndex = cc.macro.MAX_ZINDEX;
  710. zombieTs.fire_start();
  711. // 伤害
  712. cc.tween(node)
  713. .delay(0.2)
  714. .call(() => {
  715. if (zombieTs.isValid && zombieTs.HP > 0) {
  716. zombieTs.hart(5 * this.magic_hart_rate(), null, null, false, false, cc.Color.RED);
  717. } else {
  718. node.destroy();
  719. }
  720. })
  721. .union()
  722. .repeat(20)
  723. .call(() => {
  724. zombieTs.fire_end();
  725. node.destroy();
  726. })
  727. .start();
  728. gameMgr.playEffect("ranshao", enemy, 1);
  729. }
  730. }
  731. }
  732. }
  733. /** 冰霜精通 */
  734. skill_effect_26(enemy: cc.Node) {
  735. if (enemy && enemy.isValid) {
  736. let zombieTs: ZombieBase = enemy.getComponent(ZombieBase);
  737. if (zombieTs /* && !zombieTs.isBoss() */) {
  738. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_26", cc.Prefab);
  739. if (pre) {
  740. let node_frozen = cc.instantiate(pre);
  741. node_frozen.setPosition(0, 0);
  742. node_frozen.setParent(enemy);
  743. node_frozen.zIndex = cc.macro.MAX_ZINDEX;
  744. if (zombieTs.zombieId >= 8) {
  745. node_frozen.scale = 4;
  746. } else {
  747. node_frozen.scale = 2;
  748. }
  749. // 冰冻
  750. if (zombieTs.isValid) {
  751. zombieTs.frozenStart();
  752. let t = zombieTs.isBoss ? 0.5 : 2;
  753. this.scheduleOnce(() => {
  754. if (zombieTs && zombieTs.isValid) {
  755. zombieTs.frozenEnd();
  756. }
  757. // 销毁
  758. if (node_frozen && node_frozen.isValid) {
  759. node_frozen.destroy();
  760. }
  761. }, t);
  762. }
  763. // 音效
  764. gameMgr.playEffect("bingdong", enemy, 1);
  765. }
  766. }
  767. }
  768. }
  769. private _bishou: cc.Node = null;
  770. /** 通灵匕首 */
  771. updateBishou() {
  772. if (this._bishou && this._bishou.isValid && gameMgr && gameMgr.playerTs) {
  773. if (gameMgr.playerTs.atkTarget && gameMgr.playerTs.atkTarget.isValid) {
  774. // 匕首属性
  775. let bulletTs = this._bishou.getComponent(Bullet);
  776. bulletTs.isHartMusic = false;
  777. bulletTs.hitAudio = "hurt";
  778. bulletTs.atk = 50 * gameMgr.playerTs.atkRate;
  779. bulletTs.atkedArr = [];
  780. // 当前
  781. let from: cc.Vec2 = gameMgr.playerTs.node.getPosition();
  782. // 目标
  783. let div: cc.Vec2 = gameMgr.playerTs.atkTarget.getPosition().subSelf(from);
  784. let dis = div.mag();
  785. if (dis < 400) {
  786. div.normalizeSelf().mulSelf(400);
  787. }
  788. let p2: cc.Vec2 = from.add(cc.v2(1, 0).mulSelf(400).rotateSelf(this._bishou.angle / 180 * Math.PI))
  789. let to: cc.Vec2 = from.add(div);
  790. let t = div.mag() / 800;
  791. if (false == this._bishou.active) {
  792. this._bishou.active = true;
  793. this._bishou.setPosition(from);
  794. }
  795. cc.tween(this._bishou)
  796. .bezierTo(t, from, p2, to)
  797. .call(() => { this.updateBishou(); })
  798. .start();
  799. } else {
  800. this._bishou.active = false;
  801. this.scheduleOnce(() => { this.updateBishou(); }, 1);
  802. }
  803. }
  804. }
  805. public hudun: cc.Node = null;
  806. /** 神圣护盾 */
  807. updateHudun() {
  808. if (this.hudun && this.hudun.active) {
  809. this.hudun.active = false;
  810. // 破裂音效
  811. gameMgr.playEffect("ShieldDestroy");
  812. // cd
  813. this.setSkillCD(SkillType.神圣守护, 60);
  814. this.scheduleOnce(() => {
  815. if (gameMgr && gameMgr.playerTs && gameMgr.playerTs.isValid) {
  816. this.hudun.active = true;
  817. if (gameMgr.playerTs.HP) {
  818. this.hudun.opacity = 255;
  819. } else {
  820. this.hudun.opacity = 0;
  821. }
  822. }
  823. }, 60)
  824. }
  825. }
  826. private _zaishengCdTime: number = 0;
  827. /** 再生 */
  828. private _updateZaisheng() {
  829. if (this._zaishengCdTime > 0) {
  830. this._zaishengCdTime--;
  831. return;
  832. }
  833. if (cocosz.isPause) return;
  834. if (gameMgr.playerTs && !gameMgr.playerTs.isDeath && gameMgr.playerTs.HP < gameMgr.playerTs.totleHp) {
  835. gameMgr.playerTs.HP += 1;
  836. gameMgr.playerTs.recoverEffect();
  837. this._zaishengCdTime = 90;
  838. this.setSkillCD(SkillType.再生, this._zaishengCdTime);
  839. }
  840. }
  841. private _feilun: cc.Node = null;
  842. private _posArr: any[] = [
  843. [[500, 0]],
  844. [[500, 0], [-500, 0]],
  845. [[500, 0], [-300, 400], [-300, -400]],
  846. [[500, 0], [-500, 0], [0, 500], [0, -500]]
  847. ]
  848. /** 飞轮 */
  849. updateFeilun(level: number) {
  850. // 根据等级设置飞轮数量
  851. if (this._feilun && this._feilun.isValid && gameMgr && gameMgr.playerTs) {
  852. cc.tween(this._feilun).by(10, { angle: -360 * 5 }).repeatForever().start();
  853. // 飞轮
  854. let level2NumArr = [1, 2, 3, 4];
  855. let num = level2NumArr[level];
  856. for (let i = 0; i < 4; i++) {
  857. let icon = this._feilun.children[i];
  858. if (icon) {
  859. if (i < num) {
  860. icon.active = true;
  861. if (level == 3) {
  862. let sprFrame = this._feilun.getChildByName("back").getComponent(cc.Sprite).spriteFrame;
  863. icon.getComponent(cc.Sprite).spriteFrame = sprFrame;
  864. }
  865. icon.setPosition(this._posArr[level][i][0], this._posArr[level][i][1]);
  866. cc.tween(icon)
  867. .call(() => {
  868. gameMgr.playEffect("chilunStart");
  869. icon.getComponent(cc.Collider).enabled = true;
  870. })
  871. .to(1, { scale: 2.5 })
  872. .delay(8)
  873. .to(1, { scale: 0 })
  874. .call(() => { icon.getComponent(cc.Collider).enabled = false; })
  875. .delay(2)
  876. .union()
  877. .repeatForever()
  878. .start();
  879. let bulletTs = icon.getComponent(Bullet);
  880. if (bulletTs) {
  881. bulletTs.isHartMusic = false;
  882. bulletTs.hitAudio = "chilun";
  883. bulletTs.atk = 80 + 20 * level * gameMgr.playerTs.atkRate;
  884. }
  885. } else {
  886. icon.active = false;
  887. }
  888. }
  889. }
  890. }
  891. }
  892. private _shandianCount: number = 0;
  893. private _shandianNum: number[] = [1, 1, 3, 5];
  894. private _shandiCdTime: number = 0;
  895. /** 闪电 */
  896. updateShandian() {
  897. if (this._shandiCdTime > 0) {
  898. this._shandiCdTime--;
  899. return;
  900. }
  901. if (cocosz.isPause) return;
  902. let level = this.upgradeSkillArr[SkillType.闪电];
  903. if (this._shandianCount == 0) {
  904. this._shandianCount = this._shandianNum[level];
  905. }
  906. // 能够添加闪电的敌人
  907. let enemyArr = [];
  908. for (let i = gameMgr.playerTs.atkList.length - 1; i >= 0; i--) {
  909. let can: boolean = true;
  910. const node = gameMgr.playerTs.atkList[i];
  911. node.children.forEach(n => {
  912. if (n.name == "zombieSkill_shandian") {
  913. can = false;
  914. }
  915. });
  916. if (can) { enemyArr.push(node); }
  917. }
  918. if (enemyArr.length) {
  919. let pre: cc.Prefab = cocosz.resMgr.getRes("zombieSkill_shandian", cc.Prefab);
  920. if (pre) {
  921. let enemy = enemyArr.shift();
  922. if (enemy && enemy.isValid) {
  923. this._shandianCount--;
  924. // 添加雷电动画
  925. let node = cc.instantiate(pre);
  926. node.setPosition(0, -enemy.height / 2 * enemy.scaleY);
  927. node.setParent(enemy);
  928. node.zIndex = cc.macro.MAX_ZINDEX;
  929. // 动画皮肤
  930. if (level == 3) {
  931. let spAni = node.getComponent(sp.Skeleton);
  932. if (spAni) { spAni.setSkin("y"); }
  933. }
  934. // 销毁
  935. this.schedule(() => { if (node && node.isValid) { node.destroy(); } }, 1);
  936. // 伤害
  937. let zombieTs: ZombieBase = enemy.getComponent(ZombieBase);
  938. if (zombieTs) {
  939. if (zombieTs.isValid && zombieTs.HP > 0) {
  940. zombieTs.hart(200 * this.magic_hart_rate(), null, null, false, false, cc.Color.RED);
  941. }
  942. }
  943. // 音效
  944. gameMgr.playEffect("LuoLei", enemy);
  945. }
  946. } else {
  947. cocosz.resMgr.getRes("prefab_zombie_skill/zombieSkill_shandian", cc.Prefab);
  948. }
  949. }
  950. if (this._shandianCount == 0) {
  951. this._shandiCdTime = 3 + level;
  952. this.setSkillCD(SkillType.闪电, this._shandiCdTime);
  953. }
  954. }
  955. private _fireCount: number = 0;
  956. private _fireNum: number[] = [1, 1, 2, 3];
  957. private _fireCdTime: number = 0;
  958. /** 燃烧瓶 */
  959. updateFire() {
  960. if (this._fireCdTime > 0) {
  961. this._fireCdTime--;
  962. return;
  963. }
  964. if (cocosz.isPause) return;
  965. let level = this.upgradeSkillArr[SkillType.燃烧瓶];
  966. this._fireCount = this._fireNum[level];
  967. if (!cocosz.isPause && gameMgr && gameMgr.playerTs && gameMgr.playerTs.atkTarget && gameMgr.playerTs.atkTarget.isValid) {
  968. let pre = cocosz.resMgr.getRes("zombieSkill_fire", cc.Prefab);
  969. if (pre) {
  970. let div: cc.Vec2 = gameMgr.playerTs.atkTarget.getPosition().subSelf(gameMgr.playerTs.node.getPosition());
  971. div.normalizeSelf().mulSelf(400);
  972. for (let i = 0; i < this._fireCount; i++) {
  973. let radian = ((this._fireCount - 1) / 2 - i) * (Math.PI / 2);
  974. let from = gameMgr.playerTs.node.getPosition();
  975. let to = from.add(cc.v2(div).rotateSelf(radian));
  976. let p2 = cc.v2((from.x + to.x) / 2, from.y + 900);
  977. let fire: cc.Node = cc.instantiate(pre);
  978. fire.children[1].active = (level == 3 ? false : true);
  979. fire.children[2].active = (level == 3 ? true : false);
  980. fire.setPosition(from);
  981. fire.setParent(gameMgr.map);
  982. fire.zIndex = cc.macro.MAX_ZINDEX;
  983. cc.tween(fire)
  984. .parallel(
  985. cc.tween().bezierTo(1, from, p2, to),
  986. cc.tween().to(1, { angle: 720 * (div.x > 0 ? 1 : -1) })
  987. )
  988. .call(() => {
  989. fire.zIndex = ZindexLayer.zinedx_floorSkill;
  990. fire.children[1].active = fire.children[2].active = false;
  991. fire.children[0].active = true;
  992. // 子弹碰撞体
  993. fire.getComponent(cc.Collider).enabled = true;
  994. // 子弹属性
  995. let buttleTs = fire.getComponent(Bullet);
  996. buttleTs.isHartMusic = false;
  997. buttleTs.atk = 11;
  998. buttleTs.hartInterval = 0.2;
  999. // 燃烧动画
  1000. let spAni = fire.children[0].getComponent(sp.Skeleton);
  1001. spAni.setSkin(level == 3 ? "l" : "h");
  1002. spAni.setAnimation(0, "k", false);
  1003. spAni.setAnimation(0, "ranshao", true);
  1004. // 燃烧瓶破碎音效
  1005. gameMgr.playEffect("Ranshaopingposui", fire);
  1006. gameMgr.playEffect("ranshao", fire);
  1007. })
  1008. .delay(3)
  1009. .to(0.3, { opacity: 50 })
  1010. .call(() => { fire.destroy(); })
  1011. .start();
  1012. }
  1013. }
  1014. this._fireCdTime = 4;
  1015. this.setSkillCD(SkillType.燃烧瓶, 4);
  1016. }
  1017. }
  1018. }