numFont.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import { _decorator, Component, Node, Material, MeshRenderer, Prefab, instantiate, Enum } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. //目前支持: 显示————整数的靠左、居中、靠右的数字显示
  4. const horizontalAlignListCheck = new Map([
  5. [1, 'left'],
  6. [2, 'center'],
  7. [3, 'right'],
  8. ]);
  9. const horizontalAlignListName = Enum({
  10. 'left': 1,
  11. 'center': 2,
  12. 'right': 3,
  13. });
  14. @ccclass('NumFont')
  15. export class NumFont extends Component {
  16. @property(Prefab)
  17. preNum: Prefab = null!; //数字预制体
  18. @property(Material)
  19. matNumList: Array<Material> = [];
  20. @property({ type: horizontalAlignListName, displayName: "horizontalAlign", tooltip: '水平对齐' })
  21. horizontalAlign: number = 1; //水平对齐
  22. //-----------相对于Cube的大小
  23. @property({ displayName: "width / height", tooltip: '宽/高' })
  24. ndNumFont: number = 1; //'宽/高'
  25. @property({ displayName: "rangeX", tooltip: 'x轴区间' })
  26. rangeX: number = 1; //限制x轴区间
  27. @property({ displayName: "rangeZ", tooltip: 'z轴区间' })
  28. rangeZ: number = 1; //限制z轴区间
  29. /**
  30. * 代码初始化字体相关数据
  31. * @param ndNumFont
  32. * @param rangeX
  33. * @param rangeZ
  34. */
  35. public init(ndNumFont: number, rangeX: number, rangeZ: number) {
  36. this.ndNumFont = ndNumFont;
  37. this.rangeX = rangeX;
  38. this.rangeZ = rangeZ;
  39. }
  40. /**
  41. * 更新显示
  42. */
  43. public updateShow(num: number) {
  44. //将数字从后往前的顺序取出取出
  45. const numList = [];
  46. if (num === 0) {
  47. numList.push(0);
  48. } else {
  49. while (num > 0) {
  50. numList.push(num % 10);
  51. num = Math.floor(num / 10);
  52. }
  53. }
  54. let w = -1; //当前每一个字的宽度
  55. let h = -1; //当前每一个字的高度
  56. if (numList.length <= Math.floor(this.rangeX / (this.rangeZ * this.ndNumFont))) {
  57. //当前位数 < 当前最大高度可显示的字数
  58. w = this.rangeZ * this.ndNumFont;
  59. h = this.rangeZ;
  60. } else {
  61. w = this.rangeX / numList.length;
  62. h = w / this.ndNumFont;
  63. }
  64. //将暂时未使用到的节点隐藏
  65. if (this.node.children.length > numList.length) {
  66. for (let i = numList.length; i < this.node.children.length; i++) {
  67. if (!this.node.children[i].active) continue;
  68. this.node.children[i].active = false;
  69. }
  70. }
  71. let k;
  72. let startPosX: number = null!; //第一个生成的数字位置
  73. const changeItem = (itemNode: Node, mat: Material) => {
  74. if (itemNode) {
  75. itemNode.active = true;
  76. } else {
  77. itemNode = instantiate(this.preNum);
  78. this.node.addChild(itemNode);
  79. }
  80. itemNode.setPosition(startPosX, 0, 0);
  81. itemNode.setScale(w, 0.01, h);
  82. itemNode.getComponent(MeshRenderer)?.setMaterial(mat, 0);
  83. }
  84. switch (horizontalAlignListCheck.get(this.horizontalAlign)) {
  85. case 'left':
  86. startPosX = -this.rangeX / 2 + w / 2;
  87. for (k = numList.length - 1; k >= 0; k--) {
  88. changeItem(this.node.children[numList.length - 1 - k], this.matNumList[numList[k]]);
  89. startPosX += w;
  90. }
  91. break;
  92. case 'center':
  93. startPosX = numList.length / 2 * w - w / 2;
  94. for (k = 0; k < numList.length; k++) {
  95. changeItem(this.node.children[k], this.matNumList[numList[k]]);
  96. startPosX -= w;
  97. }
  98. break;
  99. case 'right':
  100. startPosX = this.rangeX / 2 - w / 2;
  101. for (k = 0; k < numList.length; k++) {
  102. changeItem(this.node.children[k], this.matNumList[numList[k]]);
  103. startPosX -= w;
  104. }
  105. break;
  106. }
  107. }
  108. }