LevelHome.js 14 KB

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