NoticeLayer.ts 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { Component, find, instantiate, Label, Node, NodePool, UIOpacity, UITransform, v3, _decorator } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. @ccclass('NoticeLayer')
  4. export class NoticeLayer extends Component {
  5. contentLayer: Node;
  6. textPool: NodePool;
  7. textItem: Node;
  8. maxContentWidth: number = 580;
  9. minContentWidth: number = 150;
  10. contentBGAdd: number = 150;
  11. orignHeight: number = 0;
  12. // 多条飘字之间的y间隔
  13. spaceY: number = 5;
  14. status: any = {
  15. fadeIn: 1,
  16. delay: 2,
  17. fadeOut: 3
  18. };
  19. // 移动速度,像素/每秒
  20. speedY: number = 300;
  21. // 透明度变化速度,透明度/每秒
  22. speedOpacity: number = 255 / 0.3;
  23. // 展示不动的时间。单位:秒
  24. delayTime: number = 0;
  25. // 渐显和渐隐移动的距离
  26. moveDy: number = 150;
  27. // 要保证只能有一个处于fadeOut状态,其他的要处于队列等待
  28. fadeOutNode: Node = null;
  29. onLoad() {
  30. this.contentLayer = find("contentLayer", this.node);
  31. this.textItem = find("contentLayer/textItem", this.node);
  32. this.textPool = new NodePool();
  33. this.textPool.put(this.textItem);
  34. this.textItem = instantiate(this.textItem);
  35. this.orignHeight = find("content", this.textItem).getComponent(UITransform).height;
  36. }
  37. noticeShow(content) {
  38. var node = this.textPool.get();
  39. if (!node) {
  40. node = instantiate(this.textItem);
  41. }
  42. node.active = true;
  43. let contentNode = find("content", node);
  44. contentNode.getComponent(UITransform).height = this.orignHeight;
  45. contentNode.getComponent(Label).overflow = Label.Overflow.NONE;
  46. contentNode.getComponent(Label).string = content + "";
  47. // 调用这个方法之后,才能在本帧获得准确宽度
  48. contentNode.getComponent(Label).updateRenderData(true);
  49. let width = contentNode.getComponent(UITransform).width;
  50. if (width > this.maxContentWidth) {
  51. contentNode.getComponent(Label).overflow = Label.Overflow.SHRINK;
  52. contentNode.getComponent(UITransform).width = this.maxContentWidth;
  53. contentNode.getComponent(UITransform).height = this.orignHeight * 2 + 10;
  54. width = this.maxContentWidth;
  55. } else if (width < this.minContentWidth) {
  56. width = this.minContentWidth;
  57. }
  58. // 设置背景图片宽度和高度
  59. node.getComponent(UITransform).width = width + this.contentBGAdd;
  60. node.getComponent(UITransform).height = contentNode.getComponent(UITransform).height + 10;
  61. node.setPosition(0, -this.moveDy);
  62. node.moveY = this.moveDy;
  63. node.moveDy = 0;
  64. node.setScale(v3(1, 1, 1));
  65. node.getComponent(UIOpacity).opacity = 0;
  66. node.status = this.status.fadeIn;
  67. node.parent = this.contentLayer;
  68. }
  69. createNotice(content) {
  70. this.noticeShow(content + "");
  71. }
  72. update(dt: number) {
  73. let chs = this.contentLayer.children;
  74. let backArr = [];
  75. for (let i in chs) {
  76. let node = chs[i];
  77. switch (node.status) {
  78. case this.status.fadeIn:
  79. var dy = dt * this.speedY;
  80. var pos = node.getPosition();
  81. pos.y += dy;
  82. node.position = pos;
  83. node.moveDy += dy;
  84. var opacity = node.getComponent(UIOpacity).opacity + this.speedOpacity * dt;
  85. if (opacity > 255) {
  86. opacity = 255;
  87. }
  88. node.getComponent(UIOpacity).opacity = opacity;
  89. if (node.moveDy >= node.moveY) {
  90. node.moveDy = 0;
  91. node.getComponent(UIOpacity).opacity = 255;
  92. node.status = this.status.delay;
  93. node.time = 0;
  94. node.delayTime = this.delayTime;
  95. }
  96. break;
  97. case this.status.delay:
  98. node.delayTime -= dt;
  99. if (node.delayTime <= 0) {
  100. node.delayTime = 0;
  101. node.status = this.status.fadeOut;
  102. }
  103. break;
  104. case this.status.fadeOut:
  105. if (this.fadeOutNode && this.fadeOutNode != node) {
  106. break;
  107. }
  108. this.fadeOutNode = node;
  109. var dy = dt * this.speedY;
  110. var pos = node.getPosition();
  111. pos.y += dy;
  112. node.position = pos;
  113. var opacity = node.getComponent(UIOpacity).opacity - this.speedOpacity * dt;
  114. if (opacity < 0) {
  115. opacity = 0;
  116. }
  117. node.getComponent(UIOpacity).opacity = opacity;
  118. if (opacity <= 0) {
  119. backArr.push(node);
  120. this.fadeOutNode = null;
  121. }
  122. break;
  123. }
  124. }
  125. for (let i in backArr) {
  126. let node = backArr[i];
  127. node.parent = null;
  128. this.textPool.put(node);
  129. }
  130. // 修正位置,保证不重叠
  131. chs = this.contentLayer.children;
  132. if (chs.length >= 2) {
  133. let lastNode = chs[chs.length - 1];
  134. for (let i = chs.length - 2; i >= 0; i--) {
  135. let node = chs[i];
  136. let dy = (node.getComponent(UITransform).height + lastNode.getComponent(UITransform).height) * 0.5 + this.spaceY;
  137. if (node.position.y - lastNode.position.y < dy) {
  138. let pos = node.getPosition();
  139. pos.y = lastNode.position.y + dy;
  140. node.position = pos;
  141. }
  142. lastNode = node;
  143. }
  144. }
  145. }
  146. }