game.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. /**
  2. * @author uu
  3. * @file 游戏控制
  4. */
  5. var AC = require('action')
  6. const ADSdk = require('ADSdk');
  7. cc.Class({
  8. extends: cc.Component,
  9. properties: {
  10. _status: 0, //0 未开始 1 游戏开始 2 游戏暂停 3 游戏结束 4 下落状态 5无法触摸状态
  11. blockPrefab: cc.Prefab,
  12. blockSprite: [cc.SpriteFrame], //todo: 换成动态生成 暂不处理
  13. warningSpriteFrame: [cc.SpriteFrame],
  14. propSpriteFrame: [cc.SpriteFrame],
  15. checkMgr: require("check"),
  16. revivePage: cc.Node,
  17. tutorialNode: cc.Node,
  18. shareBtn: cc.Node,
  19. shareSuccessDialog: cc.Node,
  20. redBtnSprite: cc.Sprite,
  21. redBtnSpriteFrame: [cc.SpriteFrame],
  22. moneyLabel:cc.Label,
  23. redBagIcon:cc.Prefab,
  24. signInBtn:cc.Node,
  25. // bombAddLabel:cc.Label,
  26. // btnLabel:cc.Label,
  27. },
  28. start() {
  29. this.showRedBtn();
  30. this.showSignInBtn();
  31. this.bindNode()
  32. this.generatePool()
  33. this.loadRes()
  34. // this.btnLabel.string = "确定";
  35. // this.bombAddLabel.string = "炸弹+1";
  36. },
  37. showRedBtn() {
  38. if (Utils.hadRedPacket()) {
  39. this.redBtnSprite.spriteFrame = this.redBtnSpriteFrame[1];
  40. this.moneyLabel.node.active = false
  41. } else {
  42. this.redBtnSprite.spriteFrame = this.redBtnSpriteFrame[0];
  43. this.moneyLabel.node.active = true;
  44. let moneyNum = Utils.getRedPacketNum();
  45. if (moneyNum == 0) moneyNum = "0.00";
  46. this.moneyLabel.string = moneyNum + "元";
  47. }
  48. },
  49. showSignInBtn() {
  50. if (Utils.isSecondDay()) {
  51. Utils.clearSignIn();
  52. }
  53. if(Utils.hadSignIn()){
  54. this.signInBtn.active = false;
  55. }else{
  56. this.signInBtn.active = true;
  57. }
  58. },
  59. closeRedUIAni() {
  60. let btn = this.redBtnSprite.node;
  61. let position = btn.convertToWorldSpaceAR(cc.v2(0, 0));// btn转世界坐标
  62. position = this.node.convertToNodeSpaceAR(position);// 世界坐标转game节点下坐标
  63. let node = cc.instantiate(this.redBagIcon);
  64. node.parent = this.node;
  65. node.runAction(
  66. cc.sequence(
  67. cc.moveTo(0.5, position),
  68. cc.scaleTo(0.3, 1, 1),
  69. cc.callFunc(() => { node.destroy(); })
  70. ));
  71. },
  72. loadRes() {
  73. },
  74. init(c) {
  75. this._controller = c
  76. this._score = c.scoreMgr
  77. this.rowNum = c.config.json.rowNum
  78. this.gap = c.config.json.gap
  79. this.animationSpeed = c.config.json.gap
  80. this.blockWidth = (730 - (this.rowNum + 1) * this.gap) / this.rowNum
  81. this.reviveTimer = null
  82. this.tutorialNode.active = false
  83. // this.isWeChat = this._controller.social.node.active
  84. this.shareSuccessDialog.active = false
  85. //console.log(this.gap)
  86. //console.log(this.blockWidth)
  87. },
  88. showBanner() {
  89. },
  90. // 动态获取需要动态控制的组件
  91. bindNode() {
  92. this.blocksContainer = this.node.getChildByName('map')
  93. },
  94. //---------------- 游戏控制 ---------------------
  95. // 游戏开始
  96. gameStart() {
  97. this.recoveryAllBlocks().then()
  98. this.shareBtn.active = true
  99. // if (this.isWeChat) {
  100. // this._controller.social.hasShared = false
  101. // }
  102. this._score.init(this)
  103. let data = [
  104. [1, 1, 1, 1, 1, 1, 1, 1],
  105. [1, 1, 1, 1, 1, 1, 1, 1],
  106. [4, 2, 3, 4, 2, 2, 3, 4]
  107. ]
  108. if (this.isFirstTime()) {
  109. this.mapSet(this.rowNum, data).then((result) => {
  110. this.showTutorial(this.map[1][4], '点击连续的区域生成炸弹鸭')
  111. this.tutorialProgress = 1
  112. this._status = 1
  113. })
  114. } else {
  115. this.mapSet(this.rowNum).then((result) => {
  116. this._status = 1
  117. })
  118. }
  119. },
  120. showTutorial(target, label) {
  121. this.tutorialNode.active = true
  122. this.tutorialNode.getChildByName('targetBtn').getChildByName('sqr').runAction(cc.repeatForever(cc.sequence(cc.scaleTo(0.3, 0.8), cc.scaleTo(0.3, 1.2))))
  123. this.tutorialNode.getChildByName('target').x = target.x
  124. this.tutorialNode.getChildByName('target').y = target.y
  125. this.tutorialNode.getChildByName('targetBtn').x = target.x
  126. this.tutorialNode.getChildByName('targetBtn').y = target.y
  127. this.tutorialNode.getChildByName('label').getChildByName('label').getComponent(cc.Label).string = label
  128. },
  129. closeTutorial() {
  130. this.tutorialNode.getChildByName('targetBtn').getChildByName('sqr').stopAllActions()
  131. // console.log('close Tutorial ')
  132. this.tutorialNode.active = false
  133. this._status = 1
  134. this.map[1][4].getComponent('cell').onTouched({
  135. type: 1
  136. }, false, false)
  137. if (this.tutorialProgress == 1) {
  138. setTimeout(() => {
  139. this.showTutorial(this.map[1][4], '点击炸弹消除所有同色方块哦')
  140. this.tutorialProgress = 2
  141. }, 1000)
  142. }
  143. },
  144. isFirstTime() {
  145. let isFirst = false
  146. if (this.isWeChat && !wx.getStorageSync('isFirst')) {
  147. wx.setStorageSync('isFirst', "1")
  148. isFirst = true
  149. } else if (!cc.sys.localStorage.getItem('isFirst')) {
  150. cc.sys.localStorage.setItem('isFirst', "1")
  151. isFirst = true
  152. }
  153. return isFirst
  154. },
  155. onItemShare() {
  156. // if (this.isWeChat) {
  157. // this._controller.social.onItemShareButton()
  158. // } else {
  159. this.fakeShareSuccess()
  160. // }
  161. },
  162. onItemAdv() {
  163. // TODO 广告 视频炸弹
  164. if (AppConst.SHOWADUI) {
  165. if (AppConst.CHANNEL == AppConst.channel.ANDROID) {
  166. ADSdk.pay(1, this);
  167. } else {
  168. ADSdk.showVideo(null, (result) => {
  169. if (result == 1) {
  170. this.fakeShareSuccess()
  171. }
  172. });
  173. }
  174. } else {
  175. this.fakeShareSuccess()
  176. }
  177. // this.fakeShareSuccess()
  178. // self._controller.scoreMgr.onLevelUpButton()
  179. },
  180. fakeShareSuccess() {
  181. this.shareBtn.active = false
  182. this.shareSuccessDialog.active = true
  183. // 2分钟后再次弹出 炸弹按钮
  184. this.scheduleOnce(() => {
  185. this.shareBtn.active = true;
  186. }, 120);
  187. },
  188. onCreateBomb() {
  189. let x = Math.floor(Math.random() * 8)
  190. let y = Math.floor(Math.random() * 8)
  191. this.shareSuccessDialog.active = false
  192. if(this.map[x][y].getComponent('cell')._itemType==0){
  193. this.map[x][y].getComponent('cell').changeItemType(2)
  194. }else{
  195. this.onCreateBomb()
  196. return
  197. }
  198. },
  199. /**
  200. * 初始化地图
  201. * @param {*} num
  202. * @param {*} data 传入颜色数组
  203. */
  204. mapSet(num, data) {
  205. this.map = new Array()
  206. let self = this
  207. // 生成两个随机的对象数组
  208. let a = Math.floor(Math.random() * num)
  209. let b = Math.floor(Math.random() * num)
  210. let c = Math.floor(1 + Math.random() * (num - 1)) - 1
  211. a == c ? c++ : ''
  212. let d = Math.floor(Math.random() * num)
  213. this.tutorialPos = [c, d]
  214. return new Promise((resolve, reject) => {
  215. for (let i = 0; i < num; i++) { //行
  216. this.map[i] = new Array()
  217. for (let j = 0; j < num; j++) { //列
  218. let itemType = (i == a && j == b) ? 1 : (i == c && j == d) ? (data ? 1 : 2) : 0
  219. self.map[i][j] = self.instantiateBlock(self, {
  220. x: j,
  221. y: i,
  222. color: (data && data[i]) ? data[i][j] : null,
  223. width: self.blockWidth,
  224. startTime: (i + j + 1) * self._controller.config.json.startAnimationTime / num * 2
  225. }, self.blocksContainer, itemType)
  226. }
  227. }
  228. this.checkMgr.init(this)
  229. setTimeout(() => {
  230. resolve('200 OK');
  231. this.checkMgr.check(this)
  232. }, self._controller.config.json.startAnimationTime * num / 2 / 1
  233. // (cc.game.getFrameRate() / 60)
  234. )
  235. })
  236. },
  237. //防抖动 判断是否需要检测下落
  238. checkNeedFall() {
  239. if (this.checkNeedFallTimer) {
  240. clearTimeout(this.checkNeedFallTimer)
  241. }
  242. this.checkNeedFallTimer = setTimeout(() => {
  243. if (this._status == 5) {
  244. this._status = 4
  245. this.onFall()
  246. }
  247. }, 300 / 1
  248. // (cc.game.getFrameRate() / 60)
  249. )
  250. },
  251. //方块下落
  252. onFall() {
  253. this.checkGenerateProp(this._score.chain).then(() => {
  254. let self = this
  255. let canFall = 0
  256. //从每一列的最下面一个开始往上判断
  257. //如果有空 就判断有几个空 然后让最上方的方块掉落下来
  258. for (let j = this.rowNum - 1; j >= 0; j--) {
  259. canFall = 0
  260. for (let i = this.rowNum - 1; i >= 0; i--) {
  261. if (this.map[i][j].getComponent('cell')._status == 2) {
  262. this.blockPool.put(this.map[i][j])
  263. this.map[i][j] = null
  264. canFall++
  265. } else {
  266. if (canFall != 0) {
  267. this.map[i + canFall][j] = this.map[i][j]
  268. this.map[i][j] = null
  269. this.map[i + canFall][j].getComponent('cell').playFallAction(canFall, {
  270. x: j,
  271. y: i + canFall,
  272. })
  273. }
  274. }
  275. }
  276. for (var k = 0; k < canFall; k++) {
  277. this.map[k][j] = this.instantiateBlock(this, {
  278. x: j,
  279. y: k,
  280. width: this.blockWidth,
  281. startTime: null
  282. }, this.blocksContainer, '', {
  283. x: j,
  284. y: -canFall + k
  285. })
  286. this.map[k][j].getComponent('cell').playFallAction(canFall, null)
  287. }
  288. }
  289. setTimeout(() => {
  290. this.checkMgr.init(this)
  291. this.checkMgr.check(this)
  292. this._status = 1
  293. }, 250)
  294. })
  295. },
  296. gameOver() {
  297. this._status = 3
  298. this._controller.pageMgr.addPage(2)
  299. this._controller.pageMgr.addPage(4)
  300. // 游戏结束 banner或者广告
  301. // if (this._controller.social.node.active) {
  302. // this._controller.social.closeBannerAdv()
  303. // }
  304. },
  305. // todo 复活
  306. askRevive() {
  307. this._controller.pageMgr.addPage(2)
  308. this._controller.pageMgr.addPage(5)
  309. this.revivePage.active = true
  310. this.revivePage.getChildByName('askRevive').active = true
  311. this.revivePage.getChildByName('successRevive').active = false
  312. this.rangeSprite = this.revivePage.getChildByName('askRevive').getChildByName('numBg').getChildByName('sprite').getComponent(cc.Sprite)
  313. this.rangeSprite.fillRange = 1
  314. this.isRangeAction = true
  315. let numLabel = this.revivePage.getChildByName('askRevive').getChildByName('numBg').getChildByName('num').getComponent(cc.Label)
  316. numLabel.string = 9
  317. if (this.reviveTimer) {
  318. clearInterval(this.reviveTimer)
  319. }
  320. this.reviveTimer = setInterval(() => {
  321. if (+numLabel.string > 0) {
  322. numLabel.string--
  323. this.rangeSprite.fillRange = 1
  324. } else {
  325. this.onSkipRevive()
  326. }
  327. }, 1000)
  328. },
  329. onReviveButton() {
  330. clearInterval(this.reviveTimer)
  331. this.isRangeAction = false
  332. // TODO 广告 视频复活
  333. if (AppConst.SHOWADUI) {
  334. if (AppConst.CHANNEL == AppConst.channel.ANDROID) {
  335. ADSdk.pay(2, this);
  336. } else {
  337. ADSdk.showVideo(null, (result) => {
  338. if (result == 1) {
  339. this.showReviveSuccess()
  340. }
  341. });
  342. }
  343. } else {
  344. this.showReviveSuccess()
  345. }
  346. // this.showReviveSuccess()
  347. // self._controller.game.onSkipRevive()
  348. },
  349. showReviveSuccess() {
  350. //console.log('打开复活成功页面')
  351. this.revivePage.getChildByName('askRevive').active = false
  352. this.revivePage.getChildByName('successRevive').active = true
  353. },
  354. onReviveCertainBtn() {
  355. this._controller.pageMgr.removePage(2)
  356. this.revivePage.active = false
  357. this._status = 1
  358. this._score.onRevive()
  359. },
  360. update() {
  361. if (this.isRangeAction) {
  362. this.rangeSprite.fillRange -= 1 / 60
  363. }
  364. },
  365. onSkipRevive() {
  366. clearInterval(this.reviveTimer)
  367. this._controller.pageMgr.pages[5].active = false
  368. this._score.onGameOver(true)
  369. this.isRangeAction = false
  370. },
  371. restart() {
  372. this._controller.pageMgr.onOpenPage(1)
  373. this.recoveryAllBlocks().then(() => {
  374. this.gameStart()
  375. })
  376. },
  377. // -----------------道具相关---------------
  378. // 储存用户点击时的方块 用于生成道具
  379. onUserTouched(iid, jid, itemType, color, warning, pos) {
  380. this.target = {
  381. i: iid,
  382. j: jid,
  383. color: color,
  384. itemType: itemType,
  385. x: pos.x,
  386. y: pos.y,
  387. warning: warning
  388. }
  389. },
  390. // 生成道具 type 1为双倍倍数 2为炸弹 3为加五百
  391. generatePropItem(type) {
  392. return new Promise((resolve, reject) => {
  393. // 是否做道具生成动画
  394. this.map[this.target.i][this.target.j] = this.instantiateBlock(this, {
  395. x: this.target.j,
  396. y: this.target.i,
  397. color: this.target.color,
  398. width: this.blockWidth,
  399. startTime: null
  400. }, this.blocksContainer, type)
  401. setTimeout(() => {
  402. resolve()
  403. }, 300)
  404. })
  405. },
  406. checkGenerateProp(chain) {
  407. return new Promise((resolve, reject) => {
  408. if (this.target && this.target.warning) {
  409. this.generatePropItem(this.target.warning).then(() => {
  410. resolve()
  411. return
  412. })
  413. }
  414. resolve()
  415. })
  416. },
  417. onItem(type, color, pos) {
  418. switch (type) {
  419. case 1:
  420. // 分数翻倍 最高八倍
  421. this._score.tipBox.init(this._score, 1)
  422. this._score.addMult(color, pos)
  423. this._controller.musicMgr.onDouble()
  424. for (let i = 0; i < this.rowNum; i++) { //行
  425. for (let j = 0; j < this.rowNum; j++) { //列
  426. if (this.map[i][j] && this.map[i][j].getComponent('cell')._status == 1) {
  427. let distance = Math.sqrt(Math.pow(pos.x - this.map[i][j].x, 2) + Math.pow(pos.y - this.map[i][j].y, 2))
  428. if (distance != 0) {
  429. this.map[i][j].getComponent('cell').surfaceAction(distance)
  430. }
  431. }
  432. }
  433. }
  434. break
  435. case 2:
  436. // 炸弹 消除同种颜色的
  437. this._score.tipBox.init(this._score, 2)
  438. this.node.runAction(AC.shackAction(0.1, 10))
  439. // 震动
  440. // if (this._controller.social.node.active) {
  441. // this._controller.social.onShakePhone()
  442. // }
  443. this.isPropChain = true
  444. this._controller.musicMgr.onBoom()
  445. for (let i = 0; i < this.rowNum; i++) { //行
  446. for (let j = 0; j < this.rowNum; j++) { //列
  447. if (this.map[i][j] && this.map[i][j].getComponent('cell').color == color && this.map[i][j] && this.map[i][j].getComponent('cell')._status != 2) {
  448. this.map[i][j].getComponent('cell').onTouched(color, false, true)
  449. } else {
  450. this.map[i][j].runAction(AC.rockAction(0.2, 10))
  451. }
  452. }
  453. }
  454. break
  455. case 3: //: 加步数
  456. this._score.tipBox.init(this._score, 4)
  457. this._controller.musicMgr.onDouble()
  458. for (let i = 0; i < this.rowNum; i++) { //行
  459. for (let j = 0; j < this.rowNum; j++) { //列
  460. if (this.map[i][j] && this.map[i][j].getComponent('cell')._status == 1) {
  461. let distance = Math.sqrt(Math.pow(pos.x - this.map[i][j].x, 2) + Math.pow(pos.y - this.map[i][j].y, 2))
  462. if (distance != 0) {
  463. this.map[i][j].getComponent('cell').surfaceAction(distance)
  464. }
  465. }
  466. }
  467. }
  468. this._score.onStep(3).then()
  469. break;
  470. case 4: // : 消除全部单身的方块
  471. this._score.tipBox.init(this._score, 5)
  472. this.isPropChain = true
  473. this._controller.musicMgr.onMagic()
  474. for (let i = 0; i < this.rowNum; i++) { //行
  475. for (let j = 0; j < this.rowNum; j++) { //列
  476. if (this.map[i][j] && this.map[i][j].getComponent('cell').isSingle && this.map[i][j] && this.map[i][j].getComponent('cell')._status != 2) {
  477. let distance = Math.sqrt(Math.pow(pos.x - this.map[i][j].x, 2) + Math.pow(pos.y - this.map[i][j].y, 2))
  478. this.map[i][j].getComponent('cell').onTouched(color, false, true, distance)
  479. // console.log("魔法棒触发的点", i, j, this.map[i][j].getComponent('cell').color, this.map[i][j].getComponent('cell').isSingle)
  480. }
  481. }
  482. }
  483. break;
  484. }
  485. },
  486. //--------------------- 预制体实例化---------------------
  487. // 生成对象池
  488. generatePool() {
  489. this.blockPool = new cc.NodePool()
  490. for (let i = 0; i < Math.pow(this.rowNum, 2); i++) {
  491. let block = cc.instantiate(this.blockPrefab)
  492. this.blockPool.put(block)
  493. }
  494. },
  495. // 实例化单个方块
  496. instantiateBlock(self, data, parent, itemType, pos) {
  497. itemType = itemType ? itemType : 0
  498. if (itemType != 0) {
  499. // console.log("道具节点数据", data, itemType)
  500. }
  501. let block = null
  502. if (self.blockPool && self.blockPool.size() > 0) {
  503. block = self.blockPool.get()
  504. } else {
  505. block = cc.instantiate(self.blockPrefab)
  506. }
  507. block.parent = parent
  508. block.scale = 1
  509. block.x = 0
  510. block.y = 0
  511. block.getComponent('cell').init(self, data, this.blockWidth, itemType, pos)
  512. return block
  513. },
  514. // 回收所有节点
  515. recoveryAllBlocks() {
  516. return new Promise((resolve, reject) => {
  517. let children = this.blocksContainer.children
  518. if (children.length != 0) {
  519. let length = children.length
  520. // console.log(length)
  521. for (let i = 0; i < length; i++) {
  522. this.blockPool.put(children[0])
  523. }
  524. for (let i = 0; i < this.rowNum; i++) {
  525. for (let j = 0; j < this.rowNum; j++) {
  526. this.map[i][j] = null
  527. }
  528. }
  529. }
  530. resolve('')
  531. })
  532. },
  533. });