gameMgr.ts 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. import { cocosz } from "../Framework/CocosZ";
  2. import { utils } from "../../common-plugin/Scripts/Utils";
  3. import Constant, { ZindexLayer } from "../Framework/Constant";
  4. import { upgradeMgr } from "./UpgradeMgr";
  5. import setMap from "./setMap";
  6. import { VibrateType } from "../../common-plugin/Scripts/YZ_Constant";
  7. import Player from "./player";
  8. import ZombieBase from "./ZombieBase";
  9. import AESUtil from "../AESUtil"
  10. import ATSDK from "../AnyThinkAds/ATJSSDK";
  11. import ATRewardedVideoSDK from "../AnyThinkAds/ATRewardedVideoJSSDK";
  12. import AAJS2 from "../ATAndroidJS2";
  13. import GlobalManager from '../GlobalManager';
  14. const { ccclass, property } = cc._decorator;
  15. //tag:{0:攻击范围,1:玩家身体,2:玩家腿部 6,减速,7,毒区 11:墙,12:道具,13:武器,14:草,15:房子,16:物资箱, 17:海水, 18:升级仓, 19:旗台}
  16. export let gameMgr: GameMgr = null;
  17. @ccclass
  18. export default class GameMgr extends cc.Component {
  19. nodePoolObj: { [name: string]: cc.NodePool } = {}
  20. nodeGet(name: string, prefab: cc.Prefab): cc.Node {
  21. let node: cc.Node = null;
  22. // 创建新的节点池
  23. if (!this.nodePoolObj[name]) {
  24. this.nodePoolObj[name] = new cc.NodePool();
  25. }
  26. // 从节点池中获取节点
  27. if (this.nodePoolObj[name].size()) {
  28. node = this.nodePoolObj[name].get();
  29. } else if (prefab && prefab.isValid) {
  30. node = cc.instantiate(prefab);
  31. }
  32. // 防止预制体和节点名字不同
  33. if (node) { node.name = name; }
  34. return node;
  35. }
  36. nodePut(name: string, node: cc.Node): void {
  37. if (this.nodePoolObj[name] && node && node.isValid) {
  38. this.nodePoolObj[name].put(node);
  39. } else {
  40. cc.log("回收出错: ", name)
  41. }
  42. }
  43. canSHowGameBanner: boolean = true;
  44. tipLayer: cc.Node = null;
  45. setMapTs: setMap = null;
  46. playerTs: Player = null;
  47. uiGamePage: cc.Node = null;
  48. moveArea: cc.Node = null;
  49. yaogan: cc.Node = null;
  50. BtnBullet: cc.Node = null;
  51. posObj: object = {}
  52. // 躲猫猫模式
  53. dmmArr: cc.SpriteFrame[] = []
  54. @property(cc.Node)
  55. red: cc.Node = null;
  56. @property(cc.Prefab)
  57. hpTip: cc.Prefab = null;
  58. @property(cc.Prefab)
  59. effect_fire: cc.Prefab = null;
  60. @property(cc.Prefab)
  61. effect_hit: cc.Prefab = null;
  62. @property(cc.Prefab)
  63. itemList: cc.Prefab[] = [];
  64. @property(cc.Prefab)
  65. itemEffect: cc.Prefab[] = [];
  66. @property(cc.Prefab)
  67. spark: cc.Prefab = null;
  68. @property(cc.Prefab)
  69. blood: cc.Prefab = null;
  70. @property(cc.Prefab)
  71. testPoint: cc.Prefab = null;
  72. @property(cc.Prefab)
  73. player: cc.Prefab = null;
  74. @property(cc.SpriteFrame)
  75. jiaoyin: cc.SpriteFrame = null;
  76. @property(cc.Node)
  77. fj: cc.Node = null;
  78. @property(cc.Node)
  79. fjTip: cc.Node = null;
  80. @property(cc.Node)
  81. mainCamereRootNode: cc.Node = null;
  82. @property(cc.Camera)
  83. mainCamera: cc.Camera = null;
  84. // LIFE-CYCLE CALLBACKS:
  85. atk: cc.Node = null;
  86. safeCenter: cc.Vec2 = cc.v2(0, 0);
  87. redCircle: cc.Node = null;
  88. redCircle2: cc.Node = null;
  89. // mask: cc.Node = null;
  90. // maskMtl: cc.Material = null;
  91. mapSize: cc.Size = cc.winSize;
  92. miniMapSize: cc.Size = null;;
  93. btnSkill: cc.Node = null;
  94. btnSkillAd: cc.Node = null;
  95. rangedWeaponMess: cc.Node = null;
  96. rangedWeaponAdMess: cc.Node = null;
  97. ammo: cc.Label = null;
  98. ammoAd: cc.Label = null;
  99. kt: cc.Node = null;
  100. model6_touxiang: cc.Node = null;
  101. model6_btnShuxing: cc.Node = null;
  102. model6_shuxing: cc.Node = null;
  103. model6_jingyanBar: cc.ProgressBar = null;
  104. model6_levelLabel: cc.Label = null;
  105. model6_skillScrollView: cc.ScrollView = null;
  106. model6_skillScrollView_content: cc.Node = null;
  107. model6_skillScrollView_item: cc.Node = null;
  108. model6_timeLabel: cc.Label = null;
  109. model6_ts: cc.Node = null;
  110. model6_bossBar: cc.ProgressBar = null;
  111. timeStr: string = "";
  112. totalNum: number = 0;
  113. deathNum: number = 0;
  114. playerRank: number = 1;
  115. //通关条件: 1击败所有敌人 2击败boss 3抵达撤离点
  116. passCondition: number = 1;
  117. bossName: string = "";
  118. map: cc.Node = null;
  119. startPoint: cc.Node = null;
  120. atkRange: cc.Node = null;
  121. curTime: number = 0;
  122. timeLabel: cc.Label = null;
  123. snow: cc.Node = null;
  124. qlzc: cc.Node = null;
  125. onLoad() {
  126. gameMgr = this;
  127. gameMgr.mainCamera.zoomRatio = 0.65;
  128. cocosz.pauseCount = 0;
  129. }
  130. start() {
  131. this.mainCamereRootNode.setContentSize(cc.winSize);
  132. this.mainCamereRootNode.width += 500;
  133. this.mainCamereRootNode.height += 500;
  134. // 飞机任务提示
  135. if (this.fjTip) {
  136. if ([5, 7].includes(cocosz.gameMode)) {
  137. this.fjTip.active = false;
  138. } else {
  139. this.fjTip.active = true;
  140. this.fjTip.zIndex = ZindexLayer.zindex_max;
  141. }
  142. }
  143. }
  144. protected lateUpdate(): void {
  145. if (cocosz.isPause || gameMgr.isWin || gameMgr.isFail) return;
  146. this.cameraFollow();
  147. }
  148. initPos() {
  149. if (cocosz.gameMode == 7) {
  150. // 坐标
  151. // rolePos0
  152. let bluePos = cc.find('posLayer/bluePos', gameMgr.map);
  153. if (bluePos) this.posObj["bluePos"] = bluePos.getPosition();
  154. // rolePos1
  155. let redPos = cc.find('posLayer/redPos', gameMgr.map);
  156. if (redPos) this.posObj["redPos"] = redPos.getPosition();
  157. // path0
  158. this.posObj["pathPos0"] = [];
  159. let pathPos0 = cc.find('posLayer/pathPos0', gameMgr.map);
  160. pathPos0 && pathPos0.children.forEach(node => { this.posObj["pathPos0"].push(node.getPosition()); });
  161. // path1
  162. this.posObj["pathPos1"] = [];
  163. let pathPos1 = cc.find('posLayer/pathPos1', gameMgr.map);
  164. pathPos1 && pathPos1.children.forEach(node => { this.posObj["pathPos1"].push(node.getPosition()); });
  165. // path2
  166. this.posObj["pathPos2"] = [];
  167. let pathPos2 = cc.find('posLayer/pathPos2', gameMgr.map);
  168. pathPos2 && pathPos2.children.forEach(node => { this.posObj["pathPos2"].push(node.getPosition()); });
  169. }
  170. }
  171. startGame() {
  172. // 添加提示层
  173. this.tipLayer = new cc.Node();
  174. this.tipLayer.name = "tipLayer";
  175. this.tipLayer.zIndex = ZindexLayer.zindex_roleLabel;
  176. this.tipLayer.setPosition(cc.Vec2.ZERO);
  177. this.tipLayer.setParent(gameMgr.map);
  178. // 小地图
  179. if (cocosz.gameMode == 6) {
  180. this.schedule(() => { this.update_model6_shuxing(); }, 1);
  181. }
  182. this.initPlayer();
  183. }
  184. GameTime: number = 0;
  185. isGameStart: boolean = false;
  186. posList = [];
  187. initPlayer() {
  188. // 僵尸模式
  189. if (cocosz.gameMode == 6) {
  190. let player1 = cc.instantiate(this.player);
  191. player1.scale = 0.6;
  192. player1.setPosition(cc.v2(2000, 0).rotateSelf(2 * Math.PI * Math.random()));
  193. player1.setParent(this.map);
  194. this.totalNum++;
  195. // 飞机运输玩家
  196. this.fjEffect();
  197. }
  198. }
  199. fjEffect() {
  200. if (this.fj && this.playerTs) {
  201. this.uiGamePage.active = false;
  202. // 玩家
  203. this.scheduleOnce(() => {
  204. this.playerTs.node.opacity = 0;
  205. this.playerTs.playerMess.opacity = 1;
  206. this.playerTs.ghAniNode.opacity = 1;
  207. })
  208. // 相机
  209. this.followNode = this.fj;
  210. // 飞机
  211. this.fj.active = true;
  212. this.fj.setParent(gameMgr.map);
  213. this.scheduleOnce(() => { this.fj.zIndex = ZindexLayer.zindex_max; })
  214. let targetPos = cc.v2(this.playerTs.node.x, this.playerTs.node.y + 500);
  215. let dis = targetPos.sub(this.fj.getPosition());
  216. this.fj.scaleX = dis.x < 0 ? -1 : 1;
  217. // 动画
  218. let fjAni = this.fj.getComponent(sp.Skeleton);
  219. fjAni.addAnimation(0, "animation0", true);
  220. // 音效
  221. cocosz.audioMgr.playEffect("fj", true, 1);
  222. // 移动
  223. let t = dis.mag() / 800;
  224. cc.tween(this.fj)
  225. .to(t, { x: targetPos.x, y: targetPos.y })
  226. .call(() => {
  227. fjAni.setAnimation(0, "animation1", false);
  228. fjAni.addAnimation(0, "animation2", false);
  229. fjAni.addAnimation(0, "animation4", false);
  230. fjAni.addAnimation(0, "animation5", true);
  231. })
  232. .delay(2)
  233. .call(() => {
  234. // 隐藏提示
  235. if (this.fjTip) { this.fjTip.active = false; }
  236. this.fj.zIndex = ZindexLayer.zindex_max - 1;
  237. this.playerTs.node.zIndex = ZindexLayer.zindex_max;
  238. // 玩家下降
  239. this.playerTs.node.opacity = 255;
  240. this.playerTs.rig.active = false;
  241. this.followNode = this.playerTs.node;
  242. this.playerTs.node.y += 600;
  243. cc.tween(this.playerTs.node)
  244. .delay(0.5)
  245. .to(1, { y: this.playerTs.node.y - 600 })
  246. .call(() => {
  247. this.uiGamePage.active = true;
  248. this.playerTs.node.zIndex = ZindexLayer.zindex_player;
  249. this.playerTs.rig.active = true;
  250. this.playerTs.playerMess.opacity = 255;
  251. this.playerTs.ghAniNode.opacity = 255;
  252. this.playerTs.updateAni("daiji_body", true);
  253. // 初始化游戏
  254. this.initGame();
  255. if (cocosz.gameMode == 6) {
  256. // 生成僵尸计时
  257. this.schedule(this.createZombieCount, 1);
  258. } else {
  259. cc.log("模式有问题")
  260. }
  261. })
  262. .start();
  263. })
  264. .delay(2)
  265. .call(() => {
  266. this.fj.zIndex = ZindexLayer.zindex_max;
  267. fjAni.setAnimation(0, "animation6", false);
  268. fjAni.addAnimation(0, "animation7", false);
  269. fjAni.addAnimation(0, "animation9", false);
  270. fjAni.addAnimation(0, "animation0", true);
  271. })
  272. .delay(2)
  273. .to(2, { position: cc.v3(dis.normalize().mulSelf(2000).add(dis)) })
  274. .call(() => {
  275. cocosz.audioMgr.stopEffect("fj");
  276. this.fj.destroy();
  277. })
  278. .start();
  279. }
  280. }
  281. showGameTime() {
  282. if (this.model6_timeLabel && this.model6_timeLabel.isValid) {
  283. let s = this.GameTime;// 秒
  284. let m = 0;// 分
  285. let h = 0;// 小时
  286. if (s > 60) {
  287. m = Math.floor(s / 60);
  288. s = Math.floor(s % 60);
  289. if (m > 60) {
  290. h = Math.floor(m / 60);
  291. m = Math.floor(m % 60);
  292. }
  293. }
  294. let r = "";
  295. r += (h == 0 ? "" : h + ":");
  296. r += (m >= 10 ? "" + m : "0" + m);
  297. r += (s >= 10 ? ":" + s : ":0" + s);
  298. this.timeStr = r;
  299. this.model6_timeLabel.string = r;
  300. }
  301. }
  302. // 刷新血滴
  303. update_model6_xuedi() {
  304. if (gameMgr.playerTs && gameMgr.playerTs.hpNumNode && gameMgr.playerTs.hpNumNode.isValid) {
  305. gameMgr.playerTs.hpNumNode.active = true;
  306. gameMgr.playerTs.hpNumNode.width = Math.min(250, gameMgr.playerTs.totleHp * 50);
  307. gameMgr.playerTs.hpNumNode.children.forEach((n, i) => {
  308. if (i < gameMgr.playerTs.totleHp) {
  309. n.active = true;
  310. if (i < gameMgr.playerTs.HP) {
  311. n.children[1].opacity = 255;
  312. } else {
  313. n.children[1].opacity = 0;
  314. }
  315. } else {
  316. n.active = false;
  317. }
  318. })
  319. }
  320. }
  321. // 刷新属性
  322. update_model6_shuxing() {
  323. if (upgradeMgr && gameMgr && gameMgr.model6_shuxing && gameMgr.model6_shuxing.isValid && gameMgr.model6_shuxing.active) {
  324. // 等级
  325. this.model6_shuxing.children[0].getComponent(cc.Label).string = upgradeMgr.curLevel.toString();
  326. // 伤害
  327. this.model6_shuxing.children[1].getComponent(cc.Label).string = (gameMgr.playerTs.atkNum * gameMgr.playerTs.atkRate).toFixed(0);
  328. // 射速
  329. this.model6_shuxing.children[2].getComponent(cc.Label).string = (gameMgr.playerTs.atkSpeed * gameMgr.playerTs.atkSpeedRate).toFixed(1);
  330. // 换弹
  331. this.model6_shuxing.children[3].getComponent(cc.Label).string = (gameMgr.playerTs.reloadSpeed * gameMgr.playerTs.reloadRate).toFixed(1);
  332. // 弹夹容量
  333. this.model6_shuxing.children[4].getComponent(cc.Label).string = gameMgr.playerTs.curWeapon.bulletNum.toString();
  334. // 移动速度
  335. this.model6_shuxing.children[5].getComponent(cc.Label).string = (gameMgr.playerTs.MoveSpeed * gameMgr.playerTs.speedRate).toFixed(0);
  336. // 拾取范围
  337. this.model6_shuxing.children[6].getComponent(cc.Label).string = upgradeMgr.jingyanRange.toString();
  338. }
  339. }
  340. showBossHp(rate: number) {
  341. if (rate > 0) {
  342. if (this.model6_bossBar && cc.isValid(this.model6_bossBar)) {
  343. this.model6_bossBar.node.active = true;
  344. this.model6_bossBar.progress = rate;
  345. }
  346. if (this.model6_jingyanBar && cc.isValid(this.model6_jingyanBar)) {
  347. this.model6_jingyanBar.node.active = false;
  348. }
  349. if (this.model6_levelLabel && cc.isValid(this.model6_levelLabel)) {
  350. this.model6_levelLabel.node.active = false;
  351. }
  352. } else {
  353. if (this.model6_bossBar && cc.isValid(this.model6_bossBar)) {
  354. this.model6_bossBar.node.active = false;
  355. this.model6_bossBar.progress = rate;
  356. }
  357. if (this.model6_jingyanBar && cc.isValid(this.model6_jingyanBar)) {
  358. this.model6_jingyanBar.node.active = true;
  359. }
  360. if (this.model6_levelLabel && cc.isValid(this.model6_levelLabel)) {
  361. this.model6_levelLabel.node.active = true;
  362. }
  363. }
  364. }
  365. boss_border: cc.Node = null;
  366. zombieTime: number = 0;
  367. zombieCurNum: number = 0;
  368. zombieMaxNum: number = 0;
  369. zombieLength: number = 2;
  370. zombieArr = ["zombie_basic", "zombie_run", "zombie_drum", "zombie_jump", "zombie_bomb", "zombie_tank", "zombie_poison"]
  371. bossArr = ["boss1", "boss2", "boss3", "boss4", "boss11", "boss5", "boss12", "boss6", "boss7", "boss8", "boss9", "boss10", "boss13"]
  372. boss2Arr = [];
  373. /** 创建僵尸计时 */
  374. createZombieCount() {
  375. if (cocosz.isPause || gameMgr.isWin || gameMgr.isFail) return;
  376. // 游戏计时
  377. this.GameTime++;
  378. this.showGameTime();
  379. // 生成逻辑
  380. if (this.boss_border) return;
  381. // 僵尸生成时间计时
  382. this.zombieTime++;
  383. let count = 1;
  384. /** 创建Boss */
  385. if (0 === this.zombieTime % 100) {
  386. this.createBossZombie();
  387. // 更新普通僵尸
  388. if (this.zombieLength < this.zombieArr.length) this.zombieLength++;
  389. }
  390. // 大波僵尸
  391. else if (0 === this.zombieTime % 50) {
  392. // 提示
  393. if (this.model6_ts) {
  394. this.model6_ts.active = true;
  395. this.scheduleOnce(() => { this.model6_ts.active = false; }, 3)
  396. let spAni = this.model6_ts.getComponent(sp.Skeleton);
  397. spAni.setSkin("sclx_" + cocosz.curLanguage);
  398. spAni.setAnimation(0, "animation", true);
  399. }
  400. // 僵尸数量
  401. this.zombieMaxNum = 20 + Math.floor(this.zombieTime / 40) * 10;
  402. if (this.zombieMaxNum > 40) this.zombieMaxNum = 40;
  403. // 小于最大数量继续生成
  404. if (this.zombieCurNum < this.zombieMaxNum) {
  405. count = this.zombieMaxNum - this.zombieCurNum;
  406. // 分成k份生成,每份10
  407. let k = Math.ceil(count / 10);
  408. // 分帧创建
  409. let angle: number = 0;
  410. let inter: number = 36;
  411. for (let i = 0; i < k; i++) {
  412. this.schedule(() => {
  413. angle += inter;
  414. this.createCommonZombie(cc.winSize.height / 2.5 / this.mainCamera.zoomRatio, angle);
  415. }, 0.1, Math.ceil(count / k), i);
  416. }
  417. }
  418. // 生成击败boss
  419. for (let i = this.boss2Arr.length - 1; i >= 0 && i >= this.boss2Arr.length - 2; i--) {
  420. let resName = this.boss2Arr[i];
  421. cc.log("创建尸潮boss: ", resName)
  422. if (resName) { this.createZombie(resName, gameMgr.playerTs.node.getPosition(), cc.winSize.width / 2 / this.mainCamera.zoomRatio); }
  423. }
  424. }
  425. // 僵尸继续
  426. else if (0 === this.zombieTime % 51 || 0 === this.zombieTime % 52 || 0 === this.zombieTime % 53 || 0 === this.zombieTime % 54 || 0 === this.zombieTime % 55) {
  427. }
  428. // 随机少量僵尸
  429. else {
  430. // 僵尸数量
  431. this.zombieMaxNum = 5 + Math.floor(this.zombieTime / 20) * 5;
  432. if (this.zombieMaxNum > 20) this.zombieMaxNum = 20;
  433. // 小于最大数量继续生成
  434. if (this.zombieCurNum < this.zombieMaxNum) {
  435. // 随机数量
  436. count = Math.ceil(Math.random() * 4);
  437. this.schedule(() => { this.createCommonZombie(cc.winSize.height / 2.5 / this.mainCamera.zoomRatio); }, 0.1, count);
  438. }
  439. }
  440. }
  441. /** 创建普通僵尸 */
  442. createCommonZombie(dis: number, angle?: number) {
  443. let index = Math.floor(Math.random() * this.zombieLength);
  444. let resName = this.zombieArr[index];
  445. if (resName) { this.createZombie(resName, gameMgr.playerTs.node.getPosition(), dis, angle); }
  446. }
  447. /** 创建Boss僵尸 */
  448. createBossZombie() {
  449. if (this.bossArr.length) {
  450. this.createBossBorder();
  451. // 提示
  452. if (this.model6_ts) {
  453. this.model6_ts.active = true;
  454. this.scheduleOnce(() => { this.model6_ts.active = false; }, 3)
  455. let spAni = this.model6_ts.getComponent(sp.Skeleton);
  456. spAni.setSkin("bosslx_" + cocosz.curLanguage);
  457. spAni.setAnimation(0, "animation", true);
  458. }
  459. // boss
  460. let resName = this.bossArr.shift();
  461. let centerPos = gameMgr.playerTs.node.getPosition();
  462. if (this.boss_border) {
  463. centerPos = this.boss_border.getPosition();
  464. }
  465. if (resName) {
  466. this.boss2Arr.push(resName);
  467. this.createZombie(resName, centerPos, 300, null, true);
  468. }
  469. }
  470. }
  471. /** 创建boss边界 */
  472. createBossBorder() {
  473. // 边界
  474. let pre = cocosz.resMgr.getRes("boss_border", cc.Prefab);
  475. if (pre) {
  476. this.boss_border = cc.instantiate(pre);
  477. this.boss_border.setPosition(gameMgr.playerTs.node.getPosition());
  478. if (this.boss_border.x - this.boss_border.width / 2 < -gameMgr.mapSize.width / 2) {
  479. this.boss_border.x = -gameMgr.mapSize.width / 2 + this.boss_border.width / 2 + 100;
  480. } else if (this.boss_border.x + this.boss_border.width / 2 > gameMgr.mapSize.width / 2) {
  481. this.boss_border.x = gameMgr.mapSize.width / 2 - this.boss_border.width / 2 - 100;
  482. }
  483. if (this.boss_border.y - this.boss_border.height / 2 < -gameMgr.mapSize.height / 2) {
  484. this.boss_border.y = -gameMgr.mapSize.height / 2 + this.boss_border.height / 2 + 100;
  485. } else if (this.boss_border.y + this.boss_border.height / 2 > gameMgr.mapSize.height / 2) {
  486. this.boss_border.y = gameMgr.mapSize.height / 2 - this.boss_border.height / 2 - 300;
  487. }
  488. this.boss_border.setParent(this.map);
  489. }
  490. }
  491. /** 创建僵尸 */
  492. createZombie(resName: string, center: cc.Vec2, dis: number, angle?: number, isBoss: boolean = false) {
  493. // 预制体
  494. let prefab = cocosz.resMgr.getRes(resName, cc.Prefab);
  495. if (prefab) {
  496. // 坐标
  497. this._recursionCount = 0;
  498. let pos = this.getZombieBirthPos(center, dis, angle);
  499. if (pos) {
  500. // 僵尸
  501. let newZombie: cc.Node = this.nodeGet(resName, prefab);
  502. if (newZombie) {
  503. let ts = newZombie.getComponent(ZombieBase);
  504. if (ts && isBoss) { ts.isBoss = true; }
  505. newZombie.setPosition(pos);
  506. newZombie.setParent(gameMgr.map);
  507. if (ts) ts.initNode();
  508. }
  509. }
  510. } else {
  511. cocosz.resMgr.loadAndCacheRes("prefab_zombie/" + resName, cc.Prefab, null, (err, res) => {
  512. if (!err) {
  513. this.createZombie(resName, center, dis, angle, isBoss);
  514. }
  515. })
  516. }
  517. }
  518. /** 获取僵尸生成坐标 */
  519. private _recursionCount: number = 0;
  520. getZombieBirthPos(center: cc.Vec2, dis, angle?: number) {
  521. if (++this._recursionCount > 100) {
  522. return null;
  523. }
  524. let radians = 0;
  525. if (angle == null || angle == undefined) {
  526. radians = 2 * Math.PI * Math.random();
  527. } else {
  528. radians = cc.misc.degreesToRadians(angle);
  529. }
  530. let dif = cc.v2(dis + Math.floor(200 * Math.random()), 0).rotateSelf(radians);
  531. let pos = center.add(dif);
  532. if (pos.x > -gameMgr.mapSize.width / 2 + 400 && pos.x < gameMgr.mapSize.width / 2 - 400 &&
  533. pos.y < gameMgr.mapSize.height / 2 - 400 && pos.y > -gameMgr.mapSize.height / 2 + 400) {
  534. return pos;
  535. } else {
  536. return this.getZombieBirthPos(center, dis);
  537. }
  538. }
  539. lastTime: number = 0;
  540. safeTime: number = 40;
  541. startPos: cc.Vec2 = null;
  542. initGame() {
  543. this.startPos = this.yaogan.getPosition();
  544. this.isGameStart = true;
  545. cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.keyDown, this);
  546. cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.keyUp, this);
  547. this.moveArea.on(cc.Node.EventType.TOUCH_START, ((event: cc.Touch) => {
  548. let pos = event.getLocation();
  549. pos = this.node.convertToNodeSpaceAR(pos);
  550. this.yaogan.setPosition(pos);
  551. }), this);
  552. this.moveArea.on(cc.Node.EventType.TOUCH_MOVE, ((event: cc.Touch) => {
  553. let div = event.getLocation().sub(event.getStartLocation());
  554. if (div.mag() > 160) {
  555. div = div.mul(160 / div.mag());
  556. }
  557. this.yaogan.children[0].setPosition(div);
  558. gameMgr.playerTs.moveDir = div.normalize();
  559. }), this)
  560. this.moveArea.on(cc.Node.EventType.TOUCH_END, ((event: cc.Touch) => {
  561. this.yaogan.setPosition(this.startPos);
  562. this.yaogan.children[0].setPosition(cc.v2(0, 0));
  563. gameMgr.playerTs.moveDir = cc.v2(0, 0);
  564. }), this)
  565. this.moveArea.on(cc.Node.EventType.TOUCH_CANCEL, ((event: cc.Touch) => {
  566. this.yaogan.setPosition(this.startPos);
  567. this.yaogan.children[0].setPosition(cc.v2(0, 0));
  568. gameMgr.playerTs.moveDir = cc.v2(0, 0);
  569. }), this)
  570. }
  571. isUp: boolean = false;
  572. isDown: boolean = false;
  573. isLeft: boolean = false;
  574. isRight: boolean = false;
  575. keyDown(event: cc.Event.EventKeyboard) {
  576. switch (event.keyCode) {
  577. case 87: {
  578. if (!this.isUp) {
  579. this.isUp = true;
  580. this.setDir();
  581. }
  582. break;
  583. }
  584. case 83: {
  585. if (!this.isDown) {
  586. this.isDown = true;
  587. this.setDir();
  588. }
  589. break;
  590. }
  591. case 65: {
  592. if (!this.isLeft) {
  593. this.isLeft = true;
  594. this.setDir();
  595. }
  596. break;
  597. }
  598. case 68: {
  599. if (!this.isRight) {
  600. this.isRight = true;
  601. this.setDir();
  602. }
  603. break;
  604. }
  605. }
  606. }
  607. keyUp(event) {
  608. switch (event.keyCode) {
  609. case 87: {
  610. this.isUp = false;
  611. this.setDir();
  612. break;
  613. }
  614. case 83: {
  615. this.isDown = false;
  616. this.setDir();
  617. break;
  618. }
  619. case 65: {
  620. this.isLeft = false;
  621. this.setDir();
  622. break;
  623. }
  624. case 68: {
  625. this.isRight = false;
  626. this.setDir();
  627. break;
  628. }
  629. }
  630. }
  631. followNode: cc.Node;
  632. isPre: boolean = true;
  633. cameraFollow() {
  634. let pos_to = null;
  635. let t = 0.1;
  636. if (this.followNode && this.followNode.isValid) {
  637. pos_to = this.followNode.getPosition();
  638. t = 0.1;
  639. }
  640. if (pos_to) {
  641. let pos_from = this.mainCamereRootNode.getPosition();
  642. let pos_out = cc.Vec2.ZERO;
  643. let ratio = this.mainCamera.zoomRatio;
  644. let winSize = new cc.Size(cc.winSize.width / ratio, cc.winSize.height / ratio);
  645. if (cocosz.gameMode == 7) {
  646. // 无边界
  647. } else {
  648. // 相机边界
  649. if ((pos_to.x + winSize.width / 2) > gameMgr.mapSize.width / 2) {
  650. pos_to.x = gameMgr.mapSize.width / 2 - winSize.width / 2;
  651. } else if ((pos_to.x - winSize.width / 2) < -gameMgr.mapSize.width / 2) {
  652. pos_to.x = -gameMgr.mapSize.width / 2 + winSize.width / 2;
  653. }
  654. if ((pos_to.y + winSize.height / 2) > gameMgr.mapSize.height / 2) {
  655. pos_to.y = gameMgr.mapSize.height / 2 - winSize.height / 2;
  656. } else if ((pos_to.y - winSize.height / 2) < -gameMgr.mapSize.height / 2) {
  657. pos_to.y = -gameMgr.mapSize.height / 2 + winSize.height / 2;
  658. }
  659. }
  660. if (pos_to.sub(pos_from).mag() < 1000) {
  661. cc.Vec2.lerp(pos_out, pos_from, pos_to, t);
  662. this.mainCamereRootNode.setPosition(pos_out);
  663. } else {
  664. this.mainCamereRootNode.setPosition(pos_to);
  665. // 更新节点透明度
  666. gameMgr.setMapTs && gameMgr.setMapTs.checkAllNode();
  667. }
  668. }
  669. }
  670. setDir() {
  671. let moveDir = cc.v2(0, 0);
  672. if (this.isUp) {
  673. moveDir.y++;
  674. }
  675. if (this.isLeft) {
  676. moveDir.x--;
  677. }
  678. if (this.isRight) {
  679. moveDir.x++;
  680. }
  681. if (this.isDown) {
  682. moveDir.y--;
  683. }
  684. this.playerTs.moveDir = moveDir.normalize();
  685. }
  686. restart() { }
  687. useMeleeWeapon() { }
  688. useRangedWeapon() {
  689. this.playerTs.changeCurWeapon(this.playerTs.rangedWeapon);
  690. }
  691. useRangedWeaponAd() {
  692. this.playerTs.changeCurWeapon(this.playerTs.rangedWeaponAd);
  693. }
  694. getNewWeapon() {
  695. cocosz.audioMgr.playEffect("changeWeapon");
  696. this.playerTs.setNewWeapon();
  697. }
  698. clipNameArr: any = {};
  699. playEffect(name: string, node?: cc.Node, interval: number = 0.2) {
  700. if (gameMgr.isWin || gameMgr.isFail || cocosz.isPause) return;
  701. if (this.clipNameArr[name]) {
  702. return;
  703. }
  704. let voice = 1;
  705. if (node && node.isValid && node.parent && node.parent.isValid) {
  706. let pos = node.getPosition();
  707. pos = node.parent.convertToWorldSpaceAR(pos);
  708. let pos2 = this.playerTs.node.getPosition();
  709. pos2 = this.playerTs.node.parent.convertToWorldSpaceAR(pos2);
  710. let dt = pos.sub(pos2).mag();
  711. if (dt > 2000) { return; }
  712. }
  713. cocosz.audioMgr.playEffect(name, false, voice);
  714. if (interval > 0) {
  715. this.clipNameArr[name] = 1;
  716. this.scheduleOnce(() => { this.clipNameArr[name] = 0; }, interval);
  717. }
  718. }
  719. playClip(clip: cc.AudioClip, node: cc.Node, interval: number = 0.2) {
  720. if (gameMgr.isWin || gameMgr.isFail || cocosz.isPause) return;
  721. if (this.clipNameArr[clip.name]) {
  722. return;
  723. }
  724. let voice = 1;
  725. if (node && node.isValid && node.parent && node.parent.isValid) {
  726. let pos = node.getPosition();
  727. pos = node.parent.convertToWorldSpaceAR(pos);
  728. let pos2 = this.playerTs.node.getPosition();
  729. pos2 = this.playerTs.node.parent.convertToWorldSpaceAR(pos2);
  730. let dt = pos.sub(pos2).mag();
  731. if (dt > 2000) { return; }
  732. }
  733. cocosz.audioMgr.playClip(clip, false, voice);
  734. // 记录
  735. if (interval > 0) {
  736. this.clipNameArr[clip.name] = 1;
  737. this.scheduleOnce(() => { this.clipNameArr[clip.name] = 0; }, interval);
  738. }
  739. }
  740. /** 文字提示效果 */
  741. showRoleTip(node: cc.Node, str: string, labelColor: cc.Color = cc.Color.WHITE) {
  742. if (node && node.isValid && this.hpTip && this.hpTip.isValid && gameMgr.tipLayer) {
  743. let tipNode = this.nodeGet("hpTip", this.hpTip);
  744. if (tipNode) {
  745. tipNode.setParent(gameMgr.tipLayer);
  746. // 初始化
  747. tipNode.setPosition(node.x + 200 * (Math.random() - 0.5), node.y + node.height / 2);
  748. tipNode.opacity = 255;
  749. tipNode.color = labelColor;
  750. tipNode.scale = (labelColor == cc.Color.WHITE ? 1 : 1.2);
  751. // 字体内容
  752. let tipLabel = tipNode.getComponent(cc.Label);
  753. if (tipLabel) { tipLabel.string = str; }
  754. // 动效
  755. tipNode.stopAllActions();
  756. cc.tween(tipNode)
  757. .by(0.5, { y: 20, scale: 1, })
  758. .by(0.3, { y: 10, scale: -1, opacity: -255 })
  759. .call(() => { this.nodePut("hpTip", tipNode); })
  760. .start();
  761. }
  762. }
  763. }
  764. isFail: boolean = false;
  765. fail() {
  766. if (this.isWin || this.isFail) return;
  767. cocosz.pauseCount++;
  768. this.isFail = true;
  769. this.unscheduleAllCallbacks();
  770. upgradeMgr && upgradeMgr.unscheduleAllCallbacks();
  771. this.scheduleOnce(() => {
  772. this.qlzc.active = true;
  773. cc.tween(this.qlzc)
  774. .delay(0.3)
  775. .call(() => { this.qlzc.getChildByName("dian").children[0].active = true })
  776. .delay(0.3)
  777. .call(() => { this.qlzc.getChildByName("dian").children[1].active = true })
  778. .delay(0.3)
  779. .call(() => { this.qlzc.getChildByName("dian").children[2].active = true })
  780. .delay(0.3)
  781. .call(() => {
  782. this.qlzc.getChildByName("dian").children[0].active = false;
  783. this.qlzc.getChildByName("dian").children[1].active = false;
  784. this.qlzc.getChildByName("dian").children[2].active = false;
  785. })
  786. .union()
  787. .repeatForever()
  788. .start();
  789. }, 2)
  790. this.scheduleOnce(() => {
  791. cocosz.gameMgr.gameFailed();
  792. }, 4)
  793. }
  794. isWin: boolean = false;
  795. win() {
  796. if (this.isWin || this.isFail) return;
  797. cocosz.pauseCount++;
  798. this.isWin = true;
  799. this.unscheduleAllCallbacks();
  800. upgradeMgr && upgradeMgr.unscheduleAllCallbacks();
  801. this.scheduleOnce(() => {
  802. this.qlzc.active = true;
  803. cc.tween(this.qlzc)
  804. .delay(0.3)
  805. .call(() => { this.qlzc.getChildByName("dian").children[0].active = true })
  806. .delay(0.3)
  807. .call(() => { this.qlzc.getChildByName("dian").children[1].active = true })
  808. .delay(0.3)
  809. .call(() => { this.qlzc.getChildByName("dian").children[2].active = true })
  810. .delay(0.3)
  811. .call(() => {
  812. this.qlzc.getChildByName("dian").children[0].active = false;
  813. this.qlzc.getChildByName("dian").children[1].active = false;
  814. this.qlzc.getChildByName("dian").children[2].active = false;
  815. })
  816. .union()
  817. .repeatForever()
  818. .start();
  819. }, 2)
  820. this.scheduleOnce(() => {
  821. cocosz.gameMgr.gameSuccess();
  822. }, 4)
  823. }
  824. isRevive: boolean = false;
  825. revive() {
  826. this.isRevive = true;
  827. this.playerTs.revive();
  828. }
  829. /**
  830. * 震屏
  831. * @param dis 范围
  832. * @param times 次数
  833. * @param isVibrate 是否震动
  834. * @returns
  835. */
  836. private _timeArr = [0, 0.04, 0.05, 0.06, 0.07];
  837. private _disArr = [0, 3, 10, 20, 30];
  838. private _vibrateTime: number = 0;// 震动时间
  839. public shakeEffect(extent: 0 | 1 | 2 | 3 | 4 = 1, times: number = 1, isVibrate: boolean = true, vibrateType: VibrateType = VibrateType.Short) {
  840. // 镜头晃动
  841. let t = this._timeArr[extent];
  842. let dis = this._disArr[extent];
  843. if (extent > 0 && times > 0) {
  844. this.mainCamera.node.stopAllActions();
  845. this.mainCamera.node.setPosition(0, 0, 0);
  846. cc.tween(this.mainCamera.node)
  847. .to(t, { position: cc.v3(dis, dis) })
  848. .to(t, { position: cc.v3(0, -dis) })
  849. .to(t, { position: cc.v3(-dis, dis) })
  850. .to(t, { position: cc.v3(-dis, -dis) })
  851. .to(t, { position: cc.v3(0, dis) })
  852. .to(t, { position: cc.v3(0, 0) })
  853. .union()
  854. .repeat(times)
  855. .start();
  856. }
  857. // 震动,间隔1秒
  858. if (cocosz.dataMgr.ShakeOn) {
  859. const currentTime = new Date().getTime();
  860. if (currentTime - this._vibrateTime > 1000) { // 间隔调整为1000毫秒即1秒
  861. this._vibrateTime = currentTime;
  862. if (isVibrate) {
  863. if (vibrateType == VibrateType.Short) {
  864. AAJS2.appVibrateShort();
  865. } else {
  866. AAJS2.appVibrateLong();
  867. }
  868. }
  869. }
  870. }
  871. if(2>1){
  872. return;
  873. }
  874. // 震动,间隔1秒
  875. if (cocosz.dataMgr.ShakeOn) {
  876. let t = new Date().getTime();
  877. if (t - this._vibrateTime > 500) {
  878. this._vibrateTime = t;
  879. isVibrate && utils.vibrate(vibrateType);
  880. }
  881. }
  882. }
  883. guideSkip() {
  884. // 新手指引跳过
  885. }
  886. }