LevelHome.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. const HomeApi = require("../net/HomeApi");
  2. const GameModule = require("../utils/GameModule");
  3. const { GameNotificationKey } = require("../utils/GameEnum")
  4. const AlertManager = require('../utils/AlertManager')
  5. cc.Class({
  6. extends: cc.Component,
  7. properties: {
  8. scrollView: cc.ScrollView,
  9. levelHomeItem: cc.Prefab,
  10. levelHomeTop: cc.Prefab,
  11. levelHomeBottom: cc.Prefab,
  12. minContentPosition: -150,
  13. _unlockBuilding: [],
  14. showOffLineUI: true,
  15. mask: cc.Node,
  16. actGift: {
  17. tooltip: '领取弹出层',
  18. default: null,
  19. type: cc.Node
  20. },
  21. },
  22. /**
  23. * home 初始化方法, 所有的初始化操作在这里操作, 必须在加入父节点之前调用
  24. * */
  25. init(uid, cityId) {
  26. this.uid = uid;
  27. this.cityId = cityId;
  28. this.buildingInfos = [];
  29. this.node.parent = cc.find("Canvas/game");
  30. this.scrollView.scrollToBottom();
  31. this.refreshTheme();
  32. this.getNetworkData();
  33. },
  34. refreshTheme() {
  35. if (this.topScript) {
  36. this.topScript.init(this.cityId);
  37. }
  38. if (this.buildings) {
  39. for (let i = 0; i < this.buildings.length; i++) {
  40. let itemScript = this.buildings[i];
  41. itemScript.init(this, this.cityId, i + 1);
  42. }
  43. }
  44. if (this.bottomScript) {
  45. this.bottomScript.init(this.cityId);
  46. }
  47. },
  48. // LIFE-CYCLE CALLBACKS:
  49. onLoad() {
  50. this.buildings = [];
  51. this.unlockBuilding = [];
  52. this.matchScreenSize();
  53. let topNode = cc.instantiate(this.levelHomeTop);
  54. this.topScript = topNode.getComponent('LevelHomeTop');
  55. this.topScript.init(this.cityId);
  56. this.scrollView.content.addChild(topNode);
  57. for (let i = 0; i < 5; i++) {
  58. let item = cc.instantiate(this.levelHomeItem);
  59. let itemScript = item.getComponent('LevelHomeItem');
  60. itemScript.init(this, this.cityId, i + 1);
  61. this.scrollView.content.addChild(item);
  62. this.buildings.push(itemScript);
  63. }
  64. let bottomNode = cc.instantiate(this.levelHomeBottom);
  65. this.bottomScript = bottomNode.getComponent('LevelHomeBottom'); this.bottomScript.init(this.cityId);
  66. this.scrollView.content.addChild(bottomNode);
  67. this.setEventLisenter();
  68. // 监听小游戏隐藏到后台事件
  69. if (CC_WECHATGAME) {
  70. wx.onHide(() => {
  71. this.wxHide = true
  72. // 离线收益计算重置
  73. this.showOffLineUI = true
  74. let lastTime = new Date().getTime()
  75. cc.sys.localStorage.setItem('offlineLastTime', lastTime);
  76. // 退出前立刻调用一次上报
  77. GameModule.userInfo.doReport()
  78. })
  79. wx.onShow(() => {
  80. if (this.wxHide) {
  81. this.refreshTheme();
  82. this.getNetworkData();
  83. this.wxHide = false
  84. }
  85. })
  86. }
  87. },
  88. setEventLisenter() {
  89. this.scrollView.node.on("scrolling", (event) => {
  90. if (this.scrollView._isOutOfBoundary()) {
  91. if (this.scrollView._outOfBoundaryAmount.y > 0) { // 超出上面的界限
  92. this.scrollView._outOfBoundaryAmount.y = 0;
  93. this.scrollView._adjustContentOutOfBoundary();
  94. } else { // 超出下面的界限
  95. if (this.scrollView._outOfBoundaryAmount.y < this.minContentPosition) {
  96. if (this.recordScrollViewPosition) {
  97. this.scrollView.content.setPosition(this.recordScrollViewPosition);
  98. return;
  99. } else {
  100. this.recordScrollViewPosition = this.scrollView.getContentPosition();
  101. }
  102. } else {
  103. this.recordScrollViewPosition = null;
  104. }
  105. }
  106. }
  107. }, this);
  108. GameEvent.on(GameNotificationKey.showCatFlyAnimation, this, () => {
  109. this.scrollView.scrollToTop(0.2);
  110. });
  111. GameEvent.on(GameNotificationKey.ReloadLevelHomeData, this, () => {
  112. this.refreshTheme();
  113. this.getNetworkData();
  114. });
  115. GameEvent.on(GameNotificationKey.ResetLevelHomePaddingBottom, this, () => {
  116. this.resetPaddingBottom();
  117. });
  118. //房间解锁通知,用来触发是否显示入驻艺人通知(因为通知需要随机出现在没有艺人的房间,所以需要在LevelHome这一层来处理)
  119. GameEvent.on(GameNotificationKey.LevelHomeItemUnlock, this, this.randomResidentTip);
  120. },
  121. /**
  122. * 适配不同高度的屏幕尺寸
  123. */
  124. matchScreenSize() {
  125. let initHeight = 1624;
  126. let vsize = cc.view.getVisibleSize()
  127. let paddingY = (initHeight - vsize.height) / 2;
  128. if (paddingY < 0) {
  129. paddingY = 0;
  130. }
  131. this.scrollView.content.getComponent(cc.Layout).paddingTop = paddingY;
  132. this.scrollView.elastic = false;
  133. // 底部加多一块100px的内边距, 让底楼不要完全显示出来
  134. this.scrollView.content.getComponent(cc.Layout).paddingBottom = paddingY - 100;
  135. },
  136. resetPaddingBottom() {
  137. let initHeight = 1624;
  138. let vsize = cc.view.getVisibleSize()
  139. let paddingY = (initHeight - vsize.height) / 2;
  140. if (GameModule.userInfo.stars >= 20) {
  141. this.scrollView.elastic = true;
  142. // 底部加多一块100px的内边距, 让底楼不要完全显示出来
  143. this.scrollView.content.getComponent(cc.Layout).paddingBottom = paddingY - 100;
  144. } else {
  145. this.scrollView.elastic = false;
  146. // 底部加多一块100px的内边距, 让底楼不要完全显示出来
  147. this.scrollView.content.getComponent(cc.Layout).paddingBottom = paddingY - 275;
  148. }
  149. this.scrollView.scrollToBottom(0);
  150. },
  151. // 用来访问自己家园时, 重置scrollView位置
  152. start() {
  153. this.scrollView.scrollToBottom(0.0);
  154. },
  155. getNetworkData(callback) {
  156. this.getUserBuildings()
  157. .then((responseData) => {
  158. // 清空数据
  159. this.buildingInfos = [];
  160. // 满级后去别的城市就置零
  161. GameModule.userInfo.levelHomeItemFullCount = 0;
  162. let sortArray = responseData.buildings.sort((a, b) => {
  163. return a.buildingId < b.buildingId;
  164. });
  165. // 离线收益金币数量
  166. let offlineGrossIncome = 0;
  167. sortArray.map((value, index, array) => {
  168. let model = Global.BuildingManager.getBuildingInfo(this.cityId, value.buildingId, value.level)
  169. this._unlockBuilding[index] = model.isUnlocked ? 1 : 0;
  170. if (model.isFull() && this.cityId === Global.devCityId) {
  171. try {
  172. GameEvent.fire(GameNotificationKey.LevelHomeItemBuildingFull);
  173. } catch (error) {
  174. console.log(error);
  175. }
  176. }
  177. model.coinCount = value.coinCount;
  178. model.artists = value.artists || [];
  179. if (model.artists.length > 0) { // 有艺人入驻的情况
  180. let addition = 0;
  181. for (let i = 0; i < model.artists.length; i++) {
  182. let artist = model.artists[i];
  183. addition += artist.stationJobLevel + 1;
  184. }
  185. offlineGrossIncome += (model.coinCount * (model.rate * addition));
  186. } else { // 无艺人入驻时
  187. offlineGrossIncome += (model.coinCount * model.rate);
  188. }
  189. this.buildingInfos.push(model);
  190. });
  191. this._unlockBuilding = this._unlockBuilding.reverse();
  192. // GameModule.userInfo.setUserInfo(responseData.user);
  193. // this.resetPaddingBottom();
  194. callback && callback();
  195. // 开始设置建筑
  196. this.configBuildings();
  197. // 离线收益处理
  198. this.configOffIncome(sortArray, offlineGrossIncome)
  199. return this.getBuildingItems();
  200. })
  201. .then((buildingItems) => {
  202. for (const buildingId in buildingItems) {
  203. let itemScript;
  204. let filterList = this.buildings.filter( item => item.buildingInfo.buildingId === parseInt(buildingId) ) || [];
  205. if (filterList.length > 0) {
  206. itemScript = filterList[0];
  207. if (buildingItems.hasOwnProperty(buildingId)) {
  208. let prop = buildingItems[buildingId];
  209. itemScript.showProp(prop, false);
  210. }
  211. }
  212. }
  213. })
  214. .catch((err) => {
  215. console.log(err);
  216. });
  217. },
  218. getUserBuildings() {
  219. return new Promise((resolve, reject) => {
  220. // 获取目标用户的建筑
  221. HomeApi.getUserBuildings(this.uid, this.cityId, (responseData) => {
  222. resolve(responseData);
  223. }, (error) => {
  224. reject(error);
  225. });
  226. })
  227. },
  228. getBuildingItems() {
  229. return new Promise((resolve, reject) => {
  230. HomeApi.getBuildingItems((buildingItems) => {
  231. resolve(buildingItems);
  232. }, (err) => {
  233. reject(err);
  234. })
  235. });
  236. },
  237. configBuildings() {
  238. for (let i = 0; i < this.buildings.length; i++) {
  239. let itemScript = this.buildings[i];
  240. itemScript.config(this.buildingInfos[i], this.uid, this._unlockBuilding, (newBuildingInfo) => {
  241. this.buildingInfos[i] = newBuildingInfo;
  242. });
  243. }
  244. this.randomResidentTip();
  245. },
  246. /**
  247. * 离线收益处理
  248. * @param {Array} sortArray 用户当前城市buildingInfos数组
  249. * @param {Number} offlineGrossIncome 离线收益金币数量
  250. */
  251. configOffIncome(sortArray, offlineGrossIncome) {
  252. let lastTime = cc.sys.localStorage.getItem('offlineLastTime');
  253. if (!lastTime) {
  254. lastTime = new Date().getTime()
  255. cc.sys.localStorage.setItem('offlineLastTime', lastTime);
  256. } else {
  257. let curTime = new Date().getTime()
  258. cc.sys.localStorage.setItem('offlineLastTime', curTime);
  259. // 显示离线收益的条件:
  260. // 1. 离上一次显示超过5分钟
  261. // 2. 用户解锁星数大于20
  262. // 3. 当前城市已解锁建筑数大于5
  263. let unLockStatus1 = curTime - lastTime > 300 * 1000
  264. let unLockStatus2 = GameModule.userInfo.stars > 20
  265. let unLockStatus3 = (() => {
  266. let flag = true
  267. sortArray.forEach(n => {
  268. if (n.level == 0) {
  269. flag = false
  270. }
  271. })
  272. return flag
  273. })()
  274. // showOffLineUI: 用户每次进入游戏离线收益只会显示1次
  275. if (this.showOffLineUI && unLockStatus1 && unLockStatus2 && unLockStatus3) {
  276. this.showOffLineUI = false;
  277. AlertManager.showOfflineGrossIncome(offlineGrossIncome);
  278. }
  279. }
  280. },
  281. randomResidentTip() {
  282. if (this.buildings && this.buildings.length > 0) {
  283. let noArtistBuildings = [];
  284. for (let i = 0; i < this.buildings.length; i++) {
  285. let itemScript = this.buildings[i];
  286. let buildingInfo = this.buildingInfos[i];
  287. if (buildingInfo.level == 0) {
  288. itemScript.setResidentTip(false);
  289. continue;
  290. }
  291. if (buildingInfo.artists && buildingInfo.artists.length > 0) {
  292. itemScript.setResidentTip(false);
  293. } else {
  294. noArtistBuildings.push(itemScript);
  295. }
  296. }
  297. if (noArtistBuildings.length > 0) {
  298. let index = Math.floor(Math.random() * noArtistBuildings.length);
  299. for (let i = 0; i < noArtistBuildings.length; i++) {
  300. noArtistBuildings[i].setResidentTip(i == index);
  301. }
  302. clearInterval(this.residentTipHideTimer);
  303. clearInterval(this.residentTipShowTimer);
  304. this.residentTipHideTimer = setInterval(() => {
  305. noArtistBuildings[index].setResidentTip(false);
  306. }, 5000);
  307. this.residentTipShowTimer = setInterval(() => {
  308. this.randomResidentTip(false);
  309. }, 15000);
  310. }
  311. }
  312. },
  313. /**
  314. * 显示领取动画
  315. */
  316. showActGift (showFrame, showText) {
  317. GameModule.audioMng.playGift()
  318. this.mask.active = true;
  319. this.actGift.active = true;
  320. cc.find('/gift_sprite', this.actGift).getComponent('cc.Sprite').spriteFrame = showFrame;
  321. cc.find('/gift_label', this.actGift).getComponent('cc.Label').string = showText;
  322. },
  323. /**
  324. * 关闭领取动画
  325. */
  326. hideActGift () {
  327. this.mask.active = false;
  328. this.actGift.active = false;
  329. },
  330. onDestroy() {
  331. if (this.residentTipHideTimer) {
  332. clearInterval(this.residentTipHideTimer);
  333. clearInterval(this.residentTipShowTimer);
  334. }
  335. GameEvent.off(GameNotificationKey.showCatFlyAnimation, this);
  336. GameEvent.off(GameNotificationKey.ReloadLevelHomeData, this);
  337. GameEvent.off(GameNotificationKey.ResetLevelHomePaddingBottom, this);
  338. GameEvent.off(GameNotificationKey.LevelHomeItemUnlock, this);
  339. },
  340. });